0
点赞
收藏
分享

微信扫一扫

32 get/put + field/static 的调试


前言

之前在 hllvm 群组看到了这样的一篇文章, [讨论] 有关实例化的内存分布 

呵呵 当时记录了一个 todo, 呵呵 这里就 跟一下 相关的代码吧 

根据 fieldName 找给定的字段, 找到偏移, 然后 在更新给定的对象给定的偏移的数据吧
[todo] get_field, put_field 的相关字节码 可以看下

一下内容基于 jdk9 + lldb-1001.0.13.3(lldb调试部分) 

测试用例

package com.hx.test06;

/**
 * GetSetField
 *
 * @author Jerry.X.He
 * @version 1.0
 * @date 2020-06-07 09:17
 */
public class Test20GetSetField {

  // identStr
  private static Test20GetSetField staticInstance = new Test20GetSetField();
  private static Test20GetSetField anotherStaticInstance = new Test20GetSetField();
  private String identStr = "identStr";
  int f01;
  int f02;
  int f03;

  // Test20GetSetField
  public static void main(String[] args) {

    staticInstance = anotherStaticInstance;

    staticInstance.f02 = 10;
    int x = staticInstance.f02;

  }

}

对应的字节码信息如下, 下面参照可能需要使用到 

master:classes jerry$ javap -c com/hx/test06/Test20GetSetField.class 
Compiled from "Test20GetSetField.java"
public class com.hx.test06.Test20GetSetField {
  int f01;

  int f02;

  int f03;

  public com.hx.test06.Test20GetSetField();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: ldc           #2                  // String identStr
       7: putfield      #3                  // Field identStr:Ljava/lang/String;
      10: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #4                  // Field anotherStaticInstance:Lcom/hx/test06/Test20GetSetField;
       3: putstatic     #5                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
       6: getstatic     #5                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
       9: bipush        10
      11: putfield      #6                  // Field f02:I
      14: getstatic     #5                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
      17: getfield      #6                  // Field f02:I
      20: istore_1
      21: return

  static {};
    Code:
       0: new           #7                  // class com/hx/test06/Test20GetSetField
       3: dup
       4: invokespecial #8                  // Method "<init>":()V
       7: putstatic     #5                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
      10: new           #7                  // class com/hx/test06/Test20GetSetField
      13: dup
      14: invokespecial #8                  // Method "<init>":()V
      17: putstatic     #4                  // Field anotherStaticInstance:Lcom/hx/test06/Test20GetSetField;
      20: return
}

getstatic 

getstatic 的代码以及汇编

生成 getstatic 的相关代码如下 

void TemplateTable::getstatic(int byte_no) {
  getfield_or_static(byte_no, true);
}

void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
  transition(vtos, vtos);

  const Register cache = rcx;
  const Register index = rdx;
  const Register obj   = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
  const Register off   = rbx;
  const Register flags = rax;
  const Register bc    = LP64_ONLY(c_rarg3) NOT_LP64(rcx); // uses same reg as obj, so don't mix them

  resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
  jvmti_post_field_access(cache, index, is_static, false);
  load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);

  if (!is_static) pop_and_check_object(obj);

  const Address field(obj, off, Address::times_1, 0*wordSize);
  NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize));

  Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;

  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
  // Make sure we don't need to mask edx after the above shift
  assert(btos == 0, "change code, btos != 0");

  __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);

  __ jcc(Assembler::notZero, notByte);
  // btos
  __ load_signed_byte(rax, field);
  __ push(btos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notByte);
  __ cmpl(flags, ztos);
  __ jcc(Assembler::notEqual, notBool);

  // ztos (same code as btos)
  __ load_signed_byte(rax, field);
  __ push(ztos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    // use btos rewriting, no truncating to t/f bit is needed for getfield.
    patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notBool);
  __ cmpl(flags, atos);
  __ jcc(Assembler::notEqual, notObj);
  // atos
  __ load_heap_oop(rax, field);
  __ push(atos);
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notObj);
  __ cmpl(flags, itos);
  __ jcc(Assembler::notEqual, notInt);
  // itos
  __ movl(rax, field);
  __ push(itos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_igetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notInt);
  __ cmpl(flags, ctos);
  __ jcc(Assembler::notEqual, notChar);
  // ctos
  __ load_unsigned_short(rax, field);
  __ push(ctos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_cgetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notChar);
  __ cmpl(flags, stos);
  __ jcc(Assembler::notEqual, notShort);
  // stos
  __ load_signed_short(rax, field);
  __ push(stos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_sgetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notShort);
  __ cmpl(flags, ltos);
  __ jcc(Assembler::notEqual, notLong);
  // ltos

#ifndef _LP64
  // Generate code as if volatile.  There just aren't enough registers to
  // save that information and this code is faster than the test.
  __ fild_d(field);                // Must load atomically
  __ subptr(rsp,2*wordSize);    // Make space for store
  __ fistp_d(Address(rsp,0));
  __ pop(rax);
  __ pop(rdx);
#else
  __ movq(rax, field);
#endif

  __ push(ltos);
  // Rewrite bytecode to be faster
  LP64_ONLY(if (!is_static && rc == may_rewrite) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx));
  __ jmp(Done);

  __ bind(notLong);
  __ cmpl(flags, ftos);
  __ jcc(Assembler::notEqual, notFloat);
  // ftos

  __ load_float(field);
  __ push(ftos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_fgetfield, bc, rbx);
  }
  __ jmp(Done);

  __ bind(notFloat);
#ifdef ASSERT
  __ cmpl(flags, dtos);
  __ jcc(Assembler::notEqual, notDouble);
#endif
  // dtos
  __ load_double(field);
  __ push(dtos);
  // Rewrite bytecode to be faster
  if (!is_static && rc == may_rewrite) {
    patch_bytecode(Bytecodes::_fast_dgetfield, bc, rbx);
  }
#ifdef ASSERT
  __ jmp(Done);


  __ bind(notDouble);
  __ stop("Bad state");
#endif

  __ bind(Done);
  // [jk] not needed currently
  // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadLoad |
  //                                              Assembler::LoadStore));
}

getstatic 的汇编代码如下 

