[GHC] #7670: StablePtrs should be organized by generation for efficient minor collections
GHC
ghc-devs at haskell.org
Tue Aug 21 21:30:02 UTC 2018
#7670: StablePtrs should be organized by generation for efficient minor
collections
-------------------------------------+-------------------------------------
Reporter: ezyang | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Runtime System | Version: 7.7
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by dfeuer):
I've been thinking about the `StableName#` representation some, and I
really don't like the redundancy between stable name objects and stable
name table entries. I can think of two approaches to fixing this: get rid
of the stable name table or get rid of stable name objects.
=== Get rid of the stable name table
This is my preferred approach, if it's workable, because it seems almost
absurdly simple. Suppose we have one counter to generate IDs (the results
of `hashStableName#`) and one hash table per generation mapping heap
pointers to stable name objects. A stable name object would look like
{{{
StableNameObject:
Header
ID -- for hashStableName#
Underlying object, treated as a weak reference
}}}
`makeStableName#` would check the hash table for the appropriate
generation to see if there's already a stable name object (SNO). If not,
it gets a fresh `ID` and builds the SNO.
Garbage collecting the hash tables, roughly speaking:
Perform a normal collection, leaving the underlying object pointers
pointing to from-space. Traverse all the hash table entries in the table
for the generation currently being collected. For each SNO pointer in the
table, check the SNO for liveness. If it's alive, get the to-space address
of its underlying object, edit the SNO accordingly, and insert it into the
hash table for the next generation. If the underlying object is dead, null
out that field.
Is this too simple, or just simple enough? I don't really understand the
idea of per-capability lists--how do you know which one a particular
target should be inserted into? But presumably if we did that, we'd
partition the ID space by high bit to give each capability its own
counter.
=== Get rid of stable name objects
1. Change the stable name table to a representation that can grow without
moving. Guess: an array of arrays, where each array is either empty or
twice the size of the one to its left.
2. Add a heap object-style header to each stable name table entry. So each
entry will look like
{{{
SNTableEntry:
Header
Index (for hashStableName#)
Underlying object
}}}
Now a `StableName#` becomes a pointer directly into the stable name table.
The garbage collector can recognize the closure type and handle it
specially. Note that stable name table entries pointing to old objects
will always be put in the old-generation stable name table. I don't know
enough about the garbage collector to say exactly how that should work.
The free list can probably just run through the headers.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7670#comment:12>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list