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
  • 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
  • rkirkman/ghc
  • gulin.serge/ghc-windows-aarch64-bootstrap
  • iris/ghc
642 results
Show changes
Commits on Source (14)
  • Simon Marlow's avatar
    Bringing over the Local GC work from my darcs branch into a git · 303a2659
    Simon Marlow authored
    branch.
    
    This implements the independent local-heap GC described in the paper
    "Multicore Garbage Collection with Local Heaps".
    303a2659
  • Simon Marlow's avatar
    Merge commit '67e48af9' into local-gc · c937dc7d
    Simon Marlow authored
    c937dc7d
  • Simon Marlow's avatar
    Merge commit '521b7925' into local-gc · f0e9125a
    Simon Marlow authored
    f0e9125a
  • Simon Marlow's avatar
    merge · e684cb6c
    Simon Marlow authored
    e684cb6c
  • Simon Marlow's avatar
    Merge commit '4f018b47' into local-gc · 13ac0151
    Simon Marlow authored
    13ac0151
  • Simon Marlow's avatar
    Merge commit '5463b55b' into local-gc · 23858412
    Simon Marlow authored
    23858412
  • Simon Marlow's avatar
    Merge commit 'a52ff761' into local-gc · 0295e399
    Simon Marlow authored
    0295e399
  • Simon Marlow's avatar
    merge · 9c9d1fd9
    Simon Marlow authored
    9c9d1fd9
  • Simon Marlow's avatar
    merge commit cc2ea98a · b044b6f4
    Simon Marlow authored
    b044b6f4
  • Simon Marlow's avatar
    merge · dcbfbb12
    Simon Marlow authored
    dcbfbb12
  • Simon Marlow's avatar
    fix merge bugs · 8e1f5e35
    Simon Marlow authored
    8e1f5e35
  • Simon Marlow's avatar
  • Simon Marlow's avatar
    fix an interaction between the new pinned_object_block policy and · ab5aad58
    Simon Marlow authored
    globalisation.
    ab5aad58
  • Simon Marlow's avatar
    The local-gc branch is in a working state at this fingerprint: · b8207d4f
    Simon Marlow authored
    .|ab5aad58
    ghc-tarballs|e7b7b152083f7c3e3559e557a239757d41ac02a6
    libraries/Cabal|6f01f56a2702b50e2da909566c4a01622cb2ca7f
    libraries/Win32|0cf603103e9ad3fccd862171ba5e689b87930622
    libraries/array|e4b4e2e0a79f4138bdff4f10d263436b0155f449
    libraries/base|be2750a0a11b919fb03cc070074e430f88bdfa90
    libraries/binary|749ac0efbde3b14901417364a872796598747aaf
    libraries/bytestring|cab9d8566fba8611598f14fb4f2ac7b8d4aae75b
    libraries/containers|592f6d9da9090e8d53432f22a01bb117fea2246c
    libraries/deepseq|91e8a93b15ed32af3941f81e927291a023feb369
    libraries/directory|3a0f2e2cb94c3e4f346023acc7201409d2876ed8
    libraries/extensible-exceptions|a667b48d0cb6469b6611cb516d16836aa002e782
    libraries/filepath|92d211a2752fe8827582ae0d97efd18722ad3d87
    libraries/ghc-prim|7fcfc880853fa399c9468049aeb14e6eadb9eae5
    libraries/haskeline|125ee5bba59fa9ac2fd77aa3922c30dffc11b7b5
    libraries/haskell2010|f90687bee55adfd693fe460f2ab4bc270a7f97e3
    libraries/haskell98|eb655b0317665acb9670025480b4af4465bc8f55
    libraries/hoopl|0febb7f04ff4326bd120fc75549845e5e9678d72
    libraries/hpc|fce8babbc3f60fb195d84545753dc342422ab8e1
    libraries/integer-gmp|2567c97aaa467cb676a6ecc2cf840c92ee1cb6ec
    libraries/integer-simple|c3e9c0268b4d59895829e429d1ac767e6041b06a
    libraries/mtl|a748dfa2770af1d348dfaa8ad6955b25b4935711
    libraries/old-locale|7f09f55ea3011c17c526805f099394a05ec9c3fe
    libraries/old-time|6aae8dc2f13cef6ab48c5436c6c0e7c1b5ae3f51
    libraries/parallel|f82611fac439236e22a057cd555bb9fe393597b0
    libraries/pretty|e00aa7e0f82fc6f13ad85f1b3a27f53efe473e60
    libraries/process|d1c2999473ba0d4ceafdc6da309debca83f91abe
    libraries/random|ba8cb1b9fdfddeb29fdfedd8612c8ce85a987af8
    libraries/stm|ccc6d74872916e5de7747df4cc61f64de64be591
    libraries/template-haskell|acd4c3292d0f7a222a1f4f426054e4732a809fc8
    libraries/terminfo|f4476f1881085b74dbe65cf4a4561e8fb34017d4
    libraries/unix|c9a0bf119ce343b291bef77828066339e94fb64d
    libraries/utf8-string|d28cd1fbd4ebaaa0608c070bd02ed72dc9b70399
    libraries/xhtml|9a4d7d64d0491a1844d5b5759275b029ccd1e2cd
    nofib|6d3ea16e56bd99d060e778fab3583aa67a6b50d4
    testsuite|6560613138d61afddd0d8d428254370f8dfdb4cd
    utils/haddock|1d8143659a81cf9611668348e33fd0775c7ab1d2
    utils/hsc2hs|c46eed44ce96f1719334ffb190eddf63695bc553
    b8207d4f
