diff options
Diffstat (limited to 'deps/v8/src/frames.h')
-rw-r--r-- | deps/v8/src/frames.h | 102 |
1 files changed, 69 insertions, 33 deletions
diff --git a/deps/v8/src/frames.h b/deps/v8/src/frames.h index 102244c9b..20111904f 100644 --- a/deps/v8/src/frames.h +++ b/deps/v8/src/frames.h @@ -46,6 +46,32 @@ class Top; class ThreadLocalTop; +class PcToCodeCache : AllStatic { + public: + struct PcToCodeCacheEntry { + Address pc; + Code* code; + }; + + static PcToCodeCacheEntry* cache(int index) { + return &cache_[index]; + } + + static Code* GcSafeFindCodeForPc(Address pc); + static Code* GcSafeCastToCode(HeapObject* object, Address pc); + + static void FlushPcToCodeCache() { + memset(&cache_[0], 0, sizeof(cache_)); + } + + static PcToCodeCacheEntry* GetCacheEntry(Address pc); + + private: + static const int kPcToCodeCacheSize = 256; + static PcToCodeCacheEntry cache_[kPcToCodeCacheSize]; +}; + + class StackHandler BASE_EMBEDDED { public: enum State { @@ -64,7 +90,7 @@ class StackHandler BASE_EMBEDDED { inline bool includes(Address address) const; // Garbage collection support. - inline void Iterate(ObjectVisitor* v) const; + inline void Iterate(ObjectVisitor* v, Code* holder) const; // Conversion support. static inline StackHandler* FromAddress(Address address); @@ -74,16 +100,11 @@ class StackHandler BASE_EMBEDDED { bool is_try_catch() { return state() == TRY_CATCH; } bool is_try_finally() { return state() == TRY_FINALLY; } - // Garbage collection support. - void Cook(Code* code); - void Uncook(Code* code); - private: // Accessors. inline State state() const; - inline Address pc() const; - inline void set_pc(Address value); + inline Address* pc_address() const; DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler); }; @@ -112,7 +133,13 @@ class StackFrame BASE_EMBEDDED { // Opaque data type for identifying stack frames. Used extensively // by the debugger. - enum Id { NO_ID = 0 }; + // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type + // has correct value range (see Issue 830 for more details). + enum Id { + ID_MIN_VALUE = kMinInt, + ID_MAX_VALUE = kMaxInt, + NO_ID = 0 + }; // Copy constructor; it breaks the connection to host iterator. StackFrame(const StackFrame& original) { @@ -152,13 +179,20 @@ class StackFrame BASE_EMBEDDED { virtual Type type() const = 0; // Get the code associated with this frame. - virtual Code* code() const = 0; + // This method could be called during marking phase of GC. + virtual Code* unchecked_code() const = 0; - // Garbage collection support. - static void CookFramesForThread(ThreadLocalTop* thread); - static void UncookFramesForThread(ThreadLocalTop* thread); + // Get the code associated with this frame. + Code* code() const { return GetContainingCode(pc()); } + + // Get the code object that contains the given pc. + Code* GetContainingCode(Address pc) const { + return PcToCodeCache::GetCacheEntry(pc)->code; + } + + virtual void Iterate(ObjectVisitor* v) const = 0; + static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); - virtual void Iterate(ObjectVisitor* v) const { } // Printing support. enum PrintMode { OVERVIEW, DETAILS }; @@ -200,10 +234,6 @@ class StackFrame BASE_EMBEDDED { // Get the type and the state of the calling frame. virtual Type GetCallerState(State* state) const; - // Cooking/uncooking support. - void Cook(); - void Uncook(); - friend class StackFrameIterator; friend class StackHandlerIterator; friend class SafeStackFrameIterator; @@ -218,7 +248,7 @@ class EntryFrame: public StackFrame { public: virtual Type type() const { return ENTRY; } - virtual Code* code() const; + virtual Code* unchecked_code() const; // Garbage collection support. virtual void Iterate(ObjectVisitor* v) const; @@ -249,7 +279,7 @@ class EntryConstructFrame: public EntryFrame { public: virtual Type type() const { return ENTRY_CONSTRUCT; } - virtual Code* code() const; + virtual Code* unchecked_code() const; static EntryConstructFrame* cast(StackFrame* frame) { ASSERT(frame->is_entry_construct()); @@ -268,10 +298,9 @@ class EntryConstructFrame: public EntryFrame { // Exit frames are used to exit JavaScript execution and go to C. class ExitFrame: public StackFrame { public: - enum Mode { MODE_NORMAL, MODE_DEBUG }; virtual Type type() const { return EXIT; } - virtual Code* code() const; + virtual Code* unchecked_code() const; Object*& code_slot() const; @@ -397,7 +426,7 @@ class JavaScriptFrame: public StandardFrame { int index) const; // Determine the code for the frame. - virtual Code* code() const; + virtual Code* unchecked_code() const; static JavaScriptFrame* cast(StackFrame* frame) { ASSERT(frame->is_java_script()); @@ -406,19 +435,11 @@ class JavaScriptFrame: public StandardFrame { protected: explicit JavaScriptFrame(StackFrameIterator* iterator) - : StandardFrame(iterator), disable_heap_access_(false) { } + : StandardFrame(iterator) { } virtual Address GetCallerStackPointer() const; - // When this mode is enabled it is not allowed to access heap objects. - // This is a special mode used when gathering stack samples in profiler. - // A shortcoming is that caller's SP value will be calculated incorrectly - // (see GetCallerStackPointer implementation), but it is not used for stack - // sampling. - void DisableHeapAccess() { disable_heap_access_ = true; } - private: - bool disable_heap_access_; inline Object* function_slot_object() const; friend class StackFrameIterator; @@ -433,7 +454,7 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame { virtual Type type() const { return ARGUMENTS_ADAPTOR; } // Determine the code for the frame. - virtual Code* code() const; + virtual Code* unchecked_code() const; static ArgumentsAdaptorFrame* cast(StackFrame* frame) { ASSERT(frame->is_arguments_adaptor()); @@ -463,7 +484,7 @@ class InternalFrame: public StandardFrame { virtual void Iterate(ObjectVisitor* v) const; // Determine the code for the frame. - virtual Code* code() const; + virtual Code* unchecked_code() const; static InternalFrame* cast(StackFrame* frame) { ASSERT(frame->is_internal()); @@ -625,6 +646,8 @@ class SafeStackFrameIterator BASE_EMBEDDED { void Advance(); void Reset(); + static bool is_active() { return active_count_ > 0; } + static bool IsWithinBounds( Address low_bound, Address high_bound, Address addr) { return low_bound <= addr && addr <= high_bound; @@ -638,6 +661,19 @@ class SafeStackFrameIterator BASE_EMBEDDED { bool IsValidFrame(StackFrame* frame) const; bool IsValidCaller(StackFrame* frame); + // This is a nasty hack to make sure the active count is incremented + // before the constructor for the embedded iterator is invoked. This + // is needed because the constructor will start looking at frames + // right away and we need to make sure it doesn't start inspecting + // heap objects. + class ActiveCountMaintainer BASE_EMBEDDED { + public: + ActiveCountMaintainer() { active_count_++; } + ~ActiveCountMaintainer() { active_count_--; } + }; + + ActiveCountMaintainer maintainer_; + static int active_count_; Address low_bound_; Address high_bound_; const bool is_valid_top_; |