< prev index next > src/hotspot/share/ci/ciField.cpp
Print this page
/*
! * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
/*
! * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
// decreases for complex compilation tasks.
// ------------------------------------------------------------------
// ciField::ciField
ciField::ciField(ciInstanceKlass* klass, int index) :
! _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
ASSERT_IN_VM;
CompilerThread *THREAD = CompilerThread::current();
assert(ciObjectFactory::is_initialized(), "not a shared field");
// decreases for complex compilation tasks.
// ------------------------------------------------------------------
// ciField::ciField
ciField::ciField(ciInstanceKlass* klass, int index) :
! _original_holder(NULL), _is_flattened(false), _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
ASSERT_IN_VM;
CompilerThread *THREAD = CompilerThread::current();
assert(ciObjectFactory::is_initialized(), "not a shared field");
_type = ciType::make(field_type);
}
_name = (ciSymbol*)ciEnv::current(THREAD)->get_symbol(name);
+ // this is needed if the field class is not yet loaded.
+ _is_null_free = _signature->is_Q_signature();
+
// Get the field's declared holder.
//
// Note: we actually create a ciInstanceKlass for this klass,
// even though we may not need to.
int holder_index = cpool->klass_ref_index_at(index);
// Either (a) it is marked shared, or else (b) we are done bootstrapping.
assert(is_shared() || ciObjectFactory::is_initialized(),
"bootstrap classes must not create & cache unshared fields");
}
+ // Special copy constructor used to flatten inline type fields by
+ // copying the fields of the inline type to a new holder klass.
+ ciField::ciField(ciField* field, ciInstanceKlass* holder, int offset, bool is_final) {
+ assert(field->holder()->is_inlinetype(), "should only be used for inline type field flattening");
+ // Set the is_final flag
+ jint final = is_final ? JVM_ACC_FINAL : ~JVM_ACC_FINAL;
+ AccessFlags flags(field->flags().as_int() & final);
+ _flags = ciFlags(flags);
+ _holder = holder;
+ _offset = offset;
+ // Copy remaining fields
+ _name = field->_name;
+ _signature = field->_signature;
+ _type = field->_type;
+ // Trust final flattened fields
+ _is_constant = is_final;
+ _known_to_link_with_put = field->_known_to_link_with_put;
+ _known_to_link_with_get = field->_known_to_link_with_get;
+ _constant_value = field->_constant_value;
+ assert(!field->is_flattened(), "field must not be flattened");
+ _is_flattened = false;
+ _is_null_free = field->_is_null_free;
+ _original_holder = (field->_original_holder != NULL) ? field->_original_holder : field->_holder;
+ }
+
static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
if (holder == NULL)
return false;
if (holder->name() == ciSymbols::java_lang_System())
// Never trust strangely unstable finals: System.out, etc.
return true;
// Trust hidden classes. They are created via Lookup.defineHiddenClass and
// can't be serialized, so there is no hacking of finals going on with them.
if (holder->is_hidden())
return true;
+ // Trust final fields in inline type buffers
+ if (holder->is_inlinetype())
+ return true;
// Trust final fields in all boxed classes
if (holder->is_box_klass())
return true;
// Trust final fields in records
if (holder->is_record())
_flags = ciFlags(fd->access_flags());
_offset = fd->offset();
Klass* field_holder = fd->field_holder();
assert(field_holder != NULL, "null field_holder");
_holder = CURRENT_ENV->get_instance_klass(field_holder);
+ _is_flattened = fd->is_inlined();
+ _is_null_free = fd->signature()->is_Q_signature();
+ _original_holder = NULL;
// Check to see if the field is constant.
Klass* k = _holder->get_Klass();
bool is_stable_field = FoldStableValues && is_stable();
if ((is_final() && !has_initialized_final_update()) || is_stable_field) {
ciType* ciField::compute_type() {
GUARDED_VM_ENTRY(return compute_type_impl();)
}
ciType* ciField::compute_type_impl() {
! ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(_holder, constantPoolHandle(), _signature, false);
if (!type->is_primitive_type() && is_shared()) {
// We must not cache a pointer to an unshared type, in a shared field.
bool type_is_also_shared = false;
if (type->is_type_array_klass()) {
type_is_also_shared = true; // int[] etc. are explicitly bootstrapped
ciType* ciField::compute_type() {
GUARDED_VM_ENTRY(return compute_type_impl();)
}
ciType* ciField::compute_type_impl() {
! // Use original holder for fields that came in through flattening
+ ciKlass* accessing_klass = (_original_holder != NULL) ? _original_holder : _holder;
+ ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(accessing_klass, constantPoolHandle(), _signature, false);
if (!type->is_primitive_type() && is_shared()) {
// We must not cache a pointer to an unshared type, in a shared field.
bool type_is_also_shared = false;
if (type->is_type_array_klass()) {
type_is_also_shared = true; // int[] etc. are explicitly bootstrapped
// link errors?
bool ciField::will_link(ciMethod* accessing_method,
Bytecodes::Code bc) {
VM_ENTRY_MARK;
assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic ||
! bc == Bytecodes::_getfield || bc == Bytecodes::_putfield,
! "unexpected bytecode");
if (_offset == -1) {
// at creation we couldn't link to our holder so we need to
// maintain that stance, otherwise there's no safe way to use this
// ciField.
// link errors?
bool ciField::will_link(ciMethod* accessing_method,
Bytecodes::Code bc) {
VM_ENTRY_MARK;
assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic ||
! bc == Bytecodes::_getfield || bc == Bytecodes::_putfield ||
! bc == Bytecodes::_withfield, "unexpected bytecode");
if (_offset == -1) {
// at creation we couldn't link to our holder so we need to
// maintain that stance, otherwise there's no safe way to use this
// ciField.
tty->print(" is_constant=%s", bool_to_str(_is_constant));
if (_is_constant && is_static()) {
tty->print(" constant_value=");
_constant_value.print();
}
+ tty->print(" is_flattened=%s", bool_to_str(_is_flattened));
+ tty->print(" is_null_free=%s", bool_to_str(_is_null_free));
tty->print(">");
}
// ------------------------------------------------------------------
// ciField::print_name_on
< prev index next >