<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 22, 2014, at 3:41 PM, Phil Bouchard &lt;<a href="mailto:philippeb8@gmail.com" class="">philippeb8@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">On 12/22/2014 10:02 AM, Filip Pizlo wrote:<br class=""><br class="">(Sorry for the late reply)<br class=""><br class=""><br class="">[...]<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">This is a good presentation on how it handles it:<br class=""><a href="https://svn.boost.org/svn/boost/sandbox/block_ptr/libs/smart_ptr/doc/BlockPointer.ppt" class="">https://svn.boost.org/svn/boost/sandbox/block_ptr/libs/smart_ptr/doc/BlockPointer.ppt</a><br class=""><br class="">You basically have "sets" of memory blocks (i.e. container = 1 set). &nbsp;If you merge the sets they become one big set. &nbsp;When the last pointer from the stack is deleted then the entire set is also destructed.<br class=""></blockquote><br class="">Yup, you reinvented regions.<br class=""></blockquote><br class="">As I read it region based memory manager use contiguous memory blocks which get destroyed as a whole without calling any destructor I can imagine, etc. &nbsp;The block pointer is much more refined than that.<br class=""></div></blockquote><div><br class=""></div><div>No, region-based memory management doesn’t mean contiguous regions of memory. &nbsp;It also doesn’t mean not calling destructors. &nbsp;RTSJ regions violate both rules, and that’s just one example. &nbsp;I’m pretty sure Cyclone regions are discontiguous because they are arbitrarily resizeable. &nbsp;(Note that RTSJ uses the term “scope”, but in the literature it’s common to view this as a special case of regions.)</div><div><br class=""></div><div>Region means that some set of objects enter into a “suicide pact” where none of them can die unless all of them die. &nbsp;Even that definition may be too strict because there have been so many variations on this theme throughout the history of CS. &nbsp;More loosely, any grouping of objects together either to simplify memory management semantics or accelerate reclamation is called “regions”.</div><div><br class=""></div><div>One of the most common reasons for using regions is that region-based allocation semantics (i.e. that suicide pact) allow the objects to be bump-allocated within a contiguous memory region. &nbsp;But they are also often used because even if you do have to call destructors, it’s very cheap to identify what needs to be freed. &nbsp;The reason why they are used infrequently despite being very well understood is that they are too inflexible - it turns out that you need to be able to kill some objects before others.</div><br class=""><blockquote type="cite" class=""><div class=""><br class="">[...]<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">You would need a tremendous amount of evidence to convince us that this<br class="">is usable for our purposes. &nbsp;Our GC may have its performance issues but<br class="">it is very robust.<br class=""></blockquote><br class="">I understand that but the garbage collectors have been tested for decades. &nbsp;The block pointer is just freshly baked and is already functional.<br class=""></blockquote><br class="">And the block pointer doesn't work for JSC and probably never will. For example each object's set will be unified with the set of its structure, which will be unified with the empty object structure, which in turn will be unified with the global object. Then the global object will be unified with its parent global object, and its internal objects will be unions with all of the internal types hanging off VM.<br class=""><br class="">So, everything will become a member of one giant set and the VM will leak memory and never free anything.<br class=""><br class="">The reason why we use GCs instead of regions is that regions are well understood as an impractical approach to general memory management.<br class=""></blockquote><br class="">Well then may I suggest a hybrid solution? &nbsp;You put a GC on top of the block pointer, this way you take the best of both worlds.<br class=""><br class="">I can easily add statistics, scan for inner cycles inside a set when some memory usage threshold is reached and remove least used allocations.<br class=""></div></blockquote><div><br class=""></div><div>This sort of compartmentalization of the heap has been tried before. &nbsp;The term I prefer for a “region with a heap” is “heaplet”. &nbsp;The most famous approach to this is G1 (<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html" class="">http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html</a>). &nbsp;There are others, too. &nbsp;I published a paper on it (<a href="http://www.filpizlo.com/papers/pizlo-lctes2007-hrtgc.pdf" class="">http://www.filpizlo.com/papers/pizlo-lctes2007-hrtgc.pdf</a>) as did some others (including&nbsp;<a href="http://researcher.watson.ibm.com/researcher/files/us-bacon/Auerbach07Java.pdf" class="">http://researcher.watson.ibm.com/researcher/files/us-bacon/Auerbach07Java.pdf</a>). &nbsp;Most of these rely to some extent on allowing references between heaplets, or having a very constrained programming model (i.e. not something we can do in WebKit).</div><div><br class=""></div><div>In hindsight the benefits of such an approach are dubious. &nbsp;If you get lucky, you get a small reduction in pause times. &nbsp;If you get unlucky, then the overhead of tracking all of these heaplets causes more overhead than a normal GC would have caused. &nbsp;As I’ve said before, if you want to reduce pauses then the best approach is to make the GC concurrent or incremental (or both).</div><br class=""><blockquote type="cite" class=""><div class=""><br class="">[...]<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">I'm just talking about the worst case scenario here but when the garbage collector kicks in on a small set-top box the whole system is easily frozen.<br class=""><br class="">How many times the garbage collector will kick in when you use the browser for a week on a set-top box? &nbsp;At least once a day, hopefully not when you're watching the 4th quarter of an important football game.<br class=""></blockquote><br class="">Your approach means that in the middle of the football game the browser will crash.<br class=""></blockquote><br class="">Lol<br class=""><br class=""><blockquote type="cite" class="">I think that if you're concerned with this scenario, you should implement a concurrent GC. I would be happy to provide some guidance on how to do it; I've had a plan for this for a while now.<br class=""></blockquote><br class="">I can add a GC on top of the block pointer, run benchmarks and see what happens.<br class=""></div></blockquote></div><br class=""><div class="">Let’s be clear, though: we’re unlikely to accept a patch in which all of our JS object references are replaced by uses of your block_ptr, unless that patch is a significant speed-up on web benchmarks, there aren’t any slow-downs, and you can prove that all of the JSC GC’s lifetime semantics are preserved (including tricky things like the relationship between Executable objects, Structure objects, and CodeBlocks). &nbsp;So, if you want to explore the heap compartment approach, I recommend implementing it within our GC rather than adding a GC to your block_ptr.</div><div class=""><br class=""></div><div class="">But if you’re going to go to all of that trouble, you might as well just implement a concurrent GC. &nbsp;Trust me, I’ve implemented both, and the concurrent GC approach is much easier.</div><div class=""><br class=""></div><div class="">-Filip</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>