<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><DIV><BLOCKQUOTE type="cite"><DIV><BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Note that we're also zeroing out automatic variables as well so if we do a collection before they're initialized we don't end up following garbage.</DIV></BLOCKQUOTE><DIV><DIV><BR class="webkit-block-placeholder"></DIV><DIV><DIV>@@ -1581,6 +1605,17 @@ void TreeToLLVM::EmitAutomaticVariableDe</DIV><DIV>   // Handle annotate attributes</DIV><DIV>   if (DECL_ATTRIBUTES(decl))</DIV><DIV>     EmitAnnotateIntrinsic(AI, decl);</DIV><DIV>+</DIV><DIV>+  // Handle gcroot attribute</DIV><DIV>+  if (POINTER_TYPE_P(TREE_TYPE (decl))</DIV><DIV>+      && TYPE_GCROOT(TREE_TYPE (decl)))</DIV><DIV>+    {</DIV><DIV>+      // We should null out local variables so that a stack crawl</DIV><DIV>+      // before initialization doesn't get garbage results to follow.</DIV><DIV>+      const Type *T = cast<PointerType>(AI->getType())->getElementType();</DIV><DIV>+      EmitTypeGcroot(AI, decl);</DIV><DIV>+      Builder.CreateStore(Constant::getNullValue(T), AI);</DIV><DIV>+    }</DIV><DIV>   </DIV><DIV>   if (TheDebugInfo) {</DIV><DIV>     if (DECL_NAME(decl)) {</DIV></DIV><DIV><BR class="webkit-block-placeholder"></DIV><DIV>This is redundant; LLVM does it for you. See thread starting here:</DIV><DIV>  <A href="http://www.mail-archive.com/llvm-commits@cs.uiuc.edu/msg23987.html">http://www.mail-archive.com/llvm-commits@cs.uiuc.edu/msg23987.html</A></DIV></DIV></DIV></BLOCKQUOTE><DIV><BR class="khtml-block-placeholder"></DIV><DIV>I don't think so: the patch makes it so that llvm.gcroot *doesn't* implicitly null out the root.  This means the front-end *does* need to explicitly emit the null init if it wants it, right?</DIV><BR><BLOCKQUOTE type="cite"><DIV><DIV><DIV>The upshot is that the collector knows whether it is necessary to initialize roots or not, and does so on the program's behalf iff necessary.</DIV></DIV></DIV></BLOCKQUOTE><DIV><BR class="khtml-block-placeholder"></DIV><DIV>I don't think the collector wants to be in the business of nulling out pointers.  The important thing is that when the collector runs, it doesn't want a root with garbage in it.</DIV><BR><BLOCKQUOTE type="cite"><DIV><DIV><DIV>However, if the source language requires null initialization semantics, then the front-end should emit explicit null initializers (as the variable comes into scope).</DIV></DIV></DIV></BLOCKQUOTE><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Even if the language doesn't require it, for GC roots, it seems very dangerous to hand the collector a root with random garbage in it, agree?</DIV><BR><BLOCKQUOTE type="cite"><DIV>+// Emits code to do something for a type attribute</DIV><DIV><DIV>+void TreeToLLVM::EmitTypeGcroot(Value *V, tree decl) {</DIV><DIV>+</DIV><DIV>+  Function *gcrootFun = Intrinsic::getDeclaration(TheModule,</DIV><DIV>+<SPAN class="Apple-tab-span" style="white-space:pre">                                               </SPAN>  Intrinsic::gcroot);</DIV><DIV>+  </DIV><DIV>+  // The idea is that it's a pointer to type "Value"</DIV><DIV>+  // which is opaque* but the routine expects i8** and i8*.</DIV><DIV>+  const PointerType *Ty = PointerType::get(Type::Int8Ty);</DIV><DIV>+  V = Builder.CreateBitCast(V, PointerType::get(Ty), "tmp");</DIV><DIV><BR></DIV></DIV><DIV><DIV>The llvm.gcroot intrinsic can be declared to take any types you care to give it in the module, so long as its eventual type is like void(<ty>**, <ty2>*).</DIV></DIV></BLOCKQUOTE><BR></DIV><DIV>Actually no, I need to update the langref.html document to make this explicit, thanks for reminding me.  The issue is that if you link two modules with different <ty>'s, the two different intrinsics would have to be merged somehow.  By forcing the intrinsic to a specific type this problem doesn't happen.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>-Chris</DIV><DIV><BR class="khtml-block-placeholder"></DIV></BODY></HTML>