Mercurial > hg > truffle
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" |