8289164: Convert ResolutionErrorTable to use ResourceHashtable
Reviewed-by: iklam, coleenp
This commit is contained in:
parent
013a5eeeb9
commit
86f63f9703
@ -25,162 +25,141 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/resolutionErrors.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
ResourceHashtable<uintptr_t, ResolutionErrorEntry*, 107, ResourceObj::C_HEAP, mtClass> _resolution_error_table;
|
||||
|
||||
// create new error entry
|
||||
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
|
||||
const constantPoolHandle& pool, int cp_index,
|
||||
void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_index,
|
||||
Symbol* error, Symbol* message,
|
||||
Symbol* cause, Symbol* cause_msg)
|
||||
{
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
assert(!pool.is_null() && error != NULL, "adding NULL obj");
|
||||
|
||||
ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool());
|
||||
entry->set_cp_index(cp_index);
|
||||
entry->set_error(error);
|
||||
entry->set_message(message);
|
||||
entry->set_nest_host_error(NULL);
|
||||
entry->set_cause(cause);
|
||||
entry->set_cause_msg(cause_msg);
|
||||
|
||||
add_entry(index, entry);
|
||||
ResolutionErrorEntry* entry = new ResolutionErrorEntry(pool(), cp_index, error, message, cause, cause_msg);
|
||||
_resolution_error_table.put(convert_key(pool, cp_index), entry);
|
||||
}
|
||||
|
||||
// create new nest host error entry
|
||||
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
|
||||
const constantPoolHandle& pool, int cp_index,
|
||||
void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_index,
|
||||
const char* message)
|
||||
{
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
assert(!pool.is_null() && message != NULL, "adding NULL obj");
|
||||
|
||||
ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool());
|
||||
entry->set_cp_index(cp_index);
|
||||
entry->set_nest_host_error(message);
|
||||
entry->set_error(NULL);
|
||||
entry->set_message(NULL);
|
||||
entry->set_cause(NULL);
|
||||
entry->set_cause_msg(NULL);
|
||||
|
||||
add_entry(index, entry);
|
||||
ResolutionErrorEntry* entry = new ResolutionErrorEntry(pool(), cp_index, message);
|
||||
_resolution_error_table.put(convert_key(pool, cp_index), entry);
|
||||
}
|
||||
|
||||
// find entry in the table
|
||||
ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int hash,
|
||||
const constantPoolHandle& pool, int cp_index)
|
||||
{
|
||||
ResolutionErrorEntry* ResolutionErrorTable::find_entry(const constantPoolHandle& pool, int cp_index) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
|
||||
for (ResolutionErrorEntry *error_probe = bucket(index);
|
||||
error_probe != NULL;
|
||||
error_probe = error_probe->next()) {
|
||||
if (error_probe->hash() == hash && error_probe->pool() == pool()) {
|
||||
return error_probe;;
|
||||
}
|
||||
ResolutionErrorEntry** entry = _resolution_error_table.get(convert_key(pool, cp_index));
|
||||
if (entry != nullptr) {
|
||||
return *entry;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void ResolutionErrorEntry::set_error(Symbol* e) {
|
||||
_error = e;
|
||||
if (_error != NULL) {
|
||||
ResolutionErrorEntry::ResolutionErrorEntry(ConstantPool* pool, int cp_index, Symbol* error, Symbol* message,
|
||||
Symbol* cause, Symbol* cause_msg):
|
||||
_cp_index(cp_index),
|
||||
_error(error),
|
||||
_message(message),
|
||||
_cause(cause),
|
||||
_cause_msg(cause_msg),
|
||||
_pool(pool),
|
||||
_nest_host_error(nullptr) {
|
||||
|
||||
if (_error != nullptr) {
|
||||
_error->increment_refcount();
|
||||
}
|
||||
}
|
||||
|
||||
void ResolutionErrorEntry::set_message(Symbol* c) {
|
||||
_message = c;
|
||||
if (_message != NULL) {
|
||||
if (_message != nullptr) {
|
||||
_message->increment_refcount();
|
||||
}
|
||||
}
|
||||
|
||||
void ResolutionErrorEntry::set_cause(Symbol* c) {
|
||||
_cause = c;
|
||||
if (_cause != NULL) {
|
||||
if (_cause != nullptr) {
|
||||
_cause->increment_refcount();
|
||||
}
|
||||
}
|
||||
|
||||
void ResolutionErrorEntry::set_cause_msg(Symbol* c) {
|
||||
_cause_msg = c;
|
||||
if (_cause_msg != NULL) {
|
||||
if (_cause_msg != nullptr) {
|
||||
_cause_msg->increment_refcount();
|
||||
}
|
||||
}
|
||||
|
||||
void ResolutionErrorEntry::set_nest_host_error(const char* message) {
|
||||
_nest_host_error = message;
|
||||
}
|
||||
|
||||
void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
|
||||
ResolutionErrorEntry::~ResolutionErrorEntry() {
|
||||
// decrement error refcount
|
||||
if (entry->error() != NULL) {
|
||||
entry->error()->decrement_refcount();
|
||||
if (error() != NULL) {
|
||||
error()->decrement_refcount();
|
||||
}
|
||||
if (entry->message() != NULL) {
|
||||
entry->message()->decrement_refcount();
|
||||
if (message() != NULL) {
|
||||
message()->decrement_refcount();
|
||||
}
|
||||
if (entry->cause() != NULL) {
|
||||
entry->cause()->decrement_refcount();
|
||||
if (cause() != NULL) {
|
||||
cause()->decrement_refcount();
|
||||
}
|
||||
if (entry->cause_msg() != NULL) {
|
||||
entry->cause_msg()->decrement_refcount();
|
||||
if (cause_msg() != NULL) {
|
||||
cause_msg()->decrement_refcount();
|
||||
}
|
||||
if (entry->nest_host_error() != NULL) {
|
||||
FREE_C_HEAP_ARRAY(char, entry->nest_host_error());
|
||||
if (nest_host_error() != NULL) {
|
||||
FREE_C_HEAP_ARRAY(char, nest_host_error());
|
||||
}
|
||||
BasicHashtable<mtClass>::free_entry(entry);
|
||||
}
|
||||
|
||||
class ResolutionErrorDeleteIterate : StackObj{
|
||||
private:
|
||||
ConstantPool* p;
|
||||
|
||||
// create resolution error table
|
||||
ResolutionErrorTable::ResolutionErrorTable(int table_size)
|
||||
: Hashtable<ConstantPool*, mtClass>(table_size, sizeof(ResolutionErrorEntry)) {
|
||||
}
|
||||
public:
|
||||
ResolutionErrorDeleteIterate(ConstantPool* pool):
|
||||
p(pool) {};
|
||||
|
||||
// RedefineClasses support - remove matching entry of a
|
||||
// constant pool that is going away
|
||||
void ResolutionErrorTable::delete_entry(ConstantPool* c) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
for (int i = 0; i < table_size(); i++) {
|
||||
for (ResolutionErrorEntry** p = bucket_addr(i); *p != NULL; ) {
|
||||
ResolutionErrorEntry* entry = *p;
|
||||
assert(entry->pool() != NULL, "resolution error table is corrupt");
|
||||
if (entry->pool() == c) {
|
||||
*p = entry->next();
|
||||
free_entry(entry);
|
||||
} else {
|
||||
p = entry->next_addr();
|
||||
}
|
||||
bool do_entry(uintptr_t key, ResolutionErrorEntry* value){
|
||||
if (value -> pool() == p) {
|
||||
delete value;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Delete entries in the table that match with ConstantPool c
|
||||
void ResolutionErrorTable::delete_entry(ConstantPool* c) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
|
||||
ResolutionErrorDeleteIterate deleteIterator(c);
|
||||
_resolution_error_table.unlink(&deleteIterator);
|
||||
}
|
||||
|
||||
class ResolutionIteratePurgeErrors : StackObj{
|
||||
public:
|
||||
bool do_entry(uintptr_t key, ResolutionErrorEntry* value) {
|
||||
ConstantPool* pool = value -> pool();
|
||||
if (!(pool->pool_holder()->is_loader_alive())) {
|
||||
delete value;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Remove unloaded entries from the table
|
||||
void ResolutionErrorTable::purge_resolution_errors() {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
for (int i = 0; i < table_size(); i++) {
|
||||
for (ResolutionErrorEntry** p = bucket_addr(i); *p != NULL; ) {
|
||||
ResolutionErrorEntry* entry = *p;
|
||||
assert(entry->pool() != (ConstantPool*)NULL, "resolution error table is corrupt");
|
||||
ConstantPool* pool = entry->pool();
|
||||
assert(pool->pool_holder() != NULL, "Constant pool without a class?");
|
||||
|
||||
if (pool->pool_holder()->is_loader_alive()) {
|
||||
p = entry->next_addr();
|
||||
} else {
|
||||
*p = entry->next();
|
||||
free_entry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
ResolutionIteratePurgeErrors purgeErrorsIterator;
|
||||
_resolution_error_table.unlink(&purgeErrorsIterator);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define SHARE_CLASSFILE_RESOLUTIONERRORS_HPP
|
||||
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "utilities/hashtable.hpp"
|
||||
|
||||
class ResolutionErrorEntry;
|
||||
|
||||
@ -39,48 +38,23 @@ class ResolutionErrorEntry;
|
||||
// index of another entry in the table.
|
||||
const int CPCACHE_INDEX_MANGLE_VALUE = 1000000;
|
||||
|
||||
class ResolutionErrorTable : public Hashtable<ConstantPool*, mtClass> {
|
||||
|
||||
private:
|
||||
void free_entry(ResolutionErrorEntry *entry);
|
||||
class ResolutionErrorTable : AllStatic {
|
||||
|
||||
public:
|
||||
ResolutionErrorTable(int table_size);
|
||||
|
||||
ResolutionErrorEntry* bucket(int i) {
|
||||
return (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::bucket(i);
|
||||
}
|
||||
|
||||
ResolutionErrorEntry** bucket_addr(int i) {
|
||||
return (ResolutionErrorEntry**)Hashtable<ConstantPool*, mtClass>::bucket_addr(i);
|
||||
}
|
||||
|
||||
void add_entry(int index, ResolutionErrorEntry* new_entry) {
|
||||
Hashtable<ConstantPool*, mtClass>::add_entry(index,
|
||||
(HashtableEntry<ConstantPool*, mtClass>*)new_entry);
|
||||
}
|
||||
|
||||
void add_entry(int index, unsigned int hash,
|
||||
const constantPoolHandle& pool, int which, Symbol* error, Symbol* message,
|
||||
static void add_entry(const constantPoolHandle& pool, int which, Symbol* error, Symbol* message,
|
||||
Symbol* cause, Symbol* cause_msg);
|
||||
|
||||
void add_entry(int index, unsigned int hash,
|
||||
const constantPoolHandle& pool, int which, const char* message);
|
||||
static void add_entry(const constantPoolHandle& pool, int which, const char* message);
|
||||
|
||||
// find error given the constant pool and constant pool index
|
||||
ResolutionErrorEntry* find_entry(int index, unsigned int hash,
|
||||
const constantPoolHandle& pool, int cp_index);
|
||||
|
||||
|
||||
unsigned int compute_hash(const constantPoolHandle& pool, int cp_index) {
|
||||
return (unsigned int) pool->identity_hash() + cp_index;
|
||||
}
|
||||
static ResolutionErrorEntry* find_entry(const constantPoolHandle& pool, int cp_index);
|
||||
|
||||
// purges unloaded entries from the table
|
||||
void purge_resolution_errors();
|
||||
static void purge_resolution_errors();
|
||||
|
||||
// RedefineClasses support - remove obsolete constant pool entry
|
||||
void delete_entry(ConstantPool* c);
|
||||
static void delete_entry(ConstantPool* c);
|
||||
|
||||
// This function is used to encode an index to differentiate it from a
|
||||
// constant pool index. It assumes it is being called with a cpCache index
|
||||
@ -89,46 +63,52 @@ public:
|
||||
assert(index < 0, "Unexpected non-negative cpCache index");
|
||||
return index + CPCACHE_INDEX_MANGLE_VALUE;
|
||||
}
|
||||
|
||||
static uintptr_t convert_key(const constantPoolHandle& pool, int cp_index) {
|
||||
return (uintptr_t) (pool() + cp_index);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ResolutionErrorEntry : public HashtableEntry<ConstantPool*, mtClass> {
|
||||
class ResolutionErrorEntry : public CHeapObj<mtClass> {
|
||||
private:
|
||||
int _cp_index;
|
||||
Symbol* _error;
|
||||
Symbol* _message;
|
||||
Symbol* _cause;
|
||||
Symbol* _cause_msg;
|
||||
ConstantPool* _pool;
|
||||
const char* _nest_host_error;
|
||||
|
||||
public:
|
||||
ConstantPool* pool() const { return literal(); }
|
||||
|
||||
ResolutionErrorEntry(ConstantPool* pool, int cp_index, Symbol* error, Symbol* message,
|
||||
Symbol* cause, Symbol* cause_msg);
|
||||
|
||||
ResolutionErrorEntry(ConstantPool* pool, int cp_index, const char* message):
|
||||
_cp_index(cp_index),
|
||||
_error(nullptr),
|
||||
_message(nullptr),
|
||||
_cause(nullptr),
|
||||
_cause_msg(nullptr),
|
||||
_pool(pool),
|
||||
_nest_host_error(message) {}
|
||||
|
||||
~ResolutionErrorEntry();
|
||||
|
||||
void set_nest_host_error(const char* message) {
|
||||
_nest_host_error = message;
|
||||
}
|
||||
|
||||
|
||||
ConstantPool* pool() const { return _pool; }
|
||||
int cp_index() const { return _cp_index; }
|
||||
void set_cp_index(int cp_index) { _cp_index = cp_index; }
|
||||
|
||||
Symbol* error() const { return _error; }
|
||||
void set_error(Symbol* e);
|
||||
|
||||
Symbol* message() const { return _message; }
|
||||
void set_message(Symbol* c);
|
||||
|
||||
Symbol* cause() const { return _cause; }
|
||||
void set_cause(Symbol* c);
|
||||
|
||||
Symbol* cause_msg() const { return _cause_msg; }
|
||||
void set_cause_msg(Symbol* c);
|
||||
|
||||
const char* nest_host_error() const { return _nest_host_error; }
|
||||
void set_nest_host_error(const char* message);
|
||||
|
||||
ResolutionErrorEntry* next() const {
|
||||
return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next();
|
||||
}
|
||||
|
||||
ResolutionErrorEntry** next_addr() {
|
||||
return (ResolutionErrorEntry**)HashtableEntry<ConstantPool*, mtClass>::next_addr();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_CLASSFILE_RESOLUTIONERRORS_HPP
|
||||
|
@ -87,7 +87,6 @@
|
||||
#include "jfr/jfr.hpp"
|
||||
#endif
|
||||
|
||||
ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL;
|
||||
SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
|
||||
ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL;
|
||||
|
||||
@ -1605,7 +1604,7 @@ bool SystemDictionary::do_unloading(GCTimer* gc_timer) {
|
||||
MutexLocker ml1(is_concurrent ? SystemDictionary_lock : NULL);
|
||||
ClassLoaderDataGraph::clean_module_and_package_info();
|
||||
constraints()->purge_loader_constraints();
|
||||
resolution_errors()->purge_resolution_errors();
|
||||
ResolutionErrorTable::purge_resolution_errors();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1647,7 +1646,6 @@ void SystemDictionary::initialize(TRAPS) {
|
||||
// Allocate arrays
|
||||
_placeholders = new PlaceholderTable(_placeholder_table_size);
|
||||
_loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
|
||||
_resolution_errors = new ResolutionErrorTable(_resolution_error_size);
|
||||
_invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
|
||||
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
|
||||
|
||||
@ -1848,30 +1846,27 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name,
|
||||
void SystemDictionary::add_resolution_error(const constantPoolHandle& pool, int which,
|
||||
Symbol* error, Symbol* message,
|
||||
Symbol* cause, Symbol* cause_msg) {
|
||||
unsigned int hash = resolution_errors()->compute_hash(pool, which);
|
||||
int index = resolution_errors()->hash_to_index(hash);
|
||||
{
|
||||
MutexLocker ml(Thread::current(), SystemDictionary_lock);
|
||||
ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
|
||||
ResolutionErrorEntry* entry = ResolutionErrorTable::find_entry(pool, which);
|
||||
if (entry == NULL) {
|
||||
resolution_errors()->add_entry(index, hash, pool, which, error, message, cause, cause_msg);
|
||||
ResolutionErrorTable::add_entry(pool, which, error, message, cause, cause_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete a resolution error for RedefineClasses for a constant pool is going away
|
||||
void SystemDictionary::delete_resolution_error(ConstantPool* pool) {
|
||||
resolution_errors()->delete_entry(pool);
|
||||
ResolutionErrorTable::delete_entry(pool);
|
||||
}
|
||||
|
||||
// Lookup resolution error table. Returns error if found, otherwise NULL.
|
||||
Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, int which,
|
||||
Symbol** message, Symbol** cause, Symbol** cause_msg) {
|
||||
unsigned int hash = resolution_errors()->compute_hash(pool, which);
|
||||
int index = resolution_errors()->hash_to_index(hash);
|
||||
|
||||
{
|
||||
MutexLocker ml(Thread::current(), SystemDictionary_lock);
|
||||
ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
|
||||
ResolutionErrorEntry* entry = ResolutionErrorTable::find_entry(pool, which);
|
||||
if (entry != NULL) {
|
||||
*message = entry->message();
|
||||
*cause = entry->cause();
|
||||
@ -1887,14 +1882,13 @@ Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool,
|
||||
// validating a nest host. This is used to construct informative error
|
||||
// messages when IllegalAccessError's occur. If an entry already exists it will
|
||||
// be updated with the nest host error message.
|
||||
|
||||
void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool,
|
||||
int which,
|
||||
const char* message) {
|
||||
unsigned int hash = resolution_errors()->compute_hash(pool, which);
|
||||
int index = resolution_errors()->hash_to_index(hash);
|
||||
{
|
||||
MutexLocker ml(Thread::current(), SystemDictionary_lock);
|
||||
ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
|
||||
ResolutionErrorEntry* entry = ResolutionErrorTable::find_entry(pool, which);
|
||||
if (entry != NULL && entry->nest_host_error() == NULL) {
|
||||
// An existing entry means we had a true resolution failure (LinkageError) with our nest host, but we
|
||||
// still want to add the error message for the higher-level access checks to report. We should
|
||||
@ -1902,18 +1896,16 @@ void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool,
|
||||
// the message. If we see it is already set then we can ignore it.
|
||||
entry->set_nest_host_error(message);
|
||||
} else {
|
||||
resolution_errors()->add_entry(index, hash, pool, which, message);
|
||||
ResolutionErrorTable::add_entry(pool, which, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup any nest host error
|
||||
const char* SystemDictionary::find_nest_host_error(const constantPoolHandle& pool, int which) {
|
||||
unsigned int hash = resolution_errors()->compute_hash(pool, which);
|
||||
int index = resolution_errors()->hash_to_index(hash);
|
||||
{
|
||||
MutexLocker ml(Thread::current(), SystemDictionary_lock);
|
||||
ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
|
||||
ResolutionErrorEntry* entry = ResolutionErrorTable::find_entry(pool, which);
|
||||
if (entry != NULL) {
|
||||
return entry->nest_host_error();
|
||||
} else {
|
||||
@ -1922,7 +1914,6 @@ const char* SystemDictionary::find_nest_host_error(const constantPoolHandle& poo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Signature constraints ensure that callers and callees agree about
|
||||
// the meaning of type names in their signatures. This routine is the
|
||||
// intake for constraints. It collects them from several places:
|
||||
|
@ -71,7 +71,6 @@ class ClassFileStream;
|
||||
class ClassLoadInfo;
|
||||
class Dictionary;
|
||||
template <MEMFLAGS F> class HashtableBucket;
|
||||
class ResolutionErrorTable;
|
||||
class SymbolPropertyTable;
|
||||
class PackageEntry;
|
||||
class ProtectionDomainCacheTable;
|
||||
@ -293,9 +292,6 @@ public:
|
||||
private:
|
||||
// Static tables owned by the SystemDictionary
|
||||
|
||||
// Resolution errors
|
||||
static ResolutionErrorTable* _resolution_errors;
|
||||
|
||||
// Invoke methods (JSR 292)
|
||||
static SymbolPropertyTable* _invoke_method_table;
|
||||
|
||||
@ -312,7 +308,6 @@ private:
|
||||
static OopHandle _java_system_loader;
|
||||
static OopHandle _java_platform_loader;
|
||||
|
||||
static ResolutionErrorTable* resolution_errors() { return _resolution_errors; }
|
||||
static SymbolPropertyTable* invoke_method_table() { return _invoke_method_table; }
|
||||
|
||||
private:
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "cds/archiveUtils.hpp"
|
||||
#include "classfile/defaultMethods.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/resolutionErrors.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmClasses.hpp"
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/moduleEntry.hpp"
|
||||
#include "classfile/resolutionErrors.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test 8289164
|
||||
* @summary Test that tests the ResolutionErrorTable
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
public class ErrorsDemoTest {
|
||||
static int x = 0;
|
||||
|
||||
public static void main(String args[]) {
|
||||
String classDirectory = System.getProperty("test.classes");
|
||||
String filename = classDirectory + File.separator + "DeleteMe.class";
|
||||
File file = new File(filename);
|
||||
boolean success = file.delete();
|
||||
String oldMessage = null;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
try {
|
||||
ErrorInResolution.doit();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
String s = t.getMessage();
|
||||
if (oldMessage == null){
|
||||
oldMessage = s;
|
||||
}
|
||||
else {
|
||||
if(!s.equals(oldMessage)){
|
||||
RuntimeException e = new RuntimeException();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteMe {
|
||||
static int x;
|
||||
}
|
||||
|
||||
class ErrorInResolution {
|
||||
static int doit() {
|
||||
return DeleteMe.x;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user