diff options
Diffstat (limited to 'rts/Interpreter.c')
-rw-r--r-- | rts/Interpreter.c | 143 |
1 files changed, 141 insertions, 2 deletions
diff --git a/rts/Interpreter.c b/rts/Interpreter.c index 6929aec5fd..efbfd091d8 100644 --- a/rts/Interpreter.c +++ b/rts/Interpreter.c @@ -4,6 +4,7 @@ * Copyright (c) The GHC Team, 1994-2002. * ---------------------------------------------------------------------------*/ + #include "PosixSource.h" #include "Rts.h" #include "RtsAPI.h" @@ -681,12 +682,13 @@ do_return_unboxed: || SpW(0) == (W_)&stg_ret_f_info || SpW(0) == (W_)&stg_ret_d_info || SpW(0) == (W_)&stg_ret_l_info + || SpW(0) == (W_)&stg_ret_t_info ); IF_DEBUG(interpreter, debugBelch( "\n---------------------------------------------------------------\n"); - debugBelch("Returning: "); printObj(obj); + debugBelch("Returning unboxed\n"); debugBelch("Sp = %p\n", Sp); #if defined(PROFILING) fprintCCS(stderr, cap->r.rCCCS); @@ -697,7 +699,7 @@ do_return_unboxed: debugBelch("\n\n"); ); - // get the offset of the stg_ctoi_ret_XXX itbl + // get the offset of the header of the next stack frame offset = stack_frame_sizeW((StgClosure *)Sp); switch (get_itbl((StgClosure*)(Sp_plusW(offset)))->type) { @@ -934,6 +936,43 @@ run_BCO_return_unboxed: // Stack checks aren't necessary at return points, the stack use // is aggregated into the enclosing function entry point. +#if defined(PROFILING) + /* + Restore the current cost centre stack if a tuple is being returned. + + When a "simple" unboxed value is returned, the cccs is restored with + an stg_restore_cccs frame on the stack, for example: + + ... + stg_ctoi_D1 + <CCCS> + stg_restore_cccs + + But stg_restore_cccs cannot deal with tuples, which may have more + things on the stack. Therefore we store the CCCS inside the + stg_ctoi_t frame. + + If we have a tuple being returned, the stack looks like this: + + ... + <CCCS> <- to restore, Sp offset <next frame + 4 words> + tuple_BCO + tuple_info + cont_BCO + stg_ctoi_t <- next frame + tuple_data_1 + ... + tuple_data_n + tuple_info + tuple_BCO + stg_ret_t <- Sp + */ + + if(SpW(0) == (W_)&stg_ret_t_info) { + cap->r.rCCCS = (CostCentreStack*)SpW(stack_frame_sizeW((StgClosure *)Sp) + 4); + } +#endif + goto run_BCO; run_BCO_fun: @@ -1329,6 +1368,100 @@ run_BCO: goto nextInsn; } + case bci_PUSH_ALTS_T: { + int o_bco = BCO_GET_LARGE_ARG; + W_ tuple_info = (W_)BCO_LIT(BCO_GET_LARGE_ARG); + int o_tuple_bco = BCO_GET_LARGE_ARG; + +#if defined(PROFILING) + SpW(-1) = (W_)cap->r.rCCCS; + Sp_subW(1); +#endif + + SpW(-1) = BCO_PTR(o_tuple_bco); + SpW(-2) = tuple_info; + SpW(-3) = BCO_PTR(o_bco); + W_ ctoi_t_offset; + int tuple_stack_words = tuple_info & 0x3fff; + switch(tuple_stack_words) { + case 0: ctoi_t_offset = (W_)&stg_ctoi_t0_info; break; + case 1: ctoi_t_offset = (W_)&stg_ctoi_t1_info; break; + case 2: ctoi_t_offset = (W_)&stg_ctoi_t2_info; break; + case 3: ctoi_t_offset = (W_)&stg_ctoi_t3_info; break; + case 4: ctoi_t_offset = (W_)&stg_ctoi_t4_info; break; + case 5: ctoi_t_offset = (W_)&stg_ctoi_t5_info; break; + case 6: ctoi_t_offset = (W_)&stg_ctoi_t6_info; break; + case 7: ctoi_t_offset = (W_)&stg_ctoi_t7_info; break; + case 8: ctoi_t_offset = (W_)&stg_ctoi_t8_info; break; + case 9: ctoi_t_offset = (W_)&stg_ctoi_t9_info; break; + + case 10: ctoi_t_offset = (W_)&stg_ctoi_t10_info; break; + case 11: ctoi_t_offset = (W_)&stg_ctoi_t11_info; break; + case 12: ctoi_t_offset = (W_)&stg_ctoi_t12_info; break; + case 13: ctoi_t_offset = (W_)&stg_ctoi_t13_info; break; + case 14: ctoi_t_offset = (W_)&stg_ctoi_t14_info; break; + case 15: ctoi_t_offset = (W_)&stg_ctoi_t15_info; break; + case 16: ctoi_t_offset = (W_)&stg_ctoi_t16_info; break; + case 17: ctoi_t_offset = (W_)&stg_ctoi_t17_info; break; + case 18: ctoi_t_offset = (W_)&stg_ctoi_t18_info; break; + case 19: ctoi_t_offset = (W_)&stg_ctoi_t19_info; break; + + case 20: ctoi_t_offset = (W_)&stg_ctoi_t20_info; break; + case 21: ctoi_t_offset = (W_)&stg_ctoi_t21_info; break; + case 22: ctoi_t_offset = (W_)&stg_ctoi_t22_info; break; + case 23: ctoi_t_offset = (W_)&stg_ctoi_t23_info; break; + case 24: ctoi_t_offset = (W_)&stg_ctoi_t24_info; break; + case 25: ctoi_t_offset = (W_)&stg_ctoi_t25_info; break; + case 26: ctoi_t_offset = (W_)&stg_ctoi_t26_info; break; + case 27: ctoi_t_offset = (W_)&stg_ctoi_t27_info; break; + case 28: ctoi_t_offset = (W_)&stg_ctoi_t28_info; break; + case 29: ctoi_t_offset = (W_)&stg_ctoi_t29_info; break; + + case 30: ctoi_t_offset = (W_)&stg_ctoi_t30_info; break; + case 31: ctoi_t_offset = (W_)&stg_ctoi_t31_info; break; + case 32: ctoi_t_offset = (W_)&stg_ctoi_t32_info; break; + case 33: ctoi_t_offset = (W_)&stg_ctoi_t33_info; break; + case 34: ctoi_t_offset = (W_)&stg_ctoi_t34_info; break; + case 35: ctoi_t_offset = (W_)&stg_ctoi_t35_info; break; + case 36: ctoi_t_offset = (W_)&stg_ctoi_t36_info; break; + case 37: ctoi_t_offset = (W_)&stg_ctoi_t37_info; break; + case 38: ctoi_t_offset = (W_)&stg_ctoi_t38_info; break; + case 39: ctoi_t_offset = (W_)&stg_ctoi_t39_info; break; + + case 40: ctoi_t_offset = (W_)&stg_ctoi_t40_info; break; + case 41: ctoi_t_offset = (W_)&stg_ctoi_t41_info; break; + case 42: ctoi_t_offset = (W_)&stg_ctoi_t42_info; break; + case 43: ctoi_t_offset = (W_)&stg_ctoi_t43_info; break; + case 44: ctoi_t_offset = (W_)&stg_ctoi_t44_info; break; + case 45: ctoi_t_offset = (W_)&stg_ctoi_t45_info; break; + case 46: ctoi_t_offset = (W_)&stg_ctoi_t46_info; break; + case 47: ctoi_t_offset = (W_)&stg_ctoi_t47_info; break; + case 48: ctoi_t_offset = (W_)&stg_ctoi_t48_info; break; + case 49: ctoi_t_offset = (W_)&stg_ctoi_t49_info; break; + + case 50: ctoi_t_offset = (W_)&stg_ctoi_t50_info; break; + case 51: ctoi_t_offset = (W_)&stg_ctoi_t51_info; break; + case 52: ctoi_t_offset = (W_)&stg_ctoi_t52_info; break; + case 53: ctoi_t_offset = (W_)&stg_ctoi_t53_info; break; + case 54: ctoi_t_offset = (W_)&stg_ctoi_t54_info; break; + case 55: ctoi_t_offset = (W_)&stg_ctoi_t55_info; break; + case 56: ctoi_t_offset = (W_)&stg_ctoi_t56_info; break; + case 57: ctoi_t_offset = (W_)&stg_ctoi_t57_info; break; + case 58: ctoi_t_offset = (W_)&stg_ctoi_t58_info; break; + case 59: ctoi_t_offset = (W_)&stg_ctoi_t59_info; break; + + case 60: ctoi_t_offset = (W_)&stg_ctoi_t60_info; break; + case 61: ctoi_t_offset = (W_)&stg_ctoi_t61_info; break; + case 62: ctoi_t_offset = (W_)&stg_ctoi_t62_info; break; + + default: barf("unsupported tuple size %d", tuple_stack_words); + } + + SpW(-4) = ctoi_t_offset; + Sp_subW(4); + goto nextInsn; + } + case bci_PUSH_APPLY_N: Sp_subW(1); SpW(0) = (W_)&stg_ap_n_info; goto nextInsn; @@ -1708,6 +1841,12 @@ run_BCO: Sp_subW(1); SpW(0) = (W_)&stg_ret_v_info; goto do_return_unboxed; + case bci_RETURN_T: { + /* tuple_info and tuple_bco must already be on the stack */ + Sp_subW(1); + SpW(0) = (W_)&stg_ret_t_info; + goto do_return_unboxed; + } case bci_SWIZZLE: { int stkoff = BCO_NEXT; |