< prev index next >

src/share/vm/code/nmethod.hpp

Print this page
rev 10577 : 8153267: nmethod's exception cache not multi-thread safe
Reviewed-by: aph, jcm

*** 39,57 **** private: enum { cache_size = 16 }; Klass* _exception_type; address _pc[cache_size]; address _handler[cache_size]; ! int _count; ExceptionCache* _next; 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; } 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; } ! int count() { return _count; } ! void increment_count() { _count++; } public: ExceptionCache(Handle exception, address pc, address handler); --- 39,58 ---- private: enum { cache_size = 16 }; Klass* _exception_type; address _pc[cache_size]; address _handler[cache_size]; ! volatile int _count; ExceptionCache* _next; 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; } 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; } ! int count() { return OrderAccess::load_acquire(&_count); } ! // increment_count is only called under lock, but there may be concurrent readers. ! void increment_count() { OrderAccess::release_store(&_count, _count + 1); } public: ExceptionCache(Handle exception, address pc, address handler);
*** 239,249 **** // set to [(ReservedCodeCacheSize / (1024 * 1024)) * 2] each time the method // is active while stack scanning (mark_active_nmethods()). The hotness // counter is decreased (by 1) while sweeping. int _hotness_counter; ! ExceptionCache *_exception_cache; PcDescCache _pc_desc_cache; // These are used for compiled synchronized native methods to // locate the owner and stack slot for the BasicLock so that we can // properly revoke the bias of the owner if necessary. They are --- 240,250 ---- // set to [(ReservedCodeCacheSize / (1024 * 1024)) * 2] each time the method // is active while stack scanning (mark_active_nmethods()). The hotness // counter is decreased (by 1) while sweeping. int _hotness_counter; ! ExceptionCache * volatile _exception_cache; PcDescCache _pc_desc_cache; // These are used for compiled synchronized native methods to // locate the owner and stack slot for the BasicLock so that we can // properly revoke the bias of the owner if necessary. They are
*** 431,441 **** unloaded = 3 }; // there should be no activations, should not be called, // will be transformed to zombie immediately // flag accessing and manipulation bool is_in_use() const { return _state == in_use; } ! bool is_alive() const { return _state == in_use || _state == not_entrant; } bool is_not_entrant() const { return _state == not_entrant; } bool is_zombie() const { return _state == zombie; } bool is_unloaded() const { return _state == unloaded; } // returns a string version of the nmethod state --- 432,442 ---- unloaded = 3 }; // there should be no activations, should not be called, // will be transformed to zombie immediately // flag accessing and manipulation bool is_in_use() const { return _state == in_use; } ! 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_zombie() const { return _state == zombie; } bool is_unloaded() const { return _state == unloaded; } // returns a string version of the nmethod state
*** 574,585 **** --- 575,588 ---- // Sweeper support long stack_traversal_mark() { return _stack_traversal_mark; } void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; } // Exception cache support + // Note: _exception_cache may be read concurrently. We rely on memory_order_consume here. ExceptionCache* exception_cache() const { return _exception_cache; } 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); void add_handler_for_exception_and_pc(Handle exception, address pc, address handler); void clean_exception_cache(BoolObjectClosure* is_alive); // implicit exceptions support
< prev index next >