Skip to content

Commit 301cf52

Browse files
committed
8297284: ResolutionErrorTable's key is wrong
Reviewed-by: matsaave, iklam
1 parent a97e7d9 commit 301cf52

File tree

2 files changed

+62
-74
lines changed

2 files changed

+62
-74
lines changed

src/hotspot/share/classfile/resolutionErrors.cpp

+50-50
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,30 @@
3333
#include "runtime/mutexLocker.hpp"
3434
#include "utilities/resourceHash.hpp"
3535

36-
ResourceHashtable<uintptr_t, ResolutionErrorEntry*, 107, AnyObj::C_HEAP, mtClass> _resolution_error_table;
36+
class ResolutionErrorKey {
37+
ConstantPool* _cpool;
38+
int _index;
39+
40+
public:
41+
ResolutionErrorKey(ConstantPool* cpool, int index) : _cpool(cpool), _index(index) {
42+
assert(_index > 0, "should be already encoded or otherwise greater than zero");
43+
}
44+
45+
ConstantPool* cpool() const { return _cpool; }
46+
47+
static unsigned hash(const ResolutionErrorKey& key) {
48+
Symbol* name = key._cpool->pool_holder()->name();
49+
return (unsigned int)(name->identity_hash() ^ key._index);
50+
}
51+
52+
static bool equals(const ResolutionErrorKey& l, const ResolutionErrorKey& r) {
53+
return (l._cpool == r._cpool) && (l._index == r._index);
54+
}
55+
};
56+
57+
ResourceHashtable<ResolutionErrorKey, ResolutionErrorEntry*, 107, AnyObj::C_HEAP, mtClass,
58+
ResolutionErrorKey::hash,
59+
ResolutionErrorKey::equals> _resolution_error_table;
3760

3861
// create new error entry
3962
void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_index,
@@ -43,8 +66,9 @@ void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_inde
4366
assert_locked_or_safepoint(SystemDictionary_lock);
4467
assert(!pool.is_null() && error != NULL, "adding NULL obj");
4568

46-
ResolutionErrorEntry* entry = new ResolutionErrorEntry(pool(), cp_index, error, message, cause, cause_msg);
47-
_resolution_error_table.put(convert_key(pool, cp_index), entry);
69+
ResolutionErrorKey key(pool(), cp_index);
70+
ResolutionErrorEntry *entry = new ResolutionErrorEntry(error, message, cause, cause_msg);
71+
_resolution_error_table.put(key, entry);
4872
}
4973

5074
// create new nest host error entry
@@ -54,78 +78,54 @@ void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_inde
5478
assert_locked_or_safepoint(SystemDictionary_lock);
5579
assert(!pool.is_null() && message != NULL, "adding NULL obj");
5680

57-
ResolutionErrorEntry* entry = new ResolutionErrorEntry(pool(), cp_index, message);
58-
_resolution_error_table.put(convert_key(pool, cp_index), entry);
81+
ResolutionErrorKey key(pool(), cp_index);
82+
ResolutionErrorEntry *entry = new ResolutionErrorEntry(message);
83+
_resolution_error_table.put(key, entry);
5984
}
6085

6186
// find entry in the table
6287
ResolutionErrorEntry* ResolutionErrorTable::find_entry(const constantPoolHandle& pool, int cp_index) {
6388
assert_locked_or_safepoint(SystemDictionary_lock);
64-
ResolutionErrorEntry** entry = _resolution_error_table.get(convert_key(pool, cp_index));
65-
if (entry != nullptr) {
66-
return *entry;
67-
} else {
68-
return nullptr;
69-
}
70-
89+
ResolutionErrorKey key(pool(), cp_index);
90+
ResolutionErrorEntry** entry = _resolution_error_table.get(key);
91+
return entry == nullptr ? nullptr : *entry;
7192
}
7293

