@@ -1464,17 +1464,6 @@ static const auto gc_preserve_end_func = new JuliaFunction<> {
1464
1464
[](LLVMContext &C) { return FunctionType::get (getVoidTy (C), {Type::getTokenTy (C)}, false ); },
1465
1465
nullptr ,
1466
1466
};
1467
- static const auto except_enter_func = new JuliaFunction<>{
1468
- " julia.except_enter" ,
1469
- [](LLVMContext &C) {
1470
- auto T_pjlvalue = JuliaType::get_pjlvalue_ty (C);
1471
- auto RT = StructType::get (getInt32Ty (C), getPointerTy (C));
1472
- return FunctionType::get (RT, {T_pjlvalue}, false ); },
1473
- [](LLVMContext &C) { return AttributeList::get (C,
1474
- Attributes (C, {Attribute::ReturnsTwice}),
1475
- AttributeSet (),
1476
- None); },
1477
- };
1478
1467
static const auto pointer_from_objref_func = new JuliaFunction<>{
1479
1468
" julia.pointer_from_objref" ,
1480
1469
[](LLVMContext &C) { return FunctionType::get (JuliaType::get_pjlvalue_ty (C),
@@ -1931,6 +1920,7 @@ class jl_codectx_t {
1931
1920
SmallVector<jl_varinfo_t , 0 > slots;
1932
1921
std::map<int , jl_varinfo_t > phic_slots;
1933
1922
std::map<int , std::pair<Value*, Value*> > scope_restore;
1923
+ std::map<jl_value_t *, AllocaInst*> eh_buffers;
1934
1924
SmallVector<jl_cgval_t , 0 > SAvalues;
1935
1925
SmallVector<std::tuple<jl_cgval_t , BasicBlock *, AllocaInst *, PHINode *, SmallVector<PHINode*,0 >, jl_value_t *>, 0 > PhiNodes;
1936
1926
SmallVector<bool , 0 > ssavalue_assigned;
@@ -6561,8 +6551,8 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
6561
6551
return ;
6562
6552
}
6563
6553
else if (head == jl_leave_sym) {
6564
- int hand_n_leave = 0 ;
6565
6554
Value *scope_to_restore = nullptr , *token = nullptr ;
6555
+ SmallVector<AllocaInst*> handler_to_end;
6566
6556
for (size_t i = 0 ; i < jl_expr_nargs (ex); ++i) {
6567
6557
jl_value_t *arg = args[i];
6568
6558
if (arg == jl_nothing)
@@ -6588,13 +6578,18 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
6588
6578
ctx.builder .CreateCall (prepare_call (gc_preserve_end_func), {token});
6589
6579
}
6590
6580
if (jl_enternode_catch_dest (enter_stmt)) {
6581
+ handler_to_end.push_back (ctx.eh_buffers [enter_stmt]);
6591
6582
// We're not actually setting up the exception frames for these, so
6592
6583
// we don't need to exit them.
6593
- hand_n_leave += 1 ;
6594
6584
scope_to_restore = nullptr ; // restored by exception handler
6595
6585
}
6596
6586
}
6597
- ctx.builder .CreateCall (prepare_call (jlleave_noexcept_func), {get_current_task (ctx), ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), hand_n_leave)});
6587
+ ctx.builder .CreateCall (prepare_call (jlleave_noexcept_func), {get_current_task (ctx), ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), handler_to_end.size ())});
6588
+ auto *handler_sz64 = ConstantInt::get (Type::getInt64Ty (ctx.builder .getContext ()),
6589
+ sizeof (jl_handler_t ));
6590
+ for (AllocaInst *handler : handler_to_end) {
6591
+ ctx.builder .CreateLifetimeEnd (handler, handler_sz64);
6592
+ }
6598
6593
if (scope_to_restore) {
6599
6594
Value *scope_ptr = get_scope_field (ctx);
6600
6595
jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe ).decorateInst (
@@ -9759,13 +9754,22 @@ static jl_llvm_functions_t
9759
9754
ctx.ssavalue_assigned [cursor] = true ;
9760
9755
// Actually enter the exception frame
9761
9756
auto ct = get_current_task (ctx);
9762
- CallInst *sj = ctx.builder .CreateCall (prepare_call (except_enter_func), {ct});
9757
+ auto *handler_sz64 = ConstantInt::get (Type::getInt64Ty (ctx.builder .getContext ()),
9758
+ sizeof (jl_handler_t ));
9759
+ AllocaInst* ehbuff = emit_static_alloca (ctx, sizeof (jl_handler_t ), Align (16 ));
9760
+ ctx.eh_buffers [stmt] = ehbuff;
9761
+ ctx.builder .CreateLifetimeStart (ehbuff, handler_sz64);
9762
+ ctx.builder .CreateCall (prepare_call (jlenter_func), {ct, ehbuff});
9763
+ CallInst *sj;
9764
+ if (ctx.emission_context .TargetTriple .isOSWindows ())
9765
+ sj = ctx.builder .CreateCall (prepare_call (setjmp_func), {ehbuff});
9766
+ else
9767
+ sj = ctx.builder .CreateCall (prepare_call (setjmp_func), {ehbuff, ConstantInt::get (Type::getInt32Ty (ctx.builder .getContext ()), 0 )});
9763
9768
// We need to mark this on the call site as well. See issue #6757
9764
9769
sj->setCanReturnTwice ();
9765
- Value *isz = ctx.builder .CreateICmpEQ (ctx.builder .CreateExtractValue (sj, 0 ), ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), 0 ));
9766
- Value *ehbuf = ctx.builder .CreateExtractValue (sj, 1 );
9770
+ Value *isz = ctx.builder .CreateICmpEQ (sj, ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), 0 ));
9767
9771
BasicBlock *tryblk = BasicBlock::Create (ctx.builder .getContext (), " try" , f);
9768
- BasicBlock *catchpop = BasicBlock::Create (ctx.builder .getContext (), " catch_pop " , f);
9772
+ BasicBlock *catchpop = BasicBlock::Create (ctx.builder .getContext (), " catch_enter " , f);
9769
9773
BasicBlock *handlr = NULL ;
9770
9774
handlr = BB[lname];
9771
9775
workstack.push_back (lname - 1 );
@@ -9774,11 +9778,12 @@ static jl_llvm_functions_t
9774
9778
ctx.builder .SetInsertPoint (catchpop);
9775
9779
{
9776
9780
ctx.builder .CreateCall (prepare_call (jlleave_func), {get_current_task (ctx), ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), 1 )});
9781
+ ctx.builder .CreateLifetimeEnd (ehbuff, handler_sz64);
9777
9782
ctx.builder .CreateBr (handlr);
9778
9783
}
9779
9784
ctx.builder .SetInsertPoint (tryblk);
9780
9785
auto ehptr = emit_ptrgep (ctx, ct, offsetof (jl_task_t , eh));
9781
- ctx.builder .CreateAlignedStore (ehbuf , ehptr, ctx.types ().alignof_ptr );
9786
+ ctx.builder .CreateAlignedStore (ehbuff , ehptr, ctx.types ().alignof_ptr );
9782
9787
}
9783
9788
// For the two-arg version of :enter, twiddle the scope
9784
9789
if (jl_enternode_scope (stmt)) {
@@ -10354,7 +10359,6 @@ static void init_jit_functions(void)
10354
10359
add_named_global (gc_preserve_begin_func, (void *)NULL );
10355
10360
add_named_global (gc_preserve_end_func, (void *)NULL );
10356
10361
add_named_global (pointer_from_objref_func, (void *)NULL );
10357
- add_named_global (except_enter_func, (void *)NULL );
10358
10362
add_named_global (julia_call, (void *)NULL );
10359
10363
add_named_global (julia_call2, (void *)NULL );
10360
10364
add_named_global (jllockvalue_func, &jl_lock_value);
0 commit comments