68 // Do Int register here |
68 // Do Int register here |
69 switch ( i ) { |
69 switch ( i ) { |
70 case 0: |
70 case 0: |
71 __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); |
71 __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); |
72 __ testl(rscratch1, JVM_ACC_STATIC); |
72 __ testl(rscratch1, JVM_ACC_STATIC); |
73 __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); |
73 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); |
74 break; |
74 break; |
75 case 1: |
75 case 1: |
76 __ movq(c_rarg2, Address(rsp, wordSize)); |
76 __ movptr(c_rarg2, Address(rsp, wordSize)); |
77 break; |
77 break; |
78 case 2: |
78 case 2: |
79 __ movq(c_rarg3, Address(rsp, 2 * wordSize)); |
79 __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); |
80 break; |
80 break; |
81 default: |
81 default: |
82 break; |
82 break; |
83 } |
83 } |
84 |
84 |
153 } |
153 } |
154 |
154 |
155 // Now handle integrals. Only do c_rarg1 if not static. |
155 // Now handle integrals. Only do c_rarg1 if not static. |
156 __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); |
156 __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); |
157 __ testl(c_rarg3, JVM_ACC_STATIC); |
157 __ testl(c_rarg3, JVM_ACC_STATIC); |
158 __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); |
158 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); |
159 |
159 |
160 __ movq(c_rarg2, Address(rsp, wordSize)); |
160 __ movptr(c_rarg2, Address(rsp, wordSize)); |
161 __ movq(c_rarg3, Address(rsp, 2 * wordSize)); |
161 __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); |
162 __ movq(c_rarg4, Address(rsp, 3 * wordSize)); |
162 __ movptr(c_rarg4, Address(rsp, 3 * wordSize)); |
163 __ movq(c_rarg5, Address(rsp, 4 * wordSize)); |
163 __ movptr(c_rarg5, Address(rsp, 4 * wordSize)); |
164 |
164 |
165 // restore rsp |
165 // restore rsp |
166 __ addq(rsp, 14 * wordSize); |
166 __ addptr(rsp, 14 * wordSize); |
167 |
167 |
168 __ ret(0); |
168 __ ret(0); |
169 |
169 |
170 return entry; |
170 return entry; |
171 } |
171 } |
216 // JDK version is only determined when universe2_init() is called. |
220 // JDK version is only determined when universe2_init() is called. |
217 |
221 |
218 // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are |
222 // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are |
219 // java methods. Interpreter::method_kind(...) will select |
223 // java methods. Interpreter::method_kind(...) will select |
220 // this entry point for the corresponding methods in JDK 1.3. |
224 // this entry point for the corresponding methods in JDK 1.3. |
221 __ sqrtsd(xmm0, Address(rsp, wordSize)); |
225 // get argument |
222 |
226 |
223 __ popq(rax); |
227 if (kind == Interpreter::java_lang_math_sqrt) { |
224 __ movq(rsp, r13); |
228 __ sqrtsd(xmm0, Address(rsp, wordSize)); |
|
229 } else { |
|
230 __ fld_d(Address(rsp, wordSize)); |
|
231 switch (kind) { |
|
232 case Interpreter::java_lang_math_sin : |
|
233 __ trigfunc('s'); |
|
234 break; |
|
235 case Interpreter::java_lang_math_cos : |
|
236 __ trigfunc('c'); |
|
237 break; |
|
238 case Interpreter::java_lang_math_tan : |
|
239 __ trigfunc('t'); |
|
240 break; |
|
241 case Interpreter::java_lang_math_abs: |
|
242 __ fabs(); |
|
243 break; |
|
244 case Interpreter::java_lang_math_log: |
|
245 __ flog(); |
|
246 break; |
|
247 case Interpreter::java_lang_math_log10: |
|
248 __ flog10(); |
|
249 break; |
|
250 default : |
|
251 ShouldNotReachHere(); |
|
252 } |
|
253 |
|
254 // return double result in xmm0 for interpreter and compilers. |
|
255 __ subptr(rsp, 2*wordSize); |
|
256 // Round to 64bit precision |
|
257 __ fstp_d(Address(rsp, 0)); |
|
258 __ movdbl(xmm0, Address(rsp, 0)); |
|
259 __ addptr(rsp, 2*wordSize); |
|
260 } |
|
261 |
|
262 |
|
263 __ pop(rax); |
|
264 __ mov(rsp, r13); |
225 __ jmp(rax); |
265 __ jmp(rax); |
226 |
266 |
227 return entry_point; |
267 return entry_point; |
228 } |
268 } |
229 |
269 |
274 |
314 |
275 // do nothing for empty methods (do not even increment invocation counter) |
315 // do nothing for empty methods (do not even increment invocation counter) |
276 // Code: _return |
316 // Code: _return |
277 // _return |
317 // _return |
278 // return w/o popping parameters |
318 // return w/o popping parameters |
279 __ popq(rax); |
319 __ pop(rax); |
280 __ movq(rsp, r13); |
320 __ mov(rsp, r13); |
281 __ jmp(rax); |
321 __ jmp(rax); |
282 |
322 |
283 __ bind(slow_path); |
323 __ bind(slow_path); |
284 (void) generate_normal_entry(false); |
324 (void) generate_normal_entry(false); |
285 return entry_point; |
325 return entry_point; |
286 |
326 |
287 } |
|
288 |
|
289 // Call an accessor method (assuming it is resolved, otherwise drop |
|
290 // into vanilla (slow path) entry |
|
291 address InterpreterGenerator::generate_accessor_entry(void) { |
|
292 // rbx: methodOop |
|
293 |
|
294 // r13: senderSP must preserver for slow path, set SP to it on fast path |
|
295 |
|
296 address entry_point = __ pc(); |
|
297 Label xreturn_path; |
|
298 |
|
299 // do fastpath for resolved accessor methods |
|
300 if (UseFastAccessorMethods) { |
|
301 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites |
|
302 // thereof; parameter size = 1 |
|
303 // Note: We can only use this code if the getfield has been resolved |
|
304 // and if we don't have a null-pointer exception => check for |
|
305 // these conditions first and use slow path if necessary. |
|
306 Label slow_path; |
|
307 // If we need a safepoint check, generate full interpreter entry. |
|
308 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
|
309 SafepointSynchronize::_not_synchronized); |
|
310 |
|
311 __ jcc(Assembler::notEqual, slow_path); |
|
312 // rbx: method |
|
313 __ movq(rax, Address(rsp, wordSize)); |
|
314 |
|
315 // check if local 0 != NULL and read field |
|
316 __ testq(rax, rax); |
|
317 __ jcc(Assembler::zero, slow_path); |
|
318 |
|
319 __ movq(rdi, Address(rbx, methodOopDesc::constants_offset())); |
|
320 // read first instruction word and extract bytecode @ 1 and index @ 2 |
|
321 __ movq(rdx, Address(rbx, methodOopDesc::const_offset())); |
|
322 __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); |
|
323 // Shift codes right to get the index on the right. |
|
324 // The bytecode fetched looks like <index><0xb4><0x2a> |
|
325 __ shrl(rdx, 2 * BitsPerByte); |
|
326 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); |
|
327 __ movq(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); |
|
328 |
|
329 // rax: local 0 |
|
330 // rbx: method |
|
331 // rdx: constant pool cache index |
|
332 // rdi: constant pool cache |
|
333 |
|
334 // check if getfield has been resolved and read constant pool cache entry |
|
335 // check the validity of the cache entry by testing whether _indices field |
|
336 // contains Bytecode::_getfield in b1 byte. |
|
337 assert(in_words(ConstantPoolCacheEntry::size()) == 4, |
|
338 "adjust shift below"); |
|
339 __ movl(rcx, |
|
340 Address(rdi, |
|
341 rdx, |
|
342 Address::times_8, |
|
343 constantPoolCacheOopDesc::base_offset() + |
|
344 ConstantPoolCacheEntry::indices_offset())); |
|
345 __ shrl(rcx, 2 * BitsPerByte); |
|
346 __ andl(rcx, 0xFF); |
|
347 __ cmpl(rcx, Bytecodes::_getfield); |
|
348 __ jcc(Assembler::notEqual, slow_path); |
|
349 |
|
350 // Note: constant pool entry is not valid before bytecode is resolved |
|
351 __ movq(rcx, |
|
352 Address(rdi, |
|
353 rdx, |
|
354 Address::times_8, |
|
355 constantPoolCacheOopDesc::base_offset() + |
|
356 ConstantPoolCacheEntry::f2_offset())); |
|
357 // edx: flags |
|
358 __ movl(rdx, |
|
359 Address(rdi, |
|
360 rdx, |
|
361 Address::times_8, |
|
362 constantPoolCacheOopDesc::base_offset() + |
|
363 ConstantPoolCacheEntry::flags_offset())); |
|
364 |
|
365 Label notObj, notInt, notByte, notShort; |
|
366 const Address field_address(rax, rcx, Address::times_1); |
|
367 |
|
368 // Need to differentiate between igetfield, agetfield, bgetfield etc. |
|
369 // because they are different sizes. |
|
370 // Use the type from the constant pool cache |
|
371 __ shrl(rdx, ConstantPoolCacheEntry::tosBits); |
|
372 // Make sure we don't need to mask edx for tosBits after the above shift |
|
373 ConstantPoolCacheEntry::verify_tosBits(); |
|
374 |
|
375 __ cmpl(rdx, atos); |
|
376 __ jcc(Assembler::notEqual, notObj); |
|
377 // atos |
|
378 __ load_heap_oop(rax, field_address); |
|
379 __ jmp(xreturn_path); |
|
380 |
|
381 __ bind(notObj); |
|
382 __ cmpl(rdx, itos); |
|
383 __ jcc(Assembler::notEqual, notInt); |
|
384 // itos |
|
385 __ movl(rax, field_address); |
|
386 __ jmp(xreturn_path); |
|
387 |
|
388 __ bind(notInt); |
|
389 __ cmpl(rdx, btos); |
|
390 __ jcc(Assembler::notEqual, notByte); |
|
391 // btos |
|
392 __ load_signed_byte(rax, field_address); |
|
393 __ jmp(xreturn_path); |
|
394 |
|
395 __ bind(notByte); |
|
396 __ cmpl(rdx, stos); |
|
397 __ jcc(Assembler::notEqual, notShort); |
|
398 // stos |
|
399 __ load_signed_word(rax, field_address); |
|
400 __ jmp(xreturn_path); |
|
401 |
|
402 __ bind(notShort); |
|
403 #ifdef ASSERT |
|
404 Label okay; |
|
405 __ cmpl(rdx, ctos); |
|
406 __ jcc(Assembler::equal, okay); |
|
407 __ stop("what type is this?"); |
|
408 __ bind(okay); |
|
409 #endif |
|
410 // ctos |
|
411 __ load_unsigned_word(rax, field_address); |
|
412 |
|
413 __ bind(xreturn_path); |
|
414 |
|
415 // _ireturn/_areturn |
|
416 __ popq(rdi); |
|
417 __ movq(rsp, r13); |
|
418 __ jmp(rdi); |
|
419 __ ret(0); |
|
420 |
|
421 // generate a vanilla interpreter entry as the slow path |
|
422 __ bind(slow_path); |
|
423 (void) generate_normal_entry(false); |
|
424 } else { |
|
425 (void) generate_normal_entry(false); |
|
426 } |
|
427 |
|
428 return entry_point; |
|
429 } |
327 } |
430 |
328 |
431 // This method tells the deoptimizer how big an interpreted frame must be: |
329 // This method tells the deoptimizer how big an interpreted frame must be: |
432 int AbstractInterpreter::size_activation(methodOop method, |
330 int AbstractInterpreter::size_activation(methodOop method, |
433 int tempcount, |
331 int tempcount, |