<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-family: Calibri, sans-serif; "><div><div>Hi,</div><div><br></div><div>I came across the following scenario, I already discussed with Thomas Schatzl, that I would like to share with you.</div><div>There is a method:</div><div><p style="margin: 0px; font-size: 11px; font-family: Monaco; "><span style="color: rgb(147, 26, 104); "><br></span></p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "><span style="color: rgb(147, 26, 104); ">private</span> <span style="color: rgb(147, 26, 104); ">static</span> <span style="color: rgb(147, 26, 104); ">final</span> HotSpotGraalRuntime <span style="color: rgb(3, 38, 204); ">instance</span> = <span style="color: rgb(147, 26, 104); ">new</span> HotSpotGraalRuntime();</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px; "> </p></div><div><p style="margin: 0px; font-size: 11px; font-family: Monaco; "><span style="color: rgb(147, 26, 104); ">public</span> <span style="color: rgb(147, 26, 104); ">static</span> HotSpotGraalRuntime runtime() {</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "> <span style="color: rgb(147, 26, 104); ">return</span> <span style="color: rgb(3, 38, 204); ">instance</span>;</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; ">}</p></div><br style="font-family: Calibri; font-size: medium; "><div style="font-family: Calibri; font-size: medium; ">The instance field is a constant oop in the code and the method is installed.</div><div style="font-family: Calibri; font-size: medium; ">At some stage there is a GC with post verification (including G1VerifyHeapRegionCodeRoots) that passes. </div><div style="font-family: Calibri; font-size: medium; ">Before the next GC cycle and during the mutation cycle, another method is being installed which causes the eviction of our method. Consequently our method is being made not_entrant and it is being patched with a jmp instruction</div><div style="font-family: Calibri; font-size: medium; ">at its verified<span style="font-style: italic; "> </span><i>entry point (nmethod.cpp::</i>make_not_entrant_or_zombie). The patching causes the oop to be overwritten by the jmp instruction. Furthemore, that oop was the only oop that was responsible for</div><div style="font-family: Calibri; font-size: medium; ">attaching this method to its correspondent HeapRegion.</div><div style="font-family: Calibri; font-size: medium; "><br></div><div style="font-family: Calibri; font-size: medium; ">The next GC cycle (Pre-verification) comes and the HeapRegionCodeRoot verification starts (nmethod.cpp::oops_do). There is a logic there (which I also believe it may be buggy as I will explain later) that checks whether the method is not_entrant. If the method is not_entrant then the logic correctly assumes that the method has been already been patched and therefore starts scanning the relocs of the method in +5 bytes (for x86)/+4 bytes (for SPARC) (as the comment states). This results in not scanning the single oop that was attaching this specific method to its heap region. The verification then correctly asserts by saying that "there is a method attached to this specific heap region with no oops pointing into it".</div><div style="font-family: Calibri; font-size: medium; "><br></div><div style="font-family: Calibri; font-size: medium; ">Concerning the second bug in the method::oops_do logic, here is the code for manipulating the reloc starting address after a method has been patched:</div><div style="font-family: Calibri; font-size: medium; "><font face="Monaco" size="2"><br></font></div><div style="font-family: Calibri; font-size: medium; "><p style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); ">// If the method is not <span style="text-decoration: underline; ">entrant</span> or <span style="text-decoration: underline; ">zombie</span> then a JMP is plastered over the</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: rgb(0, 0, 0); "> </span>// first few bytes. If an <span style="text-decoration: underline; ">oop</span> in the old code was there, that <span style="text-decoration: underline; ">oop</span></p><p style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: rgb(0, 0, 0); "> </span>// should not get GC'd. Skip the first few bytes of oops on</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: rgb(0, 0, 0); "> </span>// not-<span style="text-decoration: underline; ">entrant</span> methods.</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "> <span style="color: rgb(0, 97, 65); ">address</span> low_boundary = verified_entry_point();</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "> <span style="color: rgb(147, 26, 104); ">if</span> (is_not_entrant()) {</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "> low_boundary += <span style="color: rgb(0, 97, 65); ">NativeJump</span>::<span style="color: rgb(3, 38, 204); ">instruction_size</span>;</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: rgb(0, 0, 0); "> </span>// %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: rgb(0, 0, 0); "> </span>// (See comment above.)</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "> }</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "><br></p><p style="margin: 0px; ">The code above accounts only for the "is not entrant" scenario and not with the "is zombie" scenario. </p><p style="margin: 0px; "><br></p><p style="margin: 0px; ">I hope I got the story right…what do you think?</p><p style="margin: 0px; "><br></p><p style="margin: 0px; ">Thank you in advance</p><p style="margin: 0px; "><br></p><p style="margin: 0px; ">Regards</p><p style="margin: 0px; "><br></p><p style="margin: 0px; ">Christos</p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "><br></p><p style="margin: 0px; font-size: 11px; font-family: Monaco; "><br></p></div></div></body></html>