<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>Hi Thomas,</div><div><br class="webkit-block-placeholder"></div><div>On Feb 4, 2008, at 12:20, thomas weidner wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">i want to implement a common lisp subset using llvm for fun.</blockquote><div><br class="webkit-block-placeholder"></div><div><div>Welcome!</div><div><br class="webkit-block-placeholder"></div><div><blockquote type="cite">This requires the use of a garbage collector. I read the docs, but many things are still unclear to me.</blockquote><div><font class="Apple-style-span" color="#144FAE"><br class="webkit-block-placeholder"></font></div></div><div>One of the important things to recognize about LLVM's GC support is that it only provides facilities which must be provided by the compiler back end. There are many other necessary facilities which must be provided by a complete language implementation. For the parts of the system where it doesn't need to be involved, LLVM simply gets out of your way.</div></div><br><blockquote type="cite">1. how are collectors supposed to find all living objects? there is llvm.gcroot for marking objects on the stack,but how do collectors crawl heap objects? I did not see a way to provide custom mark functions. Are collectors supposed to rely on the type informations provided by llvm?</blockquote><div><br class="webkit-block-placeholder"></div><div>Registering roots (e.g. globals) is a facility your runtime should provide. You could use a module initializer to call into the runtime and accomplish this.</div><div><br class="webkit-block-placeholder"></div><div>Traversing the object graph is also outside of LLVM's scope. Your code would need to emit whatever metadata is necessary for it to correctly traverse the graph at runtime.</div><br><blockquote type="cite">2. what about gcreading and gcwriting objects of a different type than i8*?</blockquote><div><br class="webkit-block-placeholder"></div><div>Simply bitcast to/from i8*. If you don't need write barriers, you would be advised to ignore gcread and gcwrite entirely, since currently they will only pessimize your code as compared to direct loads and stores.</div><br><blockquote type="cite">3. No Intrinsic for allocating gc memory?</blockquote><div><br class="webkit-block-placeholder"></div><div>Again, that's a feature of the runtime. Simply write a function to do so. For efficiency, your compiler may want to inline part of allocation if you're using a bumpptr allocator.<br></div><br><blockquote type="cite">4. When passing a gc managed pointer to a c function,how should that function access the pointer? directly?</blockquote><div><br class="webkit-block-placeholder"></div><div>Generally speaking, yes, directly. If you are using a moving collector and need to pin or copy an object, LLVM neither helps nor hinders your efforts.</div><br><blockquote type="cite">there seem to be functions for that in the runtime/ source directory,but it also seems to be meant for the llvm c frontend? (and not for use in an extra c library)</blockquote><div><br class="webkit-block-placeholder"></div><div>I'm not sure what you mean here.</div><br><blockquote type="cite">5. some collectors update pointers upon read/write access, can the llvm gc api provide this?<br></blockquote><div><br class="webkit-block-placeholder"></div><div>gcread easily allows the pointer loaded from the derived pointer to be updated when it is read. Updating the object pointer from gcread or gcwrite may be possible, but is not straightforward within the framework.</div><div><br class="webkit-block-placeholder"></div><div>Have fun,</div><div>Gordon</div></div><div apple-content-edited="true"> </div><br></body></html>