73-
ResolutionErrorEntry::ResolutionErrorEntry(ConstantPool* pool, int cp_index, Symbol* error, Symbol* message,
94+
ResolutionErrorEntry::ResolutionErrorEntry(Symbol* error, Symbol* message,
7495
Symbol* cause, Symbol* cause_msg):
75-
_cp_index(cp_index),
7696
_error(error),
7797
_message(message),
7898
_cause(cause),
7999
_cause_msg(cause_msg),
80-
_pool(pool),
81100
_nest_host_error(nullptr) {
82101

83-
if (_error != nullptr) {
84-
_error->increment_refcount();
85-
}
86-
87-
if (_message != nullptr) {
88-
_message->increment_refcount();
89-
}
90-
91-
if (_cause != nullptr) {
92-
_cause->increment_refcount();
93-
}
94-
95-
if (_cause_msg != nullptr) {
96-
_cause_msg->increment_refcount();
97-
}
102+
Symbol::maybe_increment_refcount(_error);
103+
Symbol::maybe_increment_refcount(_message);
104+
Symbol::maybe_increment_refcount(_cause);
105+
Symbol::maybe_increment_refcount(_cause_msg);
98106
}
99107

100108
ResolutionErrorEntry::~ResolutionErrorEntry() {
101109
// decrement error refcount
102-
if (error() != NULL) {
103-
error()->decrement_refcount();
104-
}
105-
if (message() != NULL) {
106-
message()->decrement_refcount();
107-
}
108-
if (cause() != NULL) {
109-
cause()->decrement_refcount();
110-
}
111-
if (cause_msg() != NULL) {
112-
cause_msg()->decrement_refcount();
113-
}
110+
Symbol::maybe_decrement_refcount(_error);
111+
Symbol::maybe_decrement_refcount(_message);
112+
Symbol::maybe_decrement_refcount(_cause);
113+
Symbol::maybe_decrement_refcount(_cause_msg);
114+
114115
if (nest_host_error() != NULL) {
115116
FREE_C_HEAP_ARRAY(char, nest_host_error());
116117
}
117118
}
118119

119-
class ResolutionErrorDeleteIterate : StackObj{
120-
private:
120+
class ResolutionErrorDeleteIterate : StackObj {
121121
ConstantPool* p;
122122

123123
public:
124124
ResolutionErrorDeleteIterate(ConstantPool* pool):
125125
p(pool) {};
126126

127-
bool do_entry(uintptr_t key, ResolutionErrorEntry* value){
128-
if (value -> pool() == p) {
127+
bool do_entry(const ResolutionErrorKey& key, ResolutionErrorEntry* value){
128+
if (key.cpool() == p) {
129129
delete value;
130130
return true;
131131
} else {
@@ -142,10 +142,10 @@ void ResolutionErrorTable::delete_entry(ConstantPool* c) {
142142
_resolution_error_table.unlink(&deleteIterator);
143143
}
144144

145-
class ResolutionIteratePurgeErrors : StackObj{
145+
class ResolutionIteratePurgeErrors : StackObj {
146146
public:
147-
bool do_entry(uintptr_t key, ResolutionErrorEntry* value) {
148-
ConstantPool* pool = value -> pool();
147+
bool do_entry(const ResolutionErrorKey& key, ResolutionErrorEntry* value){
148+
ConstantPool* pool = key.cpool();
149149
if (!(pool->pool_holder()->is_loader_alive())) {
150150
delete value;
151151
return true;

src/hotspot/share/classfile/resolutionErrors.hpp

+12-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -32,18 +32,11 @@ class ResolutionErrorEntry;
3232
// ResolutionError objects are used to record errors encountered during
3333
// constant pool resolution (JVMS 5.4.3).
3434

35-
// This value is added to the cpCache index of an invokedynamic instruction when
36-
// storing the resolution error resulting from that invokedynamic instruction.
37-
// This prevents issues where the cpCache index is the same as the constant pool
38-
// index of another entry in the table.
39-
const int CPCACHE_INDEX_MANGLE_VALUE = 1000000;
40-
4135
class ResolutionErrorTable : AllStatic {
4236

4337
public:
44-
4538
static void add_entry(const constantPoolHandle& pool, int which, Symbol* error, Symbol* message,
46-
Symbol* cause, Symbol* cause_msg);
39+
Symbol* cause, Symbol* cause_msg);
4740

4841
static void add_entry(const constantPoolHandle& pool, int which, const char* message);
4942

@@ -56,42 +49,40 @@ class ResolutionErrorTable : AllStatic {
5649
// RedefineClasses support - remove obsolete constant pool entry
5750
static void delete_entry(ConstantPool* c);
5851

52+
// This value is added to the cpCache index of an invokedynamic instruction when
53+
// storing the resolution error resulting from that invokedynamic instruction.
54+
// This prevents issues where the cpCache index is the same as the constant pool
55+
// index of another entry in the table.
56+
static const int CPCACHE_INDEX_MANGLE_VALUE = 1000000;
57+
5958
// This function is used to encode an index to differentiate it from a
6059
// constant pool index. It assumes it is being called with a cpCache index
6160
// (that is less than 0).
6261
static int encode_cpcache_index(int index) {
6362
assert(index < 0, "Unexpected non-negative cpCache index");
6463
return index + CPCACHE_INDEX_MANGLE_VALUE;
6564
}
66-
67-
static uintptr_t convert_key(const constantPoolHandle& pool, int cp_index) {
68-
return (uintptr_t) (pool() + cp_index);
69-
}
7065
};
7166

7267

7368
class ResolutionErrorEntry : public CHeapObj<mtClass> {
7469
private:
75-
int _cp_index;
7670
Symbol* _error;
7771
Symbol* _message;
7872
Symbol* _cause;
7973
Symbol* _cause_msg;
80-
ConstantPool* _pool;
8174
const char* _nest_host_error;
8275

83-
public:
76+
NONCOPYABLE(ResolutionErrorEntry);
8477

85-
ResolutionErrorEntry(ConstantPool* pool, int cp_index, Symbol* error, Symbol* message,
86-
Symbol* cause, Symbol* cause_msg);
78+
public:
79+
ResolutionErrorEntry(Symbol* error, Symbol* message, Symbol* cause, Symbol* cause_msg);
8780

88-
ResolutionErrorEntry(ConstantPool* pool, int cp_index, const char* message):
89-
_cp_index(cp_index),
81+
ResolutionErrorEntry(const char* message):
9082
_error(nullptr),
9183
_message(nullptr),
9284
_cause(nullptr),
9385
_cause_msg(nullptr),
94-
_pool(pool),
9586
_nest_host_error(message) {}
9687

9788
~ResolutionErrorEntry();
@@ -101,14 +92,11 @@ class ResolutionErrorEntry : public CHeapObj<mtClass> {
10192
}
10293

10394

104-
ConstantPool* pool() const { return _pool; }
105-
int cp_index() const { return _cp_index; }
10695
Symbol* error() const { return _error; }
10796
Symbol* message() const { return _message; }
10897
Symbol* cause() const { return _cause; }
10998
Symbol* cause_msg() const { return _cause_msg; }
11099
const char* nest_host_error() const { return _nest_host_error; }
111-
112100
};
113101

114102
#endif // SHARE_CLASSFILE_RESOLUTIONERRORS_HPP

0 commit comments

Comments
 (0)