116 // Call Interpreter::remove_activation_preserving_args_entry() to get the
117 // address of the same-named entrypoint in the generated interpreter code.
118 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry));
119 jmp(rax);
120 bind(L);
121 get_thread(java_thread);
122 }
123 }
124
125
126 void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
127 get_thread(rcx);
128 movl(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset()));
129 const Address tos_addr (rcx, JvmtiThreadState::earlyret_tos_offset());
130 const Address oop_addr (rcx, JvmtiThreadState::earlyret_oop_offset());
131 const Address val_addr (rcx, JvmtiThreadState::earlyret_value_offset());
132 const Address val_addr1(rcx, JvmtiThreadState::earlyret_value_offset()
133 + in_ByteSize(wordSize));
134 switch (state) {
135 case atos: movptr(rax, oop_addr);
136 movptr(oop_addr, (int32_t)NULL_WORD);
137 verify_oop(rax, state); break;
138 case ltos:
139 movl(rdx, val_addr1); // fall through
140 case btos: // fall through
141 case ctos: // fall through
142 case stos: // fall through
143 case itos: movl(rax, val_addr); break;
144 case ftos: fld_s(val_addr); break;
145 case dtos: fld_d(val_addr); break;
146 case vtos: /* nothing to do */ break;
147 default : ShouldNotReachHere();
148 }
149 // Clean up tos value in the thread object
150 movl(tos_addr, (int32_t) ilgl);
151 movptr(val_addr, (int32_t)NULL_WORD);
152 NOT_LP64(movl(val_addr1, (int32_t)NULL_WORD));
153 }
154
155
156 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) {
157 if (JvmtiExport::can_force_early_return()) {
158 Label L;
159 Register tmp = java_thread;
160 movptr(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset()));
161 testptr(tmp, tmp);
162 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit;
163
164 // Initiate earlyret handling only if it is not already being processed.
165 // If the flag has the earlyret_processing bit set, it means that this code
166 // is called *during* earlyret handling - we don't want to reenter.
167 movl(tmp, Address(tmp, JvmtiThreadState::earlyret_state_offset()));
168 cmpl(tmp, JvmtiThreadState::earlyret_pending);
169 jcc(Assembler::notEqual, L);
170
171 // Call Interpreter::remove_activation_early_entry() to get the address of the
172 // same-named entrypoint in the generated interpreter code.
927
928 if (UseHeavyMonitors) {
929 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
930 } else {
931 Label done;
932
933 const Register swap_reg = rax; // Must use rax, for cmpxchg instruction
934 const Register header_reg = rbx; // Will contain the old oopMark
935 const Register obj_reg = rcx; // Will contain the oop
936
937 save_bcp(); // Save in case of exception
938
939 // Convert from BasicObjectLock structure to object and BasicLock structure
940 // Store the BasicLock address into %rax,
941 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
942
943 // Load oop into obj_reg(%rcx)
944 movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ()));
945
946 // Free entry
947 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);
948
949 if (UseBiasedLocking) {
950 biased_locking_exit(obj_reg, header_reg, done);
951 }
952
953 // Load the old header from BasicLock structure
954 movptr(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes()));
955
956 // Test for recursion
957 testptr(header_reg, header_reg);
958
959 // zero for recursive case
960 jcc(Assembler::zero, done);
961
962 // Atomic swap back the old header
963 if (os::is_MP()) lock();
964 cmpxchgptr(header_reg, Address(obj_reg, 0));
965
966 // zero for recursive case
967 jcc(Assembler::zero, done);
|
116 // Call Interpreter::remove_activation_preserving_args_entry() to get the
117 // address of the same-named entrypoint in the generated interpreter code.
118 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry));
119 jmp(rax);
120 bind(L);
121 get_thread(java_thread);
122 }
123 }
124
125
126 void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
127 get_thread(rcx);
128 movl(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset()));
129 const Address tos_addr (rcx, JvmtiThreadState::earlyret_tos_offset());
130 const Address oop_addr (rcx, JvmtiThreadState::earlyret_oop_offset());
131 const Address val_addr (rcx, JvmtiThreadState::earlyret_value_offset());
132 const Address val_addr1(rcx, JvmtiThreadState::earlyret_value_offset()
133 + in_ByteSize(wordSize));
134 switch (state) {
135 case atos: movptr(rax, oop_addr);
136 movptr(oop_addr, NULL_WORD);
137 verify_oop(rax, state); break;
138 case ltos:
139 movl(rdx, val_addr1); // fall through
140 case btos: // fall through
141 case ctos: // fall through
142 case stos: // fall through
143 case itos: movl(rax, val_addr); break;
144 case ftos: fld_s(val_addr); break;
145 case dtos: fld_d(val_addr); break;
146 case vtos: /* nothing to do */ break;
147 default : ShouldNotReachHere();
148 }
149 // Clean up tos value in the thread object
150 movl(tos_addr, (int32_t) ilgl);
151 movptr(val_addr, NULL_WORD);
152 NOT_LP64(movl(val_addr1, NULL_WORD));
153 }
154
155
156 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) {
157 if (JvmtiExport::can_force_early_return()) {
158 Label L;
159 Register tmp = java_thread;
160 movptr(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset()));
161 testptr(tmp, tmp);
162 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit;
163
164 // Initiate earlyret handling only if it is not already being processed.
165 // If the flag has the earlyret_processing bit set, it means that this code
166 // is called *during* earlyret handling - we don't want to reenter.
167 movl(tmp, Address(tmp, JvmtiThreadState::earlyret_state_offset()));
168 cmpl(tmp, JvmtiThreadState::earlyret_pending);
169 jcc(Assembler::notEqual, L);
170
171 // Call Interpreter::remove_activation_early_entry() to get the address of the
172 // same-named entrypoint in the generated interpreter code.
927
928 if (UseHeavyMonitors) {
929 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
930 } else {
931 Label done;
932
933 const Register swap_reg = rax; // Must use rax, for cmpxchg instruction
934 const Register header_reg = rbx; // Will contain the old oopMark
935 const Register obj_reg = rcx; // Will contain the oop
936
937 save_bcp(); // Save in case of exception
938
939 // Convert from BasicObjectLock structure to object and BasicLock structure
940 // Store the BasicLock address into %rax,
941 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
942
943 // Load oop into obj_reg(%rcx)
944 movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ()));
945
946 // Free entry
947 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD);
948
949 if (UseBiasedLocking) {
950 biased_locking_exit(obj_reg, header_reg, done);
951 }
952
953 // Load the old header from BasicLock structure
954 movptr(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes()));
955
956 // Test for recursion
957 testptr(header_reg, header_reg);
958
959 // zero for recursive case
960 jcc(Assembler::zero, done);
961
962 // Atomic swap back the old header
963 if (os::is_MP()) lock();
964 cmpxchgptr(header_reg, Address(obj_reg, 0));
965
966 // zero for recursive case
967 jcc(Assembler::zero, done);
|