Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/oops/constantPool.cpp
32285 views
/*1* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/classLoaderData.hpp"26#include "classfile/javaClasses.hpp"27#include "classfile/metadataOnStackMark.hpp"28#include "classfile/symbolTable.hpp"29#include "classfile/systemDictionary.hpp"30#include "classfile/vmSymbols.hpp"31#include "interpreter/linkResolver.hpp"32#include "memory/heapInspection.hpp"33#include "memory/metadataFactory.hpp"34#include "memory/oopFactory.hpp"35#include "oops/constantPool.hpp"36#include "oops/instanceKlass.hpp"37#include "oops/objArrayKlass.hpp"38#include "runtime/fieldType.hpp"39#include "runtime/init.hpp"40#include "runtime/javaCalls.hpp"41#include "runtime/signature.hpp"42#include "runtime/vframe.hpp"4344PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC4546ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {47// Tags are RW but comment below applies to tags also.48Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL);4950int size = ConstantPool::size(length);5152// CDS considerations:53// Allocate read-write but may be able to move to read-only at dumping time54// if all the klasses are resolved. The only other field that is writable is55// the resolved_references array, which is recreated at startup time.56// But that could be moved to InstanceKlass (although a pain to access from57// assembly code). Maybe it could be moved to the cpCache which is RW.58return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);59}6061ConstantPool::ConstantPool(Array<u1>* tags) {62set_length(tags->length());63set_tags(NULL);64set_cache(NULL);65set_reference_map(NULL);66set_resolved_references(NULL);67set_operands(NULL);68set_pool_holder(NULL);69set_flags(0);7071// only set to non-zero if constant pool is merged by RedefineClasses72set_version(0);73set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock"));7475// initialize tag array76int length = tags->length();77for (int index = 0; index < length; index++) {78tags->at_put(index, JVM_CONSTANT_Invalid);79}80set_tags(tags);81}8283void ConstantPool::deallocate_contents(ClassLoaderData* loader_data) {84MetadataFactory::free_metadata(loader_data, cache());85set_cache(NULL);86MetadataFactory::free_array<u2>(loader_data, reference_map());87set_reference_map(NULL);8889MetadataFactory::free_array<jushort>(loader_data, operands());90set_operands(NULL);9192release_C_heap_structures();9394// free tag array95MetadataFactory::free_array<u1>(loader_data, tags());96set_tags(NULL);97}9899void ConstantPool::release_C_heap_structures() {100// walk constant pool and decrement symbol reference counts101unreference_symbols();102103delete _lock;104set_lock(NULL);105}106107objArrayOop ConstantPool::resolved_references() const {108return (objArrayOop)JNIHandles::resolve(_resolved_references);109}110111// Called from outside constant pool resolution where a resolved_reference array112// may not be present.113objArrayOop ConstantPool::resolved_references_or_null() const {114if (_cache == NULL) {115return NULL;116} else {117return (objArrayOop)JNIHandles::resolve(_resolved_references);118}119}120121// Create resolved_references array and mapping array for original cp indexes122// The ldc bytecode was rewritten to have the resolved reference array index so need a way123// to map it back for resolving and some unlikely miscellaneous uses.124// The objects created by invokedynamic are appended to this list.125void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,126intStack reference_map,127int constant_pool_map_length,128TRAPS) {129// Initialized the resolved object cache.130int map_length = reference_map.length();131if (map_length > 0) {132// Only need mapping back to constant pool entries. The map isn't used for133// invokedynamic resolved_reference entries. For invokedynamic entries,134// the constant pool cache index has the mapping back to both the constant135// pool and to the resolved reference index.136if (constant_pool_map_length > 0) {137Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK);138139for (int i = 0; i < constant_pool_map_length; i++) {140int x = reference_map.at(i);141assert(x == (int)(jushort) x, "klass index is too big");142om->at_put(i, (jushort)x);143}144set_reference_map(om);145}146147// Create Java array for holding resolved strings, methodHandles,148// methodTypes, invokedynamic and invokehandle appendix objects, etc.149objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);150Handle refs_handle (THREAD, (oop)stom); // must handleize.151set_resolved_references(loader_data->add_handle(refs_handle));152}153}154155// CDS support. Create a new resolved_references array.156void ConstantPool::restore_unshareable_info(TRAPS) {157158// Only create the new resolved references array and lock if it hasn't been159// attempted before160if (resolved_references() != NULL) return;161162// restore the C++ vtable from the shared archive163restore_vtable();164165if (SystemDictionary::Object_klass_loaded()) {166// Recreate the object array and add to ClassLoaderData.167int map_length = resolved_reference_length();168if (map_length > 0) {169objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);170Handle refs_handle (THREAD, (oop)stom); // must handleize.171172ClassLoaderData* loader_data = pool_holder()->class_loader_data();173set_resolved_references(loader_data->add_handle(refs_handle));174}175176// Also need to recreate the mutex. Make sure this matches the constructor177set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock"));178}179}180181void ConstantPool::remove_unshareable_info() {182// Resolved references are not in the shared archive.183// Save the length for restoration. It is not necessarily the same length184// as reference_map.length() if invokedynamic is saved.185set_resolved_reference_length(186resolved_references() != NULL ? resolved_references()->length() : 0);187set_resolved_references(NULL);188set_lock(NULL);189}190191int ConstantPool::cp_to_object_index(int cp_index) {192// this is harder don't do this so much.193int i = reference_map()->find(cp_index);194// We might not find the index for jsr292 call.195return (i < 0) ? _no_index_sentinel : i;196}197198Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {199// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.200// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and201// tag is not updated atomicly.202203CPSlot entry = this_oop->slot_at(which);204if (entry.is_resolved()) {205assert(entry.get_klass()->is_klass(), "must be");206// Already resolved - return entry.207return entry.get_klass();208}209210// Acquire lock on constant oop while doing update. After we get the lock, we check if another object211// already has updated the object212assert(THREAD->is_Java_thread(), "must be a Java thread");213bool do_resolve = false;214bool in_error = false;215216// Create a handle for the mirror. This will preserve the resolved class217// until the loader_data is registered.218Handle mirror_handle;219220Symbol* name = NULL;221Handle loader;222{ MonitorLockerEx ml(this_oop->lock());223224if (this_oop->tag_at(which).is_unresolved_klass()) {225if (this_oop->tag_at(which).is_unresolved_klass_in_error()) {226in_error = true;227} else {228do_resolve = true;229name = this_oop->unresolved_klass_at(which);230loader = Handle(THREAD, this_oop->pool_holder()->class_loader());231}232}233} // unlocking constantPool234235236// The original attempt to resolve this constant pool entry failed so find the237// class of the original error and throw another error of the same class (JVMS 5.4.3).238// If there is a detail message, pass that detail message to the error constructor.239// The JVMS does not strictly require us to duplicate the same detail message,240// or any internal exception fields such as cause or stacktrace. But since the241// detail message is often a class name or other literal string, we will repeat it if242// we can find it in the symbol table.243if (in_error) {244throw_resolution_error(this_oop, which, CHECK_0);245}246247if (do_resolve) {248// this_oop must be unlocked during resolve_or_fail249oop protection_domain = this_oop->pool_holder()->protection_domain();250Handle h_prot (THREAD, protection_domain);251Klass* k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);252KlassHandle k;253if (!HAS_PENDING_EXCEPTION) {254k = KlassHandle(THREAD, k_oop);255// preserve the resolved klass.256mirror_handle = Handle(THREAD, k_oop->java_mirror());257// Do access check for klasses258verify_constant_pool_resolve(this_oop, k, THREAD);259}260261// Failed to resolve class. We must record the errors so that subsequent attempts262// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).263if (HAS_PENDING_EXCEPTION) {264MonitorLockerEx ml(this_oop->lock());265266// some other thread has beaten us and has resolved the class.267if (this_oop->tag_at(which).is_klass()) {268CLEAR_PENDING_EXCEPTION;269entry = this_oop->resolved_klass_at(which);270return entry.get_klass();271}272273// The tag could have changed to in-error before the lock but we have to274// handle that here for the class case.275save_and_throw_exception(this_oop, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0);276}277278if (TraceClassResolution && !k()->oop_is_array()) {279// skip resolving the constant pool so that this code get's280// called the next time some bytecodes refer to this class.281ResourceMark rm;282int line_number = -1;283const char * source_file = NULL;284if (JavaThread::current()->has_last_Java_frame()) {285// try to identify the method which called this function.286vframeStream vfst(JavaThread::current());287if (!vfst.at_end()) {288line_number = vfst.method()->line_number_from_bci(vfst.bci());289Symbol* s = vfst.method()->method_holder()->source_file_name();290if (s != NULL) {291source_file = s->as_C_string();292}293}294}295if (k() != this_oop->pool_holder()) {296// only print something if the classes are different297if (source_file != NULL) {298tty->print("RESOLVE %s %s %s:%d\n",299this_oop->pool_holder()->external_name(),300InstanceKlass::cast(k())->external_name(), source_file, line_number);301} else {302tty->print("RESOLVE %s %s\n",303this_oop->pool_holder()->external_name(),304InstanceKlass::cast(k())->external_name());305}306}307return k();308} else {309MonitorLockerEx ml(this_oop->lock());310// Only updated constant pool - if it is resolved.311do_resolve = this_oop->tag_at(which).is_unresolved_klass();312if (do_resolve) {313this_oop->klass_at_put(which, k());314}315}316}317318entry = this_oop->resolved_klass_at(which);319assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");320return entry.get_klass();321}322323324// Does not update ConstantPool* - to avoid any exception throwing. Used325// by compiler and exception handling. Also used to avoid classloads for326// instanceof operations. Returns NULL if the class has not been loaded or327// if the verification of constant pool failed328Klass* ConstantPool::klass_at_if_loaded(constantPoolHandle this_oop, int which) {329CPSlot entry = this_oop->slot_at(which);330if (entry.is_resolved()) {331assert(entry.get_klass()->is_klass(), "must be");332return entry.get_klass();333} else {334assert(entry.is_unresolved(), "must be either symbol or klass");335Thread *thread = Thread::current();336Symbol* name = entry.get_symbol();337oop loader = this_oop->pool_holder()->class_loader();338oop protection_domain = this_oop->pool_holder()->protection_domain();339Handle h_prot (thread, protection_domain);340Handle h_loader (thread, loader);341Klass* k = SystemDictionary::find(name, h_loader, h_prot, thread);342343if (k != NULL) {344// Make sure that resolving is legal345EXCEPTION_MARK;346KlassHandle klass(THREAD, k);347// return NULL if verification fails348verify_constant_pool_resolve(this_oop, klass, THREAD);349if (HAS_PENDING_EXCEPTION) {350CLEAR_PENDING_EXCEPTION;351return NULL;352}353return klass();354} else {355return k;356}357}358}359360361Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_oop, int which) {362return klass_at_if_loaded(this_oop, this_oop->klass_ref_index_at(which));363}364365366Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool,367int which) {368if (cpool->cache() == NULL) return NULL; // nothing to load yet369int cache_index = decode_cpcache_index(which, true);370if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {371// FIXME: should be an assert372if (PrintMiscellaneous && (Verbose||WizardMode)) {373tty->print_cr("bad operand %d in:", which); cpool->print();374}375return NULL;376}377ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);378return e->method_if_resolved(cpool);379}380381382bool ConstantPool::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) {383if (cpool->cache() == NULL) return false; // nothing to load yet384int cache_index = decode_cpcache_index(which, true);385ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);386return e->has_appendix();387}388389oop ConstantPool::appendix_at_if_loaded(constantPoolHandle cpool, int which) {390if (cpool->cache() == NULL) return NULL; // nothing to load yet391int cache_index = decode_cpcache_index(which, true);392ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);393return e->appendix_if_resolved(cpool);394}395396397bool ConstantPool::has_method_type_at_if_loaded(constantPoolHandle cpool, int which) {398if (cpool->cache() == NULL) return false; // nothing to load yet399int cache_index = decode_cpcache_index(which, true);400ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);401return e->has_method_type();402}403404oop ConstantPool::method_type_at_if_loaded(constantPoolHandle cpool, int which) {405if (cpool->cache() == NULL) return NULL; // nothing to load yet406int cache_index = decode_cpcache_index(which, true);407ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);408return e->method_type_if_resolved(cpool);409}410411412Symbol* ConstantPool::impl_name_ref_at(int which, bool uncached) {413int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));414return symbol_at(name_index);415}416417418Symbol* ConstantPool::impl_signature_ref_at(int which, bool uncached) {419int signature_index = signature_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));420return symbol_at(signature_index);421}422423424int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) {425int i = which;426if (!uncached && cache() != NULL) {427if (ConstantPool::is_invokedynamic_index(which)) {428// Invokedynamic index is index into resolved_references429int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();430pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);431assert(tag_at(pool_index).is_name_and_type(), "");432return pool_index;433}434// change byte-ordering and go via cache435i = remap_instruction_operand_from_cache(which);436} else {437if (tag_at(which).is_invoke_dynamic()) {438int pool_index = invoke_dynamic_name_and_type_ref_index_at(which);439assert(tag_at(pool_index).is_name_and_type(), "");440return pool_index;441}442}443assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");444assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above");445jint ref_index = *int_at_addr(i);446return extract_high_short_from_int(ref_index);447}448449450int ConstantPool::impl_klass_ref_index_at(int which, bool uncached) {451guarantee(!ConstantPool::is_invokedynamic_index(which),452"an invokedynamic instruction does not have a klass");453int i = which;454if (!uncached && cache() != NULL) {455// change byte-ordering and go via cache456i = remap_instruction_operand_from_cache(which);457}458assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");459jint ref_index = *int_at_addr(i);460return extract_low_short_from_int(ref_index);461}462463464465int ConstantPool::remap_instruction_operand_from_cache(int operand) {466int cpc_index = operand;467DEBUG_ONLY(cpc_index -= CPCACHE_INDEX_TAG);468assert((int)(u2)cpc_index == cpc_index, "clean u2");469int member_index = cache()->entry_at(cpc_index)->constant_pool_index();470return member_index;471}472473474void ConstantPool::verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle k, TRAPS) {475if (k->oop_is_instance() || k->oop_is_objArray()) {476instanceKlassHandle holder (THREAD, this_oop->pool_holder());477Klass* elem_oop = k->oop_is_instance() ? k() : ObjArrayKlass::cast(k())->bottom_klass();478KlassHandle element (THREAD, elem_oop);479480// The element type could be a typeArray - we only need the access check if it is481// an reference to another class482if (element->oop_is_instance()) {483LinkResolver::check_klass_accessability(holder, element, CHECK);484}485}486}487488489int ConstantPool::name_ref_index_at(int which_nt) {490jint ref_index = name_and_type_at(which_nt);491return extract_low_short_from_int(ref_index);492}493494495int ConstantPool::signature_ref_index_at(int which_nt) {496jint ref_index = name_and_type_at(which_nt);497return extract_high_short_from_int(ref_index);498}499500501Klass* ConstantPool::klass_ref_at(int which, TRAPS) {502return klass_at(klass_ref_index_at(which), THREAD);503}504505506Symbol* ConstantPool::klass_name_at(int which) const {507assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(),508"Corrupted constant pool");509// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.510// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and511// tag is not updated atomicly.512CPSlot entry = slot_at(which);513if (entry.is_resolved()) {514// Already resolved - return entry's name.515assert(entry.get_klass()->is_klass(), "must be");516return entry.get_klass()->name();517} else {518assert(entry.is_unresolved(), "must be either symbol or klass");519return entry.get_symbol();520}521}522523Symbol* ConstantPool::klass_ref_at_noresolve(int which) {524jint ref_index = klass_ref_index_at(which);525return klass_at_noresolve(ref_index);526}527528Symbol* ConstantPool::uncached_klass_ref_at_noresolve(int which) {529jint ref_index = uncached_klass_ref_index_at(which);530return klass_at_noresolve(ref_index);531}532533char* ConstantPool::string_at_noresolve(int which) {534Symbol* s = unresolved_string_at(which);535if (s == NULL) {536return (char*)"<pseudo-string>";537} else {538return unresolved_string_at(which)->as_C_string();539}540}541542BasicType ConstantPool::basic_type_for_signature_at(int which) {543return FieldType::basic_type(symbol_at(which));544}545546547void ConstantPool::resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS) {548for (int index = 1; index < this_oop->length(); index++) { // Index 0 is unused549if (this_oop->tag_at(index).is_string()) {550this_oop->string_at(index, CHECK);551}552}553}554555// Resolve all the classes in the constant pool. If they are all resolved,556// the constant pool is read-only. Enhancement: allocate cp entries to557// another metaspace, and copy to read-only or read-write space if this558// bit is set.559bool ConstantPool::resolve_class_constants(TRAPS) {560constantPoolHandle cp(THREAD, this);561for (int index = 1; index < length(); index++) { // Index 0 is unused562if (tag_at(index).is_unresolved_klass() &&563klass_at_if_loaded(cp, index) == NULL) {564return false;565}566}567// set_preresolution(); or some bit for future use568return true;569}570571Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) {572// Dig out the detailed message to reuse if possible573Symbol* message = java_lang_Throwable::detail_message(pending_exception);574if (message != NULL) {575return message;576}577578// Return specific message for the tag579switch (tag.value()) {580case JVM_CONSTANT_UnresolvedClass:581// return the class name in the error message582message = this_oop->unresolved_klass_at(which);583break;584case JVM_CONSTANT_MethodHandle:585// return the method handle name in the error message586message = this_oop->method_handle_name_ref_at(which);587break;588case JVM_CONSTANT_MethodType:589// return the method type signature in the error message590message = this_oop->method_type_signature_at(which);591break;592default:593ShouldNotReachHere();594}595596return message;597}598599void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) {600Symbol* message = NULL;601Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message);602assert(error != NULL && message != NULL, "checking");603CLEAR_PENDING_EXCEPTION;604ResourceMark rm;605THROW_MSG(error, message->as_C_string());606}607608// If resolution for Class, MethodHandle or MethodType fails, save the exception609// in the resolution error table, so that the same exception is thrown again.610void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which,611constantTag tag, TRAPS) {612assert(this_oop->lock()->is_locked(), "constant pool lock should be held");613Symbol* error = PENDING_EXCEPTION->klass()->name();614615int error_tag = tag.error_value();616617if (!PENDING_EXCEPTION->618is_a(SystemDictionary::LinkageError_klass())) {619// Just throw the exception and don't prevent these classes from620// being loaded due to virtual machine errors like StackOverflow621// and OutOfMemoryError, etc, or if the thread was hit by stop()622// Needs clarification to section 5.4.3 of the VM spec (see 6308271)623} else if (this_oop->tag_at(which).value() != error_tag) {624Symbol* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION);625SystemDictionary::add_resolution_error(this_oop, which, error, message);626this_oop->tag_at_put(which, error_tag);627} else {628// some other thread put this in error state629throw_resolution_error(this_oop, which, CHECK);630}631632// This exits with some pending exception633assert(HAS_PENDING_EXCEPTION, "should not be cleared");634}635636637638// Called to resolve constants in the constant pool and return an oop.639// Some constant pool entries cache their resolved oop. This is also640// called to create oops from constants to use in arguments for invokedynamic641oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) {642oop result_oop = NULL;643Handle throw_exception;644645if (cache_index == _possible_index_sentinel) {646// It is possible that this constant is one which is cached in the objects.647// We'll do a linear search. This should be OK because this usage is rare.648assert(index > 0, "valid index");649cache_index = this_oop->cp_to_object_index(index);650}651assert(cache_index == _no_index_sentinel || cache_index >= 0, "");652assert(index == _no_index_sentinel || index >= 0, "");653654if (cache_index >= 0) {655result_oop = this_oop->resolved_references()->obj_at(cache_index);656if (result_oop != NULL) {657return result_oop;658// That was easy...659}660index = this_oop->object_to_cp_index(cache_index);661}662663jvalue prim_value; // temp used only in a few cases below664665constantTag tag = this_oop->tag_at(index);666667switch (tag.value()) {668669case JVM_CONSTANT_UnresolvedClass:670case JVM_CONSTANT_UnresolvedClassInError:671case JVM_CONSTANT_Class:672{673assert(cache_index == _no_index_sentinel, "should not have been set");674Klass* resolved = klass_at_impl(this_oop, index, CHECK_NULL);675// ldc wants the java mirror.676result_oop = resolved->java_mirror();677break;678}679680case JVM_CONSTANT_String:681assert(cache_index != _no_index_sentinel, "should have been set");682if (this_oop->is_pseudo_string_at(index)) {683result_oop = this_oop->pseudo_string_at(index, cache_index);684break;685}686result_oop = string_at_impl(this_oop, index, cache_index, CHECK_NULL);687break;688689case JVM_CONSTANT_MethodHandleInError:690case JVM_CONSTANT_MethodTypeInError:691{692throw_resolution_error(this_oop, index, CHECK_NULL);693break;694}695696case JVM_CONSTANT_MethodHandle:697{698int ref_kind = this_oop->method_handle_ref_kind_at(index);699int callee_index = this_oop->method_handle_klass_index_at(index);700Symbol* name = this_oop->method_handle_name_ref_at(index);701Symbol* signature = this_oop->method_handle_signature_ref_at(index);702if (PrintMiscellaneous)703tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",704ref_kind, index, this_oop->method_handle_index_at(index),705callee_index, name->as_C_string(), signature->as_C_string());706KlassHandle callee;707{ Klass* k = klass_at_impl(this_oop, callee_index, CHECK_NULL);708callee = KlassHandle(THREAD, k);709}710KlassHandle klass(THREAD, this_oop->pool_holder());711Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,712callee, name, signature,713THREAD);714result_oop = value();715if (HAS_PENDING_EXCEPTION) {716MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag.717save_and_throw_exception(this_oop, index, tag, CHECK_NULL);718}719break;720}721722case JVM_CONSTANT_MethodType:723{724Symbol* signature = this_oop->method_type_signature_at(index);725if (PrintMiscellaneous)726tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",727index, this_oop->method_type_index_at(index),728signature->as_C_string());729KlassHandle klass(THREAD, this_oop->pool_holder());730Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);731result_oop = value();732if (HAS_PENDING_EXCEPTION) {733MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag.734save_and_throw_exception(this_oop, index, tag, CHECK_NULL);735}736break;737}738739case JVM_CONSTANT_Integer:740assert(cache_index == _no_index_sentinel, "should not have been set");741prim_value.i = this_oop->int_at(index);742result_oop = java_lang_boxing_object::create(T_INT, &prim_value, CHECK_NULL);743break;744745case JVM_CONSTANT_Float:746assert(cache_index == _no_index_sentinel, "should not have been set");747prim_value.f = this_oop->float_at(index);748result_oop = java_lang_boxing_object::create(T_FLOAT, &prim_value, CHECK_NULL);749break;750751case JVM_CONSTANT_Long:752assert(cache_index == _no_index_sentinel, "should not have been set");753prim_value.j = this_oop->long_at(index);754result_oop = java_lang_boxing_object::create(T_LONG, &prim_value, CHECK_NULL);755break;756757case JVM_CONSTANT_Double:758assert(cache_index == _no_index_sentinel, "should not have been set");759prim_value.d = this_oop->double_at(index);760result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL);761break;762763default:764DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",765this_oop(), index, cache_index, tag.value()));766assert(false, "unexpected constant tag");767break;768}769770if (cache_index >= 0) {771// Cache the oop here also.772Handle result_handle(THREAD, result_oop);773MonitorLockerEx ml(this_oop->lock()); // don't know if we really need this774oop result = this_oop->resolved_references()->obj_at(cache_index);775// Benign race condition: resolved_references may already be filled in while we were trying to lock.776// The important thing here is that all threads pick up the same result.777// It doesn't matter which racing thread wins, as long as only one778// result is used by all threads, and all future queries.779// That result may be either a resolved constant or a failure exception.780if (result == NULL) {781this_oop->resolved_references()->obj_at_put(cache_index, result_handle());782return result_handle();783} else {784// Return the winning thread's result. This can be different than785// result_handle() for MethodHandles.786return result;787}788} else {789return result_oop;790}791}792793oop ConstantPool::uncached_string_at(int which, TRAPS) {794Symbol* sym = unresolved_string_at(which);795oop str = StringTable::intern(sym, CHECK_(NULL));796assert(java_lang_String::is_instance(str), "must be string");797return str;798}799800801oop ConstantPool::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) {802assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");803804Handle bsm;805int argc;806{807// JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments808// The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.809// It is accompanied by the optional arguments.810int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index);811oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL);812if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) {813THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle");814}815816// Extract the optional static arguments.817argc = this_oop->invoke_dynamic_argument_count_at(index);818if (argc == 0) return bsm_oop;819820bsm = Handle(THREAD, bsm_oop);821}822823objArrayHandle info;824{825objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1+argc, CHECK_NULL);826info = objArrayHandle(THREAD, info_oop);827}828829info->obj_at_put(0, bsm());830for (int i = 0; i < argc; i++) {831int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i);832oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL);833info->obj_at_put(1+i, arg_oop);834}835836return info();837}838839oop ConstantPool::string_at_impl(constantPoolHandle this_oop, int which, int obj_index, TRAPS) {840// If the string has already been interned, this entry will be non-null841oop str = this_oop->resolved_references()->obj_at(obj_index);842if (str != NULL) return str;843Symbol* sym = this_oop->unresolved_string_at(which);844str = StringTable::intern(sym, CHECK_(NULL));845this_oop->string_at_put(which, obj_index, str);846assert(java_lang_String::is_instance(str), "must be string");847return str;848}849850851bool ConstantPool::klass_name_at_matches(instanceKlassHandle k,852int which) {853// Names are interned, so we can compare Symbol*s directly854Symbol* cp_name = klass_name_at(which);855return (cp_name == k->name());856}857858859// Iterate over symbols and decrement ones which are Symbol*s.860// This is done during GC so do not need to lock constantPool unless we861// have per-thread safepoints.862// Only decrement the UTF8 symbols. Unresolved classes and strings point to863// these symbols but didn't increment the reference count.864void ConstantPool::unreference_symbols() {865for (int index = 1; index < length(); index++) { // Index 0 is unused866constantTag tag = tag_at(index);867if (tag.is_symbol()) {868symbol_at(index)->decrement_refcount();869}870}871}872873874// Compare this constant pool's entry at index1 to the constant pool875// cp2's entry at index2.876bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,877int index2, TRAPS) {878879// The error tags are equivalent to non-error tags when comparing880jbyte t1 = tag_at(index1).non_error_value();881jbyte t2 = cp2->tag_at(index2).non_error_value();882883if (t1 != t2) {884// Not the same entry type so there is nothing else to check. Note885// that this style of checking will consider resolved/unresolved886// class pairs as different.887// From the ConstantPool* API point of view, this is correct888// behavior. See VM_RedefineClasses::merge_constant_pools() to see how this889// plays out in the context of ConstantPool* merging.890return false;891}892893switch (t1) {894case JVM_CONSTANT_Class:895{896Klass* k1 = klass_at(index1, CHECK_false);897Klass* k2 = cp2->klass_at(index2, CHECK_false);898if (k1 == k2) {899return true;900}901} break;902903case JVM_CONSTANT_ClassIndex:904{905int recur1 = klass_index_at(index1);906int recur2 = cp2->klass_index_at(index2);907bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);908if (match) {909return true;910}911} break;912913case JVM_CONSTANT_Double:914{915jdouble d1 = double_at(index1);916jdouble d2 = cp2->double_at(index2);917if (d1 == d2) {918return true;919}920} break;921922case JVM_CONSTANT_Fieldref:923case JVM_CONSTANT_InterfaceMethodref:924case JVM_CONSTANT_Methodref:925{926int recur1 = uncached_klass_ref_index_at(index1);927int recur2 = cp2->uncached_klass_ref_index_at(index2);928bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);929if (match) {930recur1 = uncached_name_and_type_ref_index_at(index1);931recur2 = cp2->uncached_name_and_type_ref_index_at(index2);932match = compare_entry_to(recur1, cp2, recur2, CHECK_false);933if (match) {934return true;935}936}937} break;938939case JVM_CONSTANT_Float:940{941jfloat f1 = float_at(index1);942jfloat f2 = cp2->float_at(index2);943if (f1 == f2) {944return true;945}946} break;947948case JVM_CONSTANT_Integer:949{950jint i1 = int_at(index1);951jint i2 = cp2->int_at(index2);952if (i1 == i2) {953return true;954}955} break;956957case JVM_CONSTANT_Long:958{959jlong l1 = long_at(index1);960jlong l2 = cp2->long_at(index2);961if (l1 == l2) {962return true;963}964} break;965966case JVM_CONSTANT_NameAndType:967{968int recur1 = name_ref_index_at(index1);969int recur2 = cp2->name_ref_index_at(index2);970bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);971if (match) {972recur1 = signature_ref_index_at(index1);973recur2 = cp2->signature_ref_index_at(index2);974match = compare_entry_to(recur1, cp2, recur2, CHECK_false);975if (match) {976return true;977}978}979} break;980981case JVM_CONSTANT_StringIndex:982{983int recur1 = string_index_at(index1);984int recur2 = cp2->string_index_at(index2);985bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);986if (match) {987return true;988}989} break;990991case JVM_CONSTANT_UnresolvedClass:992{993Symbol* k1 = unresolved_klass_at(index1);994Symbol* k2 = cp2->unresolved_klass_at(index2);995if (k1 == k2) {996return true;997}998} break;9991000case JVM_CONSTANT_MethodType:1001{1002int k1 = method_type_index_at_error_ok(index1);1003int k2 = cp2->method_type_index_at_error_ok(index2);1004bool match = compare_entry_to(k1, cp2, k2, CHECK_false);1005if (match) {1006return true;1007}1008} break;10091010case JVM_CONSTANT_MethodHandle:1011{1012int k1 = method_handle_ref_kind_at_error_ok(index1);1013int k2 = cp2->method_handle_ref_kind_at_error_ok(index2);1014if (k1 == k2) {1015int i1 = method_handle_index_at_error_ok(index1);1016int i2 = cp2->method_handle_index_at_error_ok(index2);1017bool match = compare_entry_to(i1, cp2, i2, CHECK_false);1018if (match) {1019return true;1020}1021}1022} break;10231024case JVM_CONSTANT_InvokeDynamic:1025{1026int k1 = invoke_dynamic_name_and_type_ref_index_at(index1);1027int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);1028int i1 = invoke_dynamic_bootstrap_specifier_index(index1);1029int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);1030// separate statements and variables because CHECK_false is used1031bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false);1032bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false);1033return (match_entry && match_operand);1034} break;10351036case JVM_CONSTANT_String:1037{1038Symbol* s1 = unresolved_string_at(index1);1039Symbol* s2 = cp2->unresolved_string_at(index2);1040if (s1 == s2) {1041return true;1042}1043} break;10441045case JVM_CONSTANT_Utf8:1046{1047Symbol* s1 = symbol_at(index1);1048Symbol* s2 = cp2->symbol_at(index2);1049if (s1 == s2) {1050return true;1051}1052} break;10531054// Invalid is used as the tag for the second constant pool entry1055// occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should1056// not be seen by itself.1057case JVM_CONSTANT_Invalid: // fall through10581059default:1060ShouldNotReachHere();1061break;1062}10631064return false;1065} // end compare_entry_to()106610671068// Resize the operands array with delta_len and delta_size.1069// Used in RedefineClasses for CP merge.1070void ConstantPool::resize_operands(int delta_len, int delta_size, TRAPS) {1071int old_len = operand_array_length(operands());1072int new_len = old_len + delta_len;1073int min_len = (delta_len > 0) ? old_len : new_len;10741075int old_size = operands()->length();1076int new_size = old_size + delta_size;1077int min_size = (delta_size > 0) ? old_size : new_size;10781079ClassLoaderData* loader_data = pool_holder()->class_loader_data();1080Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, new_size, CHECK);10811082// Set index in the resized array for existing elements only1083for (int idx = 0; idx < min_len; idx++) {1084int offset = operand_offset_at(idx); // offset in original array1085operand_offset_at_put(new_ops, idx, offset + 2*delta_len); // offset in resized array1086}1087// Copy the bootstrap specifiers only1088Copy::conjoint_memory_atomic(operands()->adr_at(2*old_len),1089new_ops->adr_at(2*new_len),1090(min_size - 2*min_len) * sizeof(u2));1091// Explicitly deallocate old operands array.1092// Note, it is not needed for 7u backport.1093if ( operands() != NULL) { // the safety check1094MetadataFactory::free_array<u2>(loader_data, operands());1095}1096set_operands(new_ops);1097} // end resize_operands()109810991100// Extend the operands array with the length and size of the ext_cp operands.1101// Used in RedefineClasses for CP merge.1102void ConstantPool::extend_operands(constantPoolHandle ext_cp, TRAPS) {1103int delta_len = operand_array_length(ext_cp->operands());1104if (delta_len == 0) {1105return; // nothing to do1106}1107int delta_size = ext_cp->operands()->length();11081109assert(delta_len > 0 && delta_size > 0, "extended operands array must be bigger");11101111if (operand_array_length(operands()) == 0) {1112ClassLoaderData* loader_data = pool_holder()->class_loader_data();1113Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, delta_size, CHECK);1114// The first element index defines the offset of second part1115operand_offset_at_put(new_ops, 0, 2*delta_len); // offset in new array1116set_operands(new_ops);1117} else {1118resize_operands(delta_len, delta_size, CHECK);1119}11201121} // end extend_operands()112211231124// Shrink the operands array to a smaller array with new_len length.1125// Used in RedefineClasses for CP merge.1126void ConstantPool::shrink_operands(int new_len, TRAPS) {1127int old_len = operand_array_length(operands());1128if (new_len == old_len) {1129return; // nothing to do1130}1131assert(new_len < old_len, "shrunken operands array must be smaller");11321133int free_base = operand_next_offset_at(new_len - 1);1134int delta_len = new_len - old_len;1135int delta_size = 2*delta_len + free_base - operands()->length();11361137resize_operands(delta_len, delta_size, CHECK);11381139} // end shrink_operands()114011411142void ConstantPool::copy_operands(constantPoolHandle from_cp,1143constantPoolHandle to_cp,1144TRAPS) {11451146int from_oplen = operand_array_length(from_cp->operands());1147int old_oplen = operand_array_length(to_cp->operands());1148if (from_oplen != 0) {1149ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data();1150// append my operands to the target's operands array1151if (old_oplen == 0) {1152// Can't just reuse from_cp's operand list because of deallocation issues1153int len = from_cp->operands()->length();1154Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, len, CHECK);1155Copy::conjoint_memory_atomic(1156from_cp->operands()->adr_at(0), new_ops->adr_at(0), len * sizeof(u2));1157to_cp->set_operands(new_ops);1158} else {1159int old_len = to_cp->operands()->length();1160int from_len = from_cp->operands()->length();1161int old_off = old_oplen * sizeof(u2);1162int from_off = from_oplen * sizeof(u2);1163// Use the metaspace for the destination constant pool1164Array<u2>* new_operands = MetadataFactory::new_array<u2>(loader_data, old_len + from_len, CHECK);1165int fillp = 0, len = 0;1166// first part of dest1167Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(0),1168new_operands->adr_at(fillp),1169(len = old_off) * sizeof(u2));1170fillp += len;1171// first part of src1172Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(0),1173new_operands->adr_at(fillp),1174(len = from_off) * sizeof(u2));1175fillp += len;1176// second part of dest1177Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(old_off),1178new_operands->adr_at(fillp),1179(len = old_len - old_off) * sizeof(u2));1180fillp += len;1181// second part of src1182Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(from_off),1183new_operands->adr_at(fillp),1184(len = from_len - from_off) * sizeof(u2));1185fillp += len;1186assert(fillp == new_operands->length(), "");11871188// Adjust indexes in the first part of the copied operands array.1189for (int j = 0; j < from_oplen; j++) {1190int offset = operand_offset_at(new_operands, old_oplen + j);1191assert(offset == operand_offset_at(from_cp->operands(), j), "correct copy");1192offset += old_len; // every new tuple is preceded by old_len extra u2's1193operand_offset_at_put(new_operands, old_oplen + j, offset);1194}11951196// replace target operands array with combined array1197to_cp->set_operands(new_operands);1198}1199}1200} // end copy_operands()120112021203// Copy this constant pool's entries at start_i to end_i (inclusive)1204// to the constant pool to_cp's entries starting at to_i. A total of1205// (end_i - start_i) + 1 entries are copied.1206void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,1207constantPoolHandle to_cp, int to_i, TRAPS) {120812091210int dest_i = to_i; // leave original alone for debug purposes12111212for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {1213copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);12141215switch (from_cp->tag_at(src_i).value()) {1216case JVM_CONSTANT_Double:1217case JVM_CONSTANT_Long:1218// double and long take two constant pool entries1219src_i += 2;1220dest_i += 2;1221break;12221223default:1224// all others take one constant pool entry1225src_i++;1226dest_i++;1227break;1228}1229}1230copy_operands(from_cp, to_cp, CHECK);12311232} // end copy_cp_to_impl()123312341235// Copy this constant pool's entry at from_i to the constant pool1236// to_cp's entry at to_i.1237void ConstantPool::copy_entry_to(constantPoolHandle from_cp, int from_i,1238constantPoolHandle to_cp, int to_i,1239TRAPS) {12401241int tag = from_cp->tag_at(from_i).value();1242switch (tag) {1243case JVM_CONSTANT_Class:1244{1245Klass* k = from_cp->klass_at(from_i, CHECK);1246to_cp->klass_at_put(to_i, k);1247} break;12481249case JVM_CONSTANT_ClassIndex:1250{1251jint ki = from_cp->klass_index_at(from_i);1252to_cp->klass_index_at_put(to_i, ki);1253} break;12541255case JVM_CONSTANT_Double:1256{1257jdouble d = from_cp->double_at(from_i);1258to_cp->double_at_put(to_i, d);1259// double takes two constant pool entries so init second entry's tag1260to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);1261} break;12621263case JVM_CONSTANT_Fieldref:1264{1265int class_index = from_cp->uncached_klass_ref_index_at(from_i);1266int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);1267to_cp->field_at_put(to_i, class_index, name_and_type_index);1268} break;12691270case JVM_CONSTANT_Float:1271{1272jfloat f = from_cp->float_at(from_i);1273to_cp->float_at_put(to_i, f);1274} break;12751276case JVM_CONSTANT_Integer:1277{1278jint i = from_cp->int_at(from_i);1279to_cp->int_at_put(to_i, i);1280} break;12811282case JVM_CONSTANT_InterfaceMethodref:1283{1284int class_index = from_cp->uncached_klass_ref_index_at(from_i);1285int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);1286to_cp->interface_method_at_put(to_i, class_index, name_and_type_index);1287} break;12881289case JVM_CONSTANT_Long:1290{1291jlong l = from_cp->long_at(from_i);1292to_cp->long_at_put(to_i, l);1293// long takes two constant pool entries so init second entry's tag1294to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);1295} break;12961297case JVM_CONSTANT_Methodref:1298{1299int class_index = from_cp->uncached_klass_ref_index_at(from_i);1300int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);1301to_cp->method_at_put(to_i, class_index, name_and_type_index);1302} break;13031304case JVM_CONSTANT_NameAndType:1305{1306int name_ref_index = from_cp->name_ref_index_at(from_i);1307int signature_ref_index = from_cp->signature_ref_index_at(from_i);1308to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index);1309} break;13101311case JVM_CONSTANT_StringIndex:1312{1313jint si = from_cp->string_index_at(from_i);1314to_cp->string_index_at_put(to_i, si);1315} break;13161317case JVM_CONSTANT_UnresolvedClass:1318case JVM_CONSTANT_UnresolvedClassInError:1319{1320// Can be resolved after checking tag, so check the slot first.1321CPSlot entry = from_cp->slot_at(from_i);1322if (entry.is_resolved()) {1323assert(entry.get_klass()->is_klass(), "must be");1324// Already resolved1325to_cp->klass_at_put(to_i, entry.get_klass());1326} else {1327to_cp->unresolved_klass_at_put(to_i, entry.get_symbol());1328}1329} break;13301331case JVM_CONSTANT_String:1332{1333Symbol* s = from_cp->unresolved_string_at(from_i);1334to_cp->unresolved_string_at_put(to_i, s);1335} break;13361337case JVM_CONSTANT_Utf8:1338{1339Symbol* s = from_cp->symbol_at(from_i);1340// Need to increase refcount, the old one will be thrown away and deferenced1341s->increment_refcount();1342to_cp->symbol_at_put(to_i, s);1343} break;13441345case JVM_CONSTANT_MethodType:1346case JVM_CONSTANT_MethodTypeInError:1347{1348jint k = from_cp->method_type_index_at_error_ok(from_i);1349to_cp->method_type_index_at_put(to_i, k);1350} break;13511352case JVM_CONSTANT_MethodHandle:1353case JVM_CONSTANT_MethodHandleInError:1354{1355int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i);1356int k2 = from_cp->method_handle_index_at_error_ok(from_i);1357to_cp->method_handle_index_at_put(to_i, k1, k2);1358} break;13591360case JVM_CONSTANT_InvokeDynamic:1361{1362int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i);1363int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);1364k1 += operand_array_length(to_cp->operands()); // to_cp might already have operands1365to_cp->invoke_dynamic_at_put(to_i, k1, k2);1366} break;13671368// Invalid is used as the tag for the second constant pool entry1369// occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should1370// not be seen by itself.1371case JVM_CONSTANT_Invalid: // fall through13721373default:1374{1375ShouldNotReachHere();1376} break;1377}1378} // end copy_entry_to()137913801381// Search constant pool search_cp for an entry that matches this1382// constant pool's entry at pattern_i. Returns the index of a1383// matching entry or zero (0) if there is no matching entry.1384int ConstantPool::find_matching_entry(int pattern_i,1385constantPoolHandle search_cp, TRAPS) {13861387// index zero (0) is not used1388for (int i = 1; i < search_cp->length(); i++) {1389bool found = compare_entry_to(pattern_i, search_cp, i, CHECK_0);1390if (found) {1391return i;1392}1393}13941395return 0; // entry not found; return unused index zero (0)1396} // end find_matching_entry()139713981399// Compare this constant pool's bootstrap specifier at idx1 to the constant pool1400// cp2's bootstrap specifier at idx2.1401bool ConstantPool::compare_operand_to(int idx1, constantPoolHandle cp2, int idx2, TRAPS) {1402int k1 = operand_bootstrap_method_ref_index_at(idx1);1403int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2);1404bool match = compare_entry_to(k1, cp2, k2, CHECK_false);14051406if (!match) {1407return false;1408}1409int argc = operand_argument_count_at(idx1);1410if (argc == cp2->operand_argument_count_at(idx2)) {1411for (int j = 0; j < argc; j++) {1412k1 = operand_argument_index_at(idx1, j);1413k2 = cp2->operand_argument_index_at(idx2, j);1414match = compare_entry_to(k1, cp2, k2, CHECK_false);1415if (!match) {1416return false;1417}1418}1419return true; // got through loop; all elements equal1420}1421return false;1422} // end compare_operand_to()14231424// Search constant pool search_cp for a bootstrap specifier that matches1425// this constant pool's bootstrap specifier at pattern_i index.1426// Return the index of a matching bootstrap specifier or (-1) if there is no match.1427int ConstantPool::find_matching_operand(int pattern_i,1428constantPoolHandle search_cp, int search_len, TRAPS) {1429for (int i = 0; i < search_len; i++) {1430bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1));1431if (found) {1432return i;1433}1434}1435return -1; // bootstrap specifier not found; return unused index (-1)1436} // end find_matching_operand()143714381439#ifndef PRODUCT14401441const char* ConstantPool::printable_name_at(int which) {14421443constantTag tag = tag_at(which);14441445if (tag.is_string()) {1446return string_at_noresolve(which);1447} else if (tag.is_klass() || tag.is_unresolved_klass()) {1448return klass_name_at(which)->as_C_string();1449} else if (tag.is_symbol()) {1450return symbol_at(which)->as_C_string();1451}1452return "";1453}14541455#endif // PRODUCT145614571458// JVMTI GetConstantPool support14591460// For debugging of constant pool1461const bool debug_cpool = false;14621463#define DBG(code) do { if (debug_cpool) { (code); } } while(0)14641465static void print_cpool_bytes(jint cnt, u1 *bytes) {1466const char* WARN_MSG = "Must not be such entry!";1467jint size = 0;1468u2 idx1, idx2;14691470for (jint idx = 1; idx < cnt; idx++) {1471jint ent_size = 0;1472u1 tag = *bytes++;1473size++; // count tag14741475printf("const #%03d, tag: %02d ", idx, tag);1476switch(tag) {1477case JVM_CONSTANT_Invalid: {1478printf("Invalid");1479break;1480}1481case JVM_CONSTANT_Unicode: {1482printf("Unicode %s", WARN_MSG);1483break;1484}1485case JVM_CONSTANT_Utf8: {1486u2 len = Bytes::get_Java_u2(bytes);1487char str[128];1488if (len > 127) {1489len = 127;1490}1491strncpy(str, (char *) (bytes+2), len);1492str[len] = '\0';1493printf("Utf8 \"%s\"", str);1494ent_size = 2 + len;1495break;1496}1497case JVM_CONSTANT_Integer: {1498u4 val = Bytes::get_Java_u4(bytes);1499printf("int %d", *(int *) &val);1500ent_size = 4;1501break;1502}1503case JVM_CONSTANT_Float: {1504u4 val = Bytes::get_Java_u4(bytes);1505printf("float %5.3ff", *(float *) &val);1506ent_size = 4;1507break;1508}1509case JVM_CONSTANT_Long: {1510u8 val = Bytes::get_Java_u8(bytes);1511printf("long " INT64_FORMAT, (int64_t) *(jlong *) &val);1512ent_size = 8;1513idx++; // Long takes two cpool slots1514break;1515}1516case JVM_CONSTANT_Double: {1517u8 val = Bytes::get_Java_u8(bytes);1518printf("double %5.3fd", *(jdouble *)&val);1519ent_size = 8;1520idx++; // Double takes two cpool slots1521break;1522}1523case JVM_CONSTANT_Class: {1524idx1 = Bytes::get_Java_u2(bytes);1525printf("class #%03d", idx1);1526ent_size = 2;1527break;1528}1529case JVM_CONSTANT_String: {1530idx1 = Bytes::get_Java_u2(bytes);1531printf("String #%03d", idx1);1532ent_size = 2;1533break;1534}1535case JVM_CONSTANT_Fieldref: {1536idx1 = Bytes::get_Java_u2(bytes);1537idx2 = Bytes::get_Java_u2(bytes+2);1538printf("Field #%03d, #%03d", (int) idx1, (int) idx2);1539ent_size = 4;1540break;1541}1542case JVM_CONSTANT_Methodref: {1543idx1 = Bytes::get_Java_u2(bytes);1544idx2 = Bytes::get_Java_u2(bytes+2);1545printf("Method #%03d, #%03d", idx1, idx2);1546ent_size = 4;1547break;1548}1549case JVM_CONSTANT_InterfaceMethodref: {1550idx1 = Bytes::get_Java_u2(bytes);1551idx2 = Bytes::get_Java_u2(bytes+2);1552printf("InterfMethod #%03d, #%03d", idx1, idx2);1553ent_size = 4;1554break;1555}1556case JVM_CONSTANT_NameAndType: {1557idx1 = Bytes::get_Java_u2(bytes);1558idx2 = Bytes::get_Java_u2(bytes+2);1559printf("NameAndType #%03d, #%03d", idx1, idx2);1560ent_size = 4;1561break;1562}1563case JVM_CONSTANT_ClassIndex: {1564printf("ClassIndex %s", WARN_MSG);1565break;1566}1567case JVM_CONSTANT_UnresolvedClass: {1568printf("UnresolvedClass: %s", WARN_MSG);1569break;1570}1571case JVM_CONSTANT_UnresolvedClassInError: {1572printf("UnresolvedClassInErr: %s", WARN_MSG);1573break;1574}1575case JVM_CONSTANT_StringIndex: {1576printf("StringIndex: %s", WARN_MSG);1577break;1578}1579}1580printf(";\n");1581bytes += ent_size;1582size += ent_size;1583}1584printf("Cpool size: %d\n", size);1585fflush(0);1586return;1587} /* end print_cpool_bytes */158815891590// Returns size of constant pool entry.1591jint ConstantPool::cpool_entry_size(jint idx) {1592switch(tag_at(idx).value()) {1593case JVM_CONSTANT_Invalid:1594case JVM_CONSTANT_Unicode:1595return 1;15961597case JVM_CONSTANT_Utf8:1598return 3 + symbol_at(idx)->utf8_length();15991600case JVM_CONSTANT_Class:1601case JVM_CONSTANT_String:1602case JVM_CONSTANT_ClassIndex:1603case JVM_CONSTANT_UnresolvedClass:1604case JVM_CONSTANT_UnresolvedClassInError:1605case JVM_CONSTANT_StringIndex:1606case JVM_CONSTANT_MethodType:1607case JVM_CONSTANT_MethodTypeInError:1608return 3;16091610case JVM_CONSTANT_MethodHandle:1611case JVM_CONSTANT_MethodHandleInError:1612return 4; //tag, ref_kind, ref_index16131614case JVM_CONSTANT_Integer:1615case JVM_CONSTANT_Float:1616case JVM_CONSTANT_Fieldref:1617case JVM_CONSTANT_Methodref:1618case JVM_CONSTANT_InterfaceMethodref:1619case JVM_CONSTANT_NameAndType:1620return 5;16211622case JVM_CONSTANT_InvokeDynamic:1623// u1 tag, u2 bsm, u2 nt1624return 5;16251626case JVM_CONSTANT_Long:1627case JVM_CONSTANT_Double:1628return 9;1629}1630assert(false, "cpool_entry_size: Invalid constant pool entry tag");1631return 1;1632} /* end cpool_entry_size */163316341635// SymbolHashMap is used to find a constant pool index from a string.1636// This function fills in SymbolHashMaps, one for utf8s and one for1637// class names, returns size of the cpool raw bytes.1638jint ConstantPool::hash_entries_to(SymbolHashMap *symmap,1639SymbolHashMap *classmap) {1640jint size = 0;16411642for (u2 idx = 1; idx < length(); idx++) {1643u2 tag = tag_at(idx).value();1644size += cpool_entry_size(idx);16451646switch(tag) {1647case JVM_CONSTANT_Utf8: {1648Symbol* sym = symbol_at(idx);1649symmap->add_entry(sym, idx);1650DBG(printf("adding symbol entry %s = %d\n", sym->as_utf8(), idx));1651break;1652}1653case JVM_CONSTANT_Class:1654case JVM_CONSTANT_UnresolvedClass:1655case JVM_CONSTANT_UnresolvedClassInError: {1656Symbol* sym = klass_name_at(idx);1657classmap->add_entry(sym, idx);1658DBG(printf("adding class entry %s = %d\n", sym->as_utf8(), idx));1659break;1660}1661case JVM_CONSTANT_Long:1662case JVM_CONSTANT_Double: {1663idx++; // Both Long and Double take two cpool slots1664break;1665}1666}1667}1668return size;1669} /* end hash_utf8_entries_to */167016711672// Copy cpool bytes.1673// Returns:1674// 0, in case of OutOfMemoryError1675// -1, in case of internal error1676// > 0, count of the raw cpool bytes that have been copied1677int ConstantPool::copy_cpool_bytes(int cpool_size,1678SymbolHashMap* tbl,1679unsigned char *bytes) {1680u2 idx1, idx2;1681jint size = 0;1682jint cnt = length();1683unsigned char *start_bytes = bytes;16841685for (jint idx = 1; idx < cnt; idx++) {1686u1 tag = tag_at(idx).value();1687jint ent_size = cpool_entry_size(idx);16881689assert(size + ent_size <= cpool_size, "Size mismatch");16901691*bytes = tag;1692DBG(printf("#%03hd tag=%03hd, ", idx, tag));1693switch(tag) {1694case JVM_CONSTANT_Invalid: {1695DBG(printf("JVM_CONSTANT_Invalid"));1696break;1697}1698case JVM_CONSTANT_Unicode: {1699assert(false, "Wrong constant pool tag: JVM_CONSTANT_Unicode");1700DBG(printf("JVM_CONSTANT_Unicode"));1701break;1702}1703case JVM_CONSTANT_Utf8: {1704Symbol* sym = symbol_at(idx);1705char* str = sym->as_utf8();1706// Warning! It's crashing on x86 with len = sym->utf8_length()1707int len = (int) strlen(str);1708Bytes::put_Java_u2((address) (bytes+1), (u2) len);1709for (int i = 0; i < len; i++) {1710bytes[3+i] = (u1) str[i];1711}1712DBG(printf("JVM_CONSTANT_Utf8: %s ", str));1713break;1714}1715case JVM_CONSTANT_Integer: {1716jint val = int_at(idx);1717Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val);1718break;1719}1720case JVM_CONSTANT_Float: {1721jfloat val = float_at(idx);1722Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val);1723break;1724}1725case JVM_CONSTANT_Long: {1726jlong val = long_at(idx);1727Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val);1728idx++; // Long takes two cpool slots1729break;1730}1731case JVM_CONSTANT_Double: {1732jdouble val = double_at(idx);1733Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val);1734idx++; // Double takes two cpool slots1735break;1736}1737case JVM_CONSTANT_Class:1738case JVM_CONSTANT_UnresolvedClass:1739case JVM_CONSTANT_UnresolvedClassInError: {1740*bytes = JVM_CONSTANT_Class;1741Symbol* sym = klass_name_at(idx);1742idx1 = tbl->symbol_to_value(sym);1743assert(idx1 != 0, "Have not found a hashtable entry");1744Bytes::put_Java_u2((address) (bytes+1), idx1);1745DBG(printf("JVM_CONSTANT_Class: idx=#%03hd, %s", idx1, sym->as_utf8()));1746break;1747}1748case JVM_CONSTANT_String: {1749*bytes = JVM_CONSTANT_String;1750Symbol* sym = unresolved_string_at(idx);1751idx1 = tbl->symbol_to_value(sym);1752assert(idx1 != 0, "Have not found a hashtable entry");1753Bytes::put_Java_u2((address) (bytes+1), idx1);1754DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, sym->as_utf8()));1755break;1756}1757case JVM_CONSTANT_Fieldref:1758case JVM_CONSTANT_Methodref:1759case JVM_CONSTANT_InterfaceMethodref: {1760idx1 = uncached_klass_ref_index_at(idx);1761idx2 = uncached_name_and_type_ref_index_at(idx);1762Bytes::put_Java_u2((address) (bytes+1), idx1);1763Bytes::put_Java_u2((address) (bytes+3), idx2);1764DBG(printf("JVM_CONSTANT_Methodref: %hd %hd", idx1, idx2));1765break;1766}1767case JVM_CONSTANT_NameAndType: {1768idx1 = name_ref_index_at(idx);1769idx2 = signature_ref_index_at(idx);1770Bytes::put_Java_u2((address) (bytes+1), idx1);1771Bytes::put_Java_u2((address) (bytes+3), idx2);1772DBG(printf("JVM_CONSTANT_NameAndType: %hd %hd", idx1, idx2));1773break;1774}1775case JVM_CONSTANT_ClassIndex: {1776*bytes = JVM_CONSTANT_Class;1777idx1 = klass_index_at(idx);1778Bytes::put_Java_u2((address) (bytes+1), idx1);1779DBG(printf("JVM_CONSTANT_ClassIndex: %hd", idx1));1780break;1781}1782case JVM_CONSTANT_StringIndex: {1783*bytes = JVM_CONSTANT_String;1784idx1 = string_index_at(idx);1785Bytes::put_Java_u2((address) (bytes+1), idx1);1786DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1));1787break;1788}1789case JVM_CONSTANT_MethodHandle:1790case JVM_CONSTANT_MethodHandleInError: {1791*bytes = JVM_CONSTANT_MethodHandle;1792int kind = method_handle_ref_kind_at_error_ok(idx);1793idx1 = method_handle_index_at_error_ok(idx);1794*(bytes+1) = (unsigned char) kind;1795Bytes::put_Java_u2((address) (bytes+2), idx1);1796DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));1797break;1798}1799case JVM_CONSTANT_MethodType:1800case JVM_CONSTANT_MethodTypeInError: {1801*bytes = JVM_CONSTANT_MethodType;1802idx1 = method_type_index_at_error_ok(idx);1803Bytes::put_Java_u2((address) (bytes+1), idx1);1804DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));1805break;1806}1807case JVM_CONSTANT_InvokeDynamic: {1808*bytes = tag;1809idx1 = extract_low_short_from_int(*int_at_addr(idx));1810idx2 = extract_high_short_from_int(*int_at_addr(idx));1811assert(idx2 == invoke_dynamic_name_and_type_ref_index_at(idx), "correct half of u4");1812Bytes::put_Java_u2((address) (bytes+1), idx1);1813Bytes::put_Java_u2((address) (bytes+3), idx2);1814DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2));1815break;1816}1817}1818DBG(printf("\n"));1819bytes += ent_size;1820size += ent_size;1821}1822assert(size == cpool_size, "Size mismatch");18231824// Keep temorarily for debugging until it's stable.1825DBG(print_cpool_bytes(cnt, start_bytes));1826return (int)(bytes - start_bytes);1827} /* end copy_cpool_bytes */18281829#undef DBG183018311832void ConstantPool::set_on_stack(const bool value) {1833if (value) {1834int old_flags = *const_cast<volatile int *>(&_flags);1835while ((old_flags & _on_stack) == 0) {1836int new_flags = old_flags | _on_stack;1837int result = Atomic::cmpxchg(new_flags, &_flags, old_flags);18381839if (result == old_flags) {1840// Succeeded.1841MetadataOnStackMark::record(this, Thread::current());1842return;1843}1844old_flags = result;1845}1846} else {1847// Clearing is done single-threadedly.1848_flags &= ~_on_stack;1849}1850}18511852// JSR 292 support for patching constant pool oops after the class is linked and1853// the oop array for resolved references are created.1854// We can't do this during classfile parsing, which is how the other indexes are1855// patched. The other patches are applied early for some error checking1856// so only defer the pseudo_strings.1857void ConstantPool::patch_resolved_references(1858GrowableArray<Handle>* cp_patches) {1859assert(EnableInvokeDynamic, "");1860for (int index = 1; index < cp_patches->length(); index++) { // Index 0 is unused1861Handle patch = cp_patches->at(index);1862if (patch.not_null()) {1863assert (tag_at(index).is_string(), "should only be string left");1864// Patching a string means pre-resolving it.1865// The spelling in the constant pool is ignored.1866// The constant reference may be any object whatever.1867// If it is not a real interned string, the constant is referred1868// to as a "pseudo-string", and must be presented to the CP1869// explicitly, because it may require scavenging.1870int obj_index = cp_to_object_index(index);1871pseudo_string_at_put(index, obj_index, patch());1872DEBUG_ONLY(cp_patches->at_put(index, Handle());)1873}1874}1875#ifdef ASSERT1876// Ensure that all the patches have been used.1877for (int index = 0; index < cp_patches->length(); index++) {1878assert(cp_patches->at(index).is_null(),1879err_msg("Unused constant pool patch at %d in class file %s",1880index,1881pool_holder()->external_name()));1882}1883#endif // ASSERT1884}18851886#ifndef PRODUCT18871888// CompileTheWorld support. Preload all classes loaded references in the passed in constantpool1889void ConstantPool::preload_and_initialize_all_classes(ConstantPool* obj, TRAPS) {1890guarantee(obj->is_constantPool(), "object must be constant pool");1891constantPoolHandle cp(THREAD, (ConstantPool*)obj);1892guarantee(cp->pool_holder() != NULL, "must be fully loaded");18931894for (int i = 0; i< cp->length(); i++) {1895if (cp->tag_at(i).is_unresolved_klass()) {1896// This will force loading of the class1897Klass* klass = cp->klass_at(i, CHECK);1898if (klass->oop_is_instance()) {1899// Force initialization of class1900InstanceKlass::cast(klass)->initialize(CHECK);1901}1902}1903}1904}19051906#endif190719081909// Printing19101911void ConstantPool::print_on(outputStream* st) const {1912EXCEPTION_MARK;1913assert(is_constantPool(), "must be constantPool");1914st->print_cr("%s", internal_name());1915if (flags() != 0) {1916st->print(" - flags: 0x%x", flags());1917if (has_preresolution()) st->print(" has_preresolution");1918if (on_stack()) st->print(" on_stack");1919st->cr();1920}1921if (pool_holder() != NULL) {1922st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder());1923}1924st->print_cr(" - cache: " INTPTR_FORMAT, cache());1925st->print_cr(" - resolved_references: " INTPTR_FORMAT, (void *)resolved_references());1926st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map());19271928for (int index = 1; index < length(); index++) { // Index 0 is unused1929((ConstantPool*)this)->print_entry_on(index, st);1930switch (tag_at(index).value()) {1931case JVM_CONSTANT_Long :1932case JVM_CONSTANT_Double :1933index++; // Skip entry following eigth-byte constant1934}19351936}1937st->cr();1938}19391940// Print one constant pool entry1941void ConstantPool::print_entry_on(const int index, outputStream* st) {1942EXCEPTION_MARK;1943st->print(" - %3d : ", index);1944tag_at(index).print_on(st);1945st->print(" : ");1946switch (tag_at(index).value()) {1947case JVM_CONSTANT_Class :1948{ Klass* k = klass_at(index, CATCH);1949guarantee(k != NULL, "need klass");1950k->print_value_on(st);1951st->print(" {0x%lx}", (address)k);1952}1953break;1954case JVM_CONSTANT_Fieldref :1955case JVM_CONSTANT_Methodref :1956case JVM_CONSTANT_InterfaceMethodref :1957st->print("klass_index=%d", uncached_klass_ref_index_at(index));1958st->print(" name_and_type_index=%d", uncached_name_and_type_ref_index_at(index));1959break;1960case JVM_CONSTANT_String :1961if (is_pseudo_string_at(index)) {1962oop anObj = pseudo_string_at(index);1963anObj->print_value_on(st);1964st->print(" {0x%lx}", (address)anObj);1965} else {1966unresolved_string_at(index)->print_value_on(st);1967}1968break;1969case JVM_CONSTANT_Integer :1970st->print("%d", int_at(index));1971break;1972case JVM_CONSTANT_Float :1973st->print("%f", float_at(index));1974break;1975case JVM_CONSTANT_Long :1976st->print_jlong(long_at(index));1977break;1978case JVM_CONSTANT_Double :1979st->print("%lf", double_at(index));1980break;1981case JVM_CONSTANT_NameAndType :1982st->print("name_index=%d", name_ref_index_at(index));1983st->print(" signature_index=%d", signature_ref_index_at(index));1984break;1985case JVM_CONSTANT_Utf8 :1986symbol_at(index)->print_value_on(st);1987break;1988case JVM_CONSTANT_UnresolvedClass : // fall-through1989case JVM_CONSTANT_UnresolvedClassInError: {1990// unresolved_klass_at requires lock or safe world.1991CPSlot entry = slot_at(index);1992if (entry.is_resolved()) {1993entry.get_klass()->print_value_on(st);1994} else {1995entry.get_symbol()->print_value_on(st);1996}1997}1998break;1999case JVM_CONSTANT_MethodHandle :2000case JVM_CONSTANT_MethodHandleInError :2001st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index));2002st->print(" ref_index=%d", method_handle_index_at_error_ok(index));2003break;2004case JVM_CONSTANT_MethodType :2005case JVM_CONSTANT_MethodTypeInError :2006st->print("signature_index=%d", method_type_index_at_error_ok(index));2007break;2008case JVM_CONSTANT_InvokeDynamic :2009{2010st->print("bootstrap_method_index=%d", invoke_dynamic_bootstrap_method_ref_index_at(index));2011st->print(" name_and_type_index=%d", invoke_dynamic_name_and_type_ref_index_at(index));2012int argc = invoke_dynamic_argument_count_at(index);2013if (argc > 0) {2014for (int arg_i = 0; arg_i < argc; arg_i++) {2015int arg = invoke_dynamic_argument_index_at(index, arg_i);2016st->print((arg_i == 0 ? " arguments={%d" : ", %d"), arg);2017}2018st->print("}");2019}2020}2021break;2022default:2023ShouldNotReachHere();2024break;2025}2026st->cr();2027}20282029void ConstantPool::print_value_on(outputStream* st) const {2030assert(is_constantPool(), "must be constantPool");2031st->print("constant pool [%d]", length());2032if (has_preresolution()) st->print("/preresolution");2033if (operands() != NULL) st->print("/operands[%d]", operands()->length());2034print_address_on(st);2035st->print(" for ");2036pool_holder()->print_value_on(st);2037if (pool_holder() != NULL) {2038bool extra = (pool_holder()->constants() != this);2039if (extra) st->print(" (extra)");2040}2041if (cache() != NULL) {2042st->print(" cache=" PTR_FORMAT, cache());2043}2044}20452046#if INCLUDE_SERVICES2047// Size Statistics2048void ConstantPool::collect_statistics(KlassSizeStats *sz) const {2049sz->_cp_all_bytes += (sz->_cp_bytes = sz->count(this));2050sz->_cp_all_bytes += (sz->_cp_tags_bytes = sz->count_array(tags()));2051sz->_cp_all_bytes += (sz->_cp_cache_bytes = sz->count(cache()));2052sz->_cp_all_bytes += (sz->_cp_operands_bytes = sz->count_array(operands()));2053sz->_cp_all_bytes += (sz->_cp_refmap_bytes = sz->count_array(reference_map()));20542055sz->_ro_bytes += sz->_cp_operands_bytes + sz->_cp_tags_bytes +2056sz->_cp_refmap_bytes;2057sz->_rw_bytes += sz->_cp_bytes + sz->_cp_cache_bytes;2058}2059#endif // INCLUDE_SERVICES20602061// Verification20622063void ConstantPool::verify_on(outputStream* st) {2064guarantee(is_constantPool(), "object must be constant pool");2065for (int i = 0; i< length(); i++) {2066constantTag tag = tag_at(i);2067CPSlot entry = slot_at(i);2068if (tag.is_klass()) {2069if (entry.is_resolved()) {2070guarantee(entry.get_klass()->is_klass(), "should be klass");2071}2072} else if (tag.is_unresolved_klass()) {2073if (entry.is_resolved()) {2074guarantee(entry.get_klass()->is_klass(), "should be klass");2075}2076} else if (tag.is_symbol()) {2077guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count");2078} else if (tag.is_string()) {2079guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count");2080}2081}2082if (cache() != NULL) {2083// Note: cache() can be NULL before a class is completely setup or2084// in temporary constant pools used during constant pool merging2085guarantee(cache()->is_constantPoolCache(), "should be constant pool cache");2086}2087if (pool_holder() != NULL) {2088// Note: pool_holder() can be NULL in temporary constant pools2089// used during constant pool merging2090guarantee(pool_holder()->is_klass(), "should be klass");2091}2092}209320942095void SymbolHashMap::add_entry(Symbol* sym, u2 value) {2096char *str = sym->as_utf8();2097unsigned int hash = compute_hash(str, sym->utf8_length());2098unsigned int index = hash % table_size();20992100// check if already in map2101// we prefer the first entry since it is more likely to be what was used in2102// the class file2103for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) {2104assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL");2105if (en->hash() == hash && en->symbol() == sym) {2106return; // already there2107}2108}21092110SymbolHashMapEntry* entry = new SymbolHashMapEntry(hash, sym, value);2111entry->set_next(bucket(index));2112_buckets[index].set_entry(entry);2113assert(entry->symbol() != NULL, "SymbolHashMapEntry symbol is NULL");2114}21152116SymbolHashMapEntry* SymbolHashMap::find_entry(Symbol* sym) {2117assert(sym != NULL, "SymbolHashMap::find_entry - symbol is NULL");2118char *str = sym->as_utf8();2119int len = sym->utf8_length();2120unsigned int hash = SymbolHashMap::compute_hash(str, len);2121unsigned int index = hash % table_size();2122for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) {2123assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL");2124if (en->hash() == hash && en->symbol() == sym) {2125return en;2126}2127}2128return NULL;2129}213021312132