21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "gc/shared/barrierSetAssembler.hpp"
28 #include "interpreter/bytecodeHistogram.hpp"
29 #include "interpreter/interp_masm.hpp"
30 #include "interpreter/interpreter.hpp"
31 #include "interpreter/interpreterRuntime.hpp"
32 #include "interpreter/templateInterpreterGenerator.hpp"
33 #include "interpreter/templateTable.hpp"
34 #include "oops/arrayOop.hpp"
35 #include "oops/methodData.hpp"
36 #include "oops/method.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "prims/jvmtiExport.hpp"
39 #include "prims/jvmtiThreadState.hpp"
40 #include "runtime/arguments.hpp"
41 #include "runtime/deoptimization.hpp"
42 #include "runtime/frame.inline.hpp"
43 #include "runtime/sharedRuntime.hpp"
44 #include "runtime/stubRoutines.hpp"
45 #include "runtime/synchronizer.hpp"
46 #include "runtime/timer.hpp"
47 #include "runtime/vframeArray.hpp"
48 #include "utilities/debug.hpp"
49 #include "utilities/macros.hpp"
50
51 #define __ _masm->
52
53 // Size of interpreter code. Increase if too small. Interpreter will
54 // fail with a guarantee ("not enough space for interpreter generation");
55 // if too small.
56 // Run with +PrintInterpreter to get the VM to print out the size.
57 // Max size with JVMTI
58 #ifdef AMD64
59 int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024;
60 #else
156 __ empty_expression_stack();
157 // setup parameters
158 __ lea(rarg, ExternalAddress((address)name));
159 if (pass_oop) {
160 __ call_VM(rax, CAST_FROM_FN_PTR(address,
161 InterpreterRuntime::
162 create_klass_exception),
163 rarg, rarg2);
164 } else {
165 __ lea(rarg2, ExternalAddress((address)message));
166 __ call_VM(rax,
167 CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
168 rarg, rarg2);
169 }
170 // throw exception
171 __ jump(ExternalAddress(Interpreter::throw_exception_entry()));
172 return entry;
173 }
174
175 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
176 address entry = __ pc();
177
178 #ifndef _LP64
179 #ifdef COMPILER2
180 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
181 if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
182 for (int i = 1; i < 8; i++) {
183 __ ffree(i);
184 }
185 } else if (UseSSE < 2) {
186 __ empty_FPU_stack();
187 }
188 #endif // COMPILER2
189 if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
190 __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
191 } else {
192 __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
193 }
194
195 if (state == ftos) {
196 __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_return_entry_for in interpreter");
197 } else if (state == dtos) {
198 __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter");
199 }
200 #endif // _LP64
201
202 // Restore stack bottom in case i2c adjusted stack
203 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
204 // and NULL it as marker that esp is now tos until next java call
205 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
206
207 __ restore_bcp();
208 __ restore_locals();
209
210 if (state == atos) {
211 Register mdp = rbx;
212 Register tmp = rcx;
213 __ profile_return_type(mdp, rax, tmp);
214 }
215
216 const Register cache = rbx;
217 const Register index = rcx;
218 __ get_cache_and_index_at_bcp(cache, index, 1, index_size);
219
220 const Register flags = cache;
221 __ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
222 __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
223 __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
224
225 const Register java_thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
226 if (JvmtiExport::can_pop_frame()) {
227 NOT_LP64(__ get_thread(java_thread));
228 __ check_and_handle_popframe(java_thread);
229 }
230 if (JvmtiExport::can_force_early_return()) {
231 NOT_LP64(__ get_thread(java_thread));
232 __ check_and_handle_earlyret(java_thread);
233 }
234
235 __ dispatch_next(state, step);
236
237 return entry;
238 }
239
240
241 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step, address continuation) {
242 address entry = __ pc();
243
244 #ifndef _LP64
245 if (state == ftos) {
246 __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_deopt_entry_for in interpreter");
247 } else if (state == dtos) {
248 __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_deopt_entry_for in interpreter");
249 }
250 #endif // _LP64
251
252 // NULL last_sp until next java call
253 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
254 __ restore_bcp();
678 } else {
679 __ push(0);
680 }
681
682 __ movptr(rdx, Address(rbx, Method::const_offset()));
683 __ movptr(rdx, Address(rdx, ConstMethod::constants_offset()));
684 __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes()));
685 __ push(rdx); // set constant pool cache
686 __ push(rlocals); // set locals pointer
687 if (native_call) {
688 __ push(0); // no bcp
689 } else {
690 __ push(rbcp); // set bcp
691 }
692 __ push(0); // reserve word for pointer to expression stack bottom
693 __ movptr(Address(rsp, 0), rsp); // set expression stack bottom
694 }
695
696 // End of helpers
697
698 // Method entry for java.lang.ref.Reference.get.
699 address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
700 // Code: _aload_0, _getfield, _areturn
701 // parameter size = 1
702 //
703 // The code that gets generated by this routine is split into 2 parts:
704 // 1. The "intrinsified" code performing an ON_WEAK_OOP_REF load,
705 // 2. The slow path - which is an expansion of the regular method entry.
706 //
707 // Notes:-
708 // * An intrinsic is always executed, where an ON_WEAK_OOP_REF load is performed.
709 // * We may jump to the slow path iff the receiver is null. If the
710 // Reference object is null then we no longer perform an ON_WEAK_OOP_REF load
711 // Thus we can use the regular method entry code to generate the NPE.
712 //
713 // rbx: Method*
714
715 // r13: senderSP must preserve for slow path, set SP to it on fast path
716
717 address entry = __ pc();
1320 __ empty_expression_stack();
1321 __ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
1322 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
1323
1324 // throw exception
1325 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorWithMethod), rbx);
1326 // the call_VM checks for exception, so we should never return here.
1327 __ should_not_reach_here();
1328
1329 return entry_point;
1330 }
1331
1332 //
1333 // Generic interpreted method entry to (asm) interpreter
1334 //
1335 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1336 // determine code generation flags
1337 bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1338
1339 // ebx: Method*
1340 // rbcp: sender sp
1341 address entry_point = __ pc();
1342
1343 const Address constMethod(rbx, Method::const_offset());
1344 const Address access_flags(rbx, Method::access_flags_offset());
1345 const Address size_of_parameters(rdx,
1346 ConstMethod::size_of_parameters_offset());
1347 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
1348
1349
1350 // get parameter size (always needed)
1351 __ movptr(rdx, constMethod);
1352 __ load_unsigned_short(rcx, size_of_parameters);
1353
1354 // rbx: Method*
1355 // rcx: size of parameters
1356 // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i )
1357
1358 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
1359 __ subl(rdx, rcx); // rdx = no. of additional locals
1360
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "gc/shared/barrierSetAssembler.hpp"
28 #include "interpreter/bytecodeHistogram.hpp"
29 #include "interpreter/interp_masm.hpp"
30 #include "interpreter/interpreter.hpp"
31 #include "interpreter/interpreterRuntime.hpp"
32 #include "interpreter/templateInterpreterGenerator.hpp"
33 #include "interpreter/templateTable.hpp"
34 #include "oops/arrayOop.hpp"
35 #include "oops/methodData.hpp"
36 #include "oops/method.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "prims/jvmtiExport.hpp"
39 #include "prims/jvmtiThreadState.hpp"
40 #include "runtime/arguments.hpp"
41 #include "runtime/continuation.hpp"
42 #include "runtime/deoptimization.hpp"
43 #include "runtime/frame.inline.hpp"
44 #include "runtime/sharedRuntime.hpp"
45 #include "runtime/stubRoutines.hpp"
46 #include "runtime/synchronizer.hpp"
47 #include "runtime/timer.hpp"
48 #include "runtime/vframeArray.hpp"
49 #include "utilities/debug.hpp"
50 #include "utilities/macros.hpp"
51
52 #define __ _masm->
53
54 // Size of interpreter code. Increase if too small. Interpreter will
55 // fail with a guarantee ("not enough space for interpreter generation");
56 // if too small.
57 // Run with +PrintInterpreter to get the VM to print out the size.
58 // Max size with JVMTI
59 #ifdef AMD64
60 int TemplateInterpreter::InterpreterCodeSize = JVMCI_ONLY(268) NOT_JVMCI(256) * 1024;
61 #else
157 __ empty_expression_stack();
158 // setup parameters
159 __ lea(rarg, ExternalAddress((address)name));
160 if (pass_oop) {
161 __ call_VM(rax, CAST_FROM_FN_PTR(address,
162 InterpreterRuntime::
163 create_klass_exception),
164 rarg, rarg2);
165 } else {
166 __ lea(rarg2, ExternalAddress((address)message));
167 __ call_VM(rax,
168 CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
169 rarg, rarg2);
170 }
171 // throw exception
172 __ jump(ExternalAddress(Interpreter::throw_exception_entry()));
173 return entry;
174 }
175
176 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
177 return generate_return_entry_for(state, step, index_size, false);
178 }
179
180 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size, bool X) {
181 address entry = __ pc();
182
183 // if(X) __ stop("XXXXXXXX 000");
184 #ifndef _LP64
185 #ifdef COMPILER2
186 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
187 if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
188 for (int i = 1; i < 8; i++) {
189 __ ffree(i);
190 }
191 } else if (UseSSE < 2) {
192 __ empty_FPU_stack();
193 }
194 #endif // COMPILER2
195 if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
196 __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
197 } else {
198 __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
199 }
200
201 if (state == ftos) {
202 __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_return_entry_for in interpreter");
203 } else if (state == dtos) {
204 __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter");
205 }
206 #endif // _LP64
207
208 // if(X) __ stop("XXXXXXXX 111");
209
210 // Restore stack bottom in case i2c adjusted stack
211 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
212 // and NULL it as marker that esp is now tos until next java call
213 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
214
215 // if(X) __ stop("XXXXXXXX 222");
216
217 __ restore_bcp();
218 __ restore_locals();
219
220 // if(X) __ stop("XXXXXXXX 333"); // rbcp = r13 locals = r14
221
222 if (state == atos) {
223 Register mdp = rbx;
224 Register tmp = rcx;
225 __ profile_return_type(mdp, rax, tmp);
226 }
227
228 const Register cache = rbx;
229 const Register index = rcx;
230 __ get_cache_and_index_at_bcp(cache, index, 1, index_size);
231
232 const Register flags = cache;
233 __ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
234 __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask);
235 __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale()));
236
237 const Register java_thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
238 if (JvmtiExport::can_pop_frame()) {
239 NOT_LP64(__ get_thread(java_thread));
240 __ check_and_handle_popframe(java_thread);
241 }
242 if (JvmtiExport::can_force_early_return()) {
243 NOT_LP64(__ get_thread(java_thread));
244 __ check_and_handle_earlyret(java_thread);
245 }
246
247 if(X) __ stop("XXXXXXXX 444");
248
249 __ dispatch_next(state, step);
250
251 return entry;
252 }
253
254
255 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step, address continuation) {
256 address entry = __ pc();
257
258 #ifndef _LP64
259 if (state == ftos) {
260 __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_deopt_entry_for in interpreter");
261 } else if (state == dtos) {
262 __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_deopt_entry_for in interpreter");
263 }
264 #endif // _LP64
265
266 // NULL last_sp until next java call
267 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
268 __ restore_bcp();
692 } else {
693 __ push(0);
694 }
695
696 __ movptr(rdx, Address(rbx, Method::const_offset()));
697 __ movptr(rdx, Address(rdx, ConstMethod::constants_offset()));
698 __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes()));
699 __ push(rdx); // set constant pool cache
700 __ push(rlocals); // set locals pointer
701 if (native_call) {
702 __ push(0); // no bcp
703 } else {
704 __ push(rbcp); // set bcp
705 }
706 __ push(0); // reserve word for pointer to expression stack bottom
707 __ movptr(Address(rsp, 0), rsp); // set expression stack bottom
708 }
709
710 // End of helpers
711
712 address TemplateInterpreterGenerator::generate_Continuation_runLevel_entry(void) {
713 address entry = __ pc();
714
715 __ movl(rax, 0);
716 __ ret(0);
717
718 return entry;
719 }
720
721 // return current sp
722 address TemplateInterpreterGenerator::generate_Continuation_getSP_entry(void) {
723 address entry = __ pc();
724
725 __ lea(rax, Address(rsp, wordSize)); // skip return address
726 __ ret(0);
727
728 return entry;
729 }
730
731 // return current fp
732 address TemplateInterpreterGenerator::generate_Continuation_getFP_entry(void) {
733 address entry = __ pc();
734
735 __ movptr(rax, rbp);
736 __ ret(0);
737
738 return entry;
739 }
740
741 // return current pc
742 address TemplateInterpreterGenerator::generate_Continuation_getPC_entry(void) {
743 address entry = __ pc();
744
745 __ movptr(rax, Address(rsp, 0));
746 __ ret(0);
747
748 return entry;
749 }
750
751 address TemplateInterpreterGenerator::generate_Continuation_doYield_entry(void) {
752 address entry = __ pc();
753 assert(StubRoutines::cont_doYield() != NULL, "stub not yet generated");
754
755 __ movl(c_rarg0, Address(rsp, wordSize)); // scopes
756 __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_doYield())));
757
758 return entry;
759 }
760
761 address TemplateInterpreterGenerator::generate_Continuation_doContinue_entry(void) {
762 address entry = __ pc();
763 assert(StubRoutines::cont_thaw() != NULL, "stub not yet generated");
764
765 __ jump(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::cont_thaw())));
766
767 return entry;
768 }
769
770 // Method entry for java.lang.ref.Reference.get.
771 address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
772 // Code: _aload_0, _getfield, _areturn
773 // parameter size = 1
774 //
775 // The code that gets generated by this routine is split into 2 parts:
776 // 1. The "intrinsified" code performing an ON_WEAK_OOP_REF load,
777 // 2. The slow path - which is an expansion of the regular method entry.
778 //
779 // Notes:-
780 // * An intrinsic is always executed, where an ON_WEAK_OOP_REF load is performed.
781 // * We may jump to the slow path iff the receiver is null. If the
782 // Reference object is null then we no longer perform an ON_WEAK_OOP_REF load
783 // Thus we can use the regular method entry code to generate the NPE.
784 //
785 // rbx: Method*
786
787 // r13: senderSP must preserve for slow path, set SP to it on fast path
788
789 address entry = __ pc();
1392 __ empty_expression_stack();
1393 __ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
1394 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
1395
1396 // throw exception
1397 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorWithMethod), rbx);
1398 // the call_VM checks for exception, so we should never return here.
1399 __ should_not_reach_here();
1400
1401 return entry_point;
1402 }
1403
1404 //
1405 // Generic interpreted method entry to (asm) interpreter
1406 //
1407 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1408 // determine code generation flags
1409 bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
1410
1411 // ebx: Method*
1412 // rbcp: sender sp (set in InterpreterMacroAssembler::prepare_to_jump_from_interpreted / generate_call_stub)
1413 address entry_point = __ pc();
1414
1415 const Address constMethod(rbx, Method::const_offset());
1416 const Address access_flags(rbx, Method::access_flags_offset());
1417 const Address size_of_parameters(rdx,
1418 ConstMethod::size_of_parameters_offset());
1419 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
1420
1421
1422 // get parameter size (always needed)
1423 __ movptr(rdx, constMethod);
1424 __ load_unsigned_short(rcx, size_of_parameters);
1425
1426 // rbx: Method*
1427 // rcx: size of parameters
1428 // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i )
1429
1430 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words
1431 __ subl(rdx, rcx); // rdx = no. of additional locals
1432
|