src/share/vm/ci/ciInstanceKlass.cpp

changeset 435
a61af66fc99e
child 479
52fed2ec0afb
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,517 @@
     1.4 +/*
     1.5 + * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "incls/_precompiled.incl"
    1.29 +#include "incls/_ciInstanceKlass.cpp.incl"
    1.30 +
    1.31 +// ciInstanceKlass
    1.32 +//
    1.33 +// This class represents a klassOop in the HotSpot virtual machine
    1.34 +// whose Klass part in an instanceKlass.
    1.35 +
    1.36 +// ------------------------------------------------------------------
    1.37 +// ciInstanceKlass::ciInstanceKlass
    1.38 +//
    1.39 +// Loaded instance klass.
    1.40 +ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) {
    1.41 +  assert(get_Klass()->oop_is_instance(), "wrong type");
    1.42 +  instanceKlass* ik = get_instanceKlass();
    1.43 +
    1.44 +  AccessFlags access_flags = ik->access_flags();
    1.45 +  _flags = ciFlags(access_flags);
    1.46 +  _has_finalizer = access_flags.has_finalizer();
    1.47 +  _has_subklass = ik->subklass() != NULL;
    1.48 +  _is_initialized = ik->is_initialized();
    1.49 +  // Next line must follow and use the result of the previous line:
    1.50 +  _is_linked = _is_initialized || ik->is_linked();
    1.51 +  _nonstatic_field_size = ik->nonstatic_field_size();
    1.52 +  _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
    1.53 +
    1.54 +  _nof_implementors = ik->nof_implementors();
    1.55 +  for (int i = 0; i < implementors_limit; i++) {
    1.56 +    _implementors[i] = NULL;  // we will fill these lazily
    1.57 +  }
    1.58 +
    1.59 +  Thread *thread = Thread::current();
    1.60 +  if (ciObjectFactory::is_initialized()) {
    1.61 +    _loader = JNIHandles::make_local(thread, ik->class_loader());
    1.62 +    _protection_domain = JNIHandles::make_local(thread,
    1.63 +                                                ik->protection_domain());
    1.64 +    _is_shared = false;
    1.65 +  } else {
    1.66 +    Handle h_loader(thread, ik->class_loader());
    1.67 +    Handle h_protection_domain(thread, ik->protection_domain());
    1.68 +    _loader = JNIHandles::make_global(h_loader);
    1.69 +    _protection_domain = JNIHandles::make_global(h_protection_domain);
    1.70 +    _is_shared = true;
    1.71 +  }
    1.72 +
    1.73 +  // Lazy fields get filled in only upon request.
    1.74 +  _super  = NULL;
    1.75 +  _java_mirror = NULL;
    1.76 +
    1.77 +  if (is_shared()) {
    1.78 +    if (h_k() != SystemDictionary::object_klass()) {
    1.79 +      super();
    1.80 +    }
    1.81 +    java_mirror();
    1.82 +    //compute_nonstatic_fields();  // done outside of constructor
    1.83 +  }
    1.84 +
    1.85 +  _field_cache = NULL;
    1.86 +}
    1.87 +
    1.88 +// Version for unloaded classes:
    1.89 +ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
    1.90 +                                 jobject loader, jobject protection_domain)
    1.91 +  : ciKlass(name, ciInstanceKlassKlass::make())
    1.92 +{
    1.93 +  assert(name->byte_at(0) != '[', "not an instance klass");
    1.94 +  _is_initialized = false;
    1.95 +  _is_linked = false;
    1.96 +  _nonstatic_field_size = -1;
    1.97 +  _nonstatic_fields = NULL;
    1.98 +  _nof_implementors = -1;
    1.99 +  _loader = loader;
   1.100 +  _protection_domain = protection_domain;
   1.101 +  _is_shared = false;
   1.102 +  _super = NULL;
   1.103 +  _java_mirror = NULL;
   1.104 +  _field_cache = NULL;
   1.105 +}
   1.106 +
   1.107 +
   1.108 +
   1.109 +// ------------------------------------------------------------------
   1.110 +// ciInstanceKlass::compute_shared_is_initialized
   1.111 +bool ciInstanceKlass::compute_shared_is_initialized() {
   1.112 +  GUARDED_VM_ENTRY(
   1.113 +    instanceKlass* ik = get_instanceKlass();
   1.114 +    _is_initialized = ik->is_initialized();
   1.115 +    return _is_initialized;
   1.116 +  )
   1.117 +}
   1.118 +
   1.119 +// ------------------------------------------------------------------
   1.120 +// ciInstanceKlass::compute_shared_is_linked
   1.121 +bool ciInstanceKlass::compute_shared_is_linked() {
   1.122 +  GUARDED_VM_ENTRY(
   1.123 +    instanceKlass* ik = get_instanceKlass();
   1.124 +    _is_linked = ik->is_linked();
   1.125 +    return _is_linked;
   1.126 +  )
   1.127 +}
   1.128 +
   1.129 +// ------------------------------------------------------------------
   1.130 +// ciInstanceKlass::compute_shared_has_subklass
   1.131 +bool ciInstanceKlass::compute_shared_has_subklass() {
   1.132 +  GUARDED_VM_ENTRY(
   1.133 +    instanceKlass* ik = get_instanceKlass();
   1.134 +    _has_subklass = ik->subklass() != NULL;
   1.135 +    return _has_subklass;
   1.136 +  )
   1.137 +}
   1.138 +
   1.139 +// ------------------------------------------------------------------
   1.140 +// ciInstanceKlass::compute_shared_nof_implementors
   1.141 +int ciInstanceKlass::compute_shared_nof_implementors() {
   1.142 +  // We requery this property, since it is a very old ciObject.
   1.143 +  GUARDED_VM_ENTRY(
   1.144 +    instanceKlass* ik = get_instanceKlass();
   1.145 +    _nof_implementors = ik->nof_implementors();
   1.146 +    return _nof_implementors;
   1.147 +  )
   1.148 +}
   1.149 +
   1.150 +// ------------------------------------------------------------------
   1.151 +// ciInstanceKlass::loader
   1.152 +oop ciInstanceKlass::loader() {
   1.153 +  ASSERT_IN_VM;
   1.154 +  return JNIHandles::resolve(_loader);
   1.155 +}
   1.156 +
   1.157 +// ------------------------------------------------------------------
   1.158 +// ciInstanceKlass::loader_handle
   1.159 +jobject ciInstanceKlass::loader_handle() {
   1.160 +  return _loader;
   1.161 +}
   1.162 +
   1.163 +// ------------------------------------------------------------------
   1.164 +// ciInstanceKlass::protection_domain
   1.165 +oop ciInstanceKlass::protection_domain() {
   1.166 +  ASSERT_IN_VM;
   1.167 +  return JNIHandles::resolve(_protection_domain);
   1.168 +}
   1.169 +
   1.170 +// ------------------------------------------------------------------
   1.171 +// ciInstanceKlass::protection_domain_handle
   1.172 +jobject ciInstanceKlass::protection_domain_handle() {
   1.173 +  return _protection_domain;
   1.174 +}
   1.175 +
   1.176 +// ------------------------------------------------------------------
   1.177 +// ciInstanceKlass::field_cache
   1.178 +//
   1.179 +// Get the field cache associated with this klass.
   1.180 +ciConstantPoolCache* ciInstanceKlass::field_cache() {
   1.181 +  if (is_shared()) {
   1.182 +    return NULL;
   1.183 +  }
   1.184 +  if (_field_cache == NULL) {
   1.185 +    assert(!is_java_lang_Object(), "Object has no fields");
   1.186 +    Arena* arena = CURRENT_ENV->arena();
   1.187 +    _field_cache = new (arena) ciConstantPoolCache(arena, 5);
   1.188 +  }
   1.189 +  return _field_cache;
   1.190 +}
   1.191 +
   1.192 +// ------------------------------------------------------------------
   1.193 +// ciInstanceKlass::get_canonical_holder
   1.194 +//
   1.195 +ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
   1.196 +  #ifdef ASSERT
   1.197 +  if (!(offset >= 0 && offset < layout_helper())) {
   1.198 +    tty->print("*** get_canonical_holder(%d) on ", offset);
   1.199 +    this->print();
   1.200 +    tty->print_cr(" ***");
   1.201 +  };
   1.202 +  assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
   1.203 +  #endif
   1.204 +
   1.205 +  if (offset < (instanceOopDesc::header_size() * wordSize)) {
   1.206 +    // All header offsets belong properly to java/lang/Object.
   1.207 +    return CURRENT_ENV->Object_klass();
   1.208 +  }
   1.209 +
   1.210 +  ciInstanceKlass* self = this;
   1.211 +  for (;;) {
   1.212 +    assert(self->is_loaded(), "must be loaded to have size");
   1.213 +    ciInstanceKlass* super = self->super();
   1.214 +    if (super == NULL || !super->contains_field_offset(offset)) {
   1.215 +      return self;
   1.216 +    } else {
   1.217 +      self = super;  // return super->get_canonical_holder(offset)
   1.218 +    }
   1.219 +  }
   1.220 +}
   1.221 +
   1.222 +// ------------------------------------------------------------------
   1.223 +// ciInstanceKlass::is_java_lang_Object
   1.224 +//
   1.225 +// Is this klass java.lang.Object?
   1.226 +bool ciInstanceKlass::is_java_lang_Object() {
   1.227 +  return equals(CURRENT_ENV->Object_klass());
   1.228 +}
   1.229 +
   1.230 +// ------------------------------------------------------------------
   1.231 +// ciInstanceKlass::uses_default_loader
   1.232 +bool ciInstanceKlass::uses_default_loader() {
   1.233 +  VM_ENTRY_MARK;
   1.234 +  return loader() == NULL;
   1.235 +}
   1.236 +
   1.237 +// ------------------------------------------------------------------
   1.238 +// ciInstanceKlass::print_impl
   1.239 +//
   1.240 +// Implementation of the print method.
   1.241 +void ciInstanceKlass::print_impl(outputStream* st) {
   1.242 +  ciKlass::print_impl(st);
   1.243 +  GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());)
   1.244 +  if (is_loaded()) {
   1.245 +    st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
   1.246 +              bool_to_str(is_initialized()),
   1.247 +              bool_to_str(has_finalizer()),
   1.248 +              bool_to_str(has_subklass()),
   1.249 +              layout_helper());
   1.250 +
   1.251 +    _flags.print_klass_flags();
   1.252 +
   1.253 +    if (_super) {
   1.254 +      st->print(" super=");
   1.255 +      _super->print_name();
   1.256 +    }
   1.257 +    if (_java_mirror) {
   1.258 +      st->print(" mirror=PRESENT");
   1.259 +    }
   1.260 +  } else {
   1.261 +    st->print(" loaded=false");
   1.262 +  }
   1.263 +}
   1.264 +
   1.265 +// ------------------------------------------------------------------
   1.266 +// ciInstanceKlass::super
   1.267 +//
   1.268 +// Get the superklass of this klass.
   1.269 +ciInstanceKlass* ciInstanceKlass::super() {
   1.270 +  assert(is_loaded(), "must be loaded");
   1.271 +  if (_super == NULL && !is_java_lang_Object()) {
   1.272 +    GUARDED_VM_ENTRY(
   1.273 +      klassOop super_klass = get_instanceKlass()->super();
   1.274 +      _super = CURRENT_ENV->get_object(super_klass)->as_instance_klass();
   1.275 +    )
   1.276 +  }
   1.277 +  return _super;
   1.278 +}
   1.279 +
   1.280 +// ------------------------------------------------------------------
   1.281 +// ciInstanceKlass::java_mirror
   1.282 +//
   1.283 +// Get the instance of java.lang.Class corresponding to this klass.
   1.284 +ciInstance* ciInstanceKlass::java_mirror() {
   1.285 +  assert(is_loaded(), "must be loaded");
   1.286 +  if (_java_mirror == NULL) {
   1.287 +    _java_mirror = ciKlass::java_mirror();
   1.288 +  }
   1.289 +  return _java_mirror;
   1.290 +}
   1.291 +
   1.292 +// ------------------------------------------------------------------
   1.293 +// ciInstanceKlass::unique_concrete_subklass
   1.294 +ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() {
   1.295 +  if (!is_loaded())     return NULL; // No change if class is not loaded
   1.296 +  if (!is_abstract())   return NULL; // Only applies to abstract classes.
   1.297 +  if (!has_subklass())  return NULL; // Must have at least one subklass.
   1.298 +  VM_ENTRY_MARK;
   1.299 +  instanceKlass* ik = get_instanceKlass();
   1.300 +  Klass* up = ik->up_cast_abstract();
   1.301 +  assert(up->oop_is_instance(), "must be instanceKlass");
   1.302 +  if (ik == up) {
   1.303 +    return NULL;
   1.304 +  }
   1.305 +  return CURRENT_THREAD_ENV->get_object(up->as_klassOop())->as_instance_klass();
   1.306 +}
   1.307 +
   1.308 +// ------------------------------------------------------------------
   1.309 +// ciInstanceKlass::has_finalizable_subclass
   1.310 +bool ciInstanceKlass::has_finalizable_subclass() {
   1.311 +  if (!is_loaded())     return true;
   1.312 +  VM_ENTRY_MARK;
   1.313 +  return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL;
   1.314 +}
   1.315 +
   1.316 +// ------------------------------------------------------------------
   1.317 +// ciInstanceKlass::get_field_by_offset
   1.318 +ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {
   1.319 +  if (!is_static) {
   1.320 +    for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) {
   1.321 +      ciField* field = _nonstatic_fields->at(i);
   1.322 +      int  field_off = field->offset_in_bytes();
   1.323 +      if (field_off == field_offset)
   1.324 +        return field;
   1.325 +      if (field_off > field_offset)
   1.326 +        break;
   1.327 +      // could do binary search or check bins, but probably not worth it
   1.328 +    }
   1.329 +    return NULL;
   1.330 +  }
   1.331 +  VM_ENTRY_MARK;
   1.332 +  instanceKlass* k = get_instanceKlass();
   1.333 +  fieldDescriptor fd;
   1.334 +  if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
   1.335 +    return NULL;
   1.336 +  }
   1.337 +  ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
   1.338 +  return field;
   1.339 +}
   1.340 +
   1.341 +static int sort_field_by_offset(ciField** a, ciField** b) {
   1.342 +  return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
   1.343 +  // (no worries about 32-bit overflow...)
   1.344 +}
   1.345 +
   1.346 +// ------------------------------------------------------------------
   1.347 +// ciInstanceKlass::compute_nonstatic_fields
   1.348 +int ciInstanceKlass::compute_nonstatic_fields() {
   1.349 +  assert(is_loaded(), "must be loaded");
   1.350 +
   1.351 +  if (_nonstatic_fields != NULL)
   1.352 +    return _nonstatic_fields->length();
   1.353 +
   1.354 +  // Size in bytes of my fields, including inherited fields.
   1.355 +  // About equal to size_helper() - sizeof(oopDesc).
   1.356 +  int fsize = nonstatic_field_size() * wordSize;
   1.357 +  if (fsize == 0) {     // easy shortcut
   1.358 +    Arena* arena = CURRENT_ENV->arena();
   1.359 +    _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL);
   1.360 +    return 0;
   1.361 +  }
   1.362 +  assert(!is_java_lang_Object(), "bootstrap OK");
   1.363 +
   1.364 +  ciInstanceKlass* super = this->super();
   1.365 +  int      super_fsize = 0;
   1.366 +  int      super_flen  = 0;
   1.367 +  GrowableArray<ciField*>* super_fields = NULL;
   1.368 +  if (super != NULL) {
   1.369 +    super_fsize  = super->nonstatic_field_size() * wordSize;
   1.370 +    super_flen   = super->nof_nonstatic_fields();
   1.371 +    super_fields = super->_nonstatic_fields;
   1.372 +    assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
   1.373 +  }
   1.374 +
   1.375 +  // See if I am no larger than my super; if so, I can use his fields.
   1.376 +  if (fsize == super_fsize) {
   1.377 +    _nonstatic_fields = super_fields;
   1.378 +    return super_fields->length();
   1.379 +  }
   1.380 +
   1.381 +  GrowableArray<ciField*>* fields = NULL;
   1.382 +  GUARDED_VM_ENTRY({
   1.383 +      fields = compute_nonstatic_fields_impl(super_fields);
   1.384 +    });
   1.385 +
   1.386 +  if (fields == NULL) {
   1.387 +    // This can happen if this class (java.lang.Class) has invisible fields.
   1.388 +    _nonstatic_fields = super_fields;
   1.389 +    return super_fields->length();
   1.390 +  }
   1.391 +
   1.392 +  int flen = fields->length();
   1.393 +
   1.394 +  // Now sort them by offset, ascending.
   1.395 +  // (In principle, they could mix with superclass fields.)
   1.396 +  fields->sort(sort_field_by_offset);
   1.397 +#ifdef ASSERT
   1.398 +  int last_offset = sizeof(oopDesc);
   1.399 +  for (int i = 0; i < fields->length(); i++) {
   1.400 +    ciField* field = fields->at(i);
   1.401 +    int offset = field->offset_in_bytes();
   1.402 +    int size   = (field->_type == NULL) ? oopSize : field->size_in_bytes();
   1.403 +    assert(last_offset <= offset, "no field overlap");
   1.404 +    if (last_offset > (int)sizeof(oopDesc))
   1.405 +      assert((offset - last_offset) < BytesPerLong, "no big holes");
   1.406 +    // Note:  Two consecutive T_BYTE fields will be separated by wordSize-1
   1.407 +    // padding bytes if one of them is declared by a superclass.
   1.408 +    // This is a minor inefficiency classFileParser.cpp.
   1.409 +    last_offset = offset + size;
   1.410 +  }
   1.411 +  assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow");
   1.412 +#endif
   1.413 +
   1.414 +  _nonstatic_fields = fields;
   1.415 +  return flen;
   1.416 +}
   1.417 +
   1.418 +GrowableArray<ciField*>*
   1.419 +ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
   1.420 +                                               super_fields) {
   1.421 +  ASSERT_IN_VM;
   1.422 +  Arena* arena = CURRENT_ENV->arena();
   1.423 +  int flen = 0;
   1.424 +  GrowableArray<ciField*>* fields = NULL;
   1.425 +  instanceKlass* k = get_instanceKlass();
   1.426 +  typeArrayOop fields_array = k->fields();
   1.427 +  for (int pass = 0; pass <= 1; pass++) {
   1.428 +    for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) {
   1.429 +      fieldDescriptor fd;
   1.430 +      fd.initialize(k->as_klassOop(), i);
   1.431 +      if (fd.is_static())  continue;
   1.432 +      if (pass == 0) {
   1.433 +        flen += 1;
   1.434 +      } else {
   1.435 +        ciField* field = new (arena) ciField(&fd);
   1.436 +        fields->append(field);
   1.437 +      }
   1.438 +    }
   1.439 +
   1.440 +    // Between passes, allocate the array:
   1.441 +    if (pass == 0) {
   1.442 +      if (flen == 0) {
   1.443 +        return NULL;  // return nothing if none are locally declared
   1.444 +      }
   1.445 +      if (super_fields != NULL) {
   1.446 +        flen += super_fields->length();
   1.447 +      }
   1.448 +      fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
   1.449 +      if (super_fields != NULL) {
   1.450 +        fields->appendAll(super_fields);
   1.451 +      }
   1.452 +    }
   1.453 +  }
   1.454 +  assert(fields->length() == flen, "sanity");
   1.455 +  return fields;
   1.456 +}
   1.457 +
   1.458 +// ------------------------------------------------------------------
   1.459 +// ciInstanceKlass::find_method
   1.460 +//
   1.461 +// Find a method in this klass.
   1.462 +ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
   1.463 +  VM_ENTRY_MARK;
   1.464 +  instanceKlass* k = get_instanceKlass();
   1.465 +  symbolOop name_sym = name->get_symbolOop();
   1.466 +  symbolOop sig_sym= signature->get_symbolOop();
   1.467 +
   1.468 +  methodOop m = k->find_method(name_sym, sig_sym);
   1.469 +  if (m == NULL)  return NULL;
   1.470 +
   1.471 +  return CURRENT_THREAD_ENV->get_object(m)->as_method();
   1.472 +}
   1.473 +
   1.474 +// ------------------------------------------------------------------
   1.475 +// ciInstanceKlass::is_leaf_type
   1.476 +bool ciInstanceKlass::is_leaf_type() {
   1.477 +  assert(is_loaded(), "must be loaded");
   1.478 +  if (is_shared()) {
   1.479 +    return is_final();  // approximately correct
   1.480 +  } else {
   1.481 +    return !_has_subklass && (_nof_implementors == 0);
   1.482 +  }
   1.483 +}
   1.484 +
   1.485 +// ------------------------------------------------------------------
   1.486 +// ciInstanceKlass::implementor
   1.487 +//
   1.488 +// Report an implementor of this interface.
   1.489 +// Returns NULL if exact information is not available.
   1.490 +// Note that there are various races here, since my copy
   1.491 +// of _nof_implementors might be out of date with respect
   1.492 +// to results returned by instanceKlass::implementor.
   1.493 +// This is OK, since any dependencies we decide to assert
   1.494 +// will be checked later under the Compile_lock.
   1.495 +ciInstanceKlass* ciInstanceKlass::implementor(int n) {
   1.496 +  if (n > implementors_limit) {
   1.497 +    return NULL;
   1.498 +  }
   1.499 +  ciInstanceKlass* impl = _implementors[n];
   1.500 +  if (impl == NULL) {
   1.501 +    if (_nof_implementors > implementors_limit) {
   1.502 +      return NULL;
   1.503 +    }
   1.504 +    // Go into the VM to fetch the implementor.
   1.505 +    {
   1.506 +      VM_ENTRY_MARK;
   1.507 +      klassOop k = get_instanceKlass()->implementor(n);
   1.508 +      if (k != NULL) {
   1.509 +        impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass();
   1.510 +      }
   1.511 +    }
   1.512 +    // Memoize this result.
   1.513 +    if (!is_shared()) {
   1.514 +      _implementors[n] = (impl == NULL)? this: impl;
   1.515 +    }
   1.516 +  } else if (impl == this) {
   1.517 +    impl = NULL;  // memoized null result from a VM query
   1.518 +  }
   1.519 +  return impl;
   1.520 +}

mercurial