invalid oops during oop_do() iteration?

Y. S. Ramakrishna y.s.ramakrishna at
Wed Jan 19 18:03:01 UTC 2011

Thanks, yes, it's probably what Tony said. These methodOop's now probably
point to their new locations to which the methodOopDesc's haven't moved yet.
I'd have guessed an assert or two in method_at() may have caught it (the
is_oop() or is_methodOop() would probably return false?)

-- ramki

On 01/19/11 09:42, Keith McGuigan wrote:
> Actually, I'm going to attack this in a different fashion (a partial 
> revert of the code), so don't worry too much about my first question 
> (though I'm still curious for the answer).
> The code I'm talking about is here:  
> http://web-east.east/~km88527/webrev/2011/6458402/src/share/vm/prims/jvmtiImpl.cpp.udiff.html 
> The 'getCacheValue()' call basically does a _methodOop->code_size() + 
> _bci, with some asserts to ensure that the bci lies within the 
> code_size.  Very occasionally during a full-gc (during 
> mark_sweep_phase3), I get a _methodOop->code_size() that is radically 
> different from what is expected.  And it crashes if I try to print the 
> methodOop, which leads me to believe that perhaps what is being pointed 
> to in that oop* is not a methodOop at all anymore (or at the very least, 
> not the one that was pointed to before).
> I'll send out a webrev soon for the paritally-reverted fix, which adds a 
> gc-epilogue and calls it from the various GCs.
> -- 
> - Keith
> On Jan 19, 2011, at 12:25 PM, 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