Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
32285 views
/*1* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "ci/ciField.hpp"26#include "ci/ciInstance.hpp"27#include "ci/ciInstanceKlass.hpp"28#include "ci/ciUtilities.hpp"29#include "classfile/systemDictionary.hpp"30#include "memory/allocation.hpp"31#include "memory/allocation.inline.hpp"32#include "oops/oop.inline.hpp"33#include "oops/fieldStreams.hpp"34#include "runtime/fieldDescriptor.hpp"3536// ciInstanceKlass37//38// This class represents a Klass* in the HotSpot virtual machine39// whose Klass part in an InstanceKlass.4041// ------------------------------------------------------------------42// ciInstanceKlass::ciInstanceKlass43//44// Loaded instance klass.45ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :46ciKlass(h_k), _non_static_fields(NULL)47{48assert(get_Klass()->oop_is_instance(), "wrong type");49assert(get_instanceKlass()->is_loaded(), "must be at least loaded");50InstanceKlass* ik = get_instanceKlass();5152AccessFlags access_flags = ik->access_flags();53_flags = ciFlags(access_flags);54_has_finalizer = access_flags.has_finalizer();55_has_subklass = ik->subklass() != NULL;56_init_state = ik->init_state();57_nonstatic_field_size = ik->nonstatic_field_size();58_has_nonstatic_fields = ik->has_nonstatic_fields();59_has_default_methods = ik->has_default_methods();60_is_anonymous = ik->is_anonymous();61_nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:6263_implementor = NULL; // we will fill these lazily6465Thread *thread = Thread::current();66if (ciObjectFactory::is_initialized()) {67_loader = JNIHandles::make_local(thread, ik->class_loader());68_protection_domain = JNIHandles::make_local(thread,69ik->protection_domain());70_is_shared = false;71} else {72Handle h_loader(thread, ik->class_loader());73Handle h_protection_domain(thread, ik->protection_domain());74_loader = JNIHandles::make_global(h_loader);75_protection_domain = JNIHandles::make_global(h_protection_domain);76_is_shared = true;77}7879// Lazy fields get filled in only upon request.80_super = NULL;81_java_mirror = NULL;8283if (is_shared()) {84if (h_k() != SystemDictionary::Object_klass()) {85super();86}87//compute_nonstatic_fields(); // done outside of constructor88}8990_field_cache = NULL;91}9293// Version for unloaded classes:94ciInstanceKlass::ciInstanceKlass(ciSymbol* name,95jobject loader, jobject protection_domain)96: ciKlass(name, T_OBJECT)97{98assert(name->byte_at(0) != '[', "not an instance klass");99_init_state = (InstanceKlass::ClassState)0;100_nonstatic_field_size = -1;101_has_nonstatic_fields = false;102_nonstatic_fields = NULL;103_is_anonymous = false;104_loader = loader;105_protection_domain = protection_domain;106_is_shared = false;107_super = NULL;108_java_mirror = NULL;109_field_cache = NULL;110}111112113114// ------------------------------------------------------------------115// ciInstanceKlass::compute_shared_is_initialized116void ciInstanceKlass::compute_shared_init_state() {117GUARDED_VM_ENTRY(118InstanceKlass* ik = get_instanceKlass();119_init_state = ik->init_state();120)121}122123// ------------------------------------------------------------------124// ciInstanceKlass::compute_shared_has_subklass125bool ciInstanceKlass::compute_shared_has_subklass() {126GUARDED_VM_ENTRY(127InstanceKlass* ik = get_instanceKlass();128_has_subklass = ik->subklass() != NULL;129return _has_subklass;130)131}132133// ------------------------------------------------------------------134// ciInstanceKlass::loader135oop ciInstanceKlass::loader() {136ASSERT_IN_VM;137return JNIHandles::resolve(_loader);138}139140// ------------------------------------------------------------------141// ciInstanceKlass::loader_handle142jobject ciInstanceKlass::loader_handle() {143return _loader;144}145146// ------------------------------------------------------------------147// ciInstanceKlass::protection_domain148oop ciInstanceKlass::protection_domain() {149ASSERT_IN_VM;150return JNIHandles::resolve(_protection_domain);151}152153// ------------------------------------------------------------------154// ciInstanceKlass::protection_domain_handle155jobject ciInstanceKlass::protection_domain_handle() {156return _protection_domain;157}158159// ------------------------------------------------------------------160// ciInstanceKlass::field_cache161//162// Get the field cache associated with this klass.163ciConstantPoolCache* ciInstanceKlass::field_cache() {164if (is_shared()) {165return NULL;166}167if (_field_cache == NULL) {168assert(!is_java_lang_Object(), "Object has no fields");169Arena* arena = CURRENT_ENV->arena();170_field_cache = new (arena) ciConstantPoolCache(arena, 5);171}172return _field_cache;173}174175// ------------------------------------------------------------------176// ciInstanceKlass::get_canonical_holder177//178ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {179#ifdef ASSERT180if (!(offset >= 0 && offset < layout_helper())) {181tty->print("*** get_canonical_holder(%d) on ", offset);182this->print();183tty->print_cr(" ***");184};185assert(offset >= 0 && offset < layout_helper(), "offset must be tame");186#endif187188if (offset < instanceOopDesc::base_offset_in_bytes()) {189// All header offsets belong properly to java/lang/Object.190return CURRENT_ENV->Object_klass();191}192193ciInstanceKlass* self = this;194for (;;) {195assert(self->is_loaded(), "must be loaded to have size");196ciInstanceKlass* super = self->super();197if (super == NULL || super->nof_nonstatic_fields() == 0 ||198!super->contains_field_offset(offset)) {199return self;200} else {201self = super; // return super->get_canonical_holder(offset)202}203}204}205206// ------------------------------------------------------------------207// ciInstanceKlass::is_java_lang_Object208//209// Is this klass java.lang.Object?210bool ciInstanceKlass::is_java_lang_Object() const {211return equals(CURRENT_ENV->Object_klass());212}213214// ------------------------------------------------------------------215// ciInstanceKlass::uses_default_loader216bool ciInstanceKlass::uses_default_loader() const {217// Note: We do not need to resolve the handle or enter the VM218// in order to test null-ness.219return _loader == NULL;220}221222// ------------------------------------------------------------------223224/**225* Return basic type of boxed value for box klass or T_OBJECT if not.226*/227BasicType ciInstanceKlass::box_klass_type() const {228if (uses_default_loader() && is_loaded()) {229return SystemDictionary::box_klass_type(get_Klass());230} else {231return T_OBJECT;232}233}234235/**236* Is this boxing klass?237*/238bool ciInstanceKlass::is_box_klass() const {239return is_java_primitive(box_klass_type());240}241242/**243* Is this boxed value offset?244*/245bool ciInstanceKlass::is_boxed_value_offset(int offset) const {246BasicType bt = box_klass_type();247return is_java_primitive(bt) &&248(offset == java_lang_boxing_object::value_offset_in_bytes(bt));249}250251// ------------------------------------------------------------------252// ciInstanceKlass::is_in_package253//254// Is this klass in the given package?255bool ciInstanceKlass::is_in_package(const char* packagename, int len) {256// To avoid class loader mischief, this test always rejects application classes.257if (!uses_default_loader())258return false;259GUARDED_VM_ENTRY(260return is_in_package_impl(packagename, len);261)262}263264bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) {265ASSERT_IN_VM;266267// If packagename contains trailing '/' exclude it from the268// prefix-test since we test for it explicitly.269if (packagename[len - 1] == '/')270len--;271272if (!name()->starts_with(packagename, len))273return false;274275// Test if the class name is something like "java/lang".276if ((len + 1) > name()->utf8_length())277return false;278279// Test for trailing '/'280if ((char) name()->byte_at(len) != '/')281return false;282283// Make sure it's not actually in a subpackage:284if (name()->index_of_at(len+1, "/", 1) >= 0)285return false;286287return true;288}289290// ------------------------------------------------------------------291// ciInstanceKlass::print_impl292//293// Implementation of the print method.294void ciInstanceKlass::print_impl(outputStream* st) {295ciKlass::print_impl(st);296GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i((address)loader()));)297if (is_loaded()) {298st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",299bool_to_str(is_initialized()),300bool_to_str(has_finalizer()),301bool_to_str(has_subklass()),302layout_helper());303304_flags.print_klass_flags();305306if (_super) {307st->print(" super=");308_super->print_name();309}310if (_java_mirror) {311st->print(" mirror=PRESENT");312}313} else {314st->print(" loaded=false");315}316}317318// ------------------------------------------------------------------319// ciInstanceKlass::super320//321// Get the superklass of this klass.322ciInstanceKlass* ciInstanceKlass::super() {323assert(is_loaded(), "must be loaded");324if (_super == NULL && !is_java_lang_Object()) {325GUARDED_VM_ENTRY(326Klass* super_klass = get_instanceKlass()->super();327_super = CURRENT_ENV->get_instance_klass(super_klass);328)329}330return _super;331}332333// ------------------------------------------------------------------334// ciInstanceKlass::java_mirror335//336// Get the instance of java.lang.Class corresponding to this klass.337// Cache it on this->_java_mirror.338ciInstance* ciInstanceKlass::java_mirror() {339if (is_shared()) {340return ciKlass::java_mirror();341}342if (_java_mirror == NULL) {343_java_mirror = ciKlass::java_mirror();344}345return _java_mirror;346}347348// ------------------------------------------------------------------349// ciInstanceKlass::unique_concrete_subklass350ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() {351if (!is_loaded()) return NULL; // No change if class is not loaded352if (!is_abstract()) return NULL; // Only applies to abstract classes.353if (!has_subklass()) return NULL; // Must have at least one subklass.354VM_ENTRY_MARK;355InstanceKlass* ik = get_instanceKlass();356Klass* up = ik->up_cast_abstract();357assert(up->oop_is_instance(), "must be InstanceKlass");358if (ik == up) {359return NULL;360}361return CURRENT_THREAD_ENV->get_instance_klass(up);362}363364// ------------------------------------------------------------------365// ciInstanceKlass::has_finalizable_subclass366bool ciInstanceKlass::has_finalizable_subclass() {367if (!is_loaded()) return true;368VM_ENTRY_MARK;369return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL;370}371372// ------------------------------------------------------------------373// ciInstanceKlass::get_field_by_offset374ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {375if (!is_static) {376for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) {377ciField* field = _nonstatic_fields->at(i);378int field_off = field->offset_in_bytes();379if (field_off == field_offset)380return field;381if (field_off > field_offset)382break;383// could do binary search or check bins, but probably not worth it384}385return NULL;386}387VM_ENTRY_MARK;388InstanceKlass* k = get_instanceKlass();389fieldDescriptor fd;390if (!k->find_field_from_offset(field_offset, is_static, &fd)) {391return NULL;392}393ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);394return field;395}396397// ------------------------------------------------------------------398// ciInstanceKlass::get_field_by_name399ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {400VM_ENTRY_MARK;401InstanceKlass* k = get_instanceKlass();402fieldDescriptor fd;403Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);404if (def == NULL) {405return NULL;406}407ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);408return field;409}410411// ------------------------------------------------------------------412// ciInstanceKlass::non_static_fields.413414class NonStaticFieldFiller: public FieldClosure {415GrowableArray<ciField*>* _arr;416ciEnv* _curEnv;417public:418NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) :419_curEnv(curEnv), _arr(arr)420{}421void do_field(fieldDescriptor* fd) {422ciField* field = new (_curEnv->arena()) ciField(fd);423_arr->append(field);424}425};426427GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() {428if (_non_static_fields == NULL) {429VM_ENTRY_MARK;430ciEnv* curEnv = ciEnv::current();431InstanceKlass* ik = get_instanceKlass();432int max_n_fields = ik->java_fields_count();433434Arena* arena = curEnv->arena();435_non_static_fields =436new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL);437NonStaticFieldFiller filler(curEnv, _non_static_fields);438ik->do_nonstatic_fields(&filler);439}440return _non_static_fields;441}442443static int sort_field_by_offset(ciField** a, ciField** b) {444return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();445// (no worries about 32-bit overflow...)446}447448// ------------------------------------------------------------------449// ciInstanceKlass::compute_nonstatic_fields450int ciInstanceKlass::compute_nonstatic_fields() {451assert(is_loaded(), "must be loaded");452453if (_nonstatic_fields != NULL)454return _nonstatic_fields->length();455456if (!has_nonstatic_fields()) {457Arena* arena = CURRENT_ENV->arena();458_nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL);459return 0;460}461assert(!is_java_lang_Object(), "bootstrap OK");462463// Size in bytes of my fields, including inherited fields.464int fsize = nonstatic_field_size() * heapOopSize;465466ciInstanceKlass* super = this->super();467GrowableArray<ciField*>* super_fields = NULL;468if (super != NULL && super->has_nonstatic_fields()) {469int super_fsize = super->nonstatic_field_size() * heapOopSize;470int super_flen = super->nof_nonstatic_fields();471super_fields = super->_nonstatic_fields;472assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");473// See if I am no larger than my super; if so, I can use his fields.474if (fsize == super_fsize) {475_nonstatic_fields = super_fields;476return super_fields->length();477}478}479480GrowableArray<ciField*>* fields = NULL;481GUARDED_VM_ENTRY({482fields = compute_nonstatic_fields_impl(super_fields);483});484485if (fields == NULL) {486// This can happen if this class (java.lang.Class) has invisible fields.487_nonstatic_fields = super_fields;488return super_fields->length();489}490491int flen = fields->length();492493// Now sort them by offset, ascending.494// (In principle, they could mix with superclass fields.)495fields->sort(sort_field_by_offset);496_nonstatic_fields = fields;497return flen;498}499500GrowableArray<ciField*>*501ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*502super_fields) {503ASSERT_IN_VM;504Arena* arena = CURRENT_ENV->arena();505int flen = 0;506GrowableArray<ciField*>* fields = NULL;507InstanceKlass* k = get_instanceKlass();508for (JavaFieldStream fs(k); !fs.done(); fs.next()) {509if (fs.access_flags().is_static()) continue;510flen += 1;511}512513// allocate the array:514if (flen == 0) {515return NULL; // return nothing if none are locally declared516}517if (super_fields != NULL) {518flen += super_fields->length();519}520fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);521if (super_fields != NULL) {522fields->appendAll(super_fields);523}524525for (JavaFieldStream fs(k); !fs.done(); fs.next()) {526if (fs.access_flags().is_static()) continue;527fieldDescriptor& fd = fs.field_descriptor();528ciField* field = new (arena) ciField(&fd);529fields->append(field);530}531assert(fields->length() == flen, "sanity");532return fields;533}534535// ------------------------------------------------------------------536// ciInstanceKlass::find_method537//538// Find a method in this klass.539ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {540VM_ENTRY_MARK;541InstanceKlass* k = get_instanceKlass();542Symbol* name_sym = name->get_symbol();543Symbol* sig_sym= signature->get_symbol();544545Method* m = k->find_method(name_sym, sig_sym);546if (m == NULL) return NULL;547548return CURRENT_THREAD_ENV->get_method(m);549}550551// ------------------------------------------------------------------552// ciInstanceKlass::is_leaf_type553bool ciInstanceKlass::is_leaf_type() {554assert(is_loaded(), "must be loaded");555if (is_shared()) {556return is_final(); // approximately correct557} else {558return !_has_subklass && (nof_implementors() == 0);559}560}561562// ------------------------------------------------------------------563// ciInstanceKlass::implementor564//565// Report an implementor of this interface.566// Note that there are various races here, since my copy567// of _nof_implementors might be out of date with respect568// to results returned by InstanceKlass::implementor.569// This is OK, since any dependencies we decide to assert570// will be checked later under the Compile_lock.571ciInstanceKlass* ciInstanceKlass::implementor() {572ciInstanceKlass* impl = _implementor;573if (impl == NULL) {574// Go into the VM to fetch the implementor.575{576VM_ENTRY_MARK;577Klass* k = get_instanceKlass()->implementor();578if (k != NULL) {579if (k == get_instanceKlass()) {580// More than one implementors. Use 'this' in this case.581impl = this;582} else {583impl = CURRENT_THREAD_ENV->get_instance_klass(k);584}585}586}587// Memoize this result.588if (!is_shared()) {589_implementor = impl;590}591}592return impl;593}594595ciInstanceKlass* ciInstanceKlass::host_klass() {596assert(is_loaded(), "must be loaded");597if (is_anonymous()) {598VM_ENTRY_MARK599Klass* host_klass = get_instanceKlass()->host_klass();600return CURRENT_ENV->get_instance_klass(host_klass);601}602return NULL;603}604605// Utility class for printing of the contents of the static fields for606// use by compilation replay. It only prints out the information that607// could be consumed by the compiler, so for primitive types it prints608// out the actual value. For Strings it's the actual string value.609// For array types it it's first level array size since that's the610// only value which statically unchangeable. For all other reference611// types it simply prints out the dynamic type.612613class StaticFinalFieldPrinter : public FieldClosure {614outputStream* _out;615const char* _holder;616public:617StaticFinalFieldPrinter(outputStream* out, const char* holder) :618_out(out),619_holder(holder) {620}621void do_field(fieldDescriptor* fd) {622if (fd->is_final() && !fd->has_initial_value()) {623ResourceMark rm;624oop mirror = fd->field_holder()->java_mirror();625_out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());626switch (fd->field_type()) {627case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break;628case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break;629case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break;630case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break;631case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break;632case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break;633case T_FLOAT: {634float f = mirror->float_field(fd->offset());635_out->print_cr("%d", *(int*)&f);636break;637}638case T_DOUBLE: {639double d = mirror->double_field(fd->offset());640_out->print_cr(INT64_FORMAT, *(int64_t*)&d);641break;642}643case T_ARRAY: {644oop value = mirror->obj_field_acquire(fd->offset());645if (value == NULL) {646_out->print_cr("null");647} else {648typeArrayOop ta = (typeArrayOop)value;649_out->print("%d", ta->length());650if (value->is_objArray()) {651objArrayOop oa = (objArrayOop)value;652const char* klass_name = value->klass()->name()->as_quoted_ascii();653_out->print(" %s", klass_name);654}655_out->cr();656}657break;658}659case T_OBJECT: {660oop value = mirror->obj_field_acquire(fd->offset());661if (value == NULL) {662_out->print_cr("null");663} else if (value->is_instance()) {664if (value->is_a(SystemDictionary::String_klass())) {665_out->print("\"");666_out->print_raw(java_lang_String::as_quoted_ascii(value));667_out->print_cr("\"");668} else {669const char* klass_name = value->klass()->name()->as_quoted_ascii();670_out->print_cr("%s", klass_name);671}672} else {673ShouldNotReachHere();674}675break;676}677default:678ShouldNotReachHere();679}680}681}682};683684685void ciInstanceKlass::dump_replay_data(outputStream* out) {686ResourceMark rm;687688InstanceKlass* ik = get_instanceKlass();689ConstantPool* cp = ik->constants();690691// Try to record related loaded classes692Klass* sub = ik->subklass();693while (sub != NULL) {694if (sub->oop_is_instance()) {695out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());696}697sub = sub->next_sibling();698}699700// Dump out the state of the constant pool tags. During replay the701// tags will be validated for things which shouldn't change and702// classes will be resolved if the tags indicate that they were703// resolved at compile time.704out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),705is_linked(), is_initialized(), cp->length());706for (int index = 1; index < cp->length(); index++) {707out->print(" %d", cp->tags()->at(index));708}709out->cr();710if (is_initialized()) {711// Dump out the static final fields in case the compilation relies712// on their value for correct replay.713StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());714ik->do_local_static_fields(&sffp);715}716}717718719