对象创建

对象创建

interpreterRuntime.cpp 解释器中new指令的入口:

// 宏展开
 // IRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* thread, ConstantPool* pool, int index))
void  InterpreterRuntime::_new(JavaThread* thread, ConstantPool* pool, int index) {                                               
    ThreadInVMfromJava __tiv(thread);                                
                                        
  HandleMarkCleaner __hm(thread);                                    
  Thread* __the_thread__ = thread;                                           
  os::verify_stack_alignment();                       
  
  // 宏展开
  // Klass* k_oop = pool->klass_at(index, CHECK);
   Klass* k_oop = pool->klass_at(index, __the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception())) return       ; (void)(0);
  
  instanceKlassHandle klass (THREAD, k_oop);

  // Make sure we are not instantiating an abstract klass
  klass->check_valid_for_instantiation(true, CHECK);

  // Make sure klass is initialized
  klass->initialize(CHECK);

  // At this point the class may not be fully initialized
  // because of recursive initialization. If it is fully
  // initialized & has_finalized is not set, we rewrite
  // it into its fast version (Note: no locking is needed
  // here since this is an atomic byte write and can be
  // done more than once).
  //
  // Note: In case of classes with has_finalized we don't
  //       rewrite since that saves us an extra check in
  //       the fast version which then would call the
  //       slow version anyway (and do a call back into
  //       Java).
  //       If we have a breakpoint, then we don't rewrite
  //       because the _breakpoint bytecode would be lost.
  oop obj = klass->allocate_instance(CHECK); // SimonNote: 解释器创建对象实力入口
  thread->set_vm_result(obj);
  
  //======再往上找谁调进来的,调用栈已经不好观察了,直接贴代码。这个好像不对,再分析
  // bytecodeInterpreter.cpp 
  CASE(_new): {
  // ......
  CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index),
                handle_exception);
  
  }
  
   

关于对象直接转unsigned char指针的写法,在codeBlob.hpp中有很多这种写法,最简单的示例如下:

typedef unsigned char u_char;
typedef u_char*       address;

void CodeBlob::printSize(){
  std::cout << _size << std::endl;
  address aa = (address)this; // 这样写是没语法错误的,转换后aa的内存地址和this一样的。
  std::cout << aa << std::endl;
}

至于怎么调到InterpreterRuntime::_new这个方法的,是从汇编指令直接跳过来的,具体的可以看《虚拟机解释器与bytecode对接》一文。

怎么调试new指令new你自己的类

要调试这个new指令怎么new你自己的类(你做实验的类),怎么做?
因为JVM在执行一个main方法时,前面会new200+个类,要调到你自己的类,得有个办法才行,不然F8一路按下去要按好久。
我的办法是:
在 InterpreterRuntime::_new加上 k_oop->name()->print();

IRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* thread, ConstantPool* pool, int index))
  Klass* k_oop = pool->klass_at(index, CHECK); 
k_oop->name()->print();instanceKlassHandle klass (THREAD, k_oop);
// 这样能把每次new的class名给打出来

这样就能发现我自己的类大概是在new指令被调用了261次后才被new,于是对此处断点加上ignore count为261,这样便能调试到new我自己的测试类了。

new指令为对象分配空间

此处我的测试类是Group

public class Group {

	
	private int id;
	
	private long t1;
	
	private long t2;
	
	private long t3;
	
	private String name;
	
	public Group(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Group [id=" + id + ", name=" + name + "]";
	}
}

计算对象大小:

instanceOop InstanceKlass::allocate_instance(TRAPS) {
  bool has_finalizer_flag = has_finalizer(); // Query before possible GC
  int size = size_helper();  // Query before forming handle.

  KlassHandle h_k(THREAD, this);

  instanceOop i;

  i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
  if (has_finalizer_flag && !RegisterFinalizersAtInit) {
    i = register_finalizer(i, CHECK_NULL);
  }
  return i;
}

此处size为6,我理解此处的单位是heapword即byte。
分配空间的栈:

