bytecode rewrite and breakpoint

San Hong Li sherrylso at gmail.com
Mon Jan 12 12:33:07 UTC 2015


Hi  Coleen:
Thanks for your attention and reply. I would like to clarify my question
again:
Given that we have the following bytecde stream:
|bp|
-------------------------------------------------
|   x  |  x    |   aload_0  |  x  |  x  |  x  |
-------------------------------------------------
and we suppose that the breakpoint gets inserted  at  the position of "
aload_0  ",   the steam would be updated as follows:

-------------------------------------------------
|   x  |  x    |   bp(202)|  x  |  x  |  x  |
-------------------------------------------------
         (original: aload_0  )

The key point here is :  bp and aload_0  have the same bcp index -  I just
deduced this from the implementation of  TemplateTable::_*breakpoint.*


Based on this layout,  when  the  *TemplateTable::patch_bytecode *was
called for aload_0
The interpreter will see that the bp will be at bcp(0)   (*NOT aload_0 *at
this time)

This explained that why the HotSpot must have the  below block in
*TemplateTable::patch_bytecode
*
to handle the case when the  at bcp(0) is bp.
*(Actually this was the intention of my original question)*

  if (JvmtiExport::can_post_breakpoint()) {
    Label L_fast_patch;
    // if a breakpoint is present we can't rewrite the stream directly
    __ movzbl(temp_reg, at_bcp(0));
    __ cmpl(temp_reg, Bytecodes::_breakpoint);
    __ jcc(Assembler::notEqual, L_fast_patch);
    __ get_method(temp_reg);
    // Let breakpoint table handling rewrite to quicker bytecode
    __ call_VM(noreg, CAST_FROM_FN_PTR(address,
InterpreterRuntime::set_original_bytecode_at), temp_reg, r13, bc_reg);
#ifndef ASSERT
    __ jmpb(L_patch_done);
#else
    __ jmp(L_patch_done);
#endif
    __ bind(L_fast_patch);
  }

Hopefully I  explain my question and answer clearly  :-)

On Fri, Jan 9, 2015 at 11:35 AM, San Hong Li <sherrylso at gmail.com> wrote:

> Hmmm, finally I got the answer for this question.
> The  at_bcp(0) would be the Bytecodes::_breakpoint if the patch_code
> happened after the  break point is set.
> The following example shows this:
>
>    33:  getstatic       #8; //Field
> java/lang/System.in:Ljava/io/InputStream;
>    36:  invokevirtual   #9; //Method java/io/InputStream.read:()I
>    39:  pop
>    40:  aload_0                  <---------------------- set break point
> here.
>    41:  getfield        #2; //Field myInt:I
>    44:  istore  6
>    46:  iload   6
>
> If we  set the breakpoint at 40 , when the  patch_code  in aload  happened
> later, the interpreter will see the  Bytecodes::_breakpoint  at bcp(0).
>
> hmmm, actually i just missed the info present
> in TemplateTable::_breakpoint - the breakpoint  used the same index with
> the original bytecode.
>
> Anyway, thanks every one.
>
>
> On Tue, Jan 6, 2015 at 10:18 PM, San Hong Li <sherrylso at gmail.com> wrote:
>
>> Hi All:
>>
>> For the bytecode patch path, the  interpreter does have some special
>> handling for breakpoint bytecode, that is,  if a breakpoint is present
>> at_bcp(0),   the bytecode patching will be skipped and  handled by
>> breakpoint table later.
>>
>> The related implementation is in  TemplateTable::patch_bytecode:
>>
>>   if (JvmtiExport::can_post_breakpoint()) {
>>     Label L_fast_patch;
>>     // if a breakpoint is present we can't rewrite the stream directly
>>     __ movzbl(temp_reg, at_bcp(0));
>>     __ cmpl(temp_reg, Bytecodes::_breakpoint);
>>     __ jcc(Assembler::notEqual, L_fast_patch);
>>     __ get_method(temp_reg);
>>     // Let breakpoint table handling rewrite to quicker bytecode
>>     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
>> InterpreterRuntime::set_original_bytecode_at), temp_reg, r13, bc_reg);
>> #ifndef ASSERT
>>     __ jmpb(L_patch_done);
>> #else
>>     __ jmp(L_patch_done);
>> #endif
>>     __ bind(L_fast_patch);
>>   }
>>
>> My understanding is the breakpoint can only be set in safepoint,
>> when the interpreter thread resumes from safepoint, because it will
>> retrieve the next bytecode for executing again,the breakpoint bytecode
>> which is set in safepoint before will get chance to be executed. I can not
>> imagine when the bcp(0) could be changed as breakpoint in above code?
>>
>> So I am curious whether the above code is already dead?
>> If not,  anyone can help to me to clarify that  how the bytecode which is
>> currently executed by interpreter could be replaced with breakpoint?
>> which case could trigger  the
>> "InterpreterRuntime::set_original_bytecode_at" to be called?
>>
>> Appreciated for your help in advance.
>>
>
>


More information about the hotspot-runtime-dev mailing list