Add instrumentation in the TemplateInterpreter

Christian Thalinger christian.thalinger at oracle.com
Thu Feb 18 17:27:52 UTC 2016


Does it have to be the template interpreter or could you do your work with Zero as well?

> On Feb 9, 2016, at 11:19 PM, Khanh Nguyen <ktruong.nguyen at gmail.com> 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