----------------------------------------------------------------------
getstatic  178 getstatic  [0x000000011ed91180, 0x000000011ed91580]  1024 bytes

  0x000000011ed91180: push   %rax
  0x000000011ed91181: jmpq   0x000000011ed911bf
  0x000000011ed91186: sub    $0x8,%rsp
  0x000000011ed9118a: vmovss %xmm0,(%rsp)
  0x000000011ed9118f: jmpq   0x000000011ed911bf
  0x000000011ed91194: sub    $0x10,%rsp
  0x000000011ed91198: vmovsd %xmm0,(%rsp)
  0x000000011ed9119d: jmpq   0x000000011ed911bf
  0x000000011ed911a2: sub    $0x10,%rsp
  0x000000011ed911a6: mov    %rax,(%rsp)
  0x000000011ed911aa: movabs $0x0,%r10
  0x000000011ed911b4: mov    %r10,0x8(%rsp)
  0x000000011ed911b9: jmpq   0x000000011ed911bf
  0x000000011ed911be: push   %rax

  // resolve_cache_and_index
  0x000000011ed911bf: movzwl 0x1(%r13),%edx
  0x000000011ed911c4: mov    -0x30(%rbp),%rcx
  0x000000011ed911c8: shl    $0x2,%edx
  0x000000011ed911cb: mov    0x10(%rcx,%rdx,8),%ebx
  0x000000011ed911cf: shr    $0x10,%ebx
  0x000000011ed911d2: and    $0xff,%ebx
  0x000000011ed911d8: cmp    $0xb2,%ebx
  0x000000011ed911de: je     0x000000011ed9131d
  0x000000011ed911e4: mov    $0xb2,%ebx
  0x000000011ed911e9: callq  0x000000011ed911f3
  0x000000011ed911ee: jmpq   0x000000011ed91311
  0x000000011ed911f3: mov    %rbx,%rsi
  0x000000011ed911f6: lea    0x8(%rsp),%rax
  0x000000011ed911fb: mov    %r13,-0x40(%rbp)
  0x000000011ed911ff: mov    %r15,%rdi
  0x000000011ed91202: mov    %rbp,0x208(%r15)
  0x000000011ed91209: mov    %rax,0x1f8(%r15)
  0x000000011ed91210: test   $0xf,%esp
  0x000000011ed91216: je     0x000000011ed9122e
  0x000000011ed9121c: sub    $0x8,%rsp
  0x000000011ed91220: callq  0x000000010c99b988 = InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)
  0x000000011ed91225: add    $0x8,%rsp
  0x000000011ed91229: jmpq   0x000000011ed91233
  0x000000011ed9122e: callq  0x000000010c99b988 = InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)
  0x000000011ed91233: movabs $0x0,%r10
  0x000000011ed9123d: mov    %r10,0x1f8(%r15)
  0x000000011ed91244: movabs $0x0,%r10
  0x000000011ed9124e: mov    %r10,0x208(%r15)
  0x000000011ed91255: movabs $0x0,%r10
  0x000000011ed9125f: mov    %r10,0x200(%r15)
  0x000000011ed91266: mov    0x324(%r15),%edi
  0x000000011ed9126d: test   $0x1,%edi
  0x000000011ed91273: je     0x000000011ed912aa
  0x000000011ed91279: test   $0x2,%edi
  0x000000011ed9127f: jne    0x000000011ed912aa
  0x000000011ed91285: test   $0xf,%esp
  0x000000011ed9128b: je     0x000000011ed912a3
  0x000000011ed91291: sub    $0x8,%rsp
  0x000000011ed91295: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed9129a: add    $0x8,%rsp
  0x000000011ed9129e: jmpq   0x000000011ed912a8
  0x000000011ed912a3: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed912a8: jmpq   *%rax
  0x000000011ed912aa: mov    0x3c8(%r15),%rdi
  0x000000011ed912b1: test   %rdi,%rdi
  0x000000011ed912b4: je     0x000000011ed912f5
  0x000000011ed912ba: mov    0x6c(%rdi),%edi
  0x000000011ed912bd: cmp    $0x1,%edi
  0x000000011ed912c0: jne    0x000000011ed912f5
  0x000000011ed912c6: mov    0x3c8(%r15),%rdi
  0x000000011ed912cd: mov    0x70(%rdi),%edi
  0x000000011ed912d0: test   $0xf,%esp
  0x000000011ed912d6: je     0x000000011ed912ee
  0x000000011ed912dc: sub    $0x8,%rsp
  0x000000011ed912e0: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed912e5: add    $0x8,%rsp
  0x000000011ed912e9: jmpq   0x000000011ed912f3
  0x000000011ed912ee: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed912f3: jmpq   *%rax
  0x000000011ed912f5: cmpq   $0x0,0x8(%r15)
  0x000000011ed912fd: je     0x000000011ed91308
  0x000000011ed91303: jmpq   0x000000011ed61a00
  0x000000011ed91308: mov    -0x40(%rbp),%r13
  0x000000011ed9130c: mov    -0x38(%rbp),%r14
  0x000000011ed91310: retq   
  0x000000011ed91311: movzwl 0x1(%r13),%edx
  0x000000011ed91316: mov    -0x30(%rbp),%rcx
  0x000000011ed9131a: shl    $0x2,%edx

  // jvmti_post_field_access
  0x000000011ed9131d: mov    -0x11e5a46b(%rip),%eax        # 0x000000010cf36eb8 = JvmtiExport::_field_access_count
  0x000000011ed91323: test   %eax,%eax
  0x000000011ed91325: je     0x000000011ed9146f
  0x000000011ed9132b: add    $0x10,%rcx
  0x000000011ed9132f: shl    $0x3,%edx
  0x000000011ed91332: add    %rdx,%rcx
  0x000000011ed91335: xor    %rax,%rax
  0x000000011ed91338: callq  0x000000011ed91342
  0x000000011ed9133d: jmpq   0x000000011ed91463
  0x000000011ed91342: mov    %rcx,%rdx
  0x000000011ed91345: mov    %rax,%rsi
  0x000000011ed91348: lea    0x8(%rsp),%rax
  0x000000011ed9134d: mov    %r13,-0x40(%rbp)
  0x000000011ed91351: mov    %r15,%rdi
  0x000000011ed91354: mov    %rbp,0x208(%r15)
  0x000000011ed9135b: mov    %rax,0x1f8(%r15)
  0x000000011ed91362: test   $0xf,%esp
  0x000000011ed91368: je     0x000000011ed91380
  0x000000011ed9136e: sub    $0x8,%rsp
  0x000000011ed91372: callq  0x000000010c99bfd6 = InterpreterRuntime::post_field_access(JavaThread*, oopDesc*, ConstantPoolCacheEntry*)
  0x000000011ed91377: add    $0x8,%rsp
  0x000000011ed9137b: jmpq   0x000000011ed91385
  0x000000011ed91380: callq  0x000000010c99bfd6 = InterpreterRuntime::post_field_access(JavaThread*, oopDesc*, ConstantPoolCacheEntry*)
  0x000000011ed91385: movabs $0x0,%r10
  0x000000011ed9138f: mov    %r10,0x1f8(%r15)
  0x000000011ed91396: movabs $0x0,%r10
  0x000000011ed913a0: mov    %r10,0x208(%r15)
  0x000000011ed913a7: movabs $0x0,%r10
  0x000000011ed913b1: mov    %r10,0x200(%r15)
  0x000000011ed913b8: mov    0x324(%r15),%edi
  0x000000011ed913bf: test   $0x1,%edi
  0x000000011ed913c5: je     0x000000011ed913fc
  0x000000011ed913cb: test   $0x2,%edi
  0x000000011ed913d1: jne    0x000000011ed913fc
  0x000000011ed913d7: test   $0xf,%esp
  0x000000011ed913dd: je     0x000000011ed913f5
  0x000000011ed913e3: sub    $0x8,%rsp
  0x000000011ed913e7: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed913ec: add    $0x8,%rsp
  0x000000011ed913f0: jmpq   0x000000011ed913fa
  0x000000011ed913f5: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed913fa: jmpq   *%rax
  0x000000011ed913fc: mov    0x3c8(%r15),%rdi
  0x000000011ed91403: test   %rdi,%rdi
  0x000000011ed91406: je     0x000000011ed91447
  0x000000011ed9140c: mov    0x6c(%rdi),%edi
  0x000000011ed9140f: cmp    $0x1,%edi
  0x000000011ed91412: jne    0x000000011ed91447
  0x000000011ed91418: mov    0x3c8(%r15),%rdi
  0x000000011ed9141f: mov    0x70(%rdi),%edi
  0x000000011ed91422: test   $0xf,%esp
  0x000000011ed91428: je     0x000000011ed91440
  0x000000011ed9142e: sub    $0x8,%rsp
  0x000000011ed91432: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed91437: add    $0x8,%rsp
  0x000000011ed9143b: jmpq   0x000000011ed91445
  0x000000011ed91440: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed91445: jmpq   *%rax
  0x000000011ed91447: cmpq   $0x0,0x8(%r15)
  0x000000011ed9144f: je     0x000000011ed9145a
  0x000000011ed91455: jmpq   0x000000011ed61a00
  0x000000011ed9145a: mov    -0x40(%rbp),%r13
  0x000000011ed9145e: mov    -0x38(%rbp),%r14
  0x000000011ed91462: retq

  // load_field_cp_cache_entry
  0x000000011ed91463: movzwl 0x1(%r13),%edx
  0x000000011ed91468: mov    -0x30(%rbp),%rcx
  0x000000011ed9146c: shl    $0x2,%edx
  0x000000011ed9146f: mov    0x20(%rcx,%rdx,8),%rbx
  0x000000011ed91474: mov    0x28(%rcx,%rdx,8),%eax
  0x000000011ed91478: mov    0x18(%rcx,%rdx,8),%rcx
  0x000000011ed9147d: mov    0x68(%rcx),%rcx

  0x000000011ed91481: shr    $0x1c,%eax

  // byte
  0x000000011ed91484: and    $0xf,%eax
  0x000000011ed91487: jne    0x000000011ed91497
  0x000000011ed9148d: movsbl (%rcx,%rbx,1),%eax
  0x000000011ed91491: push   %rax
  0x000000011ed91492: jmpq   0x000000011ed9154b

  // boolean
  0x000000011ed91497: cmp    $0x1,%eax
  0x000000011ed9149a: jne    0x000000011ed914aa
  0x000000011ed914a0: movsbl (%rcx,%rbx,1),%eax
  0x000000011ed914a4: push   %rax
  0x000000011ed914a5: jmpq   0x000000011ed9154b

  // object
  0x000000011ed914aa: cmp    $0x8,%eax
  0x000000011ed914ad: jne    0x000000011ed914c0
  0x000000011ed914b3: mov    (%rcx,%rbx,1),%eax
  0x000000011ed914b6: shl    $0x3,%rax
  0x000000011ed914ba: push   %rax
  0x000000011ed914bb: jmpq   0x000000011ed9154b

  // int
  0x000000011ed914c0: cmp    $0x4,%eax
  0x000000011ed914c3: jne    0x000000011ed914d2
  0x000000011ed914c9: mov    (%rcx,%rbx,1),%eax
  0x000000011ed914cc: push   %rax
  0x000000011ed914cd: jmpq   0x000000011ed9154b

  // char
  0x000000011ed914d2: cmp    $0x2,%eax
  0x000000011ed914d5: jne    0x000000011ed914e5
  0x000000011ed914db: movzwl (%rcx,%rbx,1),%eax
  0x000000011ed914df: push   %rax
  0x000000011ed914e0: jmpq   0x000000011ed9154b

  // short
  0x000000011ed914e5: cmp    $0x3,%eax
  0x000000011ed914e8: jne    0x000000011ed914f8
  0x000000011ed914ee: movswl (%rcx,%rbx,1),%eax
  0x000000011ed914f2: push   %rax
  0x000000011ed914f3: jmpq   0x000000011ed9154b

  // long
  0x000000011ed914f8: cmp    $0x5,%eax
  0x000000011ed914fb: jne    0x000000011ed91521
  0x000000011ed91501: mov    (%rcx,%rbx,1),%rax
  0x000000011ed91505: sub    $0x10,%rsp
  0x000000011ed91509: mov    %rax,(%rsp)
  0x000000011ed9150d: movabs $0x0,%r10
  0x000000011ed91517: mov    %r10,0x8(%rsp)
  0x000000011ed9151c: jmpq   0x000000011ed9154b

  // float
  0x000000011ed91521: cmp    $0x6,%eax
  0x000000011ed91524: jne    0x000000011ed9153d
  0x000000011ed9152a: vmovss (%rcx,%rbx,1),%xmm0
  0x000000011ed9152f: sub    $0x8,%rsp
  0x000000011ed91533: vmovss %xmm0,(%rsp)
  0x000000011ed91538: jmpq   0x000000011ed9154b

  // double 
  0x000000011ed9153d: vmovsd (%rcx,%rbx,1),%xmm0
  0x000000011ed91542: sub    $0x10,%rsp
  0x000000011ed91546: vmovsd %xmm0,(%rsp)

  0x000000011ed9154b: movzbl 0x3(%r13),%ebx
  0x000000011ed91550: add    $0x3,%r13
  0x000000011ed91554: movabs $0x10cf4c950,%r10
  0x000000011ed9155e: jmpq   *(%r10,%rbx,8)
  0x000000011ed91562: nopw   0x0(%rax,%rax,1)
  0x000000011ed91568: add    %al,(%rax)
  0x000000011ed9156a: add    %al,(%rax)
  0x000000011ed9156c: add    %al,(%rax)
  0x000000011ed9156e: add    %al,(%rax)
  0x000000011ed91570: add    %al,(%rax)
  0x000000011ed91572: add    %al,(%rax)
  0x000000011ed91574: add    %al,(%rax)
  0x000000011ed91576: add    %al,(%rax)
  0x000000011ed91578: add    %al,(%rax)
  0x000000011ed9157a: add    %al,(%rax)
  0x000000011ed9157c: add    %al,(%rax)
  0x000000011ed9157e: add    %al,(%rax)

