src/share/vm/oops/instanceMirrorKlass.cpp

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 3205
e5928e7dab26
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

never@2658 1 /*
never@2658 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
never@2658 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
never@2658 4 *
never@2658 5 * This code is free software; you can redistribute it and/or modify it
never@2658 6 * under the terms of the GNU General Public License version 2 only, as
never@2658 7 * published by the Free Software Foundation.
never@2658 8 *
never@2658 9 * This code is distributed in the hope that it will be useful, but WITHOUT
never@2658 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
never@2658 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
never@2658 12 * version 2 for more details (a copy is included in the LICENSE file that
never@2658 13 * accompanied this code).
never@2658 14 *
never@2658 15 * You should have received a copy of the GNU General Public License version
never@2658 16 * 2 along with this work; if not, write to the Free Software Foundation,
never@2658 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
never@2658 18 *
never@2658 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
never@2658 20 * or visit www.oracle.com if you need additional information or have any
never@2658 21 * questions.
never@2658 22 *
never@2658 23 */
never@2658 24
never@2658 25 #include "precompiled.hpp"
never@2658 26 #include "classfile/javaClasses.hpp"
never@2658 27 #include "classfile/systemDictionary.hpp"
never@2658 28 #include "gc_implementation/shared/markSweep.inline.hpp"
never@2658 29 #include "gc_interface/collectedHeap.inline.hpp"
never@2658 30 #include "memory/genOopClosures.inline.hpp"
never@2658 31 #include "memory/oopFactory.hpp"
never@2658 32 #include "memory/permGen.hpp"
never@2658 33 #include "oops/instanceKlass.hpp"
never@2658 34 #include "oops/instanceMirrorKlass.hpp"
never@2658 35 #include "oops/instanceOop.hpp"
never@2658 36 #include "oops/oop.inline.hpp"
never@2658 37 #include "oops/symbol.hpp"
never@2658 38 #include "runtime/handles.inline.hpp"
never@2658 39 #ifndef SERIALGC
never@2658 40 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
never@2658 41 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
never@2658 42 #include "gc_implementation/g1/g1RemSet.inline.hpp"
never@2658 43 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
never@2658 44 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
never@2658 45 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
never@2658 46 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
never@2658 47 #include "oops/oop.pcgc.inline.hpp"
never@2658 48 #endif
never@2658 49
never@2658 50 int instanceMirrorKlass::_offset_of_static_fields = 0;
never@2658 51
never@2658 52 #ifdef ASSERT
never@2658 53 template <class T> void assert_is_in(T *p) {
never@2658 54 T heap_oop = oopDesc::load_heap_oop(p);
never@2658 55 if (!oopDesc::is_null(heap_oop)) {
never@2658 56 oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
never@2658 57 assert(Universe::heap()->is_in(o), "should be in heap");
never@2658 58 }
never@2658 59 }
never@2658 60 template <class T> void assert_is_in_closed_subset(T *p) {
never@2658 61 T heap_oop = oopDesc::load_heap_oop(p);
never@2658 62 if (!oopDesc::is_null(heap_oop)) {
never@2658 63 oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
never@2658 64 assert(Universe::heap()->is_in_closed_subset(o), "should be in closed");
never@2658 65 }
never@2658 66 }
never@2658 67 template <class T> void assert_is_in_reserved(T *p) {
never@2658 68 T heap_oop = oopDesc::load_heap_oop(p);
never@2658 69 if (!oopDesc::is_null(heap_oop)) {
never@2658 70 oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
never@2658 71 assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
never@2658 72 }
never@2658 73 }
never@2658 74 template <class T> void assert_nothing(T *p) {}
never@2658 75
never@2658 76 #else
never@2658 77 template <class T> void assert_is_in(T *p) {}
never@2658 78 template <class T> void assert_is_in_closed_subset(T *p) {}
never@2658 79 template <class T> void assert_is_in_reserved(T *p) {}
never@2658 80 template <class T> void assert_nothing(T *p) {}
never@2658 81 #endif // ASSERT
never@2658 82
never@2658 83 #define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \
never@2658 84 T, start_p, count, do_oop, \
never@2658 85 assert_fn) \
never@2658 86 { \
never@2658 87 T* p = (T*)(start_p); \
never@2658 88 T* const end = p + (count); \
never@2658 89 while (p < end) { \
never@2658 90 (assert_fn)(p); \
never@2658 91 do_oop; \
never@2658 92 ++p; \
never@2658 93 } \
never@2658 94 }
never@2658 95
never@2658 96 #define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
never@2658 97 T, start_p, count, low, high, \
never@2658 98 do_oop, assert_fn) \
never@2658 99 { \
never@2658 100 T* const l = (T*)(low); \
never@2658 101 T* const h = (T*)(high); \
never@2658 102 assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
never@2658 103 mask_bits((intptr_t)h, sizeof(T)-1) == 0, \
never@2658 104 "bounded region must be properly aligned"); \
never@2658 105 T* p = (T*)(start_p); \
never@2658 106 T* end = p + (count); \
never@2658 107 if (p < l) p = l; \
never@2658 108 if (end > h) end = h; \
never@2658 109 while (p < end) { \
never@2658 110 (assert_fn)(p); \
never@2658 111 do_oop; \
never@2658 112 ++p; \
never@2658 113 } \
never@2658 114 }
never@2658 115
never@2658 116
never@2658 117 #define InstanceMirrorKlass_OOP_ITERATE(start_p, count, \
never@2658 118 do_oop, assert_fn) \
never@2658 119 { \
never@2658 120 if (UseCompressedOops) { \
never@2658 121 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
never@2658 122 start_p, count, \
never@2658 123 do_oop, assert_fn) \
never@2658 124 } else { \
never@2658 125 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop, \
never@2658 126 start_p, count, \
never@2658 127 do_oop, assert_fn) \
never@2658 128 } \
never@2658 129 }
never@2658 130
never@2658 131 // The following macros call specialized macros, passing either oop or
never@2658 132 // narrowOop as the specialization type. These test the UseCompressedOops
never@2658 133 // flag.
never@2658 134 #define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \
never@2658 135 do_oop, assert_fn) \
never@2658 136 { \
never@2658 137 if (UseCompressedOops) { \
never@2658 138 InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
never@2658 139 start_p, count, \
never@2658 140 low, high, \
never@2658 141 do_oop, assert_fn) \
never@2658 142 } else { \
never@2658 143 InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \
never@2658 144 start_p, count, \
never@2658 145 low, high, \
never@2658 146 do_oop, assert_fn) \
never@2658 147 } \
never@2658 148 }
never@2658 149
never@2658 150
never@2658 151 void instanceMirrorKlass::oop_follow_contents(oop obj) {
never@2658 152 instanceKlass::oop_follow_contents(obj);
never@2658 153 InstanceMirrorKlass_OOP_ITERATE( \
never@2658 154 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
never@2658 155 MarkSweep::mark_and_push(p), \
never@2658 156 assert_is_in_closed_subset)
never@2658 157 }
never@2658 158
never@2658 159 #ifndef SERIALGC
never@2658 160 void instanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
never@2658 161 oop obj) {
never@2658 162 instanceKlass::oop_follow_contents(cm, obj);
never@2658 163 InstanceMirrorKlass_OOP_ITERATE( \
never@2658 164 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
never@2658 165 PSParallelCompact::mark_and_push(cm, p), \
never@2658 166 assert_is_in)
never@2658 167 }
never@2658 168 #endif // SERIALGC
never@2658 169
never@2658 170 int instanceMirrorKlass::oop_adjust_pointers(oop obj) {
never@2658 171 int size = oop_size(obj);
never@2658 172 instanceKlass::oop_adjust_pointers(obj);
never@2658 173 InstanceMirrorKlass_OOP_ITERATE( \
never@2658 174 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
never@2658 175 MarkSweep::adjust_pointer(p), \
never@2658 176 assert_nothing)
never@2658 177 return size;
never@2658 178 }
never@2658 179
never@2658 180 #define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix) \
never@2658 181 InstanceMirrorKlass_OOP_ITERATE( \
never@2658 182 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
never@2658 183 (closure)->do_oop##nv_suffix(p), \
never@2658 184 assert_is_in_closed_subset) \
never@2658 185 return oop_size(obj); \
never@2658 186
never@2658 187 #define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr) \
never@2658 188 InstanceMirrorKlass_BOUNDED_OOP_ITERATE( \
never@2658 189 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
never@2658 190 mr.start(), mr.end(), \
never@2658 191 (closure)->do_oop##nv_suffix(p), \
never@2658 192 assert_is_in_closed_subset) \
never@2658 193 return oop_size(obj); \
never@2658 194
never@2658 195
never@2658 196 // Macro to define instanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for
never@2658 197 // all closures. Macros calling macros above for each oop size.
never@2658 198
never@2658 199 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
never@2658 200 \
never@2658 201 int instanceMirrorKlass:: \
never@2658 202 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
never@2658 203 /* Get size before changing pointers */ \
never@2658 204 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
never@2658 205 \
never@2658 206 instanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \
never@2658 207 \
never@2658 208 if (UseCompressedOops) { \
never@2658 209 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \
never@2658 210 } else { \
never@2658 211 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
never@2658 212 } \
never@2658 213 }
never@2658 214
never@2658 215 #ifndef SERIALGC
never@2658 216 #define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
never@2658 217 \
never@2658 218 int instanceMirrorKlass:: \
never@2658 219 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \
never@2658 220 /* Get size before changing pointers */ \
never@2658 221 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
never@2658 222 \
never@2658 223 instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
never@2658 224 \
never@2658 225 if (UseCompressedOops) { \
never@2658 226 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \
never@2658 227 } else { \
never@2658 228 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
never@2658 229 } \
never@2658 230 }
never@2658 231 #endif // !SERIALGC
never@2658 232
never@2658 233
never@2658 234 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
never@2658 235 \
never@2658 236 int instanceMirrorKlass:: \
never@2658 237 oop_oop_iterate##nv_suffix##_m(oop obj, \
never@2658 238 OopClosureType* closure, \
never@2658 239 MemRegion mr) { \
never@2658 240 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \
never@2658 241 \
never@2658 242 instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \
never@2658 243 if (UseCompressedOops) { \
never@2658 244 InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr); \
never@2658 245 } else { \
never@2658 246 InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr); \
never@2658 247 } \
never@2658 248 }
never@2658 249
never@2658 250 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
never@2658 251 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
never@2658 252 #ifndef SERIALGC
never@2658 253 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
never@2658 254 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
never@2658 255 #endif // SERIALGC
never@2658 256 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
never@2658 257 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
never@2658 258
never@2658 259 #ifndef SERIALGC
never@2658 260 void instanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
never@2658 261 instanceKlass::oop_push_contents(pm, obj);
never@2658 262 InstanceMirrorKlass_OOP_ITERATE( \
never@2658 263 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
never@2658 264 if (PSScavenge::should_scavenge(p)) { \
never@2658 265 pm->claim_or_forward_depth(p); \
never@2658 266 }, \
never@2658 267 assert_nothing )
never@2658 268 }
never@2658 269
never@2658 270 int instanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
never@2658 271 instanceKlass::oop_update_pointers(cm, obj);
never@2658 272 InstanceMirrorKlass_OOP_ITERATE( \
never@2658 273 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
never@2658 274 PSParallelCompact::adjust_pointer(p), \
never@2658 275 assert_nothing)
never@2658 276 return oop_size(obj);
never@2658 277 }
never@2658 278 #endif // SERIALGC
never@2658 279
never@2658 280 int instanceMirrorKlass::instance_size(KlassHandle k) {
never@2658 281 if (k() != NULL && k->oop_is_instance()) {
never@2658 282 return align_object_size(size_helper() + instanceKlass::cast(k())->static_field_size());
never@2658 283 }
never@2658 284 return size_helper();
never@2658 285 }
never@2658 286
never@2658 287 instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
never@2658 288 // Query before forming handle.
never@2658 289 int size = instance_size(k);
never@2658 290 KlassHandle h_k(THREAD, as_klassOop());
never@2658 291 instanceOop i;
never@2658 292
never@2658 293 if (JavaObjectsInPerm) {
never@2658 294 i = (instanceOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
never@2658 295 } else {
never@2658 296 assert(ScavengeRootsInCode > 0, "must be");
never@2658 297 i = (instanceOop) CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
never@2658 298 }
never@2658 299
never@2658 300 return i;
never@2658 301 }
never@2658 302
never@2658 303 int instanceMirrorKlass::oop_size(oop obj) const {
never@2658 304 return java_lang_Class::oop_size(obj);
never@2658 305 }
never@2658 306
never@2658 307 int instanceMirrorKlass::compute_static_oop_field_count(oop obj) {
never@2658 308 klassOop k = java_lang_Class::as_klassOop(obj);
never@2658 309 if (k != NULL && k->klass_part()->oop_is_instance()) {
never@2658 310 return instanceKlass::cast(k)->static_oop_field_count();
never@2658 311 }
never@2658 312 return 0;
never@2658 313 }

mercurial