3949 // If TLAB is enabled:
3950 // Try to allocate in the TLAB.
3951 // If fails, go to the slow path.
3952 // Initialize the allocation.
3953 // Exit.
3954 //
3955 // Go to slow path.
3956
3957 const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
3958
3959 if (UseTLAB) {
3960 NOT_LP64(__ get_thread(thread);)
3961 __ tlab_allocate(thread, rax, rdx, 0, rcx, rbx, slow_case);
3962 if (ZeroTLAB) {
3963 // the fields have been already cleared
3964 __ jmp(initialize_header);
3965 }
3966
3967 // The object is initialized before the header. If the object size is
3968 // zero, go directly to the header initialization.
3969 __ decrement(rdx, sizeof(oopDesc));
3970 __ jcc(Assembler::zero, initialize_header);
3971
3972 // Initialize topmost object field, divide rdx by 8, check if odd and
3973 // test if zero.
3974 __ xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
3975 __ shrl(rdx, LogBytesPerLong); // divide by 2*oopSize and set carry flag if odd
3976
3977 // rdx must have been multiple of 8
3978 #ifdef ASSERT
3979 // make sure rdx was multiple of 8
3980 Label L;
3981 // Ignore partial flag stall after shrl() since it is debug VM
3982 __ jcc(Assembler::carryClear, L);
3983 __ stop("object size is not multiple of 2 - adjust this code");
3984 __ bind(L);
3985 // rdx must be > 0, no extra check needed here
3986 #endif
3987
3988 // initialize remaining object fields: rdx was a multiple of 8
3989 { Label loop;
3990 __ bind(loop);
3991 __ movptr(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 1*oopSize), rcx);
3992 NOT_LP64(__ movptr(Address(rax, rdx, Address::times_8, sizeof(oopDesc) - 2*oopSize), rcx));
3993 __ decrement(rdx);
3994 __ jcc(Assembler::notZero, loop);
3995 }
3996
3997 // initialize object header only.
3998 __ bind(initialize_header);
3999 __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()),
4000 (intptr_t)markWord::prototype().value()); // header
4001 __ pop(rcx); // get saved klass back in the register.
4002 #ifdef _LP64
4003 __ xorl(rsi, rsi); // use zero reg to clear memory (shorter code)
4004 __ store_klass_gap(rax, rsi); // zero klass gap for compressed oops
4005 #endif
4006 __ store_klass(rax, rcx, rscratch1); // klass
4007
4008 {
4009 SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0, rscratch1);
4010 // Trigger dtrace event for fastpath
4011 __ push(atos);
4012 __ call_VM_leaf(
4013 CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), rax);
4014 __ pop(atos);
4015 }
4016
4017 __ jmp(done);
4018 }
4019
4020 // slow case
4021 __ bind(slow_case);
4022 __ pop(rcx); // restore stack pointer to what it was when we came in.
4023 __ bind(slow_case_no_pop);
4024
4025 Register rarg1 = LP64_ONLY(c_rarg1) NOT_LP64(rax);
4026 Register rarg2 = LP64_ONLY(c_rarg2) NOT_LP64(rdx);
|
3949 // If TLAB is enabled:
3950 // Try to allocate in the TLAB.
3951 // If fails, go to the slow path.
3952 // Initialize the allocation.
3953 // Exit.
3954 //
3955 // Go to slow path.
3956
3957 const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
3958
3959 if (UseTLAB) {
3960 NOT_LP64(__ get_thread(thread);)
3961 __ tlab_allocate(thread, rax, rdx, 0, rcx, rbx, slow_case);
3962 if (ZeroTLAB) {
3963 // the fields have been already cleared
3964 __ jmp(initialize_header);
3965 }
3966
3967 // The object is initialized before the header. If the object size is
3968 // zero, go directly to the header initialization.
3969 int header_size = align_up(oopDesc::base_offset_in_bytes(), BytesPerLong);
3970 __ decrement(rdx, header_size);
3971 __ jcc(Assembler::zero, initialize_header);
3972
3973 // Initialize topmost object field, divide rdx by 8, check if odd and
3974 // test if zero.
3975 __ xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
3976 __ shrl(rdx, LogBytesPerLong); // divide by 2*oopSize and set carry flag if odd
3977
3978 // rdx must have been multiple of 8
3979 #ifdef ASSERT
3980 // make sure rdx was multiple of 8
3981 Label L;
3982 // Ignore partial flag stall after shrl() since it is debug VM
3983 __ jcc(Assembler::carryClear, L);
3984 __ stop("object size is not multiple of 2 - adjust this code");
3985 __ bind(L);
3986 // rdx must be > 0, no extra check needed here
3987 #endif
3988
3989 // initialize remaining object fields: rdx was a multiple of 8
3990 { Label loop;
3991 __ bind(loop);
3992 __ movptr(Address(rax, rdx, Address::times_8, header_size - 1*oopSize), rcx);
3993 NOT_LP64(__ movptr(Address(rax, rdx, Address::times_8, header_size - 2*oopSize), rcx));
3994 __ decrement(rdx);
3995 __ jcc(Assembler::notZero, loop);
3996 }
3997
3998 // initialize object header only.
3999 __ bind(initialize_header);
4000 if (UseCompactObjectHeaders) {
4001 __ pop(rcx); // get saved klass back in the register.
4002 __ movptr(rbx, Address(rcx, Klass::prototype_header_offset()));
4003 __ movptr(Address(rax, oopDesc::mark_offset_in_bytes ()), rbx);
4004 } else {
4005 __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()),
4006 (intptr_t)markWord::prototype().value()); // header
4007 __ pop(rcx); // get saved klass back in the register.
4008 #ifdef _LP64
4009 __ xorl(rsi, rsi); // use zero reg to clear memory (shorter code)
4010 __ store_klass_gap(rax, rsi); // zero klass gap for compressed oops
4011 #endif
4012 __ store_klass(rax, rcx, rscratch1); // klass
4013 }
4014
4015 {
4016 SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0, rscratch1);
4017 // Trigger dtrace event for fastpath
4018 __ push(atos);
4019 __ call_VM_leaf(
4020 CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), rax);
4021 __ pop(atos);
4022 }
4023
4024 __ jmp(done);
4025 }
4026
4027 // slow case
4028 __ bind(slow_case);
4029 __ pop(rcx); // restore stack pointer to what it was when we came in.
4030 __ bind(slow_case_no_pop);
4031
4032 Register rarg1 = LP64_ONLY(c_rarg1) NOT_LP64(rax);
4033 Register rarg2 = LP64_ONLY(c_rarg2) NOT_LP64(rdx);
|