resolve_cache_and_index 的主要的作用是将解析 constantsPoolCache 中给定的字段的相关信息(所属类型, 字段索引, 字段偏移, 相关标记信息, 常量池信息)

load_field_cp_cache_entry 的主要作用是 加载字段对应的对象, 加载字段偏移 

我们这里着重关注 getstatic 的数据处理部分, 也就是上面的 根据不同的数据类型, 加载字段, push 到栈顶 

另外一点就是 到数据处理这里的时候, cx 存放的是字段对应的对象, bx 存放的是字段的偏移, 这两点信息 是我们待会儿的调试的需要注意的关键点  

getstatic 基于 lldb 的调试

进入程序, 在 getstatic 的地方打上一个断点 

(lldb) p _active_table._table[9][178]
(address) $0 = 0x00000001058495df "A\x0f\xb7U\x01H\x8bM??\U0000008b\\???\x10\x81??
(lldb) p _active_table._table[0][0]
(address) $1 = 0x0000000105830b9e "PA\x0f\xb6]\x01I??I\xbap\xb20\x04\x01"
(lldb) p _normal_table._table[0][0]
(address) $2 = 0x0000000105830b9e "PA\x0f\xb6]\x01I??I\xbap\xb20\x04\x01"
(lldb) p _safept_table._table[0][0]
(address) $3 = 0x00000001058252e0 "P?
(lldb) b 0x00000001058495df
Breakpoint 3: address = 0x00000001058495df
(lldb) c
Process 1964 resuming
Process 1964 stopped
* thread #5, stop reason = breakpoint 3.1
    frame #0: 0x00000001058495df
->  0x1058495df: movzwl 0x1(%r13), %edx
    0x1058495e4: movq   -0x30(%rbp), %rcx
    0x1058495e8: shll   $0x2, %edx
    0x1058495eb: movl   0x10(%rcx,%rdx,8), %ebx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000700001f12648
       rbx = 0x00000000000000b2
       rcx = 0x0000000000000008
       rdx = 0x0000000000000000
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12648
        r8 = 0x0000000000002901
        r9 = 0x0000000105000800
       r10 = 0x000000010430b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x0000000000000000
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef48
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x00000001058495df
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) x 0x000000011e46ef48
0x11e46ef48: b2 02 00 b3 03 00 b2 03 00 10 0a b5 04 00 b2 03  ?..?..?....?..?.
0x11e46ef58: 00 b4 04 00 3c b1 ff 00 2e 32 41 3a 00 00 00 00  .?..<??..2A:....
(lldb) x 0x0000700001f12648
0x700001f12648: 48 26 f1 01 00 70 00 00 48 ef 46 1e 01 00 00 00  H&?..p..H?F.....
0x700001f12658: a8 26 f1 01 00 70 00 00 88 f0 46 1e 01 00 00 00  ?&?..p...?F.....
(lldb) po ((ConstantPoolCache*)(0x011e46f088))->constant_pool()->print()
{constant pool}
 - holder: 0x00000007c008fc30
 - cache: 0x000000011e46f088
 - resolved_references: 0x0000000747bb8160
 - reference_map: 0x000000011e46f158
 -   1 : Method : klass_index=9 name_and_type_index=33
 -   2 : String : 'identStr'
 -   3 : Field : klass_index=7 name_and_type_index=34
 -   4 : Field : klass_index=7 name_and_type_index=35
 -   5 : Field : klass_index=7 name_and_type_index=36
 -   6 : Field : klass_index=7 name_and_type_index=37
 -   7 : Class : 'com/hx/test06/Test20GetSetField' {0x00000007c008fc30}
 -   8 : Method : klass_index=7 name_and_type_index=33
 -   9 : Class : 'java/lang/Object' {0x00000007c0000f70}
 -  10 : Utf8 : 'staticInstance'
 -  11 : Utf8 : 'Lcom/hx/test06/Test20GetSetField;'
 -  12 : Utf8 : 'anotherStaticInstance'
 -  13 : Utf8 : 'identStr'
 -  14 : Utf8 : 'Ljava/lang/String;'
 -  15 : Utf8 : 'f01'
 -  16 : Utf8 : 'I'
 -  17 : Utf8 : 'f02'
 -  18 : Utf8 : 'f03'
 -  19 : Utf8 : '<init>'
 -  20 : Utf8 : '()V'
 -  21 : Utf8 : 'Code'
 -  22 : Utf8 : 'LineNumberTable'
 -  23 : Utf8 : 'LocalVariableTable'
 -  24 : Utf8 : 'this'
 -  25 : Utf8 : 'main'
 -  26 : Utf8 : '([Ljava/lang/String;)V'
 -  27 : Utf8 : 'args'
 -  28 : Utf8 : '[Ljava/lang/String;'
 -  29 : Utf8 : 'x'
 -  30 : Utf8 : '<clinit>'
 -  31 : Utf8 : 'SourceFile'
 -  32 : Utf8 : 'Test20GetSetField.java'
 -  33 : NameAndType : name_index=19 signature_index=20
 -  34 : NameAndType : name_index=13 signature_index=14
 -  35 : NameAndType : name_index=12 signature_index=11
 -  36 : NameAndType : name_index=10 signature_index=11
 -  37 : NameAndType : name_index=17 signature_index=16
 -  38 : Utf8 : 'com/hx/test06/Test20GetSetField'
 -  39 : Utf8 : 'java/lang/Object'

(lldb) p ((InstanceKlass*)0x00000007c008fc30)->java_mirror()->print()
java.lang.Class 
{0x0000000747bb7fb0} - klass: 'java/lang/Class'
 - ---- fields (total size 15 words):
 - private volatile transient strict 'cachedConstructor' 'Ljava/lang/reflect/Constructor;' @12  NULL (0 0)
 - private volatile transient strict 'newInstanceCallerCache' 'Ljava/lang/Class;' @16  NULL (0 e8f77007)
 - private transient 'name' 'Ljava/lang/String;' @20  "com.hx.test06.Test20GetSetField"{0x0000000747bb8038} (e8f77007 e8fc0b37)
 - private transient 'module' 'Ljava/lang/Module;' @24  a 'java/lang/Module'{0x0000000747e059b8} (e8fc0b37 e8fc0af7)
 - private final 'classLoader' 'Ljava/lang/ClassLoader;' @28  a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8f767c3)
 - private transient 'packageName' 'Ljava/lang/String;' @32  "com.hx.test06"{0x0000000747bb3e18} (e8f767c3 0)
 - private final strict 'componentType' 'Ljava/lang/Class;' @36  NULL (0 e8f77027)
 - private volatile transient strict 'reflectionData' 'Ljava/lang/ref/SoftReference;' @40  a 'java/lang/ref/SoftReference'{0x0000000747bb8138} (e8f77027 0)
 - private volatile transient 'genericInfo' 'Lsun/reflect/generics/repository/ClassRepository;' @44  NULL (0 0)
 - private volatile transient strict 'enumConstants' '[Ljava/lang/Object;' @48  NULL (0 0)
 - private volatile transient strict 'enumConstantDirectory' 'Ljava/util/Map;' @52  NULL (0 0)
 - private volatile transient 'annotationData' 'Ljava/lang/Class$AnnotationData;' @56  NULL (0 0)
 - private volatile transient 'annotationType' 'Lsun/reflect/annotation/AnnotationType;' @60  NULL (0 0)
 - transient 'classValueMap' 'Ljava/lang/ClassValue$ClassValueMap;' @64  NULL (0 e8f76f31)
 - private volatile transient 'classRedefinedCount' 'I' @96  0
 - signature: Lcom/hx/test06/Test20GetSetField;
 - fake entry for mirror: 'com/hx/test06/Test20GetSetField'
 - fake entry for array: NULL
 - fake entry for oop_size: 15
 - fake entry for static_oop_field_count: 2
 - private static 'staticInstance' 'Lcom/hx/test06/Test20GetSetField;' @112  a 'com/hx/test06/Test20GetSetField'{0x0000000747bb8390} (e8f77072 e8f7707c)
 - private static 'anotherStaticInstance' 'Lcom/hx/test06/Test20GetSetField;' @116  a 'com/hx/test06/Test20GetSetField'{0x0000000747bb83e0} (e8f7707c 1)
(lldb)

打印当前的字节码相关信息, 可以定位到当前是在执行 getstatic 

b2 02 00 b3 03 00 b2 03 00 10 0a 

// 转换为字节码信息 
getstatic     #2                  // Field anotherStaticInstance:Lcom/hx/test06/Test20GetSetField;
putstatic     #3                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
getstatic     #2                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
bipush        10

