comparison src/cpu/x86/vm/x86_64.ad @ 644:c517646eef23

6813212: factor duplicated assembly code for general subclass check (for 6655638) Summary: Code in interp_masm, stubGenerator, c1_LIRAssembler, and AD files moved into MacroAssembler. Reviewed-by: kvn
author jrose
date Fri, 13 Mar 2009 18:39:22 -0700
parents c771b7f43bbf
children bd441136a5ce
comparison
equal deleted inserted replaced
643:c771b7f43bbf 644:c517646eef23
2573 %{ 2573 %{
2574 Register Rrdi = as_Register(RDI_enc); // result register 2574 Register Rrdi = as_Register(RDI_enc); // result register
2575 Register Rrax = as_Register(RAX_enc); // super class 2575 Register Rrax = as_Register(RAX_enc); // super class
2576 Register Rrcx = as_Register(RCX_enc); // killed 2576 Register Rrcx = as_Register(RCX_enc); // killed
2577 Register Rrsi = as_Register(RSI_enc); // sub class 2577 Register Rrsi = as_Register(RSI_enc); // sub class
2578 Label hit, miss, cmiss; 2578 Label miss;
2579 const bool set_cond_codes = true;
2579 2580
2580 MacroAssembler _masm(&cbuf); 2581 MacroAssembler _masm(&cbuf);
2581 // Compare super with sub directly, since super is not in its own SSA. 2582 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2582 // The compiler used to emit this test, but we fold it in here, 2583 NULL, &miss,
2583 // to allow platform-specific tweaking on sparc. 2584 /*set_cond_codes:*/ true);
2584 __ cmpptr(Rrax, Rrsi);
2585 __ jcc(Assembler::equal, hit);
2586 #ifndef PRODUCT
2587 __ lea(Rrcx, ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr));
2588 __ incrementl(Address(Rrcx, 0));
2589 #endif //PRODUCT
2590 __ movptr(Rrdi, Address(Rrsi,
2591 sizeof(oopDesc) +
2592 Klass::secondary_supers_offset_in_bytes()));
2593 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes()));
2594 __ addptr(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
2595 if (UseCompressedOops) {
2596 __ push(Rrax);
2597 __ encode_heap_oop(Rrax);
2598 __ repne_scanl();
2599 __ pop(Rrax);
2600 __ jccb(Assembler::notEqual, miss);
2601 __ movptr(Address(Rrsi,
2602 sizeof(oopDesc) +
2603 Klass::secondary_super_cache_offset_in_bytes()),
2604 Rrax);
2605 __ jmp(hit);
2606 } else {
2607 __ repne_scan();
2608 __ jccb(Assembler::notEqual, miss);
2609 __ movptr(Address(Rrsi,
2610 sizeof(oopDesc) +
2611 Klass::secondary_super_cache_offset_in_bytes()),
2612 Rrax);
2613 }
2614 __ bind(hit);
2615 if ($primary) { 2585 if ($primary) {
2616 __ xorptr(Rrdi, Rrdi); 2586 __ xorptr(Rrdi, Rrdi);
2617 } 2587 }
2618 __ bind(miss); 2588 __ bind(miss);
2619 %} 2589 %}
12177 %{ 12147 %{
12178 match(Set result (PartialSubtypeCheck sub super)); 12148 match(Set result (PartialSubtypeCheck sub super));
12179 effect(KILL rcx, KILL cr); 12149 effect(KILL rcx, KILL cr);
12180 12150
12181 ins_cost(1100); // slightly larger than the next version 12151 ins_cost(1100); // slightly larger than the next version
12182 format %{ "cmpq rax, rsi\n\t" 12152 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12183 "jeq,s hit\n\t"
12184 "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12185 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 12153 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12186 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 12154 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12187 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12155 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
12188 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12156 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
12189 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 12157 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t"
12190 "hit:\n\t"
12191 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12158 "xorq $result, $result\t\t Hit: rdi zero\n\t"
12192 "miss:\t" %} 12159 "miss:\t" %}
12193 12160
12194 opcode(0x1); // Force a XOR of RDI 12161 opcode(0x1); // Force a XOR of RDI
12195 ins_encode(enc_PartialSubtypeCheck()); 12162 ins_encode(enc_PartialSubtypeCheck());
12203 %{ 12170 %{
12204 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12171 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
12205 effect(KILL rcx, KILL result); 12172 effect(KILL rcx, KILL result);
12206 12173
12207 ins_cost(1000); 12174 ins_cost(1000);
12208 format %{ "cmpq rax, rsi\n\t" 12175 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12209 "jeq,s miss\t# Actually a hit; we are done.\n\t"
12210 "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t"
12211 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 12176 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
12212 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 12177 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
12213 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12178 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
12214 "jne,s miss\t\t# Missed: flags nz\n\t" 12179 "jne,s miss\t\t# Missed: flags nz\n\t"
12215 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 12180 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t"