Copy::pd_fill_to_words() at copy_x86.hpp:49 0x7ffff61faf7c	
Copy::fill_to_words() at copy.hpp:236 0x7ffff61fae72	
ThreadLocalAllocBuffer::allocate() at threadLocalAllocBuffer.inline.hpp:44 0x7ffff61fb04e	
CollectedHeap::allocate_from_tlab() at collectedHeap.inline.hpp:181 0x7ffff61fb97a	
CollectedHeap::common_mem_allocate_noinit() at collectedHeap.inline.hpp:124 0x7ffff61fb6d9	
CollectedHeap::common_mem_allocate_init() at collectedHeap.inline.hpp:173 0x7ffff61fb8e2	
CollectedHeap::obj_allocate() at collectedHeap.inline.hpp:201 0x7ffff660a876	
InstanceKlass::allocate_instance() at instanceKlass.cpp:1,104 0x7ffff65f36fd	
InterpreterRuntime::_new() at interpreterRuntime.cpp:172 0x7ffff6652fb8	

分配空间的代码:

// threadLocalAllocBuffer.inline.hpp
inline HeapWord* ThreadLocalAllocBuffer::allocate(size_t size) {
  invariants();
  HeapWord* obj = top();
  if (pointer_delta(end(), obj) >= size) {
    // successful thread-local allocation
#ifdef ASSERT
    // Skip mangling the space corresponding to the object header to
    // ensure that the returned space is not considered parsable by
    // any concurrent GC thread.
    size_t hdr_size = oopDesc::header_size();
    Copy::fill_to_words(obj + hdr_size, size - hdr_size, badHeapWordVal);
#endif // ASSERT
    // This addition is safe because we know that top is
    // at least size below end, so the add can't wrap.
    set_top(obj + size);

    invariants();
    return obj;
  }
  return NULL;
}


// copy_x86.hpp
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
#ifdef AMD64
  julong* to = (julong*) tohw;
  julong  v  = ((julong) value << 32) | value;
  while (count-- > 0) {
    *to++ = v;
  }
#else
  juint* to = (juint*)tohw;
  count *= HeapWordSize / BytesPerInt;
  while (count-- > 0) {
    *to++ = value;
  }
#endif // AMD64
}

编译hsdis

cd /home/appweb/600.self/03.code/01.cpp/01.jdk8-b120/hotspot-jdk8-b120/hotspot/src/share/tools/hsdis
wget ftp://sourceware.org/pub/binutils/snapshots/binutils-2.20.51.tar.bz2
tar -xjvf binutils-2.20.51.tar.bz2
export BINUTILS=binutils-2.20.51
gedit binutils-2.20.51/binutils/configure  # 修改一下  注释掉下面的代码
#if test "${ERROR_ON_WARNING}" = yes ; then
#    GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
#    NO_WERROR="-Wno-error"
#fi

gedit binutils-2.20.51/bfd//configure  # 修改一下  注释掉上面的代码
make all64
# 编译成功后 copy so文件到对应目录
 cp build/linux-amd64/hsdis-amd64.so ~/600.self/03.code/01.cpp/01.jdk8-b120/hotspot-jdk8-b120/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/

编译好后,放到正确的路径下,就可以用-XX:+PrintInterpreter打印出汇编代码了。

解释器

运行时对代码操纵的一个小demo

new一个对象的汇编代码翻译

public class ObjectCreateTest1 {
									
	public static void main(String[] args) {
		Group g = new  Group(1, "g-1");
	}

}

字节码翻译时,内存地址查看

MacroAssembler	MacroAssembler	{...}	
	Assembler	Assembler	{...}	
		AbstractAssembler	AbstractAssembler	{...}	
			ResourceObj	ResourceObj	{...}	
			_code_section	CodeSection *	0x7ffff7fdd5e0	
				_start	address	0x7fffe10449e0 "Pé*"	

附:new指令的翻译:

;_new
;start:0x7fffe10449e0
;end:0x7fffe1044e00