这里还顺便 输出了一下 Test20GetSetField 的常量池的信息, 以及 Test20GetSetField.class 的信息 

然后在我们数据处理之前打上一个断点 

(lldb) b 0x105849890
Breakpoint 4: address = 0x0000000105849890
(lldb) c
Process 1964 resuming
Process 1964 stopped
* thread #5, stop reason = breakpoint 4.1
    frame #0: 0x0000000105849890
->  0x105849890: jne    0x1058498a0
    0x105849896: movsbl (%rcx,%rbx), %eax
    0x10584989a: pushq  %rax
    0x10584989b: jmp    0x105849a61
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000000000008
       rbx = 0x0000000000000074
       rcx = 0x0000000747bb7fb0
       rdx = 0x0000000000000008
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12648
        r8 = 0x0000000000000000
        r9 = 0x0000000100340790
       r10 = 0x0000000000000000
       r11 = 0x000000010034078c
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef48
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x0000000105849890
    rflags = 0x0000000000000202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

可以发现此时 cx 是 0x0000000747bb7fb0 正是 Test20GetSetField.class 

然后 bx 是 0x0000000000000074 = 116(十进制), 在 Test20GetSetField.class 的 oop 上面 偏移为 116 的数据是 anotherStaticInstance 

到断点处 ax 存放的是 字段的类型(atos = 0x08)

然后我们来看一下 数据处理 

(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498a0
->  0x1058498a0: cmpl   $0x1, %eax
    0x1058498a3: jne    0x1058498b3
    0x1058498a9: movsbl (%rcx,%rbx), %eax
    0x1058498ad: pushq  %rax
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498a3
->  0x1058498a3: jne    0x1058498b3
    0x1058498a9: movsbl (%rcx,%rbx), %eax
    0x1058498ad: pushq  %rax
    0x1058498ae: jmp    0x105849a61
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498b3
->  0x1058498b3: cmpl   $0x8, %eax
    0x1058498b6: jne    0x105849951
    0x1058498bc: movl   (%rcx,%rbx), %eax
    0x1058498bf: pushq  %r10
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498b6
->  0x1058498b6: jne    0x105849951
    0x1058498bc: movl   (%rcx,%rbx), %eax
    0x1058498bf: pushq  %r10
    0x1058498c1: cmpq   -0x15332d8(%rip), %r12    ; Universe::_narrow_ptrs_base
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498bc
->  0x1058498bc: movl   (%rcx,%rbx), %eax
    0x1058498bf: pushq  %r10
    0x1058498c1: cmpq   -0x15332d8(%rip), %r12    ; Universe::_narrow_ptrs_base
    0x1058498c8: je     0x105849945
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498bf
->  0x1058498bf: pushq  %r10
    0x1058498c1: cmpq   -0x15332d8(%rip), %r12    ; Universe::_narrow_ptrs_base
    0x1058498c8: je     0x105849945
    0x1058498ce: movq   %rsp, -0x28(%rsp)
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x00000000e8f7707c
       rbx = 0x0000000000000074
       rcx = 0x0000000747bb7fb0
       rdx = 0x0000000000000008
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12648
        r8 = 0x0000000000000000
        r9 = 0x0000000100340790
       r10 = 0x0000000000000000
       r11 = 0x000000010034078c
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef48
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x00000001058498bf
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498c1
->  0x1058498c1: cmpq   -0x15332d8(%rip), %r12    ; Universe::_narrow_ptrs_base
    0x1058498c8: je     0x105849945
    0x1058498ce: movq   %rsp, -0x28(%rsp)
    0x1058498d3: subq   $0x80, %rsp
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x00000001058498c8
->  0x1058498c8: je     0x105849945
    0x1058498ce: movq   %rsp, -0x28(%rsp)
    0x1058498d3: subq   $0x80, %rsp
    0x1058498da: movq   %rax, 0x78(%rsp)
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849945
->  0x105849945: popq   %r10
    0x105849947: shlq   $0x3, %rax
    0x10584994b: pushq  %rax
    0x10584994c: jmp    0x105849a61
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849947
->  0x105849947: shlq   $0x3, %rax
    0x10584994b: pushq  %rax
    0x10584994c: jmp    0x105849a61
    0x105849951: cmpl   $0x4, %eax
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584994b
->  0x10584994b: pushq  %rax
    0x10584994c: jmp    0x105849a61
    0x105849951: cmpl   $0x4, %eax
    0x105849954: jne    0x105849963
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb83e0
       rbx = 0x0000000000000074
       rcx = 0x0000000747bb7fb0
       rdx = 0x0000000000000008
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12648
        r8 = 0x0000000000000000
        r9 = 0x0000000100340790
       r10 = 0x0000000000000000
       r11 = 0x000000010034078c
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef48
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x000000010584994b
    rflags = 0x0000000000000202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584994c
->  0x10584994c: jmp    0x105849a61
    0x105849951: cmpl   $0x4, %eax
    0x105849954: jne    0x105849963
    0x10584995a: movl   (%rcx,%rbx), %eax
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849a61
->  0x105849a61: movzbl 0x3(%r13), %ebx
    0x105849a66: addq   $0x3, %r13
    0x105849a6a: movabsq $0x10430b270, %r10        ; imm = 0x10430B270 
    0x105849a74: jmpq   *(%r10,%rbx,8)
Target 0: (java) stopped.
(lldb)

实际的调试过程中 会发现多了一段 r10 的相关的东西, 呵呵 但是不影响这里的逻辑 

获取了 Test20GetSetField.class 上面存放的 anotherStaticInstance 的地址信息, 然后 恢复指针(<<3) 

然后 压入表达式栈中 

putstatic 

putstatic 的代码以及汇编

生成 putstatic 的相关代码如下 

void TemplateTable::putstatic(int byte_no) {
  putfield_or_static(byte_no, true);
}

void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
  transition(vtos, vtos);

  const Register cache = rcx;
  const Register index = rdx;
  const Register obj   = rcx;
  const Register off   = rbx;
  const Register flags = rax;
  const Register bc    = LP64_ONLY(c_rarg3) NOT_LP64(rcx);

  resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
  jvmti_post_field_mod(cache, index, is_static);
  load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);

  // [jk] not needed currently
  // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
  //                                              Assembler::StoreStore));

  Label notVolatile, Done;
  __ movl(rdx, flags);
  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
  __ andl(rdx, 0x1);

  // field addresses
  const Address field(obj, off, Address::times_1, 0*wordSize);
  NOT_LP64( const Address hi(obj, off, Address::times_1, 1*wordSize);)

  Label notByte, notBool, notInt, notShort, notChar,
        notLong, notFloat, notObj, notDouble;

  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);

  assert(btos == 0, "change code, btos != 0");
  __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
  __ jcc(Assembler::notZero, notByte);

  // btos
  {
    __ pop(btos);
    if (!is_static) pop_and_check_object(obj);
    __ movb(field, rax);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notByte);
  __ cmpl(flags, ztos);
  __ jcc(Assembler::notEqual, notBool);

  // ztos
  {
    __ pop(ztos);
    if (!is_static) pop_and_check_object(obj);
    __ andl(rax, 0x1);
    __ movb(field, rax);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notBool);
  __ cmpl(flags, atos);
  __ jcc(Assembler::notEqual, notObj);

  // atos
  {
    __ pop(atos);
    if (!is_static) pop_and_check_object(obj);
    // Store into the field
    do_oop_store(_masm, field, rax, _bs->kind(), false);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notObj);
  __ cmpl(flags, itos);
  __ jcc(Assembler::notEqual, notInt);

  // itos
  {
    __ pop(itos);
    if (!is_static) pop_and_check_object(obj);
    __ movl(field, rax);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notInt);
  __ cmpl(flags, ctos);
  __ jcc(Assembler::notEqual, notChar);

  // ctos
  {
    __ pop(ctos);
    if (!is_static) pop_and_check_object(obj);
    __ movw(field, rax);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notChar);
  __ cmpl(flags, stos);
  __ jcc(Assembler::notEqual, notShort);

  // stos
  {
    __ pop(stos);
    if (!is_static) pop_and_check_object(obj);
    __ movw(field, rax);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notShort);
  __ cmpl(flags, ltos);
  __ jcc(Assembler::notEqual, notLong);

  // ltos
#ifdef _LP64
  {
    __ pop(ltos);
    if (!is_static) pop_and_check_object(obj);
    __ movq(field, rax);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }
#else
  {
    Label notVolatileLong;
    __ testl(rdx, rdx);
    __ jcc(Assembler::zero, notVolatileLong);

    __ pop(ltos);  // overwrites rdx, do this after testing volatile.
    if (!is_static) pop_and_check_object(obj);

    // Replace with real volatile test
    __ push(rdx);
    __ push(rax);                 // Must update atomically with FIST
    __ fild_d(Address(rsp,0));    // So load into FPU register
    __ fistp_d(field);            // and put into memory atomically
    __ addptr(rsp, 2*wordSize);
    // volatile_barrier();
    volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
                                                 Assembler::StoreStore));
    // Don't rewrite volatile version
    __ jmp(notVolatile);

    __ bind(notVolatileLong);

    __ pop(ltos);  // overwrites rdx
    if (!is_static) pop_and_check_object(obj);
    __ movptr(hi, rdx);
    __ movptr(field, rax);
    // Don't rewrite to _fast_lputfield for potential volatile case.
    __ jmp(notVolatile);
  }
#endif // _LP64

  __ bind(notLong);
  __ cmpl(flags, ftos);
  __ jcc(Assembler::notEqual, notFloat);

  // ftos
  {
    __ pop(ftos);
    if (!is_static) pop_and_check_object(obj);
    __ store_float(field);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no);
    }
    __ jmp(Done);
  }

  __ bind(notFloat);
