对象创建

对象创建

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

时间: 2024-11-05 02:34:13

对象创建的相关文章

【代码优化】私有构造器使用及对象创建优化

1.使用私有构造器或者枚举类型强化singleton 1>单例模式---私有构造器,提供一个公有的成员是一个静态工厂方法: public class SingleTon{ private static final  SingleTon single=new SingleTon(): private SingleTon(){ } public static SingleTon getInstance() { return single: } } 工厂方法的优势一在于它提供了灵活性:在不改变其他ap

java对象创建与内存模型总结

 1.JVM管辖的内存大致分为三个逻辑部分:java栈(Heap).java堆(JavaStack)和方法区(MethodArea).在JVM启动时创建,关闭时全部回收.  栈.本地方法栈.程序计数器:以线程为粒度,每个线程拥有自己的部分.而堆和方法区被所有线程共享.  堆:运行时的数据区域,程序(线程)运行时动态分配.  方法区:静态存储区,存储被装载到JVM中的class信息. 2.栈 i).存放基本类型的变量数据和对象的引用变量(变量本身存放在堆和常量池中). ii).java系统必须知道

【Java基础】Java类的加载和对象创建流程的详细分析

相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下. 实例问题 实例代码 Parent类 1 package mytest.javaBase; 2 3 public class Parent { 4 int a = 10; 5 static int b = 11; 6 // 静态代码块 7 static { 8 System.out.println("Parent静态代码块:b=" + b)

动态对象创建(二)重载new和delete

前言 上文我简单介绍了一下动态对象创建的方法,这一篇文章的内容主要是对重载new和delete做一些讲解,也希望能够得到博友们的指点,在这里谢过大家. 通常我们为了一些目的而使用new和delete的内存分配系统,但是在特殊情况下,它并不能够满足需要.最常见的改变分配系统的原因是出于效率考虑:也许要创建和销毁一个特定的类的非常多的对象以至于这个运算变成了速度的瓶颈.C++允许重载new和delete来实现我们自己的存储分配方案,所以可以用它来处理问题. 另一个问题就是堆碎片:分配不同大小的内存可

Objective-C设计模式——工厂方法模式virtual constructor(对象创建)

工厂方法模式 工厂方法模式可以控制对象的创建过程,屏蔽对象创建的细节,可以直接创建出我们所需要的已经配置好的对象. 工厂方法模式定义了创建方法的接口,让子类决定实例化哪一个类,工厂方法模式使得一个类的实例化延迟到其子类. 工厂方法的工厂其实是多太的一个经典应用,而其生产的产品取决于使用什么工厂,符合面向对象设计的开放封闭原则,添加产品只需要添加新的类,而不需要修改原有的代码. 使用场景 1.编译时无法准确预期要创建的对象的类: 2.类想让其子类决定在运行时创见什么: 3.类有若干辅助类为其子类,

应用程序各对象创建的顺序

应用程序对象时全局对象,它在启动之前由系统创建.应用程序启动之后,程序的主函数首先调用应用程序对象的初始化函数InitInstace(),并在该函数中创建文档模板对象 CSingleDocTemplate *pDocTemplate;//声明文档模板指针(单文档)     pDocTemplate = new CSingleDocTemplate(//创建文档模板对象         IDR_MAINFRAME,//文档模板使用的资源ID         RUNTIME_CLASS(CNOTED

Gradle 庖丁解牛(构建生命周期核心托付对象创建源代码浅析)

[工匠若水 http://blog.csdn.net/yanbober 未经同意严禁转载,请尊重作者劳动成果.私信联系我] 1 背景 上一篇<Gradle 庖丁解牛(构建源头源代码浅析)>我们分析了 Gradle 框架自身初始化(非构建生命周期初始化)的核心流程,这一篇我们续着前面的分析继续(假设没看过前一篇的建议先去看前一篇,由于这一系列存在非常高的关联性).上一篇说到当我们运行 gradle taskName 命令后经过一系列艰难的框架初始化终于走到了 DefaultGradleLaunc

C++设计模式 之 “对象创建”模式:Factory Method

part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Factory Method Abstract Factory Prototype Builder Part 1 Factory Method 工厂方法 动机(Motivation) 在软件系统中,经常面临着创建对象的工作:由于需求的变化,需要创建的对象的具体类型经常变化. 如何应对这种变化?如何绕过常规的

深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式

内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的时候,首先会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否被加载.解析并初始化.如果没有完成这个过程,则必须执行相应类的加载. (二)在堆上为对象分配空间.对象需要的空间大小在类加载完成后便能确定.之后便是在堆上为该对象分配固定大小的空间.分配的方式也有两种:

【Unity】3.1 利用内置的3D对象创建三维模型

分类:Unity.C#.VS2015 创建日期:2016-04-02 一.基本概念 Unity已经内置了一些基本的3D对象,利用这些内置的3D对象就可以直接构建出各种3D模型(当然,复杂的三维模型还需要借助专业建模软件来完成). Unity 5.3.4内置的3D对象有: Cube:立方体 Sphere:球体 Capsule:胶囊体. Cylinder:圆柱体. Plane:平面. Quad:四方格. Ragdoll:布娃娃系统. Terrain:地形. Tree:树. Wind Zone:风.