2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[CgUpdate]{Manipulating update frames}
7 module CgUpdate ( pushUpdateFrame, reserveSeqFrame, pushSeqFrame ) where
9 #include "HsVersions.h"
14 import Constants ( uF_SIZE, sCC_UF_SIZE, sEQ_FRAME_SIZE )
15 import PrimRep ( PrimRep(..) )
16 import CgStackery ( allocUpdateFrame )
17 import CgUsages ( getSpRelOffset )
18 import CmdLineOpts ( opt_SccProfilingOn )
19 import Util ( assertPanic )
23 %********************************************************
25 %* Setting up update frames *
27 %********************************************************
28 \subsection[setting-update-frames]{Setting up update frames}
30 @pushUpdateFrame@ $updatee$ pushes a general update frame which
31 points to $updatee$ as the thing to be updated. It is only used
32 when a thunk has just been entered, so the (real) stack pointers
33 are guaranteed to be nicely aligned with the top of stack.
34 @pushUpdateFrame@ adjusts the virtual and tail stack pointers
35 to reflect the frame pushed.
38 pushUpdateFrame :: CAddrMode -> Code -> Code
40 pushUpdateFrame updatee code
42 -- frame_size *includes* the return address
43 frame_size = if opt_SccProfilingOn
47 getEndOfBlockInfo `thenFC` \ eob_info ->
48 ASSERT(case eob_info of { EndOfBlockInfo _ (OnStack _) -> True;
50 allocUpdateFrame frame_size (
52 -- Emit the push macro
53 absC (CMacroStmt PUSH_UPD_FRAME [
55 int_CLit0 -- Known to be zero because we have just
60 int_CLit0 = mkIntCLit 0 -- out here to avoid pushUpdateFrame CAF (sigh)
64 We push a SEQ frame just before evaluating the scrutinee of a case, if
65 the scrutinee has a polymorphic or function type. The SEQ frame acts
66 as a barrier in case the scrutinee evaluates to a partial application.
68 reserveSeqFrame takes the EndOfBlockInfo for the case expression and
69 updates the sequel to a SeqFrame, reserving room for the frame at
70 args_sp. When the scrutinee comes around to pushing a return address,
71 it will also push the SEQ frame, using pushSeqFrame.
74 reserveSeqFrame :: EndOfBlockInfo -> EndOfBlockInfo
75 reserveSeqFrame (EndOfBlockInfo args_sp (CaseAlts amode stuff))
76 = EndOfBlockInfo (args_sp + sEQ_FRAME_SIZE) (SeqFrame amode stuff)
78 pushSeqFrame :: VirtualSpOffset -> FCode VirtualSpOffset
80 = getSpRelOffset args_sp `thenFC` \ sp_rel ->
81 absC (CMacroStmt PUSH_SEQ_FRAME [CAddr sp_rel]) `thenC`
82 returnFC (args_sp - sEQ_FRAME_SIZE)