src/share/vm/oops/constantPoolOop.cpp

changeset 435
a61af66fc99e
child 866
a45484ea312d
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/oops/constantPoolOop.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,1269 @@
     1.4 +/*
     1.5 + * Copyright 1997-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/_constantPoolOop.cpp.incl"
    1.30 +
    1.31 +klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
    1.32 +  // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
    1.33 +  // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
    1.34 +  // tag is not updated atomicly.
    1.35 +  oop entry = *(this_oop->obj_at_addr(which));
    1.36 +  if (entry->is_klass()) {
    1.37 +    // Already resolved - return entry.
    1.38 +    return (klassOop)entry;
    1.39 +  }
    1.40 +
    1.41 +  // Acquire lock on constant oop while doing update. After we get the lock, we check if another object
    1.42 +  // already has updated the object
    1.43 +  assert(THREAD->is_Java_thread(), "must be a Java thread");
    1.44 +  bool do_resolve = false;
    1.45 +  bool in_error = false;
    1.46 +
    1.47 +  symbolHandle name;
    1.48 +  Handle       loader;
    1.49 +  { ObjectLocker ol(this_oop, THREAD);
    1.50 +
    1.51 +    if (this_oop->tag_at(which).is_unresolved_klass()) {
    1.52 +      if (this_oop->tag_at(which).is_unresolved_klass_in_error()) {
    1.53 +        in_error = true;
    1.54 +      } else {
    1.55 +        do_resolve = true;
    1.56 +        name   = symbolHandle(THREAD, this_oop->unresolved_klass_at(which));
    1.57 +        loader = Handle(THREAD, instanceKlass::cast(this_oop->pool_holder())->class_loader());
    1.58 +      }
    1.59 +    }
    1.60 +  } // unlocking constantPool
    1.61 +
    1.62 +
    1.63 +  // The original attempt to resolve this constant pool entry failed so find the
    1.64 +  // original error and throw it again (JVMS 5.4.3).
    1.65 +  if (in_error) {
    1.66 +    symbolOop error = SystemDictionary::find_resolution_error(this_oop, which);
    1.67 +    guarantee(error != (symbolOop)NULL, "tag mismatch with resolution error table");
    1.68 +    ResourceMark rm;
    1.69 +    // exception text will be the class name
    1.70 +    const char* className = this_oop->unresolved_klass_at(which)->as_C_string();
    1.71 +    THROW_MSG_0(error, className);
    1.72 +  }
    1.73 +
    1.74 +  if (do_resolve) {
    1.75 +    // this_oop must be unlocked during resolve_or_fail
    1.76 +    oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
    1.77 +    Handle h_prot (THREAD, protection_domain);
    1.78 +    klassOop k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);
    1.79 +    KlassHandle k;
    1.80 +    if (!HAS_PENDING_EXCEPTION) {
    1.81 +      k = KlassHandle(THREAD, k_oop);
    1.82 +      // Do access check for klasses
    1.83 +      verify_constant_pool_resolve(this_oop, k, THREAD);
    1.84 +    }
    1.85 +
    1.86 +    // Failed to resolve class. We must record the errors so that subsequent attempts
    1.87 +    // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
    1.88 +    if (HAS_PENDING_EXCEPTION) {
    1.89 +      ResourceMark rm;
    1.90 +      symbolHandle error(PENDING_EXCEPTION->klass()->klass_part()->name());
    1.91 +
    1.92 +      bool throw_orig_error = false;
    1.93 +      {
    1.94 +        ObjectLocker ol (this_oop, THREAD);
    1.95 +
    1.96 +        // some other thread has beaten us and has resolved the class.
    1.97 +        if (this_oop->tag_at(which).is_klass()) {
    1.98 +          CLEAR_PENDING_EXCEPTION;
    1.99 +          entry = this_oop->resolved_klass_at(which);
   1.100 +          return (klassOop)entry;
   1.101 +        }
   1.102 +
   1.103 +        if (!PENDING_EXCEPTION->
   1.104 +              is_a(SystemDictionary::linkageError_klass())) {
   1.105 +          // Just throw the exception and don't prevent these classes from
   1.106 +          // being loaded due to virtual machine errors like StackOverflow
   1.107 +          // and OutOfMemoryError, etc, or if the thread was hit by stop()
   1.108 +          // Needs clarification to section 5.4.3 of the VM spec (see 6308271)
   1.109 +        }
   1.110 +        else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) {
   1.111 +          SystemDictionary::add_resolution_error(this_oop, which, error);
   1.112 +          this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError);
   1.113 +        } else {
   1.114 +          // some other thread has put the class in error state.
   1.115 +          error = symbolHandle(SystemDictionary::find_resolution_error(this_oop, which));
   1.116 +          assert(!error.is_null(), "checking");
   1.117 +          throw_orig_error = true;
   1.118 +        }
   1.119 +      } // unlocked
   1.120 +
   1.121 +      if (throw_orig_error) {
   1.122 +        CLEAR_PENDING_EXCEPTION;
   1.123 +        ResourceMark rm;
   1.124 +        const char* className = this_oop->unresolved_klass_at(which)->as_C_string();
   1.125 +        THROW_MSG_0(error, className);
   1.126 +      }
   1.127 +
   1.128 +      return 0;
   1.129 +    }
   1.130 +
   1.131 +    if (TraceClassResolution && !k()->klass_part()->oop_is_array()) {
   1.132 +      // skip resolving the constant pool so that this code get's
   1.133 +      // called the next time some bytecodes refer to this class.
   1.134 +      ResourceMark rm;
   1.135 +      int line_number = -1;
   1.136 +      const char * source_file = NULL;
   1.137 +      if (JavaThread::current()->has_last_Java_frame()) {
   1.138 +        // try to identify the method which called this function.
   1.139 +        vframeStream vfst(JavaThread::current());
   1.140 +        if (!vfst.at_end()) {
   1.141 +          line_number = vfst.method()->line_number_from_bci(vfst.bci());
   1.142 +          symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name();
   1.143 +          if (s != NULL) {
   1.144 +            source_file = s->as_C_string();
   1.145 +          }
   1.146 +        }
   1.147 +      }
   1.148 +      if (k() != this_oop->pool_holder()) {
   1.149 +        // only print something if the classes are different
   1.150 +        if (source_file != NULL) {
   1.151 +          tty->print("RESOLVE %s %s %s:%d\n",
   1.152 +                     instanceKlass::cast(this_oop->pool_holder())->external_name(),
   1.153 +                     instanceKlass::cast(k())->external_name(), source_file, line_number);
   1.154 +        } else {
   1.155 +          tty->print("RESOLVE %s %s\n",
   1.156 +                     instanceKlass::cast(this_oop->pool_holder())->external_name(),
   1.157 +                     instanceKlass::cast(k())->external_name());
   1.158 +        }
   1.159 +      }
   1.160 +      return k();
   1.161 +    } else {
   1.162 +      ObjectLocker ol (this_oop, THREAD);
   1.163 +      // Only updated constant pool - if it is resolved.
   1.164 +      do_resolve = this_oop->tag_at(which).is_unresolved_klass();
   1.165 +      if (do_resolve) {
   1.166 +        this_oop->klass_at_put(which, k());
   1.167 +      }
   1.168 +    }
   1.169 +  }
   1.170 +
   1.171 +  entry = this_oop->resolved_klass_at(which);
   1.172 +  assert(entry->is_klass(), "must be resolved at this point");
   1.173 +  return (klassOop)entry;
   1.174 +}
   1.175 +
   1.176 +
   1.177 +// Does not update constantPoolOop - to avoid any exception throwing. Used
   1.178 +// by compiler and exception handling.  Also used to avoid classloads for
   1.179 +// instanceof operations. Returns NULL if the class has not been loaded or
   1.180 +// if the verification of constant pool failed
   1.181 +klassOop constantPoolOopDesc::klass_at_if_loaded(constantPoolHandle this_oop, int which) {
   1.182 +  oop entry = *this_oop->obj_at_addr(which);
   1.183 +  if (entry->is_klass()) {
   1.184 +    return (klassOop)entry;
   1.185 +  } else {
   1.186 +    assert(entry->is_symbol(), "must be either symbol or klass");
   1.187 +    Thread *thread = Thread::current();
   1.188 +    symbolHandle name (thread, (symbolOop)entry);
   1.189 +    oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader();
   1.190 +    oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
   1.191 +    Handle h_prot (thread, protection_domain);
   1.192 +    Handle h_loader (thread, loader);
   1.193 +    klassOop k = SystemDictionary::find(name, h_loader, h_prot, thread);
   1.194 +
   1.195 +    if (k != NULL) {
   1.196 +      // Make sure that resolving is legal
   1.197 +      EXCEPTION_MARK;
   1.198 +      KlassHandle klass(THREAD, k);
   1.199 +      // return NULL if verification fails
   1.200 +      verify_constant_pool_resolve(this_oop, klass, THREAD);
   1.201 +      if (HAS_PENDING_EXCEPTION) {
   1.202 +        CLEAR_PENDING_EXCEPTION;
   1.203 +        return NULL;
   1.204 +      }
   1.205 +      return klass();
   1.206 +    } else {
   1.207 +      return k;
   1.208 +    }
   1.209 +  }
   1.210 +}
   1.211 +
   1.212 +
   1.213 +klassOop constantPoolOopDesc::klass_ref_at_if_loaded(constantPoolHandle this_oop, int which) {
   1.214 +  return klass_at_if_loaded(this_oop, this_oop->klass_ref_index_at(which));
   1.215 +}
   1.216 +
   1.217 +
   1.218 +// This is an interface for the compiler that allows accessing non-resolved entries
   1.219 +// in the constant pool - but still performs the validations tests. Must be used
   1.220 +// in a pre-parse of the compiler - to determine what it can do and not do.
   1.221 +// Note: We cannot update the ConstantPool from the vm_thread.
   1.222 +klassOop constantPoolOopDesc::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) {
   1.223 +  int which = this_oop->klass_ref_index_at(index);
   1.224 +  oop entry = *this_oop->obj_at_addr(which);
   1.225 +  if (entry->is_klass()) {
   1.226 +    return (klassOop)entry;
   1.227 +  } else {
   1.228 +    assert(entry->is_symbol(), "must be either symbol or klass");
   1.229 +    symbolHandle name (THREAD, (symbolOop)entry);
   1.230 +    oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader();
   1.231 +    oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
   1.232 +    Handle h_loader(THREAD, loader);
   1.233 +    Handle h_prot  (THREAD, protection_domain);
   1.234 +    KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD));
   1.235 +
   1.236 +    // Do access check for klasses
   1.237 +    if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL);
   1.238 +    return k();
   1.239 +  }
   1.240 +}
   1.241 +
   1.242 +
   1.243 +symbolOop constantPoolOopDesc::uncached_name_ref_at(int which) {
   1.244 +  jint ref_index = name_and_type_at(uncached_name_and_type_ref_index_at(which));
   1.245 +  int name_index = extract_low_short_from_int(ref_index);
   1.246 +  return symbol_at(name_index);
   1.247 +}
   1.248 +
   1.249 +
   1.250 +symbolOop constantPoolOopDesc::uncached_signature_ref_at(int which) {
   1.251 +  jint ref_index = name_and_type_at(uncached_name_and_type_ref_index_at(which));
   1.252 +  int signature_index = extract_high_short_from_int(ref_index);
   1.253 +  return symbol_at(signature_index);
   1.254 +}
   1.255 +
   1.256 +
   1.257 +int constantPoolOopDesc::uncached_name_and_type_ref_index_at(int which) {
   1.258 +  jint ref_index = field_or_method_at(which, true);
   1.259 +  return extract_high_short_from_int(ref_index);
   1.260 +}
   1.261 +
   1.262 +
   1.263 +int constantPoolOopDesc::uncached_klass_ref_index_at(int which) {
   1.264 +  jint ref_index = field_or_method_at(which, true);
   1.265 +  return extract_low_short_from_int(ref_index);
   1.266 +}
   1.267 +
   1.268 +
   1.269 +void constantPoolOopDesc::verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle k, TRAPS) {
   1.270 + if (k->oop_is_instance() || k->oop_is_objArray()) {
   1.271 +    instanceKlassHandle holder (THREAD, this_oop->pool_holder());
   1.272 +    klassOop elem_oop = k->oop_is_instance() ? k() : objArrayKlass::cast(k())->bottom_klass();
   1.273 +    KlassHandle element (THREAD, elem_oop);
   1.274 +
   1.275 +    // The element type could be a typeArray - we only need the access check if it is
   1.276 +    // an reference to another class
   1.277 +    if (element->oop_is_instance()) {
   1.278 +      LinkResolver::check_klass_accessability(holder, element, CHECK);
   1.279 +    }
   1.280 +  }
   1.281 +}
   1.282 +
   1.283 +
   1.284 +int constantPoolOopDesc::klass_ref_index_at(int which) {
   1.285 +  jint ref_index = field_or_method_at(which, false);
   1.286 +  return extract_low_short_from_int(ref_index);
   1.287 +}
   1.288 +
   1.289 +
   1.290 +int constantPoolOopDesc::name_and_type_ref_index_at(int which) {
   1.291 +  jint ref_index = field_or_method_at(which, false);
   1.292 +  return extract_high_short_from_int(ref_index);
   1.293 +}
   1.294 +
   1.295 +
   1.296 +int constantPoolOopDesc::name_ref_index_at(int which) {
   1.297 +  jint ref_index = name_and_type_at(which);
   1.298 +  return extract_low_short_from_int(ref_index);
   1.299 +}
   1.300 +
   1.301 +
   1.302 +int constantPoolOopDesc::signature_ref_index_at(int which) {
   1.303 +  jint ref_index = name_and_type_at(which);
   1.304 +  return extract_high_short_from_int(ref_index);
   1.305 +}
   1.306 +
   1.307 +
   1.308 +klassOop constantPoolOopDesc::klass_ref_at(int which, TRAPS) {
   1.309 +  return klass_at(klass_ref_index_at(which), CHECK_NULL);
   1.310 +}
   1.311 +
   1.312 +
   1.313 +symbolOop constantPoolOopDesc::klass_name_at(int which) {
   1.314 +  assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(),
   1.315 +         "Corrupted constant pool");
   1.316 +  // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
   1.317 +  // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
   1.318 +  // tag is not updated atomicly.
   1.319 +  oop entry = *(obj_at_addr(which));
   1.320 +  if (entry->is_klass()) {
   1.321 +    // Already resolved - return entry's name.
   1.322 +    return klassOop(entry)->klass_part()->name();
   1.323 +  } else {
   1.324 +    assert(entry->is_symbol(), "must be either symbol or klass");
   1.325 +    return (symbolOop)entry;
   1.326 +  }
   1.327 +}
   1.328 +
   1.329 +symbolOop constantPoolOopDesc::klass_ref_at_noresolve(int which) {
   1.330 +  jint ref_index = klass_ref_index_at(which);
   1.331 +  return klass_at_noresolve(ref_index);
   1.332 +}
   1.333 +
   1.334 +char* constantPoolOopDesc::string_at_noresolve(int which) {
   1.335 +  // Test entry type in case string is resolved while in here.
   1.336 +  oop entry = *(obj_at_addr(which));
   1.337 +  if (entry->is_symbol()) {
   1.338 +    return ((symbolOop)entry)->as_C_string();
   1.339 +  } else {
   1.340 +    return java_lang_String::as_utf8_string(entry);
   1.341 +  }
   1.342 +}
   1.343 +
   1.344 +
   1.345 +symbolOop constantPoolOopDesc::name_ref_at(int which) {
   1.346 +  jint ref_index = name_and_type_at(name_and_type_ref_index_at(which));
   1.347 +  int name_index = extract_low_short_from_int(ref_index);
   1.348 +  return symbol_at(name_index);
   1.349 +}
   1.350 +
   1.351 +
   1.352 +symbolOop constantPoolOopDesc::signature_ref_at(int which) {
   1.353 +  jint ref_index = name_and_type_at(name_and_type_ref_index_at(which));
   1.354 +  int signature_index = extract_high_short_from_int(ref_index);
   1.355 +  return symbol_at(signature_index);
   1.356 +}
   1.357 +
   1.358 +
   1.359 +BasicType constantPoolOopDesc::basic_type_for_signature_at(int which) {
   1.360 +  return FieldType::basic_type(symbol_at(which));
   1.361 +}
   1.362 +
   1.363 +
   1.364 +void constantPoolOopDesc::resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS) {
   1.365 +  for (int index = 1; index < this_oop->length(); index++) { // Index 0 is unused
   1.366 +    if (this_oop->tag_at(index).is_unresolved_string()) {
   1.367 +      this_oop->string_at(index, CHECK);
   1.368 +    }
   1.369 +  }
   1.370 +}
   1.371 +
   1.372 +oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
   1.373 +  oop entry = *(this_oop->obj_at_addr(which));
   1.374 +  if (entry->is_symbol()) {
   1.375 +    ObjectLocker ol(this_oop, THREAD);
   1.376 +    if (this_oop->tag_at(which).is_unresolved_string()) {
   1.377 +      // Intern string
   1.378 +      symbolOop sym = this_oop->unresolved_string_at(which);
   1.379 +      entry = StringTable::intern(sym, CHECK_(constantPoolOop(NULL)));
   1.380 +      this_oop->string_at_put(which, entry);
   1.381 +    } else {
   1.382 +      // Another thread beat us and interned string, read string from constant pool
   1.383 +      entry = this_oop->resolved_string_at(which);
   1.384 +    }
   1.385 +  }
   1.386 +  assert(java_lang_String::is_instance(entry), "must be string");
   1.387 +  return entry;
   1.388 +}
   1.389 +
   1.390 +
   1.391 +bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k,
   1.392 +                                                int which) {
   1.393 +  // Names are interned, so we can compare symbolOops directly
   1.394 +  symbolOop cp_name = klass_name_at(which);
   1.395 +  return (cp_name == k->name());
   1.396 +}
   1.397 +
   1.398 +
   1.399 +int constantPoolOopDesc::pre_resolve_shared_klasses(TRAPS) {
   1.400 +  ResourceMark rm;
   1.401 +  int count = 0;
   1.402 +  for (int index = 1; index < tags()->length(); index++) { // Index 0 is unused
   1.403 +    if (tag_at(index).is_unresolved_string()) {
   1.404 +      // Intern string
   1.405 +      symbolOop sym = unresolved_string_at(index);
   1.406 +      oop entry = StringTable::intern(sym, CHECK_(-1));
   1.407 +      string_at_put(index, entry);
   1.408 +    }
   1.409 +  }
   1.410 +  return count;
   1.411 +}
   1.412 +
   1.413 +
   1.414 +// Iterate over symbols which are used as class, field, method names and
   1.415 +// signatures (in preparation for writing to the shared archive).
   1.416 +
   1.417 +void constantPoolOopDesc::shared_symbols_iterate(OopClosure* closure) {
   1.418 +  for (int index = 1; index < length(); index++) { // Index 0 is unused
   1.419 +    switch (tag_at(index).value()) {
   1.420 +
   1.421 +    case JVM_CONSTANT_UnresolvedClass:
   1.422 +      closure->do_oop(obj_at_addr(index));
   1.423 +      break;
   1.424 +
   1.425 +    case JVM_CONSTANT_NameAndType:
   1.426 +      {
   1.427 +        int i = *int_at_addr(index);
   1.428 +        closure->do_oop(obj_at_addr((unsigned)i >> 16));
   1.429 +        closure->do_oop(obj_at_addr((unsigned)i & 0xffff));
   1.430 +      }
   1.431 +      break;
   1.432 +
   1.433 +    case JVM_CONSTANT_Class:
   1.434 +    case JVM_CONSTANT_InterfaceMethodref:
   1.435 +    case JVM_CONSTANT_Fieldref:
   1.436 +    case JVM_CONSTANT_Methodref:
   1.437 +    case JVM_CONSTANT_Integer:
   1.438 +    case JVM_CONSTANT_Float:
   1.439 +      // Do nothing!  Not an oop.
   1.440 +      // These constant types do not reference symbols at this point.
   1.441 +      break;
   1.442 +
   1.443 +    case JVM_CONSTANT_String:
   1.444 +      // Do nothing!  Not a symbol.
   1.445 +      break;
   1.446 +
   1.447 +    case JVM_CONSTANT_UnresolvedString:
   1.448 +    case JVM_CONSTANT_Utf8:
   1.449 +      // These constants are symbols, but unless these symbols are
   1.450 +      // actually to be used for something, we don't want to mark them.
   1.451 +      break;
   1.452 +
   1.453 +    case JVM_CONSTANT_Long:
   1.454 +    case JVM_CONSTANT_Double:
   1.455 +      // Do nothing!  Not an oop. (But takes two pool entries.)
   1.456 +      ++index;
   1.457 +      break;
   1.458 +
   1.459 +    default:
   1.460 +      ShouldNotReachHere();
   1.461 +      break;
   1.462 +    }
   1.463 +  }
   1.464 +}
   1.465 +
   1.466 +
   1.467 +// Iterate over the [one] tags array (in preparation for writing to the
   1.468 +// shared archive).
   1.469 +
   1.470 +void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) {
   1.471 +  closure->do_oop(tags_addr());
   1.472 +}
   1.473 +
   1.474 +
   1.475 +// Iterate over String objects (in preparation for writing to the shared
   1.476 +// archive).
   1.477 +
   1.478 +void constantPoolOopDesc::shared_strings_iterate(OopClosure* closure) {
   1.479 +  for (int index = 1; index < length(); index++) { // Index 0 is unused
   1.480 +    switch (tag_at(index).value()) {
   1.481 +
   1.482 +    case JVM_CONSTANT_UnresolvedClass:
   1.483 +    case JVM_CONSTANT_NameAndType:
   1.484 +      // Do nothing!  Not a String.
   1.485 +      break;
   1.486 +
   1.487 +    case JVM_CONSTANT_Class:
   1.488 +    case JVM_CONSTANT_InterfaceMethodref:
   1.489 +    case JVM_CONSTANT_Fieldref:
   1.490 +    case JVM_CONSTANT_Methodref:
   1.491 +    case JVM_CONSTANT_Integer:
   1.492 +    case JVM_CONSTANT_Float:
   1.493 +      // Do nothing!  Not an oop.
   1.494 +      // These constant types do not reference symbols at this point.
   1.495 +      break;
   1.496 +
   1.497 +    case JVM_CONSTANT_String:
   1.498 +      closure->do_oop(obj_at_addr(index));
   1.499 +      break;
   1.500 +
   1.501 +    case JVM_CONSTANT_UnresolvedString:
   1.502 +    case JVM_CONSTANT_Utf8:
   1.503 +      // These constants are symbols, but unless these symbols are
   1.504 +      // actually to be used for something, we don't want to mark them.
   1.505 +      break;
   1.506 +
   1.507 +    case JVM_CONSTANT_Long:
   1.508 +    case JVM_CONSTANT_Double:
   1.509 +      // Do nothing!  Not an oop. (But takes two pool entries.)
   1.510 +      ++index;
   1.511 +      break;
   1.512 +
   1.513 +    default:
   1.514 +      ShouldNotReachHere();
   1.515 +      break;
   1.516 +    }
   1.517 +  }
   1.518 +}
   1.519 +
   1.520 +
   1.521 +// Compare this constant pool's entry at index1 to the constant pool
   1.522 +// cp2's entry at index2.
   1.523 +bool constantPoolOopDesc::compare_entry_to(int index1, constantPoolHandle cp2,
   1.524 +       int index2, TRAPS) {
   1.525 +
   1.526 +  jbyte t1 = tag_at(index1).value();
   1.527 +  jbyte t2 = cp2->tag_at(index2).value();
   1.528 +
   1.529 +
   1.530 +  // JVM_CONSTANT_UnresolvedClassInError is equal to JVM_CONSTANT_UnresolvedClass
   1.531 +  // when comparing
   1.532 +  if (t1 == JVM_CONSTANT_UnresolvedClassInError) {
   1.533 +    t1 = JVM_CONSTANT_UnresolvedClass;
   1.534 +  }
   1.535 +  if (t2 == JVM_CONSTANT_UnresolvedClassInError) {
   1.536 +    t2 = JVM_CONSTANT_UnresolvedClass;
   1.537 +  }
   1.538 +
   1.539 +  if (t1 != t2) {
   1.540 +    // Not the same entry type so there is nothing else to check. Note
   1.541 +    // that this style of checking will consider resolved/unresolved
   1.542 +    // class pairs and resolved/unresolved string pairs as different.
   1.543 +    // From the constantPoolOop API point of view, this is correct
   1.544 +    // behavior. See constantPoolKlass::merge() to see how this plays
   1.545 +    // out in the context of constantPoolOop merging.
   1.546 +    return false;
   1.547 +  }
   1.548 +
   1.549 +  switch (t1) {
   1.550 +  case JVM_CONSTANT_Class:
   1.551 +  {
   1.552 +    klassOop k1 = klass_at(index1, CHECK_false);
   1.553 +    klassOop k2 = cp2->klass_at(index2, CHECK_false);
   1.554 +    if (k1 == k2) {
   1.555 +      return true;
   1.556 +    }
   1.557 +  } break;
   1.558 +
   1.559 +  case JVM_CONSTANT_ClassIndex:
   1.560 +  {
   1.561 +    int recur1 = klass_index_at(index1);
   1.562 +    int recur2 = cp2->klass_index_at(index2);
   1.563 +    bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);
   1.564 +    if (match) {
   1.565 +      return true;
   1.566 +    }
   1.567 +  } break;
   1.568 +
   1.569 +  case JVM_CONSTANT_Double:
   1.570 +  {
   1.571 +    jdouble d1 = double_at(index1);
   1.572 +    jdouble d2 = cp2->double_at(index2);
   1.573 +    if (d1 == d2) {
   1.574 +      return true;
   1.575 +    }
   1.576 +  } break;
   1.577 +
   1.578 +  case JVM_CONSTANT_Fieldref:
   1.579 +  case JVM_CONSTANT_InterfaceMethodref:
   1.580 +  case JVM_CONSTANT_Methodref:
   1.581 +  {
   1.582 +    int recur1 = uncached_klass_ref_index_at(index1);
   1.583 +    int recur2 = cp2->uncached_klass_ref_index_at(index2);
   1.584 +    bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);
   1.585 +    if (match) {
   1.586 +      recur1 = uncached_name_and_type_ref_index_at(index1);
   1.587 +      recur2 = cp2->uncached_name_and_type_ref_index_at(index2);
   1.588 +      match = compare_entry_to(recur1, cp2, recur2, CHECK_false);
   1.589 +      if (match) {
   1.590 +        return true;
   1.591 +      }
   1.592 +    }
   1.593 +  } break;
   1.594 +
   1.595 +  case JVM_CONSTANT_Float:
   1.596 +  {
   1.597 +    jfloat f1 = float_at(index1);
   1.598 +    jfloat f2 = cp2->float_at(index2);
   1.599 +    if (f1 == f2) {
   1.600 +      return true;
   1.601 +    }
   1.602 +  } break;
   1.603 +
   1.604 +  case JVM_CONSTANT_Integer:
   1.605 +  {
   1.606 +    jint i1 = int_at(index1);
   1.607 +    jint i2 = cp2->int_at(index2);
   1.608 +    if (i1 == i2) {
   1.609 +      return true;
   1.610 +    }
   1.611 +  } break;
   1.612 +
   1.613 +  case JVM_CONSTANT_Long:
   1.614 +  {
   1.615 +    jlong l1 = long_at(index1);
   1.616 +    jlong l2 = cp2->long_at(index2);
   1.617 +    if (l1 == l2) {
   1.618 +      return true;
   1.619 +    }
   1.620 +  } break;
   1.621 +
   1.622 +  case JVM_CONSTANT_NameAndType:
   1.623 +  {
   1.624 +    int recur1 = name_ref_index_at(index1);
   1.625 +    int recur2 = cp2->name_ref_index_at(index2);
   1.626 +    bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);
   1.627 +    if (match) {
   1.628 +      recur1 = signature_ref_index_at(index1);
   1.629 +      recur2 = cp2->signature_ref_index_at(index2);
   1.630 +      match = compare_entry_to(recur1, cp2, recur2, CHECK_false);
   1.631 +      if (match) {
   1.632 +        return true;
   1.633 +      }
   1.634 +    }
   1.635 +  } break;
   1.636 +
   1.637 +  case JVM_CONSTANT_String:
   1.638 +  {
   1.639 +    oop s1 = string_at(index1, CHECK_false);
   1.640 +    oop s2 = cp2->string_at(index2, CHECK_false);
   1.641 +    if (s1 == s2) {
   1.642 +      return true;
   1.643 +    }
   1.644 +  } break;
   1.645 +
   1.646 +  case JVM_CONSTANT_StringIndex:
   1.647 +  {
   1.648 +    int recur1 = string_index_at(index1);
   1.649 +    int recur2 = cp2->string_index_at(index2);
   1.650 +    bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false);
   1.651 +    if (match) {
   1.652 +      return true;
   1.653 +    }
   1.654 +  } break;
   1.655 +
   1.656 +  case JVM_CONSTANT_UnresolvedClass:
   1.657 +  {
   1.658 +    symbolOop k1 = unresolved_klass_at(index1);
   1.659 +    symbolOop k2 = cp2->unresolved_klass_at(index2);
   1.660 +    if (k1 == k2) {
   1.661 +      return true;
   1.662 +    }
   1.663 +  } break;
   1.664 +
   1.665 +  case JVM_CONSTANT_UnresolvedString:
   1.666 +  {
   1.667 +    symbolOop s1 = unresolved_string_at(index1);
   1.668 +    symbolOop s2 = cp2->unresolved_string_at(index2);
   1.669 +    if (s1 == s2) {
   1.670 +      return true;
   1.671 +    }
   1.672 +  } break;
   1.673 +
   1.674 +  case JVM_CONSTANT_Utf8:
   1.675 +  {
   1.676 +    symbolOop s1 = symbol_at(index1);
   1.677 +    symbolOop s2 = cp2->symbol_at(index2);
   1.678 +    if (s1 == s2) {
   1.679 +      return true;
   1.680 +    }
   1.681 +  } break;
   1.682 +
   1.683 +  // Invalid is used as the tag for the second constant pool entry
   1.684 +  // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
   1.685 +  // not be seen by itself.
   1.686 +  case JVM_CONSTANT_Invalid: // fall through
   1.687 +
   1.688 +  default:
   1.689 +    ShouldNotReachHere();
   1.690 +    break;
   1.691 +  }
   1.692 +
   1.693 +  return false;
   1.694 +} // end compare_entry_to()
   1.695 +
   1.696 +
   1.697 +// Copy this constant pool's entries at start_i to end_i (inclusive)
   1.698 +// to the constant pool to_cp's entries starting at to_i. A total of
   1.699 +// (end_i - start_i) + 1 entries are copied.
   1.700 +void constantPoolOopDesc::copy_cp_to(int start_i, int end_i,
   1.701 +       constantPoolHandle to_cp, int to_i, TRAPS) {
   1.702 +
   1.703 +  int dest_i = to_i;  // leave original alone for debug purposes
   1.704 +
   1.705 +  for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
   1.706 +    copy_entry_to(src_i, to_cp, dest_i, CHECK);
   1.707 +
   1.708 +    switch (tag_at(src_i).value()) {
   1.709 +    case JVM_CONSTANT_Double:
   1.710 +    case JVM_CONSTANT_Long:
   1.711 +      // double and long take two constant pool entries
   1.712 +      src_i += 2;
   1.713 +      dest_i += 2;
   1.714 +      break;
   1.715 +
   1.716 +    default:
   1.717 +      // all others take one constant pool entry
   1.718 +      src_i++;
   1.719 +      dest_i++;
   1.720 +      break;
   1.721 +    }
   1.722 +  }
   1.723 +} // end copy_cp_to()
   1.724 +
   1.725 +
   1.726 +// Copy this constant pool's entry at from_i to the constant pool
   1.727 +// to_cp's entry at to_i.
   1.728 +void constantPoolOopDesc::copy_entry_to(int from_i, constantPoolHandle to_cp,
   1.729 +       int to_i, TRAPS) {
   1.730 +
   1.731 +  switch (tag_at(from_i).value()) {
   1.732 +  case JVM_CONSTANT_Class:
   1.733 +  {
   1.734 +    klassOop k = klass_at(from_i, CHECK);
   1.735 +    to_cp->klass_at_put(to_i, k);
   1.736 +  } break;
   1.737 +
   1.738 +  case JVM_CONSTANT_ClassIndex:
   1.739 +  {
   1.740 +    jint ki = klass_index_at(from_i);
   1.741 +    to_cp->klass_index_at_put(to_i, ki);
   1.742 +  } break;
   1.743 +
   1.744 +  case JVM_CONSTANT_Double:
   1.745 +  {
   1.746 +    jdouble d = double_at(from_i);
   1.747 +    to_cp->double_at_put(to_i, d);
   1.748 +    // double takes two constant pool entries so init second entry's tag
   1.749 +    to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);
   1.750 +  } break;
   1.751 +
   1.752 +  case JVM_CONSTANT_Fieldref:
   1.753 +  {
   1.754 +    int class_index = uncached_klass_ref_index_at(from_i);
   1.755 +    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
   1.756 +    to_cp->field_at_put(to_i, class_index, name_and_type_index);
   1.757 +  } break;
   1.758 +
   1.759 +  case JVM_CONSTANT_Float:
   1.760 +  {
   1.761 +    jfloat f = float_at(from_i);
   1.762 +    to_cp->float_at_put(to_i, f);
   1.763 +  } break;
   1.764 +
   1.765 +  case JVM_CONSTANT_Integer:
   1.766 +  {
   1.767 +    jint i = int_at(from_i);
   1.768 +    to_cp->int_at_put(to_i, i);
   1.769 +  } break;
   1.770 +
   1.771 +  case JVM_CONSTANT_InterfaceMethodref:
   1.772 +  {
   1.773 +    int class_index = uncached_klass_ref_index_at(from_i);
   1.774 +    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
   1.775 +    to_cp->interface_method_at_put(to_i, class_index, name_and_type_index);
   1.776 +  } break;
   1.777 +
   1.778 +  case JVM_CONSTANT_Long:
   1.779 +  {
   1.780 +    jlong l = long_at(from_i);
   1.781 +    to_cp->long_at_put(to_i, l);
   1.782 +    // long takes two constant pool entries so init second entry's tag
   1.783 +    to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);
   1.784 +  } break;
   1.785 +
   1.786 +  case JVM_CONSTANT_Methodref:
   1.787 +  {
   1.788 +    int class_index = uncached_klass_ref_index_at(from_i);
   1.789 +    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
   1.790 +    to_cp->method_at_put(to_i, class_index, name_and_type_index);
   1.791 +  } break;
   1.792 +
   1.793 +  case JVM_CONSTANT_NameAndType:
   1.794 +  {
   1.795 +    int name_ref_index = name_ref_index_at(from_i);
   1.796 +    int signature_ref_index = signature_ref_index_at(from_i);
   1.797 +    to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index);
   1.798 +  } break;
   1.799 +
   1.800 +  case JVM_CONSTANT_String:
   1.801 +  {
   1.802 +    oop s = string_at(from_i, CHECK);
   1.803 +    to_cp->string_at_put(to_i, s);
   1.804 +  } break;
   1.805 +
   1.806 +  case JVM_CONSTANT_StringIndex:
   1.807 +  {
   1.808 +    jint si = string_index_at(from_i);
   1.809 +    to_cp->string_index_at_put(to_i, si);
   1.810 +  } break;
   1.811 +
   1.812 +  case JVM_CONSTANT_UnresolvedClass:
   1.813 +  {
   1.814 +    symbolOop k = unresolved_klass_at(from_i);
   1.815 +    to_cp->unresolved_klass_at_put(to_i, k);
   1.816 +  } break;
   1.817 +
   1.818 +  case JVM_CONSTANT_UnresolvedClassInError:
   1.819 +  {
   1.820 +    symbolOop k = unresolved_klass_at(from_i);
   1.821 +    to_cp->unresolved_klass_at_put(to_i, k);
   1.822 +    to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError);
   1.823 +  } break;
   1.824 +
   1.825 +
   1.826 +  case JVM_CONSTANT_UnresolvedString:
   1.827 +  {
   1.828 +    symbolOop s = unresolved_string_at(from_i);
   1.829 +    to_cp->unresolved_string_at_put(to_i, s);
   1.830 +  } break;
   1.831 +
   1.832 +  case JVM_CONSTANT_Utf8:
   1.833 +  {
   1.834 +    symbolOop s = symbol_at(from_i);
   1.835 +    to_cp->symbol_at_put(to_i, s);
   1.836 +  } break;
   1.837 +
   1.838 +  // Invalid is used as the tag for the second constant pool entry
   1.839 +  // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
   1.840 +  // not be seen by itself.
   1.841 +  case JVM_CONSTANT_Invalid: // fall through
   1.842 +
   1.843 +  default:
   1.844 +  {
   1.845 +    jbyte bad_value = tag_at(from_i).value(); // leave a breadcrumb
   1.846 +    ShouldNotReachHere();
   1.847 +  } break;
   1.848 +  }
   1.849 +} // end copy_entry_to()
   1.850 +
   1.851 +
   1.852 +// Search constant pool search_cp for an entry that matches this
   1.853 +// constant pool's entry at pattern_i. Returns the index of a
   1.854 +// matching entry or zero (0) if there is no matching entry.
   1.855 +int constantPoolOopDesc::find_matching_entry(int pattern_i,
   1.856 +      constantPoolHandle search_cp, TRAPS) {
   1.857 +
   1.858 +  // index zero (0) is not used
   1.859 +  for (int i = 1; i < search_cp->length(); i++) {
   1.860 +    bool found = compare_entry_to(pattern_i, search_cp, i, CHECK_0);
   1.861 +    if (found) {
   1.862 +      return i;
   1.863 +    }
   1.864 +  }
   1.865 +
   1.866 +  return 0;  // entry not found; return unused index zero (0)
   1.867 +} // end find_matching_entry()
   1.868 +
   1.869 +
   1.870 +#ifndef PRODUCT
   1.871 +
   1.872 +const char* constantPoolOopDesc::printable_name_at(int which) {
   1.873 +
   1.874 +  constantTag tag = tag_at(which);
   1.875 +
   1.876 +  if (tag.is_unresolved_string() || tag.is_string()) {
   1.877 +    return string_at_noresolve(which);
   1.878 +  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
   1.879 +    return klass_name_at(which)->as_C_string();
   1.880 +  } else if (tag.is_symbol()) {
   1.881 +    return symbol_at(which)->as_C_string();
   1.882 +  }
   1.883 +  return "";
   1.884 +}
   1.885 +
   1.886 +#endif // PRODUCT
   1.887 +
   1.888 +
   1.889 +// JVMTI GetConstantPool support
   1.890 +
   1.891 +// For temporary use until code is stable.
   1.892 +#define DBG(code)
   1.893 +
   1.894 +static const char* WARN_MSG = "Must not be such entry!";
   1.895 +
   1.896 +static void print_cpool_bytes(jint cnt, u1 *bytes) {
   1.897 +  jint size = 0;
   1.898 +  u2   idx1, idx2;
   1.899 +
   1.900 +  for (jint idx = 1; idx < cnt; idx++) {
   1.901 +    jint ent_size = 0;
   1.902 +    u1   tag  = *bytes++;
   1.903 +    size++;                       // count tag
   1.904 +
   1.905 +    printf("const #%03d, tag: %02d ", idx, tag);
   1.906 +    switch(tag) {
   1.907 +      case JVM_CONSTANT_Invalid: {
   1.908 +        printf("Invalid");
   1.909 +        break;
   1.910 +      }
   1.911 +      case JVM_CONSTANT_Unicode: {
   1.912 +        printf("Unicode      %s", WARN_MSG);
   1.913 +        break;
   1.914 +      }
   1.915 +      case JVM_CONSTANT_Utf8: {
   1.916 +        u2 len = Bytes::get_Java_u2(bytes);
   1.917 +        char str[128];
   1.918 +        if (len > 127) {
   1.919 +           len = 127;
   1.920 +        }
   1.921 +        strncpy(str, (char *) (bytes+2), len);
   1.922 +        str[len] = '\0';
   1.923 +        printf("Utf8          \"%s\"", str);
   1.924 +        ent_size = 2 + len;
   1.925 +        break;
   1.926 +      }
   1.927 +      case JVM_CONSTANT_Integer: {
   1.928 +        u4 val = Bytes::get_Java_u4(bytes);
   1.929 +        printf("int          %d", *(int *) &val);
   1.930 +        ent_size = 4;
   1.931 +        break;
   1.932 +      }
   1.933 +      case JVM_CONSTANT_Float: {
   1.934 +        u4 val = Bytes::get_Java_u4(bytes);
   1.935 +        printf("float        %5.3ff", *(float *) &val);
   1.936 +        ent_size = 4;
   1.937 +        break;
   1.938 +      }
   1.939 +      case JVM_CONSTANT_Long: {
   1.940 +        u8 val = Bytes::get_Java_u8(bytes);
   1.941 +        printf("long         %lldl", *(jlong *) &val);
   1.942 +        ent_size = 8;
   1.943 +        idx++; // Long takes two cpool slots
   1.944 +        break;
   1.945 +      }
   1.946 +      case JVM_CONSTANT_Double: {
   1.947 +        u8 val = Bytes::get_Java_u8(bytes);
   1.948 +        printf("double       %5.3fd", *(jdouble *)&val);
   1.949 +        ent_size = 8;
   1.950 +        idx++; // Double takes two cpool slots
   1.951 +        break;
   1.952 +      }
   1.953 +      case JVM_CONSTANT_Class: {
   1.954 +        idx1 = Bytes::get_Java_u2(bytes);
   1.955 +        printf("class        #%03d", idx1);
   1.956 +        ent_size = 2;
   1.957 +        break;
   1.958 +      }
   1.959 +      case JVM_CONSTANT_String: {
   1.960 +        idx1 = Bytes::get_Java_u2(bytes);
   1.961 +        printf("String       #%03d", idx1);
   1.962 +        ent_size = 2;
   1.963 +        break;
   1.964 +      }
   1.965 +      case JVM_CONSTANT_Fieldref: {
   1.966 +        idx1 = Bytes::get_Java_u2(bytes);
   1.967 +        idx2 = Bytes::get_Java_u2(bytes+2);
   1.968 +        printf("Field        #%03d, #%03d", (int) idx1, (int) idx2);
   1.969 +        ent_size = 4;
   1.970 +        break;
   1.971 +      }
   1.972 +      case JVM_CONSTANT_Methodref: {
   1.973 +        idx1 = Bytes::get_Java_u2(bytes);
   1.974 +        idx2 = Bytes::get_Java_u2(bytes+2);
   1.975 +        printf("Method       #%03d, #%03d", idx1, idx2);
   1.976 +        ent_size = 4;
   1.977 +        break;
   1.978 +      }
   1.979 +      case JVM_CONSTANT_InterfaceMethodref: {
   1.980 +        idx1 = Bytes::get_Java_u2(bytes);
   1.981 +        idx2 = Bytes::get_Java_u2(bytes+2);
   1.982 +        printf("InterfMethod #%03d, #%03d", idx1, idx2);
   1.983 +        ent_size = 4;
   1.984 +        break;
   1.985 +      }
   1.986 +      case JVM_CONSTANT_NameAndType: {
   1.987 +        idx1 = Bytes::get_Java_u2(bytes);
   1.988 +        idx2 = Bytes::get_Java_u2(bytes+2);
   1.989 +        printf("NameAndType  #%03d, #%03d", idx1, idx2);
   1.990 +        ent_size = 4;
   1.991 +        break;
   1.992 +      }
   1.993 +      case JVM_CONSTANT_ClassIndex: {
   1.994 +        printf("ClassIndex  %s", WARN_MSG);
   1.995 +        break;
   1.996 +      }
   1.997 +      case JVM_CONSTANT_UnresolvedClass: {
   1.998 +        printf("UnresolvedClass: %s", WARN_MSG);
   1.999 +        break;
  1.1000 +      }
  1.1001 +      case JVM_CONSTANT_UnresolvedClassInError: {
  1.1002 +        printf("UnresolvedClassInErr: %s", WARN_MSG);
  1.1003 +        break;
  1.1004 +      }
  1.1005 +      case JVM_CONSTANT_StringIndex: {
  1.1006 +        printf("StringIndex: %s", WARN_MSG);
  1.1007 +        break;
  1.1008 +      }
  1.1009 +      case JVM_CONSTANT_UnresolvedString: {
  1.1010 +        printf("UnresolvedString: %s", WARN_MSG);
  1.1011 +        break;
  1.1012 +      }
  1.1013 +    }
  1.1014 +    printf(";\n");
  1.1015 +    bytes += ent_size;
  1.1016 +    size  += ent_size;
  1.1017 +  }
  1.1018 +  printf("Cpool size: %d\n", size);
  1.1019 +  fflush(0);
  1.1020 +  return;
  1.1021 +} /* end print_cpool_bytes */
  1.1022 +
  1.1023 +
  1.1024 +// Returns size of constant pool entry.
  1.1025 +jint constantPoolOopDesc::cpool_entry_size(jint idx) {
  1.1026 +  switch(tag_at(idx).value()) {
  1.1027 +    case JVM_CONSTANT_Invalid:
  1.1028 +    case JVM_CONSTANT_Unicode:
  1.1029 +      return 1;
  1.1030 +
  1.1031 +    case JVM_CONSTANT_Utf8:
  1.1032 +      return 3 + symbol_at(idx)->utf8_length();
  1.1033 +
  1.1034 +    case JVM_CONSTANT_Class:
  1.1035 +    case JVM_CONSTANT_String:
  1.1036 +    case JVM_CONSTANT_ClassIndex:
  1.1037 +    case JVM_CONSTANT_UnresolvedClass:
  1.1038 +    case JVM_CONSTANT_UnresolvedClassInError:
  1.1039 +    case JVM_CONSTANT_StringIndex:
  1.1040 +    case JVM_CONSTANT_UnresolvedString:
  1.1041 +      return 3;
  1.1042 +
  1.1043 +    case JVM_CONSTANT_Integer:
  1.1044 +    case JVM_CONSTANT_Float:
  1.1045 +    case JVM_CONSTANT_Fieldref:
  1.1046 +    case JVM_CONSTANT_Methodref:
  1.1047 +    case JVM_CONSTANT_InterfaceMethodref:
  1.1048 +    case JVM_CONSTANT_NameAndType:
  1.1049 +      return 5;
  1.1050 +
  1.1051 +    case JVM_CONSTANT_Long:
  1.1052 +    case JVM_CONSTANT_Double:
  1.1053 +      return 9;
  1.1054 +  }
  1.1055 +  assert(false, "cpool_entry_size: Invalid constant pool entry tag");
  1.1056 +  return 1;
  1.1057 +} /* end cpool_entry_size */
  1.1058 +
  1.1059 +
  1.1060 +// SymbolHashMap is used to find a constant pool index from a string.
  1.1061 +// This function fills in SymbolHashMaps, one for utf8s and one for
  1.1062 +// class names, returns size of the cpool raw bytes.
  1.1063 +jint constantPoolOopDesc::hash_entries_to(SymbolHashMap *symmap,
  1.1064 +                                          SymbolHashMap *classmap) {
  1.1065 +  jint size = 0;
  1.1066 +
  1.1067 +  for (u2 idx = 1; idx < length(); idx++) {
  1.1068 +    u2 tag = tag_at(idx).value();
  1.1069 +    size += cpool_entry_size(idx);
  1.1070 +
  1.1071 +    switch(tag) {
  1.1072 +      case JVM_CONSTANT_Utf8: {
  1.1073 +        symbolOop sym = symbol_at(idx);
  1.1074 +        symmap->add_entry(sym, idx);
  1.1075 +        DBG(printf("adding symbol entry %s = %d\n", sym->as_utf8(), idx));
  1.1076 +        break;
  1.1077 +      }
  1.1078 +      case JVM_CONSTANT_Class:
  1.1079 +      case JVM_CONSTANT_UnresolvedClass:
  1.1080 +      case JVM_CONSTANT_UnresolvedClassInError: {
  1.1081 +        symbolOop sym = klass_name_at(idx);
  1.1082 +        classmap->add_entry(sym, idx);
  1.1083 +        DBG(printf("adding class entry %s = %d\n", sym->as_utf8(), idx));
  1.1084 +        break;
  1.1085 +      }
  1.1086 +      case JVM_CONSTANT_Long:
  1.1087 +      case JVM_CONSTANT_Double: {
  1.1088 +        idx++; // Both Long and Double take two cpool slots
  1.1089 +        break;
  1.1090 +      }
  1.1091 +    }
  1.1092 +  }
  1.1093 +  return size;
  1.1094 +} /* end hash_utf8_entries_to */
  1.1095 +
  1.1096 +
  1.1097 +// Copy cpool bytes.
  1.1098 +// Returns:
  1.1099 +//    0, in case of OutOfMemoryError
  1.1100 +//   -1, in case of internal error
  1.1101 +//  > 0, count of the raw cpool bytes that have been copied
  1.1102 +int constantPoolOopDesc::copy_cpool_bytes(int cpool_size,
  1.1103 +                                          SymbolHashMap* tbl,
  1.1104 +                                          unsigned char *bytes) {
  1.1105 +  u2   idx1, idx2;
  1.1106 +  jint size  = 0;
  1.1107 +  jint cnt   = length();
  1.1108 +  unsigned char *start_bytes = bytes;
  1.1109 +
  1.1110 +  for (jint idx = 1; idx < cnt; idx++) {
  1.1111 +    u1   tag      = tag_at(idx).value();
  1.1112 +    jint ent_size = cpool_entry_size(idx);
  1.1113 +
  1.1114 +    assert(size + ent_size <= cpool_size, "Size mismatch");
  1.1115 +
  1.1116 +    *bytes = tag;
  1.1117 +    DBG(printf("#%03hd tag=%03hd, ", idx, tag));
  1.1118 +    switch(tag) {
  1.1119 +      case JVM_CONSTANT_Invalid: {
  1.1120 +        DBG(printf("JVM_CONSTANT_Invalid"));
  1.1121 +        break;
  1.1122 +      }
  1.1123 +      case JVM_CONSTANT_Unicode: {
  1.1124 +        assert(false, "Wrong constant pool tag: JVM_CONSTANT_Unicode");
  1.1125 +        DBG(printf("JVM_CONSTANT_Unicode"));
  1.1126 +        break;
  1.1127 +      }
  1.1128 +      case JVM_CONSTANT_Utf8: {
  1.1129 +        symbolOop sym = symbol_at(idx);
  1.1130 +        char*     str = sym->as_utf8();
  1.1131 +        // Warning! It's crashing on x86 with len = sym->utf8_length()
  1.1132 +        int       len = (int) strlen(str);
  1.1133 +        Bytes::put_Java_u2((address) (bytes+1), (u2) len);
  1.1134 +        for (int i = 0; i < len; i++) {
  1.1135 +            bytes[3+i] = (u1) str[i];
  1.1136 +        }
  1.1137 +        DBG(printf("JVM_CONSTANT_Utf8: %s ", str));
  1.1138 +        break;
  1.1139 +      }
  1.1140 +      case JVM_CONSTANT_Integer: {
  1.1141 +        jint val = int_at(idx);
  1.1142 +        Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val);
  1.1143 +        break;
  1.1144 +      }
  1.1145 +      case JVM_CONSTANT_Float: {
  1.1146 +        jfloat val = float_at(idx);
  1.1147 +        Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val);
  1.1148 +        break;
  1.1149 +      }
  1.1150 +      case JVM_CONSTANT_Long: {
  1.1151 +        jlong val = long_at(idx);
  1.1152 +        Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val);
  1.1153 +        idx++;             // Long takes two cpool slots
  1.1154 +        break;
  1.1155 +      }
  1.1156 +      case JVM_CONSTANT_Double: {
  1.1157 +        jdouble val = double_at(idx);
  1.1158 +        Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val);
  1.1159 +        idx++;             // Double takes two cpool slots
  1.1160 +        break;
  1.1161 +      }
  1.1162 +      case JVM_CONSTANT_Class:
  1.1163 +      case JVM_CONSTANT_UnresolvedClass:
  1.1164 +      case JVM_CONSTANT_UnresolvedClassInError: {
  1.1165 +        *bytes = JVM_CONSTANT_Class;
  1.1166 +        symbolOop sym = klass_name_at(idx);
  1.1167 +        idx1 = tbl->symbol_to_value(sym);
  1.1168 +        assert(idx1 != 0, "Have not found a hashtable entry");
  1.1169 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1170 +        DBG(printf("JVM_CONSTANT_Class: idx=#%03hd, %s", idx1, sym->as_utf8()));
  1.1171 +        break;
  1.1172 +      }
  1.1173 +      case JVM_CONSTANT_String: {
  1.1174 +        unsigned int hash;
  1.1175 +        char *str = string_at_noresolve(idx);
  1.1176 +        symbolOop sym = SymbolTable::lookup_only(str, (int) strlen(str), hash);
  1.1177 +        idx1 = tbl->symbol_to_value(sym);
  1.1178 +        assert(idx1 != 0, "Have not found a hashtable entry");
  1.1179 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1180 +        DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, str));
  1.1181 +        break;
  1.1182 +      }
  1.1183 +      case JVM_CONSTANT_UnresolvedString: {
  1.1184 +        *bytes = JVM_CONSTANT_String;
  1.1185 +        symbolOop sym = unresolved_string_at(idx);
  1.1186 +        idx1 = tbl->symbol_to_value(sym);
  1.1187 +        assert(idx1 != 0, "Have not found a hashtable entry");
  1.1188 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1189 +        DBG(char *str = sym->as_utf8());
  1.1190 +        DBG(printf("JVM_CONSTANT_UnresolvedString: idx=#%03hd, %s", idx1, str));
  1.1191 +        break;
  1.1192 +      }
  1.1193 +      case JVM_CONSTANT_Fieldref:
  1.1194 +      case JVM_CONSTANT_Methodref:
  1.1195 +      case JVM_CONSTANT_InterfaceMethodref: {
  1.1196 +        idx1 = uncached_klass_ref_index_at(idx);
  1.1197 +        idx2 = uncached_name_and_type_ref_index_at(idx);
  1.1198 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1199 +        Bytes::put_Java_u2((address) (bytes+3), idx2);
  1.1200 +        DBG(printf("JVM_CONSTANT_Methodref: %hd %hd", idx1, idx2));
  1.1201 +        break;
  1.1202 +      }
  1.1203 +      case JVM_CONSTANT_NameAndType: {
  1.1204 +        idx1 = name_ref_index_at(idx);
  1.1205 +        idx2 = signature_ref_index_at(idx);
  1.1206 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1207 +        Bytes::put_Java_u2((address) (bytes+3), idx2);
  1.1208 +        DBG(printf("JVM_CONSTANT_NameAndType: %hd %hd", idx1, idx2));
  1.1209 +        break;
  1.1210 +      }
  1.1211 +      case JVM_CONSTANT_ClassIndex: {
  1.1212 +        *bytes = JVM_CONSTANT_Class;
  1.1213 +        idx1 = klass_index_at(idx);
  1.1214 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1215 +        DBG(printf("JVM_CONSTANT_ClassIndex: %hd", idx1));
  1.1216 +        break;
  1.1217 +      }
  1.1218 +      case JVM_CONSTANT_StringIndex: {
  1.1219 +        *bytes = JVM_CONSTANT_String;
  1.1220 +        idx1 = string_index_at(idx);
  1.1221 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  1.1222 +        DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1));
  1.1223 +        break;
  1.1224 +      }
  1.1225 +    }
  1.1226 +    DBG(printf("\n"));
  1.1227 +    bytes += ent_size;
  1.1228 +    size  += ent_size;
  1.1229 +  }
  1.1230 +  assert(size == cpool_size, "Size mismatch");
  1.1231 +
  1.1232 +  // Keep temorarily for debugging until it's stable.
  1.1233 +  DBG(print_cpool_bytes(cnt, start_bytes));
  1.1234 +  return (int)(bytes - start_bytes);
  1.1235 +} /* end copy_cpool_bytes */
  1.1236 +
  1.1237 +
  1.1238 +void SymbolHashMap::add_entry(symbolOop sym, u2 value) {
  1.1239 +  char *str = sym->as_utf8();
  1.1240 +  unsigned int hash = compute_hash(str, sym->utf8_length());
  1.1241 +  unsigned int index = hash % table_size();
  1.1242 +
  1.1243 +  // check if already in map
  1.1244 +  // we prefer the first entry since it is more likely to be what was used in
  1.1245 +  // the class file
  1.1246 +  for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) {
  1.1247 +    assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL");
  1.1248 +    if (en->hash() == hash && en->symbol() == sym) {
  1.1249 +        return;  // already there
  1.1250 +    }
  1.1251 +  }
  1.1252 +
  1.1253 +  SymbolHashMapEntry* entry = new SymbolHashMapEntry(hash, sym, value);
  1.1254 +  entry->set_next(bucket(index));
  1.1255 +  _buckets[index].set_entry(entry);
  1.1256 +  assert(entry->symbol() != NULL, "SymbolHashMapEntry symbol is NULL");
  1.1257 +}
  1.1258 +
  1.1259 +SymbolHashMapEntry* SymbolHashMap::find_entry(symbolOop sym) {
  1.1260 +  assert(sym != NULL, "SymbolHashMap::find_entry - symbol is NULL");
  1.1261 +  char *str = sym->as_utf8();
  1.1262 +  int   len = sym->utf8_length();
  1.1263 +  unsigned int hash = SymbolHashMap::compute_hash(str, len);
  1.1264 +  unsigned int index = hash % table_size();
  1.1265 +  for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) {
  1.1266 +    assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL");
  1.1267 +    if (en->hash() == hash && en->symbol() == sym) {
  1.1268 +      return en;
  1.1269 +    }
  1.1270 +  }
  1.1271 +  return NULL;
  1.1272 +}

mercurial