Revision 2a406b243730a0a50aa99355786b3ac41340a386 authored by Keno Fischer on 06 July 2023, 21:20:40 UTC, committed by GitHub on 06 July 2023, 21:20:40 UTC
* Add pattern matching for `typeof` into field type tparam This PR allows full elimination of the following, even in ill-typed code. ``` struct TParamTypeofTest{T} x::T @eval TParamTypeofTest(x) = $(Expr(:new, :(TParamTypeofTest{typeof(x)}), :x)) end function tparam_typeof_test_elim(x) TParamTypeofTest(x).x end ``` Before this PR, we would get: ``` julia> code_typed(tparam_typeof_test_elim, Tuple{Any}) 1-element Vector{Any}: CodeInfo( 1 ─ %1 = Main.typeof(x)::DataType │ %2 = Core.apply_type(Main.TParamTypeofTest, %1)::Type{TParamTypeofTest{_A}} where _A │ %new(%2, x)::TParamTypeofTest └── return x ``` Where the `new` is non-eliminable, because the compiler did not know that `x::_A`. Fix this by pattern matching this particular pattern (where the condition is guaranteed, because we computed `_A` by `typeof`). This is not particularly general, but this pattern comes up a lot, so it's surprisingly effective. * add test case for optimizing multiple abstract fields * improve robustness --------- Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>
1 parent 46477cc
win32_ucontext.c
// This file is a part of Julia. License is MIT: https://julialang.org/license
#include "win32_ucontext.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
extern LONG WINAPI jl_exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo);
// Instead of using ntdll!_except_handler4, we call directly to our UnhandledExceptionFilter.
// This seems to work better, since it's unclear if we have made a valid frame
// that meets the expectations of that internal functions.
JL_DLLEXPORT EXCEPTION_DISPOSITION NTAPI __julia_personality(
PEXCEPTION_RECORD ExceptionRecord,
void *EstablisherFrame,
PCONTEXT ContextRecord,
void *DispatcherContext)
{
EXCEPTION_POINTERS ExceptionInfo;
ExceptionInfo.ExceptionRecord = ExceptionRecord;
ExceptionInfo.ContextRecord = ContextRecord;
EXCEPTION_DISPOSITION rval;
switch (jl_exception_handler(&ExceptionInfo)) {
case EXCEPTION_EXECUTE_HANDLER:
rval = ExceptionExecuteHandler;
break;
case EXCEPTION_CONTINUE_EXECUTION:
rval = ExceptionContinueExecution;
break;
case EXCEPTION_CONTINUE_SEARCH: JL_FALLTHROUGH;
default:
rval = ExceptionContinueSearch;
break;
}
return rval;
}
void jl_makecontext(win32_ucontext_t *ucp, void (*func)(void))
{
char *stack_top = (char*)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size;
#if defined(_CPU_X86_64_)
stack_top -= 0x20; // shadow stack
#elif defined(_CPU_X86_)
// install unhandled SEH EXCEPTION_REGISTRATION_RECORD at top of stack
static PEXCEPTION_ROUTINE UnHandler;
if (UnHandler == NULL) {
PEXCEPTION_REGISTRATION_RECORD fs0 = (PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0x0);
while (fs0->Next != (PEXCEPTION_REGISTRATION_RECORD)0xFFFFFFFF)
fs0 = fs0->Next;
UnHandler = fs0->Handler;
}
stack_top -= 0x20;
PEXCEPTION_REGISTRATION_RECORD Registration = (PEXCEPTION_REGISTRATION_RECORD)stack_top;
Registration[0].Next = &Registration[1];
Registration[0].Handler = &__julia_personality;
Registration[1].Next = (PEXCEPTION_REGISTRATION_RECORD)0xFFFFFFFF;
Registration[1].Handler = UnHandler;
#endif
stack_top -= sizeof(void*);
*(void**)stack_top = 0; // push rta
stack_top -= sizeof(void*); // stack space for ret
_JUMP_BUFFER *jmpbuf = (_JUMP_BUFFER*)&ucp->uc_mcontext;
#if defined(_CPU_X86_64_)
jmpbuf->Rip = (unsigned long long)func;
jmpbuf->Rsp = (unsigned long long)stack_top;
jmpbuf->Rbp = 0;
jmpbuf->Frame = ~(uint64_t)0; // SEH frame
#elif defined(_CPU_X86_)
jmpbuf->Eip = (unsigned long)func;
jmpbuf->Esp = (unsigned long)stack_top;
jmpbuf->Ebp = 0;
jmpbuf->Registration = (unsigned long)&Registration[0]; // SEH frame
#else
#error jl_makecontext not defined for CPU type
#endif
}
#ifdef __cplusplus
}
#endif
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...