<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Oct 9, 2016 at 4:40 PM, Paul Bone <span dir="ltr"><<a href="mailto:paul@bone.id.au" target="_blank">paul@bone.id.au</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I'd like to check that I understand.  By pre-allocating long lived items,<br>
but not short lived items, we're more likely to guarantees that those objects<br>
are allocated on the same blocks, and not interspersed on other blocks<br>
preventing those blocks from being freed when the short-lived objects are<br>
collected?</blockquote><div><br></div><div>Right.</div><div><br></div><div>In fact there is an existing API which would be useful for this:</div><div><br></div><div>void* GC_malloc_many(size_t objSz)</div><div><br></div><div>... which is implemented by ...</div><div><br></div><div>void GC_generic_malloc_many(size_t objSz, int objKind, void **result)<br></div><div><br></div><div>It might make sense to have GC_malloc_many_atomic() or the uncollectable variants, but they din't exist at the moment and you can get the effect now by a direct call to GC_generic_malloc_many.</div><div><br></div><div>This call returns some number of objects of the same size (rounded up minimally -- just to the next multiple of 16 bytes), all of which are located in the same gc/VM page. The first bytes of each object point to the next object, and the return value is a pointer to the first object.</div><div><br></div><div>The function tries to find an existing block of objects of that size, allocating an entire new block only if one can't be found. It might make sense to add a parameter (or another function) to force always using an entire (new or reclaimed) VM page for the returned list.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> Can you or someone else on the BDWGC tell me in what order blocks are put on</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
the free lists.  Do the free spots in mostly-full blocks appear earlier on<br>
the free lists?  If things are placed on the free list in the order they are<br>
swept which blocks are swept sooner?<br></blockquote><div><br></div><div>First, the free list for objects of a particular size (and kind) always[1] contain only objects from a single gc/VM page. The objects are ordered by memory address within the gc page.</div><div><br></div><div>When the free list for objects of a particular size is empty, a single page of objects of the same size is swept and any objects that were not marked (reachable) at the previous GC are added to the free list. Some objects in the page may have since become unreachable and this is not detected, but it's impossible for a previously unreachable object to become referenced -- since it was unreachable by the app :-) </div><div><br></div><div>If a page is "nearly full" then it is skipped, on the assumption that it takes a lot of time for little benefit (speed/space tradeoff).</div><div><br></div><div>The order in which pages are swept is determined by the ok_reclaim_list for blocks with that size of object, linked together by the hb_next field. This is set up by GC_apply_to_all_blocks() after each GC, which processes pages in order of memory address.</div><div><br></div><div>[1] unless you use GC_free(), in which case anything freed by GC_free() is at the start of the free list and will be the first object(s) of that size(&kind) to be returned from GC_malloc().</div><div><br></div></div></div></div>