00007fffe10449e0:   push    %rax
00007fffe10449e1:   jmpq    0x7fffe1044a10
00007fffe10449e6:   sub     $0x8,%rsp
00007fffe10449ea:   vmovss  %xmm0,(%rsp)
00007fffe10449ef:   jmpq    0x7fffe1044a10
00007fffe10449f4:   sub     $0x10,%rsp
00007fffe10449f8:   vmovsd  %xmm0,(%rsp)
00007fffe10449fd:   jmpq    0x7fffe1044a10
00007fffe1044a02:   sub     $0x10,%rsp
00007fffe1044a06:   mov     %rax,(%rsp)
00007fffe1044a0a:   jmpq    0x7fffe1044a10
00007fffe1044a0f:   push    %rax   
; 下面开始进入TemplateTable::_new
00007fffe1044a10:   movzwl  0x1(%r13),%edx
00007fffe1044a15:   bswap   %edx
00007fffe1044a17:   shr     $0x10,%edx
; _masm->get_unsigned_2_byte_index_at_bcp(rdx, 1); 翻译出来的指令到上一行结束
00007fffe1044a1a:   mov     -0x18(%rbp),%rsi
00007fffe1044a1e:   mov     0x10(%rsi),%rsi
00007fffe1044a22:   mov     0x8(%rsi),%rsi
00007fffe1044a26:   mov     0x10(%rsi),%rax
; _masm->get_cpool_and_tags(rsi, rax); 翻译出来的指令到上一行结束
00007fffe1044a2a:   cmpb    $0x7,0x4(%rax,%rdx,1)
; const int tags_offset = Array<u1>::base_offset_in_bytes(); 
; _masm->cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class);
; 翻译出来的指令到上一行结束
00007fffe1044a2f:   jne     0x7fffe1044b92
; _masm->jcc(Assembler::notEqual, slow_case); 
00007fffe1044a35:   mov     0x58(%rsi,%rdx,8),%rsi
;// get InstanceKlass
;	  _masm->movptr(rsi, Address(rsi, rdx, Address::times_8, sizeof(ConstantPool)));
00007fffe1044a3a:   cmpb    $0x4,0x16a(%rsi)
;// make sure klass is initialized & doesn't have finalizer
;	  // make sure klass is fully initialized
;	  _masm->cmpb(Address(rsi, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
00007fffe1044a41:   jne     0x7fffe1044b92
; _masm->jcc(Assembler::notEqual, slow_case)
00007fffe1044a47:   mov     0xc(%rsi),%edx
; // get instance_size in InstanceKlass (scaled to a count of bytes)
;	  _masm->movl(rdx, Address(rsi, Klass::layout_helper_offset()));
00007fffe1044a4a:   test    $0x1,%edx
; // test to see if it has a finalizer or is malformed in some way
;	  _masm->testl(rdx, Klass::_lh_instance_slow_path_bit);
00007fffe1044a50:   jne     0x7fffe1044b92
; _masm->jcc(Assembler::notZero, slow_case);
00007fffe1044a56:   mov     0x70(%r15),%rax
; _masm->movptr(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())));
	    
	    
00007fffe1044a5a:   lea     (%rax,%rdx,1),%rbx
;_masm->lea(rbx, Address(rax, rdx, Address::times_1));
	    
00007fffe1044a5e:   cmp     0x80(%r15),%rbx
;_masm->cmpptr(rbx, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset())));
	    
00007fffe1044a65:   ja      0x7fffe1044a74
;_masm->jcc(Assembler::above, allow_shared_alloc ? allocate_shared : slow_case);
	    
00007fffe1044a6b:   mov     %rbx,0x70(%r15)
;_masm->movptr(Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())), rbx);

00007fffe1044a6f:   jmpq    0x7fffe1044aa6
; _masm->jmp(initialize_object);
00007fffe1044a74:   movabs  $0x7ffff0025338,%r10
; _masm->bind(allocate_shared);

;	    ExternalAddress top((address)Universe::heap()->top_addr());
;	    ExternalAddress end((address)Universe::heap()->end_addr());

