Thu, 07 Apr 2011 09:53:20 -0700
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes
1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef SHARE_VM_OOPS_OOPSHIERARCHY_HPP
26 #define SHARE_VM_OOPS_OOPSHIERARCHY_HPP
28 #include "runtime/globals.hpp"
29 #include "utilities/globalDefinitions.hpp"
31 // OBJECT hierarchy
32 // This hierarchy is a representation hierarchy, i.e. if A is a superclass
33 // of B, A's representation is a prefix of B's representation.
35 typedef juint narrowOop; // Offset instead of address for an oop within a java object
36 typedef class klassOopDesc* wideKlassOop; // to keep SA happy and unhandled oop
37 // detector happy.
38 typedef void* OopOrNarrowOopStar;
40 #ifndef CHECK_UNHANDLED_OOPS
42 typedef class oopDesc* oop;
43 typedef class instanceOopDesc* instanceOop;
44 typedef class methodOopDesc* methodOop;
45 typedef class constMethodOopDesc* constMethodOop;
46 typedef class methodDataOopDesc* methodDataOop;
47 typedef class arrayOopDesc* arrayOop;
48 typedef class objArrayOopDesc* objArrayOop;
49 typedef class typeArrayOopDesc* typeArrayOop;
50 typedef class constantPoolOopDesc* constantPoolOop;
51 typedef class constantPoolCacheOopDesc* constantPoolCacheOop;
52 typedef class klassOopDesc* klassOop;
53 typedef class markOopDesc* markOop;
54 typedef class compiledICHolderOopDesc* compiledICHolderOop;
56 #else
59 // When CHECK_UNHANDLED_OOPS is defined, an "oop" is a class with a
60 // carefully chosen set of constructors and conversion operators to go
61 // to and from the underlying oopDesc pointer type.
62 //
63 // Because oop and its subclasses <type>Oop are class types, arbitrary
64 // conversions are not accepted by the compiler, and you may get a message
65 // about overloading ambiguity (between long and int is common when converting
66 // from a constant in 64 bit mode), or unable to convert from type to 'oop'.
67 // Applying a cast to one of these conversion operators first will get to the
68 // underlying oopDesc* type if appropriate.
69 // Converting NULL to oop to Handle implicit is no longer accepted by the
70 // compiler because there are too many steps in the conversion. Use Handle()
71 // instead, which generates less code anyway.
73 class Thread;
74 typedef class markOopDesc* markOop;
75 class PromotedObject;
78 class oop {
79 oopDesc* _o;
81 void register_oop();
82 void unregister_oop();
84 // friend class markOop;
85 public:
86 void set_obj(const void* p) {
87 raw_set_obj(p);
88 if (CheckUnhandledOops) register_oop();
89 }
90 void raw_set_obj(const void* p) { _o = (oopDesc*)p; }
92 oop() { set_obj(NULL); }
93 oop(const volatile oop& o) { set_obj(o.obj()); }
94 oop(const void* p) { set_obj(p); }
95 oop(intptr_t i) { set_obj((void *)i); }
96 #ifdef _LP64
97 oop(int i) { set_obj((void *)i); }
98 #endif
99 ~oop() {
100 if (CheckUnhandledOops) unregister_oop();
101 }
103 oopDesc* obj() const volatile { return _o; }
105 // General access
106 oopDesc* operator->() const { return obj(); }
107 bool operator==(const oop o) const { return obj() == o.obj(); }
108 bool operator==(void *p) const { return obj() == p; }
109 bool operator!=(const oop o) const { return obj() != o.obj(); }
110 bool operator!=(void *p) const { return obj() != p; }
111 bool operator==(intptr_t p) const { return obj() == (oopDesc*)p; }
112 bool operator!=(intptr_t p) const { return obj() != (oopDesc*)p; }
114 bool operator<(oop o) const { return obj() < o.obj(); }
115 bool operator>(oop o) const { return obj() > o.obj(); }
116 bool operator<=(oop o) const { return obj() <= o.obj(); }
117 bool operator>=(oop o) const { return obj() >= o.obj(); }
118 bool operator!() const { return !obj(); }
120 // Cast
121 operator void* () const { return (void *)obj(); }
122 operator HeapWord* () const { return (HeapWord*)obj(); }
123 operator oopDesc* () const { return obj(); }
124 operator intptr_t* () const { return (intptr_t*)obj(); }
125 operator PromotedObject* () const { return (PromotedObject*)obj(); }
126 operator markOop () const { return markOop(obj()); }
128 operator address () const { return (address)obj(); }
129 operator intptr_t () const { return (intptr_t)obj(); }
131 // from javaCalls.cpp
132 operator jobject () const { return (jobject)obj(); }
133 // from javaClasses.cpp
134 operator JavaThread* () const { return (JavaThread*)obj(); }
136 #ifndef _LP64
137 // from jvm.cpp
138 operator jlong* () const { return (jlong*)obj(); }
139 #endif
141 // from parNewGeneration and other things that want to get to the end of
142 // an oop for stuff (like constMethodKlass.cpp, objArrayKlass.cpp)
143 operator oop* () const { return (oop *)obj(); }
144 };
146 #define DEF_OOP(type) \
147 class type##OopDesc; \
148 class type##Oop : public oop { \
149 public: \
150 type##Oop() : oop() {} \
151 type##Oop(const volatile oop& o) : oop(o) {} \
152 type##Oop(const void* p) : oop(p) {} \
153 operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \
154 type##OopDesc* operator->() const { \
155 return (type##OopDesc*)obj(); \
156 } \
157 }; \
159 DEF_OOP(instance);
160 DEF_OOP(method);
161 DEF_OOP(methodData);
162 DEF_OOP(array);
163 DEF_OOP(constMethod);
164 DEF_OOP(constantPool);
165 DEF_OOP(constantPoolCache);
166 DEF_OOP(objArray);
167 DEF_OOP(typeArray);
168 DEF_OOP(klass);
169 DEF_OOP(compiledICHolder);
171 #endif // CHECK_UNHANDLED_OOPS
173 // The klass hierarchy is separate from the oop hierarchy.
175 class Klass;
176 class instanceKlass;
177 class instanceMirrorKlass;
178 class instanceRefKlass;
179 class methodKlass;
180 class constMethodKlass;
181 class methodDataKlass;
182 class klassKlass;
183 class instanceKlassKlass;
184 class arrayKlassKlass;
185 class objArrayKlassKlass;
186 class typeArrayKlassKlass;
187 class arrayKlass;
188 class objArrayKlass;
189 class typeArrayKlass;
190 class constantPoolKlass;
191 class constantPoolCacheKlass;
192 class compiledICHolderKlass;
194 #endif // SHARE_VM_OOPS_OOPSHIERARCHY_HPP