Showing
with 936 additions and 127 deletions
-----------------------------------------------------------------------------
-- Plan
- fix hangs in ray with localgc N=16/20
- nbody slower with -N1? Something recent in HEAD?
- measure CnC properly
- test a multicore HTTP server
- try to improve the message-queue locking. Multiple writers should
be non-blocking.
- BLOCKING_QUEUE can point to IND_LOCAL instead of the BLACKHOLE,
assertion at Message.c:300 fails
- LinSolv has been broken by WEAK sparks
- transclos only seems to parallelise when not optimised :-(
- Don't steal another spark if we're waiting for a reply to
MSG_GLOBALISE on the first one (or maybe limit the number of
outstanding MSG_GLOBALISE messages before we stop stealing).
- running messageGlobalise eagerly is bad if the target is a BLACKHOLE
- check the perf of stage2 (need to compile it optimised)
- sort out where we allocate prim memory from. Using the nursery is
a bit of a hack, and the nursery has to be resized after each
collection.
- calcAllocated: take into account allocations from allocatePrim().
- threadStackOverflow: hacky -1s to account for global flags
- PROFILING???
- selector thunks: must check for forwarding ptr before entering
- is HEAP_ALLOCED_GC() safe to call during local GC?
- no need to maintain the global heap invariant for non-THREADED_RTS
and when -N1.
- sparks: we should look through the IND_LOCAL when deciding whether
to fizzle a spark during GC.
- STM invariants
- Now can we do pinning of arbitrary objects?
- a BF_PINNED page gets mark-swept
- we want to support unpinning too: how can we tell when to unpin
the page again?
-----------------------------------------------------------------------------
Tuning
- Push down local_gc_lock further? Do we have contention problems?
Measure.
- ray: using parBuffer 1000 much better than parBuffer 200 for -N8,
and we beat HEAD now.
- instead of setting failed_to_evac, just globalise_evac
immediately
.
- sparks: can we do better than just globalising all sparks?
e.g. separate the spark pool into local and global pools
- if a Cap is idle, it should probably do a local GC, otherwise it
will keep receiving messages requesting globalisation.
- options for global mark bits:
- word before each object
- bitmap at the beginning of the block
- low bit in the info pointer
- GC'ing IND_LOCAL:
- can't squash it to IND when scavenging, because although the IND
may point to the global gen, it might refer transitively to
something in the local gen, so this is not safe until after
globalise_mut_list.
- in globalise_mut_list, we want to squash IND_LOCALs on the mut
list; might this need two passes?
- checking whether a closure pointer is global is too complex:
EXTERN_INLINE rtsBool isGlobal (StgClosure *p)
{
bdescr *bd;
bd = Bdescr((P_)p);
return bd->gen_no != 0 || ((bd->flags & BF_PRIM) && isGlobalPrim(p));
}
(used in globalise_wrt, checkMutableList,
dirty_MUT_VAR, dirty_MUT_ARR, recordClosureMutated_)
how can we make this easier?
1. use MUT_VAR_GLOBAL iff the MUT_VAR is in the global gen,
otherwise use MUT_VAR_LOCAL. Only MUT_VAR_GLOBAL writes need to
publish. Inline dirty_MUT_VAR.
2. similarly for TSO: !tso->dirty means global and clean.
3. can omit the BF_PRIM check for objects we know to be prim.
- scavenge_mark_stack should probably set evac_gen_ix to the old gen
if the marked closure is global.
- the first time we sweep a prim block that has a global object in it,
mark the block BF_GLOBAL so we don't sweep it again?
- we could inline part of allocatePrim if newMVar, newMutVar
performance is important.
- An alternative: allocate prim objects in the nursery as normal,
but pin the whole block if they become global. Other private
objects would be copied out of the block as normal. The pinned
block then becomes part of the global heap (if we did Immix
marking then we could reclaim the free parts of the block).
We still have to mark individual objects as global/local, and we
can't use word-before-object.
- fix gc_bench: 38% slower
-----------------------------------------------------------------------------
Things to measure
- sendMessage to an idle processor: do the message eagerly or not?
- INBOX_THRESHOLD setting
- not eagerly promoting THUNKS:
- on average 3% slower over nofib/gc, constraints +13%, power +11%.
- also slower with -A1m (similar results)
- power is the biggest culprit, because it does a lot of updates
where the value is a constructor with 2 thunk fields, so we make
2 IND_LOCALs rather than 1.
- single-threaded GC perf: most things got faster, gc_bench??
- publish vs. globalise vs. globalise-to-depth vs. globalise-but-not-thunks
- for updates
- for MUT_VAR / MUT_ARR / TVAR / MVAR
- IND_LOCAL on the mut list during GC
- sparks
- right now we're not promoting anything from the local prim heap
unless it is referred to by the global heap. Is this the best
option? Alternative: mark closures global in evacuate().
- different choices of where to store mark bits.
- sparks:
- keep a local spark pool and steal by messages, compared to
a global spark pool with a work-stealing queue.
- separate the spark pool into local and global pools
- allocating MSG_BLACKHOLE globally immediately, or globalise on
demand.
- code size impact of extra tag & fwd ptr checking
- mutator impact (just the codeGen changes, no GC changes)
-----------------------------------------------------------------------------
-- Truly asynchronous globalisation
* Add a new per-CPU lock in the gc_thread: local_gc_lock. This protects
the local heap during a GC: we allow concurrent globalise(), but a
local GC gets exclusive access to the heap.
- take it when doing a GC_LOCAL
- take it when globalising from another CPU.
- take it in globalise_TSO: in here we set the TSO_GLOBALISE flag
on the TSO, we don't want concurrent globalises to find this flag
set.
* we need a separate set of mut_lists to use when globalising data
from another processor's local heap. These mut_lists are locked by
local_gc_lock.
- add cap->ext_mut_lists
- add recordMutableExt() in Capability.h
* add appropriate write_barrier()s in Globalise.c:copy_tag() etc.
* in globalise_maybe_record_mutable(), check whether we're recording
a mutable object that points to another cap's local heap, and use
ext_mut_lists if so.
* in atomicModifyIORef, writeIORef, we cannot be sure that the IORef
is not being globalised while we are modifying it, so we don't know
for sure whether we should globalise the value or not. How to
solve this race condition?
-----------------------------------------------------------------------------
-- Plan, later
* strange behaviour: iograph 30000 +RTS -H300m
612 MB total memory in use (190 MB lost due to fragmentation) ???
* MUT_VAR_CLEAN and MUT_VAR_DIRTY aren't being used. Decide what to
do about them. (similarly for other clean/dirty pairs?)
* Can we do globalise_capability_mut_lists() in the worker threads for
GC_PAR, rather than having the main thread do all of them? The
problem is that mut_list entries might be on the wrong mut_list.
* Clean up mutable arrays:
- card marking is unnecessary for an array in the global heap, because
we publish/globalise every pointer written into it
* leaving an IND_LOCAL every time we write to a mutable object in the
global gen is bad, because we'll accumulate floating garbage from
all the old values. Can we do anything at all here?
- for objects that already have a read barrier (e.g. MVar), we
could do better.
* maybe we should have MUT_VAR_PUBLIC / MUT_VAR_PRIVATE?
* Push down SM lock in GC.c
* GLOBALS that need locking in GC:
* threads lists attached to old generations (modified in tidyThreadList)
* gen->weak_ptrs lists
* gen->large_objects lists
* resurrectUnreachableThreads() can be pulled outside the lock, it only
touches the threads lists of generations collected.
* XXX we broke LDV profiling in CgTailCall
* XXX we probably don't need to duplicate the whole of Scav.c/Evac.c
* XXX major_gc is global, we rely on it always being rtsFalse for local GC
* XXX what to do about heapSizeSuggestion and resize_nursery: should
we resize the current nursery accoring to the amount of stuff that
was retained?
* XXX -G1 is not compatible with -N2 and greater, becauser there would
be no global heap.
* XXX should make publish() faster by inlining the allocation
* ToDo: check whether the interpreter looks at the info table of a
tagged closure
- do more sanity checking:
- check for proper BF_EVACUATED flags on blocks
-----------------------------------------------------------------------------
-- STM
TRecHeader (MUT_PRIM) -> { TRecHeader enclosing,
TRecChunk,
InvariantCheckQueue }
* TRecHeaders must be visible to all Capabilities, because a TVar is
locked by writing a pointer to the current TRecHeader into the
tvar->current_value field. Other Capabilities need to examine
this closure to check whether the TVar is locked.
Hence, we allocate all TRecHeaders in the global heap. Their
contents are PRIVATE, they may contain global->local pointers, and
they must be on the mutable list.
TRecChunk (TREC_CHUNK) ->
{ TRecChunk prev_chunk,
TRecEntry -> { TVar, expected, new }
}
* We consider the TRecChunk to be PRIVATE. They can contain
global->local pointers, and must be on the correct mutable list,
but they do not have to be allocated in the global heap.
TVar (MUT_PRIM) -> { value, TVarWatchQueue }
* When we write to a TVar, we must globalise as usual. Both TVars
and TVarWatchQueues are MUT_PRIM, so they both get eagerly promoted.
TVarWatchQueue (MUT_PRIM) -> { closure, prev, next }
* When creating a TVarWatchQueue we first need to check whether to
allocate it globally or locally, depending on the TVar.
AtomicInvariant (MUT_PRIM) -> { code, TrecHeader }
* TODO
InvariantCheckQueue (MUT_PRIM) -> { AtomicInvariant, TrecHeader, next }
* TODO
-----------------------------------------------------------------------------
-- BLOCKING_QUEUE structures
typedef struct StgBlockingQueue_ {
StgHeader header;
struct StgBlockingQueue_ *link; // here so it looks like an IND
StgClosure *bh; // the BLACKHOLE
StgTSO *owner;
struct MessageBlackHole_ *queue;
} StgBlockingQueue;
- BLOCKING_QUEUE and MSG_BLACKHOLE always get eagerly promoted, so we
never end up with global->local pointers in the link and queue
fields.
- BLOCKING_QUEUE may be promoted ahead of BLACKHOLE, so the BH field
may be global->local. But: a BLOCKING_QUEUE object is only pointed
to by the BH and the TSO that owns it, and the TSO must belong to
the owner of the BH, so this should be safe.
-----------------------------------------------------------------------------
-- Remembered set overhaul
If we're going to support more than one local generation, we may want
to simplify the remembered set handling. Here are some thoughts on
that:
- All remembered sets contain only TSO / IND_LOCAL objects
- every update of an old-gen thunk promotes the transitive closure
- no more recordMutable
- every GC must do globalise_mut_list for all mut lists
- write barriers:
- MUT_VAR/MUT_ARR: publish the written pointer
- TSO: as before, TSO can be in the remembered set
- MVAR
- blocking on a BLACKHOLE (modifies the BH, or the BQ)
- sending a message (modifies its link)
-----------------------------------------------------------------------------
-- Allocate MSG_BLACKHOLE locally or globally? (also MSG_THROWTO)
We have a choice here;
1. allocate the MSG_BLACKHOLE in global memory,
and globalise CurrentTSO immediately.
2. allocate the MSG_BLACKHOLE in local memory, leaving it
to messageBlackHole to globalise it (and CurrentTSO) if
necessary.
We need the MSG_BLACKHOLE to be global if:
- the BLACKHOLE is already in global memory, or
- the MSG_BLACKHOLE will be sent to another CPU
For now we do (2), ToDo: try (1) and measure
-----------------------------------------------------------------------------
-- Invariants
1. Pointers from the global heap to the local heap are allowed only in
two places: IND_LOCAL, or the stack of a TSO
1a. TSO stacks point to at most one local heap.
2. every global object that points into a Capability's local heap must
be in that Capability's remembered set (cap->mut_lists[g]).
This means that
* GC_LOCAL need only consult the local mut lists.
* MAINTAINING THE INVARIANT:
* GC_LCCAL needs to do nothing special: the invariant is
automatically maintained.
* GC_SEQ needs to add entries to the appropriate mut list
* GC_PAR may need to save up entries for adding to the appropriate
list.
3. Objects in a Capability's remembered set may only point to the
local heap of that Capability or the global heap.
So when doing a local GC, we only visit objects in the global heap
or our local heap.
-----------------------------------------------------------------------------
-- Why this design?
1. Why have IND_LOCAL rather than always promoting the transitive
closure to maintain the global heap invariant?
- we can have some closures that we do not globalise
- closures with identity, e.g. primitive arrays and suchlike
- mutable objects can still be allocated in the local heap
- we probably want to try to keep mutable closures in the private
heap, otherwise we have to do globalisation/publish on every
write. For this we might want to have two generations in the
local heap.
- might be able to reduce the latency of globalisation requests
from another CPU, by not promoting the whole transitive closure.
- we can use a shared public spark pool and work-stealing without
globalising the entire transitive closure of its contents.
-----------------------------------------------------------------------------
-- How to globalise different closure types [GLOBALISE]
Two operations:
StgClosure * publish (StgClosure *p)
// make an object representing P in the global heap
void globalise (StgClosure **p)
// move P from local to global storage
Every time we write a pointer P into an object in the old generation,
if P points to the local heap, we must write publish(P) instead. This
includes updates. (we cannot overwrite with an IND_LOCAL, because a
race condition between two processors updating the same thunk could
leave an IND_LOCAL pointing to the wrong local heap).
If we receive a message requesting that we globalise a pointer P, then
we try to copy the transitive closure of the pointer into the global
heap, this is globalise(P).
class B: BLACKHOLE
class T: THUNK/PAP/AP, untagged
class C: CONSTR, tagged
class F: FUN, tagged or untagged
class L: large or pinned unpointed
class T: TSOs
class U: small unpointed (MVar#, MutVar#, Array#, Weak#, BCO#,
StableName#, TVar#, PRIM, MUT_PRIM)
publish:
B: IND_LOCAL
T: globalise, or IND_LOCAL
C: globalise, or IND_LOCAL
F: globalise, or IND_LOCAL
L: globalise, or IND_LOCAL
T: globalise, or IND_LOCAL
U: NO
globalise:
B: NO (pointed to by stack, will be updated)
T: copy and replace with IND, publish children
C: copy and replace with forwarding ptr, publish children
F: copy and replace with forwarding ptr, publish children
L: re-link the block, publish children
T: copy, replacing with ThreadRelocated, publish children
U: NO
Note that we can neither publish nor globalise U, hence objects that
point to U can only be published, not globalised.
Since we cannot globalise U, what happens to the closures that point to U?
WE NEVER GLOBALISE A CLOSURE THAT POINTS TO U
Thunks, functions and constructors that point to U are flagged in
their info tables (info->flags & HAS_UNLIFTED_FIELDS), and if
globalise() sees one of these it refuses to globalise the closure.
What about during GC?
U CLOSURES ARE EAGERLY PROMOTED DURING GC
This is to avoid the situation where we have promoted a closure
that points to U, but not the U itself. There is no way to fix
this up post-GC to reestablish the local heap invariant, so instead
we avoid it happening by automatically promoting U closures.
L->U: we can promote L without moving it, so everything's fine.
Alternative:
do *not* eagerly promote C->U, F->U or T->U. We can guarantee
that the C->U, F->U, T->U pointers are not back-pointers, so as long
as we do not eagerly promote the C or F or T closure, we can be sure
that they stay forward-pointers, and hence we never get into a
state where C/F/T has been promoted but not U.
Should we change ENTER() to check for forwarding pointers? why has
this not gone wrong so far? - because forwarded closures are always
tagged, so ENTER just returns.
-----------------------------------------------------------------------------
How to globalise large-family constructors?
Problem is that to get the constructor tag we have to read the info
table, but we want to globalise constructors by replacing the info
pointer with a forwarding pointer.
1. don't tag large-family constructors at all,
case code checks closure type before entering
- extra 2 memory refs on entry :-(
1a. like 1, but code to check closure type is at the return pt,
so can share loading of info ptr.
- 1 extra memory ref
- extra test/branch in common case for returns
- need to distinguish tagged from untagged CONSTR in globalise() :-(
2. tag large-family constructors as before
info table identifies large-family somehow
globalise code replaces with an IND
case return code checks for a special tag value (eg. 0) for IND,
and re-enters
- extra code for re-entry, extra tag in info table :-(
3. tag large-family constructors as before
case join point checks for forwarding ptr
- extra test/branch at return pt for large-family constrs
4. globalising a large-family constructor requires building a new
info table instance in the heap. The new itbl has type
CON_GLOBALISED, and contains the address of the relocated
closure.
- complicated, but no runtime overhead
we currently do (3).
-----------------------------------------------------------------------------
Globalising the mutable list after GC
An object may contain back-pointers after scavenging it; in this case
the GC puts a reference to the object on the appropriate mutable list.
In order to respect the global heap invariant, we must ensure that the
mutable lists of the global generation(s) only contain TSO or
IND_LOCAL objects.
GC always promotes U objects (see [GLOBALISE]), so that directly after
GC globalising a pointer is always possible. So after GC we can
always globalise all the objects on the mutable list, except for TSO
and IND_LOCAL.
The remaining problem is whether we might have TSO or IND_LOCAL
objects on the *wrong* mutable list, i.e. pointing into the wrong
local heap.
TSO: this can certainly happen, we must move the TSO to the correct
mutable list.
IND_LOCAL: this cannot happen, since local GC begins with all
IND_LOCALs pointing to the right local heap, and global GC always
shorts out the IND_LOCALs.
-----------------------------------------------------------------------------
More generations
We would like to be able to expand the heap structure to allow more
generations both local and global. Here I collect notes about the
ramifications of doing so:
1. More local generations
- write barriers are more complicated: if the object is local but
in a non-zero generation, then we use the ordinary write barrier
(add it to the mutable list), otherwise globalise.
- we probably want to keep data in the local old-generation unless
it is required to be global, so the local old-gen's dest points
to itself. Might even want to mark-sweep or compact these.
2. More global generations
- mutable lists may contain not only TSO and IND_LOCAL, but also
objects that point to younger global generations.
- recordClosureMutated_: gen is wrong if we have >2 gens
-----------------------------------------------------------------------------
* TSO fields
The only TSO fields that may be read by another Capability are
tso->cap
- to determine whether the TSO belongs to the current cap or not
A TSO is special in that it may hold global->local pointers either
in its metadata (e.g. tso->bq) or on its stack. The TSO itself must
still reside in the global heap if it is referenced from there, but
clients other than the owning capability can read only the tso->cap
field.
TSO fields are subject to the write barrier as usual. A TSO is
marked dirty (tso->dirty) if any of its fields may contain
global->local pointers. If only the tso->_link and
tso->block_info.prev fields are dirty, then instead of setting
tso->dirty, the TSO_LINK_DIRTY bit may be set in tso->flags. When
marking a TSO dirty it is placed on the mutable list of the owning
Capability.
* ThreadRelocated
When a TSO is moved, the old tso has tso->what_next set to
ThreadRelocated, and tso->_link points to the new instance.
tso->cap in a ThreadRelocated may still be read, but it might be
incorrect (the TSO may have migrated to another Capability). This
may lead to a message being sent to the wrong Capability, which
shouldn't cause any problems other than a message having to be
redirected.
* XXX
The MVar operations still modify a TSO directly, but I think
harmlessly. They modify
** tso->_link
To set it to END_TSO_QUEUE, which is fine
** the stack
To pass the value back for takeMVar, but if the MVar is global
then the TSO and the value will be global too.
-----------------------------------------------------------------------------
-- Weak pointers.
- per-generation weak pointer lists: (WE DO THIS ONE)
- old-gen weak pointers would need to be on the mut list if they
pointed into a younger gen
- would need to globalise_scavenge them on the mut list
- key/value/finalizer could end up being IND_LOCALs
- link could never be an IND_LOCAL, because the link should
always point only to WEAKs in the same gen.
- in global GC, the leader thread calls traverseWeakPtrList
- in local GC, the thread traverses the weak ptr list for its
local gen(s)
- alternative: all WEAK objects are in the global heap
- no need to traverse WEAK objects during local GC
- finalizers do not start until a global GC happens
- must globalise the fields of a WEAK when creating one
- probably terrible for memo tables etc.
- probably terrible for ForeignPtrs
-----------------------------------------------------------------------------
Shorting out IND_LOCAL
- better not short out IND_LOCAL during global GC, as then a TSO
might end up pointing to more than one local heap. Instead, the
best we can do is turn them into IND during scavenge if we find
they no longer point to the local heap.
-----------------------------------------------------------------------------
ALTERNATIVE IDEA
Primitive and/or mutable objects are allocated in a special area of
the global heap (one per HEC), and marked as private or global. e.g.
MUT_VAR_PRIVATE, MUT_VAR_GLOBAL
Thus we can globalise one of these objects by marking it global and
globalising its children. All objects can therefore be globalised
(with the possible exception of BLACKHOLEs).
During a local GC, we must use mark/sweep for this area of the global
heap. Global objects are treated as marked, and we can free any
unreachable private objects (as in Domani et. al. ISMM'00). In GHC we
would either free complete blocks only, or implement Immix-style
region marking.
Compared to the other scheme:
- no need for eager promotion of primitive objects! (well actually,
primitive objects do get eagerly promoted, but without moving
them).
- we can globalise everything, globalise is simpler.
- write barriers are a bit simpler and cheaper: check info pointer,
maybe globalise (well actually, currently the check is worse
because it is a bdescr->gen check plus isGlobal).
- we need to duplicate all info tables for primitive objects, but
private/global can be a bit in the flags field of the info table,
so don't need to duplicate all the closure types too.
- we need to set up the per-Capability primitive areas of the global
generation, and arrange that they get marked/swept. Sweeping has
to traverse the primitive heap linearly looking for global objects.
- TSOs don't need to be globalised, they can be implicitly global,
similarly for BLOCKING_QUEUE and other private objects.
- Evac:
- in local GC:
if the closure is global, we're done
if the closure is private, mark it and push it on the mark stack.
- in global GC:
copy the closure as normal.
Even though the prim areas are local heap, we don't have to
record pointers from the global heap to the prim heap in the
remembered set. Instead we transitively mark all the global
objects in the prim area, so that they don't get discarded by
local GC.
What about clean/dirty?
- for TSO: still need clean/dirty
- for MUT_VAR and others: no need to do this, as the write barrier
globalises. Though we could also have muliple local generations,
and then we would need
MUT_VAR_CLEAN, MUT_VAR_DIRTY, MUT_VAR_GLOBAL
and a 3-way write barrier.
-----------------------------------------------------------------------------
Sources of overhead
- checking for forwarding pointers in apply code, PAP code, large
family constructor cases.
- slower allocation of primitive objects
- not promoting prim objects in the local heap, so they get
repeatedly scanned during local GC.
- thread migration is more expensive
-----------------------------------------------------------------------------
Related work
- DLG
- "Thread-local heaps for Java" (Domani et. al.)
(source of idea for mark-sweep with a bit to represent local/global)
- "Thread-specific heaps for Multi-threaded programs" (Steensgaard)
- "Optimisations in a private-nursery based collector"
(forces local GC to avoid violating local heap invariant; mutables
are allowed in the young gen)
To look at:
- "Pillar: A parallel implementation language"
......@@ -55,12 +55,14 @@ module CLabel (
mkSplitMarkerLabel,
mkDirty_MUT_VAR_Label,
mkDirty_MUT_ARR_Label,
mkUpdInfoLabel,
mkBHUpdInfoLabel,
mkIndStaticInfoLabel,
mkMainCapabilityLabel,
mkMUT_VAR_GLOBAL_infoLabel,
mkMAP_FROZEN_infoLabel,
mkMAP_DIRTY_infoLabel,
mkMAP_GLOBAL_infoLabel,
mkEMPTY_MVAR_infoLabel,
mkTopTickyCtrLabel,
......@@ -377,12 +379,14 @@ mkStaticConEntryLabel name c = IdLabel name c StaticConEntry
-- Constructing Cmm Labels
mkSplitMarkerLabel = CmmLabel rtsPackageId (fsLit "__stg_split_marker") CmmCode
mkDirty_MUT_VAR_Label = CmmLabel rtsPackageId (fsLit "dirty_MUT_VAR") CmmCode
mkDirty_MUT_ARR_Label = CmmLabel rtsPackageId (fsLit "dirty_MUT_ARR") CmmCode
mkUpdInfoLabel = CmmLabel rtsPackageId (fsLit "stg_upd_frame") CmmInfo
mkBHUpdInfoLabel = CmmLabel rtsPackageId (fsLit "stg_bh_upd_frame" ) CmmInfo
mkIndStaticInfoLabel = CmmLabel rtsPackageId (fsLit "stg_IND_STATIC") CmmInfo
mkMainCapabilityLabel = CmmLabel rtsPackageId (fsLit "MainCapability") CmmData
mkMUT_VAR_GLOBAL_infoLabel = CmmLabel rtsPackageId (fsLit "stg_MUT_VAR_GLOBAL") CmmInfo
mkMAP_FROZEN_infoLabel = CmmLabel rtsPackageId (fsLit "stg_MUT_ARR_PTRS_FROZEN0") CmmInfo
mkMAP_DIRTY_infoLabel = CmmLabel rtsPackageId (fsLit "stg_MUT_ARR_PTRS_DIRTY") CmmInfo
mkMAP_GLOBAL_infoLabel = CmmLabel rtsPackageId (fsLit "stg_MUT_ARR_PTRS_GLOBAL") CmmInfo
mkEMPTY_MVAR_infoLabel = CmmLabel rtsPackageId (fsLit "stg_EMPTY_MVAR") CmmInfo
mkTopTickyCtrLabel = CmmLabel rtsPackageId (fsLit "top_ct") CmmData
mkCAFBlackHoleInfoTableLabel = CmmLabel rtsPackageId (fsLit "stg_CAF_BLACKHOLE") CmmInfo
......
......@@ -399,7 +399,7 @@ cgEvalAlts cc_slot bndr alt_type@(PrimAlt tycon) alts
; cgPrimAlts GCMayHappen alt_type reg alts }
; lbl <- emitReturnTarget (idName bndr) abs_c
; returnFC (CaseAlts lbl Nothing bndr) }
; returnFC (CaseAlts lbl bndr 0) }
cgEvalAlts cc_slot bndr (UbxTupAlt _) [(con,args,_,rhs)]
= -- Unboxed tuple case
......@@ -421,7 +421,7 @@ cgEvalAlts cc_slot bndr (UbxTupAlt _) [(con,args,_,rhs)]
; unbxTupleHeapCheck live_regs ptrs nptrs noStmts
(cgExpr rhs) }
; lbl <- emitReturnTarget (idName bndr) abs_c
; returnFC (CaseAlts lbl Nothing bndr) }
; returnFC (CaseAlts lbl bndr 0) }
cgEvalAlts cc_slot bndr alt_type alts
= -- Algebraic and polymorphic case
......@@ -439,10 +439,9 @@ cgEvalAlts cc_slot bndr alt_type alts
; (alts, mb_deflt) <- cgAlgAlts GCMayHappen cc_slot alt_type alts
; (lbl, branches) <- emitAlgReturnTarget (idName bndr)
alts mb_deflt fam_sz
; lbl <- emitAlgReturnTarget (idName bndr) alts mb_deflt fam_sz
; returnFC (CaseAlts lbl branches bndr) }
; returnFC (CaseAlts lbl bndr fam_sz) }
where
fam_sz = case alt_type of
AlgAlt tc -> tyConFamilySize tc
......
......@@ -567,31 +567,23 @@ link_caf cl_info _is_upd = do
; hp_offset <- allocDynClosure bh_cl_info use_cc blame_cc [(tso,fixedHdrSize)]
; hp_rel <- getHpRelOffset hp_offset
-- Call the RTS function newCAF to add the CAF to the CafList
-- so that the garbage collector can find them
-- Call the RTS function newCAF. This:
-- - creates an IND_LOCAL to point to the local BH
-- - updates the CAF with an IND_STATIC pointing to the IND_LOCAL
-- - adds the CAF to the CAF list if necessary
-- This must be done *before* the info table pointer is overwritten,
-- because the old info table ptr is needed for reversion
; emitRtsCallWithVols rtsPackageId (fsLit "newCAF")
[ CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint,
CmmHinted (CmmReg nodeReg) AddrHint ]
CmmHinted (CmmReg nodeReg) AddrHint,
CmmHinted hp_rel AddrHint ]
[node] False
-- node is live, so save it.
-- Overwrite the closure with a (static) indirection
-- to the newly-allocated black hole
; stmtsC [ CmmStore (cmmRegOffW nodeReg off_indirectee) hp_rel
, CmmStore (CmmReg nodeReg) ind_static_info ]
; returnFC hp_rel }
where
bh_cl_info :: ClosureInfo
bh_cl_info = cafBlackHoleClosureInfo cl_info
ind_static_info :: CmmExpr
ind_static_info = mkLblExpr mkIndStaticInfoLabel
off_indirectee :: WordOff
off_indirectee = fixedHdrSize + oFFSET_StgInd_indirectee*wORD_SIZE
\end{code}
......
......@@ -44,7 +44,6 @@ import IdInfo
import Type
import PrelInfo
import Outputable
import ListSetOps
import Util
import Module
import FastString
......@@ -242,7 +241,8 @@ bindConArgs con args
-- The binding below forces the masking out of the tag bits
-- when accessing the constructor field.
bind_arg (arg, offset) = bindNewToUntagNode arg offset (mkLFArgument arg) (tagForCon con)
(_, args_w_offsets) = layOutDynConstr con (addIdReps args)
(_, _, args_w_offsets) = mkVirtHeapOffsets False{-not a thunk-}
(addIdReps args)
--
ASSERT(not (isUnboxedTupleCon con)) return ()
mapCs bind_arg args_w_offsets
......@@ -316,31 +316,7 @@ cgReturnDataCon con amodes
| opt_SccProfilingOn = build_it_then enter_it
| otherwise
= ASSERT( amodes `lengthIs` dataConRepArity con )
do { EndOfBlockInfo _ sequel <- getEndOfBlockInfo
; case sequel of
CaseAlts _ (Just (alts, deflt_lbl)) bndr
-> -- Ho! We know the constructor so we can
-- go straight to the right alternative
case assocMaybe alts (dataConTagZ con) of {
Just join_lbl -> build_it_then (jump_to join_lbl);
Nothing
-- Special case! We're returning a constructor to the default case
-- of an enclosing case. For example:
--
-- case (case e of (a,b) -> C a b) of
-- D x -> ...
-- y -> ...<returning here!>...
--
-- In this case,
-- if the default is a non-bind-default (ie does not use y),
-- then we should simply jump to the default join point;
| isDeadBinder bndr -> performReturn (jump_to deflt_lbl)
| otherwise -> build_it_then (jump_to deflt_lbl) }
_otherwise -- The usual case
-> build_it_then emitReturnInstr
}
build_it_then emitReturnInstr
where
enter_it = stmtsC [ CmmAssign nodeReg (cmmUntag (CmmReg nodeReg)),
CmmJump (entryCode (closureInfoPtr (CmmReg nodeReg))) [] ]
......
......@@ -341,7 +341,10 @@ mkRhsClosure bndr cc bi
where
lf_info = mkSelectorLFInfo bndr offset_into_int
(isUpdatable upd_flag)
(_, params_w_offsets) = layOutDynConstr con (addIdReps params)
(_, _, params_w_offsets) = mkVirtHeapOffsets False{-not a thunk-}
(addIdReps params)
-- Just want the layout
maybe_offset = assocMaybe params_w_offsets selectee
Just the_offset = maybe_offset
......
......@@ -261,26 +261,45 @@ emitAlgReturnTarget
-> [(ConTagZ, CgStmts)] -- Tagged branches
-> Maybe CgStmts -- Default branch (if any)
-> Int -- family size
-> FCode (CLabel, SemiTaggingStuff)
-> FCode CLabel
emitAlgReturnTarget name branches mb_deflt fam_sz
= do { blks <- getCgStmts $
-- is the constructor tag in the node reg?
if isSmallFamily fam_sz
then do -- yes, node has constr. tag
let tag_expr = cmmConstrTag1 (CmmReg nodeReg)
branches' = [(tag+1,branch)|(tag,branch)<-branches]
emitSwitch tag_expr branches' mb_deflt 1 fam_sz
else do -- no, get tag from info table
let -- Note that ptr _always_ has tag 1
-- when the family size is big enough
untagged_ptr = cmmRegOffB nodeReg (-1)
tag_expr = getConstrTag (untagged_ptr)
emitSwitch tag_expr branches mb_deflt 0 (fam_sz - 1)
; lbl <- emitReturnTarget name blks
; return (lbl, Nothing) }
-- Nothing: the internal branches in the switch don't have
-- global labels, so we can't use them at the 'call site'
= do
blks <- getCgStmts $
-- is the constructor tag in the node reg?
if isSmallFamily fam_sz
then do -- yes, node has constr. tag
let tag_expr = cmmConstrTag1 (CmmReg nodeReg)
branches' = [(tag+1,branch)|(tag,branch)<-branches]
emitSwitch tag_expr branches' mb_deflt 1 fam_sz
else do -- no, get tag from info table
redo <- newLabelC
is_fwd <- newLabelC
labelC redo
ip <- newTemp bWord
tag <- newTemp bWord
let iptr = CmmReg (CmmLocal ip)
let untagged_ptr = cmmRegOffB nodeReg (-1)
let one = CmmLit (mkIntCLit 1)
stmtC $ CmmAssign (CmmLocal ip) (closureInfoPtr untagged_ptr)
-- check for a forwarding pointer; if it is, we have to
-- follow it to the real closure
let
cond = CmmMachOp mo_wordNe [
CmmMachOp mo_wordAnd [iptr, one],
CmmLit zeroCLit
]
tag_expr = CmmMachOp (MO_UU_Conv halfWordWidth wordWidth) [
infoTableConstrTag (infoTable iptr)
]
stmtC $ CmmCondBranch cond is_fwd
emitSwitch tag_expr branches mb_deflt 0 (fam_sz - 1)
labelC is_fwd
-- iptr is already tagged with 1, no need to do any arithmetic
stmtC $ CmmAssign nodeReg iptr
stmtC $ CmmBranch redo
--
emitReturnTarget name blks
--------------------------------
emitReturnInstr :: Code
......
......@@ -27,7 +27,7 @@ module CgMonad (
forkLabelledCode,
forkClosureBody, forkStatics, forkAlts, forkEval,
forkEvalHelp, forkProc, codeOnly,
SemiTaggingStuff, ConTagZ,
ConTagZ,
EndOfBlockInfo(..),
setEndOfBlockInfo, getEndOfBlockInfo,
......@@ -169,15 +169,9 @@ data Sequel
= OnStack -- Continuation is on the stack
| CaseAlts
CLabel -- Jump to this; if the continuation is for a vectored
-- case this might be the label of a return vector
SemiTaggingStuff
CLabel -- Jump to this
Id -- The case binder, only used to see if it's dead
type SemiTaggingStuff
= Maybe -- Maybe[1] we don't have any semi-tagging stuff...
([(ConTagZ, CmmLit)], -- Alternatives
CmmLit) -- Default (will be a can't happen RTS label if can't happen)
Int -- family size
type ConTagZ = Int -- A *zero-indexed* contructor tag
......
......@@ -32,6 +32,8 @@ import Constants
import Outputable
import FastString
#include "HsVersions.h"
-- ---------------------------------------------------------------------------
-- Code generation for PrimOps
......@@ -132,19 +134,38 @@ emitPrimOp [res] ParOp [arg] live
emitPrimOp [res] ReadMutVarOp [mutv] _
= stmtC (CmmAssign (CmmLocal res) (cmmLoadIndexW mutv fixedHdrSize gcWord))
emitPrimOp [] WriteMutVarOp [mutv,var] live
emitPrimOp [] WriteMutVarOp [mutv,val] live
= do
stmtC (CmmStore (cmmOffsetW mutv fixedHdrSize) var)
vols <- getVolatileRegs live
join <- newLabelC
-- store the value in a register, in case it is a non-trivial expression
tmpl <- newTemp gcWord
let tmp = CmmReg (CmmLocal tmpl)
stmtC (CmmAssign (CmmLocal tmpl) val)
-- save the address of the mut var in a temporary, becuase it may not
-- be present in 'live' and hence won't be automatically saved across
-- the foreign call below (live only contains live-in-alts, not
-- live-in-whole-case, when the primop is the scrutinee of a case).
mutl <- newTemp gcWord
let mut = CmmReg (CmmLocal mutl)
stmtC (CmmAssign (CmmLocal mutl) mutv)
stmtC (CmmCondBranch (CmmMachOp mo_wordNe [
closureInfoPtr mut,
CmmLit (CmmLabel mkMUT_VAR_GLOBAL_infoLabel) ])
join)
emitForeignCall' PlayRisky
[{-no results-}]
(CmmCallee (CmmLit (CmmLabel mkDirty_MUT_VAR_Label))
CCallConv)
[CmmHinted tmpl AddrHint]
(CmmCallee (CmmLit (CmmLabel mkDirty_MUT_VAR_Label)) CCallConv)
[ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint)
, (CmmHinted mutv AddrHint) ]
, (CmmHinted tmp AddrHint) ]
(Just vols)
NoC_SRT -- No SRT b/c we do PlayRisky
CmmMayReturn
labelC join
stmtC (CmmStore (cmmOffsetW mut fixedHdrSize) tmp)
-- #define sizzeofByteArrayzh(r,a) \
-- r = ((StgArrWords *)(a))->bytes
......@@ -216,17 +237,17 @@ emitPrimOp [] CopyMutableArrayOp [src,src_off,dst,dst_off,n] live =
emitPrimOp [res] CloneArrayOp [src,src_off,n] live =
emitCloneArray mkMAP_FROZEN_infoLabel res src src_off n live
emitPrimOp [res] CloneMutableArrayOp [src,src_off,n] live =
emitCloneArray mkMAP_DIRTY_infoLabel res src src_off n live
emitCloneArray mkMAP_GLOBAL_infoLabel res src src_off n live
emitPrimOp [res] FreezeArrayOp [src,src_off,n] live =
emitCloneArray mkMAP_FROZEN_infoLabel res src src_off n live
emitPrimOp [res] ThawArrayOp [src,src_off,n] live =
emitCloneArray mkMAP_DIRTY_infoLabel res src src_off n live
emitCloneArray mkMAP_GLOBAL_infoLabel res src src_off n live
-- Reading/writing pointer arrays
emitPrimOp [r] ReadArrayOp [obj,ix] _ = doReadPtrArrayOp r obj ix
emitPrimOp [r] IndexArrayOp [obj,ix] _ = doReadPtrArrayOp r obj ix
emitPrimOp [] WriteArrayOp [obj,ix,v] _ = doWritePtrArrayOp obj ix v
emitPrimOp [] WriteArrayOp [obj,ix,v] live = doWritePtrArrayOp obj ix v live
emitPrimOp [res] SizeofArrayOp [arg] _
= stmtC $ CmmAssign (CmmLocal res) (cmmLoadIndexW arg (fixedHdrSize + oFFSET_StgMutArrPtrs_ptrs) bWord)
......@@ -588,19 +609,48 @@ doWriteByteArrayOp maybe_pre_write_cast rep [] [addr,idx,val]
doWriteByteArrayOp _ _ _ _
= panic "CgPrimOp: doWriteByteArrayOp"
doWritePtrArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> Code
doWritePtrArrayOp addr idx val
= do mkBasicIndexedWrite arrPtrsHdrSize Nothing bWord addr idx val
stmtC (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
-- the write barrier. We must write a byte into the mark table:
-- bits8[a + header_size + StgMutArrPtrs_size(a) + x >> N]
stmtC $ CmmStore (
cmmOffsetExpr
(cmmOffsetExprW (cmmOffsetB addr arrPtrsHdrSize)
(loadArrPtrsSize addr))
(CmmMachOp mo_wordUShr [idx,
CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS)])
) (CmmLit (CmmInt 1 W8))
doWritePtrArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> StgLiveVars -> Code
doWritePtrArrayOp addr idx val live
= do vols <- getVolatileRegs live
join <- newLabelC
-- store the value in a register, in case it is a non-trivial expression
tmpl <- newTemp gcWord
let tmp = CmmReg (CmmLocal tmpl)
stmtC (CmmAssign (CmmLocal tmpl) val)
-- save the address of the array in a temporary, becuase it may not
-- be present in 'live' and hence won't be automatically saved across
-- the foreign call below (live only contains live-in-alts, not
-- live-in-whole-case, when the primop is the scrutinee of a case).
arrl <- newTemp gcWord
let arr = CmmReg (CmmLocal arrl)
stmtC (CmmAssign (CmmLocal arrl) addr)
stmtC (CmmCondBranch (CmmMachOp mo_wordNe [
closureInfoPtr arr,
CmmLit (CmmLabel mkMAP_GLOBAL_infoLabel) ])
join)
emitForeignCall' PlayRisky
[CmmHinted tmpl AddrHint]
(CmmCallee (CmmLit (CmmLabel mkDirty_MUT_ARR_Label)) CCallConv)
[ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint)
, (CmmHinted tmp AddrHint) ]
(Just vols)
NoC_SRT -- No SRT b/c we do PlayRisky
CmmMayReturn
labelC join
mkBasicIndexedWrite arrPtrsHdrSize Nothing bWord arr idx tmp
-- -- the write barrier. We must write a byte into the mark table:
-- -- bits8[a + header_size + StgMutArrPtrs_size(a) + x >> N]
-- stmtC (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
-- stmtC $ CmmStore (
-- cmmOffsetExpr
-- (cmmOffsetExprW (cmmOffsetB addr arrPtrsHdrSize)
-- (loadArrPtrsSize addr))
-- (CmmMachOp mo_wordUShr [idx,
-- CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS)])
-- ) (CmmLit (CmmInt 1 W8))
loadArrPtrsSize :: CmmExpr -> CmmExpr
loadArrPtrsSize addr = CmmLoad (cmmOffsetB addr off) bWord
......@@ -672,6 +722,9 @@ emitCopyArray :: (CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> StgLiveVars
-> Code
emitCopyArray copy src0 src_off0 dst0 dst_off0 n0 live = do
-- XXX need to fix for local GC
WARN(True, text "emitCopyArray: needs fixing for local GC") return ()
-- Assign the arguments to temporaries so the code generator can
-- calculate liveness for us.
src <- assignTemp_ src0
......@@ -681,7 +734,7 @@ emitCopyArray copy src0 src_off0 dst0 dst_off0 n0 live = do
n <- assignTemp_ n0
-- Set the dirty bit in the header.
stmtC (setInfo dst (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
stmtC (setInfo dst (CmmLit (CmmLabel mkMAP_GLOBAL_infoLabel)))
dst_elems_p <- assignTemp $ cmmOffsetB dst arrPtrsHdrSize
dst_p <- assignTemp $ cmmOffsetExprW dst_elems_p dst_off
......@@ -702,6 +755,9 @@ emitCopyArray copy src0 src_off0 dst0 dst_off0 n0 live = do
emitCloneArray :: CLabel -> CmmFormal -> CmmExpr -> CmmExpr -> CmmExpr
-> StgLiveVars -> Code
emitCloneArray info_p res_r src0 src_off0 n0 live = do
-- XXX need to fix for local GC
WARN(True, text "emitCloneArray: needs fixing for local GC") return ()
-- Assign the arguments to temporaries so the code generator can
-- calculate liveness for us.
src <- assignTemp_ src0
......
......@@ -182,7 +182,6 @@ performTailCall fun_info arg_amodes pending_assts
fun_name = idName fun_id
lf_info = cgIdInfoLF fun_info
fun_has_cafs = idCafInfo fun_id
untag_node = CmmAssign nodeReg (cmmUntag (CmmReg nodeReg))
-- Test if closure is a constructor
maybeSwitchOnCons enterClosure eob
| EndOfBlockInfo _ (CaseAlts lbl _ _) <- eob,
......@@ -195,7 +194,7 @@ performTailCall fun_info arg_amodes pending_assts
; stmtC (CmmCondBranch (cmmIsTagged (CmmReg nodeReg))
is_constr)
-- No, enter the closure.
; enterClosure
; _ <- enterClosure
; labelC is_constr
; stmtC (CmmJump (entryCode $ CmmLit (CmmLabel lbl)) [])
}
......@@ -220,8 +219,15 @@ performTailCall fun_info arg_amodes pending_assts
-}
-- No case expression involved, enter the closure.
| otherwise
= do { stmtC untag_node
; enterClosure
= do { is_constr <- newLabelC
-- Is the pointer tagged?
-- Yes, jump to switch statement
; stmtC (CmmCondBranch (cmmIsTagged (CmmReg nodeReg))
is_constr)
-- No, enter the closure.
; _ <- enterClosure
; labelC is_constr
; emitReturnInstr
}
where
--cond1 tag = cmmULtWord tag lowCons
......
......@@ -209,7 +209,7 @@ mkRhsClosure bndr cc bi
body@(StgCase (StgApp scrutinee [{-no args-}])
_ _ _ _ -- ignore uniq, etc.
(AlgAlt _)
[(DataAlt con, params, _use_mask,
[(DataAlt _, params, _use_mask,
(StgApp selectee [{-no args-}]))])
| the_fv == scrutinee -- Scrutinee is the only free variable
&& maybeToBool maybe_offset -- Selectee is a component of the tuple
......@@ -226,8 +226,8 @@ mkRhsClosure bndr cc bi
where
lf_info = mkSelectorLFInfo bndr offset_into_int
(isUpdatable upd_flag)
(_, params_w_offsets) = layOutDynConstr con (addIdReps params)
-- Just want the layout
(_, _, params_w_offsets) = mkVirtHeapOffsets False{-not a thunk-}
(addIdReps params)
maybe_offset = assocMaybe params_w_offsets (NonVoid selectee)
Just the_offset = maybe_offset
offset_into_int = the_offset - fixedHdrSize
......@@ -277,11 +277,12 @@ mkRhsClosure bndr cc _ fvs upd_flag srt args body
; c_srt <- getSRTInfo srt
; let name = idName bndr
descr = closureDescription mod_name name
fv_infos = addIdReps (map stripNV reduced_fvs)
fv_details :: [(NonVoid Id, VirtualHpOffset)]
(tot_wds, ptr_wds, fv_details)
= mkVirtHeapOffsets (isLFThunk lf_info)
(tot_wds, ptr_wds, fv_details)
= mkVirtHeapOffsets (isLFThunk lf_info)
(addIdReps (map stripNV reduced_fvs))
closure_info = mkClosureInfo False -- Not static
closure_info = mkClosureInfo False -- Not static
bndr lf_info tot_wds ptr_wds
c_srt descr
......
......@@ -217,7 +217,8 @@ bindConArgs (DataAlt con) base args
= ASSERT(not (isUnboxedTupleCon con))
mapM bind_arg args_w_offsets
where
(_, args_w_offsets) = layOutDynConstr con (addIdReps args)
(_, _, args_w_offsets) = mkVirtHeapOffsets False{-not a thunk-}
(addIdReps args)
tag = tagForCon con
......
......@@ -640,7 +640,7 @@ doWriteByteArrayOp _ _ _
doWritePtrArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> FCode ()
doWritePtrArrayOp addr idx val
= do mkBasicIndexedWrite arrPtrsHdrSize Nothing addr idx val
emit (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
emit (setInfo addr (CmmLit (CmmLabel undefined {-TODO: mkMAP_DIRTY_infoLabel-})))
-- the write barrier. We must write a byte into the mark table:
-- bits8[a + header_size + StgMutArrPtrs_size(a) + x >> N]
emit $ mkStore (
......
......@@ -199,7 +199,7 @@ readCType i
| i' == aP_CODE = AP
| i == AP_STACK = AP
| i' == pAP_CODE = PAP
| i == MUT_VAR_CLEAN || i == MUT_VAR_DIRTY= MutVar i'
| i == MUT_VAR_LOCAL || i == MUT_VAR_GLOBAL= MutVar i'
| i == MVAR_CLEAN || i == MVAR_DIRTY = MVar i'
| otherwise = Other i'
where i' = fromIntegral i
......
......@@ -109,6 +109,9 @@
#define UNTAG(p) (p & ~TAG_MASK)
#define GETTAG(p) (p & TAG_MASK)
#define IS_FORWARDING_PTR(p) (((p) & 1) != 0)
#define UN_FORWARDING_PTR(p) ((p) - 1)
#if SIZEOF_INT == 4
#define CInt bits32
#elif SIZEOF_INT == 8
......@@ -296,7 +299,7 @@
case \
IND, \
IND_PERM, \
IND_STATIC: \
IND_STATIC: \
{ \
P1 = StgInd_indirectee(P1); \
goto again; \
......@@ -383,8 +386,8 @@
// allocate() - this includes many of the primops.
#define MAYBE_GC(liveness,reentry) \
if (bdescr_link(CurrentNursery) == NULL || \
generation_n_new_large_words(W_[g0]) >= CLong[large_alloc_lim]) { \
R9 = liveness; \
generation_n_new_large_words(StgRegTable_rG0(BaseReg)) >= CLong[large_alloc_lim]) { \
R9 = liveness; \
R10 = reentry; \
HpAlloc = 0; \
jump stg_gc_gen_hp; \
......@@ -431,7 +434,8 @@
/* Debugging macros */
#define LOOKS_LIKE_INFO_PTR(p) \
((p) != NULL && \
LOOKS_LIKE_INFO_PTR_NOT_NULL(p))
(IS_FORWARDING_PTR(p) || \
LOOKS_LIKE_INFO_PTR_NOT_NULL(p)))
#define LOOKS_LIKE_INFO_PTR_NOT_NULL(p) \
( (TO_W_(%INFO_TYPE(%STD_INFO(p))) != INVALID_OBJECT) && \
......@@ -469,6 +473,9 @@
#define mutArrPtrCardUp(i) (((i) + mutArrCardMask) >> MUT_ARR_PTRS_CARD_BITS)
#define mutArrPtrsCardWords(n) ROUNDUP_BYTES_TO_WDS(mutArrPtrCardUp(n))
#define isGlobalPrim(bd,p) \
(TO_W_(bdescr_gen_ix(bd)) >= TO_W_(CInt[global_gen_ix]) || (W_[(p) - WDS(1)] != 0))
#if defined(PROFILING) || (!defined(THREADED_RTS) && defined(DEBUG))
#define OVERWRITING_CLOSURE(c) foreign "C" overwritingClosure(c "ptr")
#else
......
......@@ -227,6 +227,7 @@ main(int argc, char *argv[])
field_offset(StgRegTable, rHpAlloc);
struct_field(StgRegTable, rRet);
struct_field(StgRegTable, rNursery);
struct_field(StgRegTable, rG0);
def_offset("stgEagerBlackholeInfo", FUN_OFFSET(stgEagerBlackholeInfo));
def_offset("stgGCEnter1", FUN_OFFSET(stgGCEnter1));
......@@ -243,10 +244,12 @@ main(int argc, char *argv[])
struct_field(bdescr, free);
struct_field(bdescr, blocks);
struct_field(bdescr, gen_no);
struct_field(bdescr, gen_ix);
struct_field(bdescr, link);
struct_size(generation);
struct_field(generation, n_new_large_words);
struct_field(generation, weak_ptrs);
struct_size(CostCentreStack);
struct_field(CostCentreStack, ccsID);
......
......@@ -215,22 +215,20 @@
/* Win32 only: */
#define BlockedOnDoProc 7
/* Only relevant for PAR: */
/* blocked on a remote closure represented by a Global Address: */
#define BlockedOnGA 8
/* same as above but without sending a Fetch message */
#define BlockedOnGA_NoSend 9
/* Only relevant for THREADED_RTS: */
#define BlockedOnCCall 10
#define BlockedOnCCall_Interruptible 11
/* same as above but permit killing the worker thread */
#define BlockedOnCCall 8
#define BlockedOnCCall_Interruptible 9
/* same as above but permit interrupting the call */
/* Involved in a message sent to tso->msg_cap */
#define BlockedOnMsgThrowTo 12
#define BlockedOnMsgThrowTo 10
/* The thread is not on any run queues, but can be woken up
by tryWakeupThread() */
#define ThreadMigrating 13
#define ThreadMigrating 11
/* Involved in a message sent to tso->msg_cap */
#define BlockedOnMsgGlobalise 12
/*
* These constants are returned to the scheduler by a thread that has
......
......@@ -180,6 +180,22 @@
* #define BlockedOnMsgThrowTo 16
*/
#define THREAD_SUSPENDED_FOREIGN_CALL 6
/*
* 7-20 are the tso->why_blocked values (+6)
*
* #define BlockedOnMVar 7
* #define BlockedOnBlackHole 8
* #define BlockedOnRead 9
* #define BlockedOnWrite 10
* #define BlockedOnDelay 11
* #define BlockedOnSTM 12
* #define BlockedOnDoProc 13
* #define BlockedOnCCall 14
* #define BlockedOnCCall_NoUnblockExc 15
* #define BlockedOnMsgThrowTo 16
* #define ThreadMigrating 17
* #define BlockedOnMsgGlobalise 18
*/
/*
* Capset type values for EVENT_CAPSET_CREATE
......
......@@ -36,6 +36,7 @@ struct GC_FLAGS {
nat minAllocAreaSize; /* in *blocks* */
nat minOldGenSize; /* in *blocks* */
nat heapSizeSuggestion; /* in *blocks* */
nat fixedAllocHeapSizeSuggestion; /* in *blocks* */
rtsBool heapSizeSuggestionAuto;
double oldGenFactor;
double pcFreeHeap;
......@@ -74,6 +75,7 @@ struct DEBUG_FLAGS {
rtsBool squeeze; /* 'z' stack squeezing & lazy blackholing */
rtsBool hpc; /* 'c' coverage */
rtsBool sparks; /* 'r' */
rtsBool mallocleaks; /* 'k' */
};
struct COST_CENTRE_FLAGS {
......
......@@ -16,6 +16,8 @@
#ifdef PROFILING
void LDV_recordDead (StgClosure *c, nat size);
/* retrieves the LDV word from closure c */
#define LDVW(c) (((StgClosure *)(c))->header.prof.hp.ldvw)
......@@ -33,6 +35,9 @@
#else
#define LDV_RECORD_DEAD(c,size) \
LDV_recordDead((StgClosure *)(p), size);
#define LDV_RECORD_CREATE(c) \
LDVW((c)) = ((StgWord)RTS_DEREF(era) << LDV_SHIFT) | LDV_STATE_CREATE
......@@ -40,7 +45,8 @@
#else /* !PROFILING */
#define LDV_RECORD_CREATE(c) /* nothing */
#define LDV_RECORD_CREATE(c) /* nothing */
#define LDV_RECORD_DEAD(c,size) /* nothing */
#endif /* PROFILING */
......