;	    const Register RtopAddr = rscratch1;
;	    const Register RendAddr = rscratch2;

;	    _masm->lea(RtopAddr, top);
00007fffe1044a7e:   movabs  $0x7ffff00252e8,%r11
;  _masm->lea(RendAddr, end);
00007fffe1044a88:   mov     (%r10),%rax
; _masm->movptr(rax, Address(RtopAddr, 0));
00007fffe1044a8b:   lea     (%rax,%rdx,1),%rbx
;// For retries rax gets set by cmpxchgq
;	    Label retry;
;	    _masm->bind(retry);
;	    _masm->lea(rbx, Address(rax, rdx, Address::times_1));
00007fffe1044a8f:   cmp     (%r11),%rbx
; _masm->cmpptr(rbx, Address(RendAddr, 0));
00007fffe1044a92:   ja      0x7fffe1044b92
; _masm->jcc(Assembler::above, slow_case);
00007fffe1044a98:   lock    cmpxchg %rbx,(%r10)
; _masm->lock();
; _masm->cmpxchgptr(rbx, Address(RtopAddr, 0));
00007fffe1044a9d:   jne     0x7fffe1044a8b
; _masm->jcc(Assembler::notEqual, retry);
00007fffe1044a9f:   add     %rdx,0xd0(%r15)
; _masm->incr_allocated_bytes(r15_thread, rdx, 0);
00007fffe1044aa6:   sub     $0x10,%edx
; // The object is initialized before the header.  If the object size is
;	    // zero, go directly to the header initialization.
;	    _masm->bind(initialize_object);
;	    _masm->decrementl(rdx, sizeof(oopDesc));
00007fffe1044aa9:   je      0x7fffe1044abd
; _masm->jcc(Assembler::zero, initialize_header);
00007fffe1044aaf:   xor     %ecx,%ecx
00007fffe1044ab1:   shr     $0x3,%edx
00007fffe1044ab4:   mov     %rcx,0x8(%rax,%rdx,8)
00007fffe1044ab9:   dec     %edx// Initialize object fields
00007fffe1044abb:   jne     0x7fffe1044ab4
;	    _masm->xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
;	    _masm->shrl(rdx, LogBytesPerLong);  // divide by oopSize to simplify the loop
;	    {
; _masm->bind(loop);
;	      _masm->movq(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - oopSize), rcx);
;	      _masm->decrementl(rdx);
00007fffe1044abd:   mov     0xb0(%rsi),%r10
00007fffe1044ac4:   mov     %r10,(%rax)
; _masm->movptr(rscratch1, Address(rsi, Klass::prototype_header_offset()));
;	      _masm->movptr(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1);
00007fffe1044ac7:   xor     %ecx,%ecx
00007fffe1044ac9:   mov     %ecx,0xc(%rax)
00007fffe1044acc:   shr     $0x3,%rsi
00007fffe1044ad0:   mov     %esi,0x8(%rax)
; _masm->xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
;	    _masm->store_klass_gap(rax, rcx);  // zero klass gap for compressed oops
;	    _masm->store_klass(rax, rsi);      // store klass last
00007fffe1044ad3:   cmpb    $0x0,0x16317681(%rip)        # 0x7ffff735c15b <DTraceAllocProbes>
00007fffe1044ada:   je      0x7fffe1044b8d
; SkipIfEqual skip(_masm, &DTraceAllocProbes, false);
00007fffe1044ae0:   push    %rax
; _masm->push(atos); // save the return value
00007fffe1044ae1:   mov     %rax,%rdi
00007fffe1044ae4:   cmpq    $0x0,-0x10(%rbp)
00007fffe1044aec:   je      0x7fffe1044b69
00007fffe1044af2:   mov     %rsp,-0x28(%rsp)
00007fffe1044af7:   sub     $0x80,%rsp
00007fffe1044afe:   mov     %rax,0x78(%rsp)
00007fffe1044b03:   mov     %rcx,0x70(%rsp)
00007fffe1044b08:   mov     %rdx,0x68(%rsp)
00007fffe1044b0d:   mov     %rbx,0x60(%rsp)
00007fffe1044b12:   mov     %rbp,0x50(%rsp)
00007fffe1044b17:   mov     %rsi,0x48(%rsp)
00007fffe1044b1c:   mov     %rdi,0x40(%rsp)
00007fffe1044b21:   mov     %r8,0x38(%rsp)
00007fffe1044b26:   mov     %r9,0x30(%rsp)
00007fffe1044b2b:   mov     %r10,0x28(%rsp)
00007fffe1044b30:   mov     %r11,0x20(%rsp)
00007fffe1044b35:   mov     %r12,0x18(%rsp)
00007fffe1044b3a:   mov     %r13,0x10(%rsp)
00007fffe1044b3f:   mov     %r14,0x8(%rsp)
00007fffe1044b44:   mov     %r15,(%rsp)
00007fffe1044b48:   movabs  $0x7ffff6c8ceb8,%rdi
00007fffe1044b52:   movabs  $0x7fffe1044af2,%rsi
00007fffe1044b5c:   mov     %rsp,%rdx
00007fffe1044b5f:   and     $0xfffffffffffffff0,%rsp
00007fffe1044b63:   callq   0x7ffff68024fa <MacroAssembler::debug64(char*, long, long*)>
00007fffe1044b68:   hlt     
00007fffe1044b69:   test    $0xf,%esp
00007fffe1044b6f:   je      0x7fffe1044b87
00007fffe1044b75:   sub     $0x8,%rsp
00007fffe1044b79:   callq   0x7ffff699de5c <SharedRuntime::dtrace_object_alloc(oopDesc*)>
00007fffe1044b7e:   add     $0x8,%rsp
00007fffe1044b82:   jmpq    0x7fffe1044b8c
00007fffe1044b87:   callq   0x7ffff699de5c <SharedRuntime::dtrace_object_alloc(oopDesc*)>
; _masm->call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), rax); // 这一句翻译出了很多句指令
00007fffe1044b8c:   pop     %rax
; _masm->pop(atos); // restore the return value
00007fffe1044b8d:   jmpq    0x7fffe1044e00
; _masm->jmp(done);
00007fffe1044b92:   mov     -0x18(%rbp),%rsi
00007fffe1044b96:   mov     0x10(%rsi),%rsi
00007fffe1044b9a:   mov     0x8(%rsi),%rsi
; _masm->get_constant_pool(c_rarg1);
00007fffe1044b9e:   movzwl  0x1(%r13),%edx
00007fffe1044ba3:   bswap   %edx
00007fffe1044ba5:   shr     $0x10,%edx
; _masm->get_unsigned_2_byte_index_at_bcp(c_rarg2, 1);
00007fffe1044ba8:   callq   0x7fffe1044bb2
00007fffe1044bad:   jmpq    0x7fffe1044e00
00007fffe1044bb2:   lea     0x8(%rsp),%rax
00007fffe1044bb7:   mov     %r13,-0x38(%rbp)
00007fffe1044bbb:   cmpq    $0x0,-0x10(%rbp)
00007fffe1044bc3:   je      0x7fffe1044c40
00007fffe1044bc9:   mov     %rsp,-0x28(%rsp)
00007fffe1044bce:   sub     $0x80,%rsp
00007fffe1044bd5:   mov     %rax,0x78(%rsp)
00007fffe1044bda:   mov     %rcx,0x70(%rsp)
00007fffe1044bdf:   mov     %rdx,0x68(%rsp)
00007fffe1044be4:   mov     %rbx,0x60(%rsp)
00007fffe1044be9:   mov     %rbp,0x50(%rsp)
00007fffe1044bee:   mov     %rsi,0x48(%rsp)
00007fffe1044bf3:   mov     %rdi,0x40(%rsp)
00007fffe1044bf8:   mov     %r8,0x38(%rsp)
00007fffe1044bfd:   mov     %r9,0x30(%rsp)
00007fffe1044c02:   mov     %r10,0x28(%rsp)
00007fffe1044c07:   mov     %r11,0x20(%rsp)
00007fffe1044c0c:   mov     %r12,0x18(%rsp)
00007fffe1044c11:   mov     %r13,0x10(%rsp)
00007fffe1044c16:   mov     %r14,0x8(%rsp)
00007fffe1044c1b:   mov     %r15,(%rsp)
00007fffe1044c1f:   movabs  $0x7ffff6c8ceb8,%rdi
00007fffe1044c29:   movabs  $0x7fffe1044bc9,%rsi
00007fffe1044c33:   mov     %rsp,%rdx
00007fffe1044c36:   and     $0xfffffffffffffff0,%rsp
00007fffe1044c3a:   callq   0x7ffff68024fa <MacroAssembler::debug64(char*, long, long*)>
00007fffe1044c3f:   hlt     
00007fffe1044c40:   push    %r10
00007fffe1044c42:   cmp     0x16346f27(%rip),%r12        # 0x7ffff738bb70 <_ZN8Universe17_narrow_ptrs_baseE>
00007fffe1044c49:   je      0x7fffe1044cc6
00007fffe1044c4f:   mov     %rsp,-0x28(%rsp)
00007fffe1044c54:   sub     $0x80,%rsp
00007fffe1044c5b:   mov     %rax,0x78(%rsp)
00007fffe1044c60:   mov     %rcx,0x70(%rsp)
00007fffe1044c65:   mov     %rdx,0x68(%rsp)
00007fffe1044c6a:   mov     %rbx,0x60(%rsp)
00007fffe1044c6f:   mov     %rbp,0x50(%rsp)
00007fffe1044c74:   mov     %rsi,0x48(%rsp)
00007fffe1044c79:   mov     %rdi,0x40(%rsp)
00007fffe1044c7e:   mov     %r8,0x38(%rsp)
00007fffe1044c83:   mov     %r9,0x30(%rsp)
00007fffe1044c88:   mov     %r10,0x28(%rsp)
00007fffe1044c8d:   mov     %r11,0x20(%rsp)
00007fffe1044c92:   mov     %r12,0x18(%rsp)
00007fffe1044c97:   mov     %r13,0x10(%rsp)
00007fffe1044c9c:   mov     %r14,0x8(%rsp)
00007fffe1044ca1:   mov     %r15,(%rsp)
00007fffe1044ca5:   movabs  $0x7ffff6cf9a40,%rdi
00007fffe1044caf:   movabs  $0x7fffe1044c4f,%rsi
00007fffe1044cb9:   mov     %rsp,%rdx
00007fffe1044cbc:   and     $0xfffffffffffffff0,%rsp
00007fffe1044cc0:   callq   0x7ffff68024fa <MacroAssembler::debug64(char*, long, long*)>
00007fffe1044cc5:   hlt     
00007fffe1044cc6:   pop     %r10
00007fffe1044cc8:   mov     %r15,%rdi
00007fffe1044ccb:   mov     %rbp,0x200(%r15)
00007fffe1044cd2:   mov     %rax,0x1f0(%r15)
00007fffe1044cd9:   test    $0xf,%esp
00007fffe1044cdf:   je      0x7fffe1044cf7
00007fffe1044ce5:   sub     $0x8,%rsp
00007fffe1044ce9:   callq   0x7ffff6652d9a <InterpreterRuntime::_new(JavaThread*, ConstantPool*, int)>
00007fffe1044cee:   add     $0x8,%rsp
00007fffe1044cf2:   jmpq    0x7fffe1044cfc
00007fffe1044cf7:   callq   0x7ffff6652d9a <InterpreterRuntime::_new(JavaThread*, ConstantPool*, int)>
00007fffe1044cfc:   push    %rax
00007fffe1044cfd:   push    %rdi
00007fffe1044cfe:   push    %rsi
00007fffe1044cff:   push    %rdx
00007fffe1044d00:   push    %rcx
00007fffe1044d01:   push    %r8
00007fffe1044d03:   push    %r9
00007fffe1044d05:   push    %r10
00007fffe1044d07:   mov     %rsp,%r10
00007fffe1044d0a:   and     $0xfffffffffffffff0,%rsp
00007fffe1044d0e:   push    %r10
00007fffe1044d10:   push    %r11
00007fffe1044d12:   mov     $0x1,%edi
00007fffe1044d17:   callq   0x7ffff73b3030 <__GI___pthread_getspecific>
00007fffe1044d1c:   pop     %r11
00007fffe1044d1e:   pop     %rsp
00007fffe1044d1f:   pop     %r10
00007fffe1044d21:   pop     %r9
00007fffe1044d23:   pop     %r8
00007fffe1044d25:   pop     %rcx
00007fffe1044d26:   pop     %rdx
00007fffe1044d27:   pop     %rsi
00007fffe1044d28:   pop     %rdi
00007fffe1044d29:   cmp     %rax,%r15
00007fffe1044d2c:   je      0x7fffe1044da9
00007fffe1044d32:   mov     %rsp,-0x28(%rsp)
00007fffe1044d37:   sub     $0x80,%rsp
00007fffe1044d3e:   mov     %rax,0x78(%rsp)
00007fffe1044d43:   mov     %rcx,0x70(%rsp)
00007fffe1044d48:   mov     %rdx,0x68(%rsp)
00007fffe1044d4d:   mov     %rbx,0x60(%rsp)
00007fffe1044d52:   mov     %rbp,0x50(%rsp)
00007fffe1044d57:   mov     %rsi,0x48(%rsp)
00007fffe1044d5c:   mov     %rdi,0x40(%rsp)
00007fffe1044d61:   mov     %r8,0x38(%rsp)
00007fffe1044d66:   mov     %r9,0x30(%rsp)
00007fffe1044d6b:   mov     %r10,0x28(%rsp)
00007fffe1044d70:   mov     %r11,0x20(%rsp)
00007fffe1044d75:   mov     %r12,0x18(%rsp)
00007fffe1044d7a:   mov     %r13,0x10(%rsp)
00007fffe1044d7f:   mov     %r14,0x8(%rsp)
00007fffe1044d84:   mov     %r15,(%rsp)
00007fffe1044d88:   movabs  $0x7ffff6cf9bb8,%rdi
00007fffe1044d92:   movabs  $0x7fffe1044d32,%rsi
00007fffe1044d9c:   mov     %rsp,%rdx
00007fffe1044d9f:   and     $0xfffffffffffffff0,%rsp
00007fffe1044da3:   callq   0x7ffff68024fa <MacroAssembler::debug64(char*, long, long*)>
00007fffe1044da8:   hlt     
00007fffe1044da9:   pop     %rax
00007fffe1044daa:   movabs  $0x0,%r10
00007fffe1044db4:   mov     %r10,0x1f0(%r15)
00007fffe1044dbb:   movabs  $0x0,%r10
00007fffe1044dc5:   mov     %r10,0x200(%r15)
00007fffe1044dcc:   cmpq    $0x0,0x8(%r15)
00007fffe1044dd4:   je      0x7fffe1044ddf
00007fffe1044dda:   jmpq    0x7fffe1000420
00007fffe1044ddf:   mov     0x250(%r15),%rax
00007fffe1044de6:   movabs  $0x0,%r10
00007fffe1044df0:   mov     %r10,0x250(%r15)
00007fffe1044df7:   mov     -0x38(%rbp),%r13
00007fffe1044dfb:   mov     -0x30(%rbp),%r14
;  call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), c_rarg1, c_rarg2);
00007fffe1044dff:   retq    
00007fffe1044e00:   int3

arraylength字节码翻译成汇编指令:

;start:0x7fffe10453a0
;end:0x7fffe10453a4

00007fffe10453a0:   pop     %rax
00007fffe10453a1:   mov     0xc(%rax),%eax
00007fffe10453a4:   int3

原文地址:https://www.cnblogs.com/simoncook/p/11194057.html