#ifdef ASSERT
  __ cmpl(flags, dtos);
  __ jcc(Assembler::notEqual, notDouble);
#endif

  // dtos
  {
    __ pop(dtos);
    if (!is_static) pop_and_check_object(obj);
    __ store_double(field);
    if (!is_static && rc == may_rewrite) {
      patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
    }
  }

#ifdef ASSERT
  __ jmp(Done);

  __ bind(notDouble);
  __ stop("Bad state");
#endif

  __ bind(Done);

  // Check for volatile store
  __ testl(rdx, rdx);
  __ jcc(Assembler::zero, notVolatile);
  volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
                                               Assembler::StoreStore));
  __ bind(notVolatile);
}

putstatic 的汇编代码如下 

----------------------------------------------------------------------
putstatic  179 putstatic  [0x000000011ed915a0, 0x000000011ed91ae0]  1344 bytes

  0x000000011ed915a0: push   %rax
  0x000000011ed915a1: jmpq   0x000000011ed915df
  0x000000011ed915a6: sub    $0x8,%rsp
  0x000000011ed915aa: vmovss %xmm0,(%rsp)
  0x000000011ed915af: jmpq   0x000000011ed915df
  0x000000011ed915b4: sub    $0x10,%rsp
  0x000000011ed915b8: vmovsd %xmm0,(%rsp)
  0x000000011ed915bd: jmpq   0x000000011ed915df
  0x000000011ed915c2: sub    $0x10,%rsp
  0x000000011ed915c6: mov    %rax,(%rsp)
  0x000000011ed915ca: movabs $0x0,%r10
  0x000000011ed915d4: mov    %r10,0x8(%rsp)
  0x000000011ed915d9: jmpq   0x000000011ed915df
  0x000000011ed915de: push   %rax

  // resolve_cache_and_index
  0x000000011ed915df: movzwl 0x1(%r13),%edx
  0x000000011ed915e4: mov    -0x30(%rbp),%rcx
  0x000000011ed915e8: shl    $0x2,%edx
  0x000000011ed915eb: mov    0x10(%rcx,%rdx,8),%ebx
  0x000000011ed915ef: shr    $0x18,%ebx
  0x000000011ed915f2: and    $0xff,%ebx
  0x000000011ed915f8: cmp    $0xb3,%ebx
  0x000000011ed915fe: je     0x000000011ed9173d
  0x000000011ed91604: mov    $0xb3,%ebx
  0x000000011ed91609: callq  0x000000011ed91613
  0x000000011ed9160e: jmpq   0x000000011ed91731
  0x000000011ed91613: mov    %rbx,%rsi
  0x000000011ed91616: lea    0x8(%rsp),%rax
  0x000000011ed9161b: mov    %r13,-0x40(%rbp)
  0x000000011ed9161f: mov    %r15,%rdi
  0x000000011ed91622: mov    %rbp,0x208(%r15)
  0x000000011ed91629: mov    %rax,0x1f8(%r15)
  0x000000011ed91630: test   $0xf,%esp
  0x000000011ed91636: je     0x000000011ed9164e
  0x000000011ed9163c: sub    $0x8,%rsp
  0x000000011ed91640: callq  0x000000010c99b988 = InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)
  0x000000011ed91645: add    $0x8,%rsp
  0x000000011ed91649: jmpq   0x000000011ed91653
  0x000000011ed9164e: callq  0x000000010c99b988 = InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)
  0x000000011ed91653: movabs $0x0,%r10
  0x000000011ed9165d: mov    %r10,0x1f8(%r15)
  0x000000011ed91664: movabs $0x0,%r10
  0x000000011ed9166e: mov    %r10,0x208(%r15)
  0x000000011ed91675: movabs $0x0,%r10
  0x000000011ed9167f: mov    %r10,0x200(%r15)
  0x000000011ed91686: mov    0x324(%r15),%edi
  0x000000011ed9168d: test   $0x1,%edi
  0x000000011ed91693: je     0x000000011ed916ca
  0x000000011ed91699: test   $0x2,%edi
  0x000000011ed9169f: jne    0x000000011ed916ca
  0x000000011ed916a5: test   $0xf,%esp
  0x000000011ed916ab: je     0x000000011ed916c3
  0x000000011ed916b1: sub    $0x8,%rsp
  0x000000011ed916b5: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed916ba: add    $0x8,%rsp
  0x000000011ed916be: jmpq   0x000000011ed916c8
  0x000000011ed916c3: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed916c8: jmpq   *%rax
  0x000000011ed916ca: mov    0x3c8(%r15),%rdi
  0x000000011ed916d1: test   %rdi,%rdi
  0x000000011ed916d4: je     0x000000011ed91715
  0x000000011ed916da: mov    0x6c(%rdi),%edi
  0x000000011ed916dd: cmp    $0x1,%edi
  0x000000011ed916e0: jne    0x000000011ed91715
  0x000000011ed916e6: mov    0x3c8(%r15),%rdi
  0x000000011ed916ed: mov    0x70(%rdi),%edi
  0x000000011ed916f0: test   $0xf,%esp
  0x000000011ed916f6: je     0x000000011ed9170e
  0x000000011ed916fc: sub    $0x8,%rsp
  0x000000011ed91700: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed91705: add    $0x8,%rsp
  0x000000011ed91709: jmpq   0x000000011ed91713
  0x000000011ed9170e: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed91713: jmpq   *%rax
  0x000000011ed91715: cmpq   $0x0,0x8(%r15)
  0x000000011ed9171d: je     0x000000011ed91728
  0x000000011ed91723: jmpq   0x000000011ed61a00
  0x000000011ed91728: mov    -0x40(%rbp),%r13
  0x000000011ed9172c: mov    -0x38(%rbp),%r14
  0x000000011ed91730: retq
  0x000000011ed91731: movzwl 0x1(%r13),%edx
  0x000000011ed91736: mov    -0x30(%rbp),%rcx
  0x000000011ed9173a: shl    $0x2,%edx

  // jvmti_post_field_access
  0x000000011ed9173d: mov    -0x11e5a887(%rip),%eax        # 0x000000010cf36ebc = JvmtiExport::_field_modification_count
  0x000000011ed91743: test   %eax,%eax
  0x000000011ed91745: je     0x000000011ed91899
  0x000000011ed9174b: movzwl 0x1(%r13),%r10d
  0x000000011ed91750: mov    -0x30(%rbp),%rdx
  0x000000011ed91754: shl    $0x2,%r10d
  0x000000011ed91758: xor    %esi,%esi
  0x000000011ed9175a: add    $0x10,%rdx
  0x000000011ed9175e: shl    $0x3,%r10d
  0x000000011ed91762: add    %r10,%rdx
  0x000000011ed91765: mov    %rsp,%rcx
  0x000000011ed91768: callq  0x000000011ed91772
  0x000000011ed9176d: jmpq   0x000000011ed9188d
  0x000000011ed91772: lea    0x8(%rsp),%rax
  0x000000011ed91777: mov    %r13,-0x40(%rbp)
  0x000000011ed9177b: mov    %r15,%rdi
  0x000000011ed9177e: mov    %rbp,0x208(%r15)
  0x000000011ed91785: mov    %rax,0x1f8(%r15)
  0x000000011ed9178c: test   $0xf,%esp
  0x000000011ed91792: je     0x000000011ed917aa
  0x000000011ed91798: sub    $0x8,%rsp
  0x000000011ed9179c: callq  0x000000010c99c0d8 = InterpreterRuntime::post_field_modification(JavaThread*, oopDesc*, ConstantPoolCacheEntry*, jvalue*)
  0x000000011ed917a1: add    $0x8,%rsp
  0x000000011ed917a5: jmpq   0x000000011ed917af
  0x000000011ed917aa: callq  0x000000010c99c0d8 = InterpreterRuntime::post_field_modification(JavaThread*, oopDesc*, ConstantPoolCacheEntry*, jvalue*)
  0x000000011ed917af: movabs $0x0,%r10
  0x000000011ed917b9: mov    %r10,0x1f8(%r15)
  0x000000011ed917c0: movabs $0x0,%r10
  0x000000011ed917ca: mov    %r10,0x208(%r15)
  0x000000011ed917d1: movabs $0x0,%r10
  0x000000011ed917db: mov    %r10,0x200(%r15)
  0x000000011ed917e2: mov    0x324(%r15),%edi
  0x000000011ed917e9: test   $0x1,%edi
  0x000000011ed917ef: je     0x000000011ed91826
  0x000000011ed917f5: test   $0x2,%edi
  0x000000011ed917fb: jne    0x000000011ed91826
  0x000000011ed91801: test   $0xf,%esp
  0x000000011ed91807: je     0x000000011ed9181f
  0x000000011ed9180d: sub    $0x8,%rsp
  0x000000011ed91811: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed91816: add    $0x8,%rsp
  0x000000011ed9181a: jmpq   0x000000011ed91824
  0x000000011ed9181f: callq  0x000000010c997002 = TemplateInterpreter::remove_activation_preserving_args_entry()
  0x000000011ed91824: jmpq   *%rax
  0x000000011ed91826: mov    0x3c8(%r15),%rdi
  0x000000011ed9182d: test   %rdi,%rdi
  0x000000011ed91830: je     0x000000011ed91871
  0x000000011ed91836: mov    0x6c(%rdi),%edi
  0x000000011ed91839: cmp    $0x1,%edi
  0x000000011ed9183c: jne    0x000000011ed91871
  0x000000011ed91842: mov    0x3c8(%r15),%rdi
  0x000000011ed91849: mov    0x70(%rdi),%edi
  0x000000011ed9184c: test   $0xf,%esp
  0x000000011ed91852: je     0x000000011ed9186a
  0x000000011ed91858: sub    $0x8,%rsp
  0x000000011ed9185c: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed91861: add    $0x8,%rsp
  0x000000011ed91865: jmpq   0x000000011ed9186f
  0x000000011ed9186a: callq  0x000000010c997012 = TemplateInterpreter::remove_activation_early_entry(TosState)
  0x000000011ed9186f: jmpq   *%rax
  0x000000011ed91871: cmpq   $0x0,0x8(%r15)
  0x000000011ed91879: je     0x000000011ed91884
  0x000000011ed9187f: jmpq   0x000000011ed61a00
  0x000000011ed91884: mov    -0x40(%rbp),%r13
  0x000000011ed91888: mov    -0x38(%rbp),%r14
  0x000000011ed9188c: retq

  // load_field_cp_cache_entry
  0x000000011ed9188d: movzwl 0x1(%r13),%edx
  0x000000011ed91892: mov    -0x30(%rbp),%rcx
  0x000000011ed91896: shl    $0x2,%edx
  0x000000011ed91899: mov    0x20(%rcx,%rdx,8),%rbx
  0x000000011ed9189e: mov    0x28(%rcx,%rdx,8),%eax
  0x000000011ed918a2: mov    0x18(%rcx,%rdx,8),%rcx
  0x000000011ed918a7: mov    0x68(%rcx),%rcx
  0x000000011ed918ab: mov    %eax,%edx

  0x000000011ed918ad: shr    $0x15,%edx
  0x000000011ed918b0: and    $0x1,%edx
  0x000000011ed918b3: shr    $0x1c,%eax

  // byte
  0x000000011ed918b6: and    $0xf,%eax
  0x000000011ed918b9: jne    0x000000011ed918ce
  0x000000011ed918bf: mov    (%rsp),%eax
  0x000000011ed918c2: add    $0x8,%rsp
  0x000000011ed918c6: mov    %al,(%rcx,%rbx,1)
  0x000000011ed918c9: jmpq   0x000000011ed91ab6

  // boolean
  0x000000011ed918ce: cmp    $0x1,%eax
  0x000000011ed918d1: jne    0x000000011ed918e9
  0x000000011ed918d7: mov    (%rsp),%eax
  0x000000011ed918da: add    $0x8,%rsp
  0x000000011ed918de: and    $0x1,%eax
  0x000000011ed918e1: mov    %al,(%rcx,%rbx,1)
  0x000000011ed918e4: jmpq   0x000000011ed91ab6

  // object
  0x000000011ed918e9: cmp    $0x8,%eax
  0x000000011ed918ec: jne    0x000000011ed91a28
  0x000000011ed918f2: pop    %rax
  0x000000011ed918f3: lea    (%rcx,%rbx,1),%rdx
  0x000000011ed918f7: cmpb   $0x0,0x340(%r15)
  0x000000011ed918ff: je     0x000000011ed9196f
  0x000000011ed91905: mov    (%rdx),%ebx
  0x000000011ed91907: shl    $0x3,%rbx
  0x000000011ed9190b: cmp    $0x0,%rbx
  0x000000011ed9190f: je     0x000000011ed9196f
  0x000000011ed91915: mov    0x350(%r15),%r8
  0x000000011ed9191c: cmp    $0x0,%r8
  0x000000011ed91920: je     0x000000011ed91940
  0x000000011ed91926: sub    $0x8,%r8
  0x000000011ed9192a: mov    %r8,0x350(%r15)
  0x000000011ed91931: add    0x348(%r15),%r8
  0x000000011ed91938: mov    %rbx,(%r8)
  0x000000011ed9193b: jmpq   0x000000011ed9196f
  0x000000011ed91940: push   %rax
  0x000000011ed91941: push   %rdx
  0x000000011ed91942: push   %rbx
  0x000000011ed91943: mov    %r15,%rsi
  0x000000011ed91946: mov    %rbx,%rdi
  0x000000011ed91949: test   $0xf,%esp
  0x000000011ed9194f: je     0x000000011ed91967
  0x000000011ed91955: sub    $0x8,%rsp
  0x000000011ed91959: callq  0x000000010cc6aa7e = SharedRuntime::g1_wb_pre(oopDesc*, JavaThread*)
  0x000000011ed9195e: add    $0x8,%rsp
  0x000000011ed91962: jmpq   0x000000011ed9196c
  0x000000011ed91967: callq  0x000000010cc6aa7e = SharedRuntime::g1_wb_pre(oopDesc*, JavaThread*)
  0x000000011ed9196c: pop    %rbx
  0x000000011ed9196d: pop    %rdx
  0x000000011ed9196e: pop    %rax
  0x000000011ed9196f: mov    %rax,%rbx
  0x000000011ed91972: shr    $0x3,%rax
  0x000000011ed91976: mov    %eax,(%rdx)
  0x000000011ed91978: mov    %rdx,%r8
  0x000000011ed9197b: xor    %rbx,%r8
  0x000000011ed9197e: shr    $0x14,%r8
  0x000000011ed91982: je     0x000000011ed91a23
  0x000000011ed91988: cmp    $0x0,%rbx
  0x000000011ed9198c: je     0x000000011ed91a23
  0x000000011ed91992: mov    %rdx,%r8
  0x000000011ed91995: shr    $0x9,%r8
  0x000000011ed91999: movabs $0x10ab16000,%rbx
  0x000000011ed919a3: add    %rbx,%r8
  0x000000011ed919a6: cmpb   $0x20,(%r8)
  0x000000011ed919aa: je     0x000000011ed91a23
  0x000000011ed919b0: lock addl $0x0,-0x40(%rsp)
  0x000000011ed919b6: cmpb   $0x0,(%r8)
  0x000000011ed919ba: je     0x000000011ed91a23
  0x000000011ed919c0: movb   $0x0,(%r8)
  0x000000011ed919c4: cmpl   $0x0,0x388(%r15)
  0x000000011ed919cf: je     0x000000011ed919f6
  0x000000011ed919d5: subl   $0x8,0x388(%r15)
  0x000000011ed919dd: mov    0x380(%r15),%rbx
  0x000000011ed919e4: movslq 0x388(%r15),%r10
  0x000000011ed919eb: add    %r10,%rbx
  0x000000011ed919ee: mov    %r8,(%rbx)
  0x000000011ed919f1: jmpq   0x000000011ed91a23
  0x000000011ed919f6: push   %rdx
  0x000000011ed919f7: push   %rbx
  0x000000011ed919f8: mov    %r15,%rsi
  0x000000011ed919fb: mov    %r8,%rdi
  0x000000011ed919fe: test   $0xf,%esp
  0x000000011ed91a04: je     0x000000011ed91a1c
  0x000000011ed91a0a: sub    $0x8,%rsp
  0x000000011ed91a0e: callq  0x000000010cc6aaa8 = SharedRuntime::g1_wb_post(void*, JavaThread*)
  0x000000011ed91a13: add    $0x8,%rsp
  0x000000011ed91a17: jmpq   0x000000011ed91a21
  0x000000011ed91a1c: callq  0x000000010cc6aaa8 = SharedRuntime::g1_wb_post(void*, JavaThread*)
  0x000000011ed91a21: pop    %rbx
  0x000000011ed91a22: pop    %rdx
  0x000000011ed91a23: jmpq   0x000000011ed91ab6

  // int
  0x000000011ed91a28: cmp    $0x4,%eax
  0x000000011ed91a2b: jne    0x000000011ed91a40
  0x000000011ed91a31: mov    (%rsp),%eax
  0x000000011ed91a34: add    $0x8,%rsp
  0x000000011ed91a38: mov    %eax,(%rcx,%rbx,1)
  0x000000011ed91a3b: jmpq   0x000000011ed91ab6

  // char 
  0x000000011ed91a40: cmp    $0x2,%eax
  0x000000011ed91a43: jne    0x000000011ed91a59
  0x000000011ed91a49: mov    (%rsp),%eax
  0x000000011ed91a4c: add    $0x8,%rsp
  0x000000011ed91a50: mov    %ax,(%rcx,%rbx,1)
  0x000000011ed91a54: jmpq   0x000000011ed91ab6

  // short 
  0x000000011ed91a59: cmp    $0x3,%eax
  0x000000011ed91a5c: jne    0x000000011ed91a72
  0x000000011ed91a62: mov    (%rsp),%eax
  0x000000011ed91a65: add    $0x8,%rsp
  0x000000011ed91a69: mov    %ax,(%rcx,%rbx,1)
  0x000000011ed91a6d: jmpq   0x000000011ed91ab6

  // long 
  0x000000011ed91a72: cmp    $0x5,%eax
  0x000000011ed91a75: jne    0x000000011ed91a8c
  0x000000011ed91a7b: mov    (%rsp),%rax
  0x000000011ed91a7f: add    $0x10,%rsp
  0x000000011ed91a83: mov    %rax,(%rcx,%rbx,1)
  0x000000011ed91a87: jmpq   0x000000011ed91ab6

  // float 
  0x000000011ed91a8c: cmp    $0x6,%eax
  0x000000011ed91a8f: jne    0x000000011ed91aa8
  0x000000011ed91a95: vmovss (%rsp),%xmm0
  0x000000011ed91a9a: add    $0x8,%rsp
  0x000000011ed91a9e: vmovss %xmm0,(%rcx,%rbx,1)
  0x000000011ed91aa3: jmpq   0x000000011ed91ab6

  // double 
  0x000000011ed91aa8: vmovsd (%rsp),%xmm0
  0x000000011ed91aad: add    $0x10,%rsp
  0x000000011ed91ab1: vmovsd %xmm0,(%rcx,%rbx,1)


  0x000000011ed91ab6: test   %edx,%edx
  0x000000011ed91ab8: je     0x000000011ed91ac4
  0x000000011ed91abe: lock addl $0x0,-0x40(%rsp)
  0x000000011ed91ac4: movzbl 0x3(%r13),%ebx
  0x000000011ed91ac9: add    $0x3,%r13
  0x000000011ed91acd: movabs $0x10cf4c950,%r10
  0x000000011ed91ad7: jmpq   *(%r10,%rbx,8)
  0x000000011ed91adb: nopl   0x0(%rax,%rax,1)

