1 /* 2 * Copyright (c) 2000, 2010, 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 */ 24 25 #include "precompiled.hpp" 26 #include "gc_implementation/shared/markSweep.inline.hpp" 27 #include "gc_interface/collectedHeap.inline.hpp" 28 #include "memory/gcLocker.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "memory/universe.inline.hpp" 31 #include "oops/klassOop.hpp" 32 #include "oops/methodDataKlass.hpp" 33 #include "oops/methodDataOop.hpp" 34 #include "oops/oop.inline.hpp" 35 #include "oops/oop.inline2.hpp" 36 #include "runtime/handles.inline.hpp" 37 #ifndef SERIALGC 38 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 39 #include "oops/oop.pcgc.inline.hpp" 40 #endif 41 42 klassOop methodDataKlass::create_klass(TRAPS) { 43 methodDataKlass o; 44 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); 45 KlassHandle k = base_create_klass(h_this_klass, header_size(), 46 o.vtbl_value(), CHECK_NULL); 47 // Make sure size calculation is right 48 assert(k()->size() == align_object_size(header_size()), 49 "wrong size for object"); 50 return k(); 51 } 52 53 54 int methodDataKlass::oop_size(oop obj) const { 55 assert(obj->is_methodData(), "must be method data oop"); 56 return methodDataOop(obj)->object_size(); 57 } 58 59 60 bool methodDataKlass::oop_is_parsable(oop obj) const { 61 assert(obj->is_methodData(), "must be method data oop"); 62 return methodDataOop(obj)->object_is_parsable(); 63 } 64 65 66 methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) { 67 int size = methodDataOopDesc::compute_allocation_size_in_words(method); 68 KlassHandle h_k(THREAD, as_klassOop()); 69 methodDataOop mdo = 70 (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); 71 assert(!mdo->is_parsable(), "not expecting parsability yet."); 72 No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC 73 mdo->initialize(method); 74 75 assert(mdo->is_parsable(), "should be parsable here."); 76 assert(size == mdo->object_size(), "wrong size for methodDataOop"); 77 return mdo; 78 } 79 80 81 void methodDataKlass::oop_follow_contents(oop obj) { 82 assert (obj->is_methodData(), "object must be method data"); 83 methodDataOop m = methodDataOop(obj); 84 85 obj->follow_header(); 86 MarkSweep::mark_and_push(m->adr_method()); 87 ResourceMark rm; 88 for (ProfileData* data = m->first_data(); 89 m->is_valid(data); 90 data = m->next_data(data)) { 91 data->follow_contents(); 92 } 93 } 94 95 #ifndef SERIALGC 96 void methodDataKlass::oop_follow_contents(ParCompactionManager* cm, 97 oop obj) { 98 assert (obj->is_methodData(), "object must be method data"); 99 methodDataOop m = methodDataOop(obj); 100 101 obj->follow_header(cm); 102 PSParallelCompact::mark_and_push(cm, m->adr_method()); 103 ResourceMark rm; 104 for (ProfileData* data = m->first_data(); 105 m->is_valid(data); 106 data = m->next_data(data)) { 107 data->follow_contents(cm); 108 } 109 } 110 #endif // SERIALGC 111 112 113 int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) { 114 assert (obj->is_methodData(), "object must be method data"); 115 methodDataOop m = methodDataOop(obj); 116 // Get size before changing pointers 117 // Don't call size() or oop_size() since that is a virtual call. 118 int size = m->object_size(); 119 120 obj->oop_iterate_header(blk); 121 blk->do_oop(m->adr_method()); 122 ResourceMark rm; 123 for (ProfileData* data = m->first_data(); 124 m->is_valid(data); 125 data = m->next_data(data)) { 126 data->oop_iterate(blk); 127 } 128 return size; 129 } 130 131 int methodDataKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 132 assert (obj->is_methodData(), "object must be method data"); 133 methodDataOop m = methodDataOop(obj); 134 // Get size before changing pointers 135 // Don't call size() or oop_size() since that is a virtual call. 136 int size = m->object_size(); 137 138 obj->oop_iterate_header(blk, mr); 139 oop* adr = m->adr_method(); 140 if (mr.contains(adr)) { 141 blk->do_oop(m->adr_method()); 142 } 143 ResourceMark rm; 144 for (ProfileData* data = m->first_data(); 145 m->is_valid(data); 146 data = m->next_data(data)) { 147 data->oop_iterate_m(blk, mr); 148 } 149 return size; 150 } 151 152 int methodDataKlass::oop_adjust_pointers(oop obj) { 153 assert(obj->is_methodData(), "should be method data"); 154 methodDataOop m = methodDataOop(obj); 155 // Get size before changing pointers 156 // Don't call size() or oop_size() since that is a virtual call. 157 int size = m->object_size(); 158 159 obj->adjust_header(); 160 MarkSweep::adjust_pointer(m->adr_method()); 161 ResourceMark rm; 162 ProfileData* data; 163 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { 164 data->adjust_pointers(); 165 } 166 return size; 167 } 168 169 170 #ifndef SERIALGC 171 void methodDataKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 172 assert (obj->is_methodData(), "object must be method data"); 173 methodDataOop m = methodDataOop(obj); 174 // This should never point into the young gen. 175 assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity"); 176 } 177 178 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 179 assert(obj->is_methodData(), "should be method data"); 180 methodDataOop m = methodDataOop(obj); 181 182 PSParallelCompact::adjust_pointer(m->adr_method()); 183 184 ResourceMark rm; 185 ProfileData* data; 186 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { 187 data->update_pointers(); 188 } 189 return m->object_size(); 190 } 191 192 int 193 methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, 194 HeapWord* beg_addr, HeapWord* end_addr) { 195 assert(obj->is_methodData(), "should be method data"); 196 197 oop* p; 198 methodDataOop m = methodDataOop(obj); 199 200 p = m->adr_method(); 201 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); 202 203 ResourceMark rm; 204 ProfileData* data; 205 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { 206 data->update_pointers(beg_addr, end_addr); 207 } 208 return m->object_size(); 209 } 210 #endif // SERIALGC 211 212 #ifndef PRODUCT 213 214 // Printing 215 void methodDataKlass::oop_print_on(oop obj, outputStream* st) { 216 assert(obj->is_methodData(), "should be method data"); 217 methodDataOop m = methodDataOop(obj); 218 st->print("method data for "); 219 m->method()->print_value_on(st); 220 st->cr(); 221 m->print_data_on(st); 222 } 223 224 #endif //PRODUCT 225 226 void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) { 227 assert(obj->is_methodData(), "should be method data"); 228 methodDataOop m = methodDataOop(obj); 229 st->print("method data for "); 230 m->method()->print_value_on(st); 231 } 232 233 const char* methodDataKlass::internal_name() const { 234 return "{method data}"; 235 } 236 237 238 // Verification 239 void methodDataKlass::oop_verify_on(oop obj, outputStream* st) { 240 Klass::oop_verify_on(obj, st); 241 guarantee(obj->is_methodData(), "object must be method data"); 242 methodDataOop m = methodDataOop(obj); 243 guarantee(m->is_perm(), "should be in permspace"); 244 m->verify_data_on(st); 245 }