1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/methodKlass.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,361 @@ 1.4 +/* 1.5 + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_methodKlass.cpp.incl" 1.30 + 1.31 +klassOop methodKlass::create_klass(TRAPS) { 1.32 + methodKlass o; 1.33 + KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); 1.34 + KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL); 1.35 + // Make sure size calculation is right 1.36 + assert(k()->size() == align_object_size(header_size()), "wrong size for object"); 1.37 + java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror 1.38 + return k(); 1.39 +} 1.40 + 1.41 + 1.42 +int methodKlass::oop_size(oop obj) const { 1.43 + assert(obj->is_method(), "must be method oop"); 1.44 + return methodOop(obj)->object_size(); 1.45 +} 1.46 + 1.47 + 1.48 +bool methodKlass::oop_is_parsable(oop obj) const { 1.49 + assert(obj->is_method(), "must be method oop"); 1.50 + return methodOop(obj)->object_is_parsable(); 1.51 +} 1.52 + 1.53 + 1.54 +methodOop methodKlass::allocate(constMethodHandle xconst, 1.55 + AccessFlags access_flags, TRAPS) { 1.56 + int size = methodOopDesc::object_size(access_flags.is_native()); 1.57 + KlassHandle h_k(THREAD, as_klassOop()); 1.58 + assert(xconst()->is_parsable(), "possible publication protocol violation"); 1.59 + methodOop m = (methodOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); 1.60 + assert(!m->is_parsable(), "not expecting parsability yet."); 1.61 + 1.62 + No_Safepoint_Verifier no_safepoint; // until m becomes parsable below 1.63 + m->set_constMethod(xconst()); 1.64 + m->set_access_flags(access_flags); 1.65 + m->set_method_size(size); 1.66 + m->set_name_index(0); 1.67 + m->set_signature_index(0); 1.68 +#ifdef CC_INTERP 1.69 + m->set_result_index(T_VOID); 1.70 +#endif 1.71 + m->set_constants(NULL); 1.72 + m->set_max_stack(0); 1.73 + m->set_max_locals(0); 1.74 + m->clear_intrinsic_id_cache(); 1.75 + m->set_method_data(NULL); 1.76 + m->set_interpreter_throwout_count(0); 1.77 + m->set_vtable_index(methodOopDesc::garbage_vtable_index); 1.78 + 1.79 + // Fix and bury in methodOop 1.80 + m->set_interpreter_entry(NULL); // sets i2i entry and from_int 1.81 + m->set_highest_tier_compile(CompLevel_none); 1.82 + m->set_adapter_entry(NULL); 1.83 + m->clear_code(); // from_c/from_i get set to c2i/i2i 1.84 + 1.85 + if (access_flags.is_native()) { 1.86 + m->clear_native_function(); 1.87 + m->set_signature_handler(NULL); 1.88 + } 1.89 + 1.90 + NOT_PRODUCT(m->set_compiled_invocation_count(0);) 1.91 + m->set_interpreter_invocation_count(0); 1.92 + m->invocation_counter()->init(); 1.93 + m->backedge_counter()->init(); 1.94 + m->clear_number_of_breakpoints(); 1.95 + assert(m->is_parsable(), "must be parsable here."); 1.96 + assert(m->size() == size, "wrong size for object"); 1.97 + // We should not publish an uprasable object's reference 1.98 + // into one that is parsable, since that presents problems 1.99 + // for the concurrent parallel marking and precleaning phases 1.100 + // of concurrent gc (CMS). 1.101 + xconst->set_method(m); 1.102 + return m; 1.103 +} 1.104 + 1.105 + 1.106 +void methodKlass::oop_follow_contents(oop obj) { 1.107 + assert (obj->is_method(), "object must be method"); 1.108 + methodOop m = methodOop(obj); 1.109 + // Performance tweak: We skip iterating over the klass pointer since we 1.110 + // know that Universe::methodKlassObj never moves. 1.111 + MarkSweep::mark_and_push(m->adr_constMethod()); 1.112 + MarkSweep::mark_and_push(m->adr_constants()); 1.113 + if (m->method_data() != NULL) { 1.114 + MarkSweep::mark_and_push(m->adr_method_data()); 1.115 + } 1.116 +} 1.117 + 1.118 +#ifndef SERIALGC 1.119 +void methodKlass::oop_follow_contents(ParCompactionManager* cm, 1.120 + oop obj) { 1.121 + assert (obj->is_method(), "object must be method"); 1.122 + methodOop m = methodOop(obj); 1.123 + // Performance tweak: We skip iterating over the klass pointer since we 1.124 + // know that Universe::methodKlassObj never moves. 1.125 + PSParallelCompact::mark_and_push(cm, m->adr_constMethod()); 1.126 + PSParallelCompact::mark_and_push(cm, m->adr_constants()); 1.127 +#ifdef COMPILER2 1.128 + if (m->method_data() != NULL) { 1.129 + PSParallelCompact::mark_and_push(cm, m->adr_method_data()); 1.130 + } 1.131 +#endif // COMPILER2 1.132 +} 1.133 +#endif // SERIALGC 1.134 + 1.135 +int methodKlass::oop_oop_iterate(oop obj, OopClosure* blk) { 1.136 + assert (obj->is_method(), "object must be method"); 1.137 + methodOop m = methodOop(obj); 1.138 + // Get size before changing pointers. 1.139 + // Don't call size() or oop_size() since that is a virtual call. 1.140 + int size = m->object_size(); 1.141 + // Performance tweak: We skip iterating over the klass pointer since we 1.142 + // know that Universe::methodKlassObj never moves 1.143 + blk->do_oop(m->adr_constMethod()); 1.144 + blk->do_oop(m->adr_constants()); 1.145 + if (m->method_data() != NULL) { 1.146 + blk->do_oop(m->adr_method_data()); 1.147 + } 1.148 + return size; 1.149 +} 1.150 + 1.151 + 1.152 +int methodKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 1.153 + assert (obj->is_method(), "object must be method"); 1.154 + methodOop m = methodOop(obj); 1.155 + // Get size before changing pointers. 1.156 + // Don't call size() or oop_size() since that is a virtual call. 1.157 + int size = m->object_size(); 1.158 + // Performance tweak: We skip iterating over the klass pointer since we 1.159 + // know that Universe::methodKlassObj never moves. 1.160 + oop* adr; 1.161 + adr = m->adr_constMethod(); 1.162 + if (mr.contains(adr)) blk->do_oop(adr); 1.163 + adr = m->adr_constants(); 1.164 + if (mr.contains(adr)) blk->do_oop(adr); 1.165 + if (m->method_data() != NULL) { 1.166 + adr = m->adr_method_data(); 1.167 + if (mr.contains(adr)) blk->do_oop(adr); 1.168 + } 1.169 + return size; 1.170 +} 1.171 + 1.172 + 1.173 +int methodKlass::oop_adjust_pointers(oop obj) { 1.174 + assert(obj->is_method(), "should be method"); 1.175 + methodOop m = methodOop(obj); 1.176 + // Get size before changing pointers. 1.177 + // Don't call size() or oop_size() since that is a virtual call. 1.178 + int size = m->object_size(); 1.179 + // Performance tweak: We skip iterating over the klass pointer since we 1.180 + // know that Universe::methodKlassObj never moves. 1.181 + MarkSweep::adjust_pointer(m->adr_constMethod()); 1.182 + MarkSweep::adjust_pointer(m->adr_constants()); 1.183 + if (m->method_data() != NULL) { 1.184 + MarkSweep::adjust_pointer(m->adr_method_data()); 1.185 + } 1.186 + return size; 1.187 +} 1.188 + 1.189 +#ifndef SERIALGC 1.190 +void methodKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { 1.191 + assert(obj->is_method(), "should be method"); 1.192 +} 1.193 + 1.194 +void methodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 1.195 + assert(obj->is_method(), "should be method"); 1.196 +} 1.197 + 1.198 +int methodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 1.199 + assert(obj->is_method(), "should be method"); 1.200 + methodOop m = methodOop(obj); 1.201 + PSParallelCompact::adjust_pointer(m->adr_constMethod()); 1.202 + PSParallelCompact::adjust_pointer(m->adr_constants()); 1.203 +#ifdef COMPILER2 1.204 + if (m->method_data() != NULL) { 1.205 + PSParallelCompact::adjust_pointer(m->adr_method_data()); 1.206 + } 1.207 +#endif // COMPILER2 1.208 + return m->object_size(); 1.209 +} 1.210 + 1.211 +int methodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, 1.212 + HeapWord* beg_addr, HeapWord* end_addr) { 1.213 + assert(obj->is_method(), "should be method"); 1.214 + 1.215 + oop* p; 1.216 + methodOop m = methodOop(obj); 1.217 + 1.218 + p = m->adr_constMethod(); 1.219 + PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); 1.220 + p = m->adr_constants(); 1.221 + PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); 1.222 + 1.223 +#ifdef COMPILER2 1.224 + if (m->method_data() != NULL) { 1.225 + p = m->adr_method_data(); 1.226 + PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); 1.227 + } 1.228 +#endif // COMPILER2 1.229 + return m->object_size(); 1.230 +} 1.231 +#endif // SERIALGC 1.232 + 1.233 +#ifndef PRODUCT 1.234 + 1.235 +// Printing 1.236 + 1.237 +void methodKlass::oop_print_on(oop obj, outputStream* st) { 1.238 + ResourceMark rm; 1.239 + assert(obj->is_method(), "must be method"); 1.240 + Klass::oop_print_on(obj, st); 1.241 + methodOop m = methodOop(obj); 1.242 + st->print (" - method holder: "); m->method_holder()->print_value_on(st); st->cr(); 1.243 + st->print (" - constants: " INTPTR_FORMAT, " ", (address)m->constants()); 1.244 + m->constants()->print_value_on(st); st->cr(); 1.245 + st->print (" - access: 0x%x ", m->access_flags().as_int()); m->access_flags().print_on(st); st->cr(); 1.246 + st->print (" - name: "); m->name()->print_value_on(st); st->cr(); 1.247 + st->print (" - signature: "); m->signature()->print_value_on(st); st->cr(); 1.248 + st->print_cr(" - max stack: %d", m->max_stack()); 1.249 + st->print_cr(" - max locals: %d", m->max_locals()); 1.250 + st->print_cr(" - size of params: %d", m->size_of_parameters()); 1.251 + st->print_cr(" - method size: %d", m->method_size()); 1.252 + st->print_cr(" - vtable index: %d", m->_vtable_index); 1.253 + st->print_cr(" - code size: %d", m->code_size()); 1.254 + st->print_cr(" - code start: " INTPTR_FORMAT, m->code_base()); 1.255 + st->print_cr(" - code end (excl): " INTPTR_FORMAT, m->code_base() + m->code_size()); 1.256 + if (m->method_data() != NULL) { 1.257 + st->print_cr(" - method data: " INTPTR_FORMAT, (address)m->method_data()); 1.258 + } 1.259 + st->print_cr(" - checked ex length: %d", m->checked_exceptions_length()); 1.260 + if (m->checked_exceptions_length() > 0) { 1.261 + CheckedExceptionElement* table = m->checked_exceptions_start(); 1.262 + st->print_cr(" - checked ex start: " INTPTR_FORMAT, table); 1.263 + if (Verbose) { 1.264 + for (int i = 0; i < m->checked_exceptions_length(); i++) { 1.265 + st->print_cr(" - throws %s", m->constants()->printable_name_at(table[i].class_cp_index)); 1.266 + } 1.267 + } 1.268 + } 1.269 + if (m->has_linenumber_table()) { 1.270 + u_char* table = m->compressed_linenumber_table(); 1.271 + st->print_cr(" - linenumber start: " INTPTR_FORMAT, table); 1.272 + if (Verbose) { 1.273 + CompressedLineNumberReadStream stream(table); 1.274 + while (stream.read_pair()) { 1.275 + st->print_cr(" - line %d: %d", stream.line(), stream.bci()); 1.276 + } 1.277 + } 1.278 + } 1.279 + st->print_cr(" - localvar length: %d", m->localvariable_table_length()); 1.280 + if (m->localvariable_table_length() > 0) { 1.281 + LocalVariableTableElement* table = m->localvariable_table_start(); 1.282 + st->print_cr(" - localvar start: " INTPTR_FORMAT, table); 1.283 + if (Verbose) { 1.284 + for (int i = 0; i < m->localvariable_table_length(); i++) { 1.285 + int bci = table[i].start_bci; 1.286 + int len = table[i].length; 1.287 + const char* name = m->constants()->printable_name_at(table[i].name_cp_index); 1.288 + const char* desc = m->constants()->printable_name_at(table[i].descriptor_cp_index); 1.289 + int slot = table[i].slot; 1.290 + st->print_cr(" - %s %s bci=%d len=%d slot=%d", desc, name, bci, len, slot); 1.291 + } 1.292 + } 1.293 + } 1.294 + if (m->code() != NULL) { 1.295 + st->print (" - compiled code: "); 1.296 + m->code()->print_value_on(st); 1.297 + st->cr(); 1.298 + } 1.299 +} 1.300 + 1.301 + 1.302 +void methodKlass::oop_print_value_on(oop obj, outputStream* st) { 1.303 + assert(obj->is_method(), "must be method"); 1.304 + Klass::oop_print_value_on(obj, st); 1.305 + methodOop m = methodOop(obj); 1.306 + st->print(" "); 1.307 + m->name()->print_value_on(st); 1.308 + st->print(" "); 1.309 + m->signature()->print_value_on(st); 1.310 + st->print(" in "); 1.311 + m->method_holder()->print_value_on(st); 1.312 + if (WizardMode) st->print("[%d,%d]", m->size_of_parameters(), m->max_locals()); 1.313 + if (WizardMode && m->code() != NULL) st->print(" ((nmethod*)%p)", m->code()); 1.314 +} 1.315 + 1.316 +#endif // PRODUCT 1.317 + 1.318 +const char* methodKlass::internal_name() const { 1.319 + return "{method}"; 1.320 +} 1.321 + 1.322 + 1.323 +// Verification 1.324 + 1.325 +void methodKlass::oop_verify_on(oop obj, outputStream* st) { 1.326 + Klass::oop_verify_on(obj, st); 1.327 + guarantee(obj->is_method(), "object must be method"); 1.328 + if (!obj->partially_loaded()) { 1.329 + methodOop m = methodOop(obj); 1.330 + guarantee(m->is_perm(), "should be in permspace"); 1.331 + guarantee(m->name()->is_perm(), "should be in permspace"); 1.332 + guarantee(m->name()->is_symbol(), "should be symbol"); 1.333 + guarantee(m->signature()->is_perm(), "should be in permspace"); 1.334 + guarantee(m->signature()->is_symbol(), "should be symbol"); 1.335 + guarantee(m->constants()->is_perm(), "should be in permspace"); 1.336 + guarantee(m->constants()->is_constantPool(), "should be constant pool"); 1.337 + guarantee(m->constMethod()->is_constMethod(), "should be constMethodOop"); 1.338 + guarantee(m->constMethod()->is_perm(), "should be in permspace"); 1.339 + methodDataOop method_data = m->method_data(); 1.340 + guarantee(method_data == NULL || 1.341 + method_data->is_perm(), "should be in permspace"); 1.342 + guarantee(method_data == NULL || 1.343 + method_data->is_methodData(), "should be method data"); 1.344 + } 1.345 +} 1.346 + 1.347 +bool methodKlass::oop_partially_loaded(oop obj) const { 1.348 + assert(obj->is_method(), "object must be method"); 1.349 + methodOop m = methodOop(obj); 1.350 + constMethodOop xconst = m->constMethod(); 1.351 + assert(xconst != NULL, "const method must be set"); 1.352 + constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); 1.353 + return ck->oop_partially_loaded(xconst); 1.354 +} 1.355 + 1.356 + 1.357 +void methodKlass::oop_set_partially_loaded(oop obj) { 1.358 + assert(obj->is_method(), "object must be method"); 1.359 + methodOop m = methodOop(obj); 1.360 + constMethodOop xconst = m->constMethod(); 1.361 + assert(xconst != NULL, "const method must be set"); 1.362 + constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); 1.363 + ck->oop_set_partially_loaded(xconst); 1.364 +}