interpreterRuntime.cpp 解釋器中new指令的入口:java
// 宏展開 // 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中有不少這種寫法,最簡單的示例以下:linux
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對接》一文。web
要調試這個new指令怎麼new你本身的類(你作實驗的類),怎麼作?
由於JVM在執行一個main方法時,前面會new200+個類,要調到你本身的類,得有個辦法才行,否則F8一路按下去要按很久。
個人辦法是:
在 InterpreterRuntime::_new加上 k_oop->name()->print();shell
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我本身的測試類了。app
此處個人測試類是Groupide
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 + "]"; } }
計算對象大小:oop
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
分配空間的代碼:ui
// 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 }
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打印出彙編代碼了。this
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 ;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