ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const { if (_entries.length() == 0) { return _orig; } ConstantPool* cp = ConstantPool::allocate( _orig->pool_holder()->class_loader_data(), _orig->length() + _entries.length(), CHECK_NULL); cp->set_pool_holder(_orig->pool_holder()); _orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL); for (int i = 0; i < _entries.length(); ++i) { BytecodeCPEntry entry = _entries.at(i); int idx = i + _orig->length(); switch (entry._tag) { case BytecodeCPEntry::UTF8: entry._u.utf8->increment_refcount(); cp->symbol_at_put(idx, entry._u.utf8); break; case BytecodeCPEntry::KLASS: cp->unresolved_klass_at_put( idx, cp->symbol_at(entry._u.klass)); break; case BytecodeCPEntry::STRING: cp->unresolved_string_at_put( idx, cp->symbol_at(entry._u.string)); break; case BytecodeCPEntry::NAME_AND_TYPE: cp->name_and_type_at_put(idx, entry._u.name_and_type.name_index, entry._u.name_and_type.type_index); break; case BytecodeCPEntry::METHODREF: cp->method_at_put(idx, entry._u.methodref.class_index, entry._u.methodref.name_and_type_index); break; default: ShouldNotReachHere(); } } return cp; }
static void switchover_constant_pool(BytecodeConstantPool* bpool, InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPS) { if (new_methods->length() > 0) { ConstantPool* cp = bpool->create_constant_pool(CHECK); if (cp != klass->constants()) { klass->class_loader_data()->add_to_deallocate_list(klass->constants()); klass->set_constants(cp); cp->set_pool_holder(klass); for (int i = 0; i < new_methods->length(); ++i) { new_methods->at(i)->set_constants(cp); } for (int i = 0; i < klass->methods()->length(); ++i) { Method* mo = klass->methods()->at(i); mo->set_constants(cp); } } } }