Question on TemplateTable::prepare_invoke

Tom Rodriguez Thomas.Rodriguez at Sun.COM
Wed Mar 3 12:11:33 PST 2010


While call_VM generally takes care of saving off any needed state it's not implicitly safe to use every context.  In particular I'd be suspicious of calling it after load_invoke_cp_cache_entry since that sets up state for use by later parts of the invoke path.

tom

On Mar 3, 2010, at 11:56 AM, Peng Du wrote:

> Hi, John
> 
> Thanks for the hint. I tried using TraceBytecodes and StopInterpreterAt,
> but with no luck because the order in which each class in JDK is loaded
> is totally nondeterministic. Therefore, the bytecode index corresponding
> to String.java:1218 is distinct in each run.
> 
> I also tried putting NOPs in the interpreter. However, I am not very
> proficient in debugging HotSpot at this level. So, I couldn't stop at
> the right place. 
> 
> Given the information in my first post, can someone shed some light on
> what could possibly be the reason of the error? 
> 
> Thanks
> 
> 
> 
> On Wed, 2010-03-03 at 00:10 -0800, John Cuthbertson wrote:
>> Hi Peng,
>> 
>> You may have to manually examine the generated interpreter code in a 
>> debugger to detect a register overwrite. Be warned that the code that 
>> gets generated for a call_VM macro is quite large - I find inserting 
>> sequences of nops helps locate the code I'm interested in. You could 
>> also try the TraceBytecodes and StopInterpreterAt flags in debug JVM and 
>> then do instruction stepping within a debugger.
>> 
>> As for register usage/conventions with the interpreter - the best source 
>> is probably  assembler_x86.hpp.
>> 
>> Regards,
>> 
>> JohnC
>> 
>> Peng Du wrote:
>>> Hello,
>>> 
>>> I have a very specific question about an error I ran into today. I am 
>>> very familiar
>>> with assembly programming. So, please bear with me.
>>> 
>>> If I understand correctly, TemplateTable::prepare_invoke is a helper 
>>> methods for
>>> the invokeXXX bytecodes. What I tried to do was to pass the oop of the 
>>> method
>>> receiver to InterpreterRuntime::cache_object, which  simply caches it 
>>> in the current
>>> thread.
>>> 
>>> Below is an excerpt in templateTable_x86_64.cpp) that I modified, the
>>> cache_object method in interpreterRuntime.cpp, and the cache_object 
>>> method
>>> in thread.hpp:
>>> 
>>> ===========================================================
>>> void TemplateTable::prepare_invoke(Register, Register, int) {
>>>  const Register recv   = rcx;
>>>  ...
>>>  // load receiver if needed (note: no return address pushed yet)
>>>  if (load_receiver) {
>>>    __ movl(recv, flags);
>>>    __ andl(recv, 0xFF);
>>>    if (TaggedStackInterpreter) __ shll(recv, 1);  // index*2
>>>    Address recv_addr(rsp, recv, Address::times_8, 
>>> -Interpreter::expr_offset_in_bytes(1));
>>>    if (is_invokedynamic) {
>>>      __ lea(recv, recv_addr);
>>>    } else {
>>>      __ movptr(recv, recv_addr);
>>>      __ verify_oop(recv);
>>>    }       
>>> 
>>>    // !!! cache receiver object !!!
>>>    __ call_VM(noreg, CAST_FROM_FN_PTR(address,
>>>        InterpreterRuntime::cache_object), recv);   
>>>  }
>>> ...
>>> 
>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> 
>>> IRT_ENTRY(void, InterpreterRuntime::cache_object(JavaThread* thread, 
>>> oop o))   
>>>    thread->cache_object(o);
>>> IRT_END
>>> 
>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> class JavaThread {
>>> ...
>>>    inline void cache_object(oop o)       {  _object = o;  }
>>> 
>>> ===========================================================
>>> 
>>> However, this failed even in test_gamma with the following error:
>>> Error occurred during initialization of VM
>>> java.lang.StackOverflowError
>>>    at java.lang.NullPointerException.<init>(NullPointerException.java:53)
>>>    at java.lang.NullPointerException.<init>(NullPointerException.java:53)
>>>    < a long list of NullPointerException same as above ... >
>>>    at java.lang.String.<clinit>(String.java:1218)
>>> 
>>> It appeared to me there is infinite recursive creations of 
>>> NullPointerException
>>> somewhere caused by the static initializer in String class. 
>>> String.java:1218
>>> looks like this:
>>> 
>>> public static final Comparator<String> CASE_INSENSITIVE_ORDER = new 
>>> CaseInsensitiveComparator();
>>> 
>>> Is it because I somehow clobber the recv (rcx) register? Or can 
>>> someone tell me
>>> what I did was wrong and how to fix it? Moreover, is there any 
>>> documentation on
>>> the rules that how registers are used in template interpreter?
>>> 
>>> 
>>> 
>> 
> 
> 



More information about the hotspot-dev mailing list