83 }
84
85 address TemplateInterpreterGenerator::generate_ClassCastException_handler() {
86 address entry = __ pc();
87
88 // object is at TOS
89 __ pop(c_rarg1);
90
91 // expression stack must be empty before entering the VM if an
92 // exception happened
93 __ empty_expression_stack();
94
95 __ call_VM(noreg,
96 CAST_FROM_FN_PTR(address,
97 InterpreterRuntime::
98 throw_ClassCastException),
99 c_rarg1);
100 return entry;
101 }
102
103 // Arguments are: required type in rarg1, failing object (or NULL) in rarg2
104 address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
105 address entry = __ pc();
106
107 __ pop(c_rarg2); // failing object is at TOS
108 __ pop(c_rarg1); // required type is at TOS+8
109
110 // expression stack must be empty before entering the VM if an
111 // exception happened
112 __ empty_expression_stack();
113
114 __ call_VM(noreg,
115 CAST_FROM_FN_PTR(address,
116 InterpreterRuntime::
117 throw_WrongMethodTypeException),
118 // pass required type, failing object (or NULL)
119 c_rarg1, c_rarg2);
120 return entry;
121 }
122
123 address TemplateInterpreterGenerator::generate_exception_handler_common(
124 const char* name, const char* message, bool pass_oop) {
125 assert(!pass_oop || message == NULL, "either oop or message but not both");
126 address entry = __ pc();
127 if (pass_oop) {
128 // object is at TOS
129 __ pop(c_rarg2);
130 }
131 // expression stack must be empty before entering the VM if an
132 // exception happened
133 __ empty_expression_stack();
134 // setup parameters
135 __ lea(c_rarg1, ExternalAddress((address)name));
136 if (pass_oop) {
137 __ call_VM(rax, CAST_FROM_FN_PTR(address,
165 }
166
167
168 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
169 int step) {
170
171 // amd64 doesn't need to do anything special about compiled returns
172 // to the interpreter so the code that exists on x86 to place a sentinel
173 // here and the specialized cleanup code is not needed here.
174
175 address entry = __ pc();
176
177 // Restore stack bottom in case i2c adjusted stack
178 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
179 // and NULL it as marker that esp is now tos until next java call
180 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
181
182 __ restore_bcp();
183 __ restore_locals();
184
185 __ get_cache_and_index_at_bcp(rbx, rcx, 1);
186 __ movl(rbx, Address(rbx, rcx,
187 Address::times_8,
188 in_bytes(constantPoolCacheOopDesc::base_offset()) +
189 3 * wordSize));
190 __ andl(rbx, 0xFF);
191 if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
192 __ lea(rsp, Address(rsp, rbx, Address::times_8));
193 __ dispatch_next(state, step);
194 return entry;
195 }
196
197
198 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state,
199 int step) {
200 address entry = __ pc();
201 // NULL last_sp until next java call
202 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
203 __ restore_bcp();
204 __ restore_locals();
205 // handle exceptions
206 {
207 Label L;
208 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD);
209 __ jcc(Assembler::zero, L);
210 __ call_VM(noreg,
211 CAST_FROM_FN_PTR(address,
212 InterpreterRuntime::throw_pending_exception));
213 __ should_not_reach_here();
|
83 }
84
85 address TemplateInterpreterGenerator::generate_ClassCastException_handler() {
86 address entry = __ pc();
87
88 // object is at TOS
89 __ pop(c_rarg1);
90
91 // expression stack must be empty before entering the VM if an
92 // exception happened
93 __ empty_expression_stack();
94
95 __ call_VM(noreg,
96 CAST_FROM_FN_PTR(address,
97 InterpreterRuntime::
98 throw_ClassCastException),
99 c_rarg1);
100 return entry;
101 }
102
103 // Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
104 address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
105 address entry = __ pc();
106
107 __ pop(c_rarg2); // failing object is at TOS
108 __ pop(c_rarg1); // required type is at TOS+8
109
110 __ verify_oop(c_rarg1);
111 __ verify_oop(c_rarg2);
112
113 // Various method handle types use interpreter registers as temps.
114 __ restore_bcp();
115 __ restore_locals();
116
117 // Expression stack must be empty before entering the VM for an exception.
118 __ empty_expression_stack();
119
120 __ call_VM(noreg,
121 CAST_FROM_FN_PTR(address,
122 InterpreterRuntime::throw_WrongMethodTypeException),
123 // pass required type, failing object (or NULL)
124 c_rarg1, c_rarg2);
125 return entry;
126 }
127
128 address TemplateInterpreterGenerator::generate_exception_handler_common(
129 const char* name, const char* message, bool pass_oop) {
130 assert(!pass_oop || message == NULL, "either oop or message but not both");
131 address entry = __ pc();
132 if (pass_oop) {
133 // object is at TOS
134 __ pop(c_rarg2);
135 }
136 // expression stack must be empty before entering the VM if an
137 // exception happened
138 __ empty_expression_stack();
139 // setup parameters
140 __ lea(c_rarg1, ExternalAddress((address)name));
141 if (pass_oop) {
142 __ call_VM(rax, CAST_FROM_FN_PTR(address,
170 }
171
172
173 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
174 int step) {
175
176 // amd64 doesn't need to do anything special about compiled returns
177 // to the interpreter so the code that exists on x86 to place a sentinel
178 // here and the specialized cleanup code is not needed here.
179
180 address entry = __ pc();
181
182 // Restore stack bottom in case i2c adjusted stack
183 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
184 // and NULL it as marker that esp is now tos until next java call
185 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
186
187 __ restore_bcp();
188 __ restore_locals();
189
190 Label L_got_cache, L_giant_index;
191 if (EnableInvokeDynamic) {
192 __ cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
193 __ jcc(Assembler::equal, L_giant_index);
194 }
195 __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
196 __ bind(L_got_cache);
197 __ movl(rbx, Address(rbx, rcx,
198 Address::times_ptr,
199 in_bytes(constantPoolCacheOopDesc::base_offset()) +
200 3 * wordSize));
201 __ andl(rbx, 0xFF);
202 if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
203 __ lea(rsp, Address(rsp, rbx, Address::times_8));
204 __ dispatch_next(state, step);
205
206 // out of the main line of code...
207 if (EnableInvokeDynamic) {
208 __ bind(L_giant_index);
209 __ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
210 __ jmp(L_got_cache);
211 }
212
213 return entry;
214 }
215
216
217 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state,
218 int step) {
219 address entry = __ pc();
220 // NULL last_sp until next java call
221 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
222 __ restore_bcp();
223 __ restore_locals();
224 // handle exceptions
225 {
226 Label L;
227 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD);
228 __ jcc(Assembler::zero, L);
229 __ call_VM(noreg,
230 CAST_FROM_FN_PTR(address,
231 InterpreterRuntime::throw_pending_exception));
232 __ should_not_reach_here();
|