894 // icc/xcc: set as O0 (depending on wordSize) |
895 // icc/xcc: set as O0 (depending on wordSize) |
895 // sub : O1, argument, not changed |
896 // sub : O1, argument, not changed |
896 // super: O2, argument, not changed |
897 // super: O2, argument, not changed |
897 // raddr: O7, blown by call |
898 // raddr: O7, blown by call |
898 address generate_partial_subtype_check() { |
899 address generate_partial_subtype_check() { |
|
900 __ align(CodeEntryAlignment); |
899 StubCodeMark mark(this, "StubRoutines", "partial_subtype_check"); |
901 StubCodeMark mark(this, "StubRoutines", "partial_subtype_check"); |
900 address start = __ pc(); |
902 address start = __ pc(); |
901 Label loop, miss; |
903 Label loop, miss; |
902 |
904 |
903 // Compare super with sub directly, since super is not in its own SSA. |
905 // Compare super with sub directly, since super is not in its own SSA. |
912 __ bind(L); |
914 __ bind(L); |
913 } |
915 } |
914 |
916 |
915 #if defined(COMPILER2) && !defined(_LP64) |
917 #if defined(COMPILER2) && !defined(_LP64) |
916 // Do not use a 'save' because it blows the 64-bit O registers. |
918 // Do not use a 'save' because it blows the 64-bit O registers. |
917 __ add(SP,-4*wordSize,SP); // Make space for 4 temps |
919 __ add(SP,-4*wordSize,SP); // Make space for 4 temps (stack must be 2 words aligned) |
918 __ st_ptr(L0,SP,(frame::register_save_words+0)*wordSize); |
920 __ st_ptr(L0,SP,(frame::register_save_words+0)*wordSize); |
919 __ st_ptr(L1,SP,(frame::register_save_words+1)*wordSize); |
921 __ st_ptr(L1,SP,(frame::register_save_words+1)*wordSize); |
920 __ st_ptr(L2,SP,(frame::register_save_words+2)*wordSize); |
922 __ st_ptr(L2,SP,(frame::register_save_words+2)*wordSize); |
921 __ st_ptr(L3,SP,(frame::register_save_words+3)*wordSize); |
923 __ st_ptr(L3,SP,(frame::register_save_words+3)*wordSize); |
922 Register Rret = O0; |
924 Register Rret = O0; |
932 Register L0_ary_len = L0; |
934 Register L0_ary_len = L0; |
933 Register L1_ary_ptr = L1; |
935 Register L1_ary_ptr = L1; |
934 Register L2_super = L2; |
936 Register L2_super = L2; |
935 Register L3_index = L3; |
937 Register L3_index = L3; |
936 |
938 |
|
939 #ifdef _LP64 |
|
940 Register L4_ooptmp = L4; |
|
941 |
|
942 if (UseCompressedOops) { |
|
943 // this must be under UseCompressedOops check, as we rely upon fact |
|
944 // that L4 not clobbered in C2 on 32-bit platforms, where we do explicit save |
|
945 // on stack, see several lines above |
|
946 __ encode_heap_oop(Rsuper, L4_ooptmp); |
|
947 } |
|
948 #endif |
|
949 |
937 inc_counter_np(SharedRuntime::_partial_subtype_ctr, L0, L1); |
950 inc_counter_np(SharedRuntime::_partial_subtype_ctr, L0, L1); |
938 |
951 |
939 __ ld_ptr( Rsub, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), L3 ); |
952 __ ld_ptr( Rsub, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), L3 ); |
940 __ lduw(L3,arrayOopDesc::length_offset_in_bytes(),L0_ary_len); |
953 __ lduw(L3,arrayOopDesc::length_offset_in_bytes(),L0_ary_len); |
941 __ add(L3,arrayOopDesc::base_offset_in_bytes(T_OBJECT),L1_ary_ptr); |
954 __ add(L3,arrayOopDesc::base_offset_in_bytes(T_OBJECT),L1_ary_ptr); |
942 __ clr(L3_index); // zero index |
955 __ clr(L3_index); // zero index |
943 // Load a little early; will load 1 off the end of the array. |
956 // Load a little early; will load 1 off the end of the array. |
944 // Ok for now; revisit if we have other uses of this routine. |
957 // Ok for now; revisit if we have other uses of this routine. |
945 __ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early |
958 if (UseCompressedOops) { |
946 __ align(CodeEntryAlignment); |
959 __ ld(L1_ary_ptr,0,L2_super);// Will load a little early |
947 |
960 } else { |
|
961 __ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early |
|
962 } |
|
963 |
|
964 assert(heapOopSize != 0, "heapOopSize should be initialized"); |
948 // The scan loop |
965 // The scan loop |
949 __ BIND(loop); |
966 __ BIND(loop); |
950 __ add(L1_ary_ptr,wordSize,L1_ary_ptr); // Bump by OOP size |
967 __ add(L1_ary_ptr, heapOopSize, L1_ary_ptr); // Bump by OOP size |
951 __ cmp(L3_index,L0_ary_len); |
968 __ cmp(L3_index,L0_ary_len); |
952 __ br(Assembler::equal,false,Assembler::pn,miss); |
969 __ br(Assembler::equal,false,Assembler::pn,miss); |
953 __ delayed()->inc(L3_index); // Bump index |
970 __ delayed()->inc(L3_index); // Bump index |
954 __ subcc(L2_super,Rsuper,Rret); // Check for match; zero in Rret for a hit |
971 |
955 __ brx( Assembler::notEqual, false, Assembler::pt, loop ); |
972 if (UseCompressedOops) { |
956 __ delayed()->ld_ptr(L1_ary_ptr,0,L2_super); // Will load a little early |
973 #ifdef _LP64 |
|
974 __ subcc(L2_super,L4_ooptmp,Rret); // Check for match; zero in Rret for a hit |
|
975 __ br( Assembler::notEqual, false, Assembler::pt, loop ); |
|
976 __ delayed()->ld(L1_ary_ptr,0,L2_super);// Will load a little early |
|
977 #else |
|
978 ShouldNotReachHere(); |
|
979 #endif |
|
980 } else { |
|
981 __ subcc(L2_super,Rsuper,Rret); // Check for match; zero in Rret for a hit |
|
982 __ brx( Assembler::notEqual, false, Assembler::pt, loop ); |
|
983 __ delayed()->ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early |
|
984 } |
957 |
985 |
958 // Got a hit; report success; set cache. Cache load doesn't |
986 // Got a hit; report success; set cache. Cache load doesn't |
959 // happen here; for speed it is directly emitted by the compiler. |
987 // happen here; for speed it is directly emitted by the compiler. |
960 __ st_ptr( Rsuper, Rsub, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); |
988 __ st_ptr( Rsuper, Rsub, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); |
961 |
989 |
1146 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); |
1173 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); |
1147 assert_different_registers(addr, count, tmp); |
1174 assert_different_registers(addr, count, tmp); |
1148 |
1175 |
1149 Label L_loop; |
1176 Label L_loop; |
1150 |
1177 |
1151 __ sll_ptr(count, LogBytesPerOop, count); |
1178 __ sll_ptr(count, LogBytesPerHeapOop, count); |
1152 __ sub(count, BytesPerOop, count); |
1179 __ sub(count, BytesPerHeapOop, count); |
1153 __ add(count, addr, count); |
1180 __ add(count, addr, count); |
1154 // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.) |
1181 // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.) |
1155 __ srl_ptr(addr, CardTableModRefBS::card_shift, addr); |
1182 __ srl_ptr(addr, CardTableModRefBS::card_shift, addr); |
1156 __ srl_ptr(count, CardTableModRefBS::card_shift, count); |
1183 __ srl_ptr(count, CardTableModRefBS::card_shift, count); |
1157 __ sub(count, addr, count); |
1184 __ sub(count, addr, count); |
2427 // G3, G4, G5 --- current oop, oop.klass, oop.klass.super |
2460 // G3, G4, G5 --- current oop, oop.klass, oop.klass.super |
2428 __ align(16); |
2461 __ align(16); |
2429 |
2462 |
2430 __ bind(store_element); |
2463 __ bind(store_element); |
2431 // deccc(G1_remain); // decrement the count (hoisted) |
2464 // deccc(G1_remain); // decrement the count (hoisted) |
2432 __ st_ptr(G3_oop, O1_to, O5_offset); // store the oop |
2465 __ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop |
2433 __ inc(O5_offset, wordSize); // step to next offset |
2466 __ inc(O5_offset, heapOopSize); // step to next offset |
2434 __ brx(Assembler::zero, true, Assembler::pt, do_card_marks); |
2467 __ brx(Assembler::zero, true, Assembler::pt, do_card_marks); |
2435 __ delayed()->set(0, O0); // return -1 on success |
2468 __ delayed()->set(0, O0); // return -1 on success |
2436 |
2469 |
2437 // ======== loop entry is here ======== |
2470 // ======== loop entry is here ======== |
2438 __ bind(load_element); |
2471 __ bind(load_element); |
2439 __ ld_ptr(O0_from, O5_offset, G3_oop); // load the oop |
2472 __ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop |
2440 __ br_null(G3_oop, true, Assembler::pt, store_element); |
2473 __ br_null(G3_oop, true, Assembler::pt, store_element); |
2441 __ delayed()->deccc(G1_remain); // decrement the count |
2474 __ delayed()->deccc(G1_remain); // decrement the count |
2442 |
2475 |
2443 __ ld_ptr(G3_oop, klass_off, G4_klass); // query the object klass |
2476 __ load_klass(G3_oop, G4_klass); // query the object klass |
2444 |
2477 |
2445 generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super, |
2478 generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super, |
2446 // branch to this on success: |
2479 // branch to this on success: |
2447 store_element, |
2480 store_element, |
2448 // decrement this on success: |
2481 // decrement this on success: |
2640 __ delayed()->tst(length); |
2673 __ delayed()->tst(length); |
2641 __ br(Assembler::negative, false, Assembler::pn, L_failed); |
2674 __ br(Assembler::negative, false, Assembler::pn, L_failed); |
2642 |
2675 |
2643 BLOCK_COMMENT("arraycopy argument klass checks"); |
2676 BLOCK_COMMENT("arraycopy argument klass checks"); |
2644 // get src->klass() |
2677 // get src->klass() |
2645 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), G3_src_klass); |
2678 if (UseCompressedOops) { |
|
2679 __ delayed()->nop(); // ??? not good |
|
2680 __ load_klass(src, G3_src_klass); |
|
2681 } else { |
|
2682 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), G3_src_klass); |
|
2683 } |
2646 |
2684 |
2647 #ifdef ASSERT |
2685 #ifdef ASSERT |
2648 // assert(src->klass() != NULL); |
2686 // assert(src->klass() != NULL); |
2649 BLOCK_COMMENT("assert klasses not null"); |
2687 BLOCK_COMMENT("assert klasses not null"); |
2650 { Label L_a, L_b; |
2688 { Label L_a, L_b; |
2651 __ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL |
2689 __ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL |
2652 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); |
2690 __ delayed()->nop(); |
2653 __ bind(L_a); |
2691 __ bind(L_a); |
2654 __ stop("broken null klass"); |
2692 __ stop("broken null klass"); |
2655 __ bind(L_b); |
2693 __ bind(L_b); |
|
2694 __ load_klass(dst, G4_dst_klass); |
2656 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also |
2695 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also |
2657 __ delayed()->mov(G0, G4_dst_klass); // scribble the temp |
2696 __ delayed()->mov(G0, G4_dst_klass); // scribble the temp |
2658 BLOCK_COMMENT("assert done"); |
2697 BLOCK_COMMENT("assert done"); |
2659 } |
2698 } |
2660 #endif |
2699 #endif |
2671 Klass::layout_helper_offset_in_bytes(); |
2710 Klass::layout_helper_offset_in_bytes(); |
2672 |
2711 |
2673 // Load 32-bits signed value. Use br() instruction with it to check icc. |
2712 // Load 32-bits signed value. Use br() instruction with it to check icc. |
2674 __ lduw(G3_src_klass, lh_offset, G5_lh); |
2713 __ lduw(G3_src_klass, lh_offset, G5_lh); |
2675 |
2714 |
|
2715 if (UseCompressedOops) { |
|
2716 __ load_klass(dst, G4_dst_klass); |
|
2717 } |
2676 // Handle objArrays completely differently... |
2718 // Handle objArrays completely differently... |
2677 juint objArray_lh = Klass::array_layout_helper(T_OBJECT); |
2719 juint objArray_lh = Klass::array_layout_helper(T_OBJECT); |
2678 __ set(objArray_lh, O5_temp); |
2720 __ set(objArray_lh, O5_temp); |
2679 __ cmp(G5_lh, O5_temp); |
2721 __ cmp(G5_lh, O5_temp); |
2680 __ br(Assembler::equal, false, Assembler::pt, L_objArray); |
2722 __ br(Assembler::equal, false, Assembler::pt, L_objArray); |
2681 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); |
2723 if (UseCompressedOops) { |
|
2724 __ delayed()->nop(); |
|
2725 } else { |
|
2726 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); |
|
2727 } |
2682 |
2728 |
2683 // if (src->klass() != dst->klass()) return -1; |
2729 // if (src->klass() != dst->klass()) return -1; |
2684 __ cmp(G3_src_klass, G4_dst_klass); |
2730 __ cmp(G3_src_klass, G4_dst_klass); |
2685 __ brx(Assembler::notEqual, false, Assembler::pn, L_failed); |
2731 __ brx(Assembler::notEqual, false, Assembler::pn, L_failed); |
2686 __ delayed()->nop(); |
2732 __ delayed()->nop(); |
2775 arraycopy_range_checks(src, src_pos, dst, dst_pos, length, |
2821 arraycopy_range_checks(src, src_pos, dst, dst_pos, length, |
2776 O5_temp, G5_lh, L_failed); |
2822 O5_temp, G5_lh, L_failed); |
2777 |
2823 |
2778 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset |
2824 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset |
2779 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset |
2825 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset |
2780 __ sll_ptr(src_pos, LogBytesPerOop, src_pos); |
2826 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos); |
2781 __ sll_ptr(dst_pos, LogBytesPerOop, dst_pos); |
2827 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos); |
2782 __ add(src, src_pos, from); // src_addr |
2828 __ add(src, src_pos, from); // src_addr |
2783 __ add(dst, dst_pos, to); // dst_addr |
2829 __ add(dst, dst_pos, to); // dst_addr |
2784 __ BIND(L_plain_copy); |
2830 __ BIND(L_plain_copy); |
2785 __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy); |
2831 __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy); |
2786 __ delayed()->signx(length, count); // length |
2832 __ delayed()->signx(length, count); // length |
2799 O5_temp, G5_lh, L_failed); |
2845 O5_temp, G5_lh, L_failed); |
2800 |
2846 |
2801 // Marshal the base address arguments now, freeing registers. |
2847 // Marshal the base address arguments now, freeing registers. |
2802 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset |
2848 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset |
2803 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset |
2849 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset |
2804 __ sll_ptr(src_pos, LogBytesPerOop, src_pos); |
2850 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos); |
2805 __ sll_ptr(dst_pos, LogBytesPerOop, dst_pos); |
2851 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos); |
2806 __ add(src, src_pos, from); // src_addr |
2852 __ add(src, src_pos, from); // src_addr |
2807 __ add(dst, dst_pos, to); // dst_addr |
2853 __ add(dst, dst_pos, to); // dst_addr |
2808 __ signx(length, count); // length (reloaded) |
2854 __ signx(length, count); // length (reloaded) |
2809 |
2855 |
2810 Register sco_temp = O3; // this register is free now |
2856 Register sco_temp = O3; // this register is free now |