X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FInterpreter.c;h=74f24540e866f88bcb7abd8a227496eb327f976e;hb=2fe2881b710e6ec1bea2ba71c202c85d76127663;hp=270feb0a0f5e0781e83b97031dff98695b5276bb;hpb=af13609607da81e7837a7c7c598de82452363ab5;p=ghc-hetmet.git diff --git a/ghc/rts/Interpreter.c b/ghc/rts/Interpreter.c index 270feb0..74f2454 100644 --- a/ghc/rts/Interpreter.c +++ b/ghc/rts/Interpreter.c @@ -4,12 +4,7 @@ * Copyright (c) The GHC Team, 1994-2002. * ---------------------------------------------------------------------------*/ -#if !defined(SMP) #include "PosixSource.h" -#else -/* Hack and slash.. */ -#include "Stg.h" -#endif #include "Rts.h" #include "RtsAPI.h" #include "RtsUtils.h" @@ -18,14 +13,21 @@ #include "Schedule.h" #include "RtsFlags.h" #include "Storage.h" +#include "LdvProfile.h" #include "Updates.h" #include "Sanity.h" +#include "Liveness.h" #include "Bytecodes.h" #include "Printer.h" #include "Disassembler.h" #include "Interpreter.h" +#include /* for memcpy */ +#ifdef HAVE_ERRNO_H +#include +#endif + /* -------------------------------------------------------------------------- * The bytecode interpreter @@ -58,13 +60,13 @@ return (retcode); -static inline StgPtr +STATIC_INLINE StgPtr allocate_UPD (int n_words) { return allocate(stg_max(sizeofW(StgHeader)+MIN_UPD_SIZE, n_words)); } -static inline StgPtr +STATIC_INLINE StgPtr allocate_NONUPD (int n_words) { return allocate(stg_max(sizeofW(StgHeader)+MIN_NONUPD_SIZE, n_words)); @@ -110,22 +112,22 @@ void interp_startup ( void ) void interp_shutdown ( void ) { int i, j, k, o_max, i_max, j_max; - fprintf(stderr, "%d constrs entered -> (%d BCO, %d UPD, %d ??? )\n", + debugBelch("%d constrs entered -> (%d BCO, %d UPD, %d ??? )\n", it_retto_BCO + it_retto_UPDATE + it_retto_other, it_retto_BCO, it_retto_UPDATE, it_retto_other ); - fprintf(stderr, "%d total entries, %d unknown entries \n", + debugBelch("%d total entries, %d unknown entries \n", it_total_entries, it_total_unknown_entries); for (i = 0; i < N_CLOSURE_TYPES; i++) { if (it_unknown_entries[i] == 0) continue; - fprintf(stderr, " type %2d: unknown entries (%4.1f%%) == %d\n", + debugBelch(" type %2d: unknown entries (%4.1f%%) == %d\n", i, 100.0 * ((double)it_unknown_entries[i]) / ((double)it_total_unknown_entries), it_unknown_entries[i]); } - fprintf(stderr, "%d insns, %d slides, %d BCO_entries\n", + debugBelch("%d insns, %d slides, %d BCO_entries\n", it_insns, it_slides, it_BCO_entries); for (i = 0; i < 27; i++) - fprintf(stderr, "opcode %2d got %d\n", i, it_ofreq[i] ); + debugBelch("opcode %2d got %d\n", i, it_ofreq[i] ); for (k = 1; k < 20; k++) { o_max = 0; @@ -139,7 +141,7 @@ void interp_shutdown ( void ) } } - fprintf ( stderr, "%d: count (%4.1f%%) %6d is %d then %d\n", + debugBelch("%d: count (%4.1f%%) %6d is %d then %d\n", k, ((double)o_max) * 100.0 / ((double)it_insns), o_max, i_max, j_max ); it_oofreq[i_max][j_max] = 0; @@ -160,7 +162,6 @@ static StgWord app_ptrs_itbl[] = { (W_)&stg_ap_pppp_info, (W_)&stg_ap_ppppp_info, (W_)&stg_ap_pppppp_info, - (W_)&stg_ap_ppppppp_info }; StgThreadReturnCode @@ -228,14 +229,14 @@ eval_obj: INTERP_TICK(it_total_evals); IF_DEBUG(interpreter, - fprintf(stderr, + debugBelch( "\n---------------------------------------------------------------\n"); - fprintf(stderr,"Evaluating: "); printObj(obj); - fprintf(stderr,"Sp = %p\n", Sp); - fprintf(stderr, "\n" ); + debugBelch("Evaluating: "); printObj(obj); + debugBelch("Sp = %p\n", Sp); + debugBelch("\n" ); printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); - fprintf(stderr, "\n\n"); + debugBelch("\n\n"); ); IF_DEBUG(sanity,checkStackChunk(Sp, cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size)); @@ -274,7 +275,7 @@ eval_obj: break; case BCO: - ASSERT(BCO_ARITY(obj) > 0); + ASSERT(((StgBCO *)obj)->arity > 0); break; case AP: /* Copied from stg_AP_entry. */ @@ -327,7 +328,7 @@ eval_obj: { // Can't handle this object; yield to scheduler IF_DEBUG(interpreter, - fprintf(stderr, "evaluating unknown closure -- yielding to sched\n"); + debugBelch("evaluating unknown closure -- yielding to sched\n"); printObj(obj); ); Sp -= 2; @@ -344,13 +345,13 @@ do_return: ASSERT(closure_HNF(obj)); IF_DEBUG(interpreter, - fprintf(stderr, + debugBelch( "\n---------------------------------------------------------------\n"); - fprintf(stderr,"Returning: "); printObj(obj); - fprintf(stderr,"Sp = %p\n", Sp); - fprintf(stderr, "\n" ); + debugBelch("Returning: "); printObj(obj); + debugBelch("Sp = %p\n", Sp); + debugBelch("\n" ); printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); - fprintf(stderr, "\n\n"); + debugBelch("\n\n"); ); IF_DEBUG(sanity,checkStackChunk(Sp, cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size)); @@ -395,9 +396,6 @@ do_return: if (info == (StgInfoTable *)&stg_ap_pppppp_info) { n = 6; m = 6; goto do_apply; } - if (info == (StgInfoTable *)&stg_ap_ppppppp_info) { - n = 7; m = 7; goto do_apply; - } goto do_return_unrecognised; } @@ -425,7 +423,7 @@ do_return: // Can't handle this return address; yield to scheduler INTERP_TICK(it_retto_other); IF_DEBUG(interpreter, - fprintf(stderr, "returning to unknown frame -- yielding to sched\n"); + debugBelch("returning to unknown frame -- yielding to sched\n"); printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); ); Sp -= 2; @@ -488,7 +486,7 @@ do_return_unboxed: // Can't handle this return address; yield to scheduler INTERP_TICK(it_retto_other); IF_DEBUG(interpreter, - fprintf(stderr, "returning to unknown frame -- yielding to sched\n"); + debugBelch("returning to unknown frame -- yielding to sched\n"); printStackChunk(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size); ); RETURN_TO_SCHEDULER(ThreadRunGHC, ThreadYielding); @@ -576,7 +574,7 @@ do_apply: nat arity, i; Sp++; - arity = BCO_ARITY(obj); + arity = ((StgBCO *)obj)->arity; ASSERT(arity > 0); if (arity < n) { // n must be greater than 1, and the only kinds of @@ -718,7 +716,7 @@ run_BCO: { register int bciPtr = 1; /* instruction pointer */ register StgBCO* bco = (StgBCO*)obj; - register StgWord16* instrs = (StgWord16*)(BCO_INSTRS(bco)); + register StgWord16* instrs = (StgWord16*)(bco->instrs->payload); register StgWord* literals = (StgWord*)(&bco->literals->payload[0]); register StgPtr* ptrs = (StgPtr*)(&bco->ptrs->payload[0]); register StgInfoTable** itbls = (StgInfoTable**) @@ -732,18 +730,18 @@ run_BCO: ASSERT(bciPtr <= instrs[0]); IF_DEBUG(interpreter, //if (do_print_stack) { - //fprintf(stderr, "\n-- BEGIN stack\n"); + //debugBelch("\n-- BEGIN stack\n"); //printStack(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size,iSu); - //fprintf(stderr, "-- END stack\n\n"); + //debugBelch("-- END stack\n\n"); //} - fprintf(stderr,"Sp = %p pc = %d ", Sp, bciPtr); + debugBelch("Sp = %p pc = %d ", Sp, bciPtr); disInstr(bco,bciPtr); if (0) { int i; - fprintf(stderr,"\n"); + debugBelch("\n"); for (i = 8; i >= 0; i--) { - fprintf(stderr, "%d %p\n", i, (StgPtr)(*(Sp+i))); + debugBelch("%d %p\n", i, (StgPtr)(*(Sp+i))); } - fprintf(stderr,"\n"); + debugBelch("\n"); } //if (do_print_stack) checkStack(Sp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size,iSu); ); @@ -810,7 +808,7 @@ run_BCO: case bci_PUSH_ALTS: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_R1p_info; + Sp[-2] = (W_)&stg_ctoi_R1p_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -818,7 +816,7 @@ run_BCO: case bci_PUSH_ALTS_P: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_R1unpt_info; + Sp[-2] = (W_)&stg_ctoi_R1unpt_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -826,7 +824,7 @@ run_BCO: case bci_PUSH_ALTS_N: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_R1n_info; + Sp[-2] = (W_)&stg_ctoi_R1n_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -834,7 +832,7 @@ run_BCO: case bci_PUSH_ALTS_F: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_F1_info; + Sp[-2] = (W_)&stg_ctoi_F1_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -842,7 +840,7 @@ run_BCO: case bci_PUSH_ALTS_D: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_D1_info; + Sp[-2] = (W_)&stg_ctoi_D1_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -850,7 +848,7 @@ run_BCO: case bci_PUSH_ALTS_L: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_L1_info; + Sp[-2] = (W_)&stg_ctoi_L1_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -858,7 +856,7 @@ run_BCO: case bci_PUSH_ALTS_V: { int o_bco = BCO_NEXT; - Sp[-2] = (W_)&stg_ctoi_ret_V_info; + Sp[-2] = (W_)&stg_ctoi_V_info; Sp[-1] = BCO_PTR(o_bco); Sp -= 2; goto nextInsn; @@ -897,9 +895,6 @@ run_BCO: case bci_PUSH_APPLY_PPPPPP: Sp--; Sp[0] = (W_)&stg_ap_pppppp_info; goto nextInsn; - case bci_PUSH_APPLY_PPPPPPP: - Sp--; Sp[0] = (W_)&stg_ap_ppppppp_info; - goto nextInsn; case bci_PUSH_UBX: { int i; @@ -926,7 +921,7 @@ run_BCO: case bci_ALLOC_AP: { StgAP* ap; - int n_payload = BCO_NEXT - 1; + int n_payload = BCO_NEXT; int request = PAP_sizeW(n_payload); ap = (StgAP*)allocate_UPD(request); Sp[-1] = (W_)ap; @@ -939,7 +934,7 @@ run_BCO: case bci_ALLOC_PAP: { StgPAP* pap; int arity = BCO_NEXT; - int n_payload = BCO_NEXT - 1; + int n_payload = BCO_NEXT; int request = PAP_sizeW(n_payload); pap = (StgPAP*)allocate_NONUPD(request); Sp[-1] = (W_)pap; @@ -953,7 +948,7 @@ run_BCO: case bci_MKAP: { int i; int stkoff = BCO_NEXT; - int n_payload = BCO_NEXT - 1; + int n_payload = BCO_NEXT; StgAP* ap = (StgAP*)Sp[stkoff]; ASSERT((int)ap->n_args == n_payload); ap->fun = (StgClosure*)Sp[0]; @@ -968,7 +963,7 @@ run_BCO: ap->payload[i] = (StgClosure*)Sp[i+1]; Sp += n_payload+1; IF_DEBUG(interpreter, - fprintf(stderr,"\tBuilt "); + debugBelch("\tBuilt "); printObj((StgClosure*)ap); ); goto nextInsn; @@ -1003,7 +998,7 @@ run_BCO: Sp --; Sp[0] = (W_)con; IF_DEBUG(interpreter, - fprintf(stderr,"\tBuilt "); + debugBelch("\tBuilt "); printObj((StgClosure*)con); ); goto nextInsn; @@ -1013,7 +1008,7 @@ run_BCO: int discr = BCO_NEXT; int failto = BCO_NEXT; StgClosure* con = (StgClosure*)Sp[0]; - if (constrTag(con) >= discr) { + if (GET_TAG(con) >= discr) { bciPtr = failto; } goto nextInsn; @@ -1023,7 +1018,7 @@ run_BCO: int discr = BCO_NEXT; int failto = BCO_NEXT; StgClosure* con = (StgClosure*)Sp[0]; - if (constrTag(con) != discr) { + if (GET_TAG(con) != discr) { bciPtr = failto; } goto nextInsn; @@ -1157,7 +1152,23 @@ run_BCO: int stk_offset = BCO_NEXT; int o_itbl = BCO_NEXT; void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl); - StgTSO *tso = cap->r.rCurrentTSO; + int ret_dyn_size = + RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE + + sizeofW(StgRetDyn); + +#ifdef RTS_SUPPORTS_THREADS + // Threaded RTS: + // Arguments on the TSO stack are not good, because garbage + // collection might move the TSO as soon as we call + // suspendThread below. + + 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; // There are a bunch of non-ptr words on the stack (the // ccall args, the ccall fun address and space for the @@ -1169,28 +1180,43 @@ run_BCO: // CCALL instruction. So we build a RET_DYN stack frame // on the stack frame to describe this chunk of stack. // - Sp -= RET_DYN_SIZE + sizeofW(StgRetDyn); - ((StgRetDyn *)Sp)->liveness = ALL_NON_PTRS | N_NONPTRS(stk_offset); + Sp -= ret_dyn_size; + ((StgRetDyn *)Sp)->liveness = NO_PTRS | N_NONPTRS(stk_offset); ((StgRetDyn *)Sp)->info = (StgInfoTable *)&stg_gc_gen_info; SAVE_STACK_POINTERS; - tok = suspendThread(&cap->r,rtsFalse); + tok = suspendThread(&cap->r); +#ifndef RTS_SUPPORTS_THREADS // Careful: // suspendThread might have shifted the stack // around (stack squeezing), so we have to grab the real // Sp out of the TSO to find the ccall args again. - // We don't own the capability anymore, so we mustn't use it. - // Instead, we have to save the TSO ptr beforehand. - // Also note that GC may strike at any time now (from another thread). - // FIXME - DANGER!! Can GC move our TSO? - // If so, we have to copy the args elsewhere! - marshall_fn ( (void*)(tso->sp + RET_DYN_SIZE + sizeofW(StgRetDyn)) ); - + + marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + ret_dyn_size) ); +#else + // Threaded RTS: + // We already made a copy of the arguments above. + + marshall_fn ( arguments ); +#endif + // And restart the thread again, popping the RET_DYN frame. - cap = (Capability *)((void *)resumeThread(tok,rtsFalse) - sizeof(StgFunTable)); + cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - sizeof(StgFunTable))); LOAD_STACK_POINTERS; - Sp += RET_DYN_SIZE + sizeofW(StgRetDyn); + Sp += ret_dyn_size; + + // Save the Haskell thread's current value of errno + cap->r.rCurrentTSO->saved_errno = errno; + +#ifdef RTS_SUPPORTS_THREADS + // Threaded RTS: + // Copy the "arguments", which might include a return value, + // back to the TSO stack. It would of course be enough to + // just copy the return value, but we don't know the offset. + memcpy(Sp, arguments, sizeof(W_) * stk_offset); +#endif + goto nextInsn; }