src/share/vm/ci/ciInstanceKlass.cpp

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 435
a61af66fc99e
child 479
52fed2ec0afb
permissions
-rw-r--r--

Initial load

     1 /*
     2  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_ciInstanceKlass.cpp.incl"
    28 // ciInstanceKlass
    29 //
    30 // This class represents a klassOop in the HotSpot virtual machine
    31 // whose Klass part in an instanceKlass.
    33 // ------------------------------------------------------------------
    34 // ciInstanceKlass::ciInstanceKlass
    35 //
    36 // Loaded instance klass.
    37 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) {
    38   assert(get_Klass()->oop_is_instance(), "wrong type");
    39   instanceKlass* ik = get_instanceKlass();
    41   AccessFlags access_flags = ik->access_flags();
    42   _flags = ciFlags(access_flags);
    43   _has_finalizer = access_flags.has_finalizer();
    44   _has_subklass = ik->subklass() != NULL;
    45   _is_initialized = ik->is_initialized();
    46   // Next line must follow and use the result of the previous line:
    47   _is_linked = _is_initialized || ik->is_linked();
    48   _nonstatic_field_size = ik->nonstatic_field_size();
    49   _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
    51   _nof_implementors = ik->nof_implementors();
    52   for (int i = 0; i < implementors_limit; i++) {
    53     _implementors[i] = NULL;  // we will fill these lazily
    54   }
    56   Thread *thread = Thread::current();
    57   if (ciObjectFactory::is_initialized()) {
    58     _loader = JNIHandles::make_local(thread, ik->class_loader());
    59     _protection_domain = JNIHandles::make_local(thread,
    60                                                 ik->protection_domain());
    61     _is_shared = false;
    62   } else {
    63     Handle h_loader(thread, ik->class_loader());
    64     Handle h_protection_domain(thread, ik->protection_domain());
    65     _loader = JNIHandles::make_global(h_loader);
    66     _protection_domain = JNIHandles::make_global(h_protection_domain);
    67     _is_shared = true;
    68   }
    70   // Lazy fields get filled in only upon request.
    71   _super  = NULL;
    72   _java_mirror = NULL;
    74   if (is_shared()) {
    75     if (h_k() != SystemDictionary::object_klass()) {
    76       super();
    77     }
    78     java_mirror();
    79     //compute_nonstatic_fields();  // done outside of constructor
    80   }
    82   _field_cache = NULL;
    83 }
    85 // Version for unloaded classes:
    86 ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
    87                                  jobject loader, jobject protection_domain)
    88   : ciKlass(name, ciInstanceKlassKlass::make())
    89 {
    90   assert(name->byte_at(0) != '[', "not an instance klass");
    91   _is_initialized = false;
    92   _is_linked = false;
    93   _nonstatic_field_size = -1;
    94   _nonstatic_fields = NULL;
    95   _nof_implementors = -1;
    96   _loader = loader;
    97   _protection_domain = protection_domain;
    98   _is_shared = false;
    99   _super = NULL;
   100   _java_mirror = NULL;
   101   _field_cache = NULL;
   102 }
   106 // ------------------------------------------------------------------
   107 // ciInstanceKlass::compute_shared_is_initialized
   108 bool ciInstanceKlass::compute_shared_is_initialized() {
   109   GUARDED_VM_ENTRY(
   110     instanceKlass* ik = get_instanceKlass();
   111     _is_initialized = ik->is_initialized();
   112     return _is_initialized;
   113   )
   114 }
   116 // ------------------------------------------------------------------
   117 // ciInstanceKlass::compute_shared_is_linked
   118 bool ciInstanceKlass::compute_shared_is_linked() {
   119   GUARDED_VM_ENTRY(
   120     instanceKlass* ik = get_instanceKlass();
   121     _is_linked = ik->is_linked();
   122     return _is_linked;
   123   )
   124 }
   126 // ------------------------------------------------------------------
   127 // ciInstanceKlass::compute_shared_has_subklass
   128 bool ciInstanceKlass::compute_shared_has_subklass() {
   129   GUARDED_VM_ENTRY(
   130     instanceKlass* ik = get_instanceKlass();
   131     _has_subklass = ik->subklass() != NULL;
   132     return _has_subklass;
   133   )
   134 }
   136 // ------------------------------------------------------------------
   137 // ciInstanceKlass::compute_shared_nof_implementors
   138 int ciInstanceKlass::compute_shared_nof_implementors() {
   139   // We requery this property, since it is a very old ciObject.
   140   GUARDED_VM_ENTRY(
   141     instanceKlass* ik = get_instanceKlass();
   142     _nof_implementors = ik->nof_implementors();
   143     return _nof_implementors;
   144   )
   145 }
   147 // ------------------------------------------------------------------
   148 // ciInstanceKlass::loader
   149 oop ciInstanceKlass::loader() {
   150   ASSERT_IN_VM;
   151   return JNIHandles::resolve(_loader);
   152 }
   154 // ------------------------------------------------------------------
   155 // ciInstanceKlass::loader_handle
   156 jobject ciInstanceKlass::loader_handle() {
   157   return _loader;
   158 }
   160 // ------------------------------------------------------------------
   161 // ciInstanceKlass::protection_domain
   162 oop ciInstanceKlass::protection_domain() {
   163   ASSERT_IN_VM;
   164   return JNIHandles::resolve(_protection_domain);
   165 }
   167 // ------------------------------------------------------------------
   168 // ciInstanceKlass::protection_domain_handle
   169 jobject ciInstanceKlass::protection_domain_handle() {
   170   return _protection_domain;
   171 }
   173 // ------------------------------------------------------------------
   174 // ciInstanceKlass::field_cache
   175 //
   176 // Get the field cache associated with this klass.
   177 ciConstantPoolCache* ciInstanceKlass::field_cache() {
   178   if (is_shared()) {
   179     return NULL;
   180   }
   181   if (_field_cache == NULL) {
   182     assert(!is_java_lang_Object(), "Object has no fields");
   183     Arena* arena = CURRENT_ENV->arena();
   184     _field_cache = new (arena) ciConstantPoolCache(arena, 5);
   185   }
   186   return _field_cache;
   187 }
   189 // ------------------------------------------------------------------
   190 // ciInstanceKlass::get_canonical_holder
   191 //
   192 ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
   193   #ifdef ASSERT
   194   if (!(offset >= 0 && offset < layout_helper())) {
   195     tty->print("*** get_canonical_holder(%d) on ", offset);
   196     this->print();
   197     tty->print_cr(" ***");
   198   };
   199   assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
   200   #endif
   202   if (offset < (instanceOopDesc::header_size() * wordSize)) {
   203     // All header offsets belong properly to java/lang/Object.
   204     return CURRENT_ENV->Object_klass();
   205   }
   207   ciInstanceKlass* self = this;
   208   for (;;) {
   209     assert(self->is_loaded(), "must be loaded to have size");
   210     ciInstanceKlass* super = self->super();
   211     if (super == NULL || !super->contains_field_offset(offset)) {
   212       return self;
   213     } else {
   214       self = super;  // return super->get_canonical_holder(offset)
   215     }
   216   }
   217 }
   219 // ------------------------------------------------------------------
   220 // ciInstanceKlass::is_java_lang_Object
   221 //
   222 // Is this klass java.lang.Object?
   223 bool ciInstanceKlass::is_java_lang_Object() {
   224   return equals(CURRENT_ENV->Object_klass());
   225 }
   227 // ------------------------------------------------------------------
   228 // ciInstanceKlass::uses_default_loader
   229 bool ciInstanceKlass::uses_default_loader() {
   230   VM_ENTRY_MARK;
   231   return loader() == NULL;
   232 }
   234 // ------------------------------------------------------------------
   235 // ciInstanceKlass::print_impl
   236 //
   237 // Implementation of the print method.
   238 void ciInstanceKlass::print_impl(outputStream* st) {
   239   ciKlass::print_impl(st);
   240   GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());)
   241   if (is_loaded()) {
   242     st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
   243               bool_to_str(is_initialized()),
   244               bool_to_str(has_finalizer()),
   245               bool_to_str(has_subklass()),
   246               layout_helper());
   248     _flags.print_klass_flags();
   250     if (_super) {
   251       st->print(" super=");
   252       _super->print_name();
   253     }
   254     if (_java_mirror) {
   255       st->print(" mirror=PRESENT");
   256     }
   257   } else {
   258     st->print(" loaded=false");
   259   }
   260 }
   262 // ------------------------------------------------------------------
   263 // ciInstanceKlass::super
   264 //
   265 // Get the superklass of this klass.
   266 ciInstanceKlass* ciInstanceKlass::super() {
   267   assert(is_loaded(), "must be loaded");
   268   if (_super == NULL && !is_java_lang_Object()) {
   269     GUARDED_VM_ENTRY(
   270       klassOop super_klass = get_instanceKlass()->super();
   271       _super = CURRENT_ENV->get_object(super_klass)->as_instance_klass();
   272     )
   273   }
   274   return _super;
   275 }
   277 // ------------------------------------------------------------------
   278 // ciInstanceKlass::java_mirror
   279 //
   280 // Get the instance of java.lang.Class corresponding to this klass.
   281 ciInstance* ciInstanceKlass::java_mirror() {
   282   assert(is_loaded(), "must be loaded");
   283   if (_java_mirror == NULL) {
   284     _java_mirror = ciKlass::java_mirror();
   285   }
   286   return _java_mirror;
   287 }
   289 // ------------------------------------------------------------------
   290 // ciInstanceKlass::unique_concrete_subklass
   291 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() {
   292   if (!is_loaded())     return NULL; // No change if class is not loaded
   293   if (!is_abstract())   return NULL; // Only applies to abstract classes.
   294   if (!has_subklass())  return NULL; // Must have at least one subklass.
   295   VM_ENTRY_MARK;
   296   instanceKlass* ik = get_instanceKlass();
   297   Klass* up = ik->up_cast_abstract();
   298   assert(up->oop_is_instance(), "must be instanceKlass");
   299   if (ik == up) {
   300     return NULL;
   301   }
   302   return CURRENT_THREAD_ENV->get_object(up->as_klassOop())->as_instance_klass();
   303 }
   305 // ------------------------------------------------------------------
   306 // ciInstanceKlass::has_finalizable_subclass
   307 bool ciInstanceKlass::has_finalizable_subclass() {
   308   if (!is_loaded())     return true;
   309   VM_ENTRY_MARK;
   310   return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL;
   311 }
   313 // ------------------------------------------------------------------
   314 // ciInstanceKlass::get_field_by_offset
   315 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {
   316   if (!is_static) {
   317     for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) {
   318       ciField* field = _nonstatic_fields->at(i);
   319       int  field_off = field->offset_in_bytes();
   320       if (field_off == field_offset)
   321         return field;
   322       if (field_off > field_offset)
   323         break;
   324       // could do binary search or check bins, but probably not worth it
   325     }
   326     return NULL;
   327   }
   328   VM_ENTRY_MARK;
   329   instanceKlass* k = get_instanceKlass();
   330   fieldDescriptor fd;
   331   if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
   332     return NULL;
   333   }
   334   ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
   335   return field;
   336 }
   338 static int sort_field_by_offset(ciField** a, ciField** b) {
   339   return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
   340   // (no worries about 32-bit overflow...)
   341 }
   343 // ------------------------------------------------------------------
   344 // ciInstanceKlass::compute_nonstatic_fields
   345 int ciInstanceKlass::compute_nonstatic_fields() {
   346   assert(is_loaded(), "must be loaded");
   348   if (_nonstatic_fields != NULL)
   349     return _nonstatic_fields->length();
   351   // Size in bytes of my fields, including inherited fields.
   352   // About equal to size_helper() - sizeof(oopDesc).
   353   int fsize = nonstatic_field_size() * wordSize;
   354   if (fsize == 0) {     // easy shortcut
   355     Arena* arena = CURRENT_ENV->arena();
   356     _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL);
   357     return 0;
   358   }
   359   assert(!is_java_lang_Object(), "bootstrap OK");
   361   ciInstanceKlass* super = this->super();
   362   int      super_fsize = 0;
   363   int      super_flen  = 0;
   364   GrowableArray<ciField*>* super_fields = NULL;
   365   if (super != NULL) {
   366     super_fsize  = super->nonstatic_field_size() * wordSize;
   367     super_flen   = super->nof_nonstatic_fields();
   368     super_fields = super->_nonstatic_fields;
   369     assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
   370   }
   372   // See if I am no larger than my super; if so, I can use his fields.
   373   if (fsize == super_fsize) {
   374     _nonstatic_fields = super_fields;
   375     return super_fields->length();
   376   }
   378   GrowableArray<ciField*>* fields = NULL;
   379   GUARDED_VM_ENTRY({
   380       fields = compute_nonstatic_fields_impl(super_fields);
   381     });
   383   if (fields == NULL) {
   384     // This can happen if this class (java.lang.Class) has invisible fields.
   385     _nonstatic_fields = super_fields;
   386     return super_fields->length();
   387   }
   389   int flen = fields->length();
   391   // Now sort them by offset, ascending.
   392   // (In principle, they could mix with superclass fields.)
   393   fields->sort(sort_field_by_offset);
   394 #ifdef ASSERT
   395   int last_offset = sizeof(oopDesc);
   396   for (int i = 0; i < fields->length(); i++) {
   397     ciField* field = fields->at(i);
   398     int offset = field->offset_in_bytes();
   399     int size   = (field->_type == NULL) ? oopSize : field->size_in_bytes();
   400     assert(last_offset <= offset, "no field overlap");
   401     if (last_offset > (int)sizeof(oopDesc))
   402       assert((offset - last_offset) < BytesPerLong, "no big holes");
   403     // Note:  Two consecutive T_BYTE fields will be separated by wordSize-1
   404     // padding bytes if one of them is declared by a superclass.
   405     // This is a minor inefficiency classFileParser.cpp.
   406     last_offset = offset + size;
   407   }
   408   assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow");
   409 #endif
   411   _nonstatic_fields = fields;
   412   return flen;
   413 }
   415 GrowableArray<ciField*>*
   416 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
   417                                                super_fields) {
   418   ASSERT_IN_VM;
   419   Arena* arena = CURRENT_ENV->arena();
   420   int flen = 0;
   421   GrowableArray<ciField*>* fields = NULL;
   422   instanceKlass* k = get_instanceKlass();
   423   typeArrayOop fields_array = k->fields();
   424   for (int pass = 0; pass <= 1; pass++) {
   425     for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) {
   426       fieldDescriptor fd;
   427       fd.initialize(k->as_klassOop(), i);
   428       if (fd.is_static())  continue;
   429       if (pass == 0) {
   430         flen += 1;
   431       } else {
   432         ciField* field = new (arena) ciField(&fd);
   433         fields->append(field);
   434       }
   435     }
   437     // Between passes, allocate the array:
   438     if (pass == 0) {
   439       if (flen == 0) {
   440         return NULL;  // return nothing if none are locally declared
   441       }
   442       if (super_fields != NULL) {
   443         flen += super_fields->length();
   444       }
   445       fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
   446       if (super_fields != NULL) {
   447         fields->appendAll(super_fields);
   448       }
   449     }
   450   }
   451   assert(fields->length() == flen, "sanity");
   452   return fields;
   453 }
   455 // ------------------------------------------------------------------
   456 // ciInstanceKlass::find_method
   457 //
   458 // Find a method in this klass.
   459 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
   460   VM_ENTRY_MARK;
   461   instanceKlass* k = get_instanceKlass();
   462   symbolOop name_sym = name->get_symbolOop();
   463   symbolOop sig_sym= signature->get_symbolOop();
   465   methodOop m = k->find_method(name_sym, sig_sym);
   466   if (m == NULL)  return NULL;
   468   return CURRENT_THREAD_ENV->get_object(m)->as_method();
   469 }
   471 // ------------------------------------------------------------------
   472 // ciInstanceKlass::is_leaf_type
   473 bool ciInstanceKlass::is_leaf_type() {
   474   assert(is_loaded(), "must be loaded");
   475   if (is_shared()) {
   476     return is_final();  // approximately correct
   477   } else {
   478     return !_has_subklass && (_nof_implementors == 0);
   479   }
   480 }
   482 // ------------------------------------------------------------------
   483 // ciInstanceKlass::implementor
   484 //
   485 // Report an implementor of this interface.
   486 // Returns NULL if exact information is not available.
   487 // Note that there are various races here, since my copy
   488 // of _nof_implementors might be out of date with respect
   489 // to results returned by instanceKlass::implementor.
   490 // This is OK, since any dependencies we decide to assert
   491 // will be checked later under the Compile_lock.
   492 ciInstanceKlass* ciInstanceKlass::implementor(int n) {
   493   if (n > implementors_limit) {
   494     return NULL;
   495   }
   496   ciInstanceKlass* impl = _implementors[n];
   497   if (impl == NULL) {
   498     if (_nof_implementors > implementors_limit) {
   499       return NULL;
   500     }
   501     // Go into the VM to fetch the implementor.
   502     {
   503       VM_ENTRY_MARK;
   504       klassOop k = get_instanceKlass()->implementor(n);
   505       if (k != NULL) {
   506         impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass();
   507       }
   508     }
   509     // Memoize this result.
   510     if (!is_shared()) {
   511       _implementors[n] = (impl == NULL)? this: impl;
   512     }
   513   } else if (impl == this) {
   514     impl = NULL;  // memoized null result from a VM query
   515   }
   516   return impl;
   517 }

mercurial