呵呵, 参照一下 getstatic, pustatic 的生成代码的代码, resolve_cache_and_index, load_field_cp_cache_entry 都是相同的

resolve_cache_and_index 的主要的作用是将解析 constantsPoolCache 中给定的字段的相关信息(所属类型, 字段索引, 字段偏移, 相关标记信息, 常量池信息)

load_field_cp_cache_entry 的主要作用是 加载字段对应的对象, 加载字段偏移 

我们这里着重关注 putstatic 的数据处理部分, 也就是吧栈顶的数据 移动到 cx 对应的对象 上面的 bx 偏移处 

另外一点就是 到数据处理这里的时候, cx 存放的是字段对应的对象, bx 存放的是字段的偏移, 这两点信息 是我们待会儿的调试的需要注意的关键点  

putstatic 基于 lldb 的调试

在 putstatic 的地方打上断点 

(lldb) p _active_table._table[9][179]
(address) $4 = 0x0000000105849aff "A\x0f?U\x01H\x8bM??\U0000008b\\???\x18\x81??
(lldb) b 0x0000000105849aff
Breakpoint 5: address = 0x0000000105849aff
(lldb) c
Process 1964 resuming
Process 1964 stopped
* thread #5, stop reason = breakpoint 5.1
    frame #0: 0x0000000105849aff
