X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FInterpreter.c;h=ade4ad18edff62143e8eca8aacc8a94bc3933431;hp=16a8e242bdd54c9eecb89a074c2aea2892d2153f;hb=HEAD;hpb=5d52d9b64c21dcf77849866584744722f8121389 diff --git a/rts/Interpreter.c b/rts/Interpreter.c index 16a8e24..ade4ad1 100644 --- a/rts/Interpreter.c +++ b/rts/Interpreter.c @@ -65,13 +65,13 @@ #define BCO_LIT(n) literals[n] #define LOAD_STACK_POINTERS \ - Sp = cap->r.rCurrentTSO->sp; \ + Sp = cap->r.rCurrentTSO->stackobj->sp; \ /* We don't change this ... */ \ - SpLim = cap->r.rCurrentTSO->stack + RESERVED_STACK_WORDS; + SpLim = tso_SpLim(cap->r.rCurrentTSO); #define SAVE_STACK_POINTERS \ ASSERT(Sp > SpLim); \ - cap->r.rCurrentTSO->sp = Sp + cap->r.rCurrentTSO->stackobj->sp = Sp #define RETURN_TO_SCHEDULER(todo,retcode) \ SAVE_STACK_POINTERS; \ @@ -266,7 +266,7 @@ eval_obj: debugBelch("Sp = %p\n", Sp); debugBelch("\n" ); - printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); + printStackChunk(Sp,cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size); debugBelch("\n\n"); ); @@ -276,9 +276,7 @@ eval_obj: switch ( get_itbl(obj)->type ) { case IND: - case IND_OLDGEN: case IND_PERM: - case IND_OLDGEN_PERM: case IND_STATIC: { tagged_obj = ((StgInd*)obj)->indirectee; @@ -383,11 +381,11 @@ do_return: debugBelch("Returning: "); printObj(obj); debugBelch("Sp = %p\n", Sp); debugBelch("\n" ); - printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); + printStackChunk(Sp,cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size); debugBelch("\n\n"); ); - IF_DEBUG(sanity,checkStackChunk(Sp, cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size)); + IF_DEBUG(sanity,checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size)); switch (get_itbl((StgClosure *)Sp)->type) { @@ -468,7 +466,7 @@ do_return: INTERP_TICK(it_retto_other); IF_DEBUG(interpreter, debugBelch("returning to unknown frame -- yielding to sched\n"); - printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); + printStackChunk(Sp,cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size); ); Sp -= 2; Sp[1] = (W_)tagged_obj; @@ -531,8 +529,8 @@ do_return_unboxed: INTERP_TICK(it_retto_other); IF_DEBUG(interpreter, debugBelch("returning to unknown frame -- yielding to sched\n"); - printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); - ); + printStackChunk(Sp,cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size); + ); RETURN_TO_SCHEDULER_NO_PAUSE(ThreadRunGHC, ThreadYielding); } } @@ -886,21 +884,15 @@ run_BCO: // in a reasonable state for the GC and so that // execution of this BCO can continue when we resume ioAction = (StgClosure *) deRefStablePtr (rts_breakpoint_io_action); - Sp -= 9; - Sp[8] = (W_)obj; - Sp[7] = (W_)&stg_apply_interp_info; - Sp[6] = (W_)&stg_noforceIO_info; // see [unreg] below + Sp -= 8; + Sp[7] = (W_)obj; + Sp[6] = (W_)&stg_apply_interp_info; Sp[5] = (W_)new_aps; // the AP_STACK Sp[4] = (W_)BCO_PTR(arg3_freeVars); // the info about local vars of the breakpoint Sp[3] = (W_)False_closure; // True <=> a breakpoint Sp[2] = (W_)&stg_ap_pppv_info; Sp[1] = (W_)ioAction; // apply the IO action to its two arguments above Sp[0] = (W_)&stg_enter_info; // get ready to run the IO action - // Note [unreg]: in unregisterised mode, the return - // convention for IO is different. The - // stg_noForceIO_info stack frame is necessary to - // account for this difference. - // set the flag in the TSO to say that we are now // stopping at a breakpoint so that when we resume // we don't stop on the same breakpoint that we @@ -1364,6 +1356,7 @@ run_BCO: void *tok; int stk_offset = BCO_NEXT; int o_itbl = BCO_NEXT; + int interruptible = BCO_NEXT; void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl); int ret_dyn_size = RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE @@ -1452,7 +1445,7 @@ run_BCO: ((StgRetDyn *)Sp)->payload[0] = (StgClosure *)obj; SAVE_STACK_POINTERS; - tok = suspendThread(&cap->r); + tok = suspendThread(&cap->r, interruptible ? rtsTrue : rtsFalse); // We already made a copy of the arguments above. ffi_call(cif, fn, ret, argptrs); @@ -1461,6 +1454,14 @@ run_BCO: cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - STG_FIELD_OFFSET(Capability,r))); LOAD_STACK_POINTERS; + if (Sp[0] != (W_)&stg_gc_gen_info) { + // the stack is not how we left it. This probably + // means that an exception got raised on exit from the + // foreign call, so we should just continue with + // whatever is on top of the stack now. + RETURN_TO_SCHEDULER_NO_PAUSE(ThreadRunGHC, ThreadYielding); + } + // Re-load the pointer to the BCO from the RET_DYN frame, // it might have moved during the call. Also reload the // pointers to the components of the BCO.