Version 24 (modified by bacek, 5 years ago)

GC irc talk

Tasks

  • Create an incremental tri-color mark GC module
  • Integrate the new incremental GC into the existing system (See #670)
  • Consider deleting src/gc/res_lea.c (doesn't work anyway) (See #655 and #490)

Completed Tasks

  • Rename files in src/gc for sanity, suggested names:
    • memory.c -> alloc_memory.c or mem_allocate.c (r39002)
    • register.c -> alloc_registers.c or reg_allocate.c (r39003)
    • resources.c -> alloc_resources.c or resource_allocate.c (r39004)
  • Collapse src/gc/smallobject.c into src/gc/api.c.(r39022 and r39023)
  • Move src/malloc.c and src/malloc-trace.c into src/gc (not strictly GC, but want to group all memory management), consider deleting if only used by src/gc/res_lea.c (r39006)

Improve abstraction/encapsulation for existing GC modules. (r38654 and later)

If there are any non-API functions in src/gc/api.c move them into another file, possibly src/gc/common.c to indicate that they're internal to the GC system only, but shared between all the GC modules. (r38654 file currently named "mark_sweep.c")


Renamed all API functions to Parrot_gc_* (r34775).


Renamed files:

  • dod.c -> api.c and dod.h -> gc_api.h (r34774)
  • gc_gms.c -> generational_ms.c (r34795)
  • gc_ims.c -> incremental_ms.c (r34796)

Branch History

svn copy  https://svn.perl.org/parrot/trunk \

 https://svn.perl.org/parrot/branches/pdd09gc_part1 \

-m "Creating a branch for the first round of GC refactoring."

initial revision: r34100

SVK merged r34113


(allison) svn copy  https://svn.perl.org/parrot/trunk \

 https://svn.perl.org/parrot/branches/pdd09gc_part2 \

-m "Creating a branch for a second round of GC refactoring, cleanups and code reorganization."

initial revision: r34686

(chromatic)

Brought the GC refactoring branch up to date with trunk r35194.

new revision: r35195

(allison)

svn merge -r35194:HEAD  https://svn.perl.org/parrot/trunk/

new revision: r35369

[pdd09gc] Bringing the pdd09gc_part2 branch up-to-date with trunk r35369.

(allison)

svn merge -r35369:HEAD  https://svn.perl.org/parrot/trunk/

new revision: r35373

[pdd09gc] Bringing the pdd09gc_part2 branch up-to-date with trunk r35373.

(allison)

svn merge -r34686:HEAD  https://svn.perl.org/parrot/branches/pdd09gc_part2/

new revision: r35374

[pdd09gc] Merging the pdd09gc_part2 branch into trunk for r34686 to r35374. GC refactor: reorganize code for sanity and maintainability.

(allison)

svn delete  https://svn.perl.org/parrot/branches/pdd09gc_part2 -m "Removing second GC development branch from the repository"

new revision: r35380


GC rewrapping talk

<bacek> Whiteknight: I want to break something in parrot. And I'll need your help with this idea :) <Whiteknight> i like breaking, and ideas! <bacek> Current GC API.

It's broken-by-design.

<bacek> E.g. using "Small_Object_Pool" directly for allocating objects enforce particular implementation. <bacek> Whiteknight: also, current GC API doesn't allow something like "Gimme chunk of memory with this size"

Whiteknight: and without this ability I can merge "PMC" and "ATTRibutes" into single allocation. Or convert Context to use ATTRibutes.

<Whiteknight> bacek: we need PMCs to be located together so we can sweep <purl> thanks bacek :) <bacek> So, "mark-sweep" enforces particular design. And it's bad

What about compacting GCs?

<Whiteknight> bacek: any GC is going to have a sweep <bacek> Or trademills

Whiteknight: not all of them

<Whiteknight> bacek: I can't think of a single algorithm that doesn't use some sort of sweep <bacek> In many cases it can be implicit <Whiteknight> ACTUALLY, chromatic's idea might work here <bacek> "Uniprocessor Garbage Collection Techniques"

 http://www.cs.rice.edu/~javaplt/311/Readings/wilson92uniprocessor.pdf anyway, "sweep" doesn't require all objects to be same size and allocated from "Small_Object_Pool"

<dukeleto> 67 pages of GC goodness <bacek> dukeleto: indeed

Whiteknight: check src/gc/api.c, line 329

<Whiteknight> dukeleto: You jest, but I'm going to print and read every one of them <bacek> My idea is not to have "arenas" in interp, but some "struct gc*" with few functions and "void * gc_private" <Whiteknight> bacek: Then you are going to love the new patch from jrtayloriv: It does exactly that <bacek> So, all implementation details will be decoupled from Interp. <dukeleto> Whiteknight: I don't jest. that looks like a really good introductory/overview paper. <bacek> Whiteknight: Yay! jrtayloriv++ <Whiteknight> bacek: I like that idea a lot. I've wanted to do it myself for a while <bacek> Just ensure that this functions has explicit ""size" argument <Whiteknight> bacek: if we changed the fixed-size attributes pool to include PMC and ATTR together, we could get the effect you are talking about <bacek> yes <Whiteknight> then we could sweep those pools because all objects would be guaranteed to be PMCs <bacek> Why sweeping require all objects to be PMC?

It's just chunks of memory

<Whiteknight> bacek: If we sweep linearly over a pool, we don't know if the block is a PMC or not <bacek> We know size. <Whiteknight> PMCs have flags, need destruction, etc. We need to know if an object is a PMC

but I can allocate an X byte buffer in the same pool I allocate an X byte PMC and I don't want to call VTABLE_destroy on the buffer

<bacek> Ok.

We just need pairs of function "get_raw_chunk" and "get_pmc" in gc* no, bad idea. All we need is pass (optional) pointer to "destroy function". Which will be invoked by GC during sweep.

<Whiteknight> so store the destroy function in the pool?

that idea actually has some merit

<bacek> In allocated object. <Whiteknight> so for every object we add a header with a pointer to a destroy function? <bacek> Whiteknight: only when requested. GC can be smart enough to not store it always.

E.g. in most PMC without "destroy" VTABLE it's useless.

<bacek> Bah! We have to change Pmc2s to set "active_destroy" as pragma, not in "VTABLE_init" <bacek> This step is too big... Ok, scratch last idea. <Whiteknight> yes, and custom_mark <bacek> Let's just have pair of functions for allocate memory.

Both of them should accept explicit size.

<Whiteknight> I like that idea, but we need to be able to tell whether an item is a PObj or not

and then we need to be able to find all STRING headers that point to a string buffer because of COW, it can be N:1

<bacek> Immutable strings ftw! <Whiteknight> I want immutable strings. That would be a very good idea <dukeleto> i like cows <Whiteknight> but, it would be a huge job <bacek> Actually, with this approach we can just drop STRING and always use String PMC.

Just reimplement it use ATTRibutes and allocate raw chunk of memory for real string Then, String,mark will do all required job

<Whiteknight> there is some merit to that. I think the string compactor is very expensive <bacek> And incomprehensible :) <NotFound> Note that in order to make PMC variable size we might need to forbid morphing assignments <Whiteknight> NotFound: Yes, I hadn't even thought about that <bacek> (morphing) VTABLE_morph is way-too-premature optimisation <Whiteknight> yes, but some people do use the morph opcode

so we can't kill it entirely at least, not yet

<bacek> Fortunately, I've put broad deprecation warning for all VTABLEs in 1.4 :) <NotFound> bacek: morph is not the only way of morphing. Look for example at the Undef pmc. <Whiteknight> yeah, we lose a lot of flexibility

I really like this idea. Hard part is finding a way to do it without breaking the whole damn codebase

<Whiteknight> bacek: yes, dump some of your ideas onto the wiki. I think there is a "GCTasklist" page you can use <NotFound> You can start thinking about how to avoid assignment to Undef <bacek> NotFound: anyway, we have to have something for implementing compacting GC.

And it's closely related to "assign to Undef" Because we have to update all pointers to PMC. Or wrap "PMC" into struct with single pointer.