diff options
author | Simon Marlow <marlowsd@gmail.com> | 2016-12-20 14:32:11 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2017-01-06 15:53:36 +0000 |
commit | 3a18baff06abc193569b1b76358da26375b3c8d6 (patch) | |
tree | c80e30dc27fb548eca50b9697d1fdd2a248a891a /rts/Interpreter.c | |
parent | 508811004d1806b28a91c3ff4a5c2247e2ad4655 (diff) | |
download | haskell-3a18baff06abc193569b1b76358da26375b3c8d6.tar.gz |
More fixes for #5654
* In stg_ap_0_fast, if we're evaluating a thunk, the thunk might
evaluate to a function in which case we may have to adjust its CCS.
* The interpreter has its own implementation of stg_ap_0_fast, so we
have to do the same shenanigans with creating empty PAPs and copying
PAPs there.
* GHCi creates Cost Centres as children of CCS_MAIN, which enterFunCCS()
wrongly assumed to imply that they were CAFs. Now we use the is_caf
flag for this, which we have to correctly initialise when we create a
Cost Centre in GHCi.
Diffstat (limited to 'rts/Interpreter.c')
-rw-r--r-- | rts/Interpreter.c | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/rts/Interpreter.c b/rts/Interpreter.c index 7221ff64f9..5a395670b7 100644 --- a/rts/Interpreter.c +++ b/rts/Interpreter.c @@ -214,6 +214,48 @@ void interp_shutdown ( void ) #endif +#ifdef PROFILING + +// +// Build a zero-argument PAP with the current CCS +// See Note [Evaluating functions with profiling] in Apply.cmm +// +STATIC_INLINE +StgClosure * newEmptyPAP (Capability *cap, + StgClosure *tagged_obj, // a FUN or a BCO + uint32_t arity) +{ + StgPAP *pap = (StgPAP *)allocate(cap, sizeofW(StgPAP)); + SET_HDR(pap, &stg_PAP_info, cap->r.rCCCS); + pap->arity = arity; + pap->n_args = 0; + pap->fun = tagged_obj; + return (StgClosure *)pap; +} + +// +// Make an exact copy of a PAP, except that we combine the current CCS with the +// CCS in the PAP. See Note [Evaluating functions with profiling] in Apply.cmm +// +STATIC_INLINE +StgClosure * copyPAP (Capability *cap, StgPAP *oldpap) +{ + uint32_t size = PAP_sizeW(oldpap->n_args); + StgPAP *pap = (StgPAP *)allocate(cap, size); + enterFunCCS(&cap->r, oldpap->header.prof.ccs); + SET_HDR(pap, &stg_PAP_info, cap->r.rCCCS); + pap->arity = oldpap->arity; + pap->n_args = oldpap->n_args; + pap->fun = oldpap->fun; + uint32_t i; + for (i = 0; i < ((StgPAP *)pap)->n_args; i++) { + pap->payload[i] = oldpap->payload[i]; + } + return (StgClosure *)pap; +} + +#endif + static StgWord app_ptrs_itbl[] = { (W_)&stg_ap_p_info, (W_)&stg_ap_pp_info, @@ -343,6 +385,8 @@ eval_obj: case CONSTR_1_1: case CONSTR_0_2: case CONSTR_NOCAF: + break; + case FUN: case FUN_1_0: case FUN_0_1: @@ -350,15 +394,30 @@ eval_obj: case FUN_1_1: case FUN_0_2: case FUN_STATIC: +#ifdef PROFILING + if (cap->r.rCCCS != obj->header.prof.ccs) { + tagged_obj = + newEmptyPAP(cap, tagged_obj, get_fun_itbl(obj)->f.arity); + } +#endif + break; + case PAP: - // already in WHNF +#ifdef PROFILING + if (cap->r.rCCCS != obj->header.prof.ccs) { + tagged_obj = copyPAP(cap, (StgPAP *)obj); + } +#endif break; case BCO: - { ASSERT(((StgBCO *)obj)->arity > 0); +#ifdef PROFILING + if (cap->r.rCCCS != obj->header.prof.ccs) { + tagged_obj = newEmptyPAP(cap, tagged_obj, ((StgBCO *)obj)->arity); + } +#endif break; - } case AP: /* Copied from stg_AP_entry. */ { @@ -380,7 +439,7 @@ eval_obj: // restore the CCCS after evaluating the AP Sp -= 2; Sp[1] = (W_)cap->r.rCCCS; - Sp[0] = (W_)&stg_restore_cccs_info; + Sp[0] = (W_)&stg_restore_cccs_eval_info; #endif Sp -= sizeofW(StgUpdateFrame); @@ -425,7 +484,7 @@ eval_obj: // restore the CCCS after evaluating the closure Sp -= 2; Sp[1] = (W_)cap->r.rCCCS; - Sp[0] = (W_)&stg_restore_cccs_info; + Sp[0] = (W_)&stg_restore_cccs_eval_info; #endif Sp -= 2; Sp[1] = (W_)tagged_obj; @@ -465,7 +524,8 @@ do_return: // NOTE: not using get_itbl(). info = ((StgClosure *)Sp)->header.info; - if (info == (StgInfoTable *)&stg_restore_cccs_info) { + if (info == (StgInfoTable *)&stg_restore_cccs_info || + info == (StgInfoTable *)&stg_restore_cccs_eval_info) { cap->r.rCCCS = (CostCentreStack*)Sp[1]; Sp += 2; goto do_return; |