comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 6615:09aad8452938

7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops Summary: In C2 add software membar after load from Reference.referent field to prevent commoning of loads across safepoint since GC can change its value. In C1 always generate Reference.get() intrinsic. Reviewed-by: roland, twisti, dholmes, johnc
author kvn
date Mon, 20 Aug 2012 09:58:58 -0700
parents 977007096840
children 7a302948f5a4
comparison
equal deleted inserted replaced
6614:006050192a5a 6615:09aad8452938
3056 break; 3056 break;
3057 } 3057 }
3058 3058
3059 case vmIntrinsics::_Reference_get: 3059 case vmIntrinsics::_Reference_get:
3060 { 3060 {
3061 if (UseG1GC) { 3061 {
3062 // With java.lang.ref.reference.get() we must go through the 3062 // With java.lang.ref.reference.get() we must go through the
3063 // intrinsic - when G1 is enabled - even when get() is the root 3063 // intrinsic - when G1 is enabled - even when get() is the root
3064 // method of the compile so that, if necessary, the value in 3064 // method of the compile so that, if necessary, the value in
3065 // the referent field of the reference object gets recorded by 3065 // the referent field of the reference object gets recorded by
3066 // the pre-barrier code. 3066 // the pre-barrier code.
3068 // field is recorded by the G1 SATB pre barrier. This will 3068 // field is recorded by the G1 SATB pre barrier. This will
3069 // result in the referent being marked live and the reference 3069 // result in the referent being marked live and the reference
3070 // object removed from the list of discovered references during 3070 // object removed from the list of discovered references during
3071 // reference processing. 3071 // reference processing.
3072 3072
3073 // Also we need intrinsic to prevent commoning reads from this field
3074 // across safepoint since GC can change its value.
3075
3073 // Set up a stream so that appending instructions works properly. 3076 // Set up a stream so that appending instructions works properly.
3074 ciBytecodeStream s(scope->method()); 3077 ciBytecodeStream s(scope->method());
3075 s.reset_to_bci(0); 3078 s.reset_to_bci(0);
3076 scope_data()->set_stream(&s); 3079 scope_data()->set_stream(&s);
3077 s.next(); 3080 s.next();
3224 return NULL; 3227 return NULL;
3225 } 3228 }
3226 3229
3227 3230
3228 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { 3231 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
3229 if (!InlineNatives ) INLINE_BAILOUT("intrinsic method inlining disabled");
3230 if (callee->is_synchronized()) { 3232 if (callee->is_synchronized()) {
3231 // We don't currently support any synchronized intrinsics 3233 // We don't currently support any synchronized intrinsics
3232 return false; 3234 return false;
3233 } 3235 }
3234 3236
3235 // callee seems like a good candidate 3237 // callee seems like a good candidate
3236 // determine id 3238 // determine id
3239 vmIntrinsics::ID id = callee->intrinsic_id();
3240 if (!InlineNatives && id != vmIntrinsics::_Reference_get) {
3241 // InlineNatives does not control Reference.get
3242 INLINE_BAILOUT("intrinsic method inlining disabled");
3243 }
3237 bool preserves_state = false; 3244 bool preserves_state = false;
3238 bool cantrap = true; 3245 bool cantrap = true;
3239 vmIntrinsics::ID id = callee->intrinsic_id();
3240 switch (id) { 3246 switch (id) {
3241 case vmIntrinsics::_arraycopy: 3247 case vmIntrinsics::_arraycopy:
3242 if (!InlineArrayCopy) return false; 3248 if (!InlineArrayCopy) return false;
3243 break; 3249 break;
3244 3250
3374 case vmIntrinsics::_compareAndSwapObject: 3380 case vmIntrinsics::_compareAndSwapObject:
3375 append_unsafe_CAS(callee); 3381 append_unsafe_CAS(callee);
3376 return true; 3382 return true;
3377 3383
3378 case vmIntrinsics::_Reference_get: 3384 case vmIntrinsics::_Reference_get:
3379 // It is only when G1 is enabled that we absolutely 3385 // Use the intrinsic version of Reference.get() so that the value in
3380 // need to use the intrinsic version of Reference.get() 3386 // the referent field can be registered by the G1 pre-barrier code.
3381 // so that the value in the referent field, if necessary, 3387 // Also to prevent commoning reads from this field across safepoint
3382 // can be registered by the pre-barrier code. 3388 // since GC can change its value.
3383 if (!UseG1GC) return false;
3384 preserves_state = true; 3389 preserves_state = true;
3385 break; 3390 break;
3386 3391
3387 default : return false; // do not inline 3392 default : return false; // do not inline
3388 } 3393 }