invalid oops during oop_do() iteration?

Tony Printezis tony.printezis at
Wed Jan 19 17:30:10 UTC 2011

Not very familiar with this code, but isn't mark_sweep_phase3 the phase 
that adjusts the reference fields in the live objects to reflect the new 
location of the referent *before* the objects are moved? Does this 
explain Keith's observation?

Y. S. Ramakrishna wrote:
> Can you send a pointer to the changes that you made that led
> to this issue? In my repo, I do not see a method_at() method
> of JvmtiBreakpoint to try to understand what the problem is.
> I didn't understand your statement "methopdOops will always be valid and
> refer to the same method". (methodOops that are marked by GC as reachable
> will be kept, but if you stash methodOops in yr breakpoint structure,
> and these are weak pointers, as i assume they want to be, these would
> be cleared (nulled) during a post-mark weak references iteration, after
> which class unloading is also done.)
> Not sure I understood yr problem though, so more details will help.
> -- ramki
> On 01/19/11 07:14, Keith McGuigan wrote:
>> Hello,
>> In some recent changes to JVMTI breakpoint code, I added some code to 
>> update a cache during an oop_do() iteration over of methodOop.  The 
>> cache update involves dereferencing the methodOop's constMethodOop 
>> and getting the address to the code in it.
>> Essentially, I'm doing something like this:
>> JvmtiBreakpoint::oops_do(OopClosure* f) {
>>   for (int i = 0; i < _num_methods; ++i) {
>>     methodOop* m = method_at(i);
>>     f->do_oop(m);
>>   // update the cache in case the methodOop moved
>>    _cache[i] =  (*m)->code_base() + _bci;
>>   }
>> }
>> (The actual code is in GrowableCache::oops_do() in jvmtiImpl.cpp, but 
>> this is the general idea)
>> Doing this assumes that the methodOops will always be valid and refer 
>> to the same method.  Considering what I'm seeing, I think this might 
>> be an invalid assumption.   When oops_do() is called from 
>> PSMarkSweep::mark_sweep_phase3(), I occasionally see that the 
>> resulting methodOop* refers to something else when I'm updating the 
>> cache (not sure what, but it doesn't appear to be the same 
>> methodOop).  It appears to be reset correctly in a later oops_do() 
>> iteration.
>> Is this expected?  And if so, is there any way for me to tell when 
>> doing the oops_do() whether or not the resulting oops are valid?  
>> We're seeing assertion failures and crashes in nightly testing when 
>> the oop is not the methodOop that we expected.  I'll take a quick 
>> hack to make it work for now if we can fix it better later.
>> If you've got anything for me to try, IM me (or email, but IM might 
>> be faster) and I'll give it a shot.
>> -- 
>> - Keith

More information about the hotspot-gc-dev mailing list