summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/codeGen')
-rw-r--r--compiler/codeGen/StgCmmHeap.hs2
-rw-r--r--compiler/codeGen/StgCmmLayout.hs5
-rw-r--r--compiler/codeGen/StgCmmMonad.hs36
3 files changed, 37 insertions, 6 deletions
diff --git a/compiler/codeGen/StgCmmHeap.hs b/compiler/codeGen/StgCmmHeap.hs
index 488a0e05bc..a3a47a65e7 100644
--- a/compiler/codeGen/StgCmmHeap.hs
+++ b/compiler/codeGen/StgCmmHeap.hs
@@ -8,7 +8,7 @@
module StgCmmHeap (
getVirtHp, setVirtHp, setRealHp,
- getHpRelOffset, hpRel,
+ getHpRelOffset,
entryHeapCheck, altHeapCheck, noEscapeHeapCheck, altHeapCheckReturnsTo,
heapStackCheckGen,
diff --git a/compiler/codeGen/StgCmmLayout.hs b/compiler/codeGen/StgCmmLayout.hs
index 7fbcbced81..59afc897dc 100644
--- a/compiler/codeGen/StgCmmLayout.hs
+++ b/compiler/codeGen/StgCmmLayout.hs
@@ -15,7 +15,7 @@ module StgCmmLayout (
slowCall, directCall,
- mkVirtHeapOffsets, mkVirtConstrOffsets, getHpRelOffset, hpRel,
+ mkVirtHeapOffsets, mkVirtConstrOffsets, getHpRelOffset,
ArgRep(..), toArgRep, argRepSizeW -- re-exported from StgCmmArgRep
) where
@@ -366,13 +366,14 @@ slowArgs dflags args -- careful: reps contains voids (V), but args does not
---- Laying out objects on the heap and stack
-------------------------------------------------------------------------
--- The heap always grows upwards, so hpRel is easy
+-- The heap always grows upwards, so hpRel is easy to compute
hpRel :: VirtualHpOffset -- virtual offset of Hp
-> VirtualHpOffset -- virtual offset of The Thing
-> WordOff -- integer word offset
hpRel hp off = off - hp
getHpRelOffset :: VirtualHpOffset -> FCode CmmExpr
+-- See Note [Virtual and real heap pointers] in StgCmmMonad
getHpRelOffset virtual_offset
= do dflags <- getDynFlags
hp_usg <- getHpUsage
diff --git a/compiler/codeGen/StgCmmMonad.hs b/compiler/codeGen/StgCmmMonad.hs
index 3d82e69402..348b7b9299 100644
--- a/compiler/codeGen/StgCmmMonad.hs
+++ b/compiler/codeGen/StgCmmMonad.hs
@@ -331,17 +331,47 @@ data CgState
cgs_uniqs :: UniqSupply }
-data HeapUsage =
- HeapUsage {
+data HeapUsage -- See Note [Virtual and real heap pointers]
+ = HeapUsage {
virtHp :: VirtualHpOffset, -- Virtual offset of highest-allocated word
-- Incremented whenever we allocate
realHp :: VirtualHpOffset -- realHp: Virtual offset of real heap ptr
-- Used in instruction addressing modes
- }
+ }
type VirtualHpOffset = WordOff
+{- Note [Virtual and real heap pointers]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The code generator can allocate one or more objects contiguously, performing
+one heap check to cover allocation of all the objects at once. Let's call
+this little chunk of heap space an "allocation chunk". The code generator
+will emit code to
+ * Perform a heap-exhaustion check
+ * Move the heap pointer to the end of the allocation chunk
+ * Allocate multiple objects within the chunk
+
+The code generator uses VirtualHpOffsets to address words within a
+single allocation chunk; these start at one and increase positively.
+The first word of the chunk has VirtualHpOffset=1, the second has
+VirtualHpOffset=2, and so on.
+
+ * The field realHp tracks (the VirtualHpOffset) where the real Hp
+ register is pointing. Typically it'll be pointing to the end of the
+ allocation chunk.
+
+ * The field virtHp gives the VirtualHpOffset of the highest-allocated
+ word so far. It starts at zero (meaning no word has been allocated),
+ and increases whenever an object is allocated.
+
+The difference between realHp and virtHp gives the offset from the
+real Hp register of a particular word in the allocation chunk. This
+is what getHpRelOffset does. Since the returned offset is relative
+to the real Hp register, it is valid only until you change the real
+Hp register. (Changing virtHp doesn't matter.)
+-}
+
initCgState :: UniqSupply -> CgState
initCgState uniqs