Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.ad @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 006050192a5a |
children | 7eca5de9e0b6 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
514 // emit 32 bit value and construct relocation entry from RelocationHolder | 514 // emit 32 bit value and construct relocation entry from RelocationHolder |
515 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { | 515 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { |
516 #ifdef ASSERT | 516 #ifdef ASSERT |
517 if (rspec.reloc()->type() == relocInfo::oop_type && | 517 if (rspec.reloc()->type() == relocInfo::oop_type && |
518 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { | 518 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { |
519 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); | |
519 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); | 520 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); |
520 } | 521 } |
521 #endif | 522 #endif |
522 cbuf.relocate(cbuf.insts_mark(), rspec, format); | 523 cbuf.relocate(cbuf.insts_mark(), rspec, format); |
523 cbuf.insts()->emit_int32(d32); | 524 cbuf.insts()->emit_int32(d32); |
540 // emit 64 bit value and construct relocation entry from RelocationHolder | 541 // emit 64 bit value and construct relocation entry from RelocationHolder |
541 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { | 542 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { |
542 #ifdef ASSERT | 543 #ifdef ASSERT |
543 if (rspec.reloc()->type() == relocInfo::oop_type && | 544 if (rspec.reloc()->type() == relocInfo::oop_type && |
544 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { | 545 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { |
546 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); | |
545 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), | 547 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), |
546 "cannot embed scavengable oops in code"); | 548 "cannot embed scavengable oops in code"); |
547 } | 549 } |
548 #endif | 550 #endif |
549 cbuf.relocate(cbuf.insts_mark(), rspec, format); | 551 cbuf.relocate(cbuf.insts_mark(), rspec, format); |
566 } | 568 } |
567 | 569 |
568 // rRegI ereg, memory mem) %{ // emit_reg_mem | 570 // rRegI ereg, memory mem) %{ // emit_reg_mem |
569 void encode_RegMem(CodeBuffer &cbuf, | 571 void encode_RegMem(CodeBuffer &cbuf, |
570 int reg, | 572 int reg, |
571 int base, int index, int scale, int disp, bool disp_is_oop) | 573 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) |
572 { | 574 { |
573 assert(!disp_is_oop, "cannot have disp"); | 575 assert(disp_reloc == relocInfo::none, "cannot have disp"); |
574 int regenc = reg & 7; | 576 int regenc = reg & 7; |
575 int baseenc = base & 7; | 577 int baseenc = base & 7; |
576 int indexenc = index & 7; | 578 int indexenc = index & 7; |
577 | 579 |
578 // There is no index & no scale, use form without SIB byte | 580 // There is no index & no scale, use form without SIB byte |
579 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { | 581 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { |
580 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] | 582 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] |
581 if (disp == 0 && base != RBP_enc && base != R13_enc) { | 583 if (disp == 0 && base != RBP_enc && base != R13_enc) { |
582 emit_rm(cbuf, 0x0, regenc, baseenc); // * | 584 emit_rm(cbuf, 0x0, regenc, baseenc); // * |
583 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { | 585 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { |
584 // If 8-bit displacement, mode 0x1 | 586 // If 8-bit displacement, mode 0x1 |
585 emit_rm(cbuf, 0x1, regenc, baseenc); // * | 587 emit_rm(cbuf, 0x1, regenc, baseenc); // * |
586 emit_d8(cbuf, disp); | 588 emit_d8(cbuf, disp); |
587 } else { | 589 } else { |
588 // If 32-bit displacement | 590 // If 32-bit displacement |
589 if (base == -1) { // Special flag for absolute address | 591 if (base == -1) { // Special flag for absolute address |
590 emit_rm(cbuf, 0x0, regenc, 0x5); // * | 592 emit_rm(cbuf, 0x0, regenc, 0x5); // * |
591 if (disp_is_oop) { | 593 if (disp_reloc != relocInfo::none) { |
592 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); | 594 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); |
593 } else { | 595 } else { |
594 emit_d32(cbuf, disp); | 596 emit_d32(cbuf, disp); |
595 } | 597 } |
596 } else { | 598 } else { |
597 // Normal base + offset | 599 // Normal base + offset |
598 emit_rm(cbuf, 0x2, regenc, baseenc); // * | 600 emit_rm(cbuf, 0x2, regenc, baseenc); // * |
599 if (disp_is_oop) { | 601 if (disp_reloc != relocInfo::none) { |
600 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); | 602 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); |
601 } else { | 603 } else { |
602 emit_d32(cbuf, disp); | 604 emit_d32(cbuf, disp); |
603 } | 605 } |
604 } | 606 } |
609 if (disp == 0 && base != RBP_enc && base != R13_enc) { | 611 if (disp == 0 && base != RBP_enc && base != R13_enc) { |
610 // If no displacement | 612 // If no displacement |
611 emit_rm(cbuf, 0x0, regenc, 0x4); // * | 613 emit_rm(cbuf, 0x0, regenc, 0x4); // * |
612 emit_rm(cbuf, scale, indexenc, baseenc); | 614 emit_rm(cbuf, scale, indexenc, baseenc); |
613 } else { | 615 } else { |
614 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { | 616 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { |
615 // If 8-bit displacement, mode 0x1 | 617 // If 8-bit displacement, mode 0x1 |
616 emit_rm(cbuf, 0x1, regenc, 0x4); // * | 618 emit_rm(cbuf, 0x1, regenc, 0x4); // * |
617 emit_rm(cbuf, scale, indexenc, baseenc); | 619 emit_rm(cbuf, scale, indexenc, baseenc); |
618 emit_d8(cbuf, disp); | 620 emit_d8(cbuf, disp); |
619 } else { | 621 } else { |
623 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? | 625 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? |
624 } else { | 626 } else { |
625 emit_rm(cbuf, 0x2, regenc, 0x4); | 627 emit_rm(cbuf, 0x2, regenc, 0x4); |
626 emit_rm(cbuf, scale, indexenc, baseenc); // * | 628 emit_rm(cbuf, scale, indexenc, baseenc); // * |
627 } | 629 } |
628 if (disp_is_oop) { | 630 if (disp_reloc != relocInfo::none) { |
629 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); | 631 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); |
630 } else { | 632 } else { |
631 emit_d32(cbuf, disp); | 633 emit_d32(cbuf, disp); |
632 } | 634 } |
633 } | 635 } |
1380 address base = | 1382 address base = |
1381 __ start_a_stub(Compile::MAX_stubs_size); | 1383 __ start_a_stub(Compile::MAX_stubs_size); |
1382 if (base == NULL) return; // CodeBuffer::expand failed | 1384 if (base == NULL) return; // CodeBuffer::expand failed |
1383 // static stub relocation stores the instruction address of the call | 1385 // static stub relocation stores the instruction address of the call |
1384 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); | 1386 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); |
1385 // static stub relocation also tags the methodOop in the code-stream. | 1387 // static stub relocation also tags the Method* in the code-stream. |
1386 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time | 1388 __ mov_metadata(rbx, (Metadata*) NULL); // method is zapped till fixup time |
1387 // This is recognized as unresolved by relocs/nativeinst/ic code | 1389 // This is recognized as unresolved by relocs/nativeinst/ic code |
1388 __ jump(RuntimeAddress(__ pc())); | 1390 __ jump(RuntimeAddress(__ pc())); |
1389 | 1391 |
1390 // Update current stubs pointer and restore insts_end. | 1392 // Update current stubs pointer and restore insts_end. |
1391 __ end_a_stub(); | 1393 __ end_a_stub(); |
2042 // Emit stub for static call | 2044 // Emit stub for static call |
2043 emit_java_to_interp(cbuf); | 2045 emit_java_to_interp(cbuf); |
2044 } | 2046 } |
2045 %} | 2047 %} |
2046 | 2048 |
2047 enc_class Java_Dynamic_Call(method meth) | 2049 enc_class Java_Dynamic_Call(method meth) %{ |
2048 %{ | 2050 MacroAssembler _masm(&cbuf); |
2049 // JAVA DYNAMIC CALL | 2051 __ ic_call((address)$meth$$method); |
2050 // !!!!! | |
2051 // Generate "movq rax, -1", placeholder instruction to load oop-info | |
2052 // emit_call_dynamic_prologue( cbuf ); | |
2053 cbuf.set_insts_mark(); | |
2054 | |
2055 // movq rax, -1 | |
2056 emit_opcode(cbuf, Assembler::REX_W); | |
2057 emit_opcode(cbuf, 0xB8 | RAX_enc); | |
2058 emit_d64_reloc(cbuf, | |
2059 (int64_t) Universe::non_oop_word(), | |
2060 oop_Relocation::spec_for_immediate(), RELOC_IMM64); | |
2061 address virtual_call_oop_addr = cbuf.insts_mark(); | |
2062 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine | |
2063 // who we intended to call. | |
2064 cbuf.set_insts_mark(); | |
2065 $$$emit8$primary; | |
2066 emit_d32_reloc(cbuf, | |
2067 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), | |
2068 virtual_call_Relocation::spec(virtual_call_oop_addr), | |
2069 RELOC_DISP32); | |
2070 %} | 2052 %} |
2071 | 2053 |
2072 enc_class Java_Compiled_Call(method meth) | 2054 enc_class Java_Compiled_Call(method meth) |
2073 %{ | 2055 %{ |
2074 // JAVA COMPILED CALL | 2056 // JAVA COMPILED CALL |
2075 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); | 2057 int disp = in_bytes(Method:: from_compiled_offset()); |
2076 | 2058 |
2077 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! | 2059 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! |
2078 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); | 2060 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); |
2079 | 2061 |
2080 // callq *disp(%rax) | 2062 // callq *disp(%rax) |
2188 emit_opcode(cbuf, Assembler::REX_WB); | 2170 emit_opcode(cbuf, Assembler::REX_WB); |
2189 dstenc -= 8; | 2171 dstenc -= 8; |
2190 } | 2172 } |
2191 emit_opcode(cbuf, 0xB8 | dstenc); | 2173 emit_opcode(cbuf, 0xB8 | dstenc); |
2192 // This next line should be generated from ADLC | 2174 // This next line should be generated from ADLC |
2193 if ($src->constant_is_oop()) { | 2175 if ($src->constant_reloc() != relocInfo::none) { |
2194 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); | 2176 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); |
2195 } else { | 2177 } else { |
2196 emit_d64(cbuf, $src$$constant); | 2178 emit_d64(cbuf, $src$$constant); |
2197 } | 2179 } |
2198 %} | 2180 %} |
2199 | 2181 |
2450 int reg = $ereg$$reg; | 2432 int reg = $ereg$$reg; |
2451 int base = $mem$$base; | 2433 int base = $mem$$base; |
2452 int index = $mem$$index; | 2434 int index = $mem$$index; |
2453 int scale = $mem$$scale; | 2435 int scale = $mem$$scale; |
2454 int disp = $mem$$disp; | 2436 int disp = $mem$$disp; |
2455 bool disp_is_oop = $mem->disp_is_oop(); | 2437 relocInfo::relocType disp_reloc = $mem->disp_reloc(); |
2456 | 2438 |
2457 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); | 2439 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); |
2458 %} | 2440 %} |
2459 | 2441 |
2460 enc_class RM_opc_mem(immI rm_opcode, memory mem) | 2442 enc_class RM_opc_mem(immI rm_opcode, memory mem) |
2461 %{ | 2443 %{ |
2462 int rm_byte_opcode = $rm_opcode$$constant; | 2444 int rm_byte_opcode = $rm_opcode$$constant; |
2465 int base = $mem$$base; | 2447 int base = $mem$$base; |
2466 int index = $mem$$index; | 2448 int index = $mem$$index; |
2467 int scale = $mem$$scale; | 2449 int scale = $mem$$scale; |
2468 int displace = $mem$$disp; | 2450 int displace = $mem$$disp; |
2469 | 2451 |
2470 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when | 2452 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when |
2471 // working with static | 2453 // working with static |
2472 // globals | 2454 // globals |
2473 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, | 2455 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, |
2474 disp_is_oop); | 2456 disp_reloc); |
2475 %} | 2457 %} |
2476 | 2458 |
2477 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) | 2459 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) |
2478 %{ | 2460 %{ |
2479 int reg_encoding = $dst$$reg; | 2461 int reg_encoding = $dst$$reg; |
2480 int base = $src0$$reg; // 0xFFFFFFFF indicates no base | 2462 int base = $src0$$reg; // 0xFFFFFFFF indicates no base |
2481 int index = 0x04; // 0x04 indicates no index | 2463 int index = 0x04; // 0x04 indicates no index |
2482 int scale = 0x00; // 0x00 indicates no scale | 2464 int scale = 0x00; // 0x00 indicates no scale |
2483 int displace = $src1$$constant; // 0x00 indicates no displacement | 2465 int displace = $src1$$constant; // 0x00 indicates no displacement |
2484 bool disp_is_oop = false; | 2466 relocInfo::relocType disp_reloc = relocInfo::none; |
2485 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, | 2467 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, |
2486 disp_is_oop); | 2468 disp_reloc); |
2487 %} | 2469 %} |
2488 | 2470 |
2489 enc_class neg_reg(rRegI dst) | 2471 enc_class neg_reg(rRegI dst) |
2490 %{ | 2472 %{ |
2491 int dstenc = $dst$$reg; | 2473 int dstenc = $dst$$reg; |
3167 interface(CONST_INTER); | 3149 interface(CONST_INTER); |
3168 %} | 3150 %} |
3169 | 3151 |
3170 operand immP31() | 3152 operand immP31() |
3171 %{ | 3153 %{ |
3172 predicate(!n->as_Type()->type()->isa_oopptr() | 3154 predicate(n->as_Type()->type()->reloc() == relocInfo::none |
3173 && (n->get_ptr() >> 31) == 0); | 3155 && (n->get_ptr() >> 31) == 0); |
3174 match(ConP); | 3156 match(ConP); |
3175 | 3157 |
3176 op_cost(5); | 3158 op_cost(5); |
3177 format %{ %} | 3159 format %{ %} |
6464 %} | 6446 %} |
6465 ins_pipe(ialu_reg_long); | 6447 ins_pipe(ialu_reg_long); |
6466 %} | 6448 %} |
6467 | 6449 |
6468 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ | 6450 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ |
6469 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && | 6451 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && |
6470 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); | 6452 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); |
6471 match(Set dst (DecodeN src)); | 6453 match(Set dst (DecodeN src)); |
6472 effect(KILL cr); | 6454 effect(KILL cr); |
6473 format %{ "decode_heap_oop $dst,$src" %} | 6455 format %{ "decode_heap_oop $dst,$src" %} |
6474 ins_encode %{ | 6456 ins_encode %{ |
6475 Register s = $src$$Register; | 6457 Register s = $src$$Register; |
6481 %} | 6463 %} |
6482 ins_pipe(ialu_reg_long); | 6464 ins_pipe(ialu_reg_long); |
6483 %} | 6465 %} |
6484 | 6466 |
6485 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ | 6467 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ |
6486 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || | 6468 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || |
6487 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); | 6469 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); |
6488 match(Set dst (DecodeN src)); | 6470 match(Set dst (DecodeN src)); |
6489 effect(KILL cr); | 6471 effect(KILL cr); |
6490 format %{ "decode_heap_oop_not_null $dst,$src" %} | 6472 format %{ "decode_heap_oop_not_null $dst,$src" %} |
6491 ins_encode %{ | 6473 ins_encode %{ |
6492 Register s = $src$$Register; | 6474 Register s = $src$$Register; |
10346 // Compare raw pointer (used in out-of-heap check). | 10328 // Compare raw pointer (used in out-of-heap check). |
10347 // Only works because non-oop pointers must be raw pointers | 10329 // Only works because non-oop pointers must be raw pointers |
10348 // and raw pointers have no anti-dependencies. | 10330 // and raw pointers have no anti-dependencies. |
10349 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) | 10331 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) |
10350 %{ | 10332 %{ |
10351 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); | 10333 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); |
10352 match(Set cr (CmpP op1 (LoadP op2))); | 10334 match(Set cr (CmpP op1 (LoadP op2))); |
10353 | 10335 |
10354 format %{ "cmpq $op1, $op2\t# raw ptr" %} | 10336 format %{ "cmpq $op1, $op2\t# raw ptr" %} |
10355 opcode(0x3B); /* Opcode 3B /r */ | 10337 opcode(0x3B); /* Opcode 3B /r */ |
10356 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); | 10338 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); |
10755 match(Set result (PartialSubtypeCheck sub super)); | 10737 match(Set result (PartialSubtypeCheck sub super)); |
10756 effect(KILL rcx, KILL cr); | 10738 effect(KILL rcx, KILL cr); |
10757 | 10739 |
10758 ins_cost(1100); // slightly larger than the next version | 10740 ins_cost(1100); // slightly larger than the next version |
10759 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" | 10741 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" |
10760 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" | 10742 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" |
10761 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" | 10743 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" |
10762 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" | 10744 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" |
10763 "jne,s miss\t\t# Missed: rdi not-zero\n\t" | 10745 "jne,s miss\t\t# Missed: rdi not-zero\n\t" |
10764 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" | 10746 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" |
10765 "xorq $result, $result\t\t Hit: rdi zero\n\t" | 10747 "xorq $result, $result\t\t Hit: rdi zero\n\t" |
10766 "miss:\t" %} | 10748 "miss:\t" %} |
10778 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); | 10760 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); |
10779 effect(KILL rcx, KILL result); | 10761 effect(KILL rcx, KILL result); |
10780 | 10762 |
10781 ins_cost(1000); | 10763 ins_cost(1000); |
10782 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" | 10764 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" |
10783 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" | 10765 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" |
10784 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" | 10766 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" |
10785 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" | 10767 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" |
10786 "jne,s miss\t\t# Missed: flags nz\n\t" | 10768 "jne,s miss\t\t# Missed: flags nz\n\t" |
10787 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" | 10769 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" |
10788 "miss:\t" %} | 10770 "miss:\t" %} |
10789 | 10771 |
11058 effect(USE meth); | 11040 effect(USE meth); |
11059 | 11041 |
11060 ins_cost(300); | 11042 ins_cost(300); |
11061 format %{ "movq rax, #Universe::non_oop_word()\n\t" | 11043 format %{ "movq rax, #Universe::non_oop_word()\n\t" |
11062 "call,dynamic " %} | 11044 "call,dynamic " %} |
11063 opcode(0xE8); /* E8 cd */ | |
11064 ins_encode(Java_Dynamic_Call(meth), call_epilog); | 11045 ins_encode(Java_Dynamic_Call(meth), call_epilog); |
11065 ins_pipe(pipe_slow); | 11046 ins_pipe(pipe_slow); |
11066 ins_alignment(4); | 11047 ins_alignment(4); |
11067 %} | 11048 %} |
11068 | 11049 |