Ticket #8590: 0001-Move-the-allocation-of-CAF-blackholes-into-newCAF.patch

File 0001-Move-the-allocation-of-CAF-blackholes-into-newCAF.patch, 8.0 KB (added by parcs, 18 months ago)
  • compiler/codeGen/StgCmmBind.hs

    From 9a15fb7c8bd4fb225ed3198e41f86028d364dfec Mon Sep 17 00:00:00 2001
    From: Patrick Palka <[email protected]>
    Date: Sun, 1 Dec 2013 21:17:43 -0500
    Subject: [PATCH] Move the allocation of CAF blackholes into 'newCAF'
    
    We now do the allocation of the blackhole indirection closure inside the
    RTS procedure 'newCAF' instead of generating the allocation code inline
    in the closure body of each CAF.  This slightly decreases code size in
    modules with a lot of CAFs.
    
    As a result of this change, for example, the size of DynFlags.o drops by
    ~60KB and HsExpr.o by ~100KB.
    ---
     compiler/codeGen/StgCmmBind.hs | 40 ++++++++++------------------------------
     includes/rts/storage/GC.h      |  4 ++--
     rts/sm/Storage.c               | 40 +++++++++++++++++++++++++++-------------
     3 files changed, 39 insertions(+), 45 deletions(-)
    
    diff --git a/compiler/codeGen/StgCmmBind.hs b/compiler/codeGen/StgCmmBind.hs
    index 64772c6..05aae0a 100644
    a b import StgCmmEnv 
    2121import StgCmmCon 
    2222import StgCmmHeap 
    2323import StgCmmProf (curCCS, ldvEnterClosure, enterCostCentreFun, enterCostCentreThunk, 
    24                    initUpdFrameProf, costCentreFrom) 
     24                   initUpdFrameProf) 
    2525import StgCmmTicky 
    2626import StgCmmLayout 
    2727import StgCmmUtils 
    emitUpdateFrame dflags frame lbl updatee = do 
    718718-- (which Hugs needs to do in order that combined mode works right.) 
    719719-- 
    720720 
    721 -- ToDo [Feb 04]  This entire link_caf nonsense could all be moved 
    722 -- into the "newCAF" RTS procedure, which we call anyway, including 
    723 -- the allocation of the black-hole indirection closure. 
    724 -- That way, code size would fall, the CAF-handling code would 
    725 -- be closer together, and the compiler wouldn't need to know 
    726 -- about off_indirectee etc. 
    727  
    728721link_caf :: LocalReg           -- pointer to the closure 
    729722         -> Bool               -- True <=> updatable, False <=> single-entry 
    730723         -> FCode CmmExpr      -- Returns amode for closure to be updated 
    link_caf :: LocalReg -- pointer to the closure 
    736729-- so that generational GC is easier. 
    737730link_caf node _is_upd = do 
    738731  { dflags <- getDynFlags 
    739     -- Alloc black hole specifying CC_HDR(Node) as the cost centre 
    740   ; let use_cc   = costCentreFrom dflags (CmmReg nodeReg) 
    741         blame_cc = use_cc 
    742         tso      = CmmReg (CmmGlobal CurrentTSO) 
    743  
    744   ; hp_rel <- allocDynClosureCmm Nothing cafBlackHoleInfoTable mkLFBlackHole 
    745                                          use_cc blame_cc [(tso,fixedHdrSize dflags)] 
    746         -- small optimisation: we duplicate the hp_rel expression in 
    747         -- both the newCAF call and the value returned below. 
    748         -- If we instead used allocDynClosureReg which assigns it to a reg, 
    749         -- then the reg is live across the newCAF call and gets spilled, 
    750         -- which is stupid.  Really we should have an optimisation pass to 
    751         -- fix this, but we don't yet. --SDM 
    752  
    753732        -- Call the RTS function newCAF to add the CAF to the CafList 
    754733        -- so that the garbage collector can find them 
    755734        -- This must be done *before* the info table pointer is overwritten, 
    756735        -- because the old info table ptr is needed for reversion 
    757   ; ret <- newTemp (bWord dflags) 
    758   ; emitRtsCallGen [(ret,NoHint)] (mkForeignLabel (fsLit "newCAF") Nothing ForeignLabelInExternalPackage IsFunction) 
     736  ; let newCAF_lbl = mkForeignLabel (fsLit "newCAF") Nothing 
     737                                    ForeignLabelInExternalPackage IsFunction 
     738  ; bh <- newTemp (bWord dflags) 
     739  ; emitRtsCallGen [(bh,AddrHint)] newCAF_lbl 
    759740      [ (CmmReg (CmmGlobal BaseReg),  AddrHint), 
    760         (CmmReg (CmmLocal node), AddrHint), 
    761         (hp_rel, AddrHint) ] 
     741        (CmmReg (CmmLocal node), AddrHint) ] 
    762742      False 
    763743 
    764744  -- see Note [atomic CAF entry] in rts/sm/Storage.c 
    765745  ; updfr  <- getUpdFrameOff 
     746  ; let target = entryCode dflags (closureInfoPtr dflags (CmmReg (CmmLocal node))) 
    766747  ; emit =<< mkCmmIfThen 
    767       (CmmMachOp (mo_wordEq dflags) [ CmmReg (CmmLocal ret), CmmLit (zeroCLit dflags)]) 
     748      (cmmEqWord dflags (CmmReg (CmmLocal bh)) (zeroExpr dflags)) 
    768749        -- re-enter the CAF 
    769        (let target = entryCode dflags (closureInfoPtr dflags (CmmReg (CmmLocal node))) in 
    770         mkJump dflags NativeNodeCall target [] updfr) 
     750       (mkJump dflags NativeNodeCall target [] updfr) 
    771751 
    772   ; return hp_rel } 
     752  ; return (CmmReg (CmmLocal bh)) } 
    773753 
    774754------------------------------------------------------------------------ 
    775755--              Profiling 
  • includes/rts/storage/GC.h

    diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
    index f8b8afe..63a9594 100644
    a b void performMajorGC(void); 
    181181   The CAF table - used to let us revert CAFs in GHCi 
    182182   -------------------------------------------------------------------------- */ 
    183183 
    184 StgWord newCAF    (StgRegTable *reg, StgIndStatic *caf, StgClosure *bh); 
    185 StgWord newDynCAF (StgRegTable *reg, StgIndStatic *caf, StgClosure *bh); 
     184StgInd *newCAF    (StgRegTable *reg, StgIndStatic *caf); 
     185StgInd *newDynCAF (StgRegTable *reg, StgIndStatic *caf); 
    186186void revertCAFs (void); 
    187187 
    188188// Request that all CAFs are retained indefinitely. 
  • rts/sm/Storage.c

    diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
    index b5f3202..68d2c70 100644
    a b freeStorage (rtsBool free_heap) 
    333333 
    334334   -------------------------------------------------------------------------- */ 
    335335 
    336 STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh) 
     336STATIC_INLINE StgInd * 
     337lockCAF (StgRegTable *reg, StgIndStatic *caf) 
    337338{ 
    338339    const StgInfoTable *orig_info; 
     340    Capability *cap = regTableToCapability(reg); 
     341    StgInd *bh; 
    339342 
    340343    orig_info = caf->header.info; 
    341344 
    STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh) 
    345348    if (orig_info == &stg_IND_STATIC_info || 
    346349        orig_info == &stg_WHITEHOLE_info) { 
    347350        // already claimed by another thread; re-enter the CAF 
    348         return 0; 
     351        return NULL; 
    349352    } 
    350353 
    351354    cur_info = (const StgInfoTable *) 
    STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh) 
    355358 
    356359    if (cur_info != orig_info) { 
    357360        // already claimed by another thread; re-enter the CAF 
    358         return 0; 
     361        return NULL; 
    359362    } 
    360363 
    361364    // successfully claimed by us; overwrite with IND_STATIC 
    STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh) 
    364367    // For the benefit of revertCAFs(), save the original info pointer 
    365368    caf->saved_info = orig_info; 
    366369 
    367     caf->indirectee = bh; 
     370    // Allocate the blackhole indirection closure 
     371    bh = (StgInd *)allocate(cap, sizeofW(*bh)); 
     372    bh->header.info = &stg_CAF_BLACKHOLE_info; 
     373    bh->indirectee = (StgClosure *)cap->r.rCurrentTSO; 
     374 
     375    caf->indirectee = (StgClosure *)bh; 
    368376    write_barrier(); 
    369377    SET_INFO((StgClosure*)caf,&stg_IND_STATIC_info); 
    370378 
    371     return 1; 
     379    return bh; 
    372380} 
    373381 
    374 StgWord 
    375 newCAF(StgRegTable *reg, StgIndStatic *caf, StgClosure *bh) 
     382StgInd * 
     383newCAF(StgRegTable *reg, StgIndStatic *caf) 
    376384{ 
    377     if (lockCAF(caf,bh) == 0) return 0; 
     385    StgInd *bh; 
     386 
     387    bh = lockCAF(reg, caf); 
     388    if (!bh) return NULL; 
    378389 
    379390    if(keepCAFs) 
    380391    { 
    newCAF(StgRegTable *reg, StgIndStatic *caf, StgClosure *bh) 
    418429#endif 
    419430    } 
    420431 
    421     return 1; 
     432    return bh; 
    422433} 
    423434 
    424435// External API for setting the keepCAFs flag. see #3900. 
    setKeepCAFs (void) 
    437448// 
    438449// The linker hackily arranges that references to newCaf from dynamic 
    439450// code end up pointing to newDynCAF. 
    440 StgWord 
    441 newDynCAF (StgRegTable *reg STG_UNUSED, StgIndStatic *caf, StgClosure *bh) 
     451StgInd * 
     452newDynCAF (StgRegTable *reg, StgIndStatic *caf) 
    442453{ 
    443     if (lockCAF(caf,bh) == 0) return 0; 
     454    StgInd *bh; 
     455 
     456    bh = lockCAF(reg, caf); 
     457    if (!bh) return NULL; 
    444458 
    445459    ACQUIRE_SM_LOCK; 
    446460 
    newDynCAF (StgRegTable *reg STG_UNUSED, StgIndStatic *caf, StgClosure *bh) 
    449463 
    450464    RELEASE_SM_LOCK; 
    451465 
    452     return 1; 
     466    return bh; 
    453467} 
    454468 
    455469/* -----------------------------------------------------------------------------