1031 // count - register containing element count |
1031 // count - register containing element count |
1032 // tmp - scratch register |
1032 // tmp - scratch register |
1033 // |
1033 // |
1034 // The input registers are overwritten. |
1034 // The input registers are overwritten. |
1035 // |
1035 // |
1036 void gen_write_ref_array_pre_barrier(Register addr, Register count) { |
1036 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) { |
1037 BarrierSet* bs = Universe::heap()->barrier_set(); |
1037 BarrierSet* bs = Universe::heap()->barrier_set(); |
1038 if (bs->has_write_ref_pre_barrier()) { |
1038 switch (bs->kind()) { |
1039 assert(bs->has_write_ref_array_pre_opt(), |
1039 case BarrierSet::G1SATBCT: |
1040 "Else unsupported barrier set."); |
1040 case BarrierSet::G1SATBCTLogging: |
1041 |
1041 // With G1, don't generate the call if we statically know that the target in uninitialized |
1042 __ save_frame(0); |
1042 if (!dest_uninitialized) { |
1043 // Save the necessary global regs... will be used after. |
1043 __ save_frame(0); |
1044 if (addr->is_global()) { |
1044 // Save the necessary global regs... will be used after. |
1045 __ mov(addr, L0); |
1045 if (addr->is_global()) { |
1046 } |
1046 __ mov(addr, L0); |
1047 if (count->is_global()) { |
1047 } |
1048 __ mov(count, L1); |
1048 if (count->is_global()) { |
1049 } |
1049 __ mov(count, L1); |
1050 __ mov(addr->after_save(), O0); |
1050 } |
1051 // Get the count into O1 |
1051 __ mov(addr->after_save(), O0); |
1052 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)); |
1052 // Get the count into O1 |
1053 __ delayed()->mov(count->after_save(), O1); |
1053 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)); |
1054 if (addr->is_global()) { |
1054 __ delayed()->mov(count->after_save(), O1); |
1055 __ mov(L0, addr); |
1055 if (addr->is_global()) { |
1056 } |
1056 __ mov(L0, addr); |
1057 if (count->is_global()) { |
1057 } |
1058 __ mov(L1, count); |
1058 if (count->is_global()) { |
1059 } |
1059 __ mov(L1, count); |
1060 __ restore(); |
1060 } |
|
1061 __ restore(); |
|
1062 } |
|
1063 break; |
|
1064 case BarrierSet::CardTableModRef: |
|
1065 case BarrierSet::CardTableExtension: |
|
1066 case BarrierSet::ModRef: |
|
1067 break; |
|
1068 default: |
|
1069 ShouldNotReachHere(); |
1061 } |
1070 } |
1062 } |
1071 } |
1063 // |
1072 // |
1064 // Generate post-write barrier for array. |
1073 // Generate post-write barrier for array. |
1065 // |
1074 // |
3081 address entry_jint_arraycopy; |
3091 address entry_jint_arraycopy; |
3082 address entry_oop_arraycopy; |
3092 address entry_oop_arraycopy; |
3083 address entry_jlong_arraycopy; |
3093 address entry_jlong_arraycopy; |
3084 address entry_checkcast_arraycopy; |
3094 address entry_checkcast_arraycopy; |
3085 |
3095 |
3086 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, |
3096 //*** jbyte |
3087 "jbyte_disjoint_arraycopy"); |
3097 // Always need aligned and unaligned versions |
3088 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy, |
3098 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, |
3089 "jbyte_arraycopy"); |
3099 "jbyte_disjoint_arraycopy"); |
3090 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, |
3100 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, |
3091 "jshort_disjoint_arraycopy"); |
3101 &entry_jbyte_arraycopy, |
3092 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy, |
3102 "jbyte_arraycopy"); |
3093 "jshort_arraycopy"); |
3103 StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry, |
3094 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry, |
3104 "arrayof_jbyte_disjoint_arraycopy"); |
3095 "jint_disjoint_arraycopy"); |
3105 StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, NULL, |
3096 StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, &entry_jint_arraycopy, |
3106 "arrayof_jbyte_arraycopy"); |
3097 "jint_arraycopy"); |
3107 |
3098 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(false, &entry, |
3108 //*** jshort |
3099 "jlong_disjoint_arraycopy"); |
3109 // Always need aligned and unaligned versions |
3100 StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(false, entry, &entry_jlong_arraycopy, |
3110 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, |
3101 "jlong_arraycopy"); |
3111 "jshort_disjoint_arraycopy"); |
3102 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, &entry, |
3112 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, |
3103 "oop_disjoint_arraycopy"); |
3113 &entry_jshort_arraycopy, |
3104 StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, entry, &entry_oop_arraycopy, |
3114 "jshort_arraycopy"); |
3105 "oop_arraycopy"); |
|
3106 |
|
3107 |
|
3108 StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry, |
|
3109 "arrayof_jbyte_disjoint_arraycopy"); |
|
3110 StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, NULL, |
|
3111 "arrayof_jbyte_arraycopy"); |
|
3112 |
|
3113 StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry, |
3115 StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry, |
3114 "arrayof_jshort_disjoint_arraycopy"); |
3116 "arrayof_jshort_disjoint_arraycopy"); |
3115 StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, NULL, |
3117 StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, NULL, |
3116 "arrayof_jshort_arraycopy"); |
3118 "arrayof_jshort_arraycopy"); |
3117 |
3119 |
3118 StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry, |
3120 //*** jint |
3119 "arrayof_jint_disjoint_arraycopy"); |
3121 // Aligned versions |
|
3122 StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry, |
|
3123 "arrayof_jint_disjoint_arraycopy"); |
|
3124 StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, &entry_jint_arraycopy, |
|
3125 "arrayof_jint_arraycopy"); |
3120 #ifdef _LP64 |
3126 #ifdef _LP64 |
3121 // since sizeof(jint) < sizeof(HeapWord), there's a different flavor: |
3127 // In 64 bit we need both aligned and unaligned versions of jint arraycopy. |
3122 StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, NULL, "arrayof_jint_arraycopy"); |
3128 // entry_jint_arraycopy always points to the unaligned version (notice that we overwrite it). |
3123 #else |
3129 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry, |
3124 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy; |
3130 "jint_disjoint_arraycopy"); |
|
3131 StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, |
|
3132 &entry_jint_arraycopy, |
|
3133 "jint_arraycopy"); |
|
3134 #else |
|
3135 // In 32 bit jints are always HeapWordSize aligned, so always use the aligned version |
|
3136 // (in fact in 32bit we always have a pre-loop part even in the aligned version, |
|
3137 // because it uses 64-bit loads/stores, so the aligned flag is actually ignored). |
|
3138 StubRoutines::_jint_disjoint_arraycopy = StubRoutines::_arrayof_jint_disjoint_arraycopy; |
|
3139 StubRoutines::_jint_arraycopy = StubRoutines::_arrayof_jint_arraycopy; |
3125 #endif |
3140 #endif |
3126 |
3141 |
3127 StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, NULL, |
3142 |
3128 "arrayof_jlong_disjoint_arraycopy"); |
3143 //*** jlong |
3129 StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, NULL, |
3144 // It is always aligned |
3130 "arrayof_oop_disjoint_arraycopy"); |
3145 StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, &entry, |
3131 |
3146 "arrayof_jlong_disjoint_arraycopy"); |
3132 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy; |
3147 StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy(true, entry, &entry_jlong_arraycopy, |
3133 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; |
3148 "arrayof_jlong_arraycopy"); |
3134 |
3149 StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; |
3135 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); |
3150 StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; |
|
3151 |
|
3152 |
|
3153 //*** oops |
|
3154 // Aligned versions |
|
3155 StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, &entry, |
|
3156 "arrayof_oop_disjoint_arraycopy"); |
|
3157 StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy(true, entry, &entry_oop_arraycopy, |
|
3158 "arrayof_oop_arraycopy"); |
|
3159 // Aligned versions without pre-barriers |
|
3160 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(true, &entry, |
|
3161 "arrayof_oop_disjoint_arraycopy_uninit", |
|
3162 /*dest_uninitialized*/true); |
|
3163 StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(true, entry, NULL, |
|
3164 "arrayof_oop_arraycopy_uninit", |
|
3165 /*dest_uninitialized*/true); |
|
3166 #ifdef _LP64 |
|
3167 if (UseCompressedOops) { |
|
3168 // With compressed oops we need unaligned versions, notice that we overwrite entry_oop_arraycopy. |
|
3169 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, &entry, |
|
3170 "oop_disjoint_arraycopy"); |
|
3171 StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, entry, &entry_oop_arraycopy, |
|
3172 "oop_arraycopy"); |
|
3173 // Unaligned versions without pre-barriers |
|
3174 StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(false, &entry, |
|
3175 "oop_disjoint_arraycopy_uninit", |
|
3176 /*dest_uninitialized*/true); |
|
3177 StubRoutines::_oop_arraycopy_uninit = generate_conjoint_oop_copy(false, entry, NULL, |
|
3178 "oop_arraycopy_uninit", |
|
3179 /*dest_uninitialized*/true); |
|
3180 } else |
|
3181 #endif |
|
3182 { |
|
3183 // oop arraycopy is always aligned on 32bit and 64bit without compressed oops |
|
3184 StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy; |
|
3185 StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy; |
|
3186 StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit; |
|
3187 StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit; |
|
3188 } |
|
3189 |
|
3190 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); |
|
3191 StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, |
|
3192 /*dest_uninitialized*/true); |
|
3193 |
3136 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", |
3194 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", |
3137 entry_jbyte_arraycopy, |
3195 entry_jbyte_arraycopy, |
3138 entry_jshort_arraycopy, |
3196 entry_jshort_arraycopy, |
3139 entry_jint_arraycopy, |
3197 entry_jint_arraycopy, |
3140 entry_jlong_arraycopy); |
3198 entry_jlong_arraycopy); |