Changeset 278 for trunk/openjdk/hotspot/src/cpu/x86
- Timestamp:
- Mar 26, 2011, 8:39:20 PM (14 years ago)
- Location:
- trunk/openjdk
- Files:
-
- 99 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/openjdk
- Property svn:ignore
-
old new 1 1 build 2 build-product-release
-
-
Property svn:mergeinfo
set to
/branches/vendor/oracle/openjdk6/b22 merged eligible /branches/vendor/oracle/openjdk6/current merged eligible
- Property svn:ignore
-
trunk/openjdk/hotspot/src/cpu/x86/vm/assembler_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 2252 2252 } 2253 2253 2254 #ifndef _LP64 // no 32bit push/pop on amd64 2254 2255 void Assembler::popl(Address dst) { 2255 2256 // NOTE: this will adjust stack by 8byte on 64bits … … 2259 2260 emit_operand(rax, dst); 2260 2261 } 2262 #endif 2261 2263 2262 2264 void Assembler::prefetch_prefix(Address src) { … … 2429 2431 } 2430 2432 2433 #ifndef _LP64 // no 32bit push/pop on amd64 2431 2434 void Assembler::pushl(Address src) { 2432 2435 // Note this will push 64bit on 64bit … … 2436 2439 emit_operand(rsi, src); 2437 2440 } 2441 #endif 2438 2442 2439 2443 void Assembler::pxor(XMMRegister dst, Address src) { … … 3361 3365 3362 3366 #else // LP64 3367 3368 void Assembler::set_byte_if_not_zero(Register dst) { 3369 int enc = prefix_and_encode(dst->encoding(), true); 3370 emit_byte(0x0F); 3371 emit_byte(0x95); 3372 emit_byte(0xE0 | enc); 3373 } 3363 3374 3364 3375 // 64bit only pieces of the assembler … … 5592 5603 5593 5604 void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) { 5594 andpd(dst, as_Address(src)); 5605 if (reachable(src)) { 5606 andpd(dst, as_Address(src)); 5607 } else { 5608 lea(rscratch1, src); 5609 andpd(dst, Address(rscratch1, 0)); 5610 } 5595 5611 } 5596 5612 … … 6079 6095 6080 6096 void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) { 6081 comisd(dst, as_Address(src)); 6097 if (reachable(src)) { 6098 comisd(dst, as_Address(src)); 6099 } else { 6100 lea(rscratch1, src); 6101 comisd(dst, Address(rscratch1, 0)); 6102 } 6082 6103 } 6083 6104 6084 6105 void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) { 6085 comiss(dst, as_Address(src)); 6106 if (reachable(src)) { 6107 comiss(dst, as_Address(src)); 6108 } else { 6109 lea(rscratch1, src); 6110 comiss(dst, Address(rscratch1, 0)); 6111 } 6086 6112 } 6087 6113 … … 6467 6493 6468 6494 void MacroAssembler::load_sized_value(Register dst, Address src, 6469 int size_in_bytes, bool is_signed) {6470 switch (size_in_bytes ^ (is_signed ? -1 : 0)) {6495 size_t size_in_bytes, bool is_signed) { 6496 switch (size_in_bytes) { 6471 6497 #ifndef _LP64 6472 6498 // For case 8, caller is responsible for manually loading 6473 6499 // the second word into another register. 6474 case ~8: // fall through: 6475 case 8: movl( dst, src ); break; 6500 case 8: movl(dst, src); break; 6476 6501 #else 6477 case ~8: // fall through: 6478 case 8: movq( dst, src ); break; 6502 case 8: movq(dst, src); break; 6479 6503 #endif 6480 case ~4: // fall through: 6481 case 4: movl( dst, src ); break; 6482 case ~2: load_signed_short( dst, src ); break; 6483 case 2: load_unsigned_short( dst, src ); break; 6484 case ~1: load_signed_byte( dst, src ); break; 6485 case 1: load_unsigned_byte( dst, src ); break; 6486 default: ShouldNotReachHere(); 6504 case 4: movl(dst, src); break; 6505 case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(dst, src); break; 6506 case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break; 6507 default: ShouldNotReachHere(); 6487 6508 } 6488 6509 } … … 7131 7152 addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); 7132 7153 shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); 7133 mov ptr(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);7154 movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); 7134 7155 // set klass to intArrayKlass 7135 7156 // dubious reloc why not an oop reloc? … … 7548 7569 // Scan RCX words at [RDI] for an occurrence of RAX. 7549 7570 // Set NZ/Z based on last compare. 7571 // Z flag value will not be set by 'repne' if RCX == 0 since 'repne' does 7572 // not change flags (only scas instruction which is repeated sets flags). 7573 // Set Z = 0 (not equal) before 'repne' to indicate that class was not found. 7550 7574 #ifdef _LP64 7551 7575 // This part is tricky, as values in supers array could be 32 or 64 bit wide … … 7553 7577 // the value of rax before repne. Note that rax is dead after the repne. 7554 7578 if (UseCompressedOops) { 7555 encode_heap_oop_not_null(rax); 7579 encode_heap_oop_not_null(rax); // Changes flags. 7556 7580 // The superclass is never null; it would be a basic system error if a null 7557 7581 // pointer were to sneak in here. Note that we have already loaded the 7558 7582 // Klass::super_check_offset from the super_klass in the fast path, 7559 7583 // so if there is a null in that register, we are already in the afterlife. 7584 testl(rax,rax); // Set Z = 0 7560 7585 repne_scanl(); 7561 7586 } else 7562 7587 #endif // _LP64 7588 { 7589 testptr(rax,rax); // Set Z = 0 7563 7590 repne_scan(); 7564 7591 } 7565 7592 // Unspill the temp. registers: 7566 7593 if (pushed_rdi) pop(rdi); … … 7623 7650 char* b = new char[strlen(s) + 50]; 7624 7651 sprintf(b, "verify_oop: %s: %s", reg->name(), s); 7652 #ifdef _LP64 7653 push(rscratch1); // save r10, trashed by movptr() 7654 #endif 7625 7655 push(rax); // save rax, 7626 7656 push(reg); // pass register argument … … 7633 7663 movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); 7634 7664 call(rax); 7665 // Caller pops the arguments (oop, message) and restores rax, r10 7635 7666 } 7636 7667 … … 7648 7679 #ifdef ASSERT 7649 7680 Label L; 7650 test l(tmp, tmp);7681 testptr(tmp, tmp); 7651 7682 jccb(Assembler::notZero, L); 7652 7683 hlt(); … … 7681 7712 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, 7682 7713 Register temp_reg) { 7714 assert_different_registers(vmslots_reg, mh_reg, temp_reg); 7683 7715 if (UseCompressedOops) unimplemented(); // field accesses must decode 7684 7716 // load mh.type.form.vmslots … … 7719 7751 int extra_slot_offset) { 7720 7752 // cf. TemplateTable::prepare_invoke(), if (load_receiver). 7721 int stackElementSize = Interpreter::stackElementSize ();7753 int stackElementSize = Interpreter::stackElementSize; 7722 7754 int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0); 7723 7755 #ifdef ASSERT … … 7746 7778 sprintf(b, "verify_oop_addr: %s", s); 7747 7779 7780 #ifdef _LP64 7781 push(rscratch1); // save r10, trashed by movptr() 7782 #endif 7748 7783 push(rax); // save rax, 7749 7784 // addr may contain rsp so we will have to adjust it based on the push … … 7768 7803 movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); 7769 7804 call(rax); 7770 // Caller pops the arguments and restores rax, from the stack7805 // Caller pops the arguments (addr, message) and restores rax, r10. 7771 7806 } 7772 7807 … … 7950 7985 case 3: return "empty"; 7951 7986 } 7952 ShouldNotReachHere() 7987 ShouldNotReachHere(); 7953 7988 return NULL; 7954 7989 } … … 8164 8199 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); 8165 8200 if (Universe::narrow_oop_shift() != 0) { 8166 assert(Address::times_8 == LogMinObjAlignmentInBytes && 8167 Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong"); 8168 movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 8201 assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); 8202 if (LogMinObjAlignmentInBytes == Address::times_8) { 8203 movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 8204 } else { 8205 // OK to use shift since we don't need to preserve flags. 8206 shlq(dst, LogMinObjAlignmentInBytes); 8207 movq(dst, Address(r12_heapbase, dst, Address::times_1, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 8208 } 8169 8209 } else { 8170 8210 movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); … … 8224 8264 } 8225 8265 8266 #ifdef ASSERT 8267 void MacroAssembler::verify_heapbase(const char* msg) { 8268 assert (UseCompressedOops, "should be compressed"); 8269 assert (Universe::heap() != NULL, "java heap should be initialized"); 8270 if (CheckCompressedOops) { 8271 Label ok; 8272 push(rscratch1); // cmpptr trashes rscratch1 8273 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); 8274 jcc(Assembler::equal, ok); 8275 stop(msg); 8276 bind(ok); 8277 pop(rscratch1); 8278 } 8279 } 8280 #endif 8281 8226 8282 // Algorithm must match oop.inline.hpp encode_heap_oop. 8227 8283 void MacroAssembler::encode_heap_oop(Register r) { 8228 assert (UseCompressedOops, "should be compressed"); 8229 assert (Universe::heap() != NULL, "java heap should be initialized"); 8284 #ifdef ASSERT 8285 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?"); 8286 #endif 8287 verify_oop(r, "broken oop in encode_heap_oop"); 8230 8288 if (Universe::narrow_oop_base() == NULL) { 8231 verify_oop(r, "broken oop in encode_heap_oop");8232 8289 if (Universe::narrow_oop_shift() != 0) { 8233 8290 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); … … 8236 8293 return; 8237 8294 } 8238 #ifdef ASSERT8239 if (CheckCompressedOops) {8240 Label ok;8241 push(rscratch1); // cmpptr trashes rscratch18242 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));8243 jcc(Assembler::equal, ok);8244 stop("MacroAssembler::encode_heap_oop: heap base corrupted?");8245 bind(ok);8246 pop(rscratch1);8247 }8248 #endif8249 verify_oop(r, "broken oop in encode_heap_oop");8250 8295 testq(r, r); 8251 8296 cmovq(Assembler::equal, r, r12_heapbase); … … 8255 8300 8256 8301 void MacroAssembler::encode_heap_oop_not_null(Register r) { 8257 assert (UseCompressedOops, "should be compressed");8258 assert (Universe::heap() != NULL, "java heap should be initialized");8259 8302 #ifdef ASSERT 8303 verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?"); 8260 8304 if (CheckCompressedOops) { 8261 8305 Label ok; … … 8277 8321 8278 8322 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { 8279 assert (UseCompressedOops, "should be compressed");8280 assert (Universe::heap() != NULL, "java heap should be initialized");8281 8323 #ifdef ASSERT 8324 verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?"); 8282 8325 if (CheckCompressedOops) { 8283 8326 Label ok; … … 8302 8345 8303 8346 void MacroAssembler::decode_heap_oop(Register r) { 8304 assert (UseCompressedOops, "should be compressed"); 8305 assert (Universe::heap() != NULL, "java heap should be initialized"); 8347 #ifdef ASSERT 8348 verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?"); 8349 #endif 8306 8350 if (Universe::narrow_oop_base() == NULL) { 8307 8351 if (Universe::narrow_oop_shift() != 0) { … … 8309 8353 shlq(r, LogMinObjAlignmentInBytes); 8310 8354 } 8311 verify_oop(r, "broken oop in decode_heap_oop"); 8312 return; 8313 } 8314 #ifdef ASSERT 8315 if (CheckCompressedOops) { 8316 Label ok; 8317 push(rscratch1); 8318 cmpptr(r12_heapbase, 8319 ExternalAddress((address)Universe::narrow_oop_base_addr())); 8320 jcc(Assembler::equal, ok); 8321 stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); 8322 bind(ok); 8323 pop(rscratch1); 8324 } 8325 #endif 8326 8327 Label done; 8328 shlq(r, LogMinObjAlignmentInBytes); 8329 jccb(Assembler::equal, done); 8330 addq(r, r12_heapbase); 8331 #if 0 8332 // alternate decoding probably a wash. 8333 testq(r, r); 8334 jccb(Assembler::equal, done); 8335 leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); 8336 #endif 8337 bind(done); 8355 } else { 8356 Label done; 8357 shlq(r, LogMinObjAlignmentInBytes); 8358 jccb(Assembler::equal, done); 8359 addq(r, r12_heapbase); 8360 bind(done); 8361 } 8338 8362 verify_oop(r, "broken oop in decode_heap_oop"); 8339 8363 } 8340 8364 8341 8365 void MacroAssembler::decode_heap_oop_not_null(Register r) { 8366 // Note: it will change flags 8342 8367 assert (UseCompressedOops, "should only be used for compressed headers"); 8343 8368 assert (Universe::heap() != NULL, "java heap should be initialized"); … … 8346 8371 // Also do not verify_oop as this is called by verify_oop. 8347 8372 if (Universe::narrow_oop_shift() != 0) { 8348 assert (Address::times_8 == LogMinObjAlignmentInBytes && 8349 Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong"); 8350 // Don't use Shift since it modifies flags. 8351 leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); 8373 assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); 8374 shlq(r, LogMinObjAlignmentInBytes); 8375 if (Universe::narrow_oop_base() != NULL) { 8376 addq(r, r12_heapbase); 8377 } 8352 8378 } else { 8353 8379 assert (Universe::narrow_oop_base() == NULL, "sanity"); … … 8356 8382 8357 8383 void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { 8384 // Note: it will change flags 8358 8385 assert (UseCompressedOops, "should only be used for compressed headers"); 8359 8386 assert (Universe::heap() != NULL, "java heap should be initialized"); … … 8362 8389 // Also do not verify_oop as this is called by verify_oop. 8363 8390 if (Universe::narrow_oop_shift() != 0) { 8364 assert (Address::times_8 == LogMinObjAlignmentInBytes && 8365 Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong"); 8366 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); 8367 } else if (dst != src) { 8391 assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); 8392 if (LogMinObjAlignmentInBytes == Address::times_8) { 8393 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); 8394 } else { 8395 if (dst != src) { 8396 movq(dst, src); 8397 } 8398 shlq(dst, LogMinObjAlignmentInBytes); 8399 if (Universe::narrow_oop_base() != NULL) { 8400 addq(dst, r12_heapbase); 8401 } 8402 } 8403 } else { 8368 8404 assert (Universe::narrow_oop_base() == NULL, "sanity"); 8369 movq(dst, src); 8405 if (dst != src) { 8406 movq(dst, src); 8407 } 8370 8408 } 8371 8409 } … … 8413 8451 } 8414 8452 #endif // _LP64 8453 8454 // IndexOf substring. 8455 void MacroAssembler::string_indexof(Register str1, Register str2, 8456 Register cnt1, Register cnt2, Register result, 8457 XMMRegister vec, Register tmp) { 8458 assert(UseSSE42Intrinsics, "SSE4.2 is required"); 8459 8460 Label RELOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR, 8461 SCAN_SUBSTR, RET_NOT_FOUND, CLEANUP; 8462 8463 push(str1); // string addr 8464 push(str2); // substr addr 8465 push(cnt2); // substr count 8466 jmpb(PREP_FOR_SCAN); 8467 8468 // Substr count saved at sp 8469 // Substr saved at sp+1*wordSize 8470 // String saved at sp+2*wordSize 8471 8472 // Reload substr for rescan 8473 bind(RELOAD_SUBSTR); 8474 movl(cnt2, Address(rsp, 0)); 8475 movptr(str2, Address(rsp, wordSize)); 8476 // We came here after the beginninig of the substring was 8477 // matched but the rest of it was not so we need to search 8478 // again. Start from the next element after the previous match. 8479 subptr(str1, result); // Restore counter 8480 shrl(str1, 1); 8481 addl(cnt1, str1); 8482 decrementl(cnt1); 8483 lea(str1, Address(result, 2)); // Reload string 8484 8485 // Load substr 8486 bind(PREP_FOR_SCAN); 8487 movdqu(vec, Address(str2, 0)); 8488 addl(cnt1, 8); // prime the loop 8489 subptr(str1, 16); 8490 8491 // Scan string for substr in 16-byte vectors 8492 bind(SCAN_TO_SUBSTR); 8493 subl(cnt1, 8); 8494 addptr(str1, 16); 8495 8496 // pcmpestri 8497 // inputs: 8498 // xmm - substring 8499 // rax - substring length (elements count) 8500 // mem - scaned string 8501 // rdx - string length (elements count) 8502 // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts) 8503 // outputs: 8504 // rcx - matched index in string 8505 assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri"); 8506 8507 pcmpestri(vec, Address(str1, 0), 0x0d); 8508 jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0 8509 jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0 8510 8511 // Fallthrough: found a potential substr 8512 8513 // Make sure string is still long enough 8514 subl(cnt1, tmp); 8515 cmpl(cnt1, cnt2); 8516 jccb(Assembler::negative, RET_NOT_FOUND); 8517 // Compute start addr of substr 8518 lea(str1, Address(str1, tmp, Address::times_2)); 8519 movptr(result, str1); // save 8520 8521 // Compare potential substr 8522 addl(cnt1, 8); // prime the loop 8523 addl(cnt2, 8); 8524 subptr(str1, 16); 8525 subptr(str2, 16); 8526 8527 // Scan 16-byte vectors of string and substr 8528 bind(SCAN_SUBSTR); 8529 subl(cnt1, 8); 8530 subl(cnt2, 8); 8531 addptr(str1, 16); 8532 addptr(str2, 16); 8533 movdqu(vec, Address(str2, 0)); 8534 pcmpestri(vec, Address(str1, 0), 0x0d); 8535 jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0 8536 jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0 8537 8538 // Compute substr offset 8539 subptr(result, Address(rsp, 2*wordSize)); 8540 shrl(result, 1); // index 8541 jmpb(CLEANUP); 8542 8543 bind(RET_NOT_FOUND); 8544 movl(result, -1); 8545 8546 bind(CLEANUP); 8547 addptr(rsp, 3*wordSize); 8548 } 8549 8550 // Compare strings. 8551 void MacroAssembler::string_compare(Register str1, Register str2, 8552 Register cnt1, Register cnt2, Register result, 8553 XMMRegister vec1, XMMRegister vec2) { 8554 Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL; 8555 8556 // Compute the minimum of the string lengths and the 8557 // difference of the string lengths (stack). 8558 // Do the conditional move stuff 8559 movl(result, cnt1); 8560 subl(cnt1, cnt2); 8561 push(cnt1); 8562 if (VM_Version::supports_cmov()) { 8563 cmovl(Assembler::lessEqual, cnt2, result); 8564 } else { 8565 Label GT_LABEL; 8566 jccb(Assembler::greater, GT_LABEL); 8567 movl(cnt2, result); 8568 bind(GT_LABEL); 8569 } 8570 8571 // Is the minimum length zero? 8572 testl(cnt2, cnt2); 8573 jcc(Assembler::zero, LENGTH_DIFF_LABEL); 8574 8575 // Load first characters 8576 load_unsigned_short(result, Address(str1, 0)); 8577 load_unsigned_short(cnt1, Address(str2, 0)); 8578 8579 // Compare first characters 8580 subl(result, cnt1); 8581 jcc(Assembler::notZero, POP_LABEL); 8582 decrementl(cnt2); 8583 jcc(Assembler::zero, LENGTH_DIFF_LABEL); 8584 8585 { 8586 // Check after comparing first character to see if strings are equivalent 8587 Label LSkip2; 8588 // Check if the strings start at same location 8589 cmpptr(str1, str2); 8590 jccb(Assembler::notEqual, LSkip2); 8591 8592 // Check if the length difference is zero (from stack) 8593 cmpl(Address(rsp, 0), 0x0); 8594 jcc(Assembler::equal, LENGTH_DIFF_LABEL); 8595 8596 // Strings might not be equivalent 8597 bind(LSkip2); 8598 } 8599 8600 // Advance to next character 8601 addptr(str1, 2); 8602 addptr(str2, 2); 8603 8604 if (UseSSE42Intrinsics) { 8605 // With SSE4.2, use double quad vector compare 8606 Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL; 8607 // Setup to compare 16-byte vectors 8608 movl(cnt1, cnt2); 8609 andl(cnt2, 0xfffffff8); // cnt2 holds the vector count 8610 andl(cnt1, 0x00000007); // cnt1 holds the tail count 8611 testl(cnt2, cnt2); 8612 jccb(Assembler::zero, COMPARE_TAIL); 8613 8614 lea(str2, Address(str2, cnt2, Address::times_2)); 8615 lea(str1, Address(str1, cnt2, Address::times_2)); 8616 negptr(cnt2); 8617 8618 bind(COMPARE_VECTORS); 8619 movdqu(vec1, Address(str1, cnt2, Address::times_2)); 8620 movdqu(vec2, Address(str2, cnt2, Address::times_2)); 8621 pxor(vec1, vec2); 8622 ptest(vec1, vec1); 8623 jccb(Assembler::notZero, VECTOR_NOT_EQUAL); 8624 addptr(cnt2, 8); 8625 jcc(Assembler::notZero, COMPARE_VECTORS); 8626 jmpb(COMPARE_TAIL); 8627 8628 // Mismatched characters in the vectors 8629 bind(VECTOR_NOT_EQUAL); 8630 lea(str1, Address(str1, cnt2, Address::times_2)); 8631 lea(str2, Address(str2, cnt2, Address::times_2)); 8632 movl(cnt1, 8); 8633 8634 // Compare tail (< 8 chars), or rescan last vectors to 8635 // find 1st mismatched characters 8636 bind(COMPARE_TAIL); 8637 testl(cnt1, cnt1); 8638 jccb(Assembler::zero, LENGTH_DIFF_LABEL); 8639 movl(cnt2, cnt1); 8640 // Fallthru to tail compare 8641 } 8642 8643 // Shift str2 and str1 to the end of the arrays, negate min 8644 lea(str1, Address(str1, cnt2, Address::times_2, 0)); 8645 lea(str2, Address(str2, cnt2, Address::times_2, 0)); 8646 negptr(cnt2); 8647 8648 // Compare the rest of the characters 8649 bind(WHILE_HEAD_LABEL); 8650 load_unsigned_short(result, Address(str1, cnt2, Address::times_2, 0)); 8651 load_unsigned_short(cnt1, Address(str2, cnt2, Address::times_2, 0)); 8652 subl(result, cnt1); 8653 jccb(Assembler::notZero, POP_LABEL); 8654 increment(cnt2); 8655 jcc(Assembler::notZero, WHILE_HEAD_LABEL); 8656 8657 // Strings are equal up to min length. Return the length difference. 8658 bind(LENGTH_DIFF_LABEL); 8659 pop(result); 8660 jmpb(DONE_LABEL); 8661 8662 // Discard the stored length difference 8663 bind(POP_LABEL); 8664 addptr(rsp, wordSize); 8665 8666 // That's it 8667 bind(DONE_LABEL); 8668 } 8669 8670 // Compare char[] arrays aligned to 4 bytes or substrings. 8671 void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2, 8672 Register limit, Register result, Register chr, 8673 XMMRegister vec1, XMMRegister vec2) { 8674 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR; 8675 8676 int length_offset = arrayOopDesc::length_offset_in_bytes(); 8677 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 8678 8679 // Check the input args 8680 cmpptr(ary1, ary2); 8681 jcc(Assembler::equal, TRUE_LABEL); 8682 8683 if (is_array_equ) { 8684 // Need additional checks for arrays_equals. 8685 testptr(ary1, ary1); 8686 jcc(Assembler::zero, FALSE_LABEL); 8687 testptr(ary2, ary2); 8688 jcc(Assembler::zero, FALSE_LABEL); 8689 8690 // Check the lengths 8691 movl(limit, Address(ary1, length_offset)); 8692 cmpl(limit, Address(ary2, length_offset)); 8693 jcc(Assembler::notEqual, FALSE_LABEL); 8694 } 8695 8696 // count == 0 8697 testl(limit, limit); 8698 jcc(Assembler::zero, TRUE_LABEL); 8699 8700 if (is_array_equ) { 8701 // Load array address 8702 lea(ary1, Address(ary1, base_offset)); 8703 lea(ary2, Address(ary2, base_offset)); 8704 } 8705 8706 shll(limit, 1); // byte count != 0 8707 movl(result, limit); // copy 8708 8709 if (UseSSE42Intrinsics) { 8710 // With SSE4.2, use double quad vector compare 8711 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; 8712 // Compare 16-byte vectors 8713 andl(result, 0x0000000e); // tail count (in bytes) 8714 andl(limit, 0xfffffff0); // vector count (in bytes) 8715 jccb(Assembler::zero, COMPARE_TAIL); 8716 8717 lea(ary1, Address(ary1, limit, Address::times_1)); 8718 lea(ary2, Address(ary2, limit, Address::times_1)); 8719 negptr(limit); 8720 8721 bind(COMPARE_WIDE_VECTORS); 8722 movdqu(vec1, Address(ary1, limit, Address::times_1)); 8723 movdqu(vec2, Address(ary2, limit, Address::times_1)); 8724 pxor(vec1, vec2); 8725 ptest(vec1, vec1); 8726 jccb(Assembler::notZero, FALSE_LABEL); 8727 addptr(limit, 16); 8728 jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); 8729 8730 bind(COMPARE_TAIL); // limit is zero 8731 movl(limit, result); 8732 // Fallthru to tail compare 8733 } 8734 8735 // Compare 4-byte vectors 8736 andl(limit, 0xfffffffc); // vector count (in bytes) 8737 jccb(Assembler::zero, COMPARE_CHAR); 8738 8739 lea(ary1, Address(ary1, limit, Address::times_1)); 8740 lea(ary2, Address(ary2, limit, Address::times_1)); 8741 negptr(limit); 8742 8743 bind(COMPARE_VECTORS); 8744 movl(chr, Address(ary1, limit, Address::times_1)); 8745 cmpl(chr, Address(ary2, limit, Address::times_1)); 8746 jccb(Assembler::notEqual, FALSE_LABEL); 8747 addptr(limit, 4); 8748 jcc(Assembler::notZero, COMPARE_VECTORS); 8749 8750 // Compare trailing char (final 2 bytes), if any 8751 bind(COMPARE_CHAR); 8752 testl(result, 0x2); // tail char 8753 jccb(Assembler::zero, TRUE_LABEL); 8754 load_unsigned_short(chr, Address(ary1, 0)); 8755 load_unsigned_short(limit, Address(ary2, 0)); 8756 cmpl(chr, limit); 8757 jccb(Assembler::notEqual, FALSE_LABEL); 8758 8759 bind(TRUE_LABEL); 8760 movl(result, 1); // return true 8761 jmpb(DONE); 8762 8763 bind(FALSE_LABEL); 8764 xorl(result, result); // return false 8765 8766 // That's it 8767 bind(DONE); 8768 } 8769 8770 #ifdef PRODUCT 8771 #define BLOCK_COMMENT(str) /* nothing */ 8772 #else 8773 #define BLOCK_COMMENT(str) block_comment(str) 8774 #endif 8775 8776 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 8777 void MacroAssembler::generate_fill(BasicType t, bool aligned, 8778 Register to, Register value, Register count, 8779 Register rtmp, XMMRegister xtmp) { 8780 assert_different_registers(to, value, count, rtmp); 8781 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; 8782 Label L_fill_2_bytes, L_fill_4_bytes; 8783 8784 int shift = -1; 8785 switch (t) { 8786 case T_BYTE: 8787 shift = 2; 8788 break; 8789 case T_SHORT: 8790 shift = 1; 8791 break; 8792 case T_INT: 8793 shift = 0; 8794 break; 8795 default: ShouldNotReachHere(); 8796 } 8797 8798 if (t == T_BYTE) { 8799 andl(value, 0xff); 8800 movl(rtmp, value); 8801 shll(rtmp, 8); 8802 orl(value, rtmp); 8803 } 8804 if (t == T_SHORT) { 8805 andl(value, 0xffff); 8806 } 8807 if (t == T_BYTE || t == T_SHORT) { 8808 movl(rtmp, value); 8809 shll(rtmp, 16); 8810 orl(value, rtmp); 8811 } 8812 8813 cmpl(count, 2<<shift); // Short arrays (< 8 bytes) fill by element 8814 jcc(Assembler::below, L_fill_4_bytes); // use unsigned cmp 8815 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) { 8816 // align source address at 4 bytes address boundary 8817 if (t == T_BYTE) { 8818 // One byte misalignment happens only for byte arrays 8819 testptr(to, 1); 8820 jccb(Assembler::zero, L_skip_align1); 8821 movb(Address(to, 0), value); 8822 increment(to); 8823 decrement(count); 8824 BIND(L_skip_align1); 8825 } 8826 // Two bytes misalignment happens only for byte and short (char) arrays 8827 testptr(to, 2); 8828 jccb(Assembler::zero, L_skip_align2); 8829 movw(Address(to, 0), value); 8830 addptr(to, 2); 8831 subl(count, 1<<(shift-1)); 8832 BIND(L_skip_align2); 8833 } 8834 if (UseSSE < 2) { 8835 Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes; 8836 // Fill 32-byte chunks 8837 subl(count, 8 << shift); 8838 jcc(Assembler::less, L_check_fill_8_bytes); 8839 align(16); 8840 8841 BIND(L_fill_32_bytes_loop); 8842 8843 for (int i = 0; i < 32; i += 4) { 8844 movl(Address(to, i), value); 8845 } 8846 8847 addptr(to, 32); 8848 subl(count, 8 << shift); 8849 jcc(Assembler::greaterEqual, L_fill_32_bytes_loop); 8850 BIND(L_check_fill_8_bytes); 8851 addl(count, 8 << shift); 8852 jccb(Assembler::zero, L_exit); 8853 jmpb(L_fill_8_bytes); 8854 8855 // 8856 // length is too short, just fill qwords 8857 // 8858 BIND(L_fill_8_bytes_loop); 8859 movl(Address(to, 0), value); 8860 movl(Address(to, 4), value); 8861 addptr(to, 8); 8862 BIND(L_fill_8_bytes); 8863 subl(count, 1 << (shift + 1)); 8864 jcc(Assembler::greaterEqual, L_fill_8_bytes_loop); 8865 // fall through to fill 4 bytes 8866 } else { 8867 Label L_fill_32_bytes; 8868 if (!UseUnalignedLoadStores) { 8869 // align to 8 bytes, we know we are 4 byte aligned to start 8870 testptr(to, 4); 8871 jccb(Assembler::zero, L_fill_32_bytes); 8872 movl(Address(to, 0), value); 8873 addptr(to, 4); 8874 subl(count, 1<<shift); 8875 } 8876 BIND(L_fill_32_bytes); 8877 { 8878 assert( UseSSE >= 2, "supported cpu only" ); 8879 Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes; 8880 // Fill 32-byte chunks 8881 movdl(xtmp, value); 8882 pshufd(xtmp, xtmp, 0); 8883 8884 subl(count, 8 << shift); 8885 jcc(Assembler::less, L_check_fill_8_bytes); 8886 align(16); 8887 8888 BIND(L_fill_32_bytes_loop); 8889 8890 if (UseUnalignedLoadStores) { 8891 movdqu(Address(to, 0), xtmp); 8892 movdqu(Address(to, 16), xtmp); 8893 } else { 8894 movq(Address(to, 0), xtmp); 8895 movq(Address(to, 8), xtmp); 8896 movq(Address(to, 16), xtmp); 8897 movq(Address(to, 24), xtmp); 8898 } 8899 8900 addptr(to, 32); 8901 subl(count, 8 << shift); 8902 jcc(Assembler::greaterEqual, L_fill_32_bytes_loop); 8903 BIND(L_check_fill_8_bytes); 8904 addl(count, 8 << shift); 8905 jccb(Assembler::zero, L_exit); 8906 jmpb(L_fill_8_bytes); 8907 8908 // 8909 // length is too short, just fill qwords 8910 // 8911 BIND(L_fill_8_bytes_loop); 8912 movq(Address(to, 0), xtmp); 8913 addptr(to, 8); 8914 BIND(L_fill_8_bytes); 8915 subl(count, 1 << (shift + 1)); 8916 jcc(Assembler::greaterEqual, L_fill_8_bytes_loop); 8917 } 8918 } 8919 // fill trailing 4 bytes 8920 BIND(L_fill_4_bytes); 8921 testl(count, 1<<shift); 8922 jccb(Assembler::zero, L_fill_2_bytes); 8923 movl(Address(to, 0), value); 8924 if (t == T_BYTE || t == T_SHORT) { 8925 addptr(to, 4); 8926 BIND(L_fill_2_bytes); 8927 // fill trailing 2 bytes 8928 testl(count, 1<<(shift-1)); 8929 jccb(Assembler::zero, L_fill_byte); 8930 movw(Address(to, 0), value); 8931 if (t == T_BYTE) { 8932 addptr(to, 2); 8933 BIND(L_fill_byte); 8934 // fill trailing byte 8935 testl(count, 1); 8936 jccb(Assembler::zero, L_exit); 8937 movb(Address(to, 0), value); 8938 } else { 8939 BIND(L_fill_byte); 8940 } 8941 } else { 8942 BIND(L_fill_2_bytes); 8943 } 8944 BIND(L_exit); 8945 } 8946 #undef BIND 8947 #undef BLOCK_COMMENT 8948 8415 8949 8416 8950 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { -
trunk/openjdk/hotspot/src/cpu/x86/vm/assembler_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 135 135 136 136 #endif // _LP64 137 138 // JSR 292 fixed register usages: 139 REGISTER_DECLARATION(Register, rbp_mh_SP_save, rbp); 137 140 138 141 // Address is an abstraction used to represent a memory location … … 1245 1248 void pcmpestri(XMMRegister xmm1, Address src, int imm8); 1246 1249 1250 #ifndef _LP64 // no 32bit push/pop on amd64 1247 1251 void popl(Address dst); 1252 #endif 1248 1253 1249 1254 #ifdef _LP64 … … 1286 1291 void punpcklbw(XMMRegister dst, XMMRegister src); 1287 1292 1293 #ifndef _LP64 // no 32bit push/pop on amd64 1288 1294 void pushl(Address src); 1295 #endif 1289 1296 1290 1297 void pushq(Address src); … … 1508 1515 1509 1516 // Loading values by size and signed-ness 1510 void load_sized_value(Register dst, Address src, int size_in_bytes, bool is_signed);1517 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed); 1511 1518 1512 1519 // Support for inc/dec with optimal instruction selection depending on value … … 1708 1715 // if heap base register is used - reinit it with the correct value 1709 1716 void reinit_heapbase(); 1717 1718 DEBUG_ONLY(void verify_heapbase(const char* msg);) 1719 1710 1720 #endif // _LP64 1711 1721 … … 2218 2228 void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } 2219 2229 2230 // IndexOf strings. 2231 void string_indexof(Register str1, Register str2, 2232 Register cnt1, Register cnt2, Register result, 2233 XMMRegister vec, Register tmp); 2234 2235 // Compare strings. 2236 void string_compare(Register str1, Register str2, 2237 Register cnt1, Register cnt2, Register result, 2238 XMMRegister vec1, XMMRegister vec2); 2239 2240 // Compare char[] arrays. 2241 void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2, 2242 Register limit, Register result, Register chr, 2243 XMMRegister vec1, XMMRegister vec2); 2244 2245 // Fill primitive arrays 2246 void generate_fill(BasicType t, bool aligned, 2247 Register to, Register value, Register count, 2248 Register rtmp, XMMRegister xtmp); 2220 2249 2221 2250 #undef VIRTUAL -
trunk/openjdk/hotspot/src/cpu/x86/vm/assembler_x86.inline.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp
r2 r278 1 1 /* 2 * Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 237 237 238 238 inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { 239 return op1 << 239 return op1 << op2; 240 240 } 241 241 242 242 inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { 243 return op1 >> op2; // QQ op2 & 0x1f??243 return op1 >> (op2 & 0x1f); 244 244 } 245 245 … … 249 249 250 250 inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { 251 return ((juint) op1) >> op2; // QQ op2 & 0x1f??251 return ((juint) op1) >> (op2 & 0x1f); 252 252 } 253 253 -
trunk/openjdk/hotspot/src/cpu/x86/vm/bytecodes_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/bytecodes_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/bytes_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 374 374 375 375 376 void DeoptimizeStub::emit_code(LIR_Assembler* ce) { 377 __ bind(_entry); 378 __ call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack_with_reexecution())); 379 ce->add_call_info_here(_info); 380 debug_only(__ should_not_reach_here()); 381 } 382 383 376 384 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { 377 385 ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_Defs_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_FpuStackSim_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_FpuStackSim_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 137 137 //-------------------------------------------------------- 138 138 139 void FrameMap::init () {140 if (_init_done) return;139 void FrameMap::initialize() { 140 assert(!_init_done, "once"); 141 141 142 142 assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers"); … … 310 310 311 311 312 // JSR 292 313 LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() { 314 assert(rbp == rbp_mh_SP_save, "must be same register"); 315 return rbp_opr; 316 } 317 318 312 319 bool FrameMap::validate_frame() { 313 320 return true; -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 302 302 { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); 303 303 int monitor_offset = BytesPerWord * method()->max_locals() + 304 (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1); 304 (2 * BytesPerWord) * (number_of_locks - 1); 305 // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in 306 // the OSR buffer using 2 word entries: first the lock and then 307 // the oop. 305 308 for (int i = 0; i < number_of_locks; i++) { 306 int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);309 int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); 307 310 #ifdef ASSERT 308 311 // verify the interpreter's monitor has a non-null object 309 312 { 310 313 Label L; 311 __ cmpptr(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);314 __ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD); 312 315 __ jcc(Assembler::notZero, L); 313 316 __ stop("locked object is NULL"); … … 315 318 } 316 319 #endif 317 __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes()));320 __ movptr(rbx, Address(OSR_buf, slot_offset + 0)); 318 321 __ movptr(frame_map()->address_for_monitor_lock(i), rbx); 319 __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()));322 __ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord)); 320 323 __ movptr(frame_map()->address_for_monitor_object(i), rbx); 321 324 } … … 416 419 417 420 418 voidLIR_Assembler::emit_exception_handler() {421 int LIR_Assembler::emit_exception_handler() { 419 422 // if the last instruction is a call (typically to do a throw which 420 423 // is coming at the end after block reordering) the return address … … 422 425 // failures when searching for the corresponding bci => add a nop 423 426 // (was bug 5/14/1999 - gri) 424 425 427 __ nop(); 426 428 … … 430 432 // not enough space left for the handler 431 433 bailout("exception handler overflow"); 432 return ;433 } 434 #ifdef ASSERT 434 return -1; 435 } 436 435 437 int offset = code_offset(); 436 #endif // ASSERT 437 438 compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset()); 439 440 // if the method does not have an exception handler, then there is 441 // no reason to search for one 442 if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) { 443 // the exception oop and pc are in rax, and rdx 444 // no other registers need to be preserved, so invalidate them 445 __ invalidate_registers(false, true, true, false, true, true); 446 447 // check that there is really an exception 448 __ verify_not_null_oop(rax); 449 450 // search an exception handler (rax: exception oop, rdx: throwing pc) 451 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); 452 453 // if the call returns here, then the exception handler for particular 454 // exception doesn't exist -> unwind activation and forward exception to caller 455 } 456 457 // the exception oop is in rax, 438 439 // the exception oop and pc are in rax, and rdx 458 440 // no other registers need to be preserved, so invalidate them 459 __ invalidate_registers(false, true, true, true, true, true);441 __ invalidate_registers(false, true, true, false, true, true); 460 442 461 443 // check that there is really an exception 462 444 __ verify_not_null_oop(rax); 463 445 464 // unlock the receiver/klass if necessary 465 // rax,: exception 466 ciMethod* method = compilation()->method(); 467 if (method->is_synchronized() && GenerateSynchronizationCode) { 468 monitorexit(FrameMap::rbx_oop_opr, FrameMap::rcx_opr, SYNC_header, 0, rax); 469 } 470 471 // unwind activation and forward exception to caller 472 // rax,: exception 446 // search an exception handler (rax: exception oop, rdx: throwing pc) 447 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); 448 449 __ stop("should not reach here"); 450 451 assert(code_offset() - offset <= exception_handler_size, "overflow"); 452 __ end_a_stub(); 453 454 return offset; 455 } 456 457 458 // Emit the code to remove the frame from the stack in the exception 459 // unwind path. 460 int LIR_Assembler::emit_unwind_handler() { 461 #ifndef PRODUCT 462 if (CommentedAssembly) { 463 _masm->block_comment("Unwind handler"); 464 } 465 #endif 466 467 int offset = code_offset(); 468 469 // Fetch the exception from TLS and clear out exception related thread state 470 __ get_thread(rsi); 471 __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); 472 __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); 473 __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); 474 475 __ bind(_unwind_handler_entry); 476 __ verify_not_null_oop(rax); 477 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { 478 __ mov(rsi, rax); // Preserve the exception 479 } 480 481 // Preform needed unlocking 482 MonitorExitStub* stub = NULL; 483 if (method()->is_synchronized()) { 484 monitor_address(0, FrameMap::rax_opr); 485 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); 486 __ unlock_object(rdi, rbx, rax, *stub->entry()); 487 __ bind(*stub->continuation()); 488 } 489 490 if (compilation()->env()->dtrace_method_probes()) { 491 __ get_thread(rax); 492 __ movptr(Address(rsp, 0), rax); 493 __ movoop(Address(rsp, sizeof(void*)), method()->constant_encoding()); 494 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); 495 } 496 497 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { 498 __ mov(rax, rsi); // Restore the exception 499 } 500 501 // remove the activation and dispatch to the unwind handler 502 __ remove_frame(initial_frame_size_in_bytes()); 473 503 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); 474 504 475 assert(code_offset() - offset <= exception_handler_size, "overflow"); 476 477 __ end_a_stub(); 478 } 479 480 void LIR_Assembler::emit_deopt_handler() { 505 // Emit the slow path assembly 506 if (stub != NULL) { 507 stub->emit_code(this); 508 } 509 510 return offset; 511 } 512 513 514 int LIR_Assembler::emit_deopt_handler() { 481 515 // if the last instruction is a call (typically to do a throw which 482 516 // is coming at the end after block reordering) the return address … … 484 518 // failures when searching for the corresponding bci => add a nop 485 519 // (was bug 5/14/1999 - gri) 486 487 520 __ nop(); 488 521 … … 492 525 // not enough space left for the handler 493 526 bailout("deopt handler overflow"); 494 return ;495 } 496 #ifdef ASSERT 527 return -1; 528 } 529 497 530 int offset = code_offset(); 498 #endif // ASSERT499 500 compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset());501 502 531 InternalAddress here(__ pc()); 532 503 533 __ pushptr(here.addr()); 504 505 534 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 506 535 507 536 assert(code_offset() - offset <= deopt_handler_size, "overflow"); 508 509 537 __ end_a_stub(); 510 538 539 return offset; 511 540 } 512 541 … … 601 630 602 631 // Pop the stack before the safepoint code 603 __ leave();632 __ remove_frame(initial_frame_size_in_bytes()); 604 633 605 634 bool result_is_oop = result->is_valid() ? result->is_oop() : false; … … 656 685 657 686 switch (c->type()) { 658 case T_INT: { 687 case T_INT: 688 case T_ADDRESS: { 659 689 assert(patch_code == lir_patch_none, "no patching handled here"); 660 690 __ movl(dest->as_register(), c->as_jint()); … … 739 769 case T_INT: // fall through 740 770 case T_FLOAT: 771 case T_ADDRESS: 741 772 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); 742 773 break; … … 774 805 case T_INT: // fall through 775 806 case T_FLOAT: 807 case T_ADDRESS: 776 808 __ movl(as_Address(addr), c->as_jint_bits()); 777 809 break; … … 786 818 __ movoop(as_Address(addr, noreg), c->as_jobject()); 787 819 } else { 820 #ifdef _LP64 821 __ movoop(rscratch1, c->as_jobject()); 822 null_check_here = code_offset(); 823 __ movptr(as_Address_lo(addr), rscratch1); 824 #else 788 825 __ movoop(as_Address(addr), c->as_jobject()); 826 #endif 789 827 } 790 828 } … … 1119 1157 __ popptr (frame_map()->address_for_slot(dest->single_stack_ix())); 1120 1158 } else { 1159 #ifndef _LP64 1121 1160 __ pushl(frame_map()->address_for_slot(src ->single_stack_ix())); 1122 1161 __ popl (frame_map()->address_for_slot(dest->single_stack_ix())); 1162 #else 1163 //no pushl on 64bits 1164 __ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix())); 1165 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1); 1166 #endif 1123 1167 } 1124 1168 … … 1203 1247 #endif // _L64 1204 1248 case T_INT: 1205 // %%% could this be a movl? this is safer but longer instruction 1206 __ movl2ptr(dest->as_register(), from_addr); 1249 __ movl(dest->as_register(), from_addr); 1207 1250 break; 1208 1251 … … 1262 1305 __ sarl(dest_reg, 24); 1263 1306 } 1264 // These are unsigned so the zero extension on 64bit is just what we need1265 1307 break; 1266 1308 } … … 1274 1316 __ movw(dest_reg, from_addr); 1275 1317 } 1276 // This is unsigned so the zero extension on 64bit is just what we need1277 // __ movl2ptr(dest_reg, dest_reg);1278 1318 break; 1279 1319 } … … 1288 1328 __ sarl(dest_reg, 16); 1289 1329 } 1290 // Might not be needed in 64bit but certainly doesn't hurt (except for code size)1291 __ movl2ptr(dest_reg, dest_reg);1292 1330 break; 1293 1331 } … … 1639 1677 } else { 1640 1678 #ifdef _LP64 1641 __ movoop(k_RInfo, k-> encoding());1679 __ movoop(k_RInfo, k->constant_encoding()); 1642 1680 #else 1643 1681 k_RInfo = noreg; … … 1662 1700 assert(data->is_BitData(), "need BitData for checkcast"); 1663 1701 Register mdo = klass_RInfo; 1664 __ movoop(mdo, md-> encoding());1702 __ movoop(mdo, md->constant_encoding()); 1665 1703 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); 1666 1704 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); … … 1680 1718 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1681 1719 #else 1682 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k-> encoding());1720 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); 1683 1721 #endif // _LP64 1684 1722 } else { … … 1697 1735 __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); 1698 1736 #else 1699 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k-> encoding());1737 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); 1700 1738 #endif // _LP64 1701 1739 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { … … 1708 1746 __ cmpptr(klass_RInfo, k_RInfo); 1709 1747 #else 1710 __ cmpoop(klass_RInfo, k-> encoding());1748 __ cmpoop(klass_RInfo, k->constant_encoding()); 1711 1749 #endif // _LP64 1712 1750 __ jcc(Assembler::equal, done); … … 1716 1754 __ push(k_RInfo); 1717 1755 #else 1718 __ pushoop(k-> encoding());1756 __ pushoop(k->constant_encoding()); 1719 1757 #endif // _LP64 1720 1758 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); … … 1764 1802 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); 1765 1803 } else { 1766 LP64_ONLY(__ movoop(k_RInfo, k-> encoding()));1804 LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding())); 1767 1805 } 1768 1806 assert(obj != k_RInfo, "must be different"); … … 1775 1813 // not a safepoint as obj null check happens earlier 1776 1814 if (LP64_ONLY(false &&) k->is_loaded()) { 1777 NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k-> encoding()));1815 NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding())); 1778 1816 k_RInfo = noreg; 1779 1817 } else { … … 1792 1830 if (k->is_loaded()) { 1793 1831 // See if we get an immediate positive hit 1794 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k-> encoding());1832 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); 1795 1833 __ jcc(Assembler::equal, one); 1796 1834 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) { 1797 1835 // check for self 1798 __ cmpoop(klass_RInfo, k-> encoding());1836 __ cmpoop(klass_RInfo, k->constant_encoding()); 1799 1837 __ jcc(Assembler::equal, one); 1800 1838 __ push(klass_RInfo); 1801 __ pushoop(k-> encoding());1839 __ pushoop(k->constant_encoding()); 1802 1840 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 1803 1841 __ pop(klass_RInfo); … … 2427 2465 #endif // _LP64 2428 2466 } else { 2467 #ifdef _LP64 2468 Register r_lo; 2469 if (right->type() == T_OBJECT || right->type() == T_ARRAY) { 2470 r_lo = right->as_register(); 2471 } else { 2472 r_lo = right->as_register_lo(); 2473 } 2474 #else 2429 2475 Register r_lo = right->as_register_lo(); 2430 2476 Register r_hi = right->as_register_hi(); 2431 2477 assert(l_lo != r_hi, "overwriting registers"); 2478 #endif 2432 2479 switch (code) { 2433 2480 case lir_logic_and: … … 2703 2750 assert(code == lir_cmp_l2i, "check"); 2704 2751 #ifdef _LP64 2705 Register dest = dst->as_register(); 2706 __ xorptr(dest, dest); 2707 Label high, done; 2708 __ cmpptr(left->as_register_lo(), right->as_register_lo()); 2709 __ jcc(Assembler::equal, done); 2710 __ jcc(Assembler::greater, high); 2711 __ decrement(dest); 2712 __ jmp(done); 2713 __ bind(high); 2714 __ increment(dest); 2715 2716 __ bind(done); 2717 2752 Label done; 2753 Register dest = dst->as_register(); 2754 __ cmpptr(left->as_register_lo(), right->as_register_lo()); 2755 __ movl(dest, -1); 2756 __ jccb(Assembler::less, done); 2757 __ set_byte_if_not_zero(dest); 2758 __ movzbl(dest, dest); 2759 __ bind(done); 2718 2760 #else 2719 2761 __ lcmp2int(left->as_register_hi(), … … 2734 2776 case lir_static_call: 2735 2777 case lir_optvirtual_call: 2778 case lir_dynamic_call: 2736 2779 offset += NativeCall::displacement_offset; 2737 2780 break; … … 2749 2792 2750 2793 2751 void LIR_Assembler::call( address entry, relocInfo::relocType rtype, CodeEmitInfo* info) {2794 void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { 2752 2795 assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, 2753 2796 "must be aligned"); 2754 __ call(AddressLiteral( entry, rtype));2755 add_call_info(code_offset(), info);2756 } 2757 2758 2759 void LIR_Assembler::ic_call( address entry, CodeEmitInfo* info) {2797 __ call(AddressLiteral(op->addr(), rtype)); 2798 add_call_info(code_offset(), op->info()); 2799 } 2800 2801 2802 void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { 2760 2803 RelocationHolder rh = virtual_call_Relocation::spec(pc()); 2761 2804 __ movoop(IC_Klass, (jobject)Universe::non_oop_word()); … … 2763 2806 (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, 2764 2807 "must be aligned"); 2765 __ call(AddressLiteral( entry, rh));2766 add_call_info(code_offset(), info);2808 __ call(AddressLiteral(op->addr(), rh)); 2809 add_call_info(code_offset(), op->info()); 2767 2810 } 2768 2811 2769 2812 2770 2813 /* Currently, vtable-dispatch is only enabled for sparc platforms */ 2771 void LIR_Assembler::vtable_call( int vtable_offset, CodeEmitInfo* info) {2814 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { 2772 2815 ShouldNotReachHere(); 2773 2816 } 2817 2774 2818 2775 2819 void LIR_Assembler::emit_static_call_stub() { … … 2796 2840 __ jump(RuntimeAddress(__ pc())); 2797 2841 2798 assert(__ offset() - start <= call_stub_size, "stub too big") 2842 assert(__ offset() - start <= call_stub_size, "stub too big"); 2799 2843 __ end_a_stub(); 2800 2844 } 2801 2845 2802 2846 2803 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info , bool unwind) {2847 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { 2804 2848 assert(exceptionOop->as_register() == rax, "must match"); 2805 assert( unwind ||exceptionPC->as_register() == rdx, "must match");2849 assert(exceptionPC->as_register() == rdx, "must match"); 2806 2850 2807 2851 // exception object is not added to oop map by LinearScan … … 2810 2854 Runtime1::StubID unwind_id; 2811 2855 2812 if (!unwind) { 2813 // get current pc information 2814 // pc is only needed if the method has an exception handler, the unwind code does not need it. 2815 int pc_for_athrow_offset = __ offset(); 2816 InternalAddress pc_for_athrow(__ pc()); 2817 __ lea(exceptionPC->as_register(), pc_for_athrow); 2818 add_call_info(pc_for_athrow_offset, info); // for exception handler 2819 2820 __ verify_not_null_oop(rax); 2821 // search an exception handler (rax: exception oop, rdx: throwing pc) 2822 if (compilation()->has_fpu_code()) { 2823 unwind_id = Runtime1::handle_exception_id; 2824 } else { 2825 unwind_id = Runtime1::handle_exception_nofpu_id; 2826 } 2856 // get current pc information 2857 // pc is only needed if the method has an exception handler, the unwind code does not need it. 2858 int pc_for_athrow_offset = __ offset(); 2859 InternalAddress pc_for_athrow(__ pc()); 2860 __ lea(exceptionPC->as_register(), pc_for_athrow); 2861 add_call_info(pc_for_athrow_offset, info); // for exception handler 2862 2863 __ verify_not_null_oop(rax); 2864 // search an exception handler (rax: exception oop, rdx: throwing pc) 2865 if (compilation()->has_fpu_code()) { 2866 unwind_id = Runtime1::handle_exception_id; 2827 2867 } else { 2828 unwind_id = Runtime1:: unwind_exception_id;2868 unwind_id = Runtime1::handle_exception_nofpu_id; 2829 2869 } 2830 2870 __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); … … 2832 2872 // enough room for two byte trap 2833 2873 __ nop(); 2874 } 2875 2876 2877 void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { 2878 assert(exceptionOop->as_register() == rax, "must match"); 2879 2880 __ jmp(_unwind_handler_entry); 2834 2881 } 2835 2882 … … 3113 3160 // but not necessarily exactly of type default_type. 3114 3161 Label known_ok, halt; 3115 __ movoop(tmp, default_type-> encoding());3162 __ movoop(tmp, default_type->constant_encoding()); 3116 3163 if (basic_type != T_OBJECT) { 3117 3164 __ cmpptr(tmp, dst_klass_addr); … … 3137 3184 #ifdef _LP64 3138 3185 assert_different_registers(c_rarg0, dst, dst_pos, length); 3186 __ movl2ptr(src_pos, src_pos); //higher 32bits must be null 3139 3187 __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); 3140 3188 assert_different_registers(c_rarg1, length); 3189 __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null 3141 3190 __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); 3142 3191 __ mov(c_rarg2, length); … … 3201 3250 assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); 3202 3251 Register mdo = op->mdo()->as_register(); 3203 __ movoop(mdo, md-> encoding());3252 __ movoop(mdo, md->constant_encoding()); 3204 3253 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); 3205 __ addl(counter_addr, DataLayout::counter_increment);3206 3254 Bytecodes::Code bc = method->java_code_at_bci(bci); 3207 3255 // Perform additional virtual call profiling for invokevirtual and … … 3241 3289 if (receiver == NULL) { 3242 3290 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); 3243 __ movoop(recv_addr, known_klass-> encoding());3291 __ movoop(recv_addr, known_klass->constant_encoding()); 3244 3292 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 3245 3293 __ addl(data_addr, DataLayout::counter_increment); … … 3270 3318 __ movptr(recv_addr, recv); 3271 3319 __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment); 3272 if (i < (VirtualCallData::row_limit() - 1)) { 3273 __ jmp(update_done); 3274 } 3320 __ jmp(update_done); 3275 3321 __ bind(next_test); 3276 3322 } 3323 // Receiver did not match any saved receiver and there is no empty row for it. 3324 // Increment total counter to indicate polymorphic case. 3325 __ addl(counter_addr, DataLayout::counter_increment); 3277 3326 3278 3327 __ bind(update_done); 3279 3328 } 3329 } else { 3330 // Static call 3331 __ addl(counter_addr, DataLayout::counter_increment); 3280 3332 } 3281 3333 } -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 176 176 LIR_Opr tmp = new_pointer_register(); 177 177 __ leal(LIR_OprFact::address(addr), tmp); 178 return new LIR_Address(tmp, 0,type);178 return new LIR_Address(tmp, type); 179 179 } else { 180 180 return addr; … … 186 186 LIR_Opr pointer = new_pointer_register(); 187 187 __ move(LIR_OprFact::intptrConst(counter), pointer); 188 LIR_Address* addr = new LIR_Address(pointer, 0,T_INT);188 LIR_Address* addr = new LIR_Address(pointer, T_INT); 189 189 increment_counter(addr, step); 190 190 } … … 350 350 LIR_Opr obj_temp = new_register(T_INT); 351 351 set_no_result(x); 352 monitor_exit(obj_temp, lock, syncTempOpr(), x->monitor_no());352 monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); 353 353 } 354 354 … … 756 756 757 757 LIR_Opr addr = new_pointer_register(); 758 __ move(obj.result(), addr); 759 __ add(addr, offset.result(), addr); 758 LIR_Address* a; 759 if(offset.result()->is_constant()) { 760 a = new LIR_Address(obj.result(), 761 NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()), 762 as_BasicType(type)); 763 } else { 764 a = new LIR_Address(obj.result(), 765 offset.result(), 766 LIR_Address::times_1, 767 0, 768 as_BasicType(type)); 769 } 770 __ leal(LIR_OprFact::address(a), addr); 760 771 761 772 if (type == objectType) { // Write-barrier needed for Object fields. … … 995 1006 BasicType elem_type = x->elt_type(); 996 1007 997 __ oop2reg(ciTypeArrayKlass::make(elem_type)-> encoding(), klass_reg);1008 __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg); 998 1009 999 1010 CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info); -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 318 318 319 319 320 void C1_MacroAssembler::method_exit(bool restore_frame) {321 if (restore_frame) {322 leave();323 }324 ret(0);325 }326 327 328 320 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) { 329 321 // Make sure there is enough stack space for this method's activation. … … 334 326 generate_stack_overflow_check(frame_size_in_bytes); 335 327 336 enter();328 push(rbp); 337 329 #ifdef TIERED 338 330 // c2 leaves fpu stack dirty. Clean it on entry … … 342 334 #endif // TIERED 343 335 decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0 336 } 337 338 339 void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) { 340 increment(rsp, frame_size_in_bytes); // Does not emit code for frame_size == 0 341 pop(rbp); 344 342 } 345 343 -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 689 689 oop_maps->add_gc_map(call_offset, oop_map); 690 690 691 // rax,: handler address or NULL if no handler exists691 // rax,: handler address 692 692 // will be the deopt blob if nmethod was deoptimized while we looked up 693 693 // handler regardless of whether handler existed in the nmethod. … … 696 696 __ invalidate_registers(false, true, true, true, true, true); 697 697 698 #ifdef ASSERT 698 699 // Do we have an exception handler in the nmethod? 699 Label no_handler;700 700 Label done; 701 701 __ testptr(rax, rax); 702 __ jcc(Assembler::zero, no_handler); 702 __ jcc(Assembler::notZero, done); 703 __ stop("no handler found"); 704 __ bind(done); 705 #endif 703 706 704 707 // exception handler found … … 713 716 __ ret(0); 714 717 715 __ bind(no_handler);716 // no exception handler found in this method, so the exception is717 // forwarded to the caller (using the unwind code of the nmethod)718 // there is no need to restore the registers719 720 // restore the real return address that was saved before the RT-call721 __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size));722 __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr);723 724 // load address of JavaThread object for thread-local data725 NOT_LP64(__ get_thread(thread);)726 // restore exception oop into rax, (convention for unwind code)727 __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset()));728 729 // clear exception fields in JavaThread because they are no longer needed730 // (fields must be cleared because they are processed by GC otherwise)731 __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);732 __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);733 734 // pop the stub frame off735 __ leave();736 737 generate_unwind_exception(sasm);738 __ stop("should not reach here");739 718 } 740 719 … … 743 722 // incoming parameters 744 723 const Register exception_oop = rax; 724 // callee-saved copy of exception_oop during runtime call 725 const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14); 745 726 // other registers used in this stub 746 727 const Register exception_pc = rdx; … … 770 751 __ empty_FPU_stack(); 771 752 772 // leave activation of nmethod 773 __ leave(); 774 // store return address (is on top of stack after leave) 753 // save exception_oop in callee-saved register to preserve it during runtime calls 754 __ verify_not_null_oop(exception_oop); 755 __ movptr(exception_oop_callee_saved, exception_oop); 756 757 NOT_LP64(__ get_thread(thread);) 758 // Get return address (is on top of stack after leave). 775 759 __ movptr(exception_pc, Address(rsp, 0)); 776 760 777 __ verify_oop(exception_oop);778 779 // save exception oop from rax, to stack before call780 __ push(exception_oop);781 782 761 // search the exception handler address of the caller (using the return address) 783 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc);784 // rax ,: exception handler address of the caller785 786 // only rax, is valid at this time, all other registers have been destroyed by the call787 __ invalidate_registers(false, true, true, true, true, true);762 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 763 // rax: exception handler address of the caller 764 765 // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call. 766 __ invalidate_registers(false, true, true, true, false, true); 788 767 789 768 // move result of call into correct register 790 769 __ movptr(handler_addr, rax); 791 770 792 // restore exception oop in rax, (required convention of exception handler) 793 __ pop(exception_oop); 794 795 __ verify_oop(exception_oop); 771 // Restore exception oop to RAX (required convention of exception handler). 772 __ movptr(exception_oop, exception_oop_callee_saved); 773 774 // verify that there is really a valid exception in rax 775 __ verify_not_null_oop(exception_oop); 796 776 797 777 // get throwing pc (= return address). … … 800 780 __ pop(exception_pc); 801 781 802 // verify that that there is really a valid exception in rax, 803 __ verify_not_null_oop(exception_oop); 782 // Restore SP from BP if the exception PC is a MethodHandle call site. 783 NOT_LP64(__ get_thread(thread);) 784 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0); 785 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); 804 786 805 787 // continue at exception handler (return address removed) … … 809 791 // runtime to determine the exception handler 810 792 // (GC happens at call site with arguments!) 811 // rax ,: exception oop793 // rax: exception oop 812 794 // rdx: throwing pc 813 // rbx ,: exception handler795 // rbx: exception handler 814 796 __ jmp(handler_addr); 815 797 } … … 1600 1582 break; 1601 1583 } 1602 1603 1584 __ push(rax); 1604 1585 __ push(rdx); … … 1624 1605 // Can we store original value in the thread's buffer? 1625 1606 1626 LP64_ONLY(__ movslq(tmp, queue_index);) 1627 #ifdef _LP64 1607 #ifdef _LP64 1608 __ movslq(tmp, queue_index); 1628 1609 __ cmpq(tmp, 0); 1629 1610 #else … … 1647 1628 1648 1629 __ bind(runtime); 1630 __ push(rcx); 1631 #ifdef _LP64 1632 __ push(r8); 1633 __ push(r9); 1634 __ push(r10); 1635 __ push(r11); 1636 # ifndef _WIN64 1637 __ push(rdi); 1638 __ push(rsi); 1639 # endif 1640 #endif 1649 1641 // load the pre-value 1650 __ push(rcx);1651 1642 f.load_argument(0, rcx); 1652 1643 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread); 1644 #ifdef _LP64 1645 # ifndef _WIN64 1646 __ pop(rsi); 1647 __ pop(rdi); 1648 # endif 1649 __ pop(r11); 1650 __ pop(r10); 1651 __ pop(r9); 1652 __ pop(r8); 1653 #endif 1653 1654 __ pop(rcx); 1654 1655 1655 __ bind(done); 1656 1656 1657 __ pop(rdx); 1657 1658 __ pop(rax); … … 1683 1684 1684 1685 __ push(rax); 1685 __ push(r dx);1686 __ push(rcx); 1686 1687 1687 1688 NOT_LP64(__ get_thread(thread);) … … 1689 1690 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); 1690 1691 1691 const Register card_addr = r dx;1692 const Register card_addr = rcx; 1692 1693 #ifdef _LP64 1693 1694 const Register tmp = rscratch1; … … 1698 1699 __ addq(card_addr, tmp); 1699 1700 #else 1700 const Register card_index = r dx;1701 const Register card_index = rcx; 1701 1702 f.load_argument(0, card_index); 1702 1703 __ shrl(card_index, CardTableModRefBS::card_shift); … … 1735 1736 1736 1737 __ bind(runtime); 1737 NOT_LP64(__ push(rcx);) 1738 __ push(rdx); 1739 #ifdef _LP64 1740 __ push(r8); 1741 __ push(r9); 1742 __ push(r10); 1743 __ push(r11); 1744 # ifndef _WIN64 1745 __ push(rdi); 1746 __ push(rsi); 1747 # endif 1748 #endif 1738 1749 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); 1739 NOT_LP64(__ pop(rcx);) 1740 1750 #ifdef _LP64 1751 # ifndef _WIN64 1752 __ pop(rsi); 1753 __ pop(rdi); 1754 # endif 1755 __ pop(r11); 1756 __ pop(r10); 1757 __ pop(r9); 1758 __ pop(r8); 1759 #endif 1760 __ pop(rdx); 1741 1761 __ bind(done); 1742 __ pop(rdx); 1762 1763 __ pop(rcx); 1743 1764 __ pop(rax); 1744 1765 … … 1759 1780 1760 1781 #undef __ 1782 1783 const char *Runtime1::pd_name_for_address(address entry) { 1784 return "<unknown function>"; 1785 } -
trunk/openjdk/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 81 81 define_pd_global(uint64_t,MaxRAM, 4ULL*G); 82 82 #endif // AMD64 83 define_pd_global(intx, OptoLoopAlignment, 16);84 83 define_pd_global(intx, RegisterCostAreaRatio, 16000); 85 84 -
trunk/openjdk/hotspot/src/cpu/x86/vm/c2_init_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/codeBuffer_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/copy_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/cppInterpreterGenerator_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/cppInterpreter_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 29 29 // fail with a guarantee ("not enough space for interpreter generation"); 30 30 // if too small. 31 // Run with +PrintInterpreter Sizeto get the VM to print out the size.32 // Max size with JVMTI and TaggedStackInterpreter31 // Run with +PrintInterpreter to get the VM to print out the size. 32 // Max size with JVMTI 33 33 const static int InterpreterCodeSize = 168 * 1024; -
trunk/openjdk/hotspot/src/cpu/x86/vm/debug_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/depChecker_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/depChecker_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/disassembler_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/dump_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/dump_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/frame_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 223 223 ((address *)sp())[-1] = pc; 224 224 _cb = CodeCache::find_blob(pc); 225 if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {226 address orig = (((nmethod*)_cb)->get_original_pc(this));227 assert(orig == _pc, "expected originalto be stored before patching");225 address original_pc = nmethod::get_deopt_original_pc(this); 226 if (original_pc != NULL) { 227 assert(original_pc == _pc, "expected original PC to be stored before patching"); 228 228 _deopt_state = is_deoptimized; 229 229 // leave _pc as is … … 292 292 BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset); 293 293 // make sure the pointer points inside the frame 294 assert( (intptr_t) fp() > (intptr_t) result, "result must < than framepointer");295 assert((intptr_t ) sp() <= (intptr_t) result, "result must >= than stackpointer");294 assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer"); 295 assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer"); 296 296 return result; 297 297 } … … 324 324 } 325 325 326 327 //------------------------------------------------------------------------------ 328 // frame::verify_deopt_original_pc 329 // 330 // Verifies the calculated original PC of a deoptimization PC for the 331 // given unextended SP. The unextended SP might also be the saved SP 332 // for MethodHandle call sites. 333 #if ASSERT 334 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { 335 frame fr; 336 337 // This is ugly but it's better than to change {get,set}_original_pc 338 // to take an SP value as argument. And it's only a debugging 339 // method anyway. 340 fr._unextended_sp = unextended_sp; 341 342 address original_pc = nm->get_original_pc(&fr); 343 assert(nm->code_contains(original_pc), "original PC must be in nmethod"); 344 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); 345 } 346 #endif 347 348 349 //------------------------------------------------------------------------------ 350 // frame::sender_for_interpreter_frame 326 351 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { 327 // sp is the raw sp from the sender after adapter or interpreter extension 328 intptr_t* sp = (intptr_t*) addr_at(sender_sp_offset); 352 // SP is the raw SP from the sender after adapter or interpreter 353 // extension. 354 intptr_t* sender_sp = this->sender_sp(); 329 355 330 356 // This is the sp before any possible extension (adapter/locals). 331 357 intptr_t* unextended_sp = interpreter_frame_sender_sp(); 358 359 // Stored FP. 360 intptr_t* saved_fp = link(); 361 362 address sender_pc = this->sender_pc(); 363 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); 364 assert(sender_cb, "sanity"); 365 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); 366 367 if (sender_nm != NULL) { 368 // If the sender PC is a deoptimization point, get the original 369 // PC. For MethodHandle call site the unextended_sp is stored in 370 // saved_fp. 371 if (sender_nm->is_deopt_mh_entry(sender_pc)) { 372 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); 373 unextended_sp = saved_fp; 374 } 375 else if (sender_nm->is_deopt_entry(sender_pc)) { 376 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); 377 } 378 else if (sender_nm->is_method_handle_return(sender_pc)) { 379 unextended_sp = saved_fp; 380 } 381 } 332 382 333 383 // The interpreter and compiler(s) always save EBP/RBP in a known … … 352 402 #endif // AMD64 353 403 } 354 #endif /* COMPILER2 */ 355 return frame(sp, unextended_sp, link(), sender_pc()); 356 } 357 358 359 //------------------------------sender_for_compiled_frame----------------------- 404 #endif // COMPILER2 405 406 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); 407 } 408 409 410 //------------------------------------------------------------------------------ 411 // frame::sender_for_compiled_frame 360 412 frame frame::sender_for_compiled_frame(RegisterMap* map) const { 361 413 assert(map != NULL, "map must be set"); 362 const bool c1_compiled = _cb->is_compiled_by_c1();363 414 364 415 // frame owned by optimizing compiler 365 intptr_t* sender_sp = NULL;366 367 416 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); 368 sender_sp = unextended_sp() + _cb->frame_size(); 417 intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); 418 intptr_t* unextended_sp = sender_sp; 369 419 370 420 // On Intel the return_address is always the word on the stack 371 421 address sender_pc = (address) *(sender_sp-1); 372 422 373 // This is the saved value of ebp which may or may not really be an fp. 374 // it is only an fp if the sender is an interpreter frame (or c1?) 375 376 intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); 423 // This is the saved value of EBP which may or may not really be an FP. 424 // It is only an FP if the sender is an interpreter frame (or C1?). 425 intptr_t* saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); 426 427 // If we are returning to a compiled MethodHandle call site, the 428 // saved_fp will in fact be a saved value of the unextended SP. The 429 // simplest way to tell whether we are returning to such a call site 430 // is as follows: 431 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); 432 assert(sender_cb, "sanity"); 433 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); 434 435 if (sender_nm != NULL) { 436 // If the sender PC is a deoptimization point, get the original 437 // PC. For MethodHandle call site the unextended_sp is stored in 438 // saved_fp. 439 if (sender_nm->is_deopt_mh_entry(sender_pc)) { 440 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); 441 unextended_sp = saved_fp; 442 } 443 else if (sender_nm->is_deopt_entry(sender_pc)) { 444 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); 445 } 446 else if (sender_nm->is_method_handle_return(sender_pc)) { 447 unextended_sp = saved_fp; 448 } 449 } 377 450 378 451 if (map->update_map()) { … … 384 457 OopMapSet::update_register_map(this, map); 385 458 } 386 // Since the prolog does the save and restore of epbthere is no oopmap459 // Since the prolog does the save and restore of EBP there is no oopmap 387 460 // for it so we must fill in its location as if there was an oopmap entry 388 461 // since if our caller was compiled code there could be live jvm state in it. … … 400 473 401 474 assert(sender_sp != sp(), "must have changed"); 402 return frame(sender_sp, saved_fp, sender_pc); 403 } 404 475 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); 476 } 477 478 479 //------------------------------------------------------------------------------ 480 // frame::sender 405 481 frame frame::sender(RegisterMap* map) const { 406 482 // Default is we done have to follow them. The sender_for_xxx will … … 427 503 // adjusted with: 428 504 int diff = (method->max_locals() - method->size_of_parameters()) * 429 Interpreter::stackElementWords ();505 Interpreter::stackElementWords; 430 506 return _fp == (fp - diff); 431 507 } … … 467 543 // stack frames shouldn't be much larger than max_stack elements 468 544 469 if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize ()) {545 if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { 470 546 return false; 471 547 } … … 500 576 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { 501 577 #ifdef CC_INTERP 502 // Needed for JVMTI. The result should always be in the interpreterState object503 assert(false, "NYI");578 // Needed for JVMTI. The result should always be in the 579 // interpreterState object 504 580 interpreterState istate = get_interpreterState(); 505 581 #endif // CC_INTERP … … 519 595 // This is times two because we do a push(ltos) after pushing XMM0 520 596 // and that takes two interpreter stack slots. 521 tos_addr += 2 * Interpreter::stackElementWords ();597 tos_addr += 2 * Interpreter::stackElementWords; 522 598 #else 523 599 tos_addr += 2; -
trunk/openjdk/hotspot/src/cpu/x86/vm/frame_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 164 164 } 165 165 166 #if ASSERT 167 // Used in frame::sender_for_{interpreter,compiled}_frame 168 static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false); 169 static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) { 170 verify_deopt_original_pc(nm, unextended_sp, true); 171 } 172 #endif 173 166 174 public: 167 175 // Constructors -
trunk/openjdk/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 36 36 } 37 37 38 inline frame:: 38 inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { 39 39 _sp = sp; 40 40 _unextended_sp = sp; … … 43 43 assert(pc != NULL, "no pc?"); 44 44 _cb = CodeCache::find_blob(pc); 45 _deopt_state = not_deoptimized; 46 if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 47 _pc = (((nmethod*)_cb)->get_original_pc(this)); 45 46 address original_pc = nmethod::get_deopt_original_pc(this); 47 if (original_pc != NULL) { 48 _pc = original_pc; 48 49 _deopt_state = is_deoptimized; 49 50 } else { … … 52 53 } 53 54 54 inline frame:: 55 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) { 55 56 _sp = sp; 56 57 _unextended_sp = unextended_sp; … … 59 60 assert(pc != NULL, "no pc?"); 60 61 _cb = CodeCache::find_blob(pc); 61 _deopt_state = not_deoptimized; 62 if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 63 _pc = (((nmethod*)_cb)->get_original_pc(this)); 62 63 address original_pc = nmethod::get_deopt_original_pc(this); 64 if (original_pc != NULL) { 65 _pc = original_pc; 66 assert(((nmethod*)_cb)->code_contains(_pc), "original PC must be in nmethod"); 64 67 _deopt_state = is_deoptimized; 65 68 } else { … … 87 90 _cb = CodeCache::find_blob(_pc); 88 91 89 _deopt_state = not_deoptimized;90 if ( _cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {91 _pc = (((nmethod*)_cb)->get_original_pc(this));92 address original_pc = nmethod::get_deopt_original_pc(this); 93 if (original_pc != NULL) { 94 _pc = original_pc; 92 95 _deopt_state = is_deoptimized; 93 96 } else { … … 226 229 inline intptr_t* frame::interpreter_frame_tos_address() const { 227 230 intptr_t* last_sp = interpreter_frame_last_sp(); 228 if (last_sp == NULL 231 if (last_sp == NULL) { 229 232 return sp(); 230 233 } else { 231 // sp() may have been extended by an adapter 232 assert(last_sp < fp() && last_sp >= sp(), "bad tos"); 234 // sp() may have been extended or shrunk by an adapter. At least 235 // check that we don't fall behind the legal region. 236 // For top deoptimized frame last_sp == interpreter_frame_monitor_end. 237 assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos"); 233 238 return last_sp; 234 239 } -
trunk/openjdk/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/globals_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 46 46 define_pd_global(intx, CodeEntryAlignment, 16); 47 47 #endif // COMPILER2 48 define_pd_global(intx, OptoLoopAlignment, 16); 48 49 define_pd_global(intx, InlineFrequencyCount, 100); 49 50 define_pd_global(intx, InlineSmallCode, 1000); -
trunk/openjdk/hotspot/src/cpu/x86/vm/icBuffer_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/icache_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/icache_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 190 190 191 191 192 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_offset, bool giant_index) {192 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_offset, size_t index_size) { 193 193 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); 194 if ( !giant_index) {194 if (index_size == sizeof(u2)) { 195 195 load_unsigned_short(reg, Address(rsi, bcp_offset)); 196 } else {196 } else if (index_size == sizeof(u4)) { 197 197 assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic"); 198 198 movl(reg, Address(rsi, bcp_offset)); 199 // Check if the secondary index definition is still ~x, otherwise 200 // we have to change the following assembler code to calculate the 201 // plain index. 199 202 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line"); 200 203 notl(reg); // convert to plain index 204 } else if (index_size == sizeof(u1)) { 205 assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles"); 206 load_unsigned_byte(reg, Address(rsi, bcp_offset)); 207 } else { 208 ShouldNotReachHere(); 201 209 } 202 210 } … … 204 212 205 213 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, 206 int bcp_offset, bool giant_index) {214 int bcp_offset, size_t index_size) { 207 215 assert(cache != index, "must use different registers"); 208 get_cache_index_at_bcp(index, bcp_offset, giant_index);216 get_cache_index_at_bcp(index, bcp_offset, index_size); 209 217 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); 210 218 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); … … 214 222 215 223 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, 216 int bcp_offset, bool giant_index) {224 int bcp_offset, size_t index_size) { 217 225 assert(cache != tmp, "must use different register"); 218 get_cache_index_at_bcp(tmp, bcp_offset, giant_index);226 get_cache_index_at_bcp(tmp, bcp_offset, index_size); 219 227 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); 220 228 // convert from field index to ConstantPoolCacheEntry index … … 263 271 // Java Expression Stack 264 272 265 #ifdef ASSERT266 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) {267 if (TaggedStackInterpreter) {268 Label okay;269 cmpptr(Address(rsp, wordSize), (int32_t)t);270 jcc(Assembler::equal, okay);271 // Also compare if the stack value is zero, then the tag might272 // not have been set coming from deopt.273 cmpptr(Address(rsp, 0), 0);274 jcc(Assembler::equal, okay);275 stop("Java Expression stack tag value is bad");276 bind(okay);277 }278 }279 #endif // ASSERT280 281 273 void InterpreterMacroAssembler::pop_ptr(Register r) { 282 debug_only(verify_stack_tag(frame::TagReference));283 274 pop(r); 284 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); 285 } 286 287 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { 275 } 276 277 void InterpreterMacroAssembler::pop_i(Register r) { 288 278 pop(r); 289 // Tag may not be reference for jsr, can be returnAddress290 if (TaggedStackInterpreter) pop(tag);291 }292 293 void InterpreterMacroAssembler::pop_i(Register r) {294 debug_only(verify_stack_tag(frame::TagValue));295 pop(r);296 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);297 279 } 298 280 299 281 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { 300 debug_only(verify_stack_tag(frame::TagValue));301 282 pop(lo); 302 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);303 debug_only(verify_stack_tag(frame::TagValue));304 283 pop(hi); 305 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);306 284 } 307 285 308 286 void InterpreterMacroAssembler::pop_f() { 309 debug_only(verify_stack_tag(frame::TagValue));310 287 fld_s(Address(rsp, 0)); 311 288 addptr(rsp, 1 * wordSize); 312 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);313 289 } 314 290 315 291 void InterpreterMacroAssembler::pop_d() { 316 // Write double to stack contiguously and load into ST0317 pop_dtos_to_rsp();318 292 fld_d(Address(rsp, 0)); 319 293 addptr(rsp, 2 * wordSize); 320 294 } 321 295 322 323 // Pop the top of the java expression stack to execution stack (which324 // happens to be the same place).325 void InterpreterMacroAssembler::pop_dtos_to_rsp() {326 if (TaggedStackInterpreter) {327 // Pop double value into scratch registers328 debug_only(verify_stack_tag(frame::TagValue));329 pop(rax);330 addptr(rsp, 1* wordSize);331 debug_only(verify_stack_tag(frame::TagValue));332 pop(rdx);333 addptr(rsp, 1* wordSize);334 push(rdx);335 push(rax);336 }337 }338 339 void InterpreterMacroAssembler::pop_ftos_to_rsp() {340 if (TaggedStackInterpreter) {341 debug_only(verify_stack_tag(frame::TagValue));342 pop(rax);343 addptr(rsp, 1 * wordSize);344 push(rax); // ftos is at rsp345 }346 }347 296 348 297 void InterpreterMacroAssembler::pop(TosState state) { … … 363 312 364 313 void InterpreterMacroAssembler::push_ptr(Register r) { 365 if (TaggedStackInterpreter) push(frame::TagReference);366 314 push(r); 367 315 } 368 316 369 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { 370 if (TaggedStackInterpreter) push(tag); // tag first 317 void InterpreterMacroAssembler::push_i(Register r) { 371 318 push(r); 372 319 } 373 320 374 void InterpreterMacroAssembler::push_i(Register r) {375 if (TaggedStackInterpreter) push(frame::TagValue);376 push(r);377 }378 379 321 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { 380 if (TaggedStackInterpreter) push(frame::TagValue);381 322 push(hi); 382 if (TaggedStackInterpreter) push(frame::TagValue);383 323 push(lo); 384 324 } 385 325 386 326 void InterpreterMacroAssembler::push_f() { 387 if (TaggedStackInterpreter) push(frame::TagValue);388 327 // Do not schedule for no AGI! Never write beyond rsp! 389 328 subptr(rsp, 1 * wordSize); … … 392 331 393 332 void InterpreterMacroAssembler::push_d(Register r) { 394 if (TaggedStackInterpreter) { 395 // Double values are stored as: 396 // tag 397 // high 398 // tag 399 // low 400 push(frame::TagValue); 401 subptr(rsp, 3 * wordSize); 402 fstp_d(Address(rsp, 0)); 403 // move high word up to slot n-1 404 movl(r, Address(rsp, 1*wordSize)); 405 movl(Address(rsp, 2*wordSize), r); 406 // move tag 407 movl(Address(rsp, 1*wordSize), frame::TagValue); 408 } else { 409 // Do not schedule for no AGI! Never write beyond rsp! 410 subptr(rsp, 2 * wordSize); 411 fstp_d(Address(rsp, 0)); 412 } 333 // Do not schedule for no AGI! Never write beyond rsp! 334 subptr(rsp, 2 * wordSize); 335 fstp_d(Address(rsp, 0)); 413 336 } 414 337 … … 431 354 432 355 433 // Tagged stack helpers for swap and dup 434 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, 435 Register tag) { 356 // Helpers for swap and dup 357 void InterpreterMacroAssembler::load_ptr(int n, Register val) { 436 358 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); 437 if (TaggedStackInterpreter) { 438 movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); 439 } 440 } 441 442 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, 443 Register tag) { 359 } 360 361 void InterpreterMacroAssembler::store_ptr(int n, Register val) { 444 362 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); 445 if (TaggedStackInterpreter) { 446 movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); 447 } 448 } 449 450 451 // Tagged local support 452 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { 453 if (TaggedStackInterpreter) { 454 if (tag == frame::TagCategory2) { 455 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)frame::TagValue); 456 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)frame::TagValue); 457 } else { 458 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); 459 } 460 } 461 } 462 463 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { 464 if (TaggedStackInterpreter) { 465 if (tag == frame::TagCategory2) { 466 movptr(Address(rdi, idx, Interpreter::stackElementScale(), 467 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); 468 movptr(Address(rdi, idx, Interpreter::stackElementScale(), 469 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); 470 } else { 471 movptr(Address(rdi, idx, Interpreter::stackElementScale(), 472 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)tag); 473 } 474 } 475 } 476 477 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { 478 if (TaggedStackInterpreter) { 479 // can only be TagValue or TagReference 480 movptr(Address(rdi, idx, Interpreter::stackElementScale(), 481 Interpreter::local_tag_offset_in_bytes(0)), tag); 482 } 483 } 484 485 486 void InterpreterMacroAssembler::tag_local(Register tag, int n) { 487 if (TaggedStackInterpreter) { 488 // can only be TagValue or TagReference 489 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); 490 } 491 } 492 493 #ifdef ASSERT 494 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { 495 if (TaggedStackInterpreter) { 496 frame::Tag t = tag; 497 if (tag == frame::TagCategory2) { 498 Label nbl; 499 t = frame::TagValue; // change to what is stored in locals 500 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); 501 jcc(Assembler::equal, nbl); 502 stop("Local tag is bad for long/double"); 503 bind(nbl); 504 } 505 Label notBad; 506 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); 507 jcc(Assembler::equal, notBad); 508 // Also compare if the local value is zero, then the tag might 509 // not have been set coming from deopt. 510 cmpptr(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); 511 jcc(Assembler::equal, notBad); 512 stop("Local tag is bad"); 513 bind(notBad); 514 } 515 } 516 517 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { 518 if (TaggedStackInterpreter) { 519 frame::Tag t = tag; 520 if (tag == frame::TagCategory2) { 521 Label nbl; 522 t = frame::TagValue; // change to what is stored in locals 523 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), 524 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); 525 jcc(Assembler::equal, nbl); 526 stop("Local tag is bad for long/double"); 527 bind(nbl); 528 } 529 Label notBad; 530 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), 531 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); 532 jcc(Assembler::equal, notBad); 533 // Also compare if the local value is zero, then the tag might 534 // not have been set coming from deopt. 535 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), 536 Interpreter::local_offset_in_bytes(0)), 0); 537 jcc(Assembler::equal, notBad); 538 stop("Local tag is bad"); 539 bind(notBad); 540 541 } 542 } 543 #endif // ASSERT 363 } 544 364 545 365 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { … … 1237 1057 test_method_data_pointer(mdp, profile_continue); 1238 1058 1239 // We are making a call. Increment the count.1240 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));1241 1242 1059 Label skip_receiver_profile; 1243 1060 if (receiver_can_be_null) { 1061 Label not_null; 1244 1062 testptr(receiver, receiver); 1245 jcc(Assembler::zero, skip_receiver_profile); 1063 jccb(Assembler::notZero, not_null); 1064 // We are making a call. Increment the count for null receiver. 1065 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1066 jmp(skip_receiver_profile); 1067 bind(not_null); 1246 1068 } 1247 1069 1248 1070 // Record the receiver type. 1249 record_klass_in_profile(receiver, mdp, reg2 );1071 record_klass_in_profile(receiver, mdp, reg2, true); 1250 1072 bind(skip_receiver_profile); 1251 1073 … … 1261 1083 void InterpreterMacroAssembler::record_klass_in_profile_helper( 1262 1084 Register receiver, Register mdp, 1263 Register reg2, 1264 int start_row, Label& done) { 1265 if (TypeProfileWidth == 0) 1085 Register reg2, int start_row, 1086 Label& done, bool is_virtual_call) { 1087 if (TypeProfileWidth == 0) { 1088 if (is_virtual_call) { 1089 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1090 } 1266 1091 return; 1092 } 1267 1093 1268 1094 int last_row = VirtualCallData::row_limit() - 1; … … 1292 1118 1293 1119 if (row == start_row) { 1120 Label found_null; 1294 1121 // Failed the equality check on receiver[n]... Test for null. 1295 1122 testptr(reg2, reg2); 1296 1123 if (start_row == last_row) { 1297 1124 // The only thing left to do is handle the null case. 1298 jcc(Assembler::notZero, done); 1125 if (is_virtual_call) { 1126 jccb(Assembler::zero, found_null); 1127 // Receiver did not match any saved receiver and there is no empty row for it. 1128 // Increment total counter to indicate polymorphic case. 1129 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1130 jmp(done); 1131 bind(found_null); 1132 } else { 1133 jcc(Assembler::notZero, done); 1134 } 1299 1135 break; 1300 1136 } 1301 1137 // Since null is rare, make it be the branch-taken case. 1302 Label found_null;1303 1138 jcc(Assembler::zero, found_null); 1304 1139 1305 1140 // Put all the "Case 3" tests here. 1306 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done );1141 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call); 1307 1142 1308 1143 // Found a null. Keep searching for a matching receiver, … … 1321 1156 movptr(reg2, (int32_t)DataLayout::counter_increment); 1322 1157 set_mdp_data_at(mdp, count_offset, reg2); 1323 jmp(done); 1158 if (start_row > 0) { 1159 jmp(done); 1160 } 1324 1161 } 1325 1162 1326 1163 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, 1327 Register mdp, 1328 Register reg2) {1164 Register mdp, Register reg2, 1165 bool is_virtual_call) { 1329 1166 assert(ProfileInterpreter, "must be profiling"); 1330 1167 Label done; 1331 1168 1332 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done );1169 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call); 1333 1170 1334 1171 bind (done); … … 1423 1260 1424 1261 // Record the object type. 1425 record_klass_in_profile(klass, mdp, reg2 );1262 record_klass_in_profile(klass, mdp, reg2, false); 1426 1263 assert(reg2 == rdi, "we know how to fix this blown reg"); 1427 1264 restore_locals(); // Restore EDI -
trunk/openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 77 77 } 78 78 void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); 79 void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, bool giant_index = false);80 void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, bool giant_index = false);81 void get_cache_index_at_bcp(Register index, int bcp_offset, bool giant_index = false);79 void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2)); 80 void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); 81 void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); 82 82 83 83 // Expression stack … … 86 86 87 87 void pop_ptr(Register r = rax); 88 void pop_ptr(Register r, Register tag);89 88 void pop_i(Register r = rax); 90 89 void pop_l(Register lo = rax, Register hi = rdx); 91 90 void pop_f(); 92 91 void pop_d(); 93 void pop_ftos_to_rsp();94 void pop_dtos_to_rsp();95 92 96 93 void push_ptr(Register r = rax); 97 void push_ptr(Register r, Register tag);98 94 void push_i(Register r = rax); 99 95 void push_l(Register lo = rax, Register hi = rdx); … … 113 109 void push(void* v ); // Add unimplemented ambiguous method 114 110 115 DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) 116 117 #endif // CC_INTERP 118 119 #ifndef CC_INTERP 120 121 void empty_expression_stack() { 122 movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); 123 // NULL last_sp until next java call 124 movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 111 void empty_expression_stack() { 112 movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); 113 // NULL last_sp until next java call 114 movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 125 115 } 126 116 127 // Tagged stack helpers for swap and dup 128 void load_ptr_and_tag(int n, Register val, Register tag); 129 void store_ptr_and_tag(int n, Register val, Register tag); 130 131 // Tagged Local support 132 133 void tag_local(frame::Tag tag, int n); 134 void tag_local(Register tag, int n); 135 void tag_local(frame::Tag tag, Register idx); 136 void tag_local(Register tag, Register idx); 137 138 #ifdef ASSERT 139 void verify_local_tag(frame::Tag tag, int n); 140 void verify_local_tag(frame::Tag tag, Register idx); 141 #endif // ASSERT 117 // Helpers for swap and dup 118 void load_ptr(int n, Register val); 119 void store_ptr(int n, Register val); 142 120 143 121 // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls … … 214 192 215 193 void record_klass_in_profile(Register receiver, Register mdp, 216 Register reg2 );194 Register reg2, bool is_virtual_call); 217 195 void record_klass_in_profile_helper(Register receiver, Register mdp, 218 Register reg2, 219 int start_row, Label& done);196 Register reg2, int start_row, 197 Label& done, bool is_virtual_call); 220 198 221 199 void update_mdp_by_offset(Register mdp_in, int offset_of_offset); -
trunk/openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 186 186 187 187 188 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index, 189 int bcp_offset, 190 size_t index_size) { 191 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); 192 if (index_size == sizeof(u2)) { 193 load_unsigned_short(index, Address(r13, bcp_offset)); 194 } else if (index_size == sizeof(u4)) { 195 assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic"); 196 movl(index, Address(r13, bcp_offset)); 197 // Check if the secondary index definition is still ~x, otherwise 198 // we have to change the following assembler code to calculate the 199 // plain index. 200 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line"); 201 notl(index); // convert to plain index 202 } else if (index_size == sizeof(u1)) { 203 assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles"); 204 load_unsigned_byte(index, Address(r13, bcp_offset)); 205 } else { 206 ShouldNotReachHere(); 207 } 208 } 209 210 188 211 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, 189 212 Register index, 190 int bcp_offset ) {191 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");213 int bcp_offset, 214 size_t index_size) { 192 215 assert(cache != index, "must use different registers"); 193 load_unsigned_short(index, Address(r13, bcp_offset));216 get_cache_index_at_bcp(index, bcp_offset, index_size); 194 217 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); 195 218 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); … … 201 224 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, 202 225 Register tmp, 203 int bcp_offset ) {204 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");226 int bcp_offset, 227 size_t index_size) { 205 228 assert(cache != tmp, "must use different register"); 206 load_unsigned_short(tmp, Address(r13, bcp_offset));229 get_cache_index_at_bcp(tmp, bcp_offset, index_size); 207 230 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); 208 231 // convert from field index to ConstantPoolCacheEntry index … … 247 270 // Java Expression Stack 248 271 249 #ifdef ASSERT250 // Verifies that the stack tag matches. Must be called before the stack251 // value is popped off the stack.252 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) {253 if (TaggedStackInterpreter) {254 frame::Tag tag = t;255 if (t == frame::TagCategory2) {256 tag = frame::TagValue;257 Label hokay;258 cmpptr(Address(rsp, 3*wordSize), (int32_t)tag);259 jcc(Assembler::equal, hokay);260 stop("Java Expression stack tag high value is bad");261 bind(hokay);262 }263 Label okay;264 cmpptr(Address(rsp, wordSize), (int32_t)tag);265 jcc(Assembler::equal, okay);266 // Also compare if the stack value is zero, then the tag might267 // not have been set coming from deopt.268 cmpptr(Address(rsp, 0), 0);269 jcc(Assembler::equal, okay);270 stop("Java Expression stack tag value is bad");271 bind(okay);272 }273 }274 #endif // ASSERT275 276 272 void InterpreterMacroAssembler::pop_ptr(Register r) { 277 debug_only(verify_stack_tag(frame::TagReference));278 273 pop(r); 279 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);280 }281 282 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) {283 pop(r);284 if (TaggedStackInterpreter) pop(tag);285 274 } 286 275 287 276 void InterpreterMacroAssembler::pop_i(Register r) { 288 277 // XXX can't use pop currently, upper half non clean 289 debug_only(verify_stack_tag(frame::TagValue));290 278 movl(r, Address(rsp, 0)); 291 279 addptr(rsp, wordSize); 292 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);293 280 } 294 281 295 282 void InterpreterMacroAssembler::pop_l(Register r) { 296 debug_only(verify_stack_tag(frame::TagCategory2));297 283 movq(r, Address(rsp, 0)); 298 addptr(rsp, 2 * Interpreter::stackElementSize ());284 addptr(rsp, 2 * Interpreter::stackElementSize); 299 285 } 300 286 301 287 void InterpreterMacroAssembler::pop_f(XMMRegister r) { 302 debug_only(verify_stack_tag(frame::TagValue));303 288 movflt(r, Address(rsp, 0)); 304 289 addptr(rsp, wordSize); 305 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize);306 290 } 307 291 308 292 void InterpreterMacroAssembler::pop_d(XMMRegister r) { 309 debug_only(verify_stack_tag(frame::TagCategory2));310 293 movdbl(r, Address(rsp, 0)); 311 addptr(rsp, 2 * Interpreter::stackElementSize ());294 addptr(rsp, 2 * Interpreter::stackElementSize); 312 295 } 313 296 314 297 void InterpreterMacroAssembler::push_ptr(Register r) { 315 if (TaggedStackInterpreter) push(frame::TagReference);316 298 push(r); 317 299 } 318 300 319 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { 320 if (TaggedStackInterpreter) push(tag); 301 void InterpreterMacroAssembler::push_i(Register r) { 321 302 push(r); 322 303 } 323 304 324 void InterpreterMacroAssembler::push_i(Register r) {325 if (TaggedStackInterpreter) push(frame::TagValue);326 push(r);327 }328 329 305 void InterpreterMacroAssembler::push_l(Register r) { 330 if (TaggedStackInterpreter) { 331 push(frame::TagValue); 332 subptr(rsp, 1 * wordSize); 333 push(frame::TagValue); 334 subptr(rsp, 1 * wordSize); 335 } else { 336 subptr(rsp, 2 * wordSize); 337 } 306 subptr(rsp, 2 * wordSize); 338 307 movq(Address(rsp, 0), r); 339 308 } 340 309 341 310 void InterpreterMacroAssembler::push_f(XMMRegister r) { 342 if (TaggedStackInterpreter) push(frame::TagValue);343 311 subptr(rsp, wordSize); 344 312 movflt(Address(rsp, 0), r); … … 346 314 347 315 void InterpreterMacroAssembler::push_d(XMMRegister r) { 348 if (TaggedStackInterpreter) { 349 push(frame::TagValue); 350 subptr(rsp, 1 * wordSize); 351 push(frame::TagValue); 352 subptr(rsp, 1 * wordSize); 353 } else { 354 subptr(rsp, 2 * wordSize); 355 } 316 subptr(rsp, 2 * wordSize); 356 317 movdbl(Address(rsp, 0), r); 357 318 } … … 390 351 391 352 392 393 394 // Tagged stack helpers for swap and dup 395 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, 396 Register tag) { 353 // Helpers for swap and dup 354 void InterpreterMacroAssembler::load_ptr(int n, Register val) { 397 355 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); 398 if (TaggedStackInterpreter) { 399 movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); 400 } 401 } 402 403 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, 404 Register tag) { 356 } 357 358 void InterpreterMacroAssembler::store_ptr(int n, Register val) { 405 359 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); 406 if (TaggedStackInterpreter) { 407 movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); 408 } 409 } 410 411 412 // Tagged local support 413 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { 414 if (TaggedStackInterpreter) { 415 if (tag == frame::TagCategory2) { 416 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), 417 (int32_t)frame::TagValue); 418 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), 419 (int32_t)frame::TagValue); 420 } else { 421 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); 422 } 423 } 424 } 425 426 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { 427 if (TaggedStackInterpreter) { 428 if (tag == frame::TagCategory2) { 429 movptr(Address(r14, idx, Address::times_8, 430 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); 431 movptr(Address(r14, idx, Address::times_8, 432 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); 433 } else { 434 movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), 435 (int32_t)tag); 436 } 437 } 438 } 439 440 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { 441 if (TaggedStackInterpreter) { 442 // can only be TagValue or TagReference 443 movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); 444 } 445 } 446 447 448 void InterpreterMacroAssembler::tag_local(Register tag, int n) { 449 if (TaggedStackInterpreter) { 450 // can only be TagValue or TagReference 451 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); 452 } 453 } 454 455 #ifdef ASSERT 456 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { 457 if (TaggedStackInterpreter) { 458 frame::Tag t = tag; 459 if (tag == frame::TagCategory2) { 460 Label nbl; 461 t = frame::TagValue; // change to what is stored in locals 462 cmpptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); 463 jcc(Assembler::equal, nbl); 464 stop("Local tag is bad for long/double"); 465 bind(nbl); 466 } 467 Label notBad; 468 cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); 469 jcc(Assembler::equal, notBad); 470 // Also compare if the local value is zero, then the tag might 471 // not have been set coming from deopt. 472 cmpptr(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); 473 jcc(Assembler::equal, notBad); 474 stop("Local tag is bad"); 475 bind(notBad); 476 } 477 } 478 479 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { 480 if (TaggedStackInterpreter) { 481 frame::Tag t = tag; 482 if (tag == frame::TagCategory2) { 483 Label nbl; 484 t = frame::TagValue; // change to what is stored in locals 485 cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); 486 jcc(Assembler::equal, nbl); 487 stop("Local tag is bad for long/double"); 488 bind(nbl); 489 } 490 Label notBad; 491 cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); 492 jcc(Assembler::equal, notBad); 493 // Also compare if the local value is zero, then the tag might 494 // not have been set coming from deopt. 495 cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); 496 jcc(Assembler::equal, notBad); 497 stop("Local tag is bad"); 498 bind(notBad); 499 } 500 } 501 #endif // ASSERT 360 } 502 361 503 362 … … 1237 1096 void InterpreterMacroAssembler::profile_virtual_call(Register receiver, 1238 1097 Register mdp, 1239 Register reg2) { 1098 Register reg2, 1099 bool receiver_can_be_null) { 1240 1100 if (ProfileInterpreter) { 1241 1101 Label profile_continue; … … 1244 1104 test_method_data_pointer(mdp, profile_continue); 1245 1105 1246 // We are making a call. Increment the count. 1247 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1106 Label skip_receiver_profile; 1107 if (receiver_can_be_null) { 1108 Label not_null; 1109 testptr(receiver, receiver); 1110 jccb(Assembler::notZero, not_null); 1111 // We are making a call. Increment the count for null receiver. 1112 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1113 jmp(skip_receiver_profile); 1114 bind(not_null); 1115 } 1248 1116 1249 1117 // Record the receiver type. 1250 record_klass_in_profile(receiver, mdp, reg2); 1118 record_klass_in_profile(receiver, mdp, reg2, true); 1119 bind(skip_receiver_profile); 1251 1120 1252 1121 // The method data pointer needs to be updated to reflect the new target. … … 1271 1140 void InterpreterMacroAssembler::record_klass_in_profile_helper( 1272 1141 Register receiver, Register mdp, 1273 Register reg2, 1274 int start_row, Label& done) { 1275 if (TypeProfileWidth == 0) 1142 Register reg2, int start_row, 1143 Label& done, bool is_virtual_call) { 1144 if (TypeProfileWidth == 0) { 1145 if (is_virtual_call) { 1146 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1147 } 1276 1148 return; 1149 } 1277 1150 1278 1151 int last_row = VirtualCallData::row_limit() - 1; … … 1302 1175 1303 1176 if (test_for_null_also) { 1177 Label found_null; 1304 1178 // Failed the equality check on receiver[n]... Test for null. 1305 1179 testptr(reg2, reg2); 1306 1180 if (start_row == last_row) { 1307 1181 // The only thing left to do is handle the null case. 1308 jcc(Assembler::notZero, done); 1182 if (is_virtual_call) { 1183 jccb(Assembler::zero, found_null); 1184 // Receiver did not match any saved receiver and there is no empty row for it. 1185 // Increment total counter to indicate polymorphic case. 1186 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); 1187 jmp(done); 1188 bind(found_null); 1189 } else { 1190 jcc(Assembler::notZero, done); 1191 } 1309 1192 break; 1310 1193 } 1311 1194 // Since null is rare, make it be the branch-taken case. 1312 Label found_null;1313 1195 jcc(Assembler::zero, found_null); 1314 1196 1315 1197 // Put all the "Case 3" tests here. 1316 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done );1198 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call); 1317 1199 1318 1200 // Found a null. Keep searching for a matching receiver, … … 1331 1213 movl(reg2, DataLayout::counter_increment); 1332 1214 set_mdp_data_at(mdp, count_offset, reg2); 1333 jmp(done); 1215 if (start_row > 0) { 1216 jmp(done); 1217 } 1334 1218 } 1335 1219 … … 1343 1227 // // degenerate decision tree, rooted at row[2] 1344 1228 // if (row[2].rec == rec) { row[2].incr(); goto done; } 1345 // if (row[2].rec != NULL) { goto done; } // overflow1229 // if (row[2].rec != NULL) { count.incr(); goto done; } // overflow 1346 1230 // row[2].init(rec); goto done; 1347 1231 // } else { … … 1356 1240 // row[0].init(rec); goto done; 1357 1241 // } 1242 // done: 1358 1243 1359 1244 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver, 1360 Register mdp, 1361 Register reg2) {1245 Register mdp, Register reg2, 1246 bool is_virtual_call) { 1362 1247 assert(ProfileInterpreter, "must be profiling"); 1363 1248 Label done; 1364 1249 1365 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done );1250 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call); 1366 1251 1367 1252 bind (done); … … 1459 1344 1460 1345 // Record the object type. 1461 record_klass_in_profile(klass, mdp, reg2 );1346 record_klass_in_profile(klass, mdp, reg2, false); 1462 1347 } 1463 1348 update_mdp_by_constant(mdp, mdp_delta); -
trunk/openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 96 96 void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); 97 97 void get_cache_and_index_at_bcp(Register cache, Register index, 98 int bcp_offset );98 int bcp_offset, size_t index_size = sizeof(u2)); 99 99 void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, 100 int bcp_offset); 100 int bcp_offset, size_t index_size = sizeof(u2)); 101 void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); 101 102 102 103 … … 120 121 void push(TosState state); // transition state -> vtos 121 122 122 // Tagged stack support, pop and push both tag and value. 123 void pop_ptr(Register r, Register tag); 124 void push_ptr(Register r, Register tag); 125 #endif // CC_INTERP 126 127 DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) 128 129 #ifndef CC_INTERP 130 131 // Tagged stack helpers for swap and dup 132 void load_ptr_and_tag(int n, Register val, Register tag); 133 void store_ptr_and_tag(int n, Register val, Register tag); 134 135 // Tagged Local support 136 void tag_local(frame::Tag tag, int n); 137 void tag_local(Register tag, int n); 138 void tag_local(frame::Tag tag, Register idx); 139 void tag_local(Register tag, Register idx); 140 141 #ifdef ASSERT 142 void verify_local_tag(frame::Tag tag, int n); 143 void verify_local_tag(frame::Tag tag, Register idx); 144 #endif // ASSERT 145 146 147 void empty_expression_stack() 148 { 123 void empty_expression_stack() { 149 124 movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); 150 125 // NULL last_sp until next java call 151 126 movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 152 127 } 128 129 // Helpers for swap and dup 130 void load_ptr(int n, Register val); 131 void store_ptr(int n, Register val); 153 132 154 133 // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls … … 222 201 223 202 void record_klass_in_profile(Register receiver, Register mdp, 224 Register reg2 );203 Register reg2, bool is_virtual_call); 225 204 void record_klass_in_profile_helper(Register receiver, Register mdp, 226 Register reg2, 227 int start_row, Label& done);205 Register reg2, int start_row, 206 Label& done, bool is_virtual_call); 228 207 229 208 void update_mdp_by_offset(Register mdp_in, int offset_of_offset); … … 237 216 void profile_final_call(Register mdp); 238 217 void profile_virtual_call(Register receiver, Register mdp, 239 Register scratch2); 218 Register scratch2, 219 bool receiver_can_be_null = false); 240 220 void profile_ret(Register return_bci, Register mdp); 241 221 void profile_null_seen(Register mdp); -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreterRT_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 32 32 // Implementation of SignatureHandlerGenerator 33 33 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { 34 move(offset(), jni_offset() + 1); 35 } 36 37 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { 34 38 move(offset(), jni_offset() + 1); 35 39 } … … 87 91 intptr_t* _to; 88 92 89 #ifdef ASSERT90 void verify_tag(frame::Tag t) {91 assert(!TaggedStackInterpreter ||92 *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag");93 }94 #endif // ASSERT95 96 93 virtual void pass_int() { 97 94 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 98 debug_only(verify_tag(frame::TagValue)); 99 _from -= Interpreter::stackElementSize(); 95 _from -= Interpreter::stackElementSize; 96 } 97 98 virtual void pass_float() { 99 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 100 _from -= Interpreter::stackElementSize; 100 101 } 101 102 … … 103 104 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 104 105 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 105 debug_only(verify_tag(frame::TagValue));106 106 _to += 2; 107 _from -= 2*Interpreter::stackElementSize ();107 _from -= 2*Interpreter::stackElementSize; 108 108 } 109 109 … … 112 112 intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0)); 113 113 *_to++ = (*(intptr_t*)from_addr == 0) ? NULL_WORD : from_addr; 114 debug_only(verify_tag(frame::TagReference)); 115 _from -= Interpreter::stackElementSize(); 114 _from -= Interpreter::stackElementSize; 116 115 } 117 116 -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 294 294 unsigned int _num_args; 295 295 296 #ifdef ASSERT297 void verify_tag(frame::Tag t) {298 assert(!TaggedStackInterpreter ||299 *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag");300 }301 #endif // ASSERT302 303 296 virtual void pass_int() 304 297 { 305 298 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 306 debug_only(verify_tag(frame::TagValue)); 307 _from -= Interpreter::stackElementSize(); 299 _from -= Interpreter::stackElementSize; 308 300 309 301 if (_num_args < Argument::n_int_register_parameters_c-1) { … … 318 310 { 319 311 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 320 debug_only(verify_tag(frame::TagValue)); 321 _from -= 2*Interpreter::stackElementSize(); 312 _from -= 2*Interpreter::stackElementSize; 322 313 323 314 if (_num_args < Argument::n_int_register_parameters_c-1) { … … 332 323 { 333 324 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); 334 debug_only(verify_tag(frame::TagReference)); 335 _from -= Interpreter::stackElementSize(); 325 _from -= Interpreter::stackElementSize; 336 326 if (_num_args < Argument::n_int_register_parameters_c-1) { 337 327 *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; … … 345 335 { 346 336 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 347 debug_only(verify_tag(frame::TagValue)); 348 _from -= Interpreter::stackElementSize(); 337 _from -= Interpreter::stackElementSize; 349 338 350 339 if (_num_args < Argument::n_float_register_parameters_c-1) { … … 360 349 { 361 350 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 362 debug_only(verify_tag(frame::TagValue)); 363 _from -= 2*Interpreter::stackElementSize(); 351 _from -= 2*Interpreter::stackElementSize; 364 352 365 353 if (_num_args < Argument::n_float_register_parameters_c-1) { … … 398 386 unsigned int _num_fp_args; 399 387 400 #ifdef ASSERT401 void verify_tag(frame::Tag t) {402 assert(!TaggedStackInterpreter ||403 *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag");404 }405 #endif // ASSERT406 407 388 virtual void pass_int() 408 389 { 409 390 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 410 debug_only(verify_tag(frame::TagValue)); 411 _from -= Interpreter::stackElementSize(); 391 _from -= Interpreter::stackElementSize; 412 392 413 393 if (_num_int_args < Argument::n_int_register_parameters_c-1) { … … 422 402 { 423 403 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 424 debug_only(verify_tag(frame::TagValue)); 425 _from -= 2*Interpreter::stackElementSize(); 404 _from -= 2*Interpreter::stackElementSize; 426 405 427 406 if (_num_int_args < Argument::n_int_register_parameters_c-1) { … … 436 415 { 437 416 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); 438 debug_only(verify_tag(frame::TagReference)); 439 _from -= Interpreter::stackElementSize(); 417 _from -= Interpreter::stackElementSize; 440 418 441 419 if (_num_int_args < Argument::n_int_register_parameters_c-1) { … … 450 428 { 451 429 jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0)); 452 debug_only(verify_tag(frame::TagValue)); 453 _from -= Interpreter::stackElementSize(); 430 _from -= Interpreter::stackElementSize; 454 431 455 432 if (_num_fp_args < Argument::n_float_register_parameters_c) { … … 464 441 { 465 442 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 466 _from -= 2*Interpreter::stackElementSize ();443 _from -= 2*Interpreter::stackElementSize; 467 444 468 445 if (_num_fp_args < Argument::n_float_register_parameters_c) { -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreter_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 32 32 static const int return_sentinel; 33 33 34 35 static Address::ScaleFactor stackElementScale() { 36 return TaggedStackInterpreter? Address::times_8 : Address::times_4; 37 } 34 static Address::ScaleFactor stackElementScale() { return Address::times_4; } 38 35 39 36 // Offset from rsp (which points to the last stack element) 40 static int expr_offset_in_bytes(int i) { return stackElementSize()*i ; } 41 static int expr_tag_offset_in_bytes(int i) { 42 assert(TaggedStackInterpreter, "should not call this"); 43 return expr_offset_in_bytes(i) + wordSize; 44 } 45 46 // Support for Tagged Stacks 37 static int expr_offset_in_bytes(int i) { return stackElementSize * i; } 47 38 48 39 // Stack index relative to tos (which points at value) 49 static int expr_index_at(int i) { 50 return stackElementWords() * i; 51 } 52 53 static int expr_tag_index_at(int i) { 54 assert(TaggedStackInterpreter, "should not call this"); 55 // tag is one word above java stack element 56 return stackElementWords() * i + 1; 57 } 40 static int expr_index_at(int i) { return stackElementWords * i; } 58 41 59 42 // Already negated by c++ interpreter 60 static int local_index_at(int i) 61 assert(i <=0, "local direction already negated");62 return stackElementWords () * i + (value_offset_in_bytes()/wordSize);43 static int local_index_at(int i) { 44 assert(i <= 0, "local direction already negated"); 45 return stackElementWords * i; 63 46 } 64 65 static int local_tag_index_at(int i) {66 assert(i<=0, "local direction already negated");67 assert(TaggedStackInterpreter, "should not call this");68 return stackElementWords() * i + (tag_offset_in_bytes()/wordSize);69 } -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 132 132 // this entry point for the corresponding methods in JDK 1.3. 133 133 // get argument 134 if (TaggedStackInterpreter) { 135 __ pushl(Address(rsp, 3*wordSize)); // push hi (and note rsp -= wordSize) 136 __ pushl(Address(rsp, 2*wordSize)); // push lo 137 __ fld_d(Address(rsp, 0)); // get double in ST0 138 __ addptr(rsp, 2*wordSize); 139 } else { 140 __ fld_d(Address(rsp, 1*wordSize)); 141 } 134 __ fld_d(Address(rsp, 1*wordSize)); 142 135 switch (kind) { 143 136 case Interpreter::java_lang_math_sin : -
trunk/openjdk/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 278 278 279 279 // abstract method entry 280 // remove return address. Not really needed, since exception 281 // handling throws away expression stack 282 __ pop(rbx); 283 284 // adjust stack to what a normal return would do 285 __ mov(rsp, r13); 280 281 // pop return address, reset last_sp to NULL 282 __ empty_expression_stack(); 283 __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) 284 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) 286 285 287 286 // throw exception … … 301 300 return generate_abstract_entry(); 302 301 } 303 return generate_abstract_entry(); //6815692// 302 303 address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm); 304 305 return entry_point; 304 306 } 305 307 -
trunk/openjdk/hotspot/src/cpu/x86/vm/javaFrameAnchor_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 67 67 intptr_t* last_Java_sp(void) const { return _last_Java_sp; } 68 68 69 address last_Java_pc(void) { return _last_Java_pc; } 70 69 71 private: 70 72 -
trunk/openjdk/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp
r58 r278 1 1 /* 2 * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/jniTypes_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1998-2003 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/jni_x86.h
r46 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * 5 5 * This code is free software; you can redistribute it and/or modify it 6 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Sundesignates this7 * published by the Free Software Foundation. Oracle designates this 8 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sunin the LICENSE file that accompanied this code.9 * by Oracle in the LICENSE file that accompanied this code. 10 10 * 11 11 * This code is distributed in the hope that it will be useful, but WITHOUT … … 19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 20 * 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,22 * CA 95054 USA or visit www.sun.com if you need additional information or23 * have anyquestions.21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 24 */ 25 25 -
trunk/openjdk/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 61 61 62 62 #ifdef ASSERT 63 static void verify_argslot(MacroAssembler* _masm, Register rax_argslot,63 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, 64 64 const char* error_message) { 65 65 // Verify that argslot lies within (rsp, rbp]. 66 66 Label L_ok, L_bad; 67 __ cmpptr( rax_argslot, rbp);68 __ jcc (Assembler::above, L_bad);69 __ cmpptr(rsp, rax_argslot);70 __ jcc (Assembler::below, L_ok);67 __ cmpptr(argslot_reg, rbp); 68 __ jccb(Assembler::above, L_bad); 69 __ cmpptr(rsp, argslot_reg); 70 __ jccb(Assembler::below, L_ok); 71 71 __ bind(L_bad); 72 72 __ stop(error_message); … … 128 128 int arg_mask, 129 129 Register rax_argslot, 130 Register rbx_temp, Register rdx_temp) { 130 Register rbx_temp, Register rdx_temp, Register temp3_reg) { 131 assert(temp3_reg == noreg, "temp3 not required"); 131 132 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, 132 133 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); … … 137 138 Label L_ok, L_bad; 138 139 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); 139 __ jcc (Assembler::greater, L_bad);140 __ jccb(Assembler::greater, L_bad); 140 141 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); 141 __ jcc (Assembler::zero, L_ok);142 __ jccb(Assembler::zero, L_ok); 142 143 __ bind(L_bad); 143 144 __ stop("assert arg_slots <= 0 and clear low bits"); … … 174 175 __ addptr(rdx_temp, wordSize); 175 176 __ cmpptr(rdx_temp, rax_argslot); 176 __ jcc (Assembler::less, loop);177 __ jccb(Assembler::less, loop); 177 178 } 178 179 179 180 // Now move the argslot down, to point to the opened-up space. 180 181 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); 181 182 if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) {183 // The caller has specified a bitmask of tags to put into the opened space.184 // This only works when the arg_slots value is an assembly-time constant.185 int constant_arg_slots = arg_slots.as_constant() / stack_move_unit();186 int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();187 for (int slot = 0; slot < constant_arg_slots; slot++) {188 BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT);189 int slot_offset = Interpreter::stackElementSize() * slot;190 Address tag_addr(rax_argslot, slot_offset + tag_offset);191 __ movptr(tag_addr, frame::tag_for_basic_type(slot_type));192 }193 // Note that the new argument slots are tagged properly but contain194 // garbage at this point. The value portions must be initialized195 // by the caller. (Especially references!)196 }197 182 } 198 183 … … 202 187 RegisterOrConstant arg_slots, 203 188 Register rax_argslot, 204 Register rbx_temp, Register rdx_temp) { 189 Register rbx_temp, Register rdx_temp, Register temp3_reg) { 190 assert(temp3_reg == noreg, "temp3 not required"); 205 191 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, 206 192 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); 207 193 208 194 #ifdef ASSERT 209 { 210 // Verify that [argslot..argslot+size) lies within (rsp, rbp). 211 Label L_ok, L_bad; 212 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 213 __ cmpptr(rbx_temp, rbp); 214 __ jcc(Assembler::above, L_bad); 215 __ cmpptr(rsp, rax_argslot); 216 __ jcc(Assembler::below, L_ok); 217 __ bind(L_bad); 218 __ stop("deleted argument(s) must fall within current frame"); 219 __ bind(L_ok); 220 } 195 // Verify that [argslot..argslot+size) lies within (rsp, rbp). 196 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 197 verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame"); 221 198 if (arg_slots.is_register()) { 222 199 Label L_ok, L_bad; 223 200 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); 224 __ jcc (Assembler::less, L_bad);201 __ jccb(Assembler::less, L_bad); 225 202 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); 226 __ jcc (Assembler::zero, L_ok);203 __ jccb(Assembler::zero, L_ok); 227 204 __ bind(L_bad); 228 205 __ stop("assert arg_slots >= 0 and clear low bits"); … … 259 236 __ addptr(rdx_temp, -wordSize); 260 237 __ cmpptr(rdx_temp, rsp); 261 __ jcc (Assembler::greaterEqual, loop);238 __ jccb(Assembler::greaterEqual, loop); 262 239 } 263 240 … … 269 246 270 247 #ifndef PRODUCT 248 extern "C" void print_method_handle(oop mh); 271 249 void trace_method_handle_stub(const char* adaptername, 272 oop Desc*mh,250 oop mh, 273 251 intptr_t* entry_sp, 274 intptr_t* saved_sp) { 252 intptr_t* saved_sp, 253 intptr_t* saved_bp) { 275 254 // called as a leaf from native code: do not block the JVM! 276 printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, (void*)mh, entry_sp, entry_sp - saved_sp); 255 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; 256 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; 257 printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n", 258 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); 259 if (last_sp != saved_sp) 260 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp); 261 if (Verbose) print_method_handle(mh); 277 262 } 278 263 #endif //PRODUCT 264 265 // which conversion op types are implemented here? 266 int MethodHandles::adapter_conversion_ops_supported_mask() { 267 return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY) 268 |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) 269 |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST) 270 |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM) 271 |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM) 272 |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS) 273 |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS) 274 |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS) 275 |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS) 276 //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG! 277 ); 278 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. 279 } 279 280 280 281 // Generate an "entry" field for a method handle. … … 294 295 Register rdx_temp = rdx; 295 296 297 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls) 298 // and gen_c2i_adapter (from compiled calls): 299 Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi); 300 296 301 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); 297 302 … … 310 315 Address vmarg; // __ argument_address(vmargslot) 311 316 312 int tag_offset = -1; 313 if (TaggedStackInterpreter) { 314 tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); 315 assert(tag_offset = wordSize, "stack grows as expected"); 316 } 317 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); 317 318 318 319 if (have_entry(ek)) { … … 329 330 __ lea(rax, Address(rsp, wordSize*6)); // entry_sp 330 331 // arguments: 332 __ push(rbp); // interpreter frame pointer 331 333 __ push(rsi); // saved_sp 332 334 __ push(rax); // entry_sp … … 334 336 __ push(rcx); 335 337 __ movptr(Address(rsp, 0), (intptr_t)entry_name(ek)); 336 __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 4);338 __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5); 337 339 __ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax); 338 340 } … … 340 342 341 343 switch ((int) ek) { 342 case _check_mtype: 343 { 344 // this stub is special, because it requires a live mtype argument 345 Register rax_mtype = rax; 346 347 // emit WrongMethodType path first, to enable jccb back-branch 348 Label wrong_method_type; 349 __ bind(wrong_method_type); 350 __ movptr(rdx_temp, ExternalAddress((address) &_entries[_wrong_method_type])); 351 __ jmp(Address(rdx_temp, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); 352 __ hlt(); 353 354 interp_entry = __ pc(); 355 __ check_method_handle_type(rax_mtype, rcx_recv, rdx_temp, wrong_method_type); 356 // now rax_mtype is dead; subsequent stubs will use it as a temp 357 358 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 359 } 360 break; 361 362 case _wrong_method_type: 363 { 364 // this stub is special, because it requires a live mtype argument 365 Register rax_mtype = rax; 366 367 interp_entry = __ pc(); 368 __ push(rax_mtype); // required mtype 369 __ push(rcx_recv); // random mh (1st stacked argument) 344 case _raise_exception: 345 { 346 // Not a real MH entry, but rather shared code for raising an exception. 347 // Extra local arguments are pushed on stack, as required type at TOS+8, 348 // failing object (or NULL) at TOS+4, failing bytecode type at TOS. 349 // Beyond those local arguments are the PC, of course. 350 Register rdx_code = rdx_temp; 351 Register rcx_fail = rcx_recv; 352 Register rax_want = rax_argslot; 353 Register rdi_pc = rdi; 354 __ pop(rdx_code); // TOS+0 355 __ pop(rcx_fail); // TOS+4 356 __ pop(rax_want); // TOS+8 357 __ pop(rdi_pc); // caller PC 358 359 __ mov(rsp, rsi); // cut the stack back to where the caller started 360 361 // Repush the arguments as if coming from the interpreter. 362 __ push(rdx_code); 363 __ push(rcx_fail); 364 __ push(rax_want); 365 366 Register rbx_method = rbx_temp; 367 Label no_method; 368 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method 369 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); 370 __ testptr(rbx_method, rbx_method); 371 __ jccb(Assembler::zero, no_method); 372 int jobject_oop_offset = 0; 373 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject 374 __ testptr(rbx_method, rbx_method); 375 __ jccb(Assembler::zero, no_method); 376 __ verify_oop(rbx_method); 377 __ push(rdi_pc); // and restore caller PC 378 __ jmp(rbx_method_fie); 379 380 // If we get here, the Java runtime did not do its job of creating the exception. 381 // Do something that is at least causes a valid throw from the interpreter. 382 __ bind(no_method); 383 __ pop(rax_want); 384 __ pop(rcx_fail); 385 __ push(rax_want); 386 __ push(rcx_fail); 370 387 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 371 388 } … … 417 434 base + vtableEntry::method_offset_in_bytes()); 418 435 Register rbx_method = rbx_temp; 419 __ mov l(rbx_method, vtable_entry_addr);436 __ movptr(rbx_method, vtable_entry_addr); 420 437 421 438 __ verify_oop(rbx_method); … … 443 460 __ verify_oop(rax_klass); 444 461 445 Register r cx_temp = rcx_recv;462 Register rdi_temp = rdi; 446 463 Register rbx_method = rbx_index; 447 464 … … 452 469 // note: next two args must be the same: 453 470 rbx_index, rbx_method, 454 r cx_temp,471 rdi_temp, 455 472 no_such_interface); 456 473 … … 462 479 // Throw an exception. 463 480 // For historical reasons, it will be IncompatibleClassChangeError. 464 __ should_not_reach_here(); // %%% FIXME NYI 481 __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface 482 __ push(rcx_recv); // bad receiver 483 __ push((int)Bytecodes::_invokeinterface); // who is complaining? 484 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 465 485 } 466 486 break; … … 474 494 { 475 495 bool direct_to_method = (ek >= _bound_ref_direct_mh); 476 BasicType arg_type = T_ILLEGAL; 477 if (ek == _bound_long_mh || ek == _bound_long_direct_mh) { 478 arg_type = T_LONG; 479 } else if (ek == _bound_int_mh || ek == _bound_int_direct_mh) { 480 arg_type = T_INT; 481 } else { 482 assert(ek == _bound_ref_mh || ek == _bound_ref_direct_mh, "must be ref"); 483 arg_type = T_OBJECT; 484 } 485 int arg_slots = type2size[arg_type]; 486 int arg_mask = (arg_type == T_OBJECT ? _INSERT_REF_MASK : 487 arg_slots == 1 ? _INSERT_INT_MASK : _INSERT_LONG_MASK); 496 BasicType arg_type = T_ILLEGAL; 497 int arg_mask = _INSERT_NO_MASK; 498 int arg_slots = -1; 499 get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots); 488 500 489 501 // make room for the new argument: … … 499 511 __ movptr(Address(rax_argslot, 0), rbx_temp); 500 512 } else { 501 __ load_sized_value(r bx_temp, prim_value_addr,513 __ load_sized_value(rdx_temp, prim_value_addr, 502 514 type2aelembytes(arg_type), is_signed_subword_type(arg_type)); 503 __ movptr(Address(rax_argslot, 0), r bx_temp);515 __ movptr(Address(rax_argslot, 0), rdx_temp); 504 516 #ifndef _LP64 505 517 if (arg_slots == 2) { 506 __ movl(r bx_temp, prim_value_addr.plus_disp(wordSize));507 __ movl(Address(rax_argslot, Interpreter::stackElementSize ()), rbx_temp);518 __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize)); 519 __ movl(Address(rax_argslot, Interpreter::stackElementSize), rdx_temp); 508 520 } 509 521 #endif //_LP64 510 break;511 522 } 512 523 … … 525 536 526 537 case _adapter_retype_only: 538 case _adapter_retype_raw: 527 539 // immediately jump to the next MH layer: 528 540 __ movptr(rcx_recv, rcx_mh_vmtarget); … … 546 558 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 547 559 548 // get the new MH:549 __ movptr(rcx_recv, rcx_mh_vmtarget);550 // (now we are done with the old MH)551 552 560 Label done; 553 561 __ movptr(rdx_temp, vmarg); 554 __ test l(rdx_temp, rdx_temp);555 __ jcc (Assembler::zero, done);// no cast if null562 __ testptr(rdx_temp, rdx_temp); 563 __ jccb(Assembler::zero, done); // no cast if null 556 564 __ load_klass(rdx_temp, rdx_temp); 557 565 … … 559 567 // - rbx_klass: klass required by the target method 560 568 // - rdx_temp: argument klass to test 561 // - rcx_recv: method handle to invoke (after cast succeeds)569 // - rcx_recv: adapter method handle 562 570 __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done); 563 571 … … 565 573 // Call the wrong_method_type stub, passing the failing argument type in rax. 566 574 Register rax_mtype = rax_argslot; 567 __ push(rbx_klass); // missed klass (required type) 568 __ push(rdx_temp); // bad actual type (1st stacked argument) 569 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 575 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field 576 __ movptr(rdx_temp, vmarg); 577 578 __ pushptr(rcx_amh_argument); // required class 579 __ push(rdx_temp); // bad object 580 __ push((int)Bytecodes::_checkcast); // who is complaining? 581 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 570 582 571 583 __ bind(done); 584 // get the new MH: 585 __ movptr(rcx_recv, rcx_mh_vmtarget); 572 586 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 573 587 } … … 599 613 remove_arg_slots(_masm, -stack_move_unit(), 600 614 rax_argslot, rbx_temp, rdx_temp); 601 vmarg = Address(rax_argslot, -Interpreter::stackElementSize ());615 vmarg = Address(rax_argslot, -Interpreter::stackElementSize); 602 616 __ movl(rdx_temp, vmarg); 603 617 } … … 622 636 break; 623 637 default: 624 assert(false, ""); 625 } 626 goto finish_int_conversion; 627 } 628 629 finish_int_conversion: 630 { 638 ShouldNotReachHere(); 639 } 640 641 // Do the requested conversion and store the value. 631 642 Register rbx_vminfo = rbx_temp; 632 643 __ movl(rbx_vminfo, rcx_amh_conversion); … … 638 649 639 650 // original 32-bit vmdata word must be of this form: 640 // | MBZ: 16 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |641 __ xchg l(rcx, rbx_vminfo); // free rcx for shifts651 // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 | 652 __ xchgptr(rcx, rbx_vminfo); // free rcx for shifts 642 653 __ shll(rdx_temp /*, rcx*/); 643 654 Label zero_extend, done; 644 655 __ testl(rcx, CONV_VMINFO_SIGN_FLAG); 645 __ jcc (Assembler::zero, zero_extend);656 __ jccb(Assembler::zero, zero_extend); 646 657 647 658 // this path is taken for int->byte, int->short 648 659 __ sarl(rdx_temp /*, rcx*/); 649 __ jmp (done);660 __ jmpb(done); 650 661 651 662 __ bind(zero_extend); … … 654 665 655 666 __ bind(done); 656 __ mov ptr(vmarg, rdx_temp);657 __ xchg l(rcx, rbx_vminfo); // restore rcx_recv667 __ movl(vmarg, rdx_temp); // Store the value. 668 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv 658 669 659 670 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); … … 671 682 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK, 672 683 rax_argslot, rbx_temp, rdx_temp); 673 Address vmarg1(rax_argslot, -Interpreter::stackElementSize ());674 Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize ());684 Address vmarg1(rax_argslot, -Interpreter::stackElementSize); 685 Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize); 675 686 676 687 switch (ek) { 677 688 case _adapter_opt_i2l: 678 689 { 690 #ifdef _LP64 691 __ movslq(rdx_temp, vmarg1); // Load sign-extended 692 __ movq(vmarg1, rdx_temp); // Store into first slot 693 #else 679 694 __ movl(rdx_temp, vmarg1); 680 __ sarl(rdx_temp, 31); // __ extend_sign()695 __ sarl(rdx_temp, BitsPerInt - 1); // __ extend_sign() 681 696 __ movl(vmarg2, rdx_temp); // store second word 697 #endif 682 698 } 683 699 break; … … 689 705 assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), ""); 690 706 __ null_check(rdx_temp, value_offset); 707 #ifdef _LP64 708 __ movq(rbx_temp, Address(rdx_temp, value_offset)); 709 __ movq(vmarg1, rbx_temp); 710 #else 691 711 __ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt)); 692 712 __ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt)); 693 713 __ movl(vmarg1, rbx_temp); 694 714 __ movl(vmarg2, rdx_temp); 715 #endif 695 716 } 696 717 break; 697 718 default: 698 assert(false, "");719 ShouldNotReachHere(); 699 720 } 700 721 … … 714 735 rax_argslot, rbx_temp, rdx_temp); 715 736 } 716 Address vmarg(rax_argslot, -Interpreter::stackElementSize ());737 Address vmarg(rax_argslot, -Interpreter::stackElementSize); 717 738 718 739 #ifdef _LP64 … … 730 751 __ fld_s(vmarg); // load float to ST0 731 752 __ fstp_s(vmarg); // store single 732 } else if (!TaggedStackInterpreter){753 } else { 733 754 __ fld_d(vmarg); // load double to ST0 734 __ fstp_s(vmarg); // store single735 } else {736 Address vmarg_tag = vmarg.plus_disp(tag_offset);737 Address vmarg2 = vmarg.plus_disp(Interpreter::stackElementSize());738 // vmarg2_tag does not participate in this code739 Register rbx_tag = rbx_temp;740 __ movl(rbx_tag, vmarg_tag); // preserve tag741 __ movl(rdx_temp, vmarg2); // get second word of double742 __ movl(vmarg_tag, rdx_temp); // align with first word743 __ fld_d(vmarg); // load double to ST0744 __ movl(vmarg_tag, rbx_tag); // restore tag745 755 __ fstp_s(vmarg); // store single 746 756 } … … 774 784 case _adapter_opt_rot_2_down: 775 785 { 776 int rotate = 0, swap_slots = 0; 777 switch ((int)ek) { 778 case _adapter_opt_swap_1: swap_slots = 1; break; 779 case _adapter_opt_swap_2: swap_slots = 2; break; 780 case _adapter_opt_rot_1_up: swap_slots = 1; rotate++; break; 781 case _adapter_opt_rot_1_down: swap_slots = 1; rotate--; break; 782 case _adapter_opt_rot_2_up: swap_slots = 2; rotate++; break; 783 case _adapter_opt_rot_2_down: swap_slots = 2; rotate--; break; 784 default: assert(false, ""); 785 } 786 787 // the real size of the move must be doubled if TaggedStackInterpreter: 788 int swap_bytes = (int)( swap_slots * Interpreter::stackElementWords() * wordSize ); 786 int swap_bytes = 0, rotate = 0; 787 get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate); 789 788 790 789 // 'argslot' is the position of the first argument to swap … … 824 823 Label L_ok; 825 824 __ cmpptr(rax_argslot, rbx_destslot); 826 __ jcc (Assembler::aboveEqual, L_ok);825 __ jccb(Assembler::aboveEqual, L_ok); 827 826 __ stop("source must be above destination (upward rotation)"); 828 827 __ bind(L_ok); … … 840 839 __ addptr(rax_argslot, -wordSize); 841 840 __ cmpptr(rax_argslot, rbx_destslot); 842 __ jcc (Assembler::aboveEqual, loop);841 __ jccb(Assembler::aboveEqual, loop); 843 842 } else { 844 843 __ addptr(rax_argslot, swap_bytes); … … 848 847 Label L_ok; 849 848 __ cmpptr(rax_argslot, rbx_destslot); 850 __ jcc (Assembler::belowEqual, L_ok);849 __ jccb(Assembler::belowEqual, L_ok); 851 850 __ stop("source must be below destination (downward rotation)"); 852 851 __ bind(L_ok); … … 864 863 __ addptr(rax_argslot, wordSize); 865 864 __ cmpptr(rax_argslot, rbx_destslot); 866 __ jcc (Assembler::belowEqual, loop);865 __ jccb(Assembler::belowEqual, loop); 867 866 } 868 867 … … 887 886 // 'stack_move' is negative number of words to duplicate 888 887 Register rdx_stack_move = rdx_temp; 889 __ movl (rdx_stack_move, rcx_amh_conversion);890 __ sar l(rdx_stack_move, CONV_STACK_MOVE_SHIFT);888 __ movl2ptr(rdx_stack_move, rcx_amh_conversion); 889 __ sarptr(rdx_stack_move, CONV_STACK_MOVE_SHIFT); 891 890 892 891 int argslot0_num = 0; … … 930 929 __ addptr(rdx_newarg, wordSize); 931 930 __ cmpptr(rdx_newarg, rbx_oldarg); 932 __ jcc (Assembler::less, loop);931 __ jccb(Assembler::less, loop); 933 932 934 933 __ pop(rdi); // restore temp … … 950 949 // 'stack_move' is number of words to drop 951 950 Register rdi_stack_move = rdi; 952 __ movl (rdi_stack_move, rcx_amh_conversion);953 __ sar l(rdi_stack_move, CONV_STACK_MOVE_SHIFT);951 __ movl2ptr(rdi_stack_move, rcx_amh_conversion); 952 __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 954 953 remove_arg_slots(_masm, rdi_stack_move, 955 954 rax_argslot, rbx_temp, rdx_temp); … … 976 975 { 977 976 // spread an array out into a group of arguments 978 int length_constant = -1; 979 switch (ek) { 980 case _adapter_opt_spread_0: length_constant = 0; break; 981 case _adapter_opt_spread_1: length_constant = 1; break; 982 } 977 int length_constant = get_ek_adapter_opt_spread_info(ek); 983 978 984 979 // find the address of the array argument … … 1038 1033 if (length_constant == -1) { 1039 1034 // Form a pointer to the end of the affected region. 1040 __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize ()));1035 __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize)); 1041 1036 // 'stack_move' is negative number of words to insert 1042 1037 Register rdi_stack_move = rdi; 1043 __ movl (rdi_stack_move, rcx_amh_conversion);1044 __ sar l(rdi_stack_move, CONV_STACK_MOVE_SHIFT);1038 __ movl2ptr(rdi_stack_move, rcx_amh_conversion); 1039 __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 1045 1040 Register rsi_temp = rsi_array; // spill this 1046 1041 insert_arg_slots(_masm, rdi_stack_move, -1, … … 1076 1071 __ movptr(Address(rax_argslot, 0), rbx_temp); 1077 1072 __ addptr(rsi_source, type2aelembytes(elem_type)); 1078 if (TaggedStackInterpreter) { 1079 __ movptr(Address(rax_argslot, tag_offset), 1080 frame::tag_for_basic_type(elem_type)); 1081 } 1082 __ addptr(rax_argslot, Interpreter::stackElementSize()); 1073 __ addptr(rax_argslot, Interpreter::stackElementSize); 1083 1074 __ cmpptr(rax_argslot, rdx_argslot_limit); 1084 __ jcc (Assembler::less, loop);1075 __ jccb(Assembler::less, loop); 1085 1076 } else if (length_constant == 0) { 1086 1077 __ bind(skip_array_check); … … 1093 1084 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); 1094 1085 elem_offset += type2aelembytes(elem_type); 1095 if (TaggedStackInterpreter) { 1096 __ movptr(Address(rax_argslot, slot_offset + tag_offset), 1097 frame::tag_for_basic_type(elem_type)); 1098 } 1099 slot_offset += Interpreter::stackElementSize(); 1086 slot_offset += Interpreter::stackElementSize; 1100 1087 } 1101 1088 } … … 1108 1095 __ bind(bad_array_klass); 1109 1096 UNPUSH_RSI_RDI; 1110 __ stop("bad array klass NYI"); 1097 __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type 1098 __ pushptr(vmarg); // bad array 1099 __ push((int)Bytecodes::_aaload); // who is complaining? 1100 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 1111 1101 1112 1102 __ bind(bad_array_length); 1113 1103 UNPUSH_RSI_RDI; 1114 __ stop("bad array length NYI"); 1104 __ push(rcx_recv); // AMH requiring a certain length 1105 __ pushptr(vmarg); // bad array 1106 __ push((int)Bytecodes::_arraylength); // who is complaining? 1107 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 1115 1108 1116 1109 #undef UNPUSH_RSI_RDI -
trunk/openjdk/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/registerMap_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/register_definitions_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 116 116 REGISTER_DEFINITION(MMXRegister, mmx6 ); 117 117 REGISTER_DEFINITION(MMXRegister, mmx7 ); 118 119 // JSR 292 120 REGISTER_DEFINITION(Register, rbp_mh_SP_save); -
trunk/openjdk/hotspot/src/cpu/x86/vm/register_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/register_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/relocInfo_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 44 44 // 45 45 // Arguments: 46 // rax ,: exception oop46 // rax: exception oop 47 47 // rdx: exception pc 48 48 // 49 49 // Results: 50 // rax ,: exception oop50 // rax: exception oop 51 51 // rdx: exception pc in caller or ??? 52 52 // destination: exception handler of caller … … 114 114 __ pop(rdx); // Exception pc 115 115 116 // rax: exception handler for given <exception oop/exception pc> 116 117 117 // rax,: exception handler for given <exception oop/exception pc> 118 // Restore SP from BP if the exception PC is a MethodHandle call site. 119 __ cmpl(Address(rcx, JavaThread::is_method_handle_return_offset()), 0); 120 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); 118 121 119 122 // We have a handler in rax, (could be deopt blob) … … 122 125 __ push(rax); 123 126 124 // rcx contains handler address125 126 __ get_thread(rcx); // TLS127 127 // Get the exception 128 128 __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); … … 138 138 __ pop(rcx); 139 139 140 // rax ,: exception oop140 // rax: exception oop 141 141 // rcx: exception handler 142 142 // rdx: exception pc -
trunk/openjdk/hotspot/src/cpu/x86/vm/runtime_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 504 504 505 505 506 // Helper function to put tags in interpreter stack.507 static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) {508 if (TaggedStackInterpreter) {509 int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0);510 if (sig == T_OBJECT || sig == T_ARRAY) {511 __ movptr(Address(rsp, tag_offset), frame::TagReference);512 } else if (sig == T_LONG || sig == T_DOUBLE) {513 int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1);514 __ movptr(Address(rsp, next_tag_offset), frame::TagValue);515 __ movptr(Address(rsp, tag_offset), frame::TagValue);516 } else {517 __ movptr(Address(rsp, tag_offset), frame::TagValue);518 }519 }520 }521 522 // Double and long values with Tagged stacks are not contiguous.523 506 static void move_c2i_double(MacroAssembler *masm, XMMRegister r, int st_off) { 524 int next_off = st_off - Interpreter::stackElementSize(); 525 if (TaggedStackInterpreter) { 526 __ movdbl(Address(rsp, next_off), r); 527 // Move top half up and put tag in the middle. 528 __ movl(rdi, Address(rsp, next_off+wordSize)); 529 __ movl(Address(rsp, st_off), rdi); 530 tag_stack(masm, T_DOUBLE, next_off); 531 } else { 532 __ movdbl(Address(rsp, next_off), r); 533 } 507 int next_off = st_off - Interpreter::stackElementSize; 508 __ movdbl(Address(rsp, next_off), r); 534 509 } 535 510 … … 561 536 // stack_element_size is the 562 537 // space we need. 563 int extraspace = total_args_passed * Interpreter::stackElementSize ();538 int extraspace = total_args_passed * Interpreter::stackElementSize; 564 539 565 540 // Get return address … … 579 554 580 555 // st_off points to lowest address on stack. 581 int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize ();582 int next_off = st_off - Interpreter::stackElementSize ();556 int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize; 557 int next_off = st_off - Interpreter::stackElementSize; 583 558 584 559 // Say 4 args: … … 602 577 __ movl(rdi, Address(rsp, ld_off)); 603 578 __ movptr(Address(rsp, st_off), rdi); 604 tag_stack(masm, sig_bt[i], st_off);605 579 } else { 606 580 … … 620 594 #endif /* ASSERT */ 621 595 #endif // _LP64 622 tag_stack(masm, sig_bt[i], next_off);623 596 } 624 597 } else if (r_1->is_Register()) { … … 626 599 if (!r_2->is_valid()) { 627 600 __ movl(Address(rsp, st_off), r); 628 tag_stack(masm, sig_bt[i], st_off);629 601 } else { 630 602 // long/double in gpr … … 640 612 #endif /* ASSERT */ 641 613 __ movptr(Address(rsp, next_off), r); 642 tag_stack(masm, sig_bt[i], next_off);643 614 } else { 644 615 __ movptr(Address(rsp, st_off), r); 645 tag_stack(masm, sig_bt[i], st_off);646 616 } 647 617 } … … 650 620 if (!r_2->is_valid()) { 651 621 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); 652 tag_stack(masm, sig_bt[i], st_off);653 622 } else { 654 623 assert(sig_bt[i] == T_DOUBLE || sig_bt[i] == T_LONG, "wrong type"); … … 666 635 667 636 668 // For tagged stacks, double or long value aren't contiguous on the stack669 // so get them contiguous for the xmm load670 637 static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_sp, int ld_off) { 671 int next_val_off = ld_off - Interpreter::stackElementSize(); 672 if (TaggedStackInterpreter) { 673 // use tag slot temporarily for MSW 674 __ movptr(rsi, Address(saved_sp, ld_off)); 675 __ movptr(Address(saved_sp, next_val_off+wordSize), rsi); 676 __ movdbl(r, Address(saved_sp, next_val_off)); 677 // restore tag 678 __ movptr(Address(saved_sp, next_val_off+wordSize), frame::TagValue); 679 } else { 680 __ movdbl(r, Address(saved_sp, next_val_off)); 681 } 638 int next_val_off = ld_off - Interpreter::stackElementSize; 639 __ movdbl(r, Address(saved_sp, next_val_off)); 682 640 } 683 641 … … 798 756 "scrambled load targets?"); 799 757 // Load in argument order going down. 800 int ld_off = (total_args_passed - i) *Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes();758 int ld_off = (total_args_passed - i) * Interpreter::stackElementSize; 801 759 // Point to interpreter value (vs. tag) 802 int next_off = ld_off - Interpreter::stackElementSize ();760 int next_off = ld_off - Interpreter::stackElementSize; 803 761 // 804 762 // … … 908 866 int comp_args_on_stack, 909 867 const BasicType *sig_bt, 910 const VMRegPair *regs) { 868 const VMRegPair *regs, 869 AdapterFingerPrint* fingerprint) { 911 870 address i2c_entry = __ pc(); 912 871 … … 955 914 956 915 __ flush(); 957 return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry);916 return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); 958 917 } 959 918 … … 2322 2281 // activation for use during deoptimization 2323 2282 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { 2324 return (callee_locals - callee_parameters) * Interpreter::stackElementWords ();2283 return (callee_locals - callee_parameters) * Interpreter::stackElementWords; 2325 2284 } 2326 2285 … … 2382 2341 // Save everything in sight. 2383 2342 2384 map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words );2343 map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false); 2385 2344 // Normal deoptimization 2386 2345 __ push(Deoptimization::Unpack_deopt); … … 2393 2352 2394 2353 // No need to update map as each call to save_live_registers will produce identical oopmap 2395 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words );2354 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false); 2396 2355 2397 2356 __ push(Deoptimization::Unpack_reexecute); … … 2429 2388 2430 2389 // No need to update map as each call to save_live_registers will produce identical oopmap 2431 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words );2390 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false); 2432 2391 2433 2392 // Now it is safe to overwrite any register … … 2515 2474 2516 2475 RegisterSaver::restore_result_registers(masm); 2476 2477 // Non standard control word may be leaked out through a safepoint blob, and we can 2478 // deopt at a poll point with the non standard control word. However, we should make 2479 // sure the control word is correct after restore_result_registers. 2480 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 2517 2481 2518 2482 // All of the register save area has been popped of the stack. Only the -
trunk/openjdk/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 453 453 } 454 454 455 // Helper function to put tags in interpreter stack.456 static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) {457 if (TaggedStackInterpreter) {458 int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0);459 if (sig == T_OBJECT || sig == T_ARRAY) {460 __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagReference);461 } else if (sig == T_LONG || sig == T_DOUBLE) {462 int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1);463 __ movptr(Address(rsp, next_tag_offset), (int32_t) frame::TagValue);464 __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue);465 } else {466 __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue);467 }468 }469 }470 471 455 472 456 static void gen_c2i_adapter(MacroAssembler *masm, … … 490 474 // we store it first rather than hold it in rax across all the shuffling 491 475 492 int extraspace = (total_args_passed * Interpreter::stackElementSize ()) + wordSize;476 int extraspace = (total_args_passed * Interpreter::stackElementSize) + wordSize; 493 477 494 478 // stack is aligned, keep it that way … … 514 498 515 499 // offset to start parameters 516 int st_off = (total_args_passed - i) * Interpreter::stackElementSize() + 517 Interpreter::value_offset_in_bytes(); 518 int next_off = st_off - Interpreter::stackElementSize(); 500 int st_off = (total_args_passed - i) * Interpreter::stackElementSize; 501 int next_off = st_off - Interpreter::stackElementSize; 519 502 520 503 // Say 4 args: … … 544 527 __ movl(rax, Address(rsp, ld_off)); 545 528 __ movptr(Address(rsp, st_off), rax); 546 tag_stack(masm, sig_bt[i], st_off);547 529 548 530 } else { … … 561 543 __ movptr(Address(rsp, st_off), rax); 562 544 #endif /* ASSERT */ 563 tag_stack(masm, sig_bt[i], next_off);564 545 } else { 565 546 __ movq(Address(rsp, st_off), rax); 566 tag_stack(masm, sig_bt[i], st_off);567 547 } 568 548 } … … 573 553 // why not sign extend?? 574 554 __ movl(Address(rsp, st_off), r); 575 tag_stack(masm, sig_bt[i], st_off);576 555 } else { 577 556 // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG … … 585 564 #endif /* ASSERT */ 586 565 __ movq(Address(rsp, next_off), r); 587 tag_stack(masm, sig_bt[i], next_off);588 566 } else { 589 567 __ movptr(Address(rsp, st_off), r); 590 tag_stack(masm, sig_bt[i], st_off);591 568 } 592 569 } … … 596 573 // only a float use just part of the slot 597 574 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); 598 tag_stack(masm, sig_bt[i], st_off);599 575 } else { 600 576 #ifdef ASSERT … … 604 580 #endif /* ASSERT */ 605 581 __ movdbl(Address(rsp, next_off), r_1->as_XMMRegister()); 606 tag_stack(masm, sig_bt[i], next_off);607 582 } 608 583 } … … 639 614 __ movptr(rax, Address(rsp, 0)); 640 615 616 // Must preserve original SP for loading incoming arguments because 617 // we need to align the outgoing SP for compiled code. 618 __ movptr(r11, rsp); 619 641 620 // Cut-out for having no stack args. Since up to 2 int/oop args are passed 642 621 // in registers, we will occasionally have no stack args. … … 661 640 // as far as the placement of the call instruction 662 641 __ push(rax); 642 643 // Put saved SP in another register 644 const Register saved_sp = rax; 645 __ movptr(saved_sp, r11); 663 646 664 647 // Will jump to the compiled code just as if compiled code was doing it. … … 681 664 "scrambled load targets?"); 682 665 // Load in argument order going down. 683 // int ld_off = (total_args_passed + comp_words_on_stack -i)*wordSize; 684 // base ld_off on r13 (sender_sp) as the stack alignment makes offsets from rsp 685 // unpredictable 686 int ld_off = ((total_args_passed - 1) - i)*Interpreter::stackElementSize(); 687 666 int ld_off = (total_args_passed - i)*Interpreter::stackElementSize; 688 667 // Point to interpreter value (vs. tag) 689 int next_off = ld_off - Interpreter::stackElementSize ();668 int next_off = ld_off - Interpreter::stackElementSize; 690 669 // 691 670 // … … 700 679 // Convert stack slot to an SP offset (+ wordSize to account for return address ) 701 680 int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size + wordSize; 681 682 // We can use r13 as a temp here because compiled code doesn't need r13 as an input 683 // and if we end up going thru a c2i because of a miss a reasonable value of r13 684 // will be generated. 702 685 if (!r_2->is_valid()) { 703 686 // sign extend??? 704 __ movl(r ax, Address(r13, ld_off));705 __ movptr(Address(rsp, st_off), r ax);687 __ movl(r13, Address(saved_sp, ld_off)); 688 __ movptr(Address(rsp, st_off), r13); 706 689 } else { 707 690 // … … 716 699 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? 717 700 next_off : ld_off; 718 __ movq(r ax, Address(r13, offset));701 __ movq(r13, Address(saved_sp, offset)); 719 702 // st_off is LSW (i.e. reg.first()) 720 __ movq(Address(rsp, st_off), r ax);703 __ movq(Address(rsp, st_off), r13); 721 704 } 722 705 } else if (r_1->is_Register()) { // Register argument … … 733 716 734 717 // this can be a misaligned move 735 __ movq(r, Address( r13, offset));718 __ movq(r, Address(saved_sp, offset)); 736 719 } else { 737 720 // sign extend and use a full word? 738 __ movl(r, Address( r13, ld_off));721 __ movl(r, Address(saved_sp, ld_off)); 739 722 } 740 723 } else { 741 724 if (!r_2->is_valid()) { 742 __ movflt(r_1->as_XMMRegister(), Address( r13, ld_off));725 __ movflt(r_1->as_XMMRegister(), Address(saved_sp, ld_off)); 743 726 } else { 744 __ movdbl(r_1->as_XMMRegister(), Address( r13, next_off));727 __ movdbl(r_1->as_XMMRegister(), Address(saved_sp, next_off)); 745 728 } 746 729 } … … 771 754 int comp_args_on_stack, 772 755 const BasicType *sig_bt, 773 const VMRegPair *regs) { 756 const VMRegPair *regs, 757 AdapterFingerPrint* fingerprint) { 774 758 address i2c_entry = __ pc(); 775 759 … … 817 801 818 802 __ flush(); 819 return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry);803 return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); 820 804 } 821 805 … … 2527 2511 // activation for use during deoptimization 2528 2512 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { 2529 return (callee_locals - callee_parameters) * Interpreter::stackElementWords ();2513 return (callee_locals - callee_parameters) * Interpreter::stackElementWords; 2530 2514 } 2531 2515 … … 3320 3304 // rax: exception handler 3321 3305 3306 // Restore SP from BP if the exception PC is a MethodHandle call site. 3307 __ cmpl(Address(r15_thread, JavaThread::is_method_handle_return_offset()), 0); 3308 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); 3309 3322 3310 // We have a handler in rax (could be deopt blob). 3323 3311 __ mov(r8, rax); -
trunk/openjdk/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 140 140 __ enter(); 141 141 __ movptr(rcx, parameter_size); // parameter counter 142 __ shlptr(rcx, Interpreter::logStackElementSize ()); // convert parameter count to bytes142 __ shlptr(rcx, Interpreter::logStackElementSize); // convert parameter count to bytes 143 143 __ addptr(rcx, locals_count_in_bytes); // reserve space for register saves 144 144 __ subptr(rsp, rcx); … … 195 195 196 196 __ BIND(loop); 197 if (TaggedStackInterpreter) {198 __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(),199 -2*wordSize)); // get tag200 __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(),201 Interpreter::expr_tag_offset_in_bytes(0)), rax); // store tag202 }203 197 204 198 // get parameter … … 370 364 // 371 365 // Contract with Java-level exception handlers: 372 // rax ,: exception366 // rax: exception 373 367 // rdx: throwing pc 374 368 // … … 378 372 StubCodeMark mark(this, "StubRoutines", "forward exception"); 379 373 address start = __ pc(); 374 const Register thread = rcx; 375 376 // other registers used in this stub 377 const Register exception_oop = rax; 378 const Register handler_addr = rbx; 379 const Register exception_pc = rdx; 380 380 381 381 // Upon entry, the sp points to the return address returning into Java … … 390 390 // make sure this code is only executed if there is a pending exception 391 391 { Label L; 392 __ get_thread( rcx);393 __ cmpptr(Address( rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);392 __ get_thread(thread); 393 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 394 394 __ jcc(Assembler::notEqual, L); 395 395 __ stop("StubRoutines::forward exception: no pending exception (1)"); … … 399 399 400 400 // compute exception handler into rbx, 401 __ movptr(rax, Address(rsp, 0)); 401 __ get_thread(thread); 402 __ movptr(exception_pc, Address(rsp, 0)); 402 403 BLOCK_COMMENT("call exception_handler_for_return_address"); 403 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax);404 __ mov( rbx, rax);405 406 // setup rax ,& rdx, remove return address & clear pending exception407 __ get_thread( rcx);408 __ pop( rdx);409 __ movptr( rax, Address(rcx, Thread::pending_exception_offset()));410 __ movptr(Address( rcx, Thread::pending_exception_offset()), NULL_WORD);404 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 405 __ mov(handler_addr, rax); 406 407 // setup rax & rdx, remove return address & clear pending exception 408 __ get_thread(thread); 409 __ pop(exception_pc); 410 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); 411 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); 411 412 412 413 #ifdef ASSERT 413 414 // make sure exception is set 414 415 { Label L; 415 __ testptr( rax, rax);416 __ testptr(exception_oop, exception_oop); 416 417 __ jcc(Assembler::notEqual, L); 417 418 __ stop("StubRoutines::forward exception: no pending exception (2)"); … … 420 421 #endif 421 422 423 // Verify that there is really a valid exception in RAX. 424 __ verify_oop(exception_oop); 425 426 // Restore SP from BP if the exception PC is a MethodHandle call site. 427 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0); 428 __ cmovptr(Assembler::notEqual, rsp, rbp); 429 422 430 // continue at exception handler (return address removed) 423 // rax ,: exception424 // rbx ,: exception handler431 // rax: exception 432 // rbx: exception handler 425 433 // rdx: throwing pc 426 __ verify_oop(rax); 427 __ jmp(rbx); 434 __ jmp(handler_addr); 428 435 429 436 return start; … … 719 726 { 720 727 __ pusha(); // push registers 721 __ push(count); 722 __ push(start); 723 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre))); 724 __ addptr(rsp, 2*wordSize); 728 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 729 start, count); 725 730 __ popa(); 726 731 } … … 753 758 { 754 759 __ pusha(); // push registers 755 __ push(count); 756 __ push(start); 757 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post))); 758 __ addptr(rsp, 2*wordSize); 760 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 761 start, count); 759 762 __ popa(); 760 763 } … … 804 807 // Copy 64-byte chunks 805 808 __ jmpb(L_copy_64_bytes); 806 __ align( 16);809 __ align(OptoLoopAlignment); 807 810 __ BIND(L_copy_64_bytes_loop); 808 811 … … 866 869 // Copy 64-byte chunks 867 870 __ jmpb(L_copy_64_bytes); 868 __ align( 16);871 __ align(OptoLoopAlignment); 869 872 __ BIND(L_copy_64_bytes_loop); 870 873 __ movq(mmx0, Address(from, 0)); … … 1037 1040 1038 1041 1042 address generate_fill(BasicType t, bool aligned, const char *name) { 1043 __ align(CodeEntryAlignment); 1044 StubCodeMark mark(this, "StubRoutines", name); 1045 address start = __ pc(); 1046 1047 BLOCK_COMMENT("Entry:"); 1048 1049 const Register to = rdi; // source array address 1050 const Register value = rdx; // value 1051 const Register count = rsi; // elements count 1052 1053 __ enter(); // required for proper stackwalking of RuntimeStub frame 1054 __ push(rsi); 1055 __ push(rdi); 1056 __ movptr(to , Address(rsp, 12+ 4)); 1057 __ movl(value, Address(rsp, 12+ 8)); 1058 __ movl(count, Address(rsp, 12+ 12)); 1059 1060 __ generate_fill(t, aligned, to, value, count, rax, xmm0); 1061 1062 __ pop(rdi); 1063 __ pop(rsi); 1064 __ leave(); // required for proper stackwalking of RuntimeStub frame 1065 __ ret(0); 1066 return start; 1067 } 1068 1039 1069 address generate_conjoint_copy(BasicType t, bool aligned, 1040 1070 Address::ScaleFactor sf, … … 1136 1166 __ jmpb(L_copy_8_bytes); 1137 1167 1138 __ align( 16);1168 __ align(OptoLoopAlignment); 1139 1169 // Move 8 bytes 1140 1170 __ BIND(L_copy_8_bytes_loop); … … 1227 1257 } else { 1228 1258 __ jmpb(L_copy_8_bytes); 1229 __ align( 16);1259 __ align(OptoLoopAlignment); 1230 1260 __ BIND(L_copy_8_bytes_loop); 1231 1261 __ fild_d(Address(from, 0)); … … 1274 1304 __ jmpb(L_copy_8_bytes); 1275 1305 1276 __ align( 16);1306 __ align(OptoLoopAlignment); 1277 1307 __ BIND(L_copy_8_bytes_loop); 1278 1308 if (VM_Version::supports_mmx()) { … … 1446 1476 // for (count = -count; count != 0; count++) 1447 1477 // Base pointers src, dst are biased by 8*count,to last element. 1448 __ align( 16);1478 __ align(OptoLoopAlignment); 1449 1479 1450 1480 __ BIND(L_store_element); … … 1999 2029 "jlong_arraycopy"); 2000 2030 2031 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 2032 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 2033 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); 2034 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); 2035 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); 2036 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); 2037 2001 2038 StubRoutines::_arrayof_jint_disjoint_arraycopy = 2002 2039 StubRoutines::_jint_disjoint_arraycopy; … … 2029 2066 entry_jlong_arraycopy, 2030 2067 entry_checkcast_arraycopy); 2068 } 2069 2070 void generate_math_stubs() { 2071 { 2072 StubCodeMark mark(this, "StubRoutines", "log"); 2073 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc(); 2074 2075 __ fld_d(Address(rsp, 4)); 2076 __ flog(); 2077 __ ret(0); 2078 } 2079 { 2080 StubCodeMark mark(this, "StubRoutines", "log10"); 2081 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 2082 2083 __ fld_d(Address(rsp, 4)); 2084 __ flog10(); 2085 __ ret(0); 2086 } 2087 { 2088 StubCodeMark mark(this, "StubRoutines", "sin"); 2089 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc(); 2090 2091 __ fld_d(Address(rsp, 4)); 2092 __ trigfunc('s'); 2093 __ ret(0); 2094 } 2095 { 2096 StubCodeMark mark(this, "StubRoutines", "cos"); 2097 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc(); 2098 2099 __ fld_d(Address(rsp, 4)); 2100 __ trigfunc('c'); 2101 __ ret(0); 2102 } 2103 { 2104 StubCodeMark mark(this, "StubRoutines", "tan"); 2105 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 2106 2107 __ fld_d(Address(rsp, 4)); 2108 __ trigfunc('t'); 2109 __ ret(0); 2110 } 2111 2112 // The intrinsic version of these seem to return the same value as 2113 // the strict version. 2114 StubRoutines::_intrinsic_exp = SharedRuntime::dexp; 2115 StubRoutines::_intrinsic_pow = SharedRuntime::dpow; 2031 2116 } 2032 2117 … … 2220 2305 generate_arraycopy_stubs(); 2221 2306 2222 // generic method handle stubs 2223 if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) { 2224 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; 2225 ek < MethodHandles::_EK_LIMIT; 2226 ek = MethodHandles::EntryKind(1 + (int)ek)) { 2227 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); 2228 MethodHandles::generate_method_handle_stub(_masm, ek); 2229 } 2230 } 2307 generate_math_stubs(); 2231 2308 } 2232 2309 -
trunk/openjdk/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 279 279 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1 280 280 __ BIND(loop); 281 if (TaggedStackInterpreter) {282 __ movl(rax, Address(c_rarg2, 0)); // get tag283 __ addptr(c_rarg2, wordSize); // advance to next tag284 __ push(rax); // pass tag285 }286 281 __ movptr(rax, Address(c_rarg2, 0));// get parameter 287 282 __ addptr(c_rarg2, wordSize); // advance to next parameter … … 467 462 __ call_VM_leaf(CAST_FROM_FN_PTR(address, 468 463 SharedRuntime::exception_handler_for_return_address), 469 c_rarg0);464 r15_thread, c_rarg0); 470 465 __ mov(rbx, rax); 471 466 … … 872 867 873 868 address generate_fp_mask(const char *stub_name, int64_t mask) { 869 __ align(CodeEntryAlignment); 874 870 StubCodeMark mark(this, "StubRoutines", stub_name); 875 876 __ align(16);877 871 address start = __ pc(); 878 872 … … 921 915 // * [tos + 6]: object to verify (oop) 922 916 // * [tos + 7]: saved rax - saved by caller and bashed 917 // * [tos + 8]: saved r10 (rscratch1) - saved by caller 923 918 // * = popped on exit 924 919 address generate_verify_oop() { … … 941 936 oop_to_verify = 6 * wordSize, 942 937 saved_rax = 7 * wordSize, 938 saved_r10 = 8 * wordSize, 943 939 944 940 // Before the call to MacroAssembler::debug(), see below. … … 990 986 __ bind(exit); 991 987 __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back 988 __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back 992 989 __ pop(c_rarg3); // restore c_rarg3 993 990 __ pop(c_rarg2); // restore c_rarg2 994 991 __ pop(r12); // restore r12 995 992 __ popf(); // restore flags 996 __ ret( 3* wordSize); // pop caller saved stuff993 __ ret(4 * wordSize); // pop caller saved stuff 997 994 998 995 // handle errors 999 996 __ bind(error); 1000 997 __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back 998 __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back 1001 999 __ pop(c_rarg3); // get saved c_rarg3 back 1002 1000 __ pop(c_rarg2); // get saved c_rarg2 back … … 1016 1014 // * [tos + 18] object to verify (oop) 1017 1015 // * [tos + 19] saved rax - saved by caller and bashed 1016 // * [tos + 20] saved r10 (rscratch1) - saved by caller 1018 1017 // * = popped on exit 1019 1018 … … 1028 1027 __ mov(rsp, r12); // restore rsp 1029 1028 __ popa(); // pop registers (includes r12) 1030 __ ret( 3* wordSize); // pop caller saved stuff1029 __ ret(4 * wordSize); // pop caller saved stuff 1031 1030 1032 1031 return start; … … 1173 1172 __ movptr(c_rarg1, count); 1174 1173 } 1175 __ call (RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)));1174 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2); 1176 1175 __ popa(); 1177 1176 } … … 1213 1212 __ mov(c_rarg0, start); 1214 1213 __ mov(c_rarg1, scratch); 1215 __ call (RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)));1214 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2); 1216 1215 __ popa(); 1217 1216 } … … 1269 1268 DEBUG_ONLY(__ stop("enter at entry label, not here")); 1270 1269 Label L_loop; 1271 __ align( 16);1270 __ align(OptoLoopAlignment); 1272 1271 __ BIND(L_loop); 1273 1272 if(UseUnalignedLoadStores) { … … 1310 1309 DEBUG_ONLY(__ stop("enter at entry label, not here")); 1311 1310 Label L_loop; 1312 __ align( 16);1311 __ align(OptoLoopAlignment); 1313 1312 __ BIND(L_loop); 1314 1313 if(UseUnalignedLoadStores) { … … 1624 1623 __ jmp(L_copy_4_bytes); 1625 1624 1625 return start; 1626 } 1627 1628 address generate_fill(BasicType t, bool aligned, const char *name) { 1629 __ align(CodeEntryAlignment); 1630 StubCodeMark mark(this, "StubRoutines", name); 1631 address start = __ pc(); 1632 1633 BLOCK_COMMENT("Entry:"); 1634 1635 const Register to = c_rarg0; // source array address 1636 const Register value = c_rarg1; // value 1637 const Register count = c_rarg2; // elements count 1638 1639 __ enter(); // required for proper stackwalking of RuntimeStub frame 1640 1641 __ generate_fill(t, aligned, to, value, count, rax, xmm0); 1642 1643 __ leave(); // required for proper stackwalking of RuntimeStub frame 1644 __ ret(0); 1626 1645 return start; 1627 1646 } … … 2230 2249 // for (count = -count; count != 0; count++) 2231 2250 // Base pointers src, dst are biased by 8*(count-1),to last element. 2232 __ align( 16);2251 __ align(OptoLoopAlignment); 2233 2252 2234 2253 __ BIND(L_store_element); … … 2714 2733 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); 2715 2734 2735 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 2736 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 2737 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); 2738 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); 2739 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); 2740 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); 2741 2716 2742 // We don't generate specialized code for HeapWord-aligned source 2717 2743 // arrays, so just use the code we've already generated … … 2730 2756 StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy; 2731 2757 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; 2758 } 2759 2760 void generate_math_stubs() { 2761 { 2762 StubCodeMark mark(this, "StubRoutines", "log"); 2763 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc(); 2764 2765 __ subq(rsp, 8); 2766 __ movdbl(Address(rsp, 0), xmm0); 2767 __ fld_d(Address(rsp, 0)); 2768 __ flog(); 2769 __ fstp_d(Address(rsp, 0)); 2770 __ movdbl(xmm0, Address(rsp, 0)); 2771 __ addq(rsp, 8); 2772 __ ret(0); 2773 } 2774 { 2775 StubCodeMark mark(this, "StubRoutines", "log10"); 2776 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 2777 2778 __ subq(rsp, 8); 2779 __ movdbl(Address(rsp, 0), xmm0); 2780 __ fld_d(Address(rsp, 0)); 2781 __ flog10(); 2782 __ fstp_d(Address(rsp, 0)); 2783 __ movdbl(xmm0, Address(rsp, 0)); 2784 __ addq(rsp, 8); 2785 __ ret(0); 2786 } 2787 { 2788 StubCodeMark mark(this, "StubRoutines", "sin"); 2789 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc(); 2790 2791 __ subq(rsp, 8); 2792 __ movdbl(Address(rsp, 0), xmm0); 2793 __ fld_d(Address(rsp, 0)); 2794 __ trigfunc('s'); 2795 __ fstp_d(Address(rsp, 0)); 2796 __ movdbl(xmm0, Address(rsp, 0)); 2797 __ addq(rsp, 8); 2798 __ ret(0); 2799 } 2800 { 2801 StubCodeMark mark(this, "StubRoutines", "cos"); 2802 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc(); 2803 2804 __ subq(rsp, 8); 2805 __ movdbl(Address(rsp, 0), xmm0); 2806 __ fld_d(Address(rsp, 0)); 2807 __ trigfunc('c'); 2808 __ fstp_d(Address(rsp, 0)); 2809 __ movdbl(xmm0, Address(rsp, 0)); 2810 __ addq(rsp, 8); 2811 __ ret(0); 2812 } 2813 { 2814 StubCodeMark mark(this, "StubRoutines", "tan"); 2815 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 2816 2817 __ subq(rsp, 8); 2818 __ movdbl(Address(rsp, 0), xmm0); 2819 __ fld_d(Address(rsp, 0)); 2820 __ trigfunc('t'); 2821 __ fstp_d(Address(rsp, 0)); 2822 __ movdbl(xmm0, Address(rsp, 0)); 2823 __ addq(rsp, 8); 2824 __ ret(0); 2825 } 2826 2827 // The intrinsic version of these seem to return the same value as 2828 // the strict version. 2829 StubRoutines::_intrinsic_exp = SharedRuntime::dexp; 2830 StubRoutines::_intrinsic_pow = SharedRuntime::dpow; 2732 2831 } 2733 2832 … … 2936 3035 // arraycopy stubs used by compilers 2937 3036 generate_arraycopy_stubs(); 3037 3038 generate_math_stubs(); 2938 3039 } 2939 3040 -
trunk/openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 30 30 code_size1 = 9000, // simply increase if too small (assembler will crash if too small) 31 31 code_size2 = 22000 // simply increase if too small (assembler will crash if too small) 32 }; 33 34 // MethodHandles adapters 35 enum method_handles_platform_dependent_constants { 36 method_handles_adapters_code_size = 5000 32 37 }; 33 38 -
trunk/openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
r2 r278 1 1 /* 2 * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 29 29 static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } 30 30 31 enum platform_dependent_constants 32 { 33 code_size1 = 19000, // simply increase if too small (assembler will 34 // crash if too small) 35 code_size2 = 22000 // simply increase if too small (assembler will 36 // crash if too small) 31 enum platform_dependent_constants { 32 code_size1 = 19000, // simply increase if too small (assembler will crash if too small) 33 code_size2 = 22000 // simply increase if too small (assembler will crash if too small) 34 }; 35 36 // MethodHandles adapters 37 enum method_handles_platform_dependent_constants { 38 method_handles_adapters_code_size = 13000 37 39 }; 38 40 -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 29 29 // fail with a guarantee ("not enough space for interpreter generation"); 30 30 // if too small. 31 // Run with +PrintInterpreter Sizeto get the VM to print out the size.32 // Max size with JVMTI and TaggedStackInterpreter31 // Run with +PrintInterpreter to get the VM to print out the size. 32 // Max size with JVMTI 33 33 #ifdef AMD64 34 34 const static int InterpreterCodeSize = 200 * 1024; -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 93 93 } 94 94 95 // Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4. 96 // pc at TOS (just for debugging) 95 // Arguments are: required type at TOS+4, failing object (or NULL) at TOS. 97 96 address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { 98 97 address entry = __ pc(); … … 157 156 158 157 159 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step , bool unbox) {158 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { 160 159 TosState incoming_state = state; 161 if (EnableInvokeDynamic) {162 if (unbox) {163 incoming_state = atos;164 }165 } else {166 assert(!unbox, "old behavior");167 }168 160 169 161 Label interpreter_entry; … … 218 210 __ restore_locals(); 219 211 220 Label L_fail;221 222 if (unbox && state != atos) {223 // cast and unbox224 BasicType type = as_BasicType(state);225 if (type == T_BYTE) type = T_BOOLEAN; // FIXME226 KlassHandle boxk = SystemDictionaryHandles::box_klass(type);227 __ mov32(rbx, ExternalAddress((address) boxk.raw_value()));228 __ testl(rax, rax);229 Label L_got_value, L_get_value;230 // convert nulls to zeroes (avoid NPEs here)231 if (!(type == T_FLOAT || type == T_DOUBLE)) {232 // if rax already contains zero bits, forge ahead233 __ jcc(Assembler::zero, L_got_value);234 } else {235 __ jcc(Assembler::notZero, L_get_value);236 __ fldz();237 __ jmp(L_got_value);238 }239 __ bind(L_get_value);240 __ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes()));241 __ jcc(Assembler::notEqual, L_fail);242 int offset = java_lang_boxing_object::value_offset_in_bytes(type);243 // Cf. TemplateTable::getfield_or_static244 switch (type) {245 case T_BYTE: // fall through:246 case T_BOOLEAN: __ load_signed_byte(rax, Address(rax, offset)); break;247 case T_CHAR: __ load_unsigned_short(rax, Address(rax, offset)); break;248 case T_SHORT: __ load_signed_short(rax, Address(rax, offset)); break;249 case T_INT: __ movl(rax, Address(rax, offset)); break;250 case T_FLOAT: __ fld_s(Address(rax, offset)); break;251 case T_DOUBLE: __ fld_d(Address(rax, offset)); break;252 // Access to java.lang.Double.value does not need to be atomic:253 case T_LONG: { __ movl(rdx, Address(rax, offset + 4));254 __ movl(rax, Address(rax, offset + 0)); } break;255 default: ShouldNotReachHere();256 }257 __ bind(L_got_value);258 }259 260 212 Label L_got_cache, L_giant_index; 261 213 if (EnableInvokeDynamic) { … … 263 215 __ jcc(Assembler::equal, L_giant_index); 264 216 } 265 __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);217 __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u2)); 266 218 __ bind(L_got_cache); 267 if (unbox && state == atos) {268 // insert a casting conversion, to keep verifier sane269 Label L_ok, L_ok_pops;270 __ testl(rax, rax);271 __ jcc(Assembler::zero, L_ok);272 __ push(rax); // save the object to check273 __ push(rbx); // save CP cache reference274 __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes()));275 __ movl(rbx, Address(rbx, rcx,276 Address::times_4, constantPoolCacheOopDesc::base_offset() +277 ConstantPoolCacheEntry::f1_offset()));278 __ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));279 __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx)));280 __ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx)));281 __ check_klass_subtype(rdx, rax, rbx, L_ok_pops);282 __ pop(rcx); // pop and discard CP cache283 __ mov(rbx, rax); // target supertype into rbx for L_fail284 __ pop(rax); // failed object into rax for L_fail285 __ jmp(L_fail);286 287 __ bind(L_ok_pops);288 // restore pushed temp regs:289 __ pop(rbx);290 __ pop(rax);291 __ bind(L_ok);292 }293 219 __ movl(rbx, Address(rbx, rcx, 294 220 Address::times_ptr, constantPoolCacheOopDesc::base_offset() + … … 301 227 if (EnableInvokeDynamic) { 302 228 __ bind(L_giant_index); 303 __ get_cache_and_index_at_bcp(rbx, rcx, 1, true);229 __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u4)); 304 230 __ jmp(L_got_cache); 305 306 if (unbox) {307 __ bind(L_fail);308 __ push(rbx); // missed klass (required)309 __ push(rax); // bad object (actual)310 __ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry));311 __ call(rdx);312 }313 231 } 314 232 … … 388 306 { const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); 389 307 __ pop(t); // remove return address first 390 __ pop_dtos_to_rsp();391 308 // Must return a result for interpreter or compiler. In SSE 392 309 // mode, results are returned in xmm0 and the FPU stack must … … 551 468 // then we need to verify there is enough stack space remaining 552 469 // for the additional locals. 553 __ cmpl(rdx, (page_size - overhead_size)/Interpreter::stackElementSize ());470 __ cmpl(rdx, (page_size - overhead_size)/Interpreter::stackElementSize); 554 471 __ jcc(Assembler::belowEqual, after_frame_check); 555 472 … … 965 882 __ verify_oop(method); 966 883 __ load_unsigned_short(t, Address(method, methodOopDesc::size_of_parameters_offset())); 967 __ shlptr(t, Interpreter::logStackElementSize ());884 __ shlptr(t, Interpreter::logStackElementSize); 968 885 __ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror 969 886 __ subptr(rsp, t); … … 1308 1225 __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 1309 1226 __ bind(loop); 1310 if (TaggedStackInterpreter) {1311 __ push((int32_t)NULL_WORD); // push tag1312 }1313 1227 __ push((int32_t)NULL_WORD); // initialize local variables 1314 1228 __ decrement(rdx); // until everything initialized … … 1514 1428 } 1515 1429 1430 // These should never be compiled since the interpreter will prefer 1431 // the compiled version to the intrinsic version. 1432 bool AbstractInterpreter::can_be_compiled(methodHandle m) { 1433 switch (method_kind(m)) { 1434 case Interpreter::java_lang_math_sin : // fall thru 1435 case Interpreter::java_lang_math_cos : // fall thru 1436 case Interpreter::java_lang_math_tan : // fall thru 1437 case Interpreter::java_lang_math_abs : // fall thru 1438 case Interpreter::java_lang_math_log : // fall thru 1439 case Interpreter::java_lang_math_log10 : // fall thru 1440 case Interpreter::java_lang_math_sqrt : 1441 return false; 1442 default: 1443 return true; 1444 } 1445 } 1446 1516 1447 // How much stack a method activation needs in words. 1517 1448 int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { … … 1529 1460 const int extra_stack = methodOopDesc::extra_stack_entries(); 1530 1461 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * 1531 Interpreter::stackElementWords ();1462 Interpreter::stackElementWords; 1532 1463 return overhead_size + method_stack + stub_code; 1533 1464 } … … 1553 1484 1554 1485 // fixed size of an interpreter frame: 1555 int max_locals = method->max_locals() * Interpreter::stackElementWords ();1486 int max_locals = method->max_locals() * Interpreter::stackElementWords; 1556 1487 int extra_locals = (method->max_locals() - method->size_of_parameters()) * 1557 Interpreter::stackElementWords ();1488 Interpreter::stackElementWords; 1558 1489 1559 1490 int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset; … … 1565 1496 1566 1497 int size = overhead + 1567 ((callee_locals - callee_param_count)*Interpreter::stackElementWords ()) +1498 ((callee_locals - callee_param_count)*Interpreter::stackElementWords) + 1568 1499 (moncount*frame::interpreter_frame_monitor_size()) + 1569 tempcount*Interpreter::stackElementWords ()+ popframe_extra_args;1500 tempcount*Interpreter::stackElementWords + popframe_extra_args; 1570 1501 1571 1502 if (interpreter_frame != NULL) { 1572 1503 #ifdef ASSERT 1573 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); 1504 if (!EnableMethodHandles) 1505 // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? 1506 // Probably, since deoptimization doesn't work yet. 1507 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); 1574 1508 assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); 1575 1509 #endif … … 1588 1522 // Set last_sp 1589 1523 intptr_t* rsp = (intptr_t*) monbot - 1590 tempcount*Interpreter::stackElementWords ()-1524 tempcount*Interpreter::stackElementWords - 1591 1525 popframe_extra_args; 1592 1526 interpreter_frame->interpreter_frame_set_last_sp(rsp); … … 1613 1547 // Entry point in previous activation (i.e., if the caller was interpreted) 1614 1548 Interpreter::_rethrow_exception_entry = __ pc(); 1549 const Register thread = rcx; 1615 1550 1616 1551 // Restore sp to interpreter_frame_last_sp even though we are going … … 1661 1596 // currently handling popframe, so that call_VMs that may happen later do not trigger new 1662 1597 // popframe handling cycles. 1663 __ get_thread( rcx);1664 __ movl(rdx, Address( rcx, JavaThread::popframe_condition_offset()));1598 __ get_thread(thread); 1599 __ movl(rdx, Address(thread, JavaThread::popframe_condition_offset())); 1665 1600 __ orl(rdx, JavaThread::popframe_processing_bit); 1666 __ movl(Address( rcx, JavaThread::popframe_condition_offset()), rdx);1601 __ movl(Address(thread, JavaThread::popframe_condition_offset()), rdx); 1667 1602 1668 1603 { … … 1687 1622 __ verify_oop(rax); 1688 1623 __ load_unsigned_short(rax, Address(rax, in_bytes(methodOopDesc::size_of_parameters_offset()))); 1689 __ shlptr(rax, Interpreter::logStackElementSize ());1624 __ shlptr(rax, Interpreter::logStackElementSize); 1690 1625 __ restore_locals(); 1691 1626 __ subptr(rdi, rax); 1692 1627 __ addptr(rdi, wordSize); 1693 1628 // Save these arguments 1694 __ get_thread( rcx);1695 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi);1629 __ get_thread(thread); 1630 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), thread, rax, rdi); 1696 1631 1697 1632 __ remove_activation(vtos, rdx, … … 1701 1636 1702 1637 // Inform deoptimization that it is responsible for restoring these arguments 1703 __ get_thread( rcx);1704 __ movl(Address( rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);1638 __ get_thread(thread); 1639 __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit); 1705 1640 1706 1641 // Continue in deoptimization handler … … 1728 1663 __ mov(rax, rsp); 1729 1664 __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 1730 __ get_thread( rcx);1665 __ get_thread(thread); 1731 1666 // PC must point into interpreter here 1732 __ set_last_Java_frame( rcx, noreg, rbp, __ pc());1733 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), rcx, rax, rbx);1734 __ get_thread( rcx);1735 __ reset_last_Java_frame( rcx, true, true);1667 __ set_last_Java_frame(thread, noreg, rbp, __ pc()); 1668 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx); 1669 __ get_thread(thread); 1670 __ reset_last_Java_frame(thread, true, true); 1736 1671 // Restore the last_sp and null it out 1737 1672 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); … … 1747 1682 1748 1683 // Clear the popframe condition flag 1749 __ get_thread( rcx);1750 __ movl(Address( rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);1684 __ get_thread(thread); 1685 __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); 1751 1686 1752 1687 __ dispatch_next(vtos); … … 1757 1692 // preserve exception over this code sequence 1758 1693 __ pop_ptr(rax); 1759 __ get_thread( rcx);1760 __ movptr(Address( rcx, JavaThread::vm_result_offset()), rax);1694 __ get_thread(thread); 1695 __ movptr(Address(thread, JavaThread::vm_result_offset()), rax); 1761 1696 // remove the activation (without doing throws on illegalMonitorExceptions) 1762 1697 __ remove_activation(vtos, rdx, false, true, false); 1763 1698 // restore exception 1764 __ get_thread( rcx);1765 __ movptr(rax, Address( rcx, JavaThread::vm_result_offset()));1766 __ movptr(Address( rcx, JavaThread::vm_result_offset()), NULL_WORD);1699 __ get_thread(thread); 1700 __ movptr(rax, Address(thread, JavaThread::vm_result_offset())); 1701 __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); 1767 1702 __ verify_oop(rax); 1768 1703 … … 1771 1706 // the following registers set up: 1772 1707 // 1773 // rax ,: exception1708 // rax: exception 1774 1709 // rdx: return address/pc that threw exception 1775 1710 // rsp: expression stack of caller 1776 // rbp ,: rbp, of caller1711 // rbp: rbp, of caller 1777 1712 __ push(rax); // save exception 1778 1713 __ push(rdx); // save return address 1779 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx);1714 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, rdx); 1780 1715 __ mov(rbx, rax); // save exception handler 1781 1716 __ pop(rdx); // restore return address … … 1791 1726 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { 1792 1727 address entry = __ pc(); 1728 const Register thread = rcx; 1793 1729 1794 1730 __ restore_bcp(); … … 1798 1734 __ load_earlyret_value(state); 1799 1735 1800 __ get_thread( rcx);1801 __ movptr(rcx, Address( rcx, JavaThread::jvmti_thread_state_offset()));1736 __ get_thread(thread); 1737 __ movptr(rcx, Address(thread, JavaThread::jvmti_thread_state_offset())); 1802 1738 const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset()); 1803 1739 -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 101 101 } 102 102 103 // Arguments are: required type in rarg1, failing object (or NULL) in rarg2103 // Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4. 104 104 address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { 105 105 address entry = __ pc(); … … 108 108 __ pop(c_rarg1); // required type is at TOS+8 109 109 110 // expression stack must be empty before entering the VM if an 111 // exception happened 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. 112 118 __ empty_expression_stack(); 113 119 114 120 __ call_VM(noreg, 115 121 CAST_FROM_FN_PTR(address, 116 InterpreterRuntime:: 117 throw_WrongMethodTypeException), 122 InterpreterRuntime::throw_WrongMethodTypeException), 118 123 // pass required type, failing object (or NULL) 119 124 c_rarg1, c_rarg2); … … 167 172 168 173 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, 169 int step, bool unbox) { 170 assert(!unbox, "NYI");//6815692// 174 int step) { 171 175 172 176 // amd64 doesn't need to do anything special about compiled returns … … 184 188 __ restore_locals(); 185 189 186 __ get_cache_and_index_at_bcp(rbx, rcx, 1); 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, sizeof(u2)); 196 __ bind(L_got_cache); 187 197 __ movl(rbx, Address(rbx, rcx, 188 Address::times_ 8,198 Address::times_ptr, 189 199 in_bytes(constantPoolCacheOopDesc::base_offset()) + 190 200 3 * wordSize)); 191 201 __ andl(rbx, 0xFF); 192 if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.193 202 __ lea(rsp, Address(rsp, rbx, Address::times_8)); 194 203 __ dispatch_next(state, step); 204 205 // out of the main line of code... 206 if (EnableInvokeDynamic) { 207 __ bind(L_giant_index); 208 __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u4)); 209 __ jmp(L_got_cache); 210 } 211 195 212 return entry; 196 213 } … … 400 417 // then we need to verify there is enough stack space remaining 401 418 // for the additional locals. 402 __ cmpl(rdx, (page_size - overhead_size) / Interpreter::stackElementSize ());419 __ cmpl(rdx, (page_size - overhead_size) / Interpreter::stackElementSize); 403 420 __ jcc(Assembler::belowEqual, after_frame_check); 404 421 … … 411 428 // locals + overhead, in bytes 412 429 __ mov(rax, rdx); 413 __ shlptr(rax, Interpreter::logStackElementSize ());// 2 slots per parameter.430 __ shlptr(rax, Interpreter::logStackElementSize); // 2 slots per parameter. 414 431 __ addptr(rax, overhead_size); 415 432 … … 432 449 __ subptr(rax, stack_size); 433 450 451 // Use the maximum number of pages we might bang. 452 const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages : 453 (StackRedPages+StackYellowPages); 454 434 455 // add in the red and yellow zone sizes 435 __ addptr(rax, (StackRedPages + StackYellowPages)* page_size);456 __ addptr(rax, max_pages * page_size); 436 457 437 458 // check against the current stack bottom … … 738 759 739 760 // compute beginning of parameters (r14) 740 if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter.741 761 __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); 742 762 … … 844 864 Address(method, 845 865 methodOopDesc::size_of_parameters_offset())); 846 __ shll(t, Interpreter::logStackElementSize ());866 __ shll(t, Interpreter::logStackElementSize); 847 867 848 868 __ subptr(rsp, t); … … 1207 1227 1208 1228 // compute beginning of parameters (r14) 1209 if (TaggedStackInterpreter) __ shll(rcx, 1); // 2 slots per parameter.1210 1229 __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); 1211 1230 … … 1218 1237 __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 1219 1238 __ bind(loop); 1220 if (TaggedStackInterpreter) __ push((int) NULL_WORD); // push tag1221 1239 __ push((int) NULL_WORD); // initialize local variables 1222 1240 __ decrementl(rdx); // until everything initialized … … 1435 1453 } 1436 1454 1455 // These should never be compiled since the interpreter will prefer 1456 // the compiled version to the intrinsic version. 1457 bool AbstractInterpreter::can_be_compiled(methodHandle m) { 1458 switch (method_kind(m)) { 1459 case Interpreter::java_lang_math_sin : // fall thru 1460 case Interpreter::java_lang_math_cos : // fall thru 1461 case Interpreter::java_lang_math_tan : // fall thru 1462 case Interpreter::java_lang_math_abs : // fall thru 1463 case Interpreter::java_lang_math_log : // fall thru 1464 case Interpreter::java_lang_math_log10 : // fall thru 1465 case Interpreter::java_lang_math_sqrt : 1466 return false; 1467 default: 1468 return true; 1469 } 1470 } 1471 1437 1472 // How much stack a method activation needs in words. 1438 1473 int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { … … 1448 1483 const int extra_stack = methodOopDesc::extra_stack_entries(); 1449 1484 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * 1450 Interpreter::stackElementWords ();1485 Interpreter::stackElementWords; 1451 1486 return (overhead_size + method_stack + stub_code); 1452 1487 } … … 1469 1504 1470 1505 // fixed size of an interpreter frame: 1471 int max_locals = method->max_locals() * Interpreter::stackElementWords ();1506 int max_locals = method->max_locals() * Interpreter::stackElementWords; 1472 1507 int extra_locals = (method->max_locals() - method->size_of_parameters()) * 1473 Interpreter::stackElementWords ();1508 Interpreter::stackElementWords; 1474 1509 1475 1510 int overhead = frame::sender_sp_offset - … … 1480 1515 // locals. 1481 1516 int size = overhead + 1482 (callee_locals - callee_param_count)*Interpreter::stackElementWords ()+1517 (callee_locals - callee_param_count)*Interpreter::stackElementWords + 1483 1518 moncount * frame::interpreter_frame_monitor_size() + 1484 tempcount* Interpreter::stackElementWords ()+ popframe_extra_args;1519 tempcount* Interpreter::stackElementWords + popframe_extra_args; 1485 1520 if (interpreter_frame != NULL) { 1486 1521 #ifdef ASSERT 1487 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), 1488 "Frame not properly walkable"); 1522 if (!EnableMethodHandles) 1523 // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? 1524 // Probably, since deoptimization doesn't work yet. 1525 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); 1489 1526 assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); 1490 1527 #endif … … 1504 1541 // Set last_sp 1505 1542 intptr_t* esp = (intptr_t*) monbot - 1506 tempcount*Interpreter::stackElementWords ()-1543 tempcount*Interpreter::stackElementWords - 1507 1544 popframe_extra_args; 1508 1545 interpreter_frame->interpreter_frame_set_last_sp(esp); … … 1610 1647 __ load_unsigned_short(rax, Address(rax, in_bytes(methodOopDesc:: 1611 1648 size_of_parameters_offset()))); 1612 __ shll(rax, Interpreter::logStackElementSize ());1649 __ shll(rax, Interpreter::logStackElementSize); 1613 1650 __ restore_locals(); // XXX do we need this? 1614 1651 __ subptr(r14, rax); … … 1701 1738 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, 1702 1739 SharedRuntime::exception_handler_for_return_address), 1703 r dx);1740 r15_thread, rdx); 1704 1741 __ mov(rbx, rax); // save exception handler 1705 1742 __ pop(rdx); // restore return address -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 51 51 52 52 static inline Address iaddress(Register r) { 53 return Address(rdi, r, Interpreter::stackElementScale() , Interpreter::value_offset_in_bytes());53 return Address(rdi, r, Interpreter::stackElementScale()); 54 54 } 55 55 static inline Address laddress(Register r) { … … 60 60 } 61 61 62 static inline Address faddress(Register r) { return iaddress(r); }; 63 static inline Address daddress(Register r) { 64 assert(!TaggedStackInterpreter, "This doesn't work"); 65 return laddress(r); 66 }; 67 static inline Address aaddress(Register r) { return iaddress(r); }; 62 static inline Address faddress(Register r) { return iaddress(r); } 63 static inline Address daddress(Register r) { return laddress(r); } 64 static inline Address aaddress(Register r) { return iaddress(r); } 68 65 69 66 // expression stack … … 379 376 } 380 377 378 // Fast path for caching oop constants. 379 // %%% We should use this to handle Class and String constants also. 380 // %%% It will simplify the ldc/primitive path considerably. 381 void TemplateTable::fast_aldc(bool wide) { 382 transition(vtos, atos); 383 384 if (!EnableMethodHandles) { 385 // We should not encounter this bytecode if !EnableMethodHandles. 386 // The verifier will stop it. However, if we get past the verifier, 387 // this will stop the thread in a reasonable way, without crashing the JVM. 388 __ call_VM(noreg, CAST_FROM_FN_PTR(address, 389 InterpreterRuntime::throw_IncompatibleClassChangeError)); 390 // the call_VM checks for exception, so we should never return here. 391 __ should_not_reach_here(); 392 return; 393 } 394 395 const Register cache = rcx; 396 const Register index = rdx; 397 398 resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1)); 399 if (VerifyOops) { 400 __ verify_oop(rax); 401 } 402 } 403 381 404 void TemplateTable::ldc2_w() { 382 405 transition(vtos, vtos); … … 449 472 locals_index(rbx); 450 473 __ movl(rax, iaddress(rbx)); 451 debug_only(__ verify_local_tag(frame::TagValue, rbx));452 474 } 453 475 … … 457 479 locals_index(rbx); 458 480 __ movl(rax, iaddress(rbx)); 459 debug_only(__ verify_local_tag(frame::TagValue, rbx));460 481 __ push(itos); 461 482 locals_index(rbx, 3); 462 483 __ movl(rax, iaddress(rbx)); 463 debug_only(__ verify_local_tag(frame::TagValue, rbx));464 484 } 465 485 … … 468 488 locals_index(rbx); 469 489 __ movl(rax, iaddress(rbx)); 470 debug_only(__ verify_local_tag(frame::TagValue, rbx));471 490 } 472 491 … … 477 496 __ movptr(rax, laddress(rbx)); 478 497 NOT_LP64(__ movl(rdx, haddress(rbx))); 479 debug_only(__ verify_local_tag(frame::TagCategory2, rbx));480 498 } 481 499 … … 485 503 locals_index(rbx); 486 504 __ fld_s(faddress(rbx)); 487 debug_only(__ verify_local_tag(frame::TagValue, rbx));488 505 } 489 506 … … 492 509 transition(vtos, dtos); 493 510 locals_index(rbx); 494 if (TaggedStackInterpreter) { 495 // Get double out of locals array, onto temp stack and load with 496 // float instruction into ST0 497 __ movl(rax, laddress(rbx)); 498 __ movl(rdx, haddress(rbx)); 499 __ push(rdx); // push hi first 500 __ push(rax); 501 __ fld_d(Address(rsp, 0)); 502 __ addptr(rsp, 2*wordSize); 503 debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); 504 } else { 505 __ fld_d(daddress(rbx)); 506 } 511 __ fld_d(daddress(rbx)); 507 512 } 508 513 … … 512 517 locals_index(rbx); 513 518 __ movptr(rax, aaddress(rbx)); 514 debug_only(__ verify_local_tag(frame::TagReference, rbx));515 519 } 516 520 … … 528 532 locals_index_wide(rbx); 529 533 __ movl(rax, iaddress(rbx)); 530 debug_only(__ verify_local_tag(frame::TagValue, rbx));531 534 } 532 535 … … 537 540 __ movptr(rax, laddress(rbx)); 538 541 NOT_LP64(__ movl(rdx, haddress(rbx))); 539 debug_only(__ verify_local_tag(frame::TagCategory2, rbx));540 542 } 541 543 … … 545 547 locals_index_wide(rbx); 546 548 __ fld_s(faddress(rbx)); 547 debug_only(__ verify_local_tag(frame::TagValue, rbx));548 549 } 549 550 … … 552 553 transition(vtos, dtos); 553 554 locals_index_wide(rbx); 554 if (TaggedStackInterpreter) { 555 // Get double out of locals array, onto temp stack and load with 556 // float instruction into ST0 557 __ movl(rax, laddress(rbx)); 558 __ movl(rdx, haddress(rbx)); 559 __ push(rdx); // push hi first 560 __ push(rax); 561 __ fld_d(Address(rsp, 0)); 562 __ addl(rsp, 2*wordSize); 563 debug_only(__ verify_local_tag(frame::TagCategory2, rbx)); 564 } else { 565 __ fld_d(daddress(rbx)); 566 } 555 __ fld_d(daddress(rbx)); 567 556 } 568 557 … … 572 561 locals_index_wide(rbx); 573 562 __ movptr(rax, aaddress(rbx)); 574 debug_only(__ verify_local_tag(frame::TagReference, rbx));575 563 } 576 564 … … 673 661 locals_index(rbx); 674 662 __ movl(rax, iaddress(rbx)); 675 debug_only(__ verify_local_tag(frame::TagValue, rbx));676 663 677 664 // rdx: array … … 696 683 transition(vtos, itos); 697 684 __ movl(rax, iaddress(n)); 698 debug_only(__ verify_local_tag(frame::TagValue, n));699 685 } 700 686 … … 704 690 __ movptr(rax, laddress(n)); 705 691 NOT_LP64(__ movptr(rdx, haddress(n))); 706 debug_only(__ verify_local_tag(frame::TagCategory2, n));707 692 } 708 693 … … 711 696 transition(vtos, ftos); 712 697 __ fld_s(faddress(n)); 713 debug_only(__ verify_local_tag(frame::TagValue, n));714 698 } 715 699 … … 717 701 void TemplateTable::dload(int n) { 718 702 transition(vtos, dtos); 719 if (TaggedStackInterpreter) { 720 // Get double out of locals array, onto temp stack and load with 721 // float instruction into ST0 722 __ movl(rax, laddress(n)); 723 __ movl(rdx, haddress(n)); 724 __ push(rdx); // push hi first 725 __ push(rax); 726 __ fld_d(Address(rsp, 0)); 727 __ addptr(rsp, 2*wordSize); // reset rsp 728 debug_only(__ verify_local_tag(frame::TagCategory2, n)); 729 } else { 730 __ fld_d(daddress(n)); 731 } 703 __ fld_d(daddress(n)); 732 704 } 733 705 … … 736 708 transition(vtos, atos); 737 709 __ movptr(rax, aaddress(n)); 738 debug_only(__ verify_local_tag(frame::TagReference, n));739 710 } 740 711 … … 810 781 locals_index(rbx); 811 782 __ movl(iaddress(rbx), rax); 812 __ tag_local(frame::TagValue, rbx);813 783 } 814 784 … … 819 789 __ movptr(laddress(rbx), rax); 820 790 NOT_LP64(__ movptr(haddress(rbx), rdx)); 821 __ tag_local(frame::TagCategory2, rbx);822 791 } 823 792 … … 827 796 locals_index(rbx); 828 797 __ fstp_s(faddress(rbx)); 829 __ tag_local(frame::TagValue, rbx);830 798 } 831 799 … … 834 802 transition(dtos, vtos); 835 803 locals_index(rbx); 836 if (TaggedStackInterpreter) { 837 // Store double on stack and reload into locals nonadjacently 838 __ subptr(rsp, 2 * wordSize); 839 __ fstp_d(Address(rsp, 0)); 840 __ pop(rax); 841 __ pop(rdx); 842 __ movptr(laddress(rbx), rax); 843 __ movptr(haddress(rbx), rdx); 844 __ tag_local(frame::TagCategory2, rbx); 845 } else { 846 __ fstp_d(daddress(rbx)); 847 } 804 __ fstp_d(daddress(rbx)); 848 805 } 849 806 … … 851 808 void TemplateTable::astore() { 852 809 transition(vtos, vtos); 853 __ pop_ptr(rax , rdx); // will need to pop tag too810 __ pop_ptr(rax); 854 811 locals_index(rbx); 855 812 __ movptr(aaddress(rbx), rax); 856 __ tag_local(rdx, rbx); // need to store same tag in local may be returnAddr857 813 } 858 814 … … 863 819 locals_index_wide(rbx); 864 820 __ movl(iaddress(rbx), rax); 865 __ tag_local(frame::TagValue, rbx);866 821 } 867 822 … … 873 828 __ movptr(laddress(rbx), rax); 874 829 NOT_LP64(__ movl(haddress(rbx), rdx)); 875 __ tag_local(frame::TagCategory2, rbx);876 830 } 877 831 … … 889 843 void TemplateTable::wide_astore() { 890 844 transition(vtos, vtos); 891 __ pop_ptr(rax , rdx);845 __ pop_ptr(rax); 892 846 locals_index_wide(rbx); 893 847 __ movptr(aaddress(rbx), rax); 894 __ tag_local(rdx, rbx);895 848 } 896 849 … … 991 944 // Pop stack arguments 992 945 __ bind(done); 993 __ addptr(rsp, 3 * Interpreter::stackElementSize ());946 __ addptr(rsp, 3 * Interpreter::stackElementSize); 994 947 } 995 948 … … 1025 978 transition(itos, vtos); 1026 979 __ movl(iaddress(n), rax); 1027 __ tag_local(frame::TagValue, n);1028 980 } 1029 981 … … 1033 985 __ movptr(laddress(n), rax); 1034 986 NOT_LP64(__ movptr(haddress(n), rdx)); 1035 __ tag_local(frame::TagCategory2, n);1036 987 } 1037 988 … … 1040 991 transition(ftos, vtos); 1041 992 __ fstp_s(faddress(n)); 1042 __ tag_local(frame::TagValue, n);1043 993 } 1044 994 … … 1046 996 void TemplateTable::dstore(int n) { 1047 997 transition(dtos, vtos); 1048 if (TaggedStackInterpreter) { 1049 __ subptr(rsp, 2 * wordSize); 1050 __ fstp_d(Address(rsp, 0)); 1051 __ pop(rax); 1052 __ pop(rdx); 1053 __ movl(laddress(n), rax); 1054 __ movl(haddress(n), rdx); 1055 __ tag_local(frame::TagCategory2, n); 1056 } else { 1057 __ fstp_d(daddress(n)); 1058 } 998 __ fstp_d(daddress(n)); 1059 999 } 1060 1000 … … 1062 1002 void TemplateTable::astore(int n) { 1063 1003 transition(vtos, vtos); 1064 __ pop_ptr(rax , rdx);1004 __ pop_ptr(rax); 1065 1005 __ movptr(aaddress(n), rax); 1066 __ tag_local(rdx, n);1067 1006 } 1068 1007 … … 1070 1009 void TemplateTable::pop() { 1071 1010 transition(vtos, vtos); 1072 __ addptr(rsp, Interpreter::stackElementSize ());1011 __ addptr(rsp, Interpreter::stackElementSize); 1073 1012 } 1074 1013 … … 1076 1015 void TemplateTable::pop2() { 1077 1016 transition(vtos, vtos); 1078 __ addptr(rsp, 2*Interpreter::stackElementSize ());1017 __ addptr(rsp, 2*Interpreter::stackElementSize); 1079 1018 } 1080 1019 … … 1083 1022 transition(vtos, vtos); 1084 1023 // stack: ..., a 1085 __ load_ptr _and_tag(0, rax, rdx);1086 __ push_ptr(rax , rdx);1024 __ load_ptr(0, rax); 1025 __ push_ptr(rax); 1087 1026 // stack: ..., a, a 1088 1027 } … … 1092 1031 transition(vtos, vtos); 1093 1032 // stack: ..., a, b 1094 __ load_ptr _and_tag(0, rax, rdx); // load b1095 __ load_ptr _and_tag(1, rcx, rbx); // load a1096 __ store_ptr _and_tag(1, rax, rdx);// store b1097 __ store_ptr _and_tag(0, rcx, rbx);// store a1098 __ push_ptr(rax , rdx);// push b1033 __ load_ptr( 0, rax); // load b 1034 __ load_ptr( 1, rcx); // load a 1035 __ store_ptr(1, rax); // store b 1036 __ store_ptr(0, rcx); // store a 1037 __ push_ptr(rax); // push b 1099 1038 // stack: ..., b, a, b 1100 1039 } … … 1104 1043 transition(vtos, vtos); 1105 1044 // stack: ..., a, b, c 1106 __ load_ptr _and_tag(0, rax, rdx); // load c1107 __ load_ptr _and_tag(2, rcx, rbx); // load a1108 __ store_ptr _and_tag(2, rax, rdx);// store c in a1109 __ push_ptr(rax , rdx);// push c1045 __ load_ptr( 0, rax); // load c 1046 __ load_ptr( 2, rcx); // load a 1047 __ store_ptr(2, rax); // store c in a 1048 __ push_ptr(rax); // push c 1110 1049 // stack: ..., c, b, c, c 1111 __ load_ptr _and_tag(2, rax, rdx); // load b1112 __ store_ptr _and_tag(2, rcx, rbx);// store a in b1050 __ load_ptr( 2, rax); // load b 1051 __ store_ptr(2, rcx); // store a in b 1113 1052 // stack: ..., c, a, c, c 1114 __ store_ptr _and_tag(1, rax, rdx);// store b in c1053 __ store_ptr(1, rax); // store b in c 1115 1054 // stack: ..., c, a, b, c 1116 1055 } … … 1120 1059 transition(vtos, vtos); 1121 1060 // stack: ..., a, b 1122 __ load_ptr _and_tag(1, rax, rdx); // load a1123 __ push_ptr(rax , rdx);// push a1124 __ load_ptr _and_tag(1, rax, rdx); // load b1125 __ push_ptr(rax , rdx);// push b1061 __ load_ptr(1, rax); // load a 1062 __ push_ptr(rax); // push a 1063 __ load_ptr(1, rax); // load b 1064 __ push_ptr(rax); // push b 1126 1065 // stack: ..., a, b, a, b 1127 1066 } … … 1131 1070 transition(vtos, vtos); 1132 1071 // stack: ..., a, b, c 1133 __ load_ptr _and_tag(0, rcx, rbx); // load c1134 __ load_ptr _and_tag(1, rax, rdx); // load b1135 __ push_ptr(rax , rdx);// push b1136 __ push_ptr(rcx , rbx);// push c1072 __ load_ptr( 0, rcx); // load c 1073 __ load_ptr( 1, rax); // load b 1074 __ push_ptr(rax); // push b 1075 __ push_ptr(rcx); // push c 1137 1076 // stack: ..., a, b, c, b, c 1138 __ store_ptr _and_tag(3, rcx, rbx);// store c in b1077 __ store_ptr(3, rcx); // store c in b 1139 1078 // stack: ..., a, c, c, b, c 1140 __ load_ptr _and_tag(4, rcx, rbx); // load a1141 __ store_ptr _and_tag(2, rcx, rbx);// store a in 2nd c1079 __ load_ptr( 4, rcx); // load a 1080 __ store_ptr(2, rcx); // store a in 2nd c 1142 1081 // stack: ..., a, c, a, b, c 1143 __ store_ptr _and_tag(4, rax, rdx);// store b in a1082 __ store_ptr(4, rax); // store b in a 1144 1083 // stack: ..., b, c, a, b, c 1145 1084 // stack: ..., b, c, a, b, c … … 1150 1089 transition(vtos, vtos); 1151 1090 // stack: ..., a, b, c, d 1152 __ load_ptr _and_tag(0, rcx, rbx); // load d1153 __ load_ptr _and_tag(1, rax, rdx); // load c1154 __ push_ptr(rax , rdx);// push c1155 __ push_ptr(rcx , rbx);// push d1091 __ load_ptr( 0, rcx); // load d 1092 __ load_ptr( 1, rax); // load c 1093 __ push_ptr(rax); // push c 1094 __ push_ptr(rcx); // push d 1156 1095 // stack: ..., a, b, c, d, c, d 1157 __ load_ptr _and_tag(4, rax, rdx); // load b1158 __ store_ptr _and_tag(2, rax, rdx);// store b in d1159 __ store_ptr _and_tag(4, rcx, rbx);// store d in b1096 __ load_ptr( 4, rax); // load b 1097 __ store_ptr(2, rax); // store b in d 1098 __ store_ptr(4, rcx); // store d in b 1160 1099 // stack: ..., a, d, c, b, c, d 1161 __ load_ptr _and_tag(5, rcx, rbx); // load a1162 __ load_ptr _and_tag(3, rax, rdx); // load c1163 __ store_ptr _and_tag(3, rcx, rbx);// store a in c1164 __ store_ptr _and_tag(5, rax, rdx);// store c in a1100 __ load_ptr( 5, rcx); // load a 1101 __ load_ptr( 3, rax); // load c 1102 __ store_ptr(3, rcx); // store a in c 1103 __ store_ptr(5, rax); // store c in a 1165 1104 // stack: ..., c, d, a, b, c, d 1166 1105 // stack: ..., c, d, a, b, c, d … … 1171 1110 transition(vtos, vtos); 1172 1111 // stack: ..., a, b 1173 __ load_ptr _and_tag(1, rcx, rbx); // load a1174 __ load_ptr _and_tag(0, rax, rdx); // load b1175 __ store_ptr _and_tag(0, rcx, rbx);// store a in b1176 __ store_ptr _and_tag(1, rax, rdx);// store b in a1112 __ load_ptr( 1, rcx); // load a 1113 __ load_ptr( 0, rax); // load b 1114 __ store_ptr(0, rcx); // store a in b 1115 __ store_ptr(1, rax); // store b in a 1177 1116 // stack: ..., b, a 1178 1117 } … … 1182 1121 transition(itos, itos); 1183 1122 switch (op) { 1184 case add : 1123 case add : __ pop_i(rdx); __ addl (rax, rdx); break; 1185 1124 case sub : __ mov(rdx, rax); __ pop_i(rax); __ subl (rax, rdx); break; 1186 case mul : 1187 case _and : 1188 case _or : 1189 case _xor : 1125 case mul : __ pop_i(rdx); __ imull(rax, rdx); break; 1126 case _and : __ pop_i(rdx); __ andl (rax, rdx); break; 1127 case _or : __ pop_i(rdx); __ orl (rax, rdx); break; 1128 case _xor : __ pop_i(rdx); __ xorl (rax, rdx); break; 1190 1129 case shl : __ mov(rcx, rax); __ pop_i(rax); __ shll (rax); break; // implicit masking of lower 5 bits by Intel shift instr. 1191 1130 case shr : __ mov(rcx, rax); __ pop_i(rax); __ sarl (rax); break; // implicit masking of lower 5 bits by Intel shift instr. … … 1200 1139 __ pop_l(rbx, rcx); 1201 1140 switch (op) { 1202 case add : __ addl(rax, rbx); __ adcl(rdx, rcx); break;1203 case sub : __ subl(rbx, rax); __ sbbl(rcx, rdx);1204 __ mov(rax, rbx); __ mov(rdx, rcx); break;1205 case _and : __ andl(rax, rbx); __ andl(rdx, rcx); break;1206 case _or : __ orl (rax, rbx); __ orl (rdx, rcx); break;1207 case _xor : __ xorl(rax, rbx); __ xorl(rdx, rcx); break;1208 default : ShouldNotReachHere();1141 case add : __ addl(rax, rbx); __ adcl(rdx, rcx); break; 1142 case sub : __ subl(rbx, rax); __ sbbl(rcx, rdx); 1143 __ mov (rax, rbx); __ mov (rdx, rcx); break; 1144 case _and : __ andl(rax, rbx); __ andl(rdx, rcx); break; 1145 case _or : __ orl (rax, rbx); __ orl (rdx, rcx); break; 1146 case _xor : __ xorl(rax, rbx); __ xorl(rdx, rcx); break; 1147 default : ShouldNotReachHere(); 1209 1148 } 1210 1149 } … … 1300 1239 void TemplateTable::fop2(Operation op) { 1301 1240 transition(ftos, ftos); 1302 __ pop_ftos_to_rsp(); // pop ftos into rsp1303 1241 switch (op) { 1304 1242 case add: __ fadd_s (at_rsp()); break; … … 1316 1254 void TemplateTable::dop2(Operation op) { 1317 1255 transition(dtos, dtos); 1318 __ pop_dtos_to_rsp(); // pop dtos into rsp1319 1256 1320 1257 switch (op) { … … 1558 1495 void TemplateTable::float_cmp(bool is_float, int unordered_result) { 1559 1496 if (is_float) { 1560 __ pop_ftos_to_rsp();1561 1497 __ fld_s(at_rsp()); 1562 1498 } else { 1563 __ pop_dtos_to_rsp();1564 1499 __ fld_d(at_rsp()); 1565 1500 __ pop(rdx); … … 2104 2039 } 2105 2040 2106 void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) { 2107 assert(byte_no == 1 || byte_no == 2, "byte_no out of range"); 2108 bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic); 2109 2041 void TemplateTable::resolve_cache_and_index(int byte_no, 2042 Register result, 2043 Register Rcache, 2044 Register index, 2045 size_t index_size) { 2110 2046 Register temp = rbx; 2111 2047 2112 assert_different_registers(Rcache, index, temp); 2113 2114 const int shift_count = (1 + byte_no)*BitsPerByte; 2048 assert_different_registers(result, Rcache, index, temp); 2049 2115 2050 Label resolved; 2116 __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic); 2117 if (is_invokedynamic) { 2118 // we are resolved if the f1 field contains a non-null CallSite object 2119 __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD); 2051 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); 2052 if (byte_no == f1_oop) { 2053 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) 2054 // This kind of CP cache entry does not need to match the flags byte, because 2055 // there is a 1-1 relation between bytecode type and CP entry type. 2056 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) 2057 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); 2058 __ testptr(result, result); 2120 2059 __ jcc(Assembler::notEqual, resolved); 2121 2060 } else { 2061 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); 2062 assert(result == noreg, ""); //else change code for setting result 2063 const int shift_count = (1 + byte_no)*BitsPerByte; 2122 2064 __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); 2123 2065 __ shrl(temp, shift_count); … … 2140 2082 case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break; 2141 2083 case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break; 2084 case Bytecodes::_fast_aldc : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break; 2085 case Bytecodes::_fast_aldc_w : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break; 2142 2086 default : ShouldNotReachHere(); break; 2143 2087 } … … 2145 2089 __ call_VM(noreg, entry, temp); 2146 2090 // Update registers with resolved info 2147 __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic); 2091 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); 2092 if (result != noreg) 2093 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); 2148 2094 __ bind(resolved); 2149 2095 } … … 2179 2125 Register flags, 2180 2126 bool is_invokevirtual, 2181 bool is_invokevfinal /*unused*/) { 2127 bool is_invokevfinal /*unused*/, 2128 bool is_invokedynamic) { 2182 2129 // setup registers 2183 2130 const Register cache = rcx; … … 2201 2148 ConstantPoolCacheEntry::f2_offset()); 2202 2149 2203 resolve_cache_and_index(byte_no, cache, index); 2204 2205 __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); 2150 if (byte_no == f1_oop) { 2151 // Resolved f1_oop goes directly into 'method' register. 2152 assert(is_invokedynamic, ""); 2153 resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4)); 2154 } else { 2155 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); 2156 __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); 2157 } 2206 2158 if (itable_index != noreg) { 2207 2159 __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset)); 2208 2160 } 2209 __ movl(flags , Address(cache, index, Address::times_ptr, flags_offset));2161 __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset)); 2210 2162 } 2211 2163 … … 2261 2213 const Register flags = rax; 2262 2214 2263 resolve_cache_and_index(byte_no, cache, index);2215 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); 2264 2216 jvmti_post_field_access(cache, index, is_static, false); 2265 2217 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); … … 2470 2422 const Register flags = rax; 2471 2423 2472 resolve_cache_and_index(byte_no, cache, index);2424 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); 2473 2425 jvmti_post_field_mod(cache, index, is_static); 2474 2426 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); … … 2855 2807 // get receiver 2856 2808 __ movptr(rax, aaddress(0)); 2857 debug_only(__ verify_local_tag(frame::TagReference, 0));2858 2809 // access constant pool cache 2859 2810 __ get_cache_and_index_at_bcp(rcx, rdx, 2); … … 2891 2842 2892 2843 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) { 2893 bool is_invdyn_bootstrap = (byte_no < 0);2894 if (is_invdyn_bootstrap) byte_no = -byte_no;2895 2896 2844 // determine flags 2897 2845 Bytecodes::Code code = bytecode(); … … 2908 2856 assert_different_registers(method, index, recv, flags); 2909 2857 2910 assert(!is_invdyn_bootstrap || is_invokedynamic, "byte_no<0 hack only for invdyn");2911 2912 2858 // save 'interpreter return address' 2913 2859 __ save_bcp(); 2914 2860 2915 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual );2861 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic); 2916 2862 2917 2863 // load receiver if needed (note: no return address pushed yet) 2918 2864 if (load_receiver) { 2865 assert(!is_invokedynamic, ""); 2919 2866 __ movl(recv, flags); 2920 2867 __ andl(recv, 0xFF); 2921 2868 // recv count is 0 based? 2922 2869 Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1)); 2923 if (is_invokedynamic) { 2924 __ lea(recv, recv_addr); 2925 } else { 2926 __ movptr(recv, recv_addr); 2927 __ verify_oop(recv); 2928 } 2870 __ movptr(recv, recv_addr); 2871 __ verify_oop(recv); 2929 2872 } 2930 2873 … … 2945 2888 { 2946 2889 address table_addr; 2947 if (is_invdyn_bootstrap) 2948 table_addr = (address)Interpreter::return_5_unbox_addrs_by_index_table(); 2949 else if (is_invokeinterface || is_invokedynamic) 2890 if (is_invokeinterface || is_invokedynamic) 2950 2891 table_addr = (address)Interpreter::return_5_addrs_by_index_table(); 2951 2892 else … … 3014 2955 void TemplateTable::invokevirtual(int byte_no) { 3015 2956 transition(vtos, vtos); 2957 assert(byte_no == f2_byte, "use this argument"); 3016 2958 prepare_invoke(rbx, noreg, byte_no); 3017 2959 … … 3026 2968 void TemplateTable::invokespecial(int byte_no) { 3027 2969 transition(vtos, vtos); 2970 assert(byte_no == f1_byte, "use this argument"); 3028 2971 prepare_invoke(rbx, noreg, byte_no); 3029 2972 // do the call … … 3036 2979 void TemplateTable::invokestatic(int byte_no) { 3037 2980 transition(vtos, vtos); 2981 assert(byte_no == f1_byte, "use this argument"); 3038 2982 prepare_invoke(rbx, noreg, byte_no); 3039 2983 // do the call … … 3046 2990 void TemplateTable::fast_invokevfinal(int byte_no) { 3047 2991 transition(vtos, vtos); 2992 assert(byte_no == f2_byte, "use this argument"); 3048 2993 __ stop("fast_invokevfinal not used on x86"); 3049 2994 } … … 3052 2997 void TemplateTable::invokeinterface(int byte_no) { 3053 2998 transition(vtos, vtos); 2999 assert(byte_no == f1_byte, "use this argument"); 3054 3000 prepare_invoke(rax, rbx, byte_no); 3055 3001 … … 3140 3086 } 3141 3087 3088 assert(byte_no == f1_oop, "use this argument"); 3142 3089 prepare_invoke(rax, rbx, byte_no); 3143 3090 3144 3091 // rax: CallSite object (f1) 3145 3092 // rbx: unused (f2) 3146 // rcx: receiver address3147 3093 // rdx: flags (unused) 3148 3094 … … 3154 3100 } 3155 3101 3156 Label handle_unlinked_site; 3157 __ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx))); 3158 __ testptr(rcx, rcx); 3159 __ jcc(Assembler::zero, handle_unlinked_site); 3160 3102 __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); 3103 __ null_check(rcx); 3161 3104 __ prepare_to_jump_from_interpreted(); 3162 __ jump_to_method_handle_entry(rcx, rdx);3163 3164 // Initial calls come here...3165 __ bind(handle_unlinked_site);3166 __ pop(rcx); // remove return address pushed by prepare_invoke3167 3168 // box stacked arguments into an array for the bootstrap method3169 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);3170 __ restore_bcp(); // rsi must be correct for call_VM3171 __ call_VM(rax, entry, rax);3172 __ movl(rdi, rax); // protect bootstrap MH from prepare_invoke3173 3174 // recompute return address3175 __ restore_bcp(); // rsi must be correct for prepare_invoke3176 prepare_invoke(rax, rbx, -byte_no); // smashes rcx, rdx3177 // rax: CallSite object (f1)3178 // rbx: unused (f2)3179 // rdi: bootstrap MH3180 // rdx: flags3181 3182 // now load up the arglist, which has been neatly boxed3183 __ get_thread(rcx);3184 __ movptr(rdx, Address(rcx, JavaThread::vm_result_2_offset()));3185 __ movptr(Address(rcx, JavaThread::vm_result_2_offset()), NULL_WORD);3186 __ verify_oop(rdx);3187 // rdx = arglist3188 3189 // save SP now, before we add the bootstrap call to the stack3190 // We must preserve a fiction that the original arguments are outgoing,3191 // because the return sequence will reset the stack to this point3192 // and then pop all those arguments. It seems error-prone to use3193 // a different argument list size just for bootstrapping.3194 __ prepare_to_jump_from_interpreted();3195 3196 // Now let's play adapter, pushing the real arguments on the stack.3197 __ pop(rbx); // return PC3198 __ push(rdi); // boot MH3199 __ push(rax); // call site3200 __ push(rdx); // arglist3201 __ push(rbx); // return PC, again3202 __ mov(rcx, rdi);3203 3105 __ jump_to_method_handle_entry(rcx, rdx); 3204 3106 } … … 3211 3113 __ get_unsigned_2_byte_index_at_bcp(rdx, 1); 3212 3114 Label slow_case; 3115 Label slow_case_no_pop; 3213 3116 Label done; 3214 3117 Label initialize_header; … … 3217 3120 3218 3121 __ get_cpool_and_tags(rcx, rax); 3122 3123 // Make sure the class we're about to instantiate has been resolved. 3124 // This is done before loading instanceKlass to be consistent with the order 3125 // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put) 3126 const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; 3127 __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class); 3128 __ jcc(Assembler::notEqual, slow_case_no_pop); 3129 3219 3130 // get instanceKlass 3220 3131 __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc))); 3221 3132 __ push(rcx); // save the contexts of klass for initializing the header 3222 3223 // make sure the class we're about to instantiate has been resolved.3224 // Note: slow_case does a pop of stack, which is why we loaded class/pushed above3225 const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize;3226 __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class);3227 __ jcc(Assembler::notEqual, slow_case);3228 3133 3229 3134 // make sure klass is initialized & doesn't have finalizer … … 3354 3259 __ bind(slow_case); 3355 3260 __ pop(rcx); // restore stack pointer to what it was when we came in. 3261 __ bind(slow_case_no_pop); 3356 3262 __ get_constant_pool(rax); 3357 3263 __ get_unsigned_2_byte_index_at_bcp(rdx, 1); -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp
r2 r278 1 1 /* 2 * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 59 59 60 60 static inline Address iaddress(Register r) { 61 return Address(r14, r, Address::times_8 , Interpreter::value_offset_in_bytes());61 return Address(r14, r, Address::times_8); 62 62 } 63 63 … … 204 204 __ get_method(scratch); 205 205 // Let breakpoint table handling rewrite to quicker bytecode 206 __ call_VM(noreg, 207 CAST_FROM_FN_PTR(address, 208 InterpreterRuntime::set_original_bytecode_at), 209 scratch, r13, bc); 206 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc); 210 207 #ifndef ASSERT 211 208 __ jmpb(patch_done); 212 __ bind(fast_patch);213 }214 209 #else 215 210 __ jmp(patch_done); 211 #endif 216 212 __ bind(fast_patch); 217 213 } 214 #ifdef ASSERT 218 215 Label okay; 219 216 __ load_unsigned_byte(scratch, at_bcp(0)); … … 393 390 } 394 391 392 // Fast path for caching oop constants. 393 // %%% We should use this to handle Class and String constants also. 394 // %%% It will simplify the ldc/primitive path considerably. 395 void TemplateTable::fast_aldc(bool wide) { 396 transition(vtos, atos); 397 398 if (!EnableMethodHandles) { 399 // We should not encounter this bytecode if !EnableMethodHandles. 400 // The verifier will stop it. However, if we get past the verifier, 401 // this will stop the thread in a reasonable way, without crashing the JVM. 402 __ call_VM(noreg, CAST_FROM_FN_PTR(address, 403 InterpreterRuntime::throw_IncompatibleClassChangeError)); 404 // the call_VM checks for exception, so we should never return here. 405 __ should_not_reach_here(); 406 return; 407 } 408 409 const Register cache = rcx; 410 const Register index = rdx; 411 412 resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1)); 413 if (VerifyOops) { 414 __ verify_oop(rax); 415 } 416 } 417 395 418 void TemplateTable::ldc2_w() { 396 419 transition(vtos, vtos); … … 422 445 __ load_unsigned_byte(reg, at_bcp(offset)); 423 446 __ negptr(reg); 424 if (TaggedStackInterpreter) __ shlptr(reg, 1); // index = index*2425 447 } 426 448 … … 464 486 locals_index(rbx); 465 487 __ movl(rax, iaddress(rbx)); 466 debug_only(__ verify_local_tag(frame::TagValue, rbx));467 488 } 468 489 … … 471 492 locals_index(rbx); 472 493 __ movl(rax, iaddress(rbx)); 473 debug_only(__ verify_local_tag(frame::TagValue, rbx));474 494 __ push(itos); 475 495 locals_index(rbx, 3); 476 496 __ movl(rax, iaddress(rbx)); 477 debug_only(__ verify_local_tag(frame::TagValue, rbx));478 497 } 479 498 … … 482 501 locals_index(rbx); 483 502 __ movl(rax, iaddress(rbx)); 484 debug_only(__ verify_local_tag(frame::TagValue, rbx));485 503 } 486 504 … … 489 507 locals_index(rbx); 490 508 __ movq(rax, laddress(rbx)); 491 debug_only(__ verify_local_tag(frame::TagCategory2, rbx));492 509 } 493 510 … … 496 513 locals_index(rbx); 497 514 __ movflt(xmm0, faddress(rbx)); 498 debug_only(__ verify_local_tag(frame::TagValue, rbx));499 515 } 500 516 … … 503 519 locals_index(rbx); 504 520 __ movdbl(xmm0, daddress(rbx)); 505 debug_only(__ verify_local_tag(frame::TagCategory2, rbx));506 521 } 507 522 … … 510 525 locals_index(rbx); 511 526 __ movptr(rax, aaddress(rbx)); 512 debug_only(__ verify_local_tag(frame::TagReference, rbx));513 527 } 514 528 … … 518 532 __ shrl(reg, 16); 519 533 __ negptr(reg); 520 if (TaggedStackInterpreter) __ shlptr(reg, 1); // index = index*2521 534 } 522 535 … … 525 538 locals_index_wide(rbx); 526 539 __ movl(rax, iaddress(rbx)); 527 debug_only(__ verify_local_tag(frame::TagValue, rbx));528 540 } 529 541 … … 532 544 locals_index_wide(rbx); 533 545 __ movq(rax, laddress(rbx)); 534 debug_only(__ verify_local_tag(frame::TagCategory2, rbx));535 546 } 536 547 … … 539 550 locals_index_wide(rbx); 540 551 __ movflt(xmm0, faddress(rbx)); 541 debug_only(__ verify_local_tag(frame::TagValue, rbx));542 552 } 543 553 … … 546 556 locals_index_wide(rbx); 547 557 __ movdbl(xmm0, daddress(rbx)); 548 debug_only(__ verify_local_tag(frame::TagCategory2, rbx));549 558 } 550 559 … … 553 562 locals_index_wide(rbx); 554 563 __ movptr(rax, aaddress(rbx)); 555 debug_only(__ verify_local_tag(frame::TagReference, rbx));556 564 } 557 565 … … 658 666 locals_index(rbx); 659 667 __ movl(rax, iaddress(rbx)); 660 debug_only(__ verify_local_tag(frame::TagValue, rbx));661 668 662 669 // eax: index … … 685 692 transition(vtos, itos); 686 693 __ movl(rax, iaddress(n)); 687 debug_only(__ verify_local_tag(frame::TagValue, n));688 694 } 689 695 … … 691 697 transition(vtos, ltos); 692 698 __ movq(rax, laddress(n)); 693 debug_only(__ verify_local_tag(frame::TagCategory2, n));694 699 } 695 700 … … 697 702 transition(vtos, ftos); 698 703 __ movflt(xmm0, faddress(n)); 699 debug_only(__ verify_local_tag(frame::TagValue, n));700 704 } 701 705 … … 703 707 transition(vtos, dtos); 704 708 __ movdbl(xmm0, daddress(n)); 705 debug_only(__ verify_local_tag(frame::TagCategory2, n));706 709 } 707 710 … … 709 712 transition(vtos, atos); 710 713 __ movptr(rax, aaddress(n)); 711 debug_only(__ verify_local_tag(frame::TagReference, n));712 714 } 713 715 … … 795 797 locals_index(rbx); 796 798 __ movl(iaddress(rbx), rax); 797 __ tag_local(frame::TagValue, rbx);798 799 } 799 800 … … 802 803 locals_index(rbx); 803 804 __ movq(laddress(rbx), rax); 804 __ tag_local(frame::TagCategory2, rbx);805 805 } 806 806 … … 809 809 locals_index(rbx); 810 810 __ movflt(faddress(rbx), xmm0); 811 __ tag_local(frame::TagValue, rbx);812 811 } 813 812 … … 816 815 locals_index(rbx); 817 816 __ movdbl(daddress(rbx), xmm0); 818 __ tag_local(frame::TagCategory2, rbx);819 817 } 820 818 821 819 void TemplateTable::astore() { 822 820 transition(vtos, vtos); 823 __ pop_ptr(rax , rdx); // will need to pop tag too821 __ pop_ptr(rax); 824 822 locals_index(rbx); 825 823 __ movptr(aaddress(rbx), rax); 826 __ tag_local(rdx, rbx); // store tag from stack, might be returnAddr827 824 } 828 825 … … 832 829 locals_index_wide(rbx); 833 830 __ movl(iaddress(rbx), rax); 834 __ tag_local(frame::TagValue, rbx);835 831 } 836 832 … … 840 836 locals_index_wide(rbx); 841 837 __ movq(laddress(rbx), rax); 842 __ tag_local(frame::TagCategory2, rbx);843 838 } 844 839 … … 848 843 locals_index_wide(rbx); 849 844 __ movflt(faddress(rbx), xmm0); 850 __ tag_local(frame::TagValue, rbx);851 845 } 852 846 … … 856 850 locals_index_wide(rbx); 857 851 __ movdbl(daddress(rbx), xmm0); 858 __ tag_local(frame::TagCategory2, rbx);859 852 } 860 853 861 854 void TemplateTable::wide_astore() { 862 855 transition(vtos, vtos); 863 __ pop_ptr(rax , rdx); // will need to pop tag too856 __ pop_ptr(rax); 864 857 locals_index_wide(rbx); 865 858 __ movptr(aaddress(rbx), rax); 866 __ tag_local(rdx, rbx); // store tag from stack, might be returnAddr867 859 } 868 860 … … 976 968 // Pop stack arguments 977 969 __ bind(done); 978 __ addptr(rsp, 3 * Interpreter::stackElementSize ());970 __ addptr(rsp, 3 * Interpreter::stackElementSize); 979 971 } 980 972 … … 1014 1006 transition(itos, vtos); 1015 1007 __ movl(iaddress(n), rax); 1016 __ tag_local(frame::TagValue, n);1017 1008 } 1018 1009 … … 1020 1011 transition(ltos, vtos); 1021 1012 __ movq(laddress(n), rax); 1022 __ tag_local(frame::TagCategory2, n);1023 1013 } 1024 1014 … … 1026 1016 transition(ftos, vtos); 1027 1017 __ movflt(faddress(n), xmm0); 1028 __ tag_local(frame::TagValue, n);1029 1018 } 1030 1019 … … 1032 1021 transition(dtos, vtos); 1033 1022 __ movdbl(daddress(n), xmm0); 1034 __ tag_local(frame::TagCategory2, n);1035 1023 } 1036 1024 1037 1025 void TemplateTable::astore(int n) { 1038 1026 transition(vtos, vtos); 1039 __ pop_ptr(rax , rdx);1027 __ pop_ptr(rax); 1040 1028 __ movptr(aaddress(n), rax); 1041 __ tag_local(rdx, n);1042 1029 } 1043 1030 1044 1031 void TemplateTable::pop() { 1045 1032 transition(vtos, vtos); 1046 __ addptr(rsp, Interpreter::stackElementSize ());1033 __ addptr(rsp, Interpreter::stackElementSize); 1047 1034 } 1048 1035 1049 1036 void TemplateTable::pop2() { 1050 1037 transition(vtos, vtos); 1051 __ addptr(rsp, 2 * Interpreter::stackElementSize ());1038 __ addptr(rsp, 2 * Interpreter::stackElementSize); 1052 1039 } 1053 1040 1054 1041 void TemplateTable::dup() { 1055 1042 transition(vtos, vtos); 1056 __ load_ptr _and_tag(0, rax, rdx);1057 __ push_ptr(rax , rdx);1043 __ load_ptr(0, rax); 1044 __ push_ptr(rax); 1058 1045 // stack: ..., a, a 1059 1046 } … … 1062 1049 transition(vtos, vtos); 1063 1050 // stack: ..., a, b 1064 __ load_ptr _and_tag(0, rax, rdx); // load b1065 __ load_ptr _and_tag(1, rcx, rbx); // load a1066 __ store_ptr _and_tag(1, rax, rdx);// store b1067 __ store_ptr _and_tag(0, rcx, rbx);// store a1068 __ push_ptr(rax , rdx);// push b1051 __ load_ptr( 0, rax); // load b 1052 __ load_ptr( 1, rcx); // load a 1053 __ store_ptr(1, rax); // store b 1054 __ store_ptr(0, rcx); // store a 1055 __ push_ptr(rax); // push b 1069 1056 // stack: ..., b, a, b 1070 1057 } … … 1073 1060 transition(vtos, vtos); 1074 1061 // stack: ..., a, b, c 1075 __ load_ptr _and_tag(0, rax, rdx); // load c1076 __ load_ptr _and_tag(2, rcx, rbx); // load a1077 __ store_ptr _and_tag(2, rax, rdx);// store c in a1078 __ push_ptr(rax , rdx);// push c1062 __ load_ptr( 0, rax); // load c 1063 __ load_ptr( 2, rcx); // load a 1064 __ store_ptr(2, rax); // store c in a 1065 __ push_ptr(rax); // push c 1079 1066 // stack: ..., c, b, c, c 1080 __ load_ptr _and_tag(2, rax, rdx); // load b1081 __ store_ptr _and_tag(2, rcx, rbx);// store a in b1067 __ load_ptr( 2, rax); // load b 1068 __ store_ptr(2, rcx); // store a in b 1082 1069 // stack: ..., c, a, c, c 1083 __ store_ptr _and_tag(1, rax, rdx);// store b in c1070 __ store_ptr(1, rax); // store b in c 1084 1071 // stack: ..., c, a, b, c 1085 1072 } … … 1088 1075 transition(vtos, vtos); 1089 1076 // stack: ..., a, b 1090 __ load_ptr _and_tag(1, rax, rdx); // load a1091 __ push_ptr(rax , rdx);// push a1092 __ load_ptr _and_tag(1, rax, rdx); // load b1093 __ push_ptr(rax , rdx);// push b1077 __ load_ptr(1, rax); // load a 1078 __ push_ptr(rax); // push a 1079 __ load_ptr(1, rax); // load b 1080 __ push_ptr(rax); // push b 1094 1081 // stack: ..., a, b, a, b 1095 1082 } … … 1098 1085 transition(vtos, vtos); 1099 1086 // stack: ..., a, b, c 1100 __ load_ptr _and_tag(0, rcx, rbx); // load c1101 __ load_ptr _and_tag(1, rax, rdx); // load b1102 __ push_ptr(rax , rdx);// push b1103 __ push_ptr(rcx , rbx);// push c1087 __ load_ptr( 0, rcx); // load c 1088 __ load_ptr( 1, rax); // load b 1089 __ push_ptr(rax); // push b 1090 __ push_ptr(rcx); // push c 1104 1091 // stack: ..., a, b, c, b, c 1105 __ store_ptr _and_tag(3, rcx, rbx);// store c in b1092 __ store_ptr(3, rcx); // store c in b 1106 1093 // stack: ..., a, c, c, b, c 1107 __ load_ptr _and_tag(4, rcx, rbx); // load a1108 __ store_ptr _and_tag(2, rcx, rbx);// store a in 2nd c1094 __ load_ptr( 4, rcx); // load a 1095 __ store_ptr(2, rcx); // store a in 2nd c 1109 1096 // stack: ..., a, c, a, b, c 1110 __ store_ptr _and_tag(4, rax, rdx);// store b in a1097 __ store_ptr(4, rax); // store b in a 1111 1098 // stack: ..., b, c, a, b, c 1112 1099 } … … 1115 1102 transition(vtos, vtos); 1116 1103 // stack: ..., a, b, c, d 1117 __ load_ptr _and_tag(0, rcx, rbx); // load d1118 __ load_ptr _and_tag(1, rax, rdx); // load c1119 __ push_ptr(rax , rdx);// push c1120 __ push_ptr(rcx , rbx);// push d1104 __ load_ptr( 0, rcx); // load d 1105 __ load_ptr( 1, rax); // load c 1106 __ push_ptr(rax); // push c 1107 __ push_ptr(rcx); // push d 1121 1108 // stack: ..., a, b, c, d, c, d 1122 __ load_ptr _and_tag(4, rax, rdx); // load b1123 __ store_ptr _and_tag(2, rax, rdx);// store b in d1124 __ store_ptr _and_tag(4, rcx, rbx);// store d in b1109 __ load_ptr( 4, rax); // load b 1110 __ store_ptr(2, rax); // store b in d 1111 __ store_ptr(4, rcx); // store d in b 1125 1112 // stack: ..., a, d, c, b, c, d 1126 __ load_ptr _and_tag(5, rcx, rbx); // load a1127 __ load_ptr _and_tag(3, rax, rdx); // load c1128 __ store_ptr _and_tag(3, rcx, rbx);// store a in c1129 __ store_ptr _and_tag(5, rax, rdx);// store c in a1113 __ load_ptr( 5, rcx); // load a 1114 __ load_ptr( 3, rax); // load c 1115 __ store_ptr(3, rcx); // store a in c 1116 __ store_ptr(5, rax); // store c in a 1130 1117 // stack: ..., c, d, a, b, c, d 1131 1118 } … … 1134 1121 transition(vtos, vtos); 1135 1122 // stack: ..., a, b 1136 __ load_ptr _and_tag(1, rcx, rbx); // load a1137 __ load_ptr _and_tag(0, rax, rdx); // load b1138 __ store_ptr _and_tag(0, rcx, rbx);// store a in b1139 __ store_ptr _and_tag(1, rax, rdx);// store b in a1123 __ load_ptr( 1, rcx); // load a 1124 __ load_ptr( 0, rax); // load b 1125 __ store_ptr(0, rcx); // store a in b 1126 __ store_ptr(1, rax); // store b in a 1140 1127 // stack: ..., b, a 1141 1128 } … … 1160 1147 transition(ltos, ltos); 1161 1148 switch (op) { 1162 case add : __ pop_l(rdx); __ addptr 1163 case sub : __ mov(rdx, rax); __ pop_l(rax); __ subptr 1164 case _and : __ pop_l(rdx); __ andptr 1165 case _or : __ pop_l(rdx); __ orptr 1166 case _xor : __ pop_l(rdx); __ xorptr 1167 default : ShouldNotReachHere();1149 case add : __ pop_l(rdx); __ addptr(rax, rdx); break; 1150 case sub : __ mov(rdx, rax); __ pop_l(rax); __ subptr(rax, rdx); break; 1151 case _and : __ pop_l(rdx); __ andptr(rax, rdx); break; 1152 case _or : __ pop_l(rdx); __ orptr (rax, rdx); break; 1153 case _xor : __ pop_l(rdx); __ xorptr(rax, rdx); break; 1154 default : ShouldNotReachHere(); 1168 1155 } 1169 1156 } … … 1254 1241 case add: 1255 1242 __ addss(xmm0, at_rsp()); 1256 __ addptr(rsp, Interpreter::stackElementSize ());1243 __ addptr(rsp, Interpreter::stackElementSize); 1257 1244 break; 1258 1245 case sub: … … 1263 1250 case mul: 1264 1251 __ mulss(xmm0, at_rsp()); 1265 __ addptr(rsp, Interpreter::stackElementSize ());1252 __ addptr(rsp, Interpreter::stackElementSize); 1266 1253 break; 1267 1254 case div: … … 1286 1273 case add: 1287 1274 __ addsd(xmm0, at_rsp()); 1288 __ addptr(rsp, 2 * Interpreter::stackElementSize ());1275 __ addptr(rsp, 2 * Interpreter::stackElementSize); 1289 1276 break; 1290 1277 case sub: … … 1295 1282 case mul: 1296 1283 __ mulsd(xmm0, at_rsp()); 1297 __ addptr(rsp, 2 * Interpreter::stackElementSize ());1284 __ addptr(rsp, 2 * Interpreter::stackElementSize); 1298 1285 break; 1299 1286 case div: … … 2056 2043 2057 2044 void TemplateTable::resolve_cache_and_index(int byte_no, 2045 Register result, 2058 2046 Register Rcache, 2059 Register index) { 2060 assert(byte_no == 1 || byte_no == 2, "byte_no out of range"); 2061 2047 Register index, 2048 size_t index_size) { 2062 2049 const Register temp = rbx; 2063 assert_different_registers(Rcache, index, temp); 2064 2065 const int shift_count = (1 + byte_no) * BitsPerByte; 2050 assert_different_registers(result, Rcache, index, temp); 2051 2066 2052 Label resolved; 2067 __ get_cache_and_index_at_bcp(Rcache, index, 1); 2068 __ movl(temp, Address(Rcache, 2069 index, Address::times_8, 2070 constantPoolCacheOopDesc::base_offset() + 2071 ConstantPoolCacheEntry::indices_offset())); 2072 __ shrl(temp, shift_count); 2073 // have we resolved this bytecode? 2074 __ andl(temp, 0xFF); 2075 __ cmpl(temp, (int) bytecode()); 2076 __ jcc(Assembler::equal, resolved); 2053 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); 2054 if (byte_no == f1_oop) { 2055 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) 2056 // This kind of CP cache entry does not need to match the flags byte, because 2057 // there is a 1-1 relation between bytecode type and CP entry type. 2058 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) 2059 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); 2060 __ testptr(result, result); 2061 __ jcc(Assembler::notEqual, resolved); 2062 } else { 2063 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); 2064 assert(result == noreg, ""); //else change code for setting result 2065 const int shift_count = (1 + byte_no) * BitsPerByte; 2066 __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); 2067 __ shrl(temp, shift_count); 2068 // have we resolved this bytecode? 2069 __ andl(temp, 0xFF); 2070 __ cmpl(temp, (int) bytecode()); 2071 __ jcc(Assembler::equal, resolved); 2072 } 2077 2073 2078 2074 // resolve first time through … … 2091 2087 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); 2092 2088 break; 2089 case Bytecodes::_invokedynamic: 2090 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); 2091 break; 2092 case Bytecodes::_fast_aldc: 2093 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); 2094 break; 2095 case Bytecodes::_fast_aldc_w: 2096 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); 2097 break; 2093 2098 default: 2094 2099 ShouldNotReachHere(); … … 2099 2104 2100 2105 // Update registers with resolved info 2101 __ get_cache_and_index_at_bcp(Rcache, index, 1); 2106 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); 2107 if (result != noreg) 2108 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); 2102 2109 __ bind(resolved); 2103 2110 } … … 2135 2142 Register flags, 2136 2143 bool is_invokevirtual, 2137 bool is_invokevfinal /*unused*/) { 2144 bool is_invokevfinal, /*unused*/ 2145 bool is_invokedynamic) { 2138 2146 // setup registers 2139 2147 const Register cache = rcx; … … 2155 2163 ConstantPoolCacheEntry::f2_offset()); 2156 2164 2157 resolve_cache_and_index(byte_no, cache, index); 2158 2159 assert(wordSize == 8, "adjust code below"); 2160 __ movptr(method, Address(cache, index, Address::times_8, method_offset)); 2165 if (byte_no == f1_oop) { 2166 // Resolved f1_oop goes directly into 'method' register. 2167 assert(is_invokedynamic, ""); 2168 resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4)); 2169 } else { 2170 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); 2171 __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); 2172 } 2161 2173 if (itable_index != noreg) { 2162 __ movptr(itable_index, 2163 Address(cache, index, Address::times_8, index_offset)); 2164 } 2165 __ movl(flags , Address(cache, index, Address::times_8, flags_offset)); 2174 __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset)); 2175 } 2176 __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset)); 2166 2177 } 2167 2178 … … 2222 2233 const Register bc = c_rarg3; // uses same reg as obj, so don't mix them 2223 2234 2224 resolve_cache_and_index(byte_no, cache, index);2235 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); 2225 2236 jvmti_post_field_access(cache, index, is_static, false); 2226 2237 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); … … 2425 2436 const Register bc = c_rarg3; 2426 2437 2427 resolve_cache_and_index(byte_no, cache, index);2438 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); 2428 2439 jvmti_post_field_mod(cache, index, is_static); 2429 2440 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); … … 2781 2792 // get receiver 2782 2793 __ movptr(rax, aaddress(0)); 2783 debug_only(__ verify_local_tag(frame::TagReference, 0));2784 2794 // access constant pool cache 2785 2795 __ get_cache_and_index_at_bcp(rcx, rdx, 2); … … 2833 2843 } 2834 2844 2835 void TemplateTable::prepare_invoke(Register method, 2836 Register index, 2837 int byte_no, 2838 Bytecodes::Code code) { 2845 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) { 2839 2846 // determine flags 2847 Bytecodes::Code code = bytecode(); 2840 2848 const bool is_invokeinterface = code == Bytecodes::_invokeinterface; 2849 const bool is_invokedynamic = code == Bytecodes::_invokedynamic; 2841 2850 const bool is_invokevirtual = code == Bytecodes::_invokevirtual; 2842 2851 const bool is_invokespecial = code == Bytecodes::_invokespecial; 2843 const bool load_receiver = code != Bytecodes::_invokestatic;2852 const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic); 2844 2853 const bool receiver_null_check = is_invokespecial; 2845 2854 const bool save_flags = is_invokeinterface || is_invokevirtual; … … 2852 2861 __ save_bcp(); 2853 2862 2854 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual );2863 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic); 2855 2864 2856 2865 // load receiver if needed (note: no return address pushed yet) 2857 2866 if (load_receiver) { 2867 assert(!is_invokedynamic, ""); 2858 2868 __ movl(recv, flags); 2859 2869 __ andl(recv, 0xFF); 2860 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 2861 __ movptr(recv, Address(rsp, recv, Address::times_8, 2862 -Interpreter::expr_offset_in_bytes(1))); 2870 Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1)); 2871 __ movptr(recv, recv_addr); 2863 2872 __ verify_oop(recv); 2864 2873 } … … 2879 2888 // load return address 2880 2889 { 2881 ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table()); 2882 ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table()); 2883 __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3)); 2884 __ movptr(flags, Address(rscratch1, flags, Address::times_8)); 2890 address table_addr; 2891 if (is_invokeinterface || is_invokedynamic) 2892 table_addr = (address)Interpreter::return_5_addrs_by_index_table(); 2893 else 2894 table_addr = (address)Interpreter::return_3_addrs_by_index_table(); 2895 ExternalAddress table(table_addr); 2896 __ lea(rscratch1, table); 2897 __ movptr(flags, Address(rscratch1, flags, Address::times_ptr)); 2885 2898 } 2886 2899 … … 2948 2961 void TemplateTable::invokevirtual(int byte_no) { 2949 2962 transition(vtos, vtos); 2950 prepare_invoke(rbx, noreg, byte_no, bytecode()); 2963 assert(byte_no == f2_byte, "use this argument"); 2964 prepare_invoke(rbx, noreg, byte_no); 2951 2965 2952 2966 // rbx: index … … 2960 2974 void TemplateTable::invokespecial(int byte_no) { 2961 2975 transition(vtos, vtos); 2962 prepare_invoke(rbx, noreg, byte_no, bytecode()); 2976 assert(byte_no == f1_byte, "use this argument"); 2977 prepare_invoke(rbx, noreg, byte_no); 2963 2978 // do the call 2964 2979 __ verify_oop(rbx); … … 2970 2985 void TemplateTable::invokestatic(int byte_no) { 2971 2986 transition(vtos, vtos); 2972 prepare_invoke(rbx, noreg, byte_no, bytecode()); 2987 assert(byte_no == f1_byte, "use this argument"); 2988 prepare_invoke(rbx, noreg, byte_no); 2973 2989 // do the call 2974 2990 __ verify_oop(rbx); … … 2979 2995 void TemplateTable::fast_invokevfinal(int byte_no) { 2980 2996 transition(vtos, vtos); 2997 assert(byte_no == f2_byte, "use this argument"); 2981 2998 __ stop("fast_invokevfinal not used on amd64"); 2982 2999 } … … 2984 3001 void TemplateTable::invokeinterface(int byte_no) { 2985 3002 transition(vtos, vtos); 2986 prepare_invoke(rax, rbx, byte_no, bytecode()); 3003 assert(byte_no == f1_byte, "use this argument"); 3004 prepare_invoke(rax, rbx, byte_no); 2987 3005 2988 3006 // rax: Interface … … 3061 3079 void TemplateTable::invokedynamic(int byte_no) { 3062 3080 transition(vtos, vtos); 3081 assert(byte_no == f1_oop, "use this argument"); 3063 3082 3064 3083 if (!EnableInvokeDynamic) { … … 3073 3092 } 3074 3093 3075 __ stop("invokedynamic NYI");//6815692// 3094 assert(byte_no == f1_oop, "use this argument"); 3095 prepare_invoke(rax, rbx, byte_no); 3096 3097 // rax: CallSite object (f1) 3098 // rbx: unused (f2) 3099 // rcx: receiver address 3100 // rdx: flags (unused) 3101 3102 if (ProfileInterpreter) { 3103 Label L; 3104 // %%% should make a type profile for any invokedynamic that takes a ref argument 3105 // profile this call 3106 __ profile_call(r13); 3107 } 3108 3109 __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); 3110 __ null_check(rcx); 3111 __ prepare_to_jump_from_interpreted(); 3112 __ jump_to_method_handle_entry(rcx, rdx); 3076 3113 } 3077 3114 … … 3090 3127 3091 3128 __ get_cpool_and_tags(rsi, rax); 3092 // get instanceKlass 3093 __ movptr(rsi, Address(rsi, rdx, 3094 Address::times_8, sizeof(constantPoolOopDesc))); 3095 3096 // make sure the class we're about to instantiate has been 3097 // resolved. Note: slow_case does a pop of stack, which is why we 3098 // loaded class/pushed above 3129 // Make sure the class we're about to instantiate has been resolved. 3130 // This is done before loading instanceKlass to be consistent with the order 3131 // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put) 3099 3132 const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; 3100 3133 __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), 3101 3134 JVM_CONSTANT_Class); 3102 3135 __ jcc(Assembler::notEqual, slow_case); 3136 3137 // get instanceKlass 3138 __ movptr(rsi, Address(rsi, rdx, 3139 Address::times_8, sizeof(constantPoolOopDesc))); 3103 3140 3104 3141 // make sure klass is initialized & doesn't have finalizer … … 3213 3250 __ store_klass_gap(rax, rcx); // zero klass gap for compressed oops 3214 3251 __ store_klass(rax, rsi); // store klass last 3252 3253 { 3254 SkipIfEqual skip(_masm, &DTraceAllocProbes, false); 3255 // Trigger dtrace event for fastpath 3256 __ push(atos); // save the return value 3257 __ call_VM_leaf( 3258 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), rax); 3259 __ pop(atos); // restore the return value 3260 3261 } 3215 3262 __ jmp(done); 3216 3263 } 3217 3264 3218 {3219 SkipIfEqual skip(_masm, &DTraceAllocProbes, false);3220 // Trigger dtrace event for fastpath3221 __ push(atos); // save the return value3222 __ call_VM_leaf(3223 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), rax);3224 __ pop(atos); // restore the return value3225 }3226 3265 3227 3266 // slow case … … 3587 3626 // last dim is on top of stack; we want address of first one: 3588 3627 // first_addr = last_addr + (ndims - 1) * wordSize 3589 if (TaggedStackInterpreter) __ shll(rax, 1); // index*23590 3628 __ lea(c_rarg1, Address(rsp, rax, Address::times_8, -wordSize)); 3591 3629 call_VM(rax, … … 3593 3631 c_rarg1); 3594 3632 __ load_unsigned_byte(rbx, at_bcp(3)); 3595 if (TaggedStackInterpreter) __ shll(rbx, 1); // index*23596 3633 __ lea(rsp, Address(rsp, rbx, Address::times_8)); 3597 3634 } -
trunk/openjdk/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp
r2 r278 1 1 /* 2 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ 24 24 25 static void prepare_invoke(Register method, Register index, int byte_no, 26 Bytecodes::Code code); 25 static void prepare_invoke(Register method, Register index, int byte_no); 27 26 static void invokevirtual_helper(Register index, Register recv, 28 27 Register flags); -
trunk/openjdk/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All Rights Reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 35 35 36 36 static BufferBlob* stub_blob; 37 static const int stub_size = 300;37 static const int stub_size = 400; 38 38 39 39 extern "C" { … … 57 57 const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT); 58 58 59 Label detect_486, cpu486, detect_586, std_cpuid1 ;59 Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4; 60 60 Label ext_cpuid1, ext_cpuid5, done; 61 61 … … 132 132 __ movl(Address(rsi,12), rdx); 133 133 134 __ cmpl(rax, 3); // Is cpuid(0x4) supported? 135 __ jccb(Assembler::belowEqual, std_cpuid1); 134 __ cmpl(rax, 0xa); // Is cpuid(0xB) supported? 135 __ jccb(Assembler::belowEqual, std_cpuid4); 136 137 // 138 // cpuid(0xB) Processor Topology 139 // 140 __ movl(rax, 0xb); 141 __ xorl(rcx, rcx); // Threads level 142 __ cpuid(); 143 144 __ lea(rsi, Address(rbp, in_bytes(VM_Version::tpl_cpuidB0_offset()))); 145 __ movl(Address(rsi, 0), rax); 146 __ movl(Address(rsi, 4), rbx); 147 __ movl(Address(rsi, 8), rcx); 148 __ movl(Address(rsi,12), rdx); 149 150 __ movl(rax, 0xb); 151 __ movl(rcx, 1); // Cores level 152 __ cpuid(); 153 __ push(rax); 154 __ andl(rax, 0x1f); // Determine if valid topology level 155 __ orl(rax, rbx); // eax[4:0] | ebx[0:15] == 0 indicates invalid level 156 __ andl(rax, 0xffff); 157 __ pop(rax); 158 __ jccb(Assembler::equal, std_cpuid4); 159 160 __ lea(rsi, Address(rbp, in_bytes(VM_Version::tpl_cpuidB1_offset()))); 161 __ movl(Address(rsi, 0), rax); 162 __ movl(Address(rsi, 4), rbx); 163 __ movl(Address(rsi, 8), rcx); 164 __ movl(Address(rsi,12), rdx); 165 166 __ movl(rax, 0xb); 167 __ movl(rcx, 2); // Packages level 168 __ cpuid(); 169 __ push(rax); 170 __ andl(rax, 0x1f); // Determine if valid topology level 171 __ orl(rax, rbx); // eax[4:0] | ebx[0:15] == 0 indicates invalid level 172 __ andl(rax, 0xffff); 173 __ pop(rax); 174 __ jccb(Assembler::equal, std_cpuid4); 175 176 __ lea(rsi, Address(rbp, in_bytes(VM_Version::tpl_cpuidB2_offset()))); 177 __ movl(Address(rsi, 0), rax); 178 __ movl(Address(rsi, 4), rbx); 179 __ movl(Address(rsi, 8), rcx); 180 __ movl(Address(rsi,12), rdx); 136 181 137 182 // 138 183 // cpuid(0x4) Deterministic cache params 139 184 // 185 __ bind(std_cpuid4); 140 186 __ movl(rax, 4); 187 __ cmpl(rax, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); // Is cpuid(0x4) supported? 188 __ jccb(Assembler::greater, std_cpuid1); 189 141 190 __ xorl(rcx, rcx); // L1 cache 142 191 __ cpuid(); … … 256 305 vm_exit_during_initialization("Unknown x64 processor: SSE2 not supported"); 257 306 } 307 // in 64 bit the use of SSE2 is the minimum 308 if (UseSSE < 2) UseSSE = 2; 258 309 #endif 259 310 … … 432 483 } 433 484 485 #ifdef COMPILER2 486 if (UseFPUForSpilling) { 487 if (UseSSE < 2) { 488 // Only supported with SSE2+ 489 FLAG_SET_DEFAULT(UseFPUForSpilling, false); 490 } 491 } 492 #endif 493 434 494 assert(0 <= ReadPrefetchInstr && ReadPrefetchInstr <= 3, "invalid value"); 435 495 assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 3, "invalid value"); … … 459 519 AllocatePrefetchStyle = allocate_prefetch_style(); 460 520 461 if( AllocatePrefetchStyle == 2 && is_intel() &&462 cpu_family() == 6 && supports_sse3()) { // watermark prefetching on Core521 if( is_intel() && cpu_family() == 6 && supports_sse3() ) { 522 if( AllocatePrefetchStyle == 2 ) { // watermark prefetching on Core 463 523 #ifdef _LP64 464 AllocatePrefetchDistance = 384;524 AllocatePrefetchDistance = 384; 465 525 #else 466 AllocatePrefetchDistance = 320;526 AllocatePrefetchDistance = 320; 467 527 #endif 528 } 529 if( supports_sse4_2() && supports_ht() ) { // Nehalem based cpus 530 AllocatePrefetchDistance = 192; 531 AllocatePrefetchLines = 4; 532 #ifdef COMPILER2 533 if (AggressiveOpts && FLAG_IS_DEFAULT(UseFPUForSpilling)) { 534 FLAG_SET_DEFAULT(UseFPUForSpilling, true); 535 } 536 #endif 537 } 468 538 } 469 539 assert(AllocatePrefetchDistance % AllocatePrefetchStepSize == 0, "invalid value"); -
trunk/openjdk/hotspot/src/cpu/x86/vm/vm_version_x86.hpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All Rights Reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ … … 115 115 }; 116 116 117 union TplCpuidBEbx { 118 uint32_t value; 119 struct { 120 uint32_t logical_cpus : 16, 121 : 16; 122 } bits; 123 }; 124 117 125 union ExtCpuid1Ecx { 118 126 uint32_t value; … … 211 219 uint32_t dcp_cpuid4_ecx; // unused currently 212 220 uint32_t dcp_cpuid4_edx; // unused currently 221 222 // cpuid function 0xB (processor topology) 223 // ecx = 0 224 uint32_t tpl_cpuidB0_eax; 225 TplCpuidBEbx tpl_cpuidB0_ebx; 226 uint32_t tpl_cpuidB0_ecx; // unused currently 227 uint32_t tpl_cpuidB0_edx; // unused currently 228 229 // ecx = 1 230 uint32_t tpl_cpuidB1_eax; 231 TplCpuidBEbx tpl_cpuidB1_ebx; 232 uint32_t tpl_cpuidB1_ecx; // unused currently 233 uint32_t tpl_cpuidB1_edx; // unused currently 234 235 // ecx = 2 236 uint32_t tpl_cpuidB2_eax; 237 TplCpuidBEbx tpl_cpuidB2_ebx; 238 uint32_t tpl_cpuidB2_ecx; // unused currently 239 uint32_t tpl_cpuidB2_edx; // unused currently 213 240 214 241 // cpuid function 0x80000000 // example, unused … … 317 344 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } 318 345 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } 346 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } 347 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 348 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 319 349 320 350 // Initialization … … 347 377 static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' 348 378 379 static bool supports_processor_topology() { 380 return (_cpuid_info.std_max_function >= 0xB) && 381 // eax[4:0] | ebx[0:15] == 0 indicates invalid topology level. 382 // Some cpus have max cpuid >= 0xB but do not support processor topology. 383 ((_cpuid_info.tpl_cpuidB0_eax & 0x1f | _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus) != 0); 384 } 385 349 386 static uint cores_per_cpu() { 350 387 uint result = 1; 351 388 if (is_intel()) { 352 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); 389 if (supports_processor_topology()) { 390 result = _cpuid_info.tpl_cpuidB1_ebx.bits.logical_cpus / 391 _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; 392 } else { 393 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); 394 } 353 395 } else if (is_amd()) { 354 396 result = (_cpuid_info.ext_cpuid8_ecx.bits.cores_per_cpu + 1); … … 359 401 static uint threads_per_core() { 360 402 uint result = 1; 361 if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { 403 if (is_intel() && supports_processor_topology()) { 404 result = _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; 405 } else if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { 362 406 result = _cpuid_info.std_cpuid1_ebx.bits.threads_per_cpu / 363 407 cores_per_cpu(); -
trunk/openjdk/hotspot/src/cpu/x86/vm/vmreg_x86.cpp
r2 r278 1 1 /* 2 * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/vmreg_x86.hpp
r2 r278 1 1 /* 2 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/vmreg_x86.inline.hpp
r2 r278 1 1 /* 2 * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp
r2 r278 1 1 /* 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
r2 r278 1 1 /* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 * CA 95054 USA or visit www.sun.com if you need additional information or21 * have anyquestions.19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 22 * 23 23 */ -
trunk/openjdk/hotspot/src/cpu/x86/vm/x86_32.ad
r2 r278 1 1 // 2 // Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.2 // Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 // … … 17 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 // 19 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 // CA 95054 USA or visit www.sun.com if you need additional information or21 // have anyquestions.19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 22 // 23 23 // … … 236 236 // This is a block of C++ code which provides values, functions, and 237 237 // definitions necessary in the rest of the architecture description 238 source_hpp %{ 239 // Must be visible to the DFA in dfa_x86_32.cpp 240 extern bool is_operand_hi32_zero(Node* n); 241 %} 242 238 243 source %{ 239 244 #define RELOC_IMM32 Assembler::imm_operand … … 269 274 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000)); 270 275 276 // Offset hacking within calls. 277 static int pre_call_FPU_size() { 278 if (Compile::current()->in_24_bit_fp_mode()) 279 return 6; // fldcw 280 return 0; 281 } 282 283 static int preserve_SP_size() { 284 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg) 285 } 286 271 287 // !!!!! Special hack to get all type of calls to specify the byte offset 272 288 // from the start of the call to the point where the return address 273 289 // will point. 274 290 int MachCallStaticJavaNode::ret_addr_offset() { 275 return 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); // 5 bytes from start of call to where return address points 291 int offset = 5 + pre_call_FPU_size(); // 5 bytes from start of call to where return address points 292 if (_method_handle_invoke) 293 offset += preserve_SP_size(); 294 return offset; 276 295 } 277 296 278 297 int MachCallDynamicJavaNode::ret_addr_offset() { 279 return 10 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); // 10 bytes from start of call to where return address points298 return 10 + pre_call_FPU_size(); // 10 bytes from start of call to where return address points 280 299 } 281 300 … … 284 303 int MachCallRuntimeNode::ret_addr_offset() { 285 304 assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already"); 286 return sizeof_FFree_Float_Stack_All + 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0);305 return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size(); 287 306 } 288 307 … … 300 319 // ensure that it does not span a cache line so that it can be patched. 301 320 int CallStaticJavaDirectNode::compute_padding(int current_offset) const { 302 if (Compile::current()->in_24_bit_fp_mode()) 303 current_offset += 6; // skip fldcw in pre_call_FPU, if any 321 current_offset += pre_call_FPU_size(); // skip fldcw, if any 304 322 current_offset += 1; // skip call opcode byte 305 323 return round_to(current_offset, alignment_required()) - current_offset; … … 308 326 // The address of the call instruction needs to be 4-byte aligned to 309 327 // ensure that it does not span a cache line so that it can be patched. 328 int CallStaticJavaHandleNode::compute_padding(int current_offset) const { 329 current_offset += pre_call_FPU_size(); // skip fldcw, if any 330 current_offset += preserve_SP_size(); // skip mov rbp, rsp 331 current_offset += 1; // skip call opcode byte 332 return round_to(current_offset, alignment_required()) - current_offset; 333 } 334 335 // The address of the call instruction needs to be 4-byte aligned to 336 // ensure that it does not span a cache line so that it can be patched. 310 337 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const { 311 if (Compile::current()->in_24_bit_fp_mode()) 312 current_offset += 6; // skip fldcw in pre_call_FPU, if any 338 current_offset += pre_call_FPU_size(); // skip fldcw, if any 313 339 current_offset += 5; // skip MOV instruction 314 340 current_offset += 1; // skip call opcode byte … … 380 406 #ifdef ASSERT 381 407 if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) { 382 assert(oop(d32)->is_oop() && oop(d32)->is_perm(), "cannot embed non-permoops in code");408 assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code"); 383 409 } 384 410 #endif … … 827 853 } 828 854 855 static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 856 int src_hi, int dst_hi, int size, outputStream* st ) { 857 // 32-bit 858 if (cbuf) { 859 emit_opcode(*cbuf, 0x66); 860 emit_opcode(*cbuf, 0x0F); 861 emit_opcode(*cbuf, 0x6E); 862 emit_rm(*cbuf, 0x3, Matcher::_regEncode[dst_lo] & 7, Matcher::_regEncode[src_lo] & 7); 863 #ifndef PRODUCT 864 } else if (!do_size) { 865 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 866 #endif 867 } 868 return 4; 869 } 870 871 872 static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 873 int src_hi, int dst_hi, int size, outputStream* st ) { 874 // 32-bit 875 if (cbuf) { 876 emit_opcode(*cbuf, 0x66); 877 emit_opcode(*cbuf, 0x0F); 878 emit_opcode(*cbuf, 0x7E); 879 emit_rm(*cbuf, 0x3, Matcher::_regEncode[src_lo] & 7, Matcher::_regEncode[dst_lo] & 7); 880 #ifndef PRODUCT 881 } else if (!do_size) { 882 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 883 #endif 884 } 885 return 4; 886 } 887 829 888 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) { 830 889 if( cbuf ) { … … 922 981 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st); 923 982 983 // Check for integer reg-xmm reg copy 984 if( src_first_rc == rc_int && dst_first_rc == rc_xmm ) { 985 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad), 986 "no 64 bit integer-float reg moves" ); 987 return impl_movgpr2x_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 988 } 924 989 // -------------------------------------- 925 990 // Check for float reg-reg copy … … 993 1058 } 994 1059 1060 // Check for xmm reg-integer reg copy 1061 if( src_first_rc == rc_xmm && dst_first_rc == rc_int ) { 1062 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad), 1063 "no 64 bit float-integer reg moves" ); 1064 return impl_movx2gpr_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 1065 } 1066 995 1067 // Check for xmm store 996 1068 if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) { … … 1351 1423 // registers? True for Intel but false for most RISCs 1352 1424 const bool Matcher::clone_shift_expressions = true; 1425 1426 bool Matcher::narrow_oop_use_complex_address() { 1427 ShouldNotCallThis(); 1428 return true; 1429 } 1430 1353 1431 1354 1432 // Is it better to copy float constants, or load them directly from memory? … … 1419 1497 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1420 1498 1421 // Do floats take an entire double register or just half? 1422 const bool Matcher::float_in_double = true; 1499 // Are floats conerted to double when stored to stack during deoptimization? 1500 // On x32 it is stored with convertion only when FPU is used for floats. 1501 bool Matcher::float_in_double() { return (UseSSE == 0); } 1502 1423 1503 // Do ints take an entire long register or just half? 1424 1504 const bool Matcher::int_in_long = false; … … 1459 1539 ShouldNotReachHere(); 1460 1540 return RegMask(); 1541 } 1542 1543 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1544 return EBP_REG_mask; 1545 } 1546 1547 // Returns true if the high 32 bits of the value is known to be zero. 1548 bool is_operand_hi32_zero(Node* n) { 1549 int opc = n->Opcode(); 1550 if (opc == Op_LoadUI2L) { 1551 return true; 1552 } 1553 if (opc == Op_AndL) { 1554 Node* o2 = n->in(2); 1555 if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) { 1556 return true; 1557 } 1558 } 1559 return false; 1461 1560 } 1462 1561 … … 1773 1872 enc_class pre_call_FPU %{ 1774 1873 // If method sets FPU control word restore it here 1874 debug_only(int off0 = cbuf.code_size()); 1775 1875 if( Compile::current()->in_24_bit_fp_mode() ) { 1776 1876 MacroAssembler masm(&cbuf); 1777 1877 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 1778 1878 } 1879 debug_only(int off1 = cbuf.code_size()); 1880 assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction"); 1779 1881 %} 1780 1882 … … 1785 1887 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); 1786 1888 } 1889 %} 1890 1891 enc_class preserve_SP %{ 1892 debug_only(int off0 = cbuf.code_size()); 1893 MacroAssembler _masm(&cbuf); 1894 // RBP is preserved across all calls, even compiled calls. 1895 // Use it to preserve RSP in places where the callee might change the SP. 1896 __ movptr(rbp_mh_SP_save, rsp); 1897 debug_only(int off1 = cbuf.code_size()); 1898 assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); 1899 %} 1900 1901 enc_class restore_SP %{ 1902 MacroAssembler _masm(&cbuf); 1903 __ movptr(rsp, rbp_mh_SP_save); 1787 1904 %} 1788 1905 … … 3702 3819 %} 3703 3820 3704 enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,3705 eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{3706 Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL,3707 POP_LABEL, DONE_LABEL, CONT_LABEL,3708 WHILE_HEAD_LABEL;3709 MacroAssembler masm(&cbuf);3710 3711 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);3712 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);3713 3714 // Get the first character position in both strings3715 // [8] char array, [12] offset, [16] count3716 int value_offset = java_lang_String::value_offset_in_bytes();3717 int offset_offset = java_lang_String::offset_offset_in_bytes();3718 int count_offset = java_lang_String::count_offset_in_bytes();3719 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);3720 3721 masm.movptr(rax, Address(rsi, value_offset));3722 masm.movl(rcx, Address(rsi, offset_offset));3723 masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));3724 masm.movptr(rbx, Address(rdi, value_offset));3725 masm.movl(rcx, Address(rdi, offset_offset));3726 masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));3727 3728 // Compute the minimum of the string lengths(rsi) and the3729 // difference of the string lengths (stack)3730 3731 if (VM_Version::supports_cmov()) {3732 masm.movl(rdi, Address(rdi, count_offset));3733 masm.movl(rsi, Address(rsi, count_offset));3734 masm.movl(rcx, rdi);3735 masm.subl(rdi, rsi);3736 masm.push(rdi);3737 masm.cmovl(Assembler::lessEqual, rsi, rcx);3738 } else {3739 masm.movl(rdi, Address(rdi, count_offset));3740 masm.movl(rcx, Address(rsi, count_offset));3741 masm.movl(rsi, rdi);3742 masm.subl(rdi, rcx);3743 masm.push(rdi);3744 masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);3745 masm.movl(rsi, rcx);3746 // rsi holds min, rcx is unused3747 }3748 3749 // Is the minimum length zero?3750 masm.bind(ECX_GOOD_LABEL);3751 masm.testl(rsi, rsi);3752 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);3753 3754 // Load first characters3755 masm.load_unsigned_short(rcx, Address(rbx, 0));3756 masm.load_unsigned_short(rdi, Address(rax, 0));3757 3758 // Compare first characters3759 masm.subl(rcx, rdi);3760 masm.jcc(Assembler::notZero, POP_LABEL);3761 masm.decrementl(rsi);3762 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);3763 3764 {3765 // Check after comparing first character to see if strings are equivalent3766 Label LSkip2;3767 // Check if the strings start at same location3768 masm.cmpptr(rbx,rax);3769 masm.jccb(Assembler::notEqual, LSkip2);3770 3771 // Check if the length difference is zero (from stack)3772 masm.cmpl(Address(rsp, 0), 0x0);3773 masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL);3774 3775 // Strings might not be equivalent3776 masm.bind(LSkip2);3777 }3778 3779 // Advance to next character3780 masm.addptr(rax, 2);3781 masm.addptr(rbx, 2);3782 3783 if (UseSSE42Intrinsics) {3784 // With SSE4.2, use double quad vector compare3785 Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;3786 // Setup to compare 16-byte vectors3787 masm.movl(rdi, rsi);3788 masm.andl(rsi, 0xfffffff8); // rsi holds the vector count3789 masm.andl(rdi, 0x00000007); // rdi holds the tail count3790 masm.testl(rsi, rsi);3791 masm.jccb(Assembler::zero, COMPARE_TAIL);3792 3793 masm.lea(rax, Address(rax, rsi, Address::times_2));3794 masm.lea(rbx, Address(rbx, rsi, Address::times_2));3795 masm.negl(rsi);3796 3797 masm.bind(COMPARE_VECTORS);3798 masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));3799 masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));3800 masm.pxor(tmp1Reg, tmp2Reg);3801 masm.ptest(tmp1Reg, tmp1Reg);3802 masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);3803 masm.addl(rsi, 8);3804 masm.jcc(Assembler::notZero, COMPARE_VECTORS);3805 masm.jmpb(COMPARE_TAIL);3806 3807 // Mismatched characters in the vectors3808 masm.bind(VECTOR_NOT_EQUAL);3809 masm.lea(rax, Address(rax, rsi, Address::times_2));3810 masm.lea(rbx, Address(rbx, rsi, Address::times_2));3811 masm.movl(rdi, 8);3812 3813 // Compare tail (< 8 chars), or rescan last vectors to3814 // find 1st mismatched characters3815 masm.bind(COMPARE_TAIL);3816 masm.testl(rdi, rdi);3817 masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);3818 masm.movl(rsi, rdi);3819 // Fallthru to tail compare3820 }3821 3822 //Shift rax, and rbx, to the end of the arrays, negate min3823 masm.lea(rax, Address(rax, rsi, Address::times_2, 0));3824 masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));3825 masm.negl(rsi);3826 3827 // Compare the rest of the characters3828 masm.bind(WHILE_HEAD_LABEL);3829 masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));3830 masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));3831 masm.subl(rcx, rdi);3832 masm.jccb(Assembler::notZero, POP_LABEL);3833 masm.incrementl(rsi);3834 masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);3835 3836 // Strings are equal up to min length. Return the length difference.3837 masm.bind(LENGTH_DIFF_LABEL);3838 masm.pop(rcx);3839 masm.jmpb(DONE_LABEL);3840 3841 // Discard the stored length difference3842 masm.bind(POP_LABEL);3843 masm.addptr(rsp, 4);3844 3845 // That's it3846 masm.bind(DONE_LABEL);3847 %}3848 3849 enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,3850 eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{3851 Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;3852 MacroAssembler masm(&cbuf);3853 3854 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);3855 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);3856 3857 int value_offset = java_lang_String::value_offset_in_bytes();3858 int offset_offset = java_lang_String::offset_offset_in_bytes();3859 int count_offset = java_lang_String::count_offset_in_bytes();3860 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);3861 3862 // does source == target string?3863 masm.cmpptr(rdi, rsi);3864 masm.jcc(Assembler::equal, RET_TRUE);3865 3866 // get and compare counts3867 masm.movl(rcx, Address(rdi, count_offset));3868 masm.movl(rax, Address(rsi, count_offset));3869 masm.cmpl(rcx, rax);3870 masm.jcc(Assembler::notEqual, RET_FALSE);3871 masm.testl(rax, rax);3872 masm.jcc(Assembler::zero, RET_TRUE);3873 3874 // get source string offset and value3875 masm.movptr(rbx, Address(rsi, value_offset));3876 masm.movl(rax, Address(rsi, offset_offset));3877 masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));3878 3879 // get compare string offset and value3880 masm.movptr(rbx, Address(rdi, value_offset));3881 masm.movl(rax, Address(rdi, offset_offset));3882 masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));3883 3884 // Set byte count3885 masm.shll(rcx, 1);3886 masm.movl(rax, rcx);3887 3888 if (UseSSE42Intrinsics) {3889 // With SSE4.2, use double quad vector compare3890 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;3891 // Compare 16-byte vectors3892 masm.andl(rcx, 0xfffffff0); // vector count (in bytes)3893 masm.andl(rax, 0x0000000e); // tail count (in bytes)3894 masm.testl(rcx, rcx);3895 masm.jccb(Assembler::zero, COMPARE_TAIL);3896 masm.lea(rdi, Address(rdi, rcx, Address::times_1));3897 masm.lea(rsi, Address(rsi, rcx, Address::times_1));3898 masm.negl(rcx);3899 3900 masm.bind(COMPARE_WIDE_VECTORS);3901 masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));3902 masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));3903 masm.pxor(tmp1Reg, tmp2Reg);3904 masm.ptest(tmp1Reg, tmp1Reg);3905 masm.jccb(Assembler::notZero, RET_FALSE);3906 masm.addl(rcx, 16);3907 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);3908 masm.bind(COMPARE_TAIL);3909 masm.movl(rcx, rax);3910 // Fallthru to tail compare3911 }3912 3913 // Compare 4-byte vectors3914 masm.andl(rcx, 0xfffffffc); // vector count (in bytes)3915 masm.andl(rax, 0x00000002); // tail char (in bytes)3916 masm.testl(rcx, rcx);3917 masm.jccb(Assembler::zero, COMPARE_CHAR);3918 masm.lea(rdi, Address(rdi, rcx, Address::times_1));3919 masm.lea(rsi, Address(rsi, rcx, Address::times_1));3920 masm.negl(rcx);3921 3922 masm.bind(COMPARE_VECTORS);3923 masm.movl(rbx, Address(rdi, rcx, Address::times_1));3924 masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));3925 masm.jccb(Assembler::notEqual, RET_FALSE);3926 masm.addl(rcx, 4);3927 masm.jcc(Assembler::notZero, COMPARE_VECTORS);3928 3929 // Compare trailing char (final 2 bytes), if any3930 masm.bind(COMPARE_CHAR);3931 masm.testl(rax, rax);3932 masm.jccb(Assembler::zero, RET_TRUE);3933 masm.load_unsigned_short(rbx, Address(rdi, 0));3934 masm.load_unsigned_short(rcx, Address(rsi, 0));3935 masm.cmpl(rbx, rcx);3936 masm.jccb(Assembler::notEqual, RET_FALSE);3937 3938 masm.bind(RET_TRUE);3939 masm.movl(rax, 1); // return true3940 masm.jmpb(DONE);3941 3942 masm.bind(RET_FALSE);3943 masm.xorl(rax, rax); // return false3944 3945 masm.bind(DONE);3946 %}3947 3948 enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,3949 eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{3950 // SSE4.2 version3951 Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,3952 SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;3953 MacroAssembler masm(&cbuf);3954 3955 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);3956 3957 // Get the first character position in both strings3958 // [8] char array, [12] offset, [16] count3959 int value_offset = java_lang_String::value_offset_in_bytes();3960 int offset_offset = java_lang_String::offset_offset_in_bytes();3961 int count_offset = java_lang_String::count_offset_in_bytes();3962 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);3963 3964 // Get counts for string and substr3965 masm.movl(rdx, Address(rsi, count_offset));3966 masm.movl(rax, Address(rdi, count_offset));3967 // Check for substr count > string count3968 masm.cmpl(rax, rdx);3969 masm.jcc(Assembler::greater, RET_NEG_ONE);3970 3971 // Start the indexOf operation3972 // Get start addr of string3973 masm.movptr(rbx, Address(rsi, value_offset));3974 masm.movl(rcx, Address(rsi, offset_offset));3975 masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));3976 masm.push(rsi);3977 3978 // Get start addr of substr3979 masm.movptr(rbx, Address(rdi, value_offset));3980 masm.movl(rcx, Address(rdi, offset_offset));3981 masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));3982 masm.push(rdi);3983 masm.push(rax);3984 masm.jmpb(PREP_FOR_SCAN);3985 3986 // Substr count saved at sp3987 // Substr saved at sp+43988 // String saved at sp+83989 3990 // Prep to load substr for scan3991 masm.bind(LOAD_SUBSTR);3992 masm.movptr(rdi, Address(rsp, 4));3993 masm.movl(rax, Address(rsp, 0));3994 // We came here after the beginning of the substring was3995 // matched but the rest of it was not so we need to search3996 // again. Start from the next element after the previous match.3997 masm.subptr(rsi, rbx); // Restore counter3998 masm.shrl(rsi, 1);3999 masm.addl(rdx, rsi);4000 masm.lea(rsi, Address(rbx, 2));4001 4002 // Load substr4003 masm.bind(PREP_FOR_SCAN);4004 masm.movdqu(tmp1Reg, Address(rdi, 0));4005 masm.addl(rdx, 8); // prime the loop4006 masm.subptr(rsi, 16);4007 4008 // Scan string for substr in 16-byte vectors4009 masm.bind(SCAN_TO_SUBSTR);4010 masm.subl(rdx, 8);4011 masm.addptr(rsi, 16);4012 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);4013 masm.jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 04014 masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 04015 4016 // Fallthru: found a potential substr4017 4018 // Make sure string is still long enough4019 masm.subl(rdx, rcx);4020 masm.cmpl(rdx, rax);4021 masm.jccb(Assembler::negative, RET_NOT_FOUND);4022 // Compute start addr of substr4023 masm.lea(rsi, Address(rsi, rcx, Address::times_2));4024 masm.movptr(rbx, rsi);4025 4026 // Compare potential substr4027 masm.addl(rdx, 8); // prime the loop4028 masm.addl(rax, 8);4029 masm.subptr(rsi, 16);4030 masm.subptr(rdi, 16);4031 4032 // Scan 16-byte vectors of string and substr4033 masm.bind(SCAN_SUBSTR);4034 masm.subl(rax, 8);4035 masm.subl(rdx, 8);4036 masm.addptr(rsi, 16);4037 masm.addptr(rdi, 16);4038 masm.movdqu(tmp1Reg, Address(rdi, 0));4039 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);4040 masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 04041 masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 04042 4043 // Compute substr offset4044 masm.movptr(rsi, Address(rsp, 8));4045 masm.subptr(rbx, rsi);4046 masm.shrl(rbx, 1);4047 masm.jmpb(CLEANUP);4048 4049 masm.bind(RET_NEG_ONE);4050 masm.movl(rbx, -1);4051 masm.jmpb(DONE);4052 4053 masm.bind(RET_NOT_FOUND);4054 masm.movl(rbx, -1);4055 4056 masm.bind(CLEANUP);4057 masm.addptr(rsp, 12);4058 4059 masm.bind(DONE);4060 %}4061 4062 enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,4063 eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{4064 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;4065 MacroAssembler masm(&cbuf);4066 4067 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);4068 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);4069 Register ary1Reg = as_Register($ary1$$reg);4070 Register ary2Reg = as_Register($ary2$$reg);4071 Register tmp3Reg = as_Register($tmp3$$reg);4072 Register tmp4Reg = as_Register($tmp4$$reg);4073 Register resultReg = as_Register($result$$reg);4074 4075 int length_offset = arrayOopDesc::length_offset_in_bytes();4076 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);4077 4078 // Check the input args4079 masm.cmpptr(ary1Reg, ary2Reg);4080 masm.jcc(Assembler::equal, TRUE_LABEL);4081 masm.testptr(ary1Reg, ary1Reg);4082 masm.jcc(Assembler::zero, FALSE_LABEL);4083 masm.testptr(ary2Reg, ary2Reg);4084 masm.jcc(Assembler::zero, FALSE_LABEL);4085 4086 // Check the lengths4087 masm.movl(tmp4Reg, Address(ary1Reg, length_offset));4088 masm.movl(resultReg, Address(ary2Reg, length_offset));4089 masm.cmpl(tmp4Reg, resultReg);4090 masm.jcc(Assembler::notEqual, FALSE_LABEL);4091 masm.testl(resultReg, resultReg);4092 masm.jcc(Assembler::zero, TRUE_LABEL);4093 4094 // Load array addrs4095 masm.lea(ary1Reg, Address(ary1Reg, base_offset));4096 masm.lea(ary2Reg, Address(ary2Reg, base_offset));4097 4098 // Set byte count4099 masm.shll(tmp4Reg, 1);4100 masm.movl(resultReg, tmp4Reg);4101 4102 if (UseSSE42Intrinsics) {4103 // With SSE4.2, use double quad vector compare4104 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;4105 // Compare 16-byte vectors4106 masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes)4107 masm.andl(resultReg, 0x0000000e); // tail count (in bytes)4108 masm.testl(tmp4Reg, tmp4Reg);4109 masm.jccb(Assembler::zero, COMPARE_TAIL);4110 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4111 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4112 masm.negl(tmp4Reg);4113 4114 masm.bind(COMPARE_WIDE_VECTORS);4115 masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4116 masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4117 masm.pxor(tmp1Reg, tmp2Reg);4118 masm.ptest(tmp1Reg, tmp1Reg);4119 4120 masm.jccb(Assembler::notZero, FALSE_LABEL);4121 masm.addl(tmp4Reg, 16);4122 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);4123 masm.bind(COMPARE_TAIL);4124 masm.movl(tmp4Reg, resultReg);4125 // Fallthru to tail compare4126 }4127 4128 // Compare 4-byte vectors4129 masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes)4130 masm.andl(resultReg, 0x00000002); // tail char (in bytes)4131 masm.testl(tmp4Reg, tmp4Reg);4132 masm.jccb(Assembler::zero, COMPARE_CHAR);4133 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4134 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4135 masm.negl(tmp4Reg);4136 4137 masm.bind(COMPARE_VECTORS);4138 masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4139 masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4140 masm.jccb(Assembler::notEqual, FALSE_LABEL);4141 masm.addl(tmp4Reg, 4);4142 masm.jcc(Assembler::notZero, COMPARE_VECTORS);4143 4144 // Compare trailing char (final 2 bytes), if any4145 masm.bind(COMPARE_CHAR);4146 masm.testl(resultReg, resultReg);4147 masm.jccb(Assembler::zero, TRUE_LABEL);4148 masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));4149 masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));4150 masm.cmpl(tmp3Reg, tmp4Reg);4151 masm.jccb(Assembler::notEqual, FALSE_LABEL);4152 4153 masm.bind(TRUE_LABEL);4154 masm.movl(resultReg, 1); // return true4155 masm.jmpb(DONE);4156 4157 masm.bind(FALSE_LABEL);4158 masm.xorl(resultReg, resultReg); // return false4159 4160 // That's it4161 masm.bind(DONE);4162 %}4163 3821 4164 3822 enc_class enc_pop_rdx() %{ … … 6667 6325 %} 6668 6326 6327 instruct bytes_reverse_unsigned_short(eRegI dst) %{ 6328 match(Set dst (ReverseBytesUS dst)); 6329 6330 format %{ "BSWAP $dst\n\t" 6331 "SHR $dst,16\n\t" %} 6332 ins_encode %{ 6333 __ bswapl($dst$$Register); 6334 __ shrl($dst$$Register, 16); 6335 %} 6336 ins_pipe( ialu_reg ); 6337 %} 6338 6339 instruct bytes_reverse_short(eRegI dst) %{ 6340 match(Set dst (ReverseBytesS dst)); 6341 6342 format %{ "BSWAP $dst\n\t" 6343 "SAR $dst,16\n\t" %} 6344 ins_encode %{ 6345 __ bswapl($dst$$Register); 6346 __ sarl($dst$$Register, 16); 6347 %} 6348 ins_pipe( ialu_reg ); 6349 %} 6350 6669 6351 6670 6352 //---------- Zeros Count Instructions ------------------------------------------ … … 9016 8698 %} 9017 8699 8700 // Multiply Register Long where the left operand's high 32 bits are zero 8701 instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 8702 predicate(is_operand_hi32_zero(n->in(1))); 8703 match(Set dst (MulL dst src)); 8704 effect(KILL cr, TEMP tmp); 8705 ins_cost(2*100+2*400); 8706 // Basic idea: lo(result) = lo(x_lo * y_lo) 8707 // hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0 8708 format %{ "MOV $tmp,$src.hi\n\t" 8709 "IMUL $tmp,EAX\n\t" 8710 "MUL EDX:EAX,$src.lo\n\t" 8711 "ADD EDX,$tmp" %} 8712 ins_encode %{ 8713 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); 8714 __ imull($tmp$$Register, rax); 8715 __ mull($src$$Register); 8716 __ addl(rdx, $tmp$$Register); 8717 %} 8718 ins_pipe( pipe_slow ); 8719 %} 8720 8721 // Multiply Register Long where the right operand's high 32 bits are zero 8722 instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 8723 predicate(is_operand_hi32_zero(n->in(2))); 8724 match(Set dst (MulL dst src)); 8725 effect(KILL cr, TEMP tmp); 8726 ins_cost(2*100+2*400); 8727 // Basic idea: lo(result) = lo(x_lo * y_lo) 8728 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0 8729 format %{ "MOV $tmp,$src.lo\n\t" 8730 "IMUL $tmp,EDX\n\t" 8731 "MUL EDX:EAX,$src.lo\n\t" 8732 "ADD EDX,$tmp" %} 8733 ins_encode %{ 8734 __ movl($tmp$$Register, $src$$Register); 8735 __ imull($tmp$$Register, rdx); 8736 __ mull($src$$Register); 8737 __ addl(rdx, $tmp$$Register); 8738 %} 8739 ins_pipe( pipe_slow ); 8740 %} 8741 8742 // Multiply Register Long where the left and the right operands' high 32 bits are zero 8743 instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{ 8744 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2))); 8745 match(Set dst (MulL dst src)); 8746 effect(KILL cr); 8747 ins_cost(1*400); 8748 // Basic idea: lo(result) = lo(x_lo * y_lo) 8749 // hi(result) = hi(x_lo * y_lo) where lo(x_hi * y_lo) = 0 and lo(x_lo * y_hi) = 0 because x_hi = 0 and y_hi = 0 8750 format %{ "MUL EDX:EAX,$src.lo\n\t" %} 8751 ins_encode %{ 8752 __ mull($src$$Register); 8753 %} 8754 ins_pipe( pipe_slow ); 8755 %} 8756 9018 8757 // Multiply Register Long by small constant 9019 8758 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{ … … 12726 12465 %} 12727 12466 12728 instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 12729 eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{ 12730 match(Set result (StrComp str1 str2)); 12731 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 12732 //ins_cost(300); 12733 12734 format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %} 12735 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 12467 instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2, 12468 eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{ 12469 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12470 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12471 12472 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %} 12473 ins_encode %{ 12474 __ string_compare($str1$$Register, $str2$$Register, 12475 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12476 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 12477 %} 12736 12478 ins_pipe( pipe_slow ); 12737 12479 %} 12738 12480 12739 12481 // fast string equals 12740 instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2, 12741 eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ 12742 match(Set result (StrEquals str1 str2)); 12743 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 12744 12745 format %{ "String Equals $str1,$str2 -> $result // KILL EBX, ECX" %} 12746 ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 12747 ins_pipe( pipe_slow ); 12748 %} 12749 12750 instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2, 12751 eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{ 12482 instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result, 12483 regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{ 12484 match(Set result (StrEquals (Binary str1 str2) cnt)); 12485 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12486 12487 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12488 ins_encode %{ 12489 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 12490 $cnt$$Register, $result$$Register, $tmp3$$Register, 12491 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 12492 %} 12493 ins_pipe( pipe_slow ); 12494 %} 12495 12496 instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2, 12497 eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{ 12752 12498 predicate(UseSSE42Intrinsics); 12753 match(Set result (StrIndexOf str1 str2)); 12754 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); 12755 12756 format %{ "String IndexOf $str1,$str2 -> $result // KILL EAX, ECX, EDX" %} 12757 ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 12499 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12500 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr); 12501 12502 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp2, $tmp1" %} 12503 ins_encode %{ 12504 __ string_indexof($str1$$Register, $str2$$Register, 12505 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12506 $tmp1$$XMMRegister, $tmp2$$Register); 12507 %} 12758 12508 ins_pipe( pipe_slow ); 12759 12509 %} 12760 12510 12761 12511 // fast array equals 12762 instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3, 12763 eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{ 12512 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result, 12513 regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) 12514 %{ 12764 12515 match(Set result (AryEq ary1 ary2)); 12765 12516 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12766 12517 //ins_cost(300); 12767 12518 12768 format %{ "Array Equals $ary1,$ary2 -> $result // KILL EBX, EDX" %} 12769 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) ); 12519 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12520 ins_encode %{ 12521 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 12522 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12523 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 12524 %} 12770 12525 ins_pipe( pipe_slow ); 12771 12526 %} … … 13850 13605 instruct CallStaticJavaDirect(method meth) %{ 13851 13606 match(CallStaticJava); 13607 predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke()); 13852 13608 effect(USE meth); 13853 13609 … … 13857 13613 ins_encode( pre_call_FPU, 13858 13614 Java_Static_Call( meth ), 13615 call_epilog, 13616 post_call_FPU ); 13617 ins_pipe( pipe_slow ); 13618 ins_pc_relative(1); 13619 ins_alignment(4); 13620 %} 13621 13622 // Call Java Static Instruction (method handle version) 13623 // Note: If this code changes, the corresponding ret_addr_offset() and 13624 // compute_padding() functions will have to be adjusted. 13625 instruct CallStaticJavaHandle(method meth, eBPRegP ebp_mh_SP_save) %{ 13626 match(CallStaticJava); 13627 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 13628 effect(USE meth); 13629 // EBP is saved by all callees (for interpreter stack correction). 13630 // We use it here for a similar purpose, in {preserve,restore}_SP. 13631 13632 ins_cost(300); 13633 format %{ "CALL,static/MethodHandle " %} 13634 opcode(0xE8); /* E8 cd */ 13635 ins_encode( pre_call_FPU, 13636 preserve_SP, 13637 Java_Static_Call( meth ), 13638 restore_SP, 13859 13639 call_epilog, 13860 13640 post_call_FPU ); -
trunk/openjdk/hotspot/src/cpu/x86/vm/x86_64.ad
r2 r278 1 1 // 2 // Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.2 // Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 // … … 17 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 18 // 19 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,20 // CA 95054 USA or visit www.sun.com if you need additional information or21 // have anyquestions.19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 22 // 23 23 // … … 552 552 #define __ _masm. 553 553 554 static int preserve_SP_size() { 555 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg) 556 } 557 554 558 // !!!!! Special hack to get all types of calls to specify the byte offset 555 559 // from the start of the call to the point where the return address … … 557 561 int MachCallStaticJavaNode::ret_addr_offset() 558 562 { 559 return 5; // 5 bytes from start of call to where return address points 563 int offset = 5; // 5 bytes from start of call to where return address points 564 if (_method_handle_invoke) 565 offset += preserve_SP_size(); 566 return offset; 560 567 } 561 568 … … 584 591 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 585 592 { 593 current_offset += 1; // skip call opcode byte 594 return round_to(current_offset, alignment_required()) - current_offset; 595 } 596 597 // The address of the call instruction needs to be 4-byte aligned to 598 // ensure that it does not span a cache line so that it can be patched. 599 int CallStaticJavaHandleNode::compute_padding(int current_offset) const 600 { 601 current_offset += preserve_SP_size(); // skip mov rbp, rsp 586 602 current_offset += 1; // skip call opcode byte 587 603 return round_to(current_offset, alignment_required()) - current_offset; … … 684 700 if (rspec.reloc()->type() == relocInfo::oop_type && 685 701 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 686 assert(oop((intptr_t)d32)->is_oop() && oop((intptr_t)d32)->is_perm(), "cannot embed non-permoops in code");702 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 687 703 } 688 704 #endif … … 722 738 if (rspec.reloc()->type() == relocInfo::oop_type && 723 739 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 724 assert(oop(d64)->is_oop() && oop(d64)->is_perm(),725 "cannot embed non-permoops in code");740 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), 741 "cannot embed scavengable oops in code"); 726 742 } 727 743 #endif … … 1592 1608 emit_opcode(*cbuf, 0x7E); 1593 1609 emit_rm(*cbuf, 0x3, 1594 Matcher::_regEncode[ dst_first] & 7,1595 Matcher::_regEncode[ src_first] & 7);1610 Matcher::_regEncode[src_first] & 7, 1611 Matcher::_regEncode[dst_first] & 7); 1596 1612 #ifndef PRODUCT 1597 1613 } else if (!do_size) { … … 1622 1638 emit_opcode(*cbuf, 0x7E); 1623 1639 emit_rm(*cbuf, 0x3, 1624 Matcher::_regEncode[ dst_first] & 7,1625 Matcher::_regEncode[ src_first] & 7);1640 Matcher::_regEncode[src_first] & 7, 1641 Matcher::_regEncode[dst_first] & 7); 1626 1642 #ifndef PRODUCT 1627 1643 } else if (!do_size) { … … 1836 1852 { 1837 1853 if (UseCompressedOops) { 1838 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes());1854 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1839 1855 if (Universe::narrow_oop_shift() != 0) { 1840 st->print_cr(" leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]");1856 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); 1841 1857 } 1842 st->print_cr(" cmpq rax, rscratch1\t # Inline cache check");1858 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1843 1859 } else { 1844 st->print_cr(" cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t"1845 "# Inline cache check" , oopDesc::klass_offset_in_bytes());1860 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1861 "# Inline cache check"); 1846 1862 } 1847 1863 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1848 st->print_cr("\tnop"); 1849 if (!OptoBreakpoint) { 1850 st->print_cr("\tnop"); 1851 } 1864 st->print_cr("\tnop\t# nops to align entry point"); 1852 1865 } 1853 1866 #endif … … 1856 1869 { 1857 1870 MacroAssembler masm(&cbuf); 1858 #ifdef ASSERT1859 1871 uint code_size = cbuf.code_size(); 1860 #endif1861 1872 if (UseCompressedOops) { 1862 1873 masm.load_klass(rscratch1, j_rarg0); … … 1869 1880 1870 1881 /* WARNING these NOPs are critical so that verified entry point is properly 1871 aligned for patching by NativeJump::patch_verified_entry() */1872 int nops_cnt = 1;1873 if ( !OptoBreakpoint) {1882 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1883 int nops_cnt = 4 - ((cbuf.code_size() - code_size) & 0x3); 1884 if (OptoBreakpoint) { 1874 1885 // Leave space for int3 1875 nops_cnt += 1;1886 nops_cnt -= 1; 1876 1887 } 1877 if (UseCompressedOops) { 1878 // ??? divisible by 4 is aligned? 1879 nops_cnt += 1; 1880 } 1881 masm.nop(nops_cnt); 1882 1883 assert(cbuf.code_size() - code_size == size(ra_), 1884 "checking code size of inline cache node"); 1888 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1889 if (nops_cnt > 0) 1890 masm.nop(nops_cnt); 1885 1891 } 1886 1892 1887 1893 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1888 1894 { 1889 if (UseCompressedOops) { 1890 if (Universe::narrow_oop_shift() == 0) { 1891 return OptoBreakpoint ? 15 : 16; 1892 } else { 1893 return OptoBreakpoint ? 19 : 20; 1894 } 1895 } else { 1896 return OptoBreakpoint ? 11 : 12; 1897 } 1895 return MachNode::size(ra_); // too many variables; just compute it 1896 // the hard way 1898 1897 } 1899 1898 … … 2039 2038 const bool Matcher::clone_shift_expressions = true; 2040 2039 2040 bool Matcher::narrow_oop_use_complex_address() { 2041 assert(UseCompressedOops, "only for compressed oops code"); 2042 return (LogMinObjAlignmentInBytes <= 3); 2043 } 2044 2041 2045 // Is it better to copy float constants, or load them directly from 2042 2046 // memory? Intel can load a float constant from a direct address, … … 2059 2063 const bool Matcher::strict_fp_requires_explicit_rounding = true; 2060 2064 2061 // Do floats take an entire double register or just half? 2062 const bool Matcher::float_in_double = true; 2065 // Are floats conerted to double when stored to stack during deoptimization? 2066 // On x64 it is stored without convertion so we can use normal access. 2067 bool Matcher::float_in_double() { return false; } 2068 2063 2069 // Do ints take an entire long register or just half? 2064 2070 const bool Matcher::int_in_long = true; … … 2112 2118 RegMask Matcher::modL_proj_mask() { 2113 2119 return LONG_RDX_REG_mask; 2120 } 2121 2122 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2123 return PTR_RBP_REG_mask; 2114 2124 } 2115 2125 … … 2609 2619 %} 2610 2620 2621 enc_class preserve_SP %{ 2622 debug_only(int off0 = cbuf.code_size()); 2623 MacroAssembler _masm(&cbuf); 2624 // RBP is preserved across all calls, even compiled calls. 2625 // Use it to preserve RSP in places where the callee might change the SP. 2626 __ movptr(rbp_mh_SP_save, rsp); 2627 debug_only(int off1 = cbuf.code_size()); 2628 assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); 2629 %} 2630 2631 enc_class restore_SP %{ 2632 MacroAssembler _masm(&cbuf); 2633 __ movptr(rsp, rbp_mh_SP_save); 2634 %} 2635 2611 2636 enc_class Java_Static_Call(method meth) 2612 2637 %{ … … 3702 3727 %} 3703 3728 3704 enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,3705 rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{3706 Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL,3707 POP_LABEL, DONE_LABEL, CONT_LABEL,3708 WHILE_HEAD_LABEL;3709 MacroAssembler masm(&cbuf);3710 3711 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);3712 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);3713 3714 // Get the first character position in both strings3715 // [8] char array, [12] offset, [16] count3716 int value_offset = java_lang_String::value_offset_in_bytes();3717 int offset_offset = java_lang_String::offset_offset_in_bytes();3718 int count_offset = java_lang_String::count_offset_in_bytes();3719 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);3720 3721 masm.load_heap_oop(rax, Address(rsi, value_offset));3722 masm.movl(rcx, Address(rsi, offset_offset));3723 masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));3724 masm.load_heap_oop(rbx, Address(rdi, value_offset));3725 masm.movl(rcx, Address(rdi, offset_offset));3726 masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));3727 3728 // Compute the minimum of the string lengths(rsi) and the3729 // difference of the string lengths (stack)3730 3731 // do the conditional move stuff3732 masm.movl(rdi, Address(rdi, count_offset));3733 masm.movl(rsi, Address(rsi, count_offset));3734 masm.movl(rcx, rdi);3735 masm.subl(rdi, rsi);3736 masm.push(rdi);3737 masm.cmov(Assembler::lessEqual, rsi, rcx);3738 3739 // Is the minimum length zero?3740 masm.bind(RCX_GOOD_LABEL);3741 masm.testl(rsi, rsi);3742 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);3743 3744 // Load first characters3745 masm.load_unsigned_short(rcx, Address(rbx, 0));3746 masm.load_unsigned_short(rdi, Address(rax, 0));3747 3748 // Compare first characters3749 masm.subl(rcx, rdi);3750 masm.jcc(Assembler::notZero, POP_LABEL);3751 masm.decrementl(rsi);3752 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);3753 3754 {3755 // Check after comparing first character to see if strings are equivalent3756 Label LSkip2;3757 // Check if the strings start at same location3758 masm.cmpptr(rbx, rax);3759 masm.jccb(Assembler::notEqual, LSkip2);3760 3761 // Check if the length difference is zero (from stack)3762 masm.cmpl(Address(rsp, 0), 0x0);3763 masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL);3764 3765 // Strings might not be equivalent3766 masm.bind(LSkip2);3767 }3768 3769 // Advance to next character3770 masm.addptr(rax, 2);3771 masm.addptr(rbx, 2);3772 3773 if (UseSSE42Intrinsics) {3774 // With SSE4.2, use double quad vector compare3775 Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;3776 // Setup to compare 16-byte vectors3777 masm.movl(rdi, rsi);3778 masm.andl(rsi, 0xfffffff8); // rsi holds the vector count3779 masm.andl(rdi, 0x00000007); // rdi holds the tail count3780 masm.testl(rsi, rsi);3781 masm.jccb(Assembler::zero, COMPARE_TAIL);3782 3783 masm.lea(rax, Address(rax, rsi, Address::times_2));3784 masm.lea(rbx, Address(rbx, rsi, Address::times_2));3785 masm.negptr(rsi);3786 3787 masm.bind(COMPARE_VECTORS);3788 masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));3789 masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));3790 masm.pxor(tmp1Reg, tmp2Reg);3791 masm.ptest(tmp1Reg, tmp1Reg);3792 masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);3793 masm.addptr(rsi, 8);3794 masm.jcc(Assembler::notZero, COMPARE_VECTORS);3795 masm.jmpb(COMPARE_TAIL);3796 3797 // Mismatched characters in the vectors3798 masm.bind(VECTOR_NOT_EQUAL);3799 masm.lea(rax, Address(rax, rsi, Address::times_2));3800 masm.lea(rbx, Address(rbx, rsi, Address::times_2));3801 masm.movl(rdi, 8);3802 3803 // Compare tail (< 8 chars), or rescan last vectors to3804 // find 1st mismatched characters3805 masm.bind(COMPARE_TAIL);3806 masm.testl(rdi, rdi);3807 masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);3808 masm.movl(rsi, rdi);3809 // Fallthru to tail compare3810 }3811 3812 // Shift RAX and RBX to the end of the arrays, negate min3813 masm.lea(rax, Address(rax, rsi, Address::times_2, 0));3814 masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));3815 masm.negptr(rsi);3816 3817 // Compare the rest of the characters3818 masm.bind(WHILE_HEAD_LABEL);3819 masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));3820 masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));3821 masm.subl(rcx, rdi);3822 masm.jccb(Assembler::notZero, POP_LABEL);3823 masm.increment(rsi);3824 masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);3825 3826 // Strings are equal up to min length. Return the length difference.3827 masm.bind(LENGTH_DIFF_LABEL);3828 masm.pop(rcx);3829 masm.jmpb(DONE_LABEL);3830 3831 // Discard the stored length difference3832 masm.bind(POP_LABEL);3833 masm.addptr(rsp, 8);3834 3835 // That's it3836 masm.bind(DONE_LABEL);3837 %}3838 3839 enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,3840 rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{3841 // SSE4.2 version3842 Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,3843 SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;3844 MacroAssembler masm(&cbuf);3845 3846 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);3847 3848 // Get the first character position in both strings3849 // [8] char array, [12] offset, [16] count3850 int value_offset = java_lang_String::value_offset_in_bytes();3851 int offset_offset = java_lang_String::offset_offset_in_bytes();3852 int count_offset = java_lang_String::count_offset_in_bytes();3853 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);3854 3855 // Get counts for string and substr3856 masm.movl(rdx, Address(rsi, count_offset));3857 masm.movl(rax, Address(rdi, count_offset));3858 // Check for substr count > string count3859 masm.cmpl(rax, rdx);3860 masm.jcc(Assembler::greater, RET_NEG_ONE);3861 3862 // Start the indexOf operation3863 // Get start addr of string3864 masm.load_heap_oop(rbx, Address(rsi, value_offset));3865 masm.movl(rcx, Address(rsi, offset_offset));3866 masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));3867 masm.push(rsi);3868 3869 // Get start addr of substr3870 masm.load_heap_oop(rbx, Address(rdi, value_offset));3871 masm.movl(rcx, Address(rdi, offset_offset));3872 masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));3873 masm.push(rdi);3874 masm.push(rax);3875 masm.jmpb(PREP_FOR_SCAN);3876 3877 // Substr count saved at sp3878 // Substr saved at sp+83879 // String saved at sp+163880 3881 // Prep to load substr for scan3882 masm.bind(LOAD_SUBSTR);3883 masm.movptr(rdi, Address(rsp, 8));3884 masm.movl(rax, Address(rsp, 0));3885 // We came here after the beginning of the substring was3886 // matched but the rest of it was not so we need to search3887 // again. Start from the next element after the previous match.3888 masm.subptr(rsi, rbx); // Restore counter3889 masm.shrq(rsi, 1);3890 masm.addq(rdx, rsi);3891 masm.lea(rsi, Address(rbx, 2));3892 3893 // Load substr3894 masm.bind(PREP_FOR_SCAN);3895 masm.movdqu(tmp1Reg, Address(rdi, 0));3896 masm.addq(rdx, 8); // prime the loop3897 masm.subptr(rsi, 16);3898 3899 // Scan string for substr in 16-byte vectors3900 masm.bind(SCAN_TO_SUBSTR);3901 masm.subq(rdx, 8);3902 masm.addptr(rsi, 16);3903 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);3904 masm.jcc(Assembler::above, SCAN_TO_SUBSTR);3905 masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND);3906 3907 // Fallthru: found a potential substr3908 3909 //Make sure string is still long enough3910 masm.subl(rdx, rcx);3911 masm.cmpl(rdx, rax);3912 masm.jccb(Assembler::negative, RET_NOT_FOUND);3913 // Compute start addr of substr3914 masm.lea(rsi, Address(rsi, rcx, Address::times_2));3915 masm.movptr(rbx, rsi);3916 3917 // Compare potential substr3918 masm.addq(rdx, 8); // prime the loop3919 masm.addq(rax, 8);3920 masm.subptr(rsi, 16);3921 masm.subptr(rdi, 16);3922 3923 // Scan 16-byte vectors of string and substr3924 masm.bind(SCAN_SUBSTR);3925 masm.subq(rax, 8);3926 masm.subq(rdx, 8);3927 masm.addptr(rsi, 16);3928 masm.addptr(rdi, 16);3929 masm.movdqu(tmp1Reg, Address(rdi, 0));3930 masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);3931 masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 03932 masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 03933 3934 // Compute substr offset3935 masm.movptr(rsi, Address(rsp, 16));3936 masm.subptr(rbx, rsi);3937 masm.shrl(rbx, 1);3938 masm.jmpb(CLEANUP);3939 3940 masm.bind(RET_NEG_ONE);3941 masm.movl(rbx, -1);3942 masm.jmpb(DONE);3943 3944 masm.bind(RET_NOT_FOUND);3945 masm.movl(rbx, -1);3946 3947 masm.bind(CLEANUP);3948 masm.addptr(rsp, 24);3949 3950 masm.bind(DONE);3951 %}3952 3953 enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,3954 rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{3955 Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;3956 MacroAssembler masm(&cbuf);3957 3958 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);3959 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);3960 3961 int value_offset = java_lang_String::value_offset_in_bytes();3962 int offset_offset = java_lang_String::offset_offset_in_bytes();3963 int count_offset = java_lang_String::count_offset_in_bytes();3964 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);3965 3966 // does source == target string?3967 masm.cmpptr(rdi, rsi);3968 masm.jcc(Assembler::equal, RET_TRUE);3969 3970 // get and compare counts3971 masm.movl(rcx, Address(rdi, count_offset));3972 masm.movl(rax, Address(rsi, count_offset));3973 masm.cmpl(rcx, rax);3974 masm.jcc(Assembler::notEqual, RET_FALSE);3975 masm.testl(rax, rax);3976 masm.jcc(Assembler::zero, RET_TRUE);3977 3978 // get source string offset and value3979 masm.load_heap_oop(rbx, Address(rsi, value_offset));3980 masm.movl(rax, Address(rsi, offset_offset));3981 masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset));3982 3983 // get compare string offset and value3984 masm.load_heap_oop(rbx, Address(rdi, value_offset));3985 masm.movl(rax, Address(rdi, offset_offset));3986 masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset));3987 3988 // Set byte count3989 masm.shll(rcx, 1);3990 masm.movl(rax, rcx);3991 3992 if (UseSSE42Intrinsics) {3993 // With SSE4.2, use double quad vector compare3994 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;3995 // Compare 16-byte vectors3996 masm.andl(rcx, 0xfffffff0); // vector count (in bytes)3997 masm.andl(rax, 0x0000000e); // tail count (in bytes)3998 masm.testl(rcx, rcx);3999 masm.jccb(Assembler::zero, COMPARE_TAIL);4000 masm.lea(rdi, Address(rdi, rcx, Address::times_1));4001 masm.lea(rsi, Address(rsi, rcx, Address::times_1));4002 masm.negptr(rcx);4003 4004 masm.bind(COMPARE_WIDE_VECTORS);4005 masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));4006 masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));4007 masm.pxor(tmp1Reg, tmp2Reg);4008 masm.ptest(tmp1Reg, tmp1Reg);4009 masm.jccb(Assembler::notZero, RET_FALSE);4010 masm.addptr(rcx, 16);4011 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);4012 masm.bind(COMPARE_TAIL);4013 masm.movl(rcx, rax);4014 // Fallthru to tail compare4015 }4016 4017 // Compare 4-byte vectors4018 masm.andl(rcx, 0xfffffffc); // vector count (in bytes)4019 masm.andl(rax, 0x00000002); // tail char (in bytes)4020 masm.testl(rcx, rcx);4021 masm.jccb(Assembler::zero, COMPARE_CHAR);4022 masm.lea(rdi, Address(rdi, rcx, Address::times_1));4023 masm.lea(rsi, Address(rsi, rcx, Address::times_1));4024 masm.negptr(rcx);4025 4026 masm.bind(COMPARE_VECTORS);4027 masm.movl(rbx, Address(rdi, rcx, Address::times_1));4028 masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));4029 masm.jccb(Assembler::notEqual, RET_FALSE);4030 masm.addptr(rcx, 4);4031 masm.jcc(Assembler::notZero, COMPARE_VECTORS);4032 4033 // Compare trailing char (final 2 bytes), if any4034 masm.bind(COMPARE_CHAR);4035 masm.testl(rax, rax);4036 masm.jccb(Assembler::zero, RET_TRUE);4037 masm.load_unsigned_short(rbx, Address(rdi, 0));4038 masm.load_unsigned_short(rcx, Address(rsi, 0));4039 masm.cmpl(rbx, rcx);4040 masm.jccb(Assembler::notEqual, RET_FALSE);4041 4042 masm.bind(RET_TRUE);4043 masm.movl(rax, 1); // return true4044 masm.jmpb(DONE);4045 4046 masm.bind(RET_FALSE);4047 masm.xorl(rax, rax); // return false4048 4049 masm.bind(DONE);4050 %}4051 4052 enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2,4053 rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{4054 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;4055 MacroAssembler masm(&cbuf);4056 4057 XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);4058 XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);4059 Register ary1Reg = as_Register($ary1$$reg);4060 Register ary2Reg = as_Register($ary2$$reg);4061 Register tmp3Reg = as_Register($tmp3$$reg);4062 Register tmp4Reg = as_Register($tmp4$$reg);4063 Register resultReg = as_Register($result$$reg);4064 4065 int length_offset = arrayOopDesc::length_offset_in_bytes();4066 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);4067 4068 // Check the input args4069 masm.cmpq(ary1Reg, ary2Reg);4070 masm.jcc(Assembler::equal, TRUE_LABEL);4071 masm.testq(ary1Reg, ary1Reg);4072 masm.jcc(Assembler::zero, FALSE_LABEL);4073 masm.testq(ary2Reg, ary2Reg);4074 masm.jcc(Assembler::zero, FALSE_LABEL);4075 4076 // Check the lengths4077 masm.movl(tmp4Reg, Address(ary1Reg, length_offset));4078 masm.movl(resultReg, Address(ary2Reg, length_offset));4079 masm.cmpl(tmp4Reg, resultReg);4080 masm.jcc(Assembler::notEqual, FALSE_LABEL);4081 masm.testl(resultReg, resultReg);4082 masm.jcc(Assembler::zero, TRUE_LABEL);4083 4084 //load array address4085 masm.lea(ary1Reg, Address(ary1Reg, base_offset));4086 masm.lea(ary2Reg, Address(ary2Reg, base_offset));4087 4088 //set byte count4089 masm.shll(tmp4Reg, 1);4090 masm.movl(resultReg,tmp4Reg);4091 4092 if (UseSSE42Intrinsics){4093 // With SSE4.2, use double quad vector compare4094 Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;4095 // Compare 16-byte vectors4096 masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes)4097 masm.andl(resultReg, 0x0000000e); // tail count (in bytes)4098 masm.testl(tmp4Reg, tmp4Reg);4099 masm.jccb(Assembler::zero, COMPARE_TAIL);4100 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4101 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4102 masm.negptr(tmp4Reg);4103 4104 masm.bind(COMPARE_WIDE_VECTORS);4105 masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4106 masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4107 masm.pxor(tmp1Reg, tmp2Reg);4108 masm.ptest(tmp1Reg, tmp1Reg);4109 4110 masm.jccb(Assembler::notZero, FALSE_LABEL);4111 masm.addptr(tmp4Reg, 16);4112 masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);4113 masm.bind(COMPARE_TAIL);4114 masm.movl(tmp4Reg, resultReg);4115 // Fallthru to tail compare4116 }4117 4118 // Compare 4-byte vectors4119 masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes)4120 masm.andl(resultReg, 0x00000002); // tail char (in bytes)4121 masm.testl(tmp4Reg, tmp4Reg); //if tmp2 == 0, only compare char4122 masm.jccb(Assembler::zero, COMPARE_CHAR);4123 masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4124 masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4125 masm.negptr(tmp4Reg);4126 4127 masm.bind(COMPARE_VECTORS);4128 masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));4129 masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));4130 masm.jccb(Assembler::notEqual, FALSE_LABEL);4131 masm.addptr(tmp4Reg, 4);4132 masm.jcc(Assembler::notZero, COMPARE_VECTORS);4133 4134 // Compare trailing char (final 2 bytes), if any4135 masm.bind(COMPARE_CHAR);4136 masm.testl(resultReg, resultReg);4137 masm.jccb(Assembler::zero, TRUE_LABEL);4138 masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));4139 masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));4140 masm.cmpl(tmp3Reg, tmp4Reg);4141 masm.jccb(Assembler::notEqual, FALSE_LABEL);4142 4143 masm.bind(TRUE_LABEL);4144 masm.movl(resultReg, 1); // return true4145 masm.jmpb(DONE);4146 4147 masm.bind(FALSE_LABEL);4148 masm.xorl(resultReg, resultReg); // return false4149 4150 // That's it4151 masm.bind(DONE);4152 %}4153 3729 4154 3730 enc_class enc_rethrow() … … 5540 5116 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 5541 5117 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 5542 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));5118 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 5543 5119 constraint(ALLOC_IN_RC(ptr_reg)); 5544 5120 match(AddP (DecodeN reg) off); … … 7784 7360 %} 7785 7361 7362 instruct bytes_reverse_unsigned_short(rRegI dst) %{ 7363 match(Set dst (ReverseBytesUS dst)); 7364 7365 format %{ "bswapl $dst\n\t" 7366 "shrl $dst,16\n\t" %} 7367 ins_encode %{ 7368 __ bswapl($dst$$Register); 7369 __ shrl($dst$$Register, 16); 7370 %} 7371 ins_pipe( ialu_reg ); 7372 %} 7373 7374 instruct bytes_reverse_short(rRegI dst) %{ 7375 match(Set dst (ReverseBytesS dst)); 7376 7377 format %{ "bswapl $dst\n\t" 7378 "sar $dst,16\n\t" %} 7379 ins_encode %{ 7380 __ bswapl($dst$$Register); 7381 __ sarl($dst$$Register, 16); 7382 %} 7383 ins_pipe( ialu_reg ); 7384 %} 7385 7786 7386 instruct loadI_reversed(rRegI dst, memory src) %{ 7787 7387 match(Set dst (ReverseBytesI (LoadI src))); … … 8131 7731 %} 8132 7732 8133 instruct decodeHeapOop_not_null(rRegP dst, rRegN src ) %{7733 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 8134 7734 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 8135 7735 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); 8136 7736 match(Set dst (DecodeN src)); 7737 effect(KILL cr); 8137 7738 format %{ "decode_heap_oop_not_null $dst,$src" %} 8138 7739 ins_encode %{ … … 12104 11705 %} 12105 11706 12106 instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, 12107 rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr) 12108 %{ 12109 match(Set result (StrComp str1 str2)); 12110 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 12111 //ins_cost(300); 12112 12113 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} 12114 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 11707 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2, 11708 rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr) 11709 %{ 11710 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11711 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11712 11713 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %} 11714 ins_encode %{ 11715 __ string_compare($str1$$Register, $str2$$Register, 11716 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11717 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11718 %} 12115 11719 ins_pipe( pipe_slow ); 12116 11720 %} 12117 11721 12118 instruct string_indexof(r si_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,12119 r cx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr)11722 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11723 rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr) 12120 11724 %{ 12121 11725 predicate(UseSSE42Intrinsics); 12122 match(Set result (StrIndexOf str1 str2)); 12123 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr); 12124 12125 format %{ "String IndexOf $str1,$str2 -> $result // KILL RAX, RCX, RDX" %} 12126 ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 11726 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11727 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr); 11728 11729 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %} 11730 ins_encode %{ 11731 __ string_indexof($str1$$Register, $str2$$Register, 11732 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11733 $tmp1$$XMMRegister, $tmp2$$Register); 11734 %} 12127 11735 ins_pipe( pipe_slow ); 12128 11736 %} 12129 11737 12130 11738 // fast string equals 12131 instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3, 12132 rcx_RegI tmp4, rax_RegI result, rFlagsReg cr) 12133 %{ 12134 match(Set result (StrEquals str1 str2)); 12135 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr); 12136 12137 format %{ "String Equals $str1,$str2 -> $result // KILL RBX, RCX" %} 12138 ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) ); 11739 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11740 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11741 %{ 11742 match(Set result (StrEquals (Binary str1 str2) cnt)); 11743 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11744 11745 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11746 ins_encode %{ 11747 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 11748 $cnt$$Register, $result$$Register, $tmp3$$Register, 11749 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11750 %} 12139 11751 ins_pipe( pipe_slow ); 12140 11752 %} 12141 11753 12142 11754 // fast array equals 12143 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, r egD tmp1, regD tmp2, rax_RegI tmp3,12144 r bx_RegI tmp4, rcx_RegI result, rFlagsReg cr)11755 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11756 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12145 11757 %{ 12146 11758 match(Set result (AryEq ary1 ary2)); … … 12148 11760 //ins_cost(300); 12149 11761 12150 format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %} 12151 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) ); 11762 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11763 ins_encode %{ 11764 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 11765 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11766 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11767 %} 12152 11768 ins_pipe( pipe_slow ); 12153 11769 %} … … 12961 12577 // Note: If this code changes, the corresponding ret_addr_offset() and 12962 12578 // compute_padding() functions will have to be adjusted. 12963 instruct CallStaticJavaDirect(method meth) 12964 %{ 12579 instruct CallStaticJavaDirect(method meth) %{ 12965 12580 match(CallStaticJava); 12581 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 12966 12582 effect(USE meth); 12967 12583 … … 12970 12586 opcode(0xE8); /* E8 cd */ 12971 12587 ins_encode(Java_Static_Call(meth), call_epilog); 12588 ins_pipe(pipe_slow); 12589 ins_pc_relative(1); 12590 ins_alignment(4); 12591 %} 12592 12593 // Call Java Static Instruction (method handle version) 12594 // Note: If this code changes, the corresponding ret_addr_offset() and 12595 // compute_padding() functions will have to be adjusted. 12596 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 12597 match(CallStaticJava); 12598 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 12599 effect(USE meth); 12600 // RBP is saved by all callees (for interpreter stack correction). 12601 // We use it here for a similar purpose, in {preserve,restore}_SP. 12602 12603 ins_cost(300); 12604 format %{ "call,static/MethodHandle " %} 12605 opcode(0xE8); /* E8 cd */ 12606 ins_encode(preserve_SP, 12607 Java_Static_Call(meth), 12608 restore_SP, 12609 call_epilog); 12972 12610 ins_pipe(pipe_slow); 12973 12611 ins_pc_relative(1);
Note:
See TracChangeset
for help on using the changeset viewer.