Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ghc/ghc
  • bgamari/ghc
  • syd/ghc
  • ggreif/ghc
  • watashi/ghc
  • RolandSenn/ghc
  • mpickering/ghc
  • DavidEichmann/ghc
  • carter/ghc
  • harpocrates/ghc
  • ethercrow/ghc
  • mijicd/ghc
  • adamse/ghc
  • alexbiehl/ghc
  • gridaphobe/ghc
  • trofi/ghc
  • supersven/ghc
  • ppk/ghc
  • ulysses4ever/ghc
  • AndreasK/ghc
  • ghuntley/ghc
  • shayne-fletcher-da/ghc
  • fgaz/ghc
  • yav/ghc
  • osa1/ghc
  • mbbx6spp/ghc
  • JulianLeviston/ghc
  • reactormonk/ghc
  • rae/ghc
  • takenobu-hs/ghc
  • michalt/ghc
  • andrewthad/ghc
  • hsyl20/ghc
  • scottgw/ghc
  • sjakobi/ghc
  • angerman/ghc
  • RyanGlScott/ghc
  • hvr/ghc
  • howtonotwin/ghc
  • chessai/ghc
  • m-renaud/ghc
  • brprice/ghc
  • stevehartdata/ghc
  • sighingnow/ghc
  • kgardas/ghc
  • ckoparkar/ghc
  • alp/ghc
  • smaeul/ghc
  • kakkun61/ghc
  • sykloid/ghc
  • newhoggy/ghc
  • toonn/ghc
  • nineonine/ghc
  • Phyx/ghc
  • ezyang/ghc
  • tweag/ghc
  • langston/ghc
  • ndmitchell/ghc
  • rockbmb/ghc
  • artempyanykh/ghc
  • mniip/ghc
  • mynguyenbmc/ghc
  • alexfmpe/ghc
  • crockeea/ghc
  • nh2/ghc
  • vaibhavsagar/ghc
  • phadej/ghc
  • Haskell-mouse/ghc
  • lolotp/ghc
  • spacekitteh/ghc
  • michaelpj/ghc
  • mgsloan/ghc
  • HPCohen/ghc
  • tmobile/ghc
  • radrow/ghc
  • simonmar/ghc
  • _deepfire/ghc
  • Ericson2314/ghc
  • leitao/ghc
  • fumieval/ghc
  • trac-isovector/ghc
  • cblp/ghc
  • xich/ghc
  • ciil/ghc
  • erthalion/ghc
  • xldenis/ghc
  • autotaker/ghc
  • haskell-wasm/ghc
  • kcsongor/ghc
  • agander/ghc
  • Baranowski/ghc
  • trac-dredozubov/ghc
  • 23Skidoo/ghc
  • iustin/ghc
  • ningning/ghc
  • josefs/ghc
  • kabuhr/ghc
  • gallais/ghc
  • dten/ghc
  • expipiplus1/ghc
  • Pluralia/ghc
  • rohanjr/ghc
  • intricate/ghc
  • kirelagin/ghc
  • Javran/ghc
  • DanielG/ghc
  • trac-mizunashi_mana/ghc
  • pparkkin/ghc
  • bollu/ghc
  • ntc2/ghc
  • jaspervdj/ghc
  • JoshMeredith/ghc
  • wz1000/ghc
  • zkourouma/ghc
  • code5hot/ghc
  • jdprice/ghc
  • tdammers/ghc
  • J-mie6/ghc
  • trac-lantti/ghc
  • ch1bo/ghc
  • cgohla/ghc
  • lucamolteni/ghc
  • acairncross/ghc
  • amerocu/ghc
  • chreekat/ghc
  • txsmith/ghc
  • trupill/ghc
  • typetetris/ghc
  • sergv/ghc
  • fryguybob/ghc
  • erikd/ghc
  • trac-roland/ghc
  • setupminimal/ghc
  • Friede80/ghc
  • SkyWriter/ghc
  • xplorld/ghc
  • abrar/ghc
  • obsidiansystems/ghc
  • Icelandjack/ghc
  • adinapoli/ghc
  • trac-matthewbauer/ghc
  • heatsink/ghc
  • dwijnand/ghc
  • Cmdv/ghc
  • alinab/ghc
  • pepeiborra/ghc
  • fommil/ghc
  • luochen1990/ghc
  • rlupton20/ghc
  • applePrincess/ghc
  • lehins/ghc
  • ronmrdechai/ghc
  • leeadam/ghc
  • harendra/ghc
  • mightymosquito1991/ghc
  • trac-gershomb/ghc
  • lucajulian/ghc
  • Rizary/ghc
  • VictorCMiraldo/ghc
  • jamesbrock/ghc
  • andrewdmeier/ghc
  • luke/ghc
  • pranaysashank/ghc
  • cocreature/ghc
  • hithroc/ghc
  • obreitwi/ghc
  • slrtbtfs/ghc
  • kaol/ghc
  • yairchu/ghc
  • Mathemagician98/ghc
  • trac-taylorfausak/ghc
  • leungbk/ghc
  • MichaWiedenmann/ghc
  • chris-martin/ghc
  • TDecki/ghc
  • adithyaov/ghc
  • trac-gelisam/ghc
  • Lysxia/ghc
  • complyue/ghc
  • bwignall/ghc
  • sternmull/ghc
  • sonika/ghc
  • leif/ghc
  • broadwaylamb/ghc
  • myszon/ghc
  • danbroooks/ghc
  • Mechachleopteryx/ghc
  • zardyh/ghc
  • trac-vdukhovni/ghc
  • OmarKhaledAbdo/ghc
  • arrowd/ghc
  • Bodigrim/ghc
  • matheus23/ghc
  • cardenaso11/ghc
  • trac-Athas/ghc
  • mb720/ghc
  • DylanZA/ghc
  • liff/ghc
  • typedrat/ghc
  • trac-claude/ghc
  • jbm/ghc
  • Gertjan423/ghc
  • PHO/ghc
  • JKTKops/ghc
  • kockahonza/ghc
  • msakai/ghc
  • Sir4ur0n/ghc
  • barambani/ghc
  • vishnu.c/ghc
  • dcoutts/ghc
  • trac-runeks/ghc
  • trac-MaxGabriel/ghc
  • lexi.lambda/ghc
  • strake/ghc
  • spavikevik/ghc
  • JakobBruenker/ghc
  • rmanne/ghc
  • gdziadkiewicz/ghc
  • ani/ghc
  • iliastsi/ghc
  • smunix/ghc
  • judah/ghc
  • blackgnezdo/ghc
  • emilypi/ghc
  • trac-bpfoley/ghc
  • muesli4/ghc
  • trac-gkaracha/ghc
  • Kleidukos/ghc
  • nek0/ghc
  • TristanCacqueray/ghc
  • dwulive/ghc
  • mbakke/ghc
  • arybczak/ghc
  • Yang123321/ghc
  • maksbotan/ghc
  • QuietMisdreavus/ghc
  • trac-olshanskydr/ghc
  • emekoi/ghc
  • samuela/ghc
  • josephcsible/ghc
  • dramforever/ghc
  • lpsmith/ghc
  • DenisFrezzato/ghc
  • michivi/ghc
  • jneira/ghc
  • jeffhappily/ghc
  • Ivan-Yudin/ghc
  • nakaji-dayo/ghc
  • gdevanla/ghc
  • galen/ghc
  • fendor/ghc
  • yaitskov/ghc
  • rcythr/ghc
  • awpr/ghc
  • jeremyschlatter/ghc
  • Aver1y/ghc
  • mitchellvitez/ghc
  • merijn/ghc
  • tomjaguarpaw1/ghc
  • trac-NoidedSuper/ghc
  • erewok/ghc
  • trac-junji.hashimoto/ghc
  • adamwespiser/ghc
  • bjaress/ghc
  • jhrcek/ghc
  • leonschoorl/ghc
  • lukasz-golebiewski/ghc
  • sheaf/ghc
  • last-g/ghc
  • carassius1014/ghc
  • eschwartz/ghc
  • dwincort/ghc
  • felixwiemuth/ghc
  • TimWSpence/ghc
  • marcusmonteirodesouza/ghc
  • WJWH/ghc
  • vtols/ghc
  • theobat/ghc
  • BinderDavid/ghc
  • ckoparkar0/ghc
  • alexander-kjeldaas/ghc
  • dme2/ghc
  • philderbeast/ghc
  • aaronallen8455/ghc
  • rayshih/ghc
  • benkard/ghc
  • mpardalos/ghc
  • saidelman/ghc
  • leiftw/ghc
  • ca333/ghc
  • bwroga/ghc
  • nmichael44/ghc
  • trac-crobbins/ghc
  • felixonmars/ghc
  • adityagupta1089/ghc
  • hgsipiere/ghc
  • treeowl/ghc
  • alexpeits/ghc
  • CraigFe/ghc
  • dnlkrgr/ghc
  • kerckhove_ts/ghc
  • cptwunderlich/ghc
  • eiais/ghc
  • hahohihu/ghc
  • sanchayan/ghc
  • lemmih/ghc
  • sehqlr/ghc
  • trac-dbeacham/ghc
  • luite/ghc
  • trac-f-a/ghc
  • vados/ghc
  • luntain/ghc
  • fatho/ghc
  • alexbiehl-gc/ghc
  • dcbdan/ghc
  • tvh/ghc
  • liam-ly/ghc
  • timbobbarnes/ghc
  • GovanifY/ghc
  • shanth2600/ghc
  • gliboc/ghc
  • duog/ghc
  • moxonsghost/ghc
  • zander/ghc
  • masaeedu/ghc
  • georgefst/ghc
  • guibou/ghc
  • nicuveo/ghc
  • mdebruijne/ghc
  • stjordanis/ghc
  • emiflake/ghc
  • wygulmage/ghc
  • frasertweedale/ghc
  • coot/ghc
  • aratamizuki/ghc
  • tsandstr/ghc
  • mrBliss/ghc
  • Anton-Latukha/ghc
  • tadfisher/ghc
  • vapourismo/ghc
  • Sorokin-Anton/ghc
  • basile-henry/ghc
  • trac-mightybyte/ghc
  • AbsoluteNikola/ghc
  • cobrien99/ghc
  • songzh/ghc
  • blamario/ghc
  • aj4ayushjain/ghc
  • trac-utdemir/ghc
  • tangcl/ghc
  • hdgarrood/ghc
  • maerwald/ghc
  • arjun/ghc
  • ratherforky/ghc
  • haskieLambda/ghc
  • EmilGedda/ghc
  • Bogicevic/ghc
  • eddiejessup/ghc
  • kozross/ghc
  • AlistairB/ghc
  • 3Rafal/ghc
  • christiaanb/ghc
  • trac-bit/ghc
  • matsumonkie/ghc
  • trac-parsonsmatt/ghc
  • chisui/ghc
  • jaro/ghc
  • trac-kmiyazato/ghc
  • davidsd/ghc
  • Tritlo/ghc
  • I-B-3/ghc
  • lykahb/ghc
  • AriFordsham/ghc
  • turion1/ghc
  • berberman/ghc
  • christiantakle/ghc
  • zyklotomic/ghc
  • trac-ocramz/ghc
  • CSEdd/ghc
  • doyougnu/ghc
  • mmhat/ghc
  • why-not-try-calmer/ghc
  • plutotulp/ghc
  • kjekac/ghc
  • Manvi07/ghc
  • teo/ghc
  • cactus/ghc
  • CarrieMY/ghc
  • abel/ghc
  • yihming/ghc
  • tsakki/ghc
  • jessicah/ghc
  • oliverbunting/ghc
  • meld/ghc
  • friedbrice/ghc
  • Joald/ghc
  • abarbu/ghc
  • DigitalBrains1/ghc
  • sterni/ghc
  • alexDarcy/ghc
  • hexchain/ghc
  • minimario/ghc
  • zliu41/ghc
  • tommd/ghc
  • jazcarate/ghc
  • peterbecich/ghc
  • alirezaghey/ghc
  • solomon/ghc
  • mikael.urankar/ghc
  • davjam/ghc
  • int-index/ghc
  • MorrowM/ghc
  • nrnrnr/ghc
  • Sonfamm/ghc-test-only
  • afzt1/ghc
  • nguyenhaibinh-tpc/ghc
  • trac-lierdakil/ghc
  • MichaWiedenmann1/ghc
  • jmorag/ghc
  • Ziharrk/ghc
  • trac-MitchellSalad/ghc
  • juampe/ghc
  • jwaldmann/ghc
  • snowleopard/ghc
  • juhp/ghc
  • normalcoder/ghc
  • ksqsf/ghc
  • trac-jberryman/ghc
  • roberth/ghc
  • 1ntEgr8/ghc
  • epworth/ghc
  • MrAdityaAlok/ghc
  • JunmingZhao42/ghc
  • jappeace/ghc
  • trac-Gabriel439/ghc
  • alt-romes/ghc
  • HugoPeters1024/ghc
  • 10ne1/ghc-fork
  • agentultra/ghc
  • Garfield1002/ghc
  • ChickenProp/ghc
  • clyring/ghc
  • MaxHearnden/ghc
  • jumper149/ghc
  • vem/ghc
  • ketzacoatl/ghc
  • Rosuavio/ghc
  • jackohughes/ghc
  • p4l1ly/ghc
  • konsumlamm/ghc
  • shlevy/ghc
  • torsten.schmits/ghc
  • andremarianiello/ghc
  • amesgen/ghc
  • googleson78/ghc
  • InfiniteVerma/ghc
  • uhbif19/ghc
  • yiyunliu/ghc
  • raehik/ghc
  • mrkun/ghc
  • telser/ghc
  • 1Jajen1/ghc
  • slotThe/ghc
  • WinstonHartnett/ghc
  • mpilgrem/ghc
  • dreamsmasher/ghc
  • schuelermine/ghc
  • trac-Viwor/ghc
  • undergroundquizscene/ghc
  • evertedsphere/ghc
  • coltenwebb/ghc
  • oberblastmeister/ghc
  • agrue/ghc
  • lf-/ghc
  • zacwood9/ghc
  • steshaw/ghc
  • high-cloud/ghc
  • SkamDart/ghc
  • PiDelport/ghc
  • maoif/ghc
  • RossPaterson/ghc
  • CharlesTaylor7/ghc
  • ribosomerocker/ghc
  • trac-ramirez7/ghc
  • daig/ghc
  • NicolasT/ghc
  • FinleyMcIlwaine/ghc
  • lawtonnichols/ghc
  • jmtd/ghc
  • ozkutuk/ghc
  • wildsebastian/ghc
  • nikshalark/ghc
  • lrzlin/ghc
  • tobias/ghc
  • fw/ghc
  • hawkinsw/ghc
  • type-dance/ghc
  • rui314/ghc
  • ocharles/ghc
  • wavewave/ghc
  • TheKK/ghc
  • nomeata/ghc
  • trac-csabahruska/ghc
  • jonathanjameswatson/ghc
  • L-as/ghc
  • Axman6/ghc
  • barracuda156/ghc
  • trac-jship/ghc
  • jake-87/ghc
  • meooow/ghc
  • rebeccat/ghc
  • hamana55/ghc
  • Enigmage/ghc
  • kokobd/ghc
  • agevelt/ghc
  • gshen42/ghc
  • chrismwendt/ghc
  • MangoIV/ghc
  • teto/ghc
  • Sookr1/ghc
  • trac-thomasjm/ghc
  • barci2/ghc-dev
  • trac-m4dc4p/ghc
  • dixonary/ghc
  • breakerzirconia/ghc
  • alexsio27444/ghc
  • glocq/ghc
  • sourabhxyz/ghc
  • ryantrinkle/ghc
  • Jade/ghc
  • scedfaliako/ghc
  • martijnbastiaan/ghc
  • trac-george.colpitts/ghc
  • ammarbinfaisal/ghc
  • mimi.vx/ghc
  • lortabac/ghc
  • trac-zyla/ghc
  • benbellick/ghc
  • aadaa-fgtaa/ghc
  • jvanbruegge/ghc
  • archbung/ghc
  • gilmi/ghc
  • mfonism/ghc
  • alex-mckenna/ghc
  • Ei30metry/ghc
  • DiegoDiverio/ghc
  • jorgecunhamendes/ghc
  • liesnikov/ghc
  • akrmn/ghc
  • trac-simplifierticks/ghc
  • jacco/ghc
  • rhendric/ghc
  • damhiya/ghc
  • ryndubei/ghc
  • DaveBarton/ghc
  • trac-Profpatsch/ghc
  • GZGavinZhao/ghc
  • ncfavier/ghc
  • jameshaydon/ghc
  • ajccosta/ghc
  • dschrempf/ghc
  • cydparser/ghc
  • LinuxUserGD/ghc
  • elodielander/ghc
  • facundominguez/ghc
  • psilospore/ghc
  • lachrimae/ghc
  • dylan-thinnes/ghc-type-errors-plugin
  • hamishmack/ghc
  • Leary/ghc
  • lzszt/ghc
  • lyokha/ghc
  • trac-glaubitz/ghc
  • Rewbert/ghc
  • andreabedini/ghc
  • Jasagredo/ghc
  • sol/ghc
  • OlegAlexander/ghc
  • trac-sthibaul/ghc
  • avdv/ghc
  • Wendaolee/ghc
  • ur4t/ghc
  • daylily/ghc
  • boltzmannrain/ghc
  • mmzk1526/ghc
  • trac-fizzixnerd/ghc
  • soulomoon/ghc
  • rwmjones/ghc
  • j14i/ghc
  • tracsis/ghc
  • gesh/ghc
  • flip101/ghc
  • eldritch-cookie/ghc
  • LemonjamesD/ghc
  • pgujjula/ghc
  • skeuchel/ghc
  • noteed/ghc
  • gulin.serge/ghc
  • Torrekie/ghc
  • jlwoodwa/ghc
  • ayanamists/ghc
  • husong998/ghc
  • trac-edmundnoble/ghc
  • josephf/ghc
  • contrun/ghc
  • baulig/ghc
  • edsko/ghc
  • mzschr/ghc-issue-24732
  • ulidtko/ghc
  • Arsen/ghc
  • trac-sjoerd_visscher/ghc
  • crumbtoo/ghc
  • L0neGamer/ghc
  • DrewFenwick/ghc
  • benz0li/ghc
  • MaciejWas/ghc
  • jordanrule/ghc
  • trac-qqwy/ghc
  • LiamGoodacre/ghc
  • isomorpheme/ghc
  • trac-danidiaz/ghc
  • Kariim/ghc
  • MTaimoorZaeem/ghc
  • hololeap/ghc
  • ticat-fp/ghc
  • meritamen/ghc
  • criskell/ghc
  • trac-kraai/ghc
  • aergus/ghc
  • jdral/ghc
  • SamB/ghc
  • Tristian/ghc
  • ywgrit/ghc
  • KatsuPatrick/ghc
  • OsePedro/ghc
  • mpscholten/ghc
  • fp/ghc
  • zaquest/ghc
  • fangyi-zhou/ghc
  • augyg/ghc
