mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8212184: Incorrect oop ref strength used for referents in FinalReference
Reviewed-by: eosterlund, kbarrett
This commit is contained in:
parent
ca91f514d8
commit
54d4acf73f
3 changed files with 13 additions and 1 deletions
|
@ -912,6 +912,7 @@ class java_lang_ref_Reference: AllStatic {
|
||||||
static inline oop queue(oop ref);
|
static inline oop queue(oop ref);
|
||||||
static inline void set_queue(oop ref, oop value);
|
static inline void set_queue(oop ref, oop value);
|
||||||
static bool is_referent_field(oop obj, ptrdiff_t offset);
|
static bool is_referent_field(oop obj, ptrdiff_t offset);
|
||||||
|
static inline bool is_final(oop ref);
|
||||||
static inline bool is_phantom(oop ref);
|
static inline bool is_phantom(oop ref);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,9 @@ void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
|
||||||
HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
|
HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
|
||||||
return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
|
return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
|
||||||
}
|
}
|
||||||
|
bool java_lang_ref_Reference::is_final(oop ref) {
|
||||||
|
return InstanceKlass::cast(ref->klass())->reference_type() == REF_FINAL;
|
||||||
|
}
|
||||||
bool java_lang_ref_Reference::is_phantom(oop ref) {
|
bool java_lang_ref_Reference::is_phantom(oop ref) {
|
||||||
return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
|
return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,16 @@
|
||||||
#include "oops/access.hpp"
|
#include "oops/access.hpp"
|
||||||
|
|
||||||
DecoratorSet AccessBarrierSupport::resolve_unknown_oop_ref_strength(DecoratorSet decorators, oop base, ptrdiff_t offset) {
|
DecoratorSet AccessBarrierSupport::resolve_unknown_oop_ref_strength(DecoratorSet decorators, oop base, ptrdiff_t offset) {
|
||||||
|
// Note that the referent in a FinalReference is technically not strong.
|
||||||
|
// However, it always behaves like one in practice. The two cases are:
|
||||||
|
// 1) A mutator calls Reference.get(). However, a mutator can only ever
|
||||||
|
// see inactive FinalReferences, whose referents really are strong.
|
||||||
|
// 2) A GC heap walking operation. In this case the GC can see active
|
||||||
|
// FinalReferences, but the GC always wants to follow the referent
|
||||||
|
// as if it was strong.
|
||||||
DecoratorSet ds = decorators & ~ON_UNKNOWN_OOP_REF;
|
DecoratorSet ds = decorators & ~ON_UNKNOWN_OOP_REF;
|
||||||
if (!java_lang_ref_Reference::is_referent_field(base, offset)) {
|
if (!java_lang_ref_Reference::is_referent_field(base, offset) ||
|
||||||
|
java_lang_ref_Reference::is_final(base)) {
|
||||||
ds |= ON_STRONG_OOP_REF;
|
ds |= ON_STRONG_OOP_REF;
|
||||||
} else if (java_lang_ref_Reference::is_phantom(base)) {
|
} else if (java_lang_ref_Reference::is_phantom(base)) {
|
||||||
ds |= ON_PHANTOM_OOP_REF;
|
ds |= ON_PHANTOM_OOP_REF;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue