summaryrefslogtreecommitdiff
path: root/compiler/prelude/primops.txt.pp
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagn@cs.stanford.edu>2016-07-15 19:47:26 +0100
committerSimon Marlow <marlowsd@gmail.com>2016-07-20 16:35:23 +0100
commitcf989ffe490c146be4ed0fd7e0c00d3ff8fe1453 (patch)
tree1bdf626d6e713506852bf0015dae1e1be7d280c0 /compiler/prelude/primops.txt.pp
parent93acc02f7db7eb86967b4ec586359f408d62f75d (diff)
downloadhaskell-cf989ffe490c146be4ed0fd7e0c00d3ff8fe1453.tar.gz
Compact Regions
This brings in initial support for compact regions, as described in the ICFP 2015 paper "Efficient Communication and Collection with Compact Normal Forms" (Edward Z. Yang et.al.) and implemented by Giovanni Campagna. Some things may change before the 8.2 release, but I (Simon M.) wanted to get the main patch committed so that we can iterate. What documentation there is is in the Data.Compact module in the new compact package. We'll need to extend and polish the documentation before the release. Test Plan: validate (new test cases included) Reviewers: ezyang, simonmar, hvr, bgamari, austin Subscribers: vikraman, Yuras, RyanGlScott, qnikst, mboes, facundominguez, rrnewton, thomie, erikd Differential Revision: https://phabricator.haskell.org/D1264 GHC Trac Issues: #11493
Diffstat (limited to 'compiler/prelude/primops.txt.pp')
-rw-r--r--compiler/prelude/primops.txt.pp101
1 files changed, 101 insertions, 0 deletions
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index bfeb7852c6..9fd5d17f14 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -2426,6 +2426,92 @@ primop StableNameToIntOp "stableNameToInt#" GenPrimOp
StableName# a -> Int#
------------------------------------------------------------------------
+section "Compact normal form"
+------------------------------------------------------------------------
+
+primtype Compact#
+
+primop CompactNewOp "compactNew#" GenPrimOp
+ Word# -> State# RealWorld -> (# State# RealWorld, Compact# #)
+ { Create a new Compact with the given size (in bytes, not words).
+ The size is rounded up to a multiple of the allocator block size,
+ and capped to one mega block. }
+ with
+ has_side_effects = True
+ out_of_line = True
+
+primop CompactAppendOp "compactAppend#" GenPrimOp
+ Compact# -> a -> Int# -> State# RealWorld -> (# State# RealWorld, a #)
+ { Append an object to a compact, return the new address in the Compact.
+ The third argument is 1 if sharing should be preserved, 0 otherwise. }
+ with
+ has_side_effects = True
+ out_of_line = True
+
+primop CompactResizeOp "compactResize#" GenPrimOp
+ Compact# -> Word# -> State# RealWorld ->
+ State# RealWorld
+ { Set the new allocation size of the compact. This value (in bytes)
+ determines the size of each block in the compact chain. }
+ with
+ has_side_effects = True
+ out_of_line = True
+
+primop CompactContainsOp "compactContains#" GenPrimOp
+ Compact# -> a -> State# RealWorld -> (# State# RealWorld, Int# #)
+ { Returns 1# if the object is contained in the compact, 0# otherwise. }
+ with
+ out_of_line = True
+
+primop CompactContainsAnyOp "compactContainsAny#" GenPrimOp
+ a -> State# RealWorld -> (# State# RealWorld, Int# #)
+ { Returns 1# if the object is in any compact at all, 0# otherwise. }
+ with
+ out_of_line = True
+
+primop CompactGetFirstBlockOp "compactGetFirstBlock#" GenPrimOp
+ Compact# -> State# RealWorld -> (# State# RealWorld, Addr#, Word# #)
+ { Returns the address and the size (in bytes) of the first block of
+ a compact. }
+ with
+ out_of_line = True
+
+primop CompactGetNextBlockOp "compactGetNextBlock#" GenPrimOp
+ Compact# -> Addr# -> State# RealWorld -> (# State# RealWorld, Addr#, Word# #)
+ { Given a compact and the address of one its blocks, returns the
+ next block and its size, or #nullAddr if the argument was the
+ last block in the compact. }
+ with
+ out_of_line = True
+
+primop CompactAllocateBlockOp "compactAllocateBlock#" GenPrimOp
+ Word# -> Addr# -> State# RealWorld -> (# State# RealWorld, Addr# #)
+ { Attempt to allocate a compact block with the given size (in
+ bytes) at the given address. The first argument is a hint to
+ the allocator, allocation might be satisfied at a different
+ address (which is returned).
+ The resulting block is not known to the GC until
+ compactFixupPointers# is called on it, and care must be taken
+ so that the address does not escape or memory will be leaked.
+ }
+ with
+ has_side_effects = True
+ out_of_line = True
+
+primop CompactFixupPointersOp "compactFixupPointers#" GenPrimOp
+ Addr# -> Addr# -> State# RealWorld -> (# State# RealWorld, Compact#, Addr# #)
+ { Given the pointer to the first block of a compact, and the
+ address of the root object in the old address space, fix up
+ the internal pointers inside the compact to account for
+ a different position in memory than when it was serialized.
+ This method must be called exactly once after importing
+ a serialized compact, and returns the new compact and
+ the new adjusted root address. }
+ with
+ has_side_effects = True
+ out_of_line = True
+
+------------------------------------------------------------------------
section "Unsafe pointer equality"
-- (#1 Bad Guy: Alistair Reid :)
------------------------------------------------------------------------
@@ -2507,6 +2593,21 @@ primop AddrToAnyOp "addrToAny#" GenPrimOp
with
code_size = 0
+primop AnyToAddrOp "anyToAddr#" GenPrimOp
+ a -> State# RealWorld -> (# State# RealWorld, Addr# #)
+ { Retrive the address of any Haskell value. This is
+ essentially an {\texttt unsafeCoerce\#}, but if implemented as such
+ the core lint pass complains and fails to compile.
+ As a primop, it is opaque to core/stg, and only appears
+ in cmm (where the copy propagation pass will get rid of it).
+ Note that "a" must be a value, not a thunk! It's too late
+ for strictness analysis to enforce this, so you're on your
+ own to guarantee this. Also note that {\texttt Addr\#} is not a GC
+ pointer - up to you to guarantee that it does not become
+ a dangling pointer immediately after you get it.}
+ with
+ code_size = 0
+
primop MkApUpd0_Op "mkApUpd0#" GenPrimOp
BCO# -> (# a #)
{ Wrap a BCO in a {\tt AP_UPD} thunk which will be updated with the value of