src/share/vm/oops/oopsHierarchy.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2658
c7f3d0b4570f
child 4037
da91efe96a93
permissions
-rw-r--r--

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

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

mercurial