invalid oops during oop_do() iteration?

Keith McGuigan keith.mcguigan at oracle.com
Wed Jan 19 17:42:40 UTC 2011


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