diff options
Diffstat (limited to 'runtime/instrumentation.h')
| -rw-r--r-- | runtime/instrumentation.h | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h index 612ca14cf5..726cf1b461 100644 --- a/runtime/instrumentation.h +++ b/runtime/instrumentation.h @@ -397,6 +397,11 @@ class Instrumentation { SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Locks::thread_list_lock_); + static size_t ComputeFrameId(Thread* self, + size_t frame_depth, + size_t inlined_frames_before_frame) + SHARED_REQUIRES(Locks::mutator_lock_); + private: InstrumentationLevel GetCurrentInstrumentationLevel() const; @@ -512,20 +517,25 @@ class Instrumentation { InstrumentationLevelTable requested_instrumentation_levels_ GUARDED_BY(Locks::mutator_lock_); // The event listeners, written to with the mutator_lock_ exclusively held. + // Mutators must be able to iterate over these lists concurrently, that is, with listeners being + // added or removed while iterating. The modifying thread holds exclusive lock, + // so other threads cannot iterate (i.e. read the data of the list) at the same time but they + // do keep iterators that need to remain valid. This is the reason these listeners are std::list + // and not for example std::vector: the existing storage for a std::list does not move. + // Note that mutators cannot make a copy of these lists before iterating, as the instrumentation + // listeners can also be deleted concurrently. + // As a result, these lists are never trimmed. That's acceptable given the low number of + // listeners we have. std::list<InstrumentationListener*> method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_); std::list<InstrumentationListener*> method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_); std::list<InstrumentationListener*> method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_); std::list<InstrumentationListener*> backward_branch_listeners_ GUARDED_BY(Locks::mutator_lock_); std::list<InstrumentationListener*> invoke_virtual_or_interface_listeners_ GUARDED_BY(Locks::mutator_lock_); - std::shared_ptr<std::list<InstrumentationListener*>> dex_pc_listeners_ - GUARDED_BY(Locks::mutator_lock_); - std::shared_ptr<std::list<InstrumentationListener*>> field_read_listeners_ - GUARDED_BY(Locks::mutator_lock_); - std::shared_ptr<std::list<InstrumentationListener*>> field_write_listeners_ - GUARDED_BY(Locks::mutator_lock_); - std::shared_ptr<std::list<InstrumentationListener*>> exception_caught_listeners_ - GUARDED_BY(Locks::mutator_lock_); + std::list<InstrumentationListener*> dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_); + std::list<InstrumentationListener*> field_read_listeners_ GUARDED_BY(Locks::mutator_lock_); + std::list<InstrumentationListener*> field_write_listeners_ GUARDED_BY(Locks::mutator_lock_); + std::list<InstrumentationListener*> exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_); // The set of methods being deoptimized (by the debugger) which must be executed with interpreter // only. |