640 results
Show changes
Commits on Source (4)
...@@ -1852,6 +1852,70 @@ section "Byte Arrays" ...@@ -1852,6 +1852,70 @@ section "Byte Arrays"
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- Note [Byte arrays outside of the HEAP_ALLOCED space]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- It is useful to be able to allocate byte arrays outside of the heap,
-- i.e. outside of the memory space covered by the HEAP_ALLOCED() test.
--
-- There are two major use cases (see issue #17747):
--
-- 1. Having foreign memory appear as a normal GHC byte array. This
-- are use cases similar to the use of a ForeignPtr, but where it
-- is useful to have the representation be a byte array type, for
-- easier interoperability with existing libraries.
--
-- 2. Static byte arrays in object files for constant values.
--
-- The second is not yet available as it requires additional support
-- from the code gen.
--
-- An example of the first category can be seen in GHC test T17747.
-- A concrete use-case is to memory map a file
-- but have it appear as a ByteArray# rather than a ForeignPtr. Doing
-- so of course requires that space is reserved immediately before the
-- file data for the byte array heap object header. See the
-- placeByteArray# primop documentation below and the FFI section of
-- the user guide for more details.
--
-- To have the first use-case work requires a few things:
--
-- * For the GC to not fail when it encounters byte arrays outside of
-- the HEAP_ALLOCED space. This is straightforward because the GC
-- has support for a number of different closure types to appear
-- outside the heap (primarily for statically allocated values), and
-- byte arrays are easy because they contain no heap pointers. See
-- the reference back to this note in `evacuate(StgClosure **p)` in
-- `rts/sm/Evac.c`
--
-- * For all other byte array primops (e.g. shrinkMutableByteArray#,
-- sameMutableByteArray#, isByteArrayPinned#, etc.) to not fail when
-- encountering byte arrays outside of the heap. Specifically
-- isByteArrayPinned# requires special support. This is currently the
-- only primop that needs special support.
-- See Note [isByteArrayPinned# support for off heap byte arrays].
--
-- * A mechanism to set up the heap object header for a byte array at
-- an address outside of the HEAP_ALLOCED space. This is needed to
-- make the foreign allocated memory look like a byte array. This is
-- provided by the placeByteArray# primop.
--
-- Note [isByteArrayPinned# support for off heap byte arrays]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- The isByteArrayPinned# primop is implemented by reading block descriptor
-- flags. Since off heap byte arrays don't have block descriptors,
-- isByteArrayPinned# must explicitly check if the byte array is HEAP_ALLOCED
-- or not. If not HEAP_ALLOCED then it is certainly pinned. This requires CMM
-- support for the HEAP_ALLOCED test, which is otherwise only called from C
-- code in the RTS. The current design is to provide full CMM
-- implementations of HEAP_ALLOCED enabled in `rts/storage/HeapAlloc.h` with the
-- CMINUSMINUS cpp flag. This includes HEAP_ALLOCED_CALLISH which essentially
-- duplicates what is already a complex C implementation. This is fast
-- but an alternative would be to use a CMM C call to a C function that use
-- the existing C implementation of HEAP_ALLOCED.
primtype ByteArray# primtype ByteArray#
{ {
A boxed, unlifted datatype representing a region of raw memory in the garbage-collected heap, A boxed, unlifted datatype representing a region of raw memory in the garbage-collected heap,
...@@ -1902,10 +1966,17 @@ primop NewByteArrayOp_Char "newByteArray#" GenPrimOp ...@@ -1902,10 +1966,17 @@ primop NewByteArrayOp_Char "newByteArray#" GenPrimOp
with out_of_line = True with out_of_line = True
effect = ReadWriteEffect effect = ReadWriteEffect
-- See Note [Byte arrays outside of the HEAP_ALLOCED space]
primop PlaceByteArrayOp_Char "placeByteArray#" GenPrimOp primop PlaceByteArrayOp_Char "placeByteArray#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, MutableByteArray# s #) Addr# -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
{Place a new byte array header for the specified size (in bytes), at the {Place a new byte array header at the specified address outside of the heap,
specified address outside of the heap, in the specified state thread.} for the specified payload size (in bytes), in the specified state thread. In
C code with `#include "Rts.h"`, use `sizeOf(StgArrBytes)` or
`sizeOfW(StgArrBytes)` to get the size of a byte array header in bytes or
words respectively. The caller must ensure `sizeof(StgArrBytes) + n` bytes of
space is allocated at the give address for the heap object header followed by
n bytes of payload. See the FFI section of the user guide for more details
on how to use this primop.}
with out_of_line = True with out_of_line = True
effect = ReadWriteEffect effect = ReadWriteEffect
......
...@@ -831,7 +831,7 @@ Note that the object header size is different for normal and profiling ...@@ -831,7 +831,7 @@ Note that the object header size is different for normal and profiling
builds. When allocating in foreign memory, space must be made available builds. When allocating in foreign memory, space must be made available
for this in the memory layout immediately before the data payload. for this in the memory layout immediately before the data payload.
In C code, ``#include "rts.h"`` and use ``sizeOf(StgArrBytes)`` or In C code, ``#include "Rts.h"`` and use ``sizeOf(StgArrBytes)`` or
``sizeOfW(StgArrBytes)`` to get the size of a byte array heap object ``sizeOfW(StgArrBytes)`` to get the size of a byte array heap object
header in bytes or words respectively. This is the space that must be header in bytes or words respectively. This is the space that must be
reserved at the memory location immediately before the intended payload. reserved at the memory location immediately before the intended payload.
......
...@@ -135,6 +135,7 @@ stg_newByteArrayzh ( W_ n ) ...@@ -135,6 +135,7 @@ stg_newByteArrayzh ( W_ n )
} }
stg_placeByteArrayzh ( W_ addr, W_ n ) stg_placeByteArrayzh ( W_ addr, W_ n )
// Addr# -> Int# -> MutableByteArray# {
{ {
/* Place an ARR_WORDS object header at the given address outside the heap. /* Place an ARR_WORDS object header at the given address outside the heap.
The caller must arrange for space for the heap object header. */ The caller must arrange for space for the heap object header. */
...@@ -148,6 +149,7 @@ stg_placeByteArrayzh ( W_ addr, W_ n ) ...@@ -148,6 +149,7 @@ stg_placeByteArrayzh ( W_ addr, W_ n )
#define BA_ALIGN 16 #define BA_ALIGN 16
#define BA_MASK (BA_ALIGN-1) #define BA_MASK (BA_ALIGN-1)
// See Note [Byte arrays outside of the HEAP_ALLOCED space]
stg_newPinnedByteArrayzh ( W_ n ) stg_newPinnedByteArrayzh ( W_ n )
{ {
W_ words, bytes, payload_words; W_ words, bytes, payload_words;
......
...@@ -78,6 +78,8 @@ extern struct mblock_address_range mblock_address_space; ...@@ -78,6 +78,8 @@ extern struct mblock_address_range mblock_address_space;
#else /* defined(CMINUSMINUS) */ #else /* defined(CMINUSMINUS) */
/* See Note [Byte arrays outside of the HEAP_ALLOCED space] */
import mblock_address_space; import mblock_address_space;
// We explicitly duplicate the bound checking implementation of `HEAP_ALLOCED` for performance // We explicitly duplicate the bound checking implementation of `HEAP_ALLOCED` for performance
...@@ -100,6 +102,8 @@ extern StgWord8 mblock_map[]; ...@@ -100,6 +102,8 @@ extern StgWord8 mblock_map[];
#else /* defined(CMINUSMINUS) */ #else /* defined(CMINUSMINUS) */
/* See Note [Byte arrays outside of the HEAP_ALLOCED space] */
import CLOSURE mblock_map; import CLOSURE mblock_map;
# define MBLOCK_MAP_ENTRY(p) ((p) >> MBLOCK_SHIFT) # define MBLOCK_MAP_ENTRY(p) ((p) >> MBLOCK_SHIFT)
...@@ -259,6 +263,8 @@ StgBool HEAP_ALLOCED_GC(const void *p) ...@@ -259,6 +263,8 @@ StgBool HEAP_ALLOCED_GC(const void *p)
#else /* defined(CMINUSMINUS) */ #else /* defined(CMINUSMINUS) */
/* See Note [Byte arrays outside of the HEAP_ALLOCED space] */
// This is a call to HEAP_ALLOCED C function defined above. That function is reified via the // This is a call to HEAP_ALLOCED C function defined above. That function is reified via the
// Inlines.c file. Since the implementation that can't use USE_LARGE_ADDRESS_SPACE is big and // Inlines.c file. Since the implementation that can't use USE_LARGE_ADDRESS_SPACE is big and
// complicated we prevent duplicating it's logic. We define the interface to be used in a statement // complicated we prevent duplicating it's logic. We define the interface to be used in a statement
......
...@@ -741,6 +741,7 @@ loop: ...@@ -741,6 +741,7 @@ loop:
case CONSTR_0_1: case CONSTR_0_1:
case CONSTR_0_2: case CONSTR_0_2:
case CONSTR_NOCAF: case CONSTR_NOCAF:
/* See Note [Byte arrays outside of the HEAP_ALLOCED space] */
case ARR_WORDS: case ARR_WORDS:
/* no need to put these on the static linked list, they don't need /* no need to put these on the static linked list, they don't need
* to be scavenged. * to be scavenged.
......
...@@ -4223,6 +4223,7 @@ module GHC.Base where ...@@ -4223,6 +4223,7 @@ module GHC.Base where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
...@@ -6325,6 +6326,7 @@ module GHC.Exts where ...@@ -6325,6 +6326,7 @@ module GHC.Exts where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
......
...@@ -4223,6 +4223,7 @@ module GHC.Base where ...@@ -4223,6 +4223,7 @@ module GHC.Base where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
...@@ -6294,6 +6295,7 @@ module GHC.Exts where ...@@ -6294,6 +6295,7 @@ module GHC.Exts where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
...@@ -4226,6 +4226,7 @@ module GHC.Base where ...@@ -4226,6 +4226,7 @@ module GHC.Base where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
...@@ -6474,6 +6475,7 @@ module GHC.Exts where ...@@ -6474,6 +6475,7 @@ module GHC.Exts where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
......
...@@ -4223,6 +4223,7 @@ module GHC.Base where ...@@ -4223,6 +4223,7 @@ module GHC.Base where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
...@@ -6325,6 +6326,7 @@ module GHC.Exts where ...@@ -6325,6 +6326,7 @@ module GHC.Exts where
pext32# :: Word# -> Word# -> Word# pext32# :: Word# -> Word# -> Word#
pext64# :: Word64# -> Word64# -> Word64# pext64# :: Word64# -> Word64# -> Word64#
pext8# :: Word# -> Word# -> Word# pext8# :: Word# -> Word# -> Word#
placeByteArray# :: forall d. Addr# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
plusAddr# :: Addr# -> Int# -> Addr# plusAddr# :: Addr# -> Int# -> Addr#
plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# plusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2#
plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# plusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4#
......
...@@ -15,33 +15,26 @@ import GHC.Exts ...@@ -15,33 +15,26 @@ import GHC.Exts
import GHC.Base (IO(IO)) import GHC.Base (IO(IO))
-- | Test that we can allocate 'ByteArray#'s outside of the @HEAP_ALLOCED()@ -- | Test that we can allocate 'ByteArray#'s outside of the @HEAP_ALLOCED()@ address space without
-- address space without upsetting the GC. To be extra sure we attach weak -- upsetting the GC. To be extra sure we attach weak pointers with C finalizers to the
-- pointers with C finalizers to the 'ByteArray#'s. We keep them alive and run -- 'ByteArray#'s. We keep them alive and run a major GC so that the GC has to trace the live
-- a major GC so that the GC has to trace the live 'ByteArray#'s. -- 'ByteArray#'s.
-- --
-- On older GHC versions this upsets the GC because it does not expect heap -- On older GHC versions this upsets the GC because it does not expect heap objects with closure
-- objects with closure type @ARR_WORDS@ to exist outside the heap. -- type @ARR_WORDS@ to exist outside the heap.
-- --
-- > internal error: evacuate(static): strange closure type 42 -- > internal error: evacuate(static): strange closure type 42
-- --
-- Finally we allow everything to be GC'd again, and check that the C -- Finally we free the backing memory with `unsafeFreeByteArray`. Then we rerun the GC'd again.
-- finalizers did run. -- Note: When connecting finalizers they seem to fire on shutdown of the RTS not on a major GC
-- invocation.
-- --
main :: IO () main :: IO ()
main = do main = do
heapallocedTest heapallocedTest
n1 <- getMallocByteArrayCount
putStrLn ("malloc_count = " ++ show n1)
bytearrayTest bytearrayTest
-- check that all the C finalizers ran to free() the things we allocated
performMajorGC
n2 <- getMallocByteArrayCount
putStrLn ("malloc_count = " ++ show n1)
-- | This checks that the CMM impl of HEAP_ALLOCED matches the behaviour of -- | This checks that the CMM impl of HEAP_ALLOCED matches the behaviour of
-- the C version. This test lives here since the CMM HEAP_ALLOCED is used by -- the C version. This test lives here since the CMM HEAP_ALLOCED is used by
-- the isByteArrayPinned# primop now that it supports byte arrays that are -- the isByteArrayPinned# primop now that it supports byte arrays that are
...@@ -55,40 +48,67 @@ heapallocedTest = do ...@@ -55,40 +48,67 @@ heapallocedTest = do
putStrLn ("HEAP_ALLOCED = " ++ show same putStrLn ("HEAP_ALLOCED = " ++ show same
++ "\t(c_HEAP_ALLOCED ptr == cmm_HEAP_ALLOCED ptr)") ++ "\t(c_HEAP_ALLOCED ptr == cmm_HEAP_ALLOCED ptr)")
where where
addrs = -- For values selected here see OSMem.c
heapLowerbound = 8 * (2^30) -- 8GB lower bound starting index of the heap
heapDefaultStart = 0x4200000000 -- > 32GB default starting address of the heap
heapSizes = [0 -- Check the heap lower starting bound
, 2^40, 2^38] -- Check the heap upper bounds at both 1TB and 1/4TB of virtual memory
addrs
-- Addresses around the start of the heap
= [heapStart + heapSize + offset
| heapStart <- [heapLowerbound, heapDefaultStart]
, heapSize <- heapSizes
, offset <- [-1000..1000]] -- Area of the bounds check
-- 2k address probes, appropriate to the address space -- 2k address probes, appropriate to the address space
case sizeOf (nullPtr :: Ptr ()) of ++ case sizeOf (nullPtr :: Ptr ()) of
4 -> [0, 2^21 .. 2^32-1] -- 0 to 4Gb-1 in 2Mb jumps 4 -> [0, 2^21 .. 2^32-1] -- 0 to 4Gb-1 in 2Mb jumps
8 -> [0, 2^30 .. 2^41-1] -- 0 to 2Tb-1 in 1Gb jumps 8 -> [0, 2^30 .. 2^41-1] -- 0 to 2Tb-1 in 1Gb jumps
_ -> error "sizeOf ptr not 4 or 8" _ -> error "sizeOf ptr not 4 or 8"
bytearrayTest :: IO () bytearrayTest :: IO ()
bytearrayTest = do bytearrayTest = do
printMallocCount "initial"
let byteLengths = [0..99]
-- malloc() a bunch of ByteArray#s on the C heap -- malloc() a bunch of ByteArray#s on the C heap
foreignBAs <- mapM newForeignHeapByteArray [0..99] (foreignPtrs, foreignBAs) <- unzip <$> mapM newForeignHeapByteArray byteLengths
n1 <- getMallocByteArrayCount printMallocCount "alloced"
putStrLn ("malloc_count = " ++ show n1)
-- allocate a bunch of ByteArray#s on the GHC heap -- allocate a bunch of ByteArray#s on the GHC heap
nativeBAs <- mapM newNativeHeapByteArray [0..99] nativeBAs <- mapM newNativeHeapByteArray byteLengths
-- as a sanity check compare them to each other -- as a sanity check compare them to each other
let same = and (zipWith equalByteArrays foreignBAs nativeBAs) let same = and (zipWith equalByteArrays foreignBAs nativeBAs)
putStrLn ("arrays equal = " ++ show same putStrLn ("arrays equal = " ++ show same
++ "\t(and (zipWith equalByteArrays foreignBAs nativeBAs))") ++ "\t(and (zipWith equalByteArrays foreignBAs nativeBAs))")
-- and test the isByteArrayPinned# primop on them all -- and test the isByteArrayPinned# primop on them foreign byte arrays
let pinned = all isByteArrayPinned foreignBAs let pinnedForeign = all isByteArrayPinned foreignBAs
putStrLn ("arrays pinned = " ++ show pinned putStrLn ("arrays pinned = " ++ show pinnedForeign
++ "\t(all isByteArrayPinned foreignBAs)") ++ "\t(all isByteArrayPinned foreignBAs)")
-- and test the isByteArrayPinned# primop on them native byte arrays
let pinnedNative = all isByteArrayPinned nativeBAs
putStrLn ("arrays pinned = " ++ show pinnedNative
++ "\t(all isByteArrayPinned nativeBAs)")
-- while they're still live, have the GC inspect them all -- while they're still live, have the GC inspect them all
performMajorGC performMajorGC
n2 <- getMallocByteArrayCount printMallocCount "alive"
putStrLn ("malloc_count = " ++ show n2)
mapM_ touchByteArray foreignBAs mapM_ touchByteArray foreignBAs
-- after they have been freed, have another GC run
mapM_ unsafeFreeByteArray foreignPtrs
-- WARNING: DO NOT USE `foreignPtrs` OR `foreignBAs` AFTER THIS POINT
-- We have released the memory backing the byte arrays
performMajorGC
printMallocCount "final"
printMallocCount :: String -> IO ()
printMallocCount phase = do
n <- getMallocByteArrayCount
putStrLn ("malloc_count = " ++ show n ++ "\t" ++ phase)
data ByteArray = ByteArray ByteArray# data ByteArray = ByteArray ByteArray#
data MutableByteArray = MutableByteArray (MutableByteArray# RealWorld) data MutableByteArray = MutableByteArray (MutableByteArray# RealWorld)
...@@ -98,12 +118,14 @@ newNativeHeapByteArray n = do ...@@ -98,12 +118,14 @@ newNativeHeapByteArray n = do
mba <- newByteArray n mba <- newByteArray n
fillAndFreezeByteArray mba n fillAndFreezeByteArray mba n
newForeignHeapByteArray :: Int -> IO ByteArray newForeignHeapByteArray :: Int -> IO (Ptr a, ByteArray)
newForeignHeapByteArray n = do newForeignHeapByteArray n = do
-- mallocByteArray also allocates memory for the header of a ByteArray#
ptr <- mallocByteArray (fromIntegral n) ptr <- mallocByteArray (fromIntegral n)
-- placeByteArray# writes the ByteArray# header in this additionally allocated memory
mba <- placeByteArray ptr n mba <- placeByteArray ptr n
addCFinalizerToByteArray mba freeByteArray ptr ba <- fillAndFreezeByteArray mba n
fillAndFreezeByteArray mba n pure (ptr, ba)
newByteArray :: Int -> IO MutableByteArray newByteArray :: Int -> IO MutableByteArray
newByteArray (I# n#) = newByteArray (I# n#) =
...@@ -125,18 +147,6 @@ fillAndFreezeByteArray (MutableByteArray mba#) (I# n#) = ...@@ -125,18 +147,6 @@ fillAndFreezeByteArray (MutableByteArray mba#) (I# n#) =
case unsafeFreezeByteArray# mba# s1 of case unsafeFreezeByteArray# mba# s1 of
(# s2, ba# #) -> (# s2, ByteArray ba# #) (# s2, ba# #) -> (# s2, ByteArray ba# #)
addCFinalizerToByteArray :: MutableByteArray
-> FunPtr (Ptr a -> IO ())
-> Ptr a
-> IO ()
addCFinalizerToByteArray (MutableByteArray ba#) (FunPtr cfunptr#) (Ptr ptr#) =
IO $ \s0 ->
case mkWeakNoFinalizer# ba# () s0 of
(# s1, weak# #) ->
-- 0# flag here means don't pass any env ptr to the finalizer
case addCFinalizerToWeak# cfunptr# ptr# 0# nullAddr# weak# s1 of
(# s2, _success# #) -> (# s2, () #)
touchByteArray :: ByteArray -> IO () touchByteArray :: ByteArray -> IO ()
touchByteArray (ByteArray ba#) = touchByteArray (ByteArray ba#) =
IO $ \s0 -> IO $ \s0 ->
...@@ -161,8 +171,8 @@ cmm_HEAP_ALLOCED (Ptr addr#) = I# (cmm_HEAP_ALLOCED# addr#) ...@@ -161,8 +171,8 @@ cmm_HEAP_ALLOCED (Ptr addr#) = I# (cmm_HEAP_ALLOCED# addr#)
foreign import ccall unsafe "mallocByteArray" foreign import ccall unsafe "mallocByteArray"
mallocByteArray :: CInt -> IO (Ptr a) mallocByteArray :: CInt -> IO (Ptr a)
foreign import ccall unsafe "&freeByteArray" foreign import ccall unsafe "unsafeFreeByteArray"
freeByteArray :: FunPtr (Ptr a -> IO ()) unsafeFreeByteArray :: Ptr a -> IO ()
foreign import ccall unsafe "getMallocByteArrayCount" foreign import ccall unsafe "getMallocByteArrayCount"
getMallocByteArrayCount :: IO CInt getMallocByteArrayCount :: IO CInt
...@@ -172,4 +182,3 @@ foreign import ccall unsafe "c_HEAP_ALLOCED" ...@@ -172,4 +182,3 @@ foreign import ccall unsafe "c_HEAP_ALLOCED"
foreign import prim "cmm_HEAP_ALLOCED" foreign import prim "cmm_HEAP_ALLOCED"
cmm_HEAP_ALLOCED# :: Addr# -> Int# cmm_HEAP_ALLOCED# :: Addr# -> Int#
HEAP_ALLOCED = True (c_HEAP_ALLOCED ptr == cmm_HEAP_ALLOCED ptr) HEAP_ALLOCED = True (c_HEAP_ALLOCED ptr == cmm_HEAP_ALLOCED ptr)
malloc_count = 0 malloc_count = 0 initial
malloc_count = 100 malloc_count = 100 alloced
arrays equal = True (and (zipWith equalByteArrays foreignBAs nativeBAs)) arrays equal = True (and (zipWith equalByteArrays foreignBAs nativeBAs))
arrays pinned = True (all isByteArrayPinned foreignBAs) arrays pinned = True (all isByteArrayPinned foreignBAs)
malloc_count = 100 arrays pinned = False (all isByteArrayPinned nativeBAs)
malloc_count = 0 malloc_count = 100 alive
malloc_count = 0 final
...@@ -11,7 +11,7 @@ void *mallocByteArray (StgWord len) ...@@ -11,7 +11,7 @@ void *mallocByteArray (StgWord len)
return malloc(sizeof(StgArrBytes) + len); return malloc(sizeof(StgArrBytes) + len);
} }
void freeByteArray (void *arr) void unsafeFreeByteArray (void *arr)
{ {
free(arr); free(arr);
malloc_count--; malloc_count--;
...@@ -26,4 +26,3 @@ int c_HEAP_ALLOCED(void * p) ...@@ -26,4 +26,3 @@ int c_HEAP_ALLOCED(void * p)
{ {
return HEAP_ALLOCED(p); return HEAP_ALLOCED(p);
} }