src/share/vm/oops/arrayKlassKlass.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
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 "gc_implementation/shared/markSweep.inline.hpp"
stefank@2314 28 #include "oops/arrayKlassKlass.hpp"
stefank@2314 29 #include "oops/oop.inline.hpp"
stefank@2314 30 #include "runtime/handles.inline.hpp"
never@2658 31 #ifndef SERIALGC
never@2658 32 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
never@2658 33 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
never@2658 34 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
never@2658 35 #include "memory/cardTableRS.hpp"
never@2658 36 #include "oops/oop.pcgc.inline.hpp"
never@2658 37 #endif
duke@435 38
duke@435 39
duke@435 40 klassOop arrayKlassKlass::create_klass(TRAPS) {
duke@435 41 arrayKlassKlass o;
duke@435 42 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
duke@435 43 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
duke@435 44 // Make sure size calculation is right
duke@435 45 assert(k()->size() == align_object_size(header_size()), "wrong size for object");
duke@435 46 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror, make links
duke@435 47 return k();
duke@435 48 }
duke@435 49
duke@435 50 bool arrayKlassKlass::oop_is_parsable(oop obj) const {
duke@435 51 assert(obj->is_klass(), "must be klass");
duke@435 52 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 53 return (!ak->null_vtbl()) && ak->object_is_parsable();
duke@435 54 }
duke@435 55
duke@435 56 void arrayKlassKlass::oop_follow_contents(oop obj) {
duke@435 57 assert(obj->is_klass(), "must be klass");
duke@435 58 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 59 MarkSweep::mark_and_push(ak->adr_component_mirror());
duke@435 60 MarkSweep::mark_and_push(ak->adr_lower_dimension());
duke@435 61 MarkSweep::mark_and_push(ak->adr_higher_dimension());
duke@435 62 {
duke@435 63 HandleMark hm;
duke@435 64 ak->vtable()->oop_follow_contents();
duke@435 65 }
duke@435 66 klassKlass::oop_follow_contents(obj);
duke@435 67 }
duke@435 68
duke@435 69 #ifndef SERIALGC
duke@435 70 void arrayKlassKlass::oop_follow_contents(ParCompactionManager* cm,
duke@435 71 oop obj) {
duke@435 72 assert(obj->is_klass(), "must be klass");
duke@435 73 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 74 PSParallelCompact::mark_and_push(cm, ak->adr_component_mirror());
duke@435 75 PSParallelCompact::mark_and_push(cm, ak->adr_lower_dimension());
duke@435 76 PSParallelCompact::mark_and_push(cm, ak->adr_higher_dimension());
duke@435 77 {
duke@435 78 HandleMark hm;
duke@435 79 ak->vtable()->oop_follow_contents(cm);
duke@435 80 }
duke@435 81 klassKlass::oop_follow_contents(cm, obj);
duke@435 82 }
duke@435 83 #endif // SERIALGC
duke@435 84
duke@435 85
duke@435 86 int arrayKlassKlass::oop_adjust_pointers(oop obj) {
duke@435 87 assert(obj->is_klass(), "must be klass");
duke@435 88 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 89 MarkSweep::adjust_pointer(ak->adr_component_mirror());
duke@435 90 MarkSweep::adjust_pointer(ak->adr_lower_dimension());
duke@435 91 MarkSweep::adjust_pointer(ak->adr_higher_dimension());
duke@435 92 {
duke@435 93 HandleMark hm;
duke@435 94 ak->vtable()->oop_adjust_pointers();
duke@435 95 }
duke@435 96 return klassKlass::oop_adjust_pointers(obj);
duke@435 97 }
duke@435 98
duke@435 99
duke@435 100 int arrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
duke@435 101 assert(obj->is_klass(), "must be klass");
duke@435 102 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 103 blk->do_oop(ak->adr_component_mirror());
duke@435 104 blk->do_oop(ak->adr_lower_dimension());
duke@435 105 blk->do_oop(ak->adr_higher_dimension());
duke@435 106 ak->vtable()->oop_oop_iterate(blk);
duke@435 107 return klassKlass::oop_oop_iterate(obj, blk);
duke@435 108 }
duke@435 109
duke@435 110
duke@435 111 int arrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
duke@435 112 assert(obj->is_klass(), "must be klass");
duke@435 113 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
never@2658 114 oop* addr = ak->adr_component_mirror();
never@2658 115 if (mr.contains(addr)) blk->do_oop(addr);
never@2658 116 addr = ak->adr_lower_dimension();
never@2658 117 if (mr.contains(addr)) blk->do_oop(addr);
never@2658 118 addr = ak->adr_higher_dimension();
never@2658 119 if (mr.contains(addr)) blk->do_oop(addr);
duke@435 120 ak->vtable()->oop_oop_iterate_m(blk, mr);
duke@435 121 return klassKlass::oop_oop_iterate_m(obj, blk, mr);
duke@435 122 }
duke@435 123
duke@435 124 #ifndef SERIALGC
duke@435 125 void arrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
duke@435 126 assert(obj->blueprint()->oop_is_arrayKlass(),"must be an array klass");
never@2658 127 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
never@2658 128 oop* p = ak->adr_component_mirror();
never@2658 129 if (PSScavenge::should_scavenge(p)) {
never@2658 130 pm->claim_or_forward_depth(p);
never@2658 131 }
never@2658 132 klassKlass::oop_push_contents(pm, obj);
duke@435 133 }
duke@435 134
duke@435 135 int arrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
duke@435 136 assert(obj->is_klass(), "must be klass");
duke@435 137 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 138 PSParallelCompact::adjust_pointer(ak->adr_component_mirror());
duke@435 139 PSParallelCompact::adjust_pointer(ak->adr_lower_dimension());
duke@435 140 PSParallelCompact::adjust_pointer(ak->adr_higher_dimension());
duke@435 141 {
duke@435 142 HandleMark hm;
duke@435 143 ak->vtable()->oop_update_pointers(cm);
duke@435 144 }
duke@435 145 return klassKlass::oop_update_pointers(cm, obj);
duke@435 146 }
duke@435 147 #endif // SERIALGC
duke@435 148
duke@435 149 // Printing
duke@435 150
duke@435 151 void arrayKlassKlass::oop_print_on(oop obj, outputStream* st) {
duke@435 152 assert(obj->is_klass(), "must be klass");
duke@435 153 klassKlass::oop_print_on(obj, st);
duke@435 154 }
duke@435 155
duke@435 156 void arrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) {
duke@435 157 assert(obj->is_klass(), "must be klass");
duke@435 158 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 159 for(int index = 0; index < ak->dimension(); index++) {
duke@435 160 st->print("[]");
duke@435 161 }
duke@435 162 }
duke@435 163
duke@435 164
duke@435 165 const char* arrayKlassKlass::internal_name() const {
duke@435 166 return "{array class}";
duke@435 167 }
duke@435 168
duke@435 169 void arrayKlassKlass::oop_verify_on(oop obj, outputStream* st) {
duke@435 170 klassKlass::oop_verify_on(obj, st);
duke@435 171
duke@435 172 arrayKlass* ak = arrayKlass::cast(klassOop(obj));
duke@435 173 if (!obj->partially_loaded()) {
duke@435 174 if (ak->component_mirror() != NULL)
duke@435 175 guarantee(ak->component_mirror()->klass(), "should have a class");
duke@435 176 if (ak->lower_dimension() != NULL)
duke@435 177 guarantee(ak->lower_dimension()->klass(), "should have a class");
duke@435 178 if (ak->higher_dimension() != NULL)
duke@435 179 guarantee(ak->higher_dimension()->klass(), "should have a class");
duke@435 180 }
duke@435 181 }

mercurial