Add instrumentation in the TemplateInterpreter

Coleen Phillimore coleen.phillimore at oracle.com
Fri Feb 19 18:55:25 UTC 2016


Hi, I think what you want to do is look for the calls to 
InterpreterRuntime::post_field_access() and add your own call at these 
places (and change the conditionals from checking if jvmti is on).  
These are called when it's safe to call into the jvm. Hacking 
do_oop_store() is pretty ugly, I'd suggest also piggybacking on 
post_field_modification and add some call to aastore().

The Zero interpreter is slower but works.  Configure with 
--with-jvm-variants=zero --with-target-bits=64 
--disable-warnings-as-errors.  Maybe you don't need the last one 
anymore, and install libffi where it wants to be installed.

Nobody knows if Shark compiler can be built anymore.

Thanks,
Coleen

On 2/10/16 4:19 AM, Khanh Nguyen wrote:
> Hello,
>
> I want to add instrumentation to monitor all reads and writes in the
> TemplateInterpreter, I think I got the correct place for it in
> /cpu/x86/vm/templateTable_x86_64.cpp. Can someone please tell me if I'm
> doing it right?
>
> For writes:
> static void do_oop_store(InterpreterMacroAssembler* _masm,
>                           Address obj,
>                           Register val,
>                           BarrierSet::Name barrier,
>                           bool precise) {
> [...]
>   case BarrierSet::CardTableModRef:
>    case BarrierSet::CardTableExtension:
>        {
>          if (val == noreg) {
>            __ store_heap_oop_null(obj);
>          } else {
>            __ store_heap_oop(obj, val);
>
>   /*mycodeA*/  __ movptr(c_rarg1, obj.base()); // save this value otherwise
> it will be changed?
>
>            // flatten object address if needed
>            if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
>              __ store_check(obj.base());
>   /*mycodeB*/ __ call_VM(noreg, //void
>                         CAST_FROM_FN_PTR(address,
>                                          InterpreterRuntime::write_helper),
>                         c_rarg1,  // obj
>                         c_rarg1, // field address because store check is
> called on field address
>                         val);
>            } else {
>              __ leaq(rdx, obj);
>              __ store_check(rdx);
>   /*mycodeC*/ __ call_VM(noreg, //void
>                           CAST_FROM_FN_PTR(address,
>                                            InterpreterRuntime::write_helper),
>                           c_rarg1,  // obj
>                           rdx, // field address, because store check is
> called on field address
>                           val);
>          }
>        }
>        break;
>
> For reads:
> case Bytecodes::_fast_agetfield:
>      __ load_heap_oop(rax, field);
>
> /*mycodeD*/     __ call_VM(noreg,
>                 CAST_FROM_FN_PTR(address,
>                                  InterpreterRuntime::read_barrier_helper),
>                 rax);
>
> __ verify_oop(rax);
>      break;
>
> My questions are:
>
> 1) I thought this represents a putfield a.f=b where a.f is represented by
> the parameter obj of type Address. b is obvious the parameter val of type
> Register. Especially in obj there are fields: base, index and disp. But as
> I run this, looks like obj is actually the field address. (the case mycodeB)
> I haven't found a test case that can trigger the case mycodeC to see the
> behavior (i.e., rdx might get destroyed and I got random value back or
> c_rarg1 is the obj address and rdx is field address)
>
> 2) Before this, I tried to insert the same __ call_VM in fast_aputfield
> before do_oop_store but it results in JVM crash. I don't understand the
> reason why. What I did in the call is just print the parameters. I did see
> the values printed (only the 1st time it goes to the method) but then the
> VM crashed. I thought __ call_VM will preserve all registers's value and
> restore properly when comes back. My instrumentation has no side effect, I
> just observe and record the values (actually just printing the values to
> test).
>
> 3) Is it strictly required to have the line /*mycodeA*/ I tried to, in
> mycodeB line, pass obj.base() twice and it got build errors for "smashed
> args"?
>
> I greatly appreciate your time,
>
> Best,
>
> Khanh Nguyen



More information about the hotspot-dev mailing list