->  0x105849aff: movzwl 0x1(%r13), %edx
    0x105849b04: movq   -0x30(%rbp), %rcx
    0x105849b08: shll   $0x2, %edx
    0x105849b0b: movl   0x10(%rcx,%rdx,8), %ebx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb83e0
       rbx = 0x00000000000000b3
       rcx = 0x0000000747bb7fb0
       rdx = 0x0000000000000008
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12640
        r8 = 0x0000000000000000
        r9 = 0x0000000100340790
       r10 = 0x000000010430b270  libjvm.dylib`TemplateInterpreter::_active_table + 18432
       r11 = 0x000000010034078c
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef4b
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x0000000105849aff
    rflags = 0x0000000000000206
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) x 0x000000011e46ef4b
0x11e46ef4b: b3 03 00 b2 03 00 10 0a b5 04 00 b2 03 00 b4 04  ?..?....?..?..?.
0x11e46ef5b: 00 3c b1 ff 00 2e 32 41 3a 00 00 00 00 16 00 1b  .<??..2A:.......
(lldb) x 0x0000700001f12640 -c 0x30
0x700001f12640: e0 83 bb 47 07 00 00 00 48 26 f1 01 00 70 00 00  ?.?G....H&?..p..
0x700001f12650: 48 ef 46 1e 01 00 00 00 a8 26 f1 01 00 70 00 00  H?F.....?&?..p..
0x700001f12660: 88 f0 46 1e 01 00 00 00 00 00 00 00 00 00 00 00  .?F.............
(lldb)

打印当前的字节码相关信息, 可以定位到当前是在执行 petstatic 

b3 03 00 b2 03 00 10 0a 

// 转换为字节码信息 
putstatic     #3                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
getstatic     #2                  // Field staticInstance:Lcom/hx/test06/Test20GetSetField;
bipush        10

然后 表达式栈 栈底为 0x700001f12648

表达式栈栈顶上面有一个slot, 0x0000000747bb83e0 对应的是 Test20GetSetField.anotherStaticInstance 的地址 

然后在我们数据处理之前打上一个断点 

(lldb) b 0x105849db8
Breakpoint 6: address = 0x0000000105849db8
(lldb) c
Process 1964 resuming
Process 1964 stopped
* thread #5, stop reason = breakpoint 6.1
    frame #0: 0x0000000105849db8
->  0x105849db8: jne    0x105849dcd
    0x105849dbe: movl   (%rsp), %eax
    0x105849dc1: addq   $0x8, %rsp
    0x105849dc5: movb   %al, (%rcx,%rbx)
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000000000008
       rbx = 0x0000000000000070
       rcx = 0x0000000747bb7fb0
       rdx = 0x0000000000000000
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12640
        r8 = 0x000000011e46f0f8
        r9 = 0x0000000000000070
       r10 = 0x0000000000000000
       r11 = 0x0000000100340700
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef4b
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x0000000105849db8
    rflags = 0x0000000000000202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

可以发现此时 cx 是 0x0000000747bb7fb0 正是 Test20GetSetField.class 

然后 bx 是 0x0000000000000070 = 112(十进制), 在 Test20GetSetField.class 的 oop 上面 偏移为 112 的数据是 staticInstance 

到断点处 ax 存放的是 字段的类型(atos = 0x08)

然后我们来看一下 数据处理 

(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849dcd
->  0x105849dcd: cmpl   $0x1, %eax
    0x105849dd0: jne    0x105849de8
    0x105849dd6: movl   (%rsp), %eax
    0x105849dd9: addq   $0x8, %rsp
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849dd0
->  0x105849dd0: jne    0x105849de8
    0x105849dd6: movl   (%rsp), %eax
    0x105849dd9: addq   $0x8, %rsp
    0x105849ddd: andl   $0x1, %eax
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849de8
->  0x105849de8: cmpl   $0x8, %eax
    0x105849deb: jne    0x10584a141
    0x105849df1: popq   %rax
    0x105849df2: leaq   (%rcx,%rbx), %rdx
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849deb
->  0x105849deb: jne    0x10584a141
    0x105849df1: popq   %rax
    0x105849df2: leaq   (%rcx,%rbx), %rdx
    0x105849df6: cmpb   $0x0, 0x550(%r15)
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849df1
->  0x105849df1: popq   %rax
    0x105849df2: leaq   (%rcx,%rbx), %rdx
    0x105849df6: cmpb   $0x0, 0x550(%r15)
    0x105849dfe: je     0x105849f7b
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849df2
->  0x105849df2: leaq   (%rcx,%rbx), %rdx
    0x105849df6: cmpb   $0x0, 0x550(%r15)
    0x105849dfe: je     0x105849f7b
    0x105849e04: movl   (%rdx), %ebx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
       rax = 0x0000000747bb83e0
       rbx = 0x0000000000000070
       rcx = 0x0000000747bb7fb0
       rdx = 0x0000000000000000
       rdi = 0x0000000105000800
       rsi = 0x0000000000000008
       rbp = 0x0000700001f12690
       rsp = 0x0000700001f12648
        r8 = 0x000000011e46f0f8
        r9 = 0x0000000000000070
       r10 = 0x0000000000000000
       r11 = 0x0000000100340700
       r12 = 0x0000000000000000
       r13 = 0x000000011e46ef4b
       r14 = 0x0000700001f126a8
       r15 = 0x0000000105000800
       rip = 0x0000000105849df2
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849df6
->  0x105849df6: cmpb   $0x0, 0x550(%r15)
    0x105849dfe: je     0x105849f7b
    0x105849e04: movl   (%rdx), %ebx
    0x105849e06: pushq  %r10
Target 0: (java) stopped.
(lldb) p ((oopDesc*)0x0000000747bb7fb0)->print()
java.lang.Class 
{0x0000000747bb7fb0} - klass: 'java/lang/Class'
 - ---- fields (total size 15 words):
 - private volatile transient strict 'cachedConstructor' 'Ljava/lang/reflect/Constructor;' @12  NULL (0 0)
 - private volatile transient strict 'newInstanceCallerCache' 'Ljava/lang/Class;' @16  NULL (0 e8f77007)
 - private transient 'name' 'Ljava/lang/String;' @20  "com.hx.test06.Test20GetSetField"{0x0000000747bb8038} (e8f77007 e8fc0b37)
 - private transient 'module' 'Ljava/lang/Module;' @24  a 'java/lang/Module'{0x0000000747e059b8} (e8fc0b37 e8fc0af7)
 - private final 'classLoader' 'Ljava/lang/ClassLoader;' @28  a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8f767c3)
 - private transient 'packageName' 'Ljava/lang/String;' @32  "com.hx.test06"{0x0000000747bb3e18} (e8f767c3 0)
 - private final strict 'componentType' 'Ljava/lang/Class;' @36  NULL (0 e8f77027)
 - private volatile transient strict 'reflectionData' 'Ljava/lang/ref/SoftReference;' @40  a 'java/lang/ref/SoftReference'{0x0000000747bb8138} (e8f77027 0)
 - private volatile transient 'genericInfo' 'Lsun/reflect/generics/repository/ClassRepository;' @44  NULL (0 0)
 - private volatile transient strict 'enumConstants' '[Ljava/lang/Object;' @48  NULL (0 0)
 - private volatile transient strict 'enumConstantDirectory' 'Ljava/util/Map;' @52  NULL (0 0)
 - private volatile transient 'annotationData' 'LjavaWarning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.
/langWarning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.
/Class$AnnotationData;' @56  NULL (0 0)
 - private volatile transient 'annotationType' 'Lsun/reflect/annotation/AnnotationType;' @60  NULL (0 0)
 - transient 'classValueMap' 'Ljava/lang/CWarning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.
lassValue$ClassValueMap;' @64  NULL (0 e8f76f31)Warning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.

 - private volatile transient 'classRedefinedCount' 'I' @96  0
 - signature: Lcom/hx/test06/Test20GetSetField;
 - fake entry for mirror: 'com/hx/test06/Test20GetSetField'
 - fake entry for array: NULL
 - fake entry for oop_size: 15
 - fake entry for static_oop_field_count: 2
 - private static 'staticInstance' 'Lcom/hx/tesWarning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.
t06/TeWarning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.
st20GetSetField;' @112  a 'com/hx/test06/Test20GetSetField'{0x0000000747bb8390} (e8f77072 e8f7707c)
 - private static 'anotherStaticInstance' 'Lcom/hx/test06/Test20GetSetField;' @116  a 'com/hx/test06/Test20GetSetField'{0x0000000747bb83e0} (e8f7707c 1)
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849dfe
->  0x105849dfe: je     0x105849f7b
    0x105849e04: movl   (%rdx), %ebx
    0x105849e06: pushq  %r10
    0x105849e08: cmpq   -0x153381f(%rip), %r12    ; Universe::_narrow_ptrs_base
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849f7b
->  0x105849f7b: movq   %rax, %rbx
    0x105849f7e: pushq  %r10
    0x105849f80: cmpq   -0x1533997(%rip), %r12    ; Universe::_narrow_ptrs_base
    0x105849f87: je     0x10584a004
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849f7e
->  0x105849f7e: pushq  %r10
    0x105849f80: cmpq   -0x1533997(%rip), %r12    ; Universe::_narrow_ptrs_base
    0x105849f87: je     0x10584a004
    0x105849f8d: movq   %rsp, -0x28(%rsp)
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849f80
->  0x105849f80: cmpq   -0x1533997(%rip), %r12    ; Universe::_narrow_ptrs_base
    0x105849f87: je     0x10584a004
    0x105849f8d: movq   %rsp, -0x28(%rsp)
    0x105849f92: subq   $0x80, %rsp
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x0000000105849f87
->  0x105849f87: je     0x10584a004
    0x105849f8d: movq   %rsp, -0x28(%rsp)
    0x105849f92: subq   $0x80, %rsp
    0x105849f99: movq   %rax, 0x78(%rsp)
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a004
->  0x10584a004: popq   %r10
    0x10584a006: shrq   $0x3, %rax
    0x10584a00a: movl   %eax, (%rdx)
    0x10584a00c: movq   %rdx, %r8
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a006
->  0x10584a006: shrq   $0x3, %rax
    0x10584a00a: movl   %eax, (%rdx)
    0x10584a00c: movq   %rdx, %r8
    0x10584a00f: xorq   %rbx, %r8
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a00a
->  0x10584a00a: movl   %eax, (%rdx)
    0x10584a00c: movq   %rdx, %r8
    0x10584a00f: xorq   %rbx, %r8
    0x10584a012: shrq   $0x14, %r8
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a00c
->  0x10584a00c: movq   %rdx, %r8
    0x10584a00f: xorq   %rbx, %r8
    0x10584a012: shrq   $0x14, %r8
    0x10584a016: je     0x10584a13c
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a00f
->  0x10584a00f: xorq   %rbx, %r8
    0x10584a012: shrq   $0x14, %r8
    0x10584a016: je     0x10584a13c
    0x10584a01c: cmpq   $0x0, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a012
->  0x10584a012: shrq   $0x14, %r8
    0x10584a016: je     0x10584a13c
    0x10584a01c: cmpq   $0x0, %rbx
    0x10584a020: je     0x10584a13c
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a016
->  0x10584a016: je     0x10584a13c
    0x10584a01c: cmpq   $0x0, %rbx
    0x10584a020: je     0x10584a13c
    0x10584a026: movq   %rdx, %r8
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a13c
->  0x10584a13c: jmp    0x10584a254
    0x10584a141: cmpl   $0x4, %eax
    0x10584a144: jne    0x10584a159
    0x10584a14a: movl   (%rsp), %eax
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a254
->  0x10584a254: testl  %edx, %edx
    0x10584a256: je     0x10584a262
    0x10584a25c: lock   
    0x10584a25d: addl   $0x0, -0x40(%rsp)
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a256
->  0x10584a256: je     0x10584a262
    0x10584a25c: lock   
    0x10584a25d: addl   $0x0, -0x40(%rsp)
    0x10584a262: movzbl 0x3(%r13), %ebx
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a25c
->  0x10584a25c: lock   
    0x10584a25d: addl   $0x0, -0x40(%rsp)
    0x10584a262: movzbl 0x3(%r13), %ebx
    0x10584a267: addq   $0x3, %r13
Target 0: (java) stopped.
(lldb) stepi
Process 1964 stopped
* thread #5, stop reason = instruction step into
    frame #0: 0x000000010584a262
->  0x10584a262: movzbl 0x3(%r13), %ebx
    0x10584a267: addq   $0x3, %r13
    0x10584a26b: movabsq $0x10430b270, %r10        ; imm = 0x10430B270 
    0x10584a275: jmpq   *(%r10,%rbx,8)
Target 0: (java) stopped.
(lldb) p ((oopDesc*)0x0000000747bb7fb0)->print()
java.lang.Class 
{0x0000000747bb7fb0} - klass: 'java/lang/Class'
 - ---- fields (total size 15 words):
 - private volatile transient strict 'cachedConstructor' 'Ljava/lang/reflect/Constructor;' @12  NULL (0 0)
 - private volatile transient strict 'newInstanceCallerCache' 'Ljava/lang/Class;' @16  NULL (0 e8f77007)
 - private transient 'name' 'Ljava/lang/String;' @20  "com.hx.test06.Test20GetSetField"{0x0000000747bb8038} (e8f77007 e8fc0b37)
 - private transient 'module' 'Ljava/lang/Module;' @24  a 'java/lang/Module'{0x0000000747e059b8} (e8fc0b37 e8fc0af7)
 - private final 'classLoader' 'Ljava/lang/ClassLoader;' @28  a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8f767c3)
 - private transient 'packageName' 'Ljava/lang/String;' @32  "com.hx.test06"{0x0000000747bb3e18} (e8f767c3 0)
 - private final strict 'componentType' 'Ljava/lang/Class;' @36  NULL (0 e8f77027)
 - private volatile transient strict 'reflectionData' 'Ljava/lang/ref/SoftReference;' @40  a 'java/lang/ref/SoftReference'{0x0000000747bb8138} (e8f77027 0)
 - private volatile transient 'genericInfo' 'Lsun/reflect/generics/repository/ClassRepository;' @44  NULL (0 0)
 - private volatile transient strict 'enumConstants' '[Ljava/lang/Object;' @48  NULL (0 0)
 - private volatile transient strict 'enumConstantDirectory' 'Ljava/util/Map;' @52  NULL (0 0)
 - private volatile transient 'annotationData' 'Ljava/lang/Class$AnnotationData;' @56  NULL (0 0)
 - private volatile transient 'annotationType' 'Lsun/reflect/annotation/AnnotationType;' @60  NULL (0 0)
 - transient 'classValueMap' 'Ljava/lang/ClassValue$ClassValueMap;' @64  NULL (0 e8f76f31)
 - private volatile transient 'classRedefinedCount' 'I' @96  0
 - signature: Lcom/hx/test06/Test20GetSetField;
 - fake entry for mirror: 'com/hx/test06/Test20GetSetField'
 - fake entry for array: NULL
 - fake entry for oop_size: 15
 - fake entry for static_oop_field_count: 2
 - private static 'staticInstance' 'Lcom/hx/test06/Test20GetSetField;' @112  a 'com/hx/test06/Test20GetSetField'{0x0000000747bb83e0} (e8f7707c e8f7707c)
 - private static 'anotherStaticInstance' 'Lcom/hx/test06/Test20GetSetField;' @116  a 'com/hx/test06/Test20GetSetField'{0x0000000747bb83e0} (e8f7707c 1)
(lldb)

呵呵 这里的运行时的代码 和 PrintInterpreter 打出来了的似乎是又有一些不同, 不过 实现的效果都是一致 的 


0x10584a00a 的地方吧 Test20GetSetField.anotherStaticInstance 引用的对象的地址, 放到了 Test20GetSetField.staticInstance 引用上面, 这下 Test20GetSetField.anotherStaticInstance 和 Test20GetSetField.staticInstance 引用的是同一个对象了


getfield & putfield

void TemplateTable::getfield(int byte_no) {
  getfield_or_static(byte_no, false);
}

void TemplateTable::putfield(int byte_no) {
  putfield_or_static(byte_no, false);
}

呵呵 同上面使用的同一套代码, 只是存在 细微的不同, 这里就不多 赘述了 

resolve_cache_and_index

我们最后 来看一下 解析 constantsPoolCache 中给定的字段的相关信息(所属类型, 字段索引, 字段偏移, 相关标记信息, 常量池信息) 

main 线程的第一个 getstatic 如下 

32 get/put + field/static 的调试_bc

遍历 Test20GetSetField 的所有的字段查询字段  anotherStaticInstance

32 get/put + field/static 的调试_java_02

解析 constantsPoolCache 中给定的字段的相关信息(所属类型, 字段索引, 字段偏移, 相关标记信息, 常量池信息) 

32 get/put + field/static 的调试_ide_03

完 

参考

 [讨论] 有关实例化的内存分布 

举报

相关推荐

0 条评论