3081 |
3081 |
3082 ShenandoahLoadReferenceBarrierNode::Strength ShenandoahLoadReferenceBarrierNode::get_barrier_strength() { |
3082 ShenandoahLoadReferenceBarrierNode::Strength ShenandoahLoadReferenceBarrierNode::get_barrier_strength() { |
3083 Unique_Node_List visited; |
3083 Unique_Node_List visited; |
3084 Node_Stack stack(0); |
3084 Node_Stack stack(0); |
3085 stack.push(this, 0); |
3085 stack.push(this, 0); |
|
3086 |
|
3087 // Look for strongest strength: go over nodes looking for STRONG ones. |
|
3088 // Stop once we encountered STRONG. Otherwise, walk until we ran out of nodes, |
|
3089 // and then the overall strength is NONE. |
3086 Strength strength = NONE; |
3090 Strength strength = NONE; |
3087 while (strength != STRONG && stack.size() > 0) { |
3091 while (strength != STRONG && stack.size() > 0) { |
3088 Node* n = stack.node(); |
3092 Node* n = stack.node(); |
3089 if (visited.member(n)) { |
3093 if (visited.member(n)) { |
3090 stack.pop(); |
3094 stack.pop(); |
3091 continue; |
3095 continue; |
3092 } |
3096 } |
3093 visited.push(n); |
3097 visited.push(n); |
3094 bool visit_users = false; |
3098 bool visit_users = false; |
3095 switch (n->Opcode()) { |
3099 switch (n->Opcode()) { |
3096 case Op_StoreN: |
3100 case Op_CallStaticJava: |
3097 case Op_StoreP: { |
|
3098 strength = STRONG; |
|
3099 break; |
|
3100 } |
|
3101 case Op_CmpP: { |
|
3102 if (!n->in(1)->bottom_type()->higher_equal(TypePtr::NULL_PTR) && |
|
3103 !n->in(2)->bottom_type()->higher_equal(TypePtr::NULL_PTR)) { |
|
3104 strength = STRONG; |
|
3105 } |
|
3106 break; |
|
3107 } |
|
3108 case Op_CallStaticJava: { |
|
3109 strength = STRONG; |
|
3110 break; |
|
3111 } |
|
3112 case Op_CallDynamicJava: |
3101 case Op_CallDynamicJava: |
3113 case Op_CallLeaf: |
3102 case Op_CallLeaf: |
3114 case Op_CallLeafNoFP: |
3103 case Op_CallLeafNoFP: |
3115 case Op_CompareAndSwapL: |
3104 case Op_CompareAndSwapL: |
3116 case Op_CompareAndSwapI: |
3105 case Op_CompareAndSwapI: |
3157 case Op_StoreF: |
3146 case Op_StoreF: |
3158 case Op_StoreL: |
3147 case Op_StoreL: |
3159 case Op_StoreLConditional: |
3148 case Op_StoreLConditional: |
3160 case Op_StoreI: |
3149 case Op_StoreI: |
3161 case Op_StoreIConditional: |
3150 case Op_StoreIConditional: |
|
3151 case Op_StoreN: |
|
3152 case Op_StoreP: |
3162 case Op_StoreVector: |
3153 case Op_StoreVector: |
3163 case Op_StrInflatedCopy: |
3154 case Op_StrInflatedCopy: |
3164 case Op_StrCompressedCopy: |
3155 case Op_StrCompressedCopy: |
3165 case Op_EncodeP: |
3156 case Op_EncodeP: |
3166 case Op_CastP2X: |
3157 case Op_CastP2X: |
3167 case Op_SafePoint: |
3158 case Op_SafePoint: |
3168 case Op_EncodeISOArray: |
3159 case Op_EncodeISOArray: |
|
3160 case Op_AryEq: |
|
3161 case Op_StrEquals: |
|
3162 case Op_StrComp: |
|
3163 case Op_StrIndexOf: |
|
3164 case Op_StrIndexOfChar: |
|
3165 case Op_HasNegatives: |
|
3166 // Known to require barriers |
3169 strength = STRONG; |
3167 strength = STRONG; |
3170 break; |
3168 break; |
|
3169 case Op_CmpP: { |
|
3170 if (n->in(1)->bottom_type()->higher_equal(TypePtr::NULL_PTR) || |
|
3171 n->in(2)->bottom_type()->higher_equal(TypePtr::NULL_PTR)) { |
|
3172 // One of the sides is known null, no need for barrier. |
|
3173 } else { |
|
3174 strength = STRONG; |
|
3175 } |
|
3176 break; |
|
3177 } |
3171 case Op_LoadB: |
3178 case Op_LoadB: |
3172 case Op_LoadUB: |
3179 case Op_LoadUB: |
3173 case Op_LoadUS: |
3180 case Op_LoadUS: |
3174 case Op_LoadD: |
3181 case Op_LoadD: |
3175 case Op_LoadF: |
3182 case Op_LoadF: |
3183 int alias_idx = Compile::current()->get_alias_index(adr_type); |
3190 int alias_idx = Compile::current()->get_alias_index(adr_type); |
3184 Compile::AliasType* alias_type = Compile::current()->alias_type(alias_idx); |
3191 Compile::AliasType* alias_type = Compile::current()->alias_type(alias_idx); |
3185 ciField* field = alias_type->field(); |
3192 ciField* field = alias_type->field(); |
3186 bool is_static = field != NULL && field->is_static(); |
3193 bool is_static = field != NULL && field->is_static(); |
3187 bool is_final = field != NULL && field->is_final(); |
3194 bool is_final = field != NULL && field->is_final(); |
|
3195 |
3188 if (ShenandoahOptimizeStaticFinals && is_static && is_final) { |
3196 if (ShenandoahOptimizeStaticFinals && is_static && is_final) { |
3189 // Leave strength as is. |
3197 // Loading the constant does not require barriers: it should be handled |
|
3198 // as part of GC roots already. |
3190 } else { |
3199 } else { |
3191 strength = WEAK; |
3200 strength = STRONG; |
3192 } |
3201 } |
3193 break; |
3202 break; |
3194 } |
3203 } |
3195 case Op_AryEq: |
|
3196 case Op_StrEquals: |
|
3197 case Op_StrComp: |
|
3198 case Op_StrIndexOf: |
|
3199 case Op_StrIndexOfChar: |
|
3200 case Op_HasNegatives: |
|
3201 strength = WEAK; |
|
3202 break; |
|
3203 case Op_Conv2B: |
3204 case Op_Conv2B: |
3204 case Op_LoadRange: |
3205 case Op_LoadRange: |
3205 case Op_LoadKlass: |
3206 case Op_LoadKlass: |
3206 case Op_LoadNKlass: |
3207 case Op_LoadNKlass: |
3207 // NONE, i.e. leave current strength as is |
3208 // Do not require barriers |
3208 break; |
3209 break; |
3209 case Op_AddP: |
3210 case Op_AddP: |
3210 case Op_CheckCastPP: |
3211 case Op_CheckCastPP: |
3211 case Op_CastPP: |
3212 case Op_CastPP: |
3212 case Op_CMoveP: |
3213 case Op_CMoveP: |
3213 case Op_Phi: |
3214 case Op_Phi: |
3214 case Op_ShenandoahLoadReferenceBarrier: |
3215 case Op_ShenandoahLoadReferenceBarrier: |
|
3216 // Whether or not these need the barriers depends on their users |
3215 visit_users = true; |
3217 visit_users = true; |
3216 break; |
3218 break; |
3217 default: { |
3219 default: { |
3218 #ifdef ASSERT |
3220 #ifdef ASSERT |
3219 tty->print_cr("Unknown node in get_barrier_strength:"); |
3221 fatal("Unknown node in get_barrier_strength: %s", NodeClassNames[n->Opcode()]); |
3220 n->dump(1); |
|
3221 ShouldNotReachHere(); |
|
3222 #else |
3222 #else |
|
3223 // Default to strong: better to have excess barriers, rather than miss some. |
3223 strength = STRONG; |
3224 strength = STRONG; |
3224 #endif |
3225 #endif |
3225 } |
3226 } |
3226 } |
3227 } |
3227 #ifdef ASSERT |
3228 |
3228 /* |
|
3229 if (strength == STRONG) { |
|
3230 tty->print("strengthening node: "); |
|
3231 n->dump(); |
|
3232 } |
|
3233 */ |
|
3234 #endif |
|
3235 stack.pop(); |
3229 stack.pop(); |
3236 if (visit_users) { |
3230 if (visit_users) { |
3237 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
3231 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
3238 Node* user = n->fast_out(i); |
3232 Node* user = n->fast_out(i); |
3239 if (user != NULL) { |
3233 if (user != NULL) { |