JDK-6309761 : interpreter uses oops while in thread_in_native state
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-08-11
  • Updated: 2012-10-08
  • Resolved: 2005-09-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u7Fixed 6 b53Fixed
Description
While getting reviews for the fix to 6303534 I noticed that the interpreters are using a 
methodOop while the thread state is still thread_in_native. Since a gc can be going on
concurrently this can cause a failure. Since methodOops are in perm space they rarely
move so the bug is probably hard to observe (FullGCALot would increase the odds).
Here's a snippet of the bad code from interpreter_i486.cpp with comments added:

  // Change state to native 
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);    
  __ call(eax, relocInfo::none);

  // result potentially in edx:eax or ST0
  __ get_method(method);    

BUG! Can't access method here
  __ get_thread(thread);

  // Either restore the MXCSR register after returning from the JNI Call
  // or verify that it wasn't changed.
  if (VM_Version::supports_sse()) {
    if (RestoreMXCSROnJNICalls) {
      __ ldmxcsr(Address((int) StubRoutines::addr_mxcsr_std(), relocInfo::none));
    }
    else if (CheckJNICalls ) {
      __ call(CAST_FROM_FN_PTR(address, StubRoutines::i486::verify_mxcsr_entry()), 
              relocInfo::runtime_call_type);
    }
  }

  // restore esi to have legal interpreter frame, i.e., bci == 0 <=> esi == code_base()
  __ movl(esi, Address(method,methodOopDesc::const_offset())); // get constMethodOop

BUG! can't access method here.

The other platforms have similar code.

Comments
EVALUATION I think this bug fix should be backported to 1.5.0_u7 as it is low risk and to eliminate one cause of potential difficult-to-track failure at customer sites.
29-11-2005

EVALUATION Fixed 6309761: interpreter uses oops while in thread_in_native state Fixed x86 and amd64 interpreter to get the methodOop later in the assembly code when it's needed (which is after thread_in_Java transition). So there it's safe from GC. Sparc didn't have this problem. Fix verified (y/n)? y Verified by: Visual inspection. I wrote a test case for it but the timing hole is so small I never got it to fail. Other testing: runThese -full x86 -client/-server nsk vm.nightly x86 -client/-server runThese -full amd64 -d64 nsk vm.nightly amd64 -d64 Reviewed by: Paul, Steve G, Keith
16-09-2005

EVALUATION Not a problem on sparc but on i486 and amd. I tried to write a test case with lots of synchronized native methods and a lot of full gc's but I couldn't make it fail. It seems to be a really small timing hole. The fix is to move the get_method(method) and the fetch of (bcp) register down to where it's really needed after the thread goes into thread_in_Java state but before exception handling and any call_VM calls.
07-09-2005