1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/cpCacheOop.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,449 @@ 1.4 +/* 1.5 + * Copyright 1998-2006 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/_cpCacheOop.cpp.incl" 1.30 + 1.31 + 1.32 +// Implememtation of ConstantPoolCacheEntry 1.33 + 1.34 +void ConstantPoolCacheEntry::set_initial_state(int index) { 1.35 + assert(0 <= index && index < 0x10000, "sanity check"); 1.36 + _indices = index; 1.37 +} 1.38 + 1.39 + 1.40 +int ConstantPoolCacheEntry::as_flags(TosState state, bool is_final, 1.41 + bool is_vfinal, bool is_volatile, 1.42 + bool is_method_interface, bool is_method) { 1.43 + int f = state; 1.44 + 1.45 + assert( state < number_of_states, "Invalid state in as_flags"); 1.46 + 1.47 + f <<= 1; 1.48 + if (is_final) f |= 1; 1.49 + f <<= 1; 1.50 + if (is_vfinal) f |= 1; 1.51 + f <<= 1; 1.52 + if (is_volatile) f |= 1; 1.53 + f <<= 1; 1.54 + if (is_method_interface) f |= 1; 1.55 + f <<= 1; 1.56 + if (is_method) f |= 1; 1.57 + f <<= ConstantPoolCacheEntry::hotSwapBit; 1.58 + // Preserve existing flag bit values 1.59 +#ifdef ASSERT 1.60 + int old_state = ((_flags >> tosBits) & 0x0F); 1.61 + assert(old_state == 0 || old_state == state, 1.62 + "inconsistent cpCache flags state"); 1.63 +#endif 1.64 + return (_flags | f) ; 1.65 +} 1.66 + 1.67 +void ConstantPoolCacheEntry::set_bytecode_1(Bytecodes::Code code) { 1.68 +#ifdef ASSERT 1.69 + // Read once. 1.70 + volatile Bytecodes::Code c = bytecode_1(); 1.71 + assert(c == 0 || c == code || code == 0, "update must be consistent"); 1.72 +#endif 1.73 + // Need to flush pending stores here before bytecode is written. 1.74 + OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << 16)); 1.75 +} 1.76 + 1.77 +void ConstantPoolCacheEntry::set_bytecode_2(Bytecodes::Code code) { 1.78 +#ifdef ASSERT 1.79 + // Read once. 1.80 + volatile Bytecodes::Code c = bytecode_2(); 1.81 + assert(c == 0 || c == code || code == 0, "update must be consistent"); 1.82 +#endif 1.83 + // Need to flush pending stores here before bytecode is written. 1.84 + OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << 24)); 1.85 +} 1.86 + 1.87 +#ifdef ASSERT 1.88 +// It is possible to have two different dummy methodOops created 1.89 +// when the resolve code for invoke interface executes concurrently 1.90 +// Hence the assertion below is weakened a bit for the invokeinterface 1.91 +// case. 1.92 +bool ConstantPoolCacheEntry::same_methodOop(oop cur_f1, oop f1) { 1.93 + return (cur_f1 == f1 || ((methodOop)cur_f1)->name() == 1.94 + ((methodOop)f1)->name() || ((methodOop)cur_f1)->signature() == 1.95 + ((methodOop)f1)->signature()); 1.96 +} 1.97 +#endif 1.98 + 1.99 +// Note that concurrent update of both bytecodes can leave one of them 1.100 +// reset to zero. This is harmless; the interpreter will simply re-resolve 1.101 +// the damaged entry. More seriously, the memory synchronization is needed 1.102 +// to flush other fields (f1, f2) completely to memory before the bytecodes 1.103 +// are updated, lest other processors see a non-zero bytecode but zero f1/f2. 1.104 +void ConstantPoolCacheEntry::set_field(Bytecodes::Code get_code, 1.105 + Bytecodes::Code put_code, 1.106 + KlassHandle field_holder, 1.107 + int orig_field_index, 1.108 + int field_offset, 1.109 + TosState field_type, 1.110 + bool is_final, 1.111 + bool is_volatile) { 1.112 + set_f1(field_holder()); 1.113 + set_f2(field_offset); 1.114 + // The field index is used by jvm/ti and is the index into fields() array 1.115 + // in holder instanceKlass. This is scaled by instanceKlass::next_offset. 1.116 + assert((orig_field_index % instanceKlass::next_offset) == 0, "wierd index"); 1.117 + const int field_index = orig_field_index / instanceKlass::next_offset; 1.118 + assert(field_index <= field_index_mask, 1.119 + "field index does not fit in low flag bits"); 1.120 + set_flags(as_flags(field_type, is_final, false, is_volatile, false, false) | 1.121 + (field_index & field_index_mask)); 1.122 + set_bytecode_1(get_code); 1.123 + set_bytecode_2(put_code); 1.124 + NOT_PRODUCT(verify(tty)); 1.125 +} 1.126 + 1.127 +int ConstantPoolCacheEntry::field_index() const { 1.128 + return (_flags & field_index_mask) * instanceKlass::next_offset; 1.129 +} 1.130 + 1.131 +void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, 1.132 + methodHandle method, 1.133 + int vtable_index) { 1.134 + 1.135 + assert(method->interpreter_entry() != NULL, "should have been set at this point"); 1.136 + assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); 1.137 + bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface); 1.138 + 1.139 + int byte_no = -1; 1.140 + bool needs_vfinal_flag = false; 1.141 + switch (invoke_code) { 1.142 + case Bytecodes::_invokevirtual: 1.143 + case Bytecodes::_invokeinterface: { 1.144 + if (method->can_be_statically_bound()) { 1.145 + set_f2((intptr_t)method()); 1.146 + needs_vfinal_flag = true; 1.147 + } else { 1.148 + assert(vtable_index >= 0, "valid index"); 1.149 + set_f2(vtable_index); 1.150 + } 1.151 + byte_no = 2; 1.152 + break; 1.153 + } 1.154 + case Bytecodes::_invokespecial: 1.155 + // Preserve the value of the vfinal flag on invokevirtual bytecode 1.156 + // which may be shared with this constant pool cache entry. 1.157 + needs_vfinal_flag = is_resolved(Bytecodes::_invokevirtual) && is_vfinal(); 1.158 + // fall through 1.159 + case Bytecodes::_invokestatic: 1.160 + set_f1(method()); 1.161 + byte_no = 1; 1.162 + break; 1.163 + default: 1.164 + ShouldNotReachHere(); 1.165 + break; 1.166 + } 1.167 + 1.168 + set_flags(as_flags(as_TosState(method->result_type()), 1.169 + method->is_final_method(), 1.170 + needs_vfinal_flag, 1.171 + false, 1.172 + change_to_virtual, 1.173 + true)| 1.174 + method()->size_of_parameters()); 1.175 + 1.176 + // Note: byte_no also appears in TemplateTable::resolve. 1.177 + if (byte_no == 1) { 1.178 + set_bytecode_1(invoke_code); 1.179 + } else if (byte_no == 2) { 1.180 + if (change_to_virtual) { 1.181 + // NOTE: THIS IS A HACK - BE VERY CAREFUL!!! 1.182 + // 1.183 + // Workaround for the case where we encounter an invokeinterface, but we 1.184 + // should really have an _invokevirtual since the resolved method is a 1.185 + // virtual method in java.lang.Object. This is a corner case in the spec 1.186 + // but is presumably legal. javac does not generate this code. 1.187 + // 1.188 + // We set bytecode_1() to _invokeinterface, because that is the 1.189 + // bytecode # used by the interpreter to see if it is resolved. 1.190 + // We set bytecode_2() to _invokevirtual. 1.191 + // See also interpreterRuntime.cpp. (8/25/2000) 1.192 + // Only set resolved for the invokeinterface case if method is public. 1.193 + // Otherwise, the method needs to be reresolved with caller for each 1.194 + // interface call. 1.195 + if (method->is_public()) set_bytecode_1(invoke_code); 1.196 + set_bytecode_2(Bytecodes::_invokevirtual); 1.197 + } else { 1.198 + set_bytecode_2(invoke_code); 1.199 + } 1.200 + } else { 1.201 + ShouldNotReachHere(); 1.202 + } 1.203 + NOT_PRODUCT(verify(tty)); 1.204 +} 1.205 + 1.206 + 1.207 +void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { 1.208 + klassOop interf = method->method_holder(); 1.209 + assert(instanceKlass::cast(interf)->is_interface(), "must be an interface"); 1.210 + set_f1(interf); 1.211 + set_f2(index); 1.212 + set_flags(as_flags(as_TosState(method->result_type()), method->is_final_method(), false, false, false, true) | method()->size_of_parameters()); 1.213 + set_bytecode_1(Bytecodes::_invokeinterface); 1.214 +} 1.215 + 1.216 + 1.217 +class LocalOopClosure: public OopClosure { 1.218 + private: 1.219 + void (*_f)(oop*); 1.220 + 1.221 + public: 1.222 + LocalOopClosure(void f(oop*)) { _f = f; } 1.223 + virtual void do_oop(oop* o) { _f(o); } 1.224 +}; 1.225 + 1.226 + 1.227 +void ConstantPoolCacheEntry::oops_do(void f(oop*)) { 1.228 + LocalOopClosure blk(f); 1.229 + oop_iterate(&blk); 1.230 +} 1.231 + 1.232 + 1.233 +void ConstantPoolCacheEntry::oop_iterate(OopClosure* blk) { 1.234 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.235 + // field[1] is always oop or NULL 1.236 + blk->do_oop((oop*)&_f1); 1.237 + if (is_vfinal()) { 1.238 + blk->do_oop((oop*)&_f2); 1.239 + } 1.240 +} 1.241 + 1.242 + 1.243 +void ConstantPoolCacheEntry::oop_iterate_m(OopClosure* blk, MemRegion mr) { 1.244 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.245 + // field[1] is always oop or NULL 1.246 + if (mr.contains((oop *)&_f1)) blk->do_oop((oop*)&_f1); 1.247 + if (is_vfinal()) { 1.248 + if (mr.contains((oop *)&_f2)) blk->do_oop((oop*)&_f2); 1.249 + } 1.250 +} 1.251 + 1.252 + 1.253 +void ConstantPoolCacheEntry::follow_contents() { 1.254 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.255 + // field[1] is always oop or NULL 1.256 + MarkSweep::mark_and_push((oop*)&_f1); 1.257 + if (is_vfinal()) { 1.258 + MarkSweep::mark_and_push((oop*)&_f2); 1.259 + } 1.260 +} 1.261 + 1.262 +#ifndef SERIALGC 1.263 +void ConstantPoolCacheEntry::follow_contents(ParCompactionManager* cm) { 1.264 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.265 + // field[1] is always oop or NULL 1.266 + PSParallelCompact::mark_and_push(cm, (oop*)&_f1); 1.267 + if (is_vfinal()) { 1.268 + PSParallelCompact::mark_and_push(cm, (oop*)&_f2); 1.269 + } 1.270 +} 1.271 +#endif // SERIALGC 1.272 + 1.273 +void ConstantPoolCacheEntry::adjust_pointers() { 1.274 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.275 + // field[1] is always oop or NULL 1.276 + MarkSweep::adjust_pointer((oop*)&_f1); 1.277 + if (is_vfinal()) { 1.278 + MarkSweep::adjust_pointer((oop*)&_f2); 1.279 + } 1.280 +} 1.281 + 1.282 +#ifndef SERIALGC 1.283 +void ConstantPoolCacheEntry::update_pointers() { 1.284 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.285 + // field[1] is always oop or NULL 1.286 + PSParallelCompact::adjust_pointer((oop*)&_f1); 1.287 + if (is_vfinal()) { 1.288 + PSParallelCompact::adjust_pointer((oop*)&_f2); 1.289 + } 1.290 +} 1.291 + 1.292 +void ConstantPoolCacheEntry::update_pointers(HeapWord* beg_addr, 1.293 + HeapWord* end_addr) { 1.294 + assert(in_words(size()) == 4, "check code below - may need adjustment"); 1.295 + // field[1] is always oop or NULL 1.296 + PSParallelCompact::adjust_pointer((oop*)&_f1, beg_addr, end_addr); 1.297 + if (is_vfinal()) { 1.298 + PSParallelCompact::adjust_pointer((oop*)&_f2, beg_addr, end_addr); 1.299 + } 1.300 +} 1.301 +#endif // SERIALGC 1.302 + 1.303 +// RedefineClasses() API support: 1.304 +// If this constantPoolCacheEntry refers to old_method then update it 1.305 +// to refer to new_method. 1.306 +bool ConstantPoolCacheEntry::adjust_method_entry(methodOop old_method, 1.307 + methodOop new_method, bool * trace_name_printed) { 1.308 + 1.309 + if (is_vfinal()) { 1.310 + // virtual and final so f2() contains method ptr instead of vtable index 1.311 + if (f2() == (intptr_t)old_method) { 1.312 + // match old_method so need an update 1.313 + _f2 = (intptr_t)new_method; 1.314 + if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { 1.315 + if (!(*trace_name_printed)) { 1.316 + // RC_TRACE_MESG macro has an embedded ResourceMark 1.317 + RC_TRACE_MESG(("adjust: name=%s", 1.318 + Klass::cast(old_method->method_holder())->external_name())); 1.319 + *trace_name_printed = true; 1.320 + } 1.321 + // RC_TRACE macro has an embedded ResourceMark 1.322 + RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)", 1.323 + new_method->name()->as_C_string(), 1.324 + new_method->signature()->as_C_string())); 1.325 + } 1.326 + 1.327 + return true; 1.328 + } 1.329 + 1.330 + // f1() is not used with virtual entries so bail out 1.331 + return false; 1.332 + } 1.333 + 1.334 + if ((oop)_f1 == NULL) { 1.335 + // NULL f1() means this is a virtual entry so bail out 1.336 + // We are assuming that the vtable index does not need change. 1.337 + return false; 1.338 + } 1.339 + 1.340 + if ((oop)_f1 == old_method) { 1.341 + _f1 = new_method; 1.342 + if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { 1.343 + if (!(*trace_name_printed)) { 1.344 + // RC_TRACE_MESG macro has an embedded ResourceMark 1.345 + RC_TRACE_MESG(("adjust: name=%s", 1.346 + Klass::cast(old_method->method_holder())->external_name())); 1.347 + *trace_name_printed = true; 1.348 + } 1.349 + // RC_TRACE macro has an embedded ResourceMark 1.350 + RC_TRACE(0x00400000, ("cpc entry update: %s(%s)", 1.351 + new_method->name()->as_C_string(), 1.352 + new_method->signature()->as_C_string())); 1.353 + } 1.354 + 1.355 + return true; 1.356 + } 1.357 + 1.358 + return false; 1.359 +} 1.360 + 1.361 +bool ConstantPoolCacheEntry::is_interesting_method_entry(klassOop k) { 1.362 + if (!is_method_entry()) { 1.363 + // not a method entry so not interesting by default 1.364 + return false; 1.365 + } 1.366 + 1.367 + methodOop m = NULL; 1.368 + if (is_vfinal()) { 1.369 + // virtual and final so _f2 contains method ptr instead of vtable index 1.370 + m = (methodOop)_f2; 1.371 + } else if ((oop)_f1 == NULL) { 1.372 + // NULL _f1 means this is a virtual entry so also not interesting 1.373 + return false; 1.374 + } else { 1.375 + if (!((oop)_f1)->is_method()) { 1.376 + // _f1 can also contain a klassOop for an interface 1.377 + return false; 1.378 + } 1.379 + m = (methodOop)_f1; 1.380 + } 1.381 + 1.382 + assert(m != NULL && m->is_method(), "sanity check"); 1.383 + if (m == NULL || !m->is_method() || m->method_holder() != k) { 1.384 + // robustness for above sanity checks or method is not in 1.385 + // the interesting class 1.386 + return false; 1.387 + } 1.388 + 1.389 + // the method is in the interesting class so the entry is interesting 1.390 + return true; 1.391 +} 1.392 + 1.393 +void ConstantPoolCacheEntry::print(outputStream* st, int index) const { 1.394 + // print separator 1.395 + if (index == 0) tty->print_cr(" -------------"); 1.396 + // print entry 1.397 + tty->print_cr("%3d (%08x) [%02x|%02x|%5d]", index, this, bytecode_2(), bytecode_1(), constant_pool_index()); 1.398 + tty->print_cr(" [ %08x]", (address)(oop)_f1); 1.399 + tty->print_cr(" [ %08x]", _f2); 1.400 + tty->print_cr(" [ %08x]", _flags); 1.401 + tty->print_cr(" -------------"); 1.402 +} 1.403 + 1.404 +void ConstantPoolCacheEntry::verify(outputStream* st) const { 1.405 + // not implemented yet 1.406 +} 1.407 + 1.408 +// Implementation of ConstantPoolCache 1.409 + 1.410 +void constantPoolCacheOopDesc::initialize(intArray& inverse_index_map) { 1.411 + assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache"); 1.412 + for (int i = 0; i < length(); i++) entry_at(i)->set_initial_state(inverse_index_map[i]); 1.413 +} 1.414 + 1.415 +// RedefineClasses() API support: 1.416 +// If any entry of this constantPoolCache points to any of 1.417 +// old_methods, replace it with the corresponding new_method. 1.418 +void constantPoolCacheOopDesc::adjust_method_entries(methodOop* old_methods, methodOop* new_methods, 1.419 + int methods_length, bool * trace_name_printed) { 1.420 + 1.421 + if (methods_length == 0) { 1.422 + // nothing to do if there are no methods 1.423 + return; 1.424 + } 1.425 + 1.426 + // get shorthand for the interesting class 1.427 + klassOop old_holder = old_methods[0]->method_holder(); 1.428 + 1.429 + for (int i = 0; i < length(); i++) { 1.430 + if (!entry_at(i)->is_interesting_method_entry(old_holder)) { 1.431 + // skip uninteresting methods 1.432 + continue; 1.433 + } 1.434 + 1.435 + // The constantPoolCache contains entries for several different 1.436 + // things, but we only care about methods. In fact, we only care 1.437 + // about methods in the same class as the one that contains the 1.438 + // old_methods. At this point, we have an interesting entry. 1.439 + 1.440 + for (int j = 0; j < methods_length; j++) { 1.441 + methodOop old_method = old_methods[j]; 1.442 + methodOop new_method = new_methods[j]; 1.443 + 1.444 + if (entry_at(i)->adjust_method_entry(old_method, new_method, 1.445 + trace_name_printed)) { 1.446 + // current old_method matched this entry and we updated it so 1.447 + // break out and get to the next interesting entry if there one 1.448 + break; 1.449 + } 1.450 + } 1.451 + } 1.452 +}