mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8153267: nmethod's exception cache not multi-thread safe
Reviewed-by: aph, jcm, kvn
This commit is contained in:
parent
cd3197f341
commit
611e659be1
3 changed files with 15 additions and 11 deletions
|
@ -313,7 +313,8 @@ bool ExceptionCache::match_exception_with_space(Handle exception) {
|
||||||
|
|
||||||
|
|
||||||
address ExceptionCache::test_address(address addr) {
|
address ExceptionCache::test_address(address addr) {
|
||||||
for (int i=0; i<count(); i++) {
|
int limit = count();
|
||||||
|
for (int i = 0; i < limit; i++) {
|
||||||
if (pc_at(i) == addr) {
|
if (pc_at(i) == addr) {
|
||||||
return handler_at(i);
|
return handler_at(i);
|
||||||
}
|
}
|
||||||
|
@ -329,7 +330,6 @@ bool ExceptionCache::add_address_and_handler(address addr, address handler) {
|
||||||
if (index < cache_size) {
|
if (index < cache_size) {
|
||||||
set_pc_at(index, addr);
|
set_pc_at(index, addr);
|
||||||
set_handler_at(index, handler);
|
set_handler_at(index, handler);
|
||||||
OrderAccess::storestore();
|
|
||||||
increment_count();
|
increment_count();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -442,10 +442,11 @@ void nmethod::add_exception_cache_entry(ExceptionCache* new_entry) {
|
||||||
assert(new_entry != NULL,"Must be non null");
|
assert(new_entry != NULL,"Must be non null");
|
||||||
assert(new_entry->next() == NULL, "Must be null");
|
assert(new_entry->next() == NULL, "Must be null");
|
||||||
|
|
||||||
if (exception_cache() != NULL) {
|
ExceptionCache *ec = exception_cache();
|
||||||
new_entry->set_next(exception_cache());
|
if (ec != NULL) {
|
||||||
|
new_entry->set_next(ec);
|
||||||
}
|
}
|
||||||
set_exception_cache(new_entry);
|
release_set_exception_cache(new_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) {
|
void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) {
|
||||||
|
|
|
@ -41,15 +41,16 @@ class ExceptionCache : public CHeapObj<mtCode> {
|
||||||
Klass* _exception_type;
|
Klass* _exception_type;
|
||||||
address _pc[cache_size];
|
address _pc[cache_size];
|
||||||
address _handler[cache_size];
|
address _handler[cache_size];
|
||||||
int _count;
|
volatile int _count;
|
||||||
ExceptionCache* _next;
|
ExceptionCache* _next;
|
||||||
|
|
||||||
address pc_at(int index) { assert(index >= 0 && index < count(),""); return _pc[index]; }
|
address pc_at(int index) { assert(index >= 0 && index < count(),""); return _pc[index]; }
|
||||||
void set_pc_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
|
void set_pc_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
|
||||||
address handler_at(int index) { assert(index >= 0 && index < count(),""); return _handler[index]; }
|
address handler_at(int index) { assert(index >= 0 && index < count(),""); return _handler[index]; }
|
||||||
void set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
|
void set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
|
||||||
int count() { return _count; }
|
int count() { return OrderAccess::load_acquire(&_count); }
|
||||||
void increment_count() { _count++; }
|
// increment_count is only called under lock, but there may be concurrent readers.
|
||||||
|
void increment_count() { OrderAccess::release_store(&_count, _count + 1); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -241,7 +242,7 @@ class nmethod : public CodeBlob {
|
||||||
// counter is decreased (by 1) while sweeping.
|
// counter is decreased (by 1) while sweeping.
|
||||||
int _hotness_counter;
|
int _hotness_counter;
|
||||||
|
|
||||||
ExceptionCache *_exception_cache;
|
ExceptionCache * volatile _exception_cache;
|
||||||
PcDescCache _pc_desc_cache;
|
PcDescCache _pc_desc_cache;
|
||||||
|
|
||||||
// These are used for compiled synchronized native methods to
|
// These are used for compiled synchronized native methods to
|
||||||
|
@ -433,7 +434,7 @@ class nmethod : public CodeBlob {
|
||||||
|
|
||||||
// flag accessing and manipulation
|
// flag accessing and manipulation
|
||||||
bool is_in_use() const { return _state == in_use; }
|
bool is_in_use() const { return _state == in_use; }
|
||||||
bool is_alive() const { return _state == in_use || _state == not_entrant; }
|
bool is_alive() const { unsigned char s = _state; return s == in_use || s == not_entrant; }
|
||||||
bool is_not_entrant() const { return _state == not_entrant; }
|
bool is_not_entrant() const { return _state == not_entrant; }
|
||||||
bool is_zombie() const { return _state == zombie; }
|
bool is_zombie() const { return _state == zombie; }
|
||||||
bool is_unloaded() const { return _state == unloaded; }
|
bool is_unloaded() const { return _state == unloaded; }
|
||||||
|
@ -576,8 +577,10 @@ public:
|
||||||
void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; }
|
void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; }
|
||||||
|
|
||||||
// Exception cache support
|
// Exception cache support
|
||||||
|
// Note: _exception_cache may be read concurrently. We rely on memory_order_consume here.
|
||||||
ExceptionCache* exception_cache() const { return _exception_cache; }
|
ExceptionCache* exception_cache() const { return _exception_cache; }
|
||||||
void set_exception_cache(ExceptionCache *ec) { _exception_cache = ec; }
|
void set_exception_cache(ExceptionCache *ec) { _exception_cache = ec; }
|
||||||
|
void release_set_exception_cache(ExceptionCache *ec) { OrderAccess::release_store_ptr(&_exception_cache, ec); }
|
||||||
address handler_for_exception_and_pc(Handle exception, address pc);
|
address handler_for_exception_and_pc(Handle exception, address pc);
|
||||||
void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
|
void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
|
||||||
void clean_exception_cache(BoolObjectClosure* is_alive);
|
void clean_exception_cache(BoolObjectClosure* is_alive);
|
||||||
|
|
|
@ -962,7 +962,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
||||||
nonstatic_field(nmethod, _stack_traversal_mark, long) \
|
nonstatic_field(nmethod, _stack_traversal_mark, long) \
|
||||||
nonstatic_field(nmethod, _compile_id, int) \
|
nonstatic_field(nmethod, _compile_id, int) \
|
||||||
nonstatic_field(nmethod, _comp_level, int) \
|
nonstatic_field(nmethod, _comp_level, int) \
|
||||||
nonstatic_field(nmethod, _exception_cache, ExceptionCache*) \
|
volatile_nonstatic_field(nmethod, _exception_cache, ExceptionCache*) \
|
||||||
\
|
\
|
||||||
unchecked_c2_static_field(Deoptimization, _trap_reason_name, void*) \
|
unchecked_c2_static_field(Deoptimization, _trap_reason_name, void*) \
|
||||||
\
|
\
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue