8256741: Reduce footprint of compiler interface data structures

Reviewed-by: cjplummer, kvn
This commit is contained in:
Claes Redestad 2020-11-23 10:17:43 +00:00
parent 65b77d5920
commit c0689d25fb
9 changed files with 138 additions and 198 deletions

View file

@ -1280,8 +1280,8 @@ BCEscapeAnalyzer *ciMethod::get_bcea() {
} }
ciMethodBlocks *ciMethod::get_method_blocks() { ciMethodBlocks *ciMethod::get_method_blocks() {
Arena *arena = CURRENT_ENV->arena();
if (_method_blocks == NULL) { if (_method_blocks == NULL) {
Arena *arena = CURRENT_ENV->arena();
_method_blocks = new (arena) ciMethodBlocks(arena, this); _method_blocks = new (arena) ciMethodBlocks(arena, this);
} }
return _method_blocks; return _method_blocks;

View file

@ -75,30 +75,24 @@ volatile bool ciObjectFactory::_initialized = false;
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciObjectFactory::ciObjectFactory // ciObjectFactory::ciObjectFactory
ciObjectFactory::ciObjectFactory(Arena* arena, ciObjectFactory::ciObjectFactory(Arena* arena,
int expected_size) { int expected_size)
: _arena(arena),
_ci_metadata(arena, expected_size, 0, NULL),
_unloaded_methods(arena, 4, 0, NULL),
_unloaded_klasses(arena, 8, 0, NULL),
_unloaded_instances(arena, 4, 0, NULL),
_return_addresses(arena, 8, 0, NULL),
_symbols(arena, 100, 0, NULL),
_next_ident(_shared_ident_limit),
_non_perm_count(0) {
for (int i = 0; i < NON_PERM_BUCKETS; i++) { for (int i = 0; i < NON_PERM_BUCKETS; i++) {
_non_perm_bucket[i] = NULL; _non_perm_bucket[i] = NULL;
} }
_non_perm_count = 0;
_next_ident = _shared_ident_limit;
_arena = arena;
_ci_metadata = new (arena) GrowableArray<ciMetadata*>(arena, expected_size, 0, NULL);
// If the shared ci objects exist append them to this factory's objects // If the shared ci objects exist append them to this factory's objects
if (_shared_ci_metadata != NULL) { if (_shared_ci_metadata != NULL) {
_ci_metadata->appendAll(_shared_ci_metadata); _ci_metadata.appendAll(_shared_ci_metadata);
} }
_unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL);
_unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL);
_unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL);
_return_addresses =
new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL);
_symbols = new (arena) GrowableArray<ciSymbol*>(arena, 100, 0, NULL);
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -145,8 +139,6 @@ void ciObjectFactory::init_shared_objects() {
#endif #endif
} }
_ci_metadata = new (_arena) GrowableArray<ciMetadata*>(_arena, 64, 0, NULL);
for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) { for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) {
BasicType t = (BasicType)i; BasicType t = (BasicType)i;
if (type2name(t) != NULL && !is_reference_type(t) && if (type2name(t) != NULL && !is_reference_type(t) &&
@ -166,10 +158,10 @@ void ciObjectFactory::init_shared_objects() {
WK_KLASSES_DO(WK_KLASS_DEFN) WK_KLASSES_DO(WK_KLASS_DEFN)
#undef WK_KLASS_DEFN #undef WK_KLASS_DEFN
for (int len = -1; len != _ci_metadata->length(); ) { for (int len = -1; len != _ci_metadata.length(); ) {
len = _ci_metadata->length(); len = _ci_metadata.length();
for (int i2 = 0; i2 < len; i2++) { for (int i2 = 0; i2 < len; i2++) {
ciMetadata* obj = _ci_metadata->at(i2); ciMetadata* obj = _ci_metadata.at(i2);
assert (obj->is_metadata(), "what else would it be?"); assert (obj->is_metadata(), "what else would it be?");
if (obj->is_loaded() && obj->is_instance_klass()) { if (obj->is_loaded() && obj->is_instance_klass()) {
obj->as_instance_klass()->compute_nonstatic_fields(); obj->as_instance_klass()->compute_nonstatic_fields();
@ -194,8 +186,6 @@ void ciObjectFactory::init_shared_objects() {
get_metadata(Universe::intArrayKlassObj()); get_metadata(Universe::intArrayKlassObj());
get_metadata(Universe::longArrayKlassObj()); get_metadata(Universe::longArrayKlassObj());
assert(_non_perm_count == 0, "no shared non-perm objects"); assert(_non_perm_count == 0, "no shared non-perm objects");
// The shared_ident_limit is the first ident number that will // The shared_ident_limit is the first ident number that will
@ -204,7 +194,7 @@ void ciObjectFactory::init_shared_objects() {
// while the higher numbers are recycled afresh by each new ciEnv. // while the higher numbers are recycled afresh by each new ciEnv.
_shared_ident_limit = _next_ident; _shared_ident_limit = _next_ident;
_shared_ci_metadata = _ci_metadata; _shared_ci_metadata = &_ci_metadata;
} }
@ -217,14 +207,14 @@ ciSymbol* ciObjectFactory::get_symbol(Symbol* key) {
assert(vmSymbols::find_sid(key) == vmSymbolID::NO_SID, ""); assert(vmSymbols::find_sid(key) == vmSymbolID::NO_SID, "");
ciSymbol* s = new (arena()) ciSymbol(key, vmSymbolID::NO_SID); ciSymbol* s = new (arena()) ciSymbol(key, vmSymbolID::NO_SID);
_symbols->push(s); _symbols.push(s);
return s; return s;
} }
// Decrement the refcount when done on symbols referenced by this compilation. // Decrement the refcount when done on symbols referenced by this compilation.
void ciObjectFactory::remove_symbols() { void ciObjectFactory::remove_symbols() {
for (int i = 0; i < _symbols->length(); i++) { for (int i = 0; i < _symbols.length(); i++) {
ciSymbol* s = _symbols->at(i); ciSymbol* s = _symbols.at(i);
s->get_symbol()->decrement_refcount(); s->get_symbol()->decrement_refcount();
} }
// Since _symbols is resource allocated we're not allowed to delete it // Since _symbols is resource allocated we're not allowed to delete it
@ -276,12 +266,12 @@ ciMetadata* ciObjectFactory::cached_metadata(Metadata* key) {
ASSERT_IN_VM; ASSERT_IN_VM;
bool found = false; bool found = false;
int index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found); int index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
if (!found) { if (!found) {
return NULL; return NULL;
} }
return _ci_metadata->at(index)->as_metadata(); return _ci_metadata.at(index)->as_metadata();
} }
@ -297,20 +287,20 @@ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
#ifdef ASSERT #ifdef ASSERT
if (CIObjectFactoryVerify) { if (CIObjectFactoryVerify) {
Metadata* last = NULL; Metadata* last = NULL;
for (int j = 0; j< _ci_metadata->length(); j++) { for (int j = 0; j < _ci_metadata.length(); j++) {
Metadata* o = _ci_metadata->at(j)->constant_encoding(); Metadata* o = _ci_metadata.at(j)->constant_encoding();
assert(last < o, "out of order"); assert(last < o, "out of order");
last = o; last = o;
} }
} }
#endif // ASSERT #endif // ASSERT
int len = _ci_metadata->length(); int len = _ci_metadata.length();
bool found = false; bool found = false;
int index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found); int index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
#ifdef ASSERT #ifdef ASSERT
if (CIObjectFactoryVerify) { if (CIObjectFactoryVerify) {
for (int i=0; i<_ci_metadata->length(); i++) { for (int i = 0; i < _ci_metadata.length(); i++) {
if (_ci_metadata->at(i)->constant_encoding() == key) { if (_ci_metadata.at(i)->constant_encoding() == key) {
assert(index == i, " bad lookup"); assert(index == i, " bad lookup");
} }
} }
@ -324,16 +314,16 @@ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
init_ident_of(new_object); init_ident_of(new_object);
assert(new_object->is_metadata(), "must be"); assert(new_object->is_metadata(), "must be");
if (len != _ci_metadata->length()) { if (len != _ci_metadata.length()) {
// creating the new object has recursively entered new objects // creating the new object has recursively entered new objects
// into the table. We need to recompute our index. // into the table. We need to recompute our index.
index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found); index = _ci_metadata.find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
} }
assert(!found, "no double insert"); assert(!found, "no double insert");
_ci_metadata->insert_before(index, new_object); _ci_metadata.insert_before(index, new_object);
return new_object; return new_object;
} }
return _ci_metadata->at(index)->as_metadata(); return _ci_metadata.at(index)->as_metadata();
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -420,8 +410,8 @@ ciMethod* ciObjectFactory::get_unloaded_method(ciInstanceKlass* holder,
ciInstanceKlass* accessor) { ciInstanceKlass* accessor) {
assert(accessor != NULL, "need origin of access"); assert(accessor != NULL, "need origin of access");
ciSignature* that = NULL; ciSignature* that = NULL;
for (int i = 0; i < _unloaded_methods->length(); i++) { for (int i = 0; i < _unloaded_methods.length(); i++) {
ciMethod* entry = _unloaded_methods->at(i); ciMethod* entry = _unloaded_methods.at(i);
if (entry->holder()->equals(holder) && if (entry->holder()->equals(holder) &&
entry->name()->equals(name) && entry->name()->equals(name) &&
entry->signature()->as_symbol()->equals(signature)) { entry->signature()->as_symbol()->equals(signature)) {
@ -445,7 +435,7 @@ ciMethod* ciObjectFactory::get_unloaded_method(ciInstanceKlass* holder,
ciMethod* new_method = new (arena()) ciMethod(holder, name, signature, accessor); ciMethod* new_method = new (arena()) ciMethod(holder, name, signature, accessor);
init_ident_of(new_method); init_ident_of(new_method);
_unloaded_methods->append(new_method); _unloaded_methods.append(new_method);
return new_method; return new_method;
} }
@ -468,8 +458,8 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass,
loader = accessing_klass->loader(); loader = accessing_klass->loader();
domain = accessing_klass->protection_domain(); domain = accessing_klass->protection_domain();
} }
for (int i=0; i<_unloaded_klasses->length(); i++) { for (int i = 0; i < _unloaded_klasses.length(); i++) {
ciKlass* entry = _unloaded_klasses->at(i); ciKlass* entry = _unloaded_klasses.at(i);
if (entry->name()->equals(name) && if (entry->name()->equals(name) &&
entry->loader() == loader && entry->loader() == loader &&
entry->protection_domain() == domain) { entry->protection_domain() == domain) {
@ -519,7 +509,7 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass,
new_klass = new (arena()) ciInstanceKlass(name, loader_handle, domain_handle); new_klass = new (arena()) ciInstanceKlass(name, loader_handle, domain_handle);
} }
init_ident_of(new_klass); init_ident_of(new_klass);
_unloaded_klasses->append(new_klass); _unloaded_klasses.append(new_klass);
return new_klass; return new_klass;
} }
@ -531,8 +521,8 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass,
// Get a ciInstance representing an as-yet undetermined instance of a given class. // Get a ciInstance representing an as-yet undetermined instance of a given class.
// //
ciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_klass) { ciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_klass) {
for (int i=0; i<_unloaded_instances->length(); i++) { for (int i = 0; i < _unloaded_instances.length(); i++) {
ciInstance* entry = _unloaded_instances->at(i); ciInstance* entry = _unloaded_instances.at(i);
if (entry->klass()->equals(instance_klass)) { if (entry->klass()->equals(instance_klass)) {
// We've found a match. // We've found a match.
return entry; return entry;
@ -544,7 +534,7 @@ ciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_kla
ciInstance* new_instance = new (arena()) ciInstance(instance_klass); ciInstance* new_instance = new (arena()) ciInstance(instance_klass);
init_ident_of(new_instance); init_ident_of(new_instance);
_unloaded_instances->append(new_instance); _unloaded_instances.append(new_instance);
// make sure it looks the way we want: // make sure it looks the way we want:
assert(!new_instance->is_loaded(), ""); assert(!new_instance->is_loaded(), "");
@ -611,8 +601,8 @@ ciMethodData* ciObjectFactory::get_empty_methodData() {
// //
// Get a ciReturnAddress for a specified bci. // Get a ciReturnAddress for a specified bci.
ciReturnAddress* ciObjectFactory::get_return_address(int bci) { ciReturnAddress* ciObjectFactory::get_return_address(int bci) {
for (int i=0; i<_return_addresses->length(); i++) { for (int i = 0; i < _return_addresses.length(); i++) {
ciReturnAddress* entry = _return_addresses->at(i); ciReturnAddress* entry = _return_addresses.at(i);
if (entry->bci() == bci) { if (entry->bci() == bci) {
// We've found a match. // We've found a match.
return entry; return entry;
@ -621,7 +611,7 @@ ciReturnAddress* ciObjectFactory::get_return_address(int bci) {
ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci); ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci);
init_ident_of(new_ret_addr); init_ident_of(new_ret_addr);
_return_addresses->append(new_ret_addr); _return_addresses.append(new_ret_addr);
return new_ret_addr; return new_ret_addr;
} }
@ -687,9 +677,8 @@ ciSymbol* ciObjectFactory::vm_symbol_at(vmSymbolID sid) {
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciObjectFactory::metadata_do // ciObjectFactory::metadata_do
void ciObjectFactory::metadata_do(MetadataClosure* f) { void ciObjectFactory::metadata_do(MetadataClosure* f) {
if (_ci_metadata == NULL) return; for (int j = 0; j < _ci_metadata.length(); j++) {
for (int j = 0; j< _ci_metadata->length(); j++) { Metadata* o = _ci_metadata.at(j)->constant_encoding();
Metadata* o = _ci_metadata->at(j)->constant_encoding();
f->do_metadata(o); f->do_metadata(o);
} }
} }
@ -697,10 +686,10 @@ void ciObjectFactory::metadata_do(MetadataClosure* f) {
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciObjectFactory::print_contents_impl // ciObjectFactory::print_contents_impl
void ciObjectFactory::print_contents_impl() { void ciObjectFactory::print_contents_impl() {
int len = _ci_metadata->length(); int len = _ci_metadata.length();
tty->print_cr("ciObjectFactory (%d) meta data contents:", len); tty->print_cr("ciObjectFactory (%d) meta data contents:", len);
for (int i=0; i<len; i++) { for (int i = 0; i < len; i++) {
_ci_metadata->at(i)->print(); _ci_metadata.at(i)->print();
tty->cr(); tty->cr();
} }
} }
@ -719,7 +708,7 @@ void ciObjectFactory::print_contents() {
// Print debugging information about the object factory // Print debugging information about the object factory
void ciObjectFactory::print() { void ciObjectFactory::print() {
tty->print("<ciObjectFactory oops=%d metadata=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>", tty->print("<ciObjectFactory oops=%d metadata=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>",
_non_perm_count, _ci_metadata->length(), _unloaded_methods->length(), _non_perm_count, _ci_metadata.length(), _unloaded_methods.length(),
_unloaded_instances->length(), _unloaded_instances.length(),
_unloaded_klasses->length()); _unloaded_klasses.length());
} }

View file

@ -46,14 +46,14 @@ private:
static ciSymbol* _shared_ci_symbols[]; static ciSymbol* _shared_ci_symbols[];
static int _shared_ident_limit; static int _shared_ident_limit;
Arena* _arena; Arena* _arena;
GrowableArray<ciMetadata*>* _ci_metadata; GrowableArray<ciMetadata*> _ci_metadata;
GrowableArray<ciMethod*>* _unloaded_methods; GrowableArray<ciMethod*> _unloaded_methods;
GrowableArray<ciKlass*>* _unloaded_klasses; GrowableArray<ciKlass*> _unloaded_klasses;
GrowableArray<ciInstance*>* _unloaded_instances; GrowableArray<ciInstance*> _unloaded_instances;
GrowableArray<ciReturnAddress*>* _return_addresses; GrowableArray<ciReturnAddress*> _return_addresses;
GrowableArray<ciSymbol*>* _symbols; // keep list of symbols created GrowableArray<ciSymbol*> _symbols; // keep list of symbols created
int _next_ident; int _next_ident;
public: public:
struct NonPermObject : public ResourceObj { struct NonPermObject : public ResourceObj {
@ -139,7 +139,7 @@ public:
ciReturnAddress* get_return_address(int bci); ciReturnAddress* get_return_address(int bci);
GrowableArray<ciMetadata*>* get_ci_metadata() const { return _ci_metadata; } GrowableArray<ciMetadata*>* get_ci_metadata() { return &_ci_metadata; }
// RedefineClasses support // RedefineClasses support
void metadata_do(MetadataClosure* f); void metadata_do(MetadataClosure* f);

View file

@ -37,16 +37,13 @@
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciSignature::ciSignature // ciSignature::ciSignature
ciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* symbol) { ciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* symbol)
: _symbol(symbol), _accessing_klass(accessing_klass), _types(CURRENT_ENV->arena(), 8, 0, NULL) {
ASSERT_IN_VM; ASSERT_IN_VM;
EXCEPTION_CONTEXT; EXCEPTION_CONTEXT;
assert(accessing_klass != NULL, "need origin of access"); assert(accessing_klass != NULL, "need origin of access");
_accessing_klass = accessing_klass;
_symbol = symbol;
ciEnv* env = CURRENT_ENV; ciEnv* env = CURRENT_ENV;
Arena* arena = env->arena();
_types = new (arena) GrowableArray<ciType*>(arena, 8, 0, NULL);
int size = 0; int size = 0;
int count = 0; int count = 0;
@ -62,53 +59,15 @@ ciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpo
ciSymbol* klass_name = env->get_symbol(ss.as_symbol()); ciSymbol* klass_name = env->get_symbol(ss.as_symbol());
type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false); type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
} }
_types->append(type);
if (ss.at_return_type()) { if (ss.at_return_type()) {
// Done processing the return type; do not add it into the count. // don't include return type in size calculation
_return_type = type;
break; break;
} }
_types.append(type);
size += type->size(); size += type->size();
count++;
} }
_size = size; _size = size;
_count = count;
}
// ------------------------------------------------------------------
// ciSignature::ciSignature
ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol, ciMethodType* method_type) :
_symbol(symbol),
_accessing_klass(accessing_klass),
_size( method_type->ptype_slot_count()),
_count(method_type->ptype_count())
{
ASSERT_IN_VM;
EXCEPTION_CONTEXT;
Arena* arena = CURRENT_ENV->arena();
_types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
for (int i = 0; i < _count; i++) {
_types->append(method_type->ptype_at(i));
}
_types->append(method_type->rtype());
}
// ------------------------------------------------------------------
// ciSignature::return_type
//
// What is the return type of this signature?
ciType* ciSignature::return_type() const {
return _types->at(_count);
}
// ------------------------------------------------------------------
// ciSignature::type_at
//
// What is the type of the index'th element of this
// signature?
ciType* ciSignature::type_at(int index) const {
assert(index < _count, "out of bounds");
// The first _klasses element holds the return klass.
return _types->at(index);
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -119,13 +78,22 @@ ciType* ciSignature::type_at(int index) const {
// types are defined to be equal. // types are defined to be equal.
bool ciSignature::equals(ciSignature* that) { bool ciSignature::equals(ciSignature* that) {
// Compare signature // Compare signature
if (!this->as_symbol()->equals(that->as_symbol())) return false; if (!this->as_symbol()->equals(that->as_symbol())) {
return false;
}
// Compare all types of the arguments // Compare all types of the arguments
for (int i = 0; i < _count; i++) { if (_types.length() != that->_types.length()) {
if (this->type_at(i) != that->type_at(i)) return false; return false;
}
for (int i = 0; i < _types.length(); i++) {
if (this->type_at(i) != that->type_at(i)) {
return false;
}
} }
// Compare the return type // Compare the return type
if (this->return_type() != that->return_type()) return false; if (this->return_type() != that->return_type()) {
return false;
}
return true; return true;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,16 +39,15 @@ private:
ciSymbol* _symbol; ciSymbol* _symbol;
ciKlass* _accessing_klass; ciKlass* _accessing_klass;
GrowableArray<ciType*>* _types; GrowableArray<ciType*> _types; // parameter types
ciType* _return_type;
int _size; // number of stack slots required for arguments int _size; // number of stack slots required for arguments
int _count; // number of parameter types in the signature
friend class ciMethod; friend class ciMethod;
friend class ciBytecodeStream; friend class ciBytecodeStream;
friend class ciObjectFactory; friend class ciObjectFactory;
ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* signature); ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* signature);
ciSignature(ciKlass* accessing_klass, ciSymbol* signature, ciMethodType* method_type);
Symbol* get_symbol() const { return _symbol->get_symbol(); } Symbol* get_symbol() const { return _symbol->get_symbol(); }
@ -56,11 +55,11 @@ public:
ciSymbol* as_symbol() const { return _symbol; } ciSymbol* as_symbol() const { return _symbol; }
ciKlass* accessing_klass() const { return _accessing_klass; } ciKlass* accessing_klass() const { return _accessing_klass; }
ciType* return_type() const; ciType* return_type() const { return _return_type; }
ciType* type_at(int index) const; ciType* type_at(int index) const { return _types.at(index); }
int size() const { return _size; } int size() const { return _size; }
int count() const { return _count; } int count() const { return _types.length(); }
int arg_size_for_bc(Bytecodes::Code bc) { return size() + (Bytecodes::has_receiver(bc) ? 1 : 0); } int arg_size_for_bc(Bytecodes::Code bc) { return size() + (Bytecodes::has_receiver(bc) ? 1 : 0); }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -55,23 +55,22 @@
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciTypeFlow::JsrSet::JsrSet // ciTypeFlow::JsrSet::JsrSet
ciTypeFlow::JsrSet::JsrSet(Arena* arena, int default_len) {
if (arena != NULL) { // Allocate growable array storage in Arena.
// Allocate growable array in Arena. ciTypeFlow::JsrSet::JsrSet(Arena* arena, int default_len) : _set(arena, default_len, 0, NULL) {
_set = new (arena) GrowableArray<JsrRecord*>(arena, default_len, 0, NULL); assert(arena != NULL, "invariant");
} else {
// Allocate growable array in current ResourceArea.
_set = new GrowableArray<JsrRecord*>(4, 0, NULL);
}
} }
// Allocate growable array storage in current ResourceArea.
ciTypeFlow::JsrSet::JsrSet(int default_len) : _set(default_len, 0, NULL) {}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciTypeFlow::JsrSet::copy_into // ciTypeFlow::JsrSet::copy_into
void ciTypeFlow::JsrSet::copy_into(JsrSet* jsrs) { void ciTypeFlow::JsrSet::copy_into(JsrSet* jsrs) {
int len = size(); int len = size();
jsrs->_set->clear(); jsrs->_set.clear();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
jsrs->_set->append(_set->at(i)); jsrs->_set.append(_set.at(i));
} }
} }
@ -158,7 +157,7 @@ void ciTypeFlow::JsrSet::insert_jsr_record(JsrRecord* record) {
JsrRecord* current = record_at(pos); JsrRecord* current = record_at(pos);
if (entry == current->entry_address()) { if (entry == current->entry_address()) {
// Stomp over this entry. // Stomp over this entry.
_set->at_put(pos, record); _set.at_put(pos, record);
assert(size() == len, "must be same size"); assert(size() == len, "must be same size");
return; return;
} else if (entry < current->entry_address()) { } else if (entry < current->entry_address()) {
@ -170,11 +169,11 @@ void ciTypeFlow::JsrSet::insert_jsr_record(JsrRecord* record) {
JsrRecord* swap = record; JsrRecord* swap = record;
JsrRecord* temp = NULL; JsrRecord* temp = NULL;
for ( ; pos < len; pos++) { for ( ; pos < len; pos++) {
temp = _set->at(pos); temp = _set.at(pos);
_set->at_put(pos, swap); _set.at_put(pos, swap);
swap = temp; swap = temp;
} }
_set->append(swap); _set.append(swap);
assert(size() == len+1, "must be larger"); assert(size() == len+1, "must be larger");
} }
@ -188,10 +187,10 @@ void ciTypeFlow::JsrSet::remove_jsr_record(int return_address) {
if (record_at(i)->return_address() == return_address) { if (record_at(i)->return_address() == return_address) {
// We have found the proper entry. Remove it from the // We have found the proper entry. Remove it from the
// JsrSet and exit. // JsrSet and exit.
for (int j = i+1; j < len ; j++) { for (int j = i + 1; j < len ; j++) {
_set->at_put(j-1, _set->at(j)); _set.at_put(j - 1, _set.at(j));
} }
_set->trunc_to(len-1); _set.trunc_to(len - 1);
assert(size() == len-1, "must be smaller"); assert(size() == len-1, "must be smaller");
return; return;
} }
@ -239,10 +238,10 @@ void ciTypeFlow::JsrSet::print_on(outputStream* st) const {
if (num_elements > 0) { if (num_elements > 0) {
int i = 0; int i = 0;
for( ; i < num_elements - 1; i++) { for( ; i < num_elements - 1; i++) {
_set->at(i)->print_on(st); _set.at(i)->print_on(st);
st->print(", "); st->print(", ");
} }
_set->at(i)->print_on(st); _set.at(i)->print_on(st);
st->print(" "); st->print(" ");
} }
st->print("}"); st->print("}");
@ -371,7 +370,7 @@ const ciTypeFlow::StateVector* ciTypeFlow::get_start_state() {
record_failure(non_osr_flow->failure_reason()); record_failure(non_osr_flow->failure_reason());
return NULL; return NULL;
} }
JsrSet* jsrs = new JsrSet(NULL, 16); JsrSet* jsrs = new JsrSet(4);
Block* non_osr_block = non_osr_flow->existing_block_at(start_bci(), jsrs); Block* non_osr_block = non_osr_flow->existing_block_at(start_bci(), jsrs);
if (non_osr_block == NULL) { if (non_osr_block == NULL) {
record_failure("cannot reach OSR point"); record_failure("cannot reach OSR point");
@ -1584,12 +1583,11 @@ void ciTypeFlow::SuccIter::set_succ(Block* succ) {
// ciTypeFlow::Block::Block // ciTypeFlow::Block::Block
ciTypeFlow::Block::Block(ciTypeFlow* outer, ciTypeFlow::Block::Block(ciTypeFlow* outer,
ciBlock *ciblk, ciBlock *ciblk,
ciTypeFlow::JsrSet* jsrs) { ciTypeFlow::JsrSet* jsrs) : _predecessors(outer->arena(), 1, 0, NULL) {
_ciblock = ciblk; _ciblock = ciblk;
_exceptions = NULL; _exceptions = NULL;
_exc_klasses = NULL; _exc_klasses = NULL;
_successors = NULL; _successors = NULL;
_predecessors = new (outer->arena()) GrowableArray<Block*>(outer->arena(), 1, 0, NULL);
_state = new (outer->arena()) StateVector(outer); _state = new (outer->arena()) StateVector(outer);
JsrSet* new_jsrs = JsrSet* new_jsrs =
new (outer->arena()) JsrSet(outer->arena(), jsrs->size()); new (outer->arena()) JsrSet(outer->arena(), jsrs->size());
@ -1919,13 +1917,13 @@ void ciTypeFlow::Block::print_on(outputStream* st) const {
st->cr(); st->cr();
} }
} }
if (_predecessors == NULL) { if (_predecessors.is_empty()) {
st->print_cr(" No predecessor information"); st->print_cr(" No predecessor information");
} else { } else {
int num_predecessors = _predecessors->length(); int num_predecessors = _predecessors.length();
st->print_cr(" Predecessors : %d", num_predecessors); st->print_cr(" Predecessors : %d", num_predecessors);
for (int i = 0; i < num_predecessors; i++) { for (int i = 0; i < num_predecessors; i++) {
Block* predecessor = _predecessors->at(i); Block* predecessor = _predecessors.at(i);
st->print(" "); st->print(" ");
predecessor->print_value_on(st); predecessor->print_value_on(st);
st->cr(); st->cr();
@ -1979,23 +1977,18 @@ void ciTypeFlow::LocalSet::print_on(outputStream* st, int limit) const {
ciTypeFlow::ciTypeFlow(ciEnv* env, ciMethod* method, int osr_bci) { ciTypeFlow::ciTypeFlow(ciEnv* env, ciMethod* method, int osr_bci) {
_env = env; _env = env;
_method = method; _method = method;
_methodBlocks = method->get_method_blocks();
_max_locals = method->max_locals();
_max_stack = method->max_stack();
_code_size = method->code_size();
_has_irreducible_entry = false; _has_irreducible_entry = false;
_osr_bci = osr_bci; _osr_bci = osr_bci;
_failure_reason = NULL; _failure_reason = NULL;
assert(0 <= start_bci() && start_bci() < code_size() , "correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size()); assert(0 <= start_bci() && start_bci() < code_size() , "correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size());
_work_list = NULL; _work_list = NULL;
_ciblock_count = _methodBlocks->num_blocks(); int ciblock_count = _method->get_method_blocks()->num_blocks();
_idx_to_blocklist = NEW_ARENA_ARRAY(arena(), GrowableArray<Block*>*, _ciblock_count); _idx_to_blocklist = NEW_ARENA_ARRAY(arena(), GrowableArray<Block*>*, ciblock_count);
for (int i = 0; i < _ciblock_count; i++) { for (int i = 0; i < ciblock_count; i++) {
_idx_to_blocklist[i] = NULL; _idx_to_blocklist[i] = NULL;
} }
_block_map = NULL; // until all blocks are seen _block_map = NULL; // until all blocks are seen
_jsr_count = 0;
_jsr_records = NULL; _jsr_records = NULL;
} }
@ -2065,7 +2058,7 @@ ciTypeFlow::Block* ciTypeFlow::block_at(int bci, ciTypeFlow::JsrSet* jsrs, Creat
tty->cr(); tty->cr();
} }
ciBlock* ciblk = _methodBlocks->block_containing(bci); ciBlock* ciblk = _method->get_method_blocks()->block_containing(bci);
assert(ciblk->start_bci() == bci, "bad ciBlock boundaries"); assert(ciblk->start_bci() == bci, "bad ciBlock boundaries");
Block* block = get_block_for(ciblk->index(), jsrs, option); Block* block = get_block_for(ciblk->index(), jsrs, option);
@ -2093,7 +2086,7 @@ ciTypeFlow::JsrRecord* ciTypeFlow::make_jsr_record(int entry_address,
int return_address) { int return_address) {
if (_jsr_records == NULL) { if (_jsr_records == NULL) {
_jsr_records = new (arena()) GrowableArray<JsrRecord*>(arena(), _jsr_records = new (arena()) GrowableArray<JsrRecord*>(arena(),
_jsr_count, 2,
0, 0,
NULL); NULL);
} }
@ -2637,8 +2630,8 @@ void ciTypeFlow::df_flow_types(Block* start,
int dft_len = 100; int dft_len = 100;
GrowableArray<Block*> stk(dft_len); GrowableArray<Block*> stk(dft_len);
ciBlock* dummy = _methodBlocks->make_dummy_block(); ciBlock* dummy = _method->get_method_blocks()->make_dummy_block();
JsrSet* root_set = new JsrSet(NULL, 0); JsrSet* root_set = new JsrSet(0);
Block* root_head = new (arena()) Block(this, dummy, root_set); Block* root_head = new (arena()) Block(this, dummy, root_set);
Block* root_tail = new (arena()) Block(this, dummy, root_set); Block* root_tail = new (arena()) Block(this, dummy, root_set);
root_head->set_pre_order(0); root_head->set_pre_order(0);
@ -2711,7 +2704,7 @@ void ciTypeFlow::df_flow_types(Block* start,
void ciTypeFlow::flow_types() { void ciTypeFlow::flow_types() {
ResourceMark rm; ResourceMark rm;
StateVector* temp_vector = new StateVector(this); StateVector* temp_vector = new StateVector(this);
JsrSet* temp_set = new JsrSet(NULL, 16); JsrSet* temp_set = new JsrSet(4);
// Create the method entry block. // Create the method entry block.
Block* start = block_at(start_bci(), temp_set); Block* start = block_at(start_bci(), temp_set);
@ -2839,7 +2832,7 @@ ciTypeFlow::Block* ciTypeFlow::get_block_for(int ciBlockIndex, ciTypeFlow::JsrSe
if (option == no_create) return NULL; if (option == no_create) return NULL;
// We did not find a compatible block. Create one. // We did not find a compatible block. Create one.
Block* new_block = new (a) Block(this, _methodBlocks->block(ciBlockIndex), jsrs); Block* new_block = new (a) Block(this, _method->get_method_blocks()->block(ciBlockIndex), jsrs);
if (option == create_backedge_copy) new_block->set_backedge_copy(true); if (option == create_backedge_copy) new_block->set_backedge_copy(true);
blocks->append(new_block); blocks->append(new_block);
return new_block; return new_block;
@ -2904,9 +2897,9 @@ bool ciTypeFlow::is_dominated_by(int bci, int dom_bci) {
assert(!method()->has_jsrs(), "jsrs are not supported"); assert(!method()->has_jsrs(), "jsrs are not supported");
ResourceMark rm; ResourceMark rm;
JsrSet* jsrs = new ciTypeFlow::JsrSet(NULL); JsrSet* jsrs = new ciTypeFlow::JsrSet();
int index = _methodBlocks->block_containing(bci)->index(); int index = _method->get_method_blocks()->block_containing(bci)->index();
int dom_index = _methodBlocks->block_containing(dom_bci)->index(); int dom_index = _method->get_method_blocks()->block_containing(dom_bci)->index();
Block* block = get_block_for(index, jsrs, ciTypeFlow::no_create); Block* block = get_block_for(index, jsrs, ciTypeFlow::no_create);
Block* dom_block = get_block_for(dom_index, jsrs, ciTypeFlow::no_create); Block* dom_block = get_block_for(dom_index, jsrs, ciTypeFlow::no_create);
@ -2988,7 +2981,7 @@ void ciTypeFlow::print_on(outputStream* st) const {
method()->name()->print_symbol_on(st); method()->name()->print_symbol_on(st);
int limit_bci = code_size(); int limit_bci = code_size();
st->print_cr(" %d bytes", limit_bci); st->print_cr(" %d bytes", limit_bci);
ciMethodBlocks *mblks = _methodBlocks; ciMethodBlocks* mblks = _method->get_method_blocks();
ciBlock* current = NULL; ciBlock* current = NULL;
for (int bci = 0; bci < limit_bci; bci++) { for (int bci = 0; bci < limit_bci; bci++) {
ciBlock* blk = mblks->block_containing(bci); ciBlock* blk = mblks->block_containing(bci);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,13 +36,8 @@ class ciTypeFlow : public ResourceObj {
private: private:
ciEnv* _env; ciEnv* _env;
ciMethod* _method; ciMethod* _method;
ciMethodBlocks* _methodBlocks;
int _osr_bci; int _osr_bci;
// information cached from the method:
int _max_locals;
int _max_stack;
int _code_size;
bool _has_irreducible_entry; bool _has_irreducible_entry;
const char* _failure_reason; const char* _failure_reason;
@ -62,10 +57,10 @@ public:
Arena* arena() { return _env->arena(); } Arena* arena() { return _env->arena(); }
bool is_osr_flow() const{ return _osr_bci != InvocationEntryBci; } bool is_osr_flow() const{ return _osr_bci != InvocationEntryBci; }
int start_bci() const { return is_osr_flow()? _osr_bci: 0; } int start_bci() const { return is_osr_flow()? _osr_bci: 0; }
int max_locals() const { return _max_locals; } int max_locals() const { return method()->max_locals(); }
int max_stack() const { return _max_stack; } int max_stack() const { return method()->max_stack(); }
int max_cells() const { return _max_locals + _max_stack; } int max_cells() const { return max_locals() + max_stack(); }
int code_size() const { return _code_size; } int code_size() const { return method()->code_size(); }
bool has_irreducible_entry() const { return _has_irreducible_entry; } bool has_irreducible_entry() const { return _has_irreducible_entry; }
// Represents information about an "active" jsr call. This // Represents information about an "active" jsr call. This
@ -104,10 +99,10 @@ public:
// if paths are compatible. <DISCUSSION> // if paths are compatible. <DISCUSSION>
class JsrSet : public ResourceObj { class JsrSet : public ResourceObj {
private: private:
GrowableArray<JsrRecord*>* _set; GrowableArray<JsrRecord*> _set;
JsrRecord* record_at(int i) { JsrRecord* record_at(int i) {
return _set->at(i); return _set.at(i);
} }
// Insert the given JsrRecord into the JsrSet, maintaining the order // Insert the given JsrRecord into the JsrSet, maintaining the order
@ -119,6 +114,7 @@ public:
public: public:
JsrSet(Arena* arena, int default_len = 4); JsrSet(Arena* arena, int default_len = 4);
JsrSet(int default_len = 4);
// Copy this JsrSet. // Copy this JsrSet.
void copy_into(JsrSet* jsrs); void copy_into(JsrSet* jsrs);
@ -132,7 +128,7 @@ public:
StateVector* state); StateVector* state);
// What is the cardinality of this set? // What is the cardinality of this set?
int size() const { return _set->length(); } int size() const { return _set.length(); }
void print_on(outputStream* st) const PRODUCT_RETURN; void print_on(outputStream* st) const PRODUCT_RETURN;
}; };
@ -523,7 +519,7 @@ public:
GrowableArray<Block*>* _exceptions; GrowableArray<Block*>* _exceptions;
GrowableArray<ciInstanceKlass*>* _exc_klasses; GrowableArray<ciInstanceKlass*>* _exc_klasses;
GrowableArray<Block*>* _successors; GrowableArray<Block*>* _successors;
GrowableArray<Block*>* _predecessors; GrowableArray<Block*> _predecessors;
StateVector* _state; StateVector* _state;
JsrSet* _jsrs; JsrSet* _jsrs;
@ -614,8 +610,7 @@ public:
// Predecessors of this block (including exception edges) // Predecessors of this block (including exception edges)
GrowableArray<Block*>* predecessors() { GrowableArray<Block*>* predecessors() {
assert(_predecessors != NULL, "must be filled in"); return &_predecessors;
return _predecessors;
} }
// Get the exceptional successors for this Block. // Get the exceptional successors for this Block.
@ -795,8 +790,6 @@ private:
// For each ciBlock index, a list of Blocks which share this ciBlock. // For each ciBlock index, a list of Blocks which share this ciBlock.
GrowableArray<Block*>** _idx_to_blocklist; GrowableArray<Block*>** _idx_to_blocklist;
// count of ciBlocks
int _ciblock_count;
// Tells if a given instruction is able to generate an exception edge. // Tells if a given instruction is able to generate an exception edge.
bool can_trap(ciBytecodeStream& str); bool can_trap(ciBytecodeStream& str);
@ -872,7 +865,6 @@ private:
Loop* _loop_tree_root; Loop* _loop_tree_root;
// State used for make_jsr_record // State used for make_jsr_record
int _jsr_count;
GrowableArray<JsrRecord*>* _jsr_records; GrowableArray<JsrRecord*>* _jsr_records;
public: public:

View file

@ -865,9 +865,8 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
nonstatic_field(ciField, _is_constant, bool) \ nonstatic_field(ciField, _is_constant, bool) \
nonstatic_field(ciField, _constant_value, ciConstant) \ nonstatic_field(ciField, _constant_value, ciConstant) \
\ \
nonstatic_field(ciObjectFactory, _ci_metadata, GrowableArray<ciMetadata*>*) \ nonstatic_field(ciObjectFactory, _ci_metadata, GrowableArray<ciMetadata*>) \
nonstatic_field(ciObjectFactory, _symbols, GrowableArray<ciSymbol*>*) \ nonstatic_field(ciObjectFactory, _symbols, GrowableArray<ciSymbol*>) \
nonstatic_field(ciObjectFactory, _unloaded_methods, GrowableArray<ciMethod*>*) \
\ \
nonstatic_field(ciConstant, _type, BasicType) \ nonstatic_field(ciConstant, _type, BasicType) \
nonstatic_field(ciConstant, _value._int, jint) \ nonstatic_field(ciConstant, _value._int, jint) \

View file

@ -45,7 +45,6 @@ public class ciObjectFactory extends VMObject {
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("ciObjectFactory"); Type type = db.lookupType("ciObjectFactory");
unloadedMethodsField = type.getAddressField("_unloaded_methods");
ciMetadataField = type.getAddressField("_ci_metadata"); ciMetadataField = type.getAddressField("_ci_metadata");
symbolsField = type.getAddressField("_symbols"); symbolsField = type.getAddressField("_symbols");
@ -54,7 +53,6 @@ public class ciObjectFactory extends VMObject {
ciSymbolConstructor = new VirtualBaseConstructor<ciSymbol>(db, db.lookupType("ciSymbol"), "sun.jvm.hotspot.ci", ciSymbol.class); ciSymbolConstructor = new VirtualBaseConstructor<ciSymbol>(db, db.lookupType("ciSymbol"), "sun.jvm.hotspot.ci", ciSymbol.class);
} }
private static AddressField unloadedMethodsField;
private static AddressField ciMetadataField; private static AddressField ciMetadataField;
private static AddressField symbolsField; private static AddressField symbolsField;
@ -75,11 +73,13 @@ public class ciObjectFactory extends VMObject {
} }
public GrowableArray<ciMetadata> objects() { public GrowableArray<ciMetadata> objects() {
return GrowableArray.create(ciMetadataField.getValue(getAddress()), ciMetadataConstructor); Address addr = getAddress().addOffsetTo(ciMetadataField.getOffset());
return GrowableArray.create(addr, ciMetadataConstructor);
} }
public GrowableArray<ciSymbol> symbols() { public GrowableArray<ciSymbol> symbols() {
return GrowableArray.create(symbolsField.getValue(getAddress()), ciSymbolConstructor); Address addr = getAddress().addOffsetTo(symbolsField.getOffset());
return GrowableArray.create(addr, ciSymbolConstructor);
} }
public ciObjectFactory(Address addr) { public ciObjectFactory(Address addr) {