< prev index next > src/hotspot/share/ci/ciEnv.cpp
Print this page
#include "precompiled.hpp"
#include "ci/ciConstant.hpp"
#include "ci/ciEnv.hpp"
#include "ci/ciField.hpp"
+ #include "ci/ciInlineKlass.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciReplay.hpp"
// In either case, if we can find the element type in the system dictionary,
// we must build an array type around it. The CI requires array klasses
// to be loaded if their element klasses are loaded, except when memory
// is exhausted.
if (Signature::is_array(sym) &&
! (sym->char_at(1) == JVM_SIGNATURE_ARRAY || sym->char_at(1) == JVM_SIGNATURE_CLASS)) {
// We have an unloaded array.
// Build it on the fly if the element class exists.
SignatureStream ss(sym, false);
ss.skip_array_prefix(1);
// Get element ciKlass recursively.
// In either case, if we can find the element type in the system dictionary,
// we must build an array type around it. The CI requires array klasses
// to be loaded if their element klasses are loaded, except when memory
// is exhausted.
if (Signature::is_array(sym) &&
! (sym->char_at(1) == JVM_SIGNATURE_ARRAY ||
+ sym->char_at(1) == JVM_SIGNATURE_CLASS ||
+ sym->char_at(1) == JVM_SIGNATURE_PRIMITIVE_OBJECT )) {
// We have an unloaded array.
// Build it on the fly if the element class exists.
SignatureStream ss(sym, false);
ss.skip_array_prefix(1);
// Get element ciKlass recursively.
cpool,
get_symbol(ss.as_symbol()),
require_local);
if (elem_klass != nullptr && elem_klass->is_loaded()) {
// Now make an array for it
! return ciObjArrayKlass::make_impl(elem_klass);
}
}
if (found_klass == nullptr && !cpool.is_null() && cpool->has_preresolution()) {
// Look inside the constant pool for pre-resolved class entries.
cpool,
get_symbol(ss.as_symbol()),
require_local);
if (elem_klass != nullptr && elem_klass->is_loaded()) {
// Now make an array for it
! bool null_free_array = sym->is_Q_array_signature() && sym->char_at(1) == JVM_SIGNATURE_PRIMITIVE_OBJECT;
+ return ciArrayKlass::make(elem_klass, null_free_array);
}
}
if (found_klass == nullptr && !cpool.is_null() && cpool->has_preresolution()) {
// Look inside the constant pool for pre-resolved class entries.
if (require_local) return nullptr;
// Not yet loaded into the VM, or not governed by loader constraints.
// Make a CI representative for it.
+ int i = 0;
+ while (sym->char_at(i) == JVM_SIGNATURE_ARRAY) {
+ i++;
+ }
+ if (i > 0 && sym->char_at(i) == JVM_SIGNATURE_PRIMITIVE_OBJECT) {
+ // An unloaded array class of inline types is an ObjArrayKlass, an
+ // unloaded inline type class is an InstanceKlass. For consistency,
+ // make the signature of the unloaded array of inline type use L
+ // rather than Q.
+ char* new_name = name_buffer(sym->utf8_length()+1);
+ strncpy(new_name, (char*)sym->base(), sym->utf8_length());
+ new_name[i] = JVM_SIGNATURE_CLASS;
+ new_name[sym->utf8_length()] = '\0';
+ return get_unloaded_klass(accessing_klass, ciSymbol::make(new_name));
+ }
return get_unloaded_klass(accessing_klass, name);
}
// ------------------------------------------------------------------
// ciEnv::get_klass_by_name
bool& is_accessible,
ciInstanceKlass* accessor) {
GUARDED_VM_ENTRY(return get_klass_by_index_impl(cpool, index, is_accessible, accessor);)
}
+ // ------------------------------------------------------------------
+ // ciEnv::is_inline_klass
+ //
+ // Check if the klass is an inline klass.
+ bool ciEnv::has_Q_signature(const constantPoolHandle& cpool, int index) {
+ GUARDED_VM_ENTRY(return cpool->klass_name_at(index)->is_Q_signature();)
+ }
+
// ------------------------------------------------------------------
// ciEnv::unbox_primitive_value
//
// Unbox a primitive and return it as a ciConstant.
ciConstant ciEnv::unbox_primitive_value(ciObject* cibox, BasicType expected_bt) {
return ciConstant(T_OBJECT, get_unloaded_klass_mirror(nullptr));
} else if (tag.is_klass() || tag.is_unresolved_klass()) {
bool will_link;
ciKlass* klass = get_klass_by_index_impl(cpool, index, will_link, accessor);
ciInstance* mirror = (will_link ? klass->java_mirror() : get_unloaded_klass_mirror(klass));
! return ciConstant(T_OBJECT, mirror);
} else if (tag.is_method_type() || tag.is_method_type_in_error()) {
// must execute Java code to link this CP entry into cache[i].f1
assert(obj_index >= 0, "should have an object index");
ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index));
ciObject* ciobj = get_unloaded_method_type_constant(signature);
return ciConstant(T_OBJECT, get_unloaded_klass_mirror(nullptr));
} else if (tag.is_klass() || tag.is_unresolved_klass()) {
bool will_link;
ciKlass* klass = get_klass_by_index_impl(cpool, index, will_link, accessor);
ciInstance* mirror = (will_link ? klass->java_mirror() : get_unloaded_klass_mirror(klass));
! if (klass->is_loaded() && tag.is_Qdescriptor_klass()) {
+ return ciConstant(T_OBJECT, klass->as_inline_klass()->val_mirror());
+ } else {
+ return ciConstant(T_OBJECT, mirror);
+ }
} else if (tag.is_method_type() || tag.is_method_type_in_error()) {
// must execute Java code to link this CP entry into cache[i].f1
assert(obj_index >= 0, "should have an object index");
ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index));
ciObject* ciobj = get_unloaded_method_type_constant(signature);
< prev index next >