<li><a href="#gcimpls">GC implementations available</a>
<ul>
<li><a href="#semispace">SemiSpace - A simple copying garbage collector</a></li>
+ </ul>
</li>
<!--
<p>Conservative garbage collection often does not require any special support
from either the language or the compiler: it can handle non-type-safe
programming languages (such as C/C++) and does not require any special
-information from the compiler. The [LINK] Boehm collector is an example of a
-state-of-the-art conservative collector.</p>
+information from the compiler. The
+<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">Boehm collector</a> is
+an example of a state-of-the-art conservative collector.</p>
<p>Accurate garbage collection requires the ability to identify all pointers in
the program at run-time (which requires that the source-language be type-safe in
<div class="doc_text">
<div class="doc_code"><tt>
- void %llvm.gcroot(<ty>** %ptrloc, <ty2>* %metadata)
+ void %llvm.gcroot(i8** %ptrloc, i8* %metadata)
</tt></div>
<p>
The <tt>llvm.gcroot</tt> intrinsic is used to inform LLVM of a pointer variable
on the stack. The first argument contains the address of the variable on the
stack, and the second contains a pointer to metadata that should be associated
-with the pointer (which <b>must</b> be a constant or global value address). At
-runtime, the <tt>llvm.gcroot</tt> intrinsic stores a null pointer into the
-specified location to initialize the pointer.</p>
+with the pointer (which <b>must</b> be a constant or global value address).</p>
<p>
Consider the following fragment of Java code:
%X = alloca %Object*
...
+ ;; Java null-initializes pointers.
+ store %Object* null, %Object** %X
+
;; "CodeBlock" is the block corresponding to the start
;; of the scope above.
CodeBlock:
;; Initialize the object, telling LLVM that it is now live.
;; Java has type-tags on objects, so it doesn't need any
;; metadata.
- call void %llvm.gcroot(%Object** %X, sbyte* null)
+ %tmp = bitcast %Object** %X to i8**
+ call void %llvm.gcroot(i8** %tmp, i8* null)
...
;; As the pointer goes out of scope, store a null value into
<div class="doc_text">
<div class="doc_code"><tt>
- sbyte *%llvm_gc_allocate(unsigned %Size)
+ void *llvm_gc_allocate(unsigned Size)
</tt></div>
<p>The <tt>llvm_gc_allocate</tt> function is a global function defined by the
-garbage collector implementation to allocate memory. It should return a
+garbage collector implementation to allocate memory. It returns a
zeroed-out block of memory of the appropriate size.</p>
</div>
<div class="doc_text">
<div class="doc_code"><tt>
- sbyte *%llvm.gcread(sbyte **)<br>
- void %llvm.gcwrite(sbyte*, sbyte**)
+ i8 *%llvm.gcread(i8 *, i8 **)<br>
+ void %llvm.gcwrite(i8*, i8*, i8**)
</tt></div>
<p>Several of the more interesting garbage collectors (e.g., generational
collection) reads or writes object references into the heap. In the case of a
generational collector, it needs to keep track of which "old" generation objects
have references stored into them. The amount of code that typically needs to be
-executed is usually quite small, so the overall performance impact of the
-inserted code is tolerable.</p>
+executed is usually quite small (and not on the critical path of any
+computation), so the overall performance impact of the inserted code is
+tolerable.</p>
<p>To support garbage collectors that use read or write barriers, LLVM provides
the <tt>llvm.gcread</tt> and <tt>llvm.gcwrite</tt> intrinsics. The first
intrinsic has exactly the same semantics as a non-volatile LLVM load and the
-second has the same semantics as a non-volatile LLVM store. At code generation
+second has the same semantics as a non-volatile LLVM store, with the
+additions that they also take a pointer to the start of the memory
+object as an argument. At code generation
time, these intrinsics are replaced with calls into the garbage collector
(<tt><a href="#llvm_gc_readwrite">llvm_gc_read</a></tt> and <tt><a
href="#llvm_gc_readwrite">llvm_gc_write</a></tt> respectively), which are then
<div class="doc_text">
<div class="doc_code"><tt>
- void *llvm_gc_read(void **)<br>
- void llvm_gc_write(void*, void**)
+ void *llvm_gc_read(void*, void **)<br>
+ void llvm_gc_write(void*, void *, void**)
</tt></div>
<p>
<p>
If an actual read or write barrier is needed, it should be straight-forward to
-implement it. Note that we may add a pointer to the start of the memory object
-as a parameter in the future, if needed.
+implement it.
</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
- <a name="callbacks">Callback functions used to implement the garbage collector</a></li>
+ <a name="callbacks">Callback functions used to implement the garbage collector</a>
</div>
+<div class="doc_text">
+<p>
Garbage collector implementations make use of call-back functions that are
implemented by other parts of the LLVM system.
+</p>
+</div>
<!--_________________________________________________________________________-->
<div class="doc_subsubsection">
generator that iterates through all of the GC roots on the stack, calling the
specified function pointer with each record. For each GC root, the address of
the pointer and the meta-data (from the <a
-href="#gcroot"><tt>llvm.gcroot</tt></a> intrinsic) are provided.
+href="#roots"><tt>llvm.gcroot</tt></a> intrinsic) are provided.
</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
- <a name="semispace">SemiSpace - A simple copying garbage collector</a></li>
+ <a name="semispace">SemiSpace - A simple copying garbage collector</a>
</div>
<div class="doc_text">
src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
- <a href="http://llvm.cs.uiuc.edu">LLVM Compiler Infrastructure</a><br>
+ <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
Last modified: $Date$
</address>