Question on TemplateTable::prepare_invoke

Peng Du imdupeng at gmail.com
Wed Mar 3 11:56:55 PST 2010


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