- -- If the sequel is an update frame, we might be able to
- -- do update in place...
- UpdateCode
- | not (isNullaryDataCon con) -- no nullary constructors, please
- && not (any isFollowableRep (map getAmodeRep amodes))
- -- no ptrs please (generational gc...)
- && closureSize closure_info <= mIN_UPD_SIZE
- -- don't know the real size of the
- -- thunk, so assume mIN_UPD_SIZE
-
- -> -- get a new temporary and make it point to the updatee
- let
- uniq = getUnique con
- temp = CTemp uniq PtrRep
- in
-
- profCtrC FSLIT("TICK_UPD_CON_IN_PLACE")
- [mkIntCLit (length amodes)] `thenC`
-
- getSpRelOffset args_sp `thenFC` \ sp_rel ->
- absC (CAssign temp
- (CMacroExpr PtrRep UPD_FRAME_UPDATEE [CAddr sp_rel]))
- `thenC`
-
- -- stomp all over it with the new constructor
- inPlaceAllocDynClosure closure_info temp (CReg CurCostCentre) stuff
- `thenC`
-
- -- set Node to point to the closure being returned
- -- (can't be done earlier: node might conflict with amodes)
- absC (CAssign (CReg node) temp) `thenC`
-
- -- pop the update frame off the stack, and do the proper
- -- return.
- let new_sp = args_sp - updateFrameSize in
- setEndOfBlockInfo (EndOfBlockInfo new_sp (OnStack new_sp)) $
- performReturn (AbsCNop) (mkStaticAlgReturnCode con)
-
- where
- (closure_info, stuff) = layOutDynConstr con getAmodeRep amodes
-