src/share/vm/oops/objArrayKlassKlass.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 3682
fc9d8850ab8b
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 /*
stefank@2534 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 #include "precompiled.hpp"
stefank@2314 26 #include "classfile/javaClasses.hpp"
stefank@2314 27 #include "classfile/systemDictionary.hpp"
stefank@2314 28 #include "gc_implementation/shared/markSweep.inline.hpp"
stefank@2314 29 #include "gc_interface/collectedHeap.inline.hpp"
stefank@2314 30 #include "oops/instanceKlass.hpp"
stefank@2314 31 #include "oops/objArrayKlassKlass.hpp"
stefank@2314 32 #include "oops/oop.inline.hpp"
stefank@2314 33 #include "oops/oop.inline2.hpp"
never@2658 34 #ifndef SERIALGC
never@2658 35 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
never@2658 36 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
never@2658 37 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
never@2658 38 #include "memory/cardTableRS.hpp"
never@2658 39 #include "oops/oop.pcgc.inline.hpp"
never@2658 40 #endif
duke@435 41
duke@435 42 klassOop objArrayKlassKlass::create_klass(TRAPS) {
duke@435 43 objArrayKlassKlass o;
duke@435 44 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
duke@435 45 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_0);
duke@435 46 assert(k()->size() == align_object_size(header_size()), "wrong size for object");
duke@435 47 java_lang_Class::create_mirror(k, CHECK_0); // Allocate mirror
duke@435 48 return k();
duke@435 49 }
duke@435 50
duke@435 51 klassOop objArrayKlassKlass::allocate_system_objArray_klass(TRAPS) {
duke@435 52 // system_objArrays have no instance klass, so allocate with fake class, then reset to NULL
duke@435 53 KlassHandle kk(THREAD, Universe::intArrayKlassObj());
duke@435 54 klassOop k = allocate_objArray_klass(1, kk, CHECK_0);
duke@435 55 objArrayKlass* tk = (objArrayKlass*) k->klass_part();
duke@435 56 tk->set_element_klass(NULL);
duke@435 57 tk->set_bottom_klass(NULL);
duke@435 58 return k;
duke@435 59 }
duke@435 60
duke@435 61
duke@435 62 klassOop objArrayKlassKlass::allocate_objArray_klass(int n, KlassHandle element_klass, TRAPS) {
duke@435 63 objArrayKlassKlassHandle this_oop(THREAD, as_klassOop());
duke@435 64 return allocate_objArray_klass_impl(this_oop, n, element_klass, THREAD);
duke@435 65 }
duke@435 66
duke@435 67 klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHandle this_oop,
duke@435 68 int n, KlassHandle element_klass, TRAPS) {
duke@435 69
duke@435 70 // Eagerly allocate the direct array supertype.
duke@435 71 KlassHandle super_klass = KlassHandle();
duke@435 72 if (!Universe::is_bootstrapping()) {
duke@435 73 KlassHandle element_super (THREAD, element_klass->super());
duke@435 74 if (element_super.not_null()) {
duke@435 75 // The element type has a direct super. E.g., String[] has direct super of Object[].
duke@435 76 super_klass = KlassHandle(THREAD, element_super->array_klass_or_null());
duke@435 77 bool supers_exist = super_klass.not_null();
duke@435 78 // Also, see if the element has secondary supertypes.
duke@435 79 // We need an array type for each.
duke@435 80 objArrayHandle element_supers = objArrayHandle(THREAD,
duke@435 81 element_klass->secondary_supers());
duke@435 82 for( int i = element_supers->length()-1; i >= 0; i-- ) {
duke@435 83 klassOop elem_super = (klassOop) element_supers->obj_at(i);
duke@435 84 if (Klass::cast(elem_super)->array_klass_or_null() == NULL) {
duke@435 85 supers_exist = false;
duke@435 86 break;
duke@435 87 }
duke@435 88 }
duke@435 89 if (!supers_exist) {
duke@435 90 // Oops. Not allocated yet. Back out, allocate it, and retry.
duke@435 91 #ifndef PRODUCT
duke@435 92 if (WizardMode) {
duke@435 93 tty->print_cr("Must retry array klass creation for depth %d",n);
duke@435 94 }
duke@435 95 #endif
duke@435 96 KlassHandle ek;
duke@435 97 {
duke@435 98 MutexUnlocker mu(MultiArray_lock);
duke@435 99 MutexUnlocker mc(Compile_lock); // for vtables
duke@435 100 klassOop sk = element_super->array_klass(CHECK_0);
duke@435 101 super_klass = KlassHandle(THREAD, sk);
duke@435 102 for( int i = element_supers->length()-1; i >= 0; i-- ) {
duke@435 103 KlassHandle elem_super (THREAD, element_supers->obj_at(i));
duke@435 104 elem_super->array_klass(CHECK_0);
duke@435 105 }
duke@435 106 // Now retry from the beginning
duke@435 107 klassOop klass_oop = element_klass->array_klass(n, CHECK_0);
duke@435 108 // Create a handle because the enclosing brace, when locking
duke@435 109 // can cause a gc. Better to have this function return a Handle.
duke@435 110 ek = KlassHandle(THREAD, klass_oop);
duke@435 111 } // re-lock
duke@435 112 return ek();
duke@435 113 }
duke@435 114 } else {
duke@435 115 // The element type is already Object. Object[] has direct super of Object.
never@1577 116 super_klass = KlassHandle(THREAD, SystemDictionary::Object_klass());
duke@435 117 }
duke@435 118 }
duke@435 119
coleenp@2497 120 // Create type name for klass.
coleenp@2497 121 Symbol* name = NULL;
coleenp@2497 122 if (!element_klass->oop_is_instance() ||
coleenp@2497 123 (name = instanceKlass::cast(element_klass())->array_name()) == NULL) {
duke@435 124
duke@435 125 ResourceMark rm(THREAD);
duke@435 126 char *name_str = element_klass->name()->as_C_string();
duke@435 127 int len = element_klass->name()->utf8_length();
duke@435 128 char *new_str = NEW_RESOURCE_ARRAY(char, len + 4);
duke@435 129 int idx = 0;
duke@435 130 new_str[idx++] = '[';
duke@435 131 if (element_klass->oop_is_instance()) { // it could be an array or simple type
duke@435 132 new_str[idx++] = 'L';
duke@435 133 }
duke@435 134 memcpy(&new_str[idx], name_str, len * sizeof(char));
duke@435 135 idx += len;
duke@435 136 if (element_klass->oop_is_instance()) {
duke@435 137 new_str[idx++] = ';';
duke@435 138 }
duke@435 139 new_str[idx++] = '\0';
coleenp@2497 140 name = SymbolTable::new_symbol(new_str, CHECK_0);
coleenp@2497 141 if (element_klass->oop_is_instance()) {
coleenp@2497 142 instanceKlass* ik = instanceKlass::cast(element_klass());
coleenp@2497 143 ik->set_array_name(name);
coleenp@2497 144 }
duke@435 145 }
duke@435 146
duke@435 147 objArrayKlass o;
duke@435 148 arrayKlassHandle k = arrayKlass::base_create_array_klass(o.vtbl_value(),
duke@435 149 objArrayKlass::header_size(),
duke@435 150 this_oop,
duke@435 151 CHECK_0);
duke@435 152
duke@435 153 // Initialize instance variables
duke@435 154 objArrayKlass* oak = objArrayKlass::cast(k());
duke@435 155 oak->set_dimension(n);
duke@435 156 oak->set_element_klass(element_klass());
coleenp@2497 157 oak->set_name(name);
coleenp@2497 158 // decrement refcount because object arrays are not explicitly freed. The
coleenp@2497 159 // instanceKlass array_name() keeps the name counted while the klass is
coleenp@2497 160 // loaded.
coleenp@2497 161 name->decrement_refcount();
duke@435 162
duke@435 163 klassOop bk;
duke@435 164 if (element_klass->oop_is_objArray()) {
duke@435 165 bk = objArrayKlass::cast(element_klass())->bottom_klass();
duke@435 166 } else {
duke@435 167 bk = element_klass();
duke@435 168 }
duke@435 169 assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass");
duke@435 170 oak->set_bottom_klass(bk);
duke@435 171
duke@435 172 oak->set_layout_helper(array_layout_helper(T_OBJECT));
duke@435 173 assert(oak->oop_is_javaArray(), "sanity");
duke@435 174 assert(oak->oop_is_objArray(), "sanity");
duke@435 175
duke@435 176 // Call complete_create_array_klass after all instance variables has been initialized.
duke@435 177 arrayKlass::complete_create_array_klass(k, super_klass, CHECK_0);
duke@435 178
duke@435 179 return k();
duke@435 180 }
duke@435 181
duke@435 182
duke@435 183 void objArrayKlassKlass::oop_follow_contents(oop obj) {
duke@435 184 assert(obj->is_klass(), "must be klass");
duke@435 185 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
duke@435 186
duke@435 187 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 188 MarkSweep::mark_and_push(oak->element_klass_addr());
duke@435 189 MarkSweep::mark_and_push(oak->bottom_klass_addr());
duke@435 190
duke@435 191 arrayKlassKlass::oop_follow_contents(obj);
duke@435 192 }
duke@435 193
duke@435 194 #ifndef SERIALGC
duke@435 195 void objArrayKlassKlass::oop_follow_contents(ParCompactionManager* cm,
duke@435 196 oop obj) {
duke@435 197 assert(obj->is_klass(), "must be klass");
duke@435 198 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
duke@435 199
duke@435 200 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 201 PSParallelCompact::mark_and_push(cm, oak->element_klass_addr());
duke@435 202 PSParallelCompact::mark_and_push(cm, oak->bottom_klass_addr());
duke@435 203
duke@435 204 arrayKlassKlass::oop_follow_contents(cm, obj);
duke@435 205 }
duke@435 206 #endif // SERIALGC
duke@435 207
duke@435 208
duke@435 209 int objArrayKlassKlass::oop_adjust_pointers(oop obj) {
duke@435 210 assert(obj->is_klass(), "must be klass");
duke@435 211 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
duke@435 212
duke@435 213 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 214 MarkSweep::adjust_pointer(oak->element_klass_addr());
duke@435 215 MarkSweep::adjust_pointer(oak->bottom_klass_addr());
duke@435 216
duke@435 217 return arrayKlassKlass::oop_adjust_pointers(obj);
duke@435 218 }
duke@435 219
duke@435 220
duke@435 221
duke@435 222 int objArrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
duke@435 223 assert(obj->is_klass(), "must be klass");
duke@435 224 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
duke@435 225
duke@435 226 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 227 blk->do_oop(oak->element_klass_addr());
duke@435 228 blk->do_oop(oak->bottom_klass_addr());
duke@435 229
duke@435 230 return arrayKlassKlass::oop_oop_iterate(obj, blk);
duke@435 231 }
duke@435 232
duke@435 233
duke@435 234 int
duke@435 235 objArrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
duke@435 236 assert(obj->is_klass(), "must be klass");
duke@435 237 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
duke@435 238
duke@435 239 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 240 oop* addr;
duke@435 241 addr = oak->element_klass_addr();
duke@435 242 if (mr.contains(addr)) blk->do_oop(addr);
duke@435 243 addr = oak->bottom_klass_addr();
duke@435 244 if (mr.contains(addr)) blk->do_oop(addr);
duke@435 245
never@2658 246 return arrayKlassKlass::oop_oop_iterate_m(obj, blk, mr);
duke@435 247 }
duke@435 248
duke@435 249 #ifndef SERIALGC
duke@435 250 void objArrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
duke@435 251 assert(obj->blueprint()->oop_is_objArrayKlass(),"must be an obj array klass");
never@2658 252 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
never@2658 253 oop* p = oak->element_klass_addr();
never@2658 254 if (PSScavenge::should_scavenge(p)) {
never@2658 255 pm->claim_or_forward_depth(p);
never@2658 256 }
never@2658 257 p = oak->bottom_klass_addr();
never@2658 258 if (PSScavenge::should_scavenge(p)) {
never@2658 259 pm->claim_or_forward_depth(p);
never@2658 260 }
never@2658 261
never@2658 262 arrayKlassKlass::oop_push_contents(pm, obj);
duke@435 263 }
duke@435 264
duke@435 265 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
duke@435 266 assert(obj->is_klass(), "must be klass");
duke@435 267 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
duke@435 268
duke@435 269 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 270 PSParallelCompact::adjust_pointer(oak->element_klass_addr());
duke@435 271 PSParallelCompact::adjust_pointer(oak->bottom_klass_addr());
duke@435 272
duke@435 273 return arrayKlassKlass::oop_update_pointers(cm, obj);
duke@435 274 }
duke@435 275 #endif // SERIALGC
duke@435 276
duke@435 277 #ifndef PRODUCT
duke@435 278
duke@435 279 // Printing
duke@435 280
duke@435 281 void objArrayKlassKlass::oop_print_on(oop obj, outputStream* st) {
duke@435 282 assert(obj->is_klass(), "must be klass");
duke@435 283 objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part();
duke@435 284 klassKlass::oop_print_on(obj, st);
duke@435 285 st->print(" - instance klass: ");
duke@435 286 oak->element_klass()->print_value_on(st);
duke@435 287 st->cr();
duke@435 288 }
duke@435 289
jrose@1590 290 #endif //PRODUCT
duke@435 291
duke@435 292 void objArrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) {
duke@435 293 assert(obj->is_klass(), "must be klass");
duke@435 294 objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part();
duke@435 295
duke@435 296 oak->element_klass()->print_value_on(st);
duke@435 297 st->print("[]");
duke@435 298 }
duke@435 299
duke@435 300 const char* objArrayKlassKlass::internal_name() const {
duke@435 301 return "{object array class}";
duke@435 302 }
duke@435 303
duke@435 304
duke@435 305 // Verification
duke@435 306
duke@435 307 void objArrayKlassKlass::oop_verify_on(oop obj, outputStream* st) {
never@2658 308 arrayKlassKlass::oop_verify_on(obj, st);
duke@435 309 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
duke@435 310 guarantee(oak->element_klass()->is_perm(), "should be in permspace");
duke@435 311 guarantee(oak->element_klass()->is_klass(), "should be klass");
duke@435 312 guarantee(oak->bottom_klass()->is_perm(), "should be in permspace");
duke@435 313 guarantee(oak->bottom_klass()->is_klass(), "should be klass");
duke@435 314 Klass* bk = Klass::cast(oak->bottom_klass());
duke@435 315 guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass");
duke@435 316 }

mercurial