@@ -1955,7 +1955,7 @@ class jl_codectx_t {
1955
1955
// local var info. globals are not in here.
1956
1956
SmallVector<jl_varinfo_t , 0 > slots;
1957
1957
std::map<int , jl_varinfo_t > phic_slots;
1958
- std::map<int , Value*> scope_tokens ;
1958
+ std::map<int , std::pair< Value*, Value*> > scope_restore ;
1959
1959
SmallVector<jl_cgval_t , 0 > SAvalues;
1960
1960
SmallVector<std::tuple<jl_cgval_t , BasicBlock *, AllocaInst *, PHINode *, SmallVector<PHINode*,0 >, jl_value_t *>, 0 > PhiNodes;
1961
1961
SmallVector<bool , 0 > ssavalue_assigned;
@@ -6573,6 +6573,7 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
6573
6573
}
6574
6574
else if (head == jl_leave_sym) {
6575
6575
int hand_n_leave = 0 ;
6576
+ Value *scope_to_restore = nullptr , *token = nullptr ;
6576
6577
for (size_t i = 0 ; i < jl_expr_nargs (ex); ++i) {
6577
6578
jl_value_t *arg = args[i];
6578
6579
if (arg == jl_nothing)
@@ -6582,7 +6583,7 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
6582
6583
jl_value_t *enter_stmt = jl_array_ptr_ref (ctx.code , enter_idx);
6583
6584
if (enter_stmt == jl_nothing)
6584
6585
continue ;
6585
- if (ctx.scope_tokens .count (enter_idx)) {
6586
+ if (ctx.scope_restore .count (enter_idx)) {
6586
6587
// TODO: The semantics of `gc_preserve` are not perfect here. An `Expr(:enter, ...)` block may
6587
6588
// have multiple exits, but effects of `preserve_end` are only extended to the end of the
6588
6589
// dominance of each `Expr(:leave, ...)`.
@@ -6594,15 +6595,22 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
6594
6595
//
6595
6596
// This is correct as-is anyway - it just means the scope lives longer than it needs to
6596
6597
// if the `Expr(:enter, ...)` has multiple exits.
6597
- ctx.builder .CreateCall (prepare_call (gc_preserve_end_func), {ctx.scope_tokens [enter_idx]});
6598
+ std::tie (token, scope_to_restore) = ctx.scope_restore [enter_idx];
6599
+ ctx.builder .CreateCall (prepare_call (gc_preserve_end_func), {token});
6598
6600
}
6599
6601
if (jl_enternode_catch_dest (enter_stmt)) {
6600
6602
// We're not actually setting up the exception frames for these, so
6601
6603
// we don't need to exit them.
6602
6604
hand_n_leave += 1 ;
6605
+ scope_to_restore = nullptr ; // restored by exception handler
6603
6606
}
6604
6607
}
6605
6608
ctx.builder .CreateCall (prepare_call (jlleave_noexcept_func), {get_current_task (ctx), ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), hand_n_leave)});
6609
+ if (scope_to_restore) {
6610
+ Value *scope_ptr = get_scope_field (ctx);
6611
+ jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe ).decorateInst (
6612
+ ctx.builder .CreateAlignedStore (scope_to_restore, scope_ptr, ctx.types ().alignof_ptr ));
6613
+ }
6606
6614
}
6607
6615
else if (head == jl_pop_exception_sym) {
6608
6616
jl_cgval_t excstack_state = emit_expr (ctx, jl_exprarg (expr, 0 ));
@@ -9652,12 +9660,16 @@ static jl_llvm_functions_t
9652
9660
continue ;
9653
9661
}
9654
9662
Value *scope_boxed = boxed (ctx, scope);
9655
- StoreInst *scope_store = ctx.builder .CreateAlignedStore (scope_boxed, get_scope_field (ctx), ctx.types ().alignof_ptr );
9663
+ Value *scope_ptr = get_scope_field (ctx);
9664
+ LoadInst *current_scope = ctx.builder .CreateAlignedLoad (ctx.types ().T_prjlvalue , scope_ptr, ctx.types ().alignof_ptr );
9665
+ StoreInst *scope_store = ctx.builder .CreateAlignedStore (scope_boxed, scope_ptr, ctx.types ().alignof_ptr );
9666
+ jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe ).decorateInst (current_scope);
9656
9667
jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe ).decorateInst (scope_store);
9657
9668
// GC preserve the scope, since it is not rooted in the `jl_handler_t *`
9658
9669
// and may be removed from jl_current_task by any nested block and then
9659
9670
// replaced later
9660
- ctx.scope_tokens [cursor] = ctx.builder .CreateCall (prepare_call (gc_preserve_begin_func), {scope_boxed});
9671
+ Value *scope_token = ctx.builder .CreateCall (prepare_call (gc_preserve_begin_func), {scope_boxed});
9672
+ ctx.scope_restore [cursor] = std::make_pair (scope_token, current_scope);
9661
9673
}
9662
9674
}
9663
9675
else {
0 commit comments