src/cpu/sparc/vm/stubGenerator_sparc.cpp
Print this page
*** 564,643 ****
address generate_flush_callers_register_windows() {
StubCodeMark mark(this, "StubRoutines", "flush_callers_register_windows");
address start = __ pc();
! __ flush_windows();
__ retl(false);
__ delayed()->add( FP, STACK_BIAS, O0 );
// The returned value must be a stack pointer whose register save area
// is flushed, and will stay flushed while the caller executes.
return start;
}
- // Helper functions for v8 atomic operations.
- //
- void get_v8_oop_lock_ptr(Register lock_ptr_reg, Register mark_oop_reg, Register scratch_reg) {
- if (mark_oop_reg == noreg) {
- address lock_ptr = (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr();
- __ set((intptr_t)lock_ptr, lock_ptr_reg);
- } else {
- assert(scratch_reg != noreg, "just checking");
- address lock_ptr = (address)StubRoutines::Sparc::_v8_oop_lock_cache;
- __ set((intptr_t)lock_ptr, lock_ptr_reg);
- __ and3(mark_oop_reg, StubRoutines::Sparc::v8_oop_lock_mask_in_place, scratch_reg);
- __ add(lock_ptr_reg, scratch_reg, lock_ptr_reg);
- }
- }
-
- void generate_v8_lock_prologue(Register lock_reg, Register lock_ptr_reg, Register yield_reg, Label& retry, Label& dontyield, Register mark_oop_reg = noreg, Register scratch_reg = noreg) {
-
- get_v8_oop_lock_ptr(lock_ptr_reg, mark_oop_reg, scratch_reg);
- __ set(StubRoutines::Sparc::locked, lock_reg);
- // Initialize yield counter
- __ mov(G0,yield_reg);
-
- __ BIND(retry);
- __ cmp_and_br_short(yield_reg, V8AtomicOperationUnderLockSpinCount, Assembler::less, Assembler::pt, dontyield);
-
- // This code can only be called from inside the VM, this
- // stub is only invoked from Atomic::add(). We do not
- // want to use call_VM, because _last_java_sp and such
- // must already be set.
- //
- // Save the regs and make space for a C call
- __ save(SP, -96, SP);
- __ save_all_globals_into_locals();
- BLOCK_COMMENT("call os::naked_sleep");
- __ call(CAST_FROM_FN_PTR(address, os::naked_sleep));
- __ delayed()->nop();
- __ restore_globals_from_locals();
- __ restore();
- // reset the counter
- __ mov(G0,yield_reg);
-
- __ BIND(dontyield);
-
- // try to get lock
- __ swap(lock_ptr_reg, 0, lock_reg);
-
- // did we get the lock?
- __ cmp(lock_reg, StubRoutines::Sparc::unlocked);
- __ br(Assembler::notEqual, true, Assembler::pn, retry);
- __ delayed()->add(yield_reg,1,yield_reg);
-
- // yes, got lock. do the operation here.
- }
-
- void generate_v8_lock_epilogue(Register lock_reg, Register lock_ptr_reg, Register yield_reg, Label& retry, Label& dontyield, Register mark_oop_reg = noreg, Register scratch_reg = noreg) {
- __ st(lock_reg, lock_ptr_reg, 0); // unlock
- }
-
// Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
//
! // Arguments :
//
// exchange_value: O0
// dest: O1
//
// Results:
--- 564,585 ----
address generate_flush_callers_register_windows() {
StubCodeMark mark(this, "StubRoutines", "flush_callers_register_windows");
address start = __ pc();
! __ flushw();
__ retl(false);
__ delayed()->add( FP, STACK_BIAS, O0 );
// The returned value must be a stack pointer whose register save area
// is flushed, and will stay flushed while the caller executes.
return start;
}
// Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
//
! // Arguments:
//
// exchange_value: O0
// dest: O1
//
// Results:
*** 654,746 ****
Label retry;
__ BIND(retry);
__ mov(O0, O3); // scratch copy of exchange value
__ ld(O1, 0, O2); // observe the previous value
// try to replace O2 with O3
! __ cas_under_lock(O1, O2, O3,
! (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false);
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->mov(O2, O0); // report previous value to caller
-
} else {
- if (VM_Version::v9_instructions_work()) {
__ retl(false);
__ delayed()->swap(O1, 0, O0);
- } else {
- const Register& lock_reg = O2;
- const Register& lock_ptr_reg = O3;
- const Register& yield_reg = O4;
-
- Label retry;
- Label dontyield;
-
- generate_v8_lock_prologue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
- // got the lock, do the swap
- __ swap(O1, 0, O0);
-
- generate_v8_lock_epilogue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
- __ retl(false);
- __ delayed()->nop();
- }
}
return start;
}
// Support for jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value)
//
! // Arguments :
//
// exchange_value: O0
// dest: O1
// compare_value: O2
//
// Results:
//
// O0: the value previously stored in dest
//
- // Overwrites (v8): O3,O4,O5
- //
address generate_atomic_cmpxchg() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg");
address start = __ pc();
// cmpxchg(dest, compare_value, exchange_value)
! __ cas_under_lock(O1, O2, O0,
! (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false);
__ retl(false);
__ delayed()->nop();
return start;
}
// Support for jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong *dest, jlong compare_value)
//
! // Arguments :
//
// exchange_value: O1:O0
// dest: O2
// compare_value: O4:O3
//
// Results:
//
// O1:O0: the value previously stored in dest
//
- // This only works on V9, on V8 we don't generate any
- // code and just return NULL.
- //
// Overwrites: G1,G2,G3
//
address generate_atomic_cmpxchg_long() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_long");
address start = __ pc();
- if (!VM_Version::supports_cx8())
- return NULL;;
__ sllx(O0, 32, O0);
__ srl(O1, 0, O1);
__ or3(O0,O1,O0); // O0 holds 64-bit value from compare_value
__ sllx(O3, 32, O3);
__ srl(O4, 0, O4);
--- 596,661 ----
Label retry;
__ BIND(retry);
__ mov(O0, O3); // scratch copy of exchange value
__ ld(O1, 0, O2); // observe the previous value
// try to replace O2 with O3
! __ cas(O1, O2, O3);
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->mov(O2, O0); // report previous value to caller
} else {
__ retl(false);
__ delayed()->swap(O1, 0, O0);
}
return start;
}
// Support for jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value)
//
! // Arguments:
//
// exchange_value: O0
// dest: O1
// compare_value: O2
//
// Results:
//
// O0: the value previously stored in dest
//
address generate_atomic_cmpxchg() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg");
address start = __ pc();
// cmpxchg(dest, compare_value, exchange_value)
! __ cas(O1, O2, O0);
__ retl(false);
__ delayed()->nop();
return start;
}
// Support for jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong *dest, jlong compare_value)
//
! // Arguments:
//
// exchange_value: O1:O0
// dest: O2
// compare_value: O4:O3
//
// Results:
//
// O1:O0: the value previously stored in dest
//
// Overwrites: G1,G2,G3
//
address generate_atomic_cmpxchg_long() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_long");
address start = __ pc();
__ sllx(O0, 32, O0);
__ srl(O1, 0, O1);
__ or3(O0,O1,O0); // O0 holds 64-bit value from compare_value
__ sllx(O3, 32, O3);
__ srl(O4, 0, O4);
*** 754,813 ****
}
// Support for jint Atomic::add(jint add_value, volatile jint* dest).
//
! // Arguments :
//
// add_value: O0 (e.g., +1 or -1)
// dest: O1
//
// Results:
//
// O0: the new value stored in dest
//
! // Overwrites (v9): O3
! // Overwrites (v8): O3,O4,O5
//
address generate_atomic_add() {
StubCodeMark mark(this, "StubRoutines", "atomic_add");
address start = __ pc();
__ BIND(_atomic_add_stub);
- if (VM_Version::v9_instructions_work()) {
Label(retry);
__ BIND(retry);
__ lduw(O1, 0, O2);
__ add(O0, O2, O3);
__ cas(O1, O2, O3);
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->add(O0, O2, O0); // note that cas made O2==O3
- } else {
- const Register& lock_reg = O2;
- const Register& lock_ptr_reg = O3;
- const Register& value_reg = O4;
- const Register& yield_reg = O5;
-
- Label(retry);
- Label(dontyield);
-
- generate_v8_lock_prologue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
- // got lock, do the increment
- __ ld(O1, 0, value_reg);
- __ add(O0, value_reg, value_reg);
- __ st(value_reg, O1, 0);
-
- // %%% only for RMO and PSO
- __ membar(Assembler::StoreStore);
-
- generate_v8_lock_epilogue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
-
- __ retl(false);
- __ delayed()->mov(value_reg, O0);
- }
return start;
}
Label _atomic_add_stub; // called from other stubs
--- 669,703 ----
}
// Support for jint Atomic::add(jint add_value, volatile jint* dest).
//
! // Arguments:
//
// add_value: O0 (e.g., +1 or -1)
// dest: O1
//
// Results:
//
// O0: the new value stored in dest
//
! // Overwrites: O3
//
address generate_atomic_add() {
StubCodeMark mark(this, "StubRoutines", "atomic_add");
address start = __ pc();
__ BIND(_atomic_add_stub);
Label(retry);
__ BIND(retry);
__ lduw(O1, 0, O2);
__ add(O0, O2, O3);
__ cas(O1, O2, O3);
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->add(O0, O2, O0); // note that cas made O2==O3
return start;
}
Label _atomic_add_stub; // called from other stubs
*** 839,849 ****
__ mov(G1, L1);
__ mov(G2, L2);
__ mov(G3, L3);
__ mov(G4, L4);
__ mov(G5, L5);
! for (i = 0; i < (VM_Version::v9_instructions_work() ? 64 : 32); i += 2) {
__ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
}
address entry_point = CAST_FROM_FN_PTR(address, handle_unsafe_access);
BLOCK_COMMENT("call handle_unsafe_access");
--- 729,739 ----
__ mov(G1, L1);
__ mov(G2, L2);
__ mov(G3, L3);
__ mov(G4, L4);
__ mov(G5, L5);
! for (i = 0; i < 64; i += 2) {
__ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
}
address entry_point = CAST_FROM_FN_PTR(address, handle_unsafe_access);
BLOCK_COMMENT("call handle_unsafe_access");
*** 853,863 ****
__ mov(L1, G1);
__ mov(L2, G2);
__ mov(L3, G3);
__ mov(L4, G4);
__ mov(L5, G5);
! for (i = 0; i < (VM_Version::v9_instructions_work() ? 64 : 32); i += 2) {
__ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
}
__ verify_thread();
--- 743,753 ----
__ mov(L1, G1);
__ mov(L2, G2);
__ mov(L3, G3);
__ mov(L4, G4);
__ mov(L5, G5);
! for (i = 0; i < 64; i += 2) {
__ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
}
__ verify_thread();