X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FInterpreter.c;h=1a6e9273e0ec33773332c46be2a5fe60624ca121;hb=a8e1e190ee5aa16f31bdde26daf3c897314e8994;hp=39628569c0df925bcd040c21de11162278d3b1a7;hpb=937eb1f1386f12c729c6d819417fe81bc4786b9f;p=ghc-hetmet.git diff --git a/rts/Interpreter.c b/rts/Interpreter.c index 3962856..1a6e927 100644 --- a/rts/Interpreter.c +++ b/rts/Interpreter.c @@ -28,9 +28,7 @@ #include #endif -#ifdef USE_LIBFFI -#include -#endif +#include "ffi.h" /* -------------------------------------------------------------------------- * The bytecode interpreter @@ -65,6 +63,7 @@ SpLim = cap->r.rCurrentTSO->stack + RESERVED_STACK_WORDS; #define SAVE_STACK_POINTERS \ + ASSERT(Sp > SpLim); \ cap->r.rCurrentTSO->sp = Sp #define RETURN_TO_SCHEDULER(todo,retcode) \ @@ -197,6 +196,9 @@ interpretBCO (Capability* cap) LOAD_STACK_POINTERS; + cap->r.rHpLim = (P_)1; // HpLim is the context-switch flag; when it + // goes to zero we must return to the scheduler. + // ------------------------------------------------------------------------ // Case 1: // @@ -551,6 +553,16 @@ do_apply: goto defer_apply_to_sched; } + // Stack check: we're about to unpack the PAP onto the + // stack. The (+1) is for the (arity < n) case, where we + // also need space for an extra info pointer. + if (Sp - (pap->n_args + 1) < SpLim) { + Sp -= 2; + Sp[1] = (W_)tagged_obj; + Sp[0] = (W_)&stg_enter_info; + RETURN_TO_SCHEDULER(ThreadInterpret, StackOverflow); + } + Sp++; arity = pap->arity; ASSERT(arity > 0); @@ -1272,7 +1284,7 @@ run_BCO: // context switching: sometimes the scheduler can invoke // the interpreter with context_switch == 1, particularly // if the -C0 flag has been given on the cmd line. - if (context_switch) { + if (cap->r.rHpLim == NULL) { Sp--; Sp[0] = (W_)&stg_enter_info; RETURN_TO_SCHEDULER(ThreadInterpret, ThreadYielding); } @@ -1347,7 +1359,6 @@ run_BCO: So we make a copy of the argument block. */ -#ifdef USE_LIBFFI #define ROUND_UP_WDS(p) ((((StgWord)(p)) + sizeof(W_)-1)/sizeof(W_)) ffi_cif *cif = (ffi_cif *)marshall_fn; @@ -1384,10 +1395,6 @@ run_BCO: // this is the function we're going to call fn = (void(*)(void))Sp[ret_size]; -#else - W_ arguments[stk_offset]; - memcpy(arguments, Sp, sizeof(W_) * stk_offset); -#endif // Restore the Haskell thread's current value of errno errno = cap->r.rCurrentTSO->saved_errno; @@ -1415,14 +1422,10 @@ run_BCO: tok = suspendThread(&cap->r); // We already made a copy of the arguments above. -#ifdef USE_LIBFFI ffi_call(cif, fn, ret, argptrs); -#else - marshall_fn ( arguments ); -#endif // And restart the thread again, popping the RET_DYN frame. - cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - sizeof(StgFunTable))); + cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - FIELD_OFFSET(Capability,r))); LOAD_STACK_POINTERS; // Re-load the pointer to the BCO from the RET_DYN frame, @@ -1441,11 +1444,7 @@ run_BCO: // Copy the return value back to the TSO stack. It is at // most 2 words large, and resides at arguments[0]. -#ifdef USE_LIBFFI memcpy(Sp, ret, sizeof(W_) * stg_min(stk_offset,ret_size)); -#else - memcpy(Sp, arguments, sizeof(W_) * stg_min(stk_offset,2)); -#endif goto nextInsn; }