| Index: src/frames.h
|
| diff --git a/src/frames.h b/src/frames.h
|
| index 16bba9e478e7901c3e3de2d31a08de9895c377e9..865d18708d26bfa77649ac8b780191c3c87a6e49 100644
|
| --- a/src/frames.h
|
| +++ b/src/frames.h
|
| @@ -28,6 +28,8 @@
|
| #ifndef V8_FRAMES_H_
|
| #define V8_FRAMES_H_
|
|
|
| +#include "handles.h"
|
| +
|
| namespace v8 {
|
| namespace internal {
|
|
|
| @@ -50,9 +52,12 @@ class PcToCodeCache {
|
| struct PcToCodeCacheEntry {
|
| Address pc;
|
| Code* code;
|
| + uint8_t* safepoint_entry;
|
| };
|
|
|
| - explicit PcToCodeCache(Isolate* isolate) : isolate_(isolate) {}
|
| + explicit PcToCodeCache(Isolate* isolate) : isolate_(isolate) {
|
| + Flush();
|
| + }
|
|
|
| Code* GcSafeFindCodeForPc(Address pc);
|
| Code* GcSafeCastToCode(HeapObject* object, Address pc);
|
| @@ -118,6 +123,7 @@ class StackHandler BASE_EMBEDDED {
|
| V(ENTRY_CONSTRUCT, EntryConstructFrame) \
|
| V(EXIT, ExitFrame) \
|
| V(JAVA_SCRIPT, JavaScriptFrame) \
|
| + V(OPTIMIZED, OptimizedFrame) \
|
| V(INTERNAL, InternalFrame) \
|
| V(CONSTRUCT, ConstructFrame) \
|
| V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
|
| @@ -161,12 +167,17 @@ class StackFrame BASE_EMBEDDED {
|
| bool is_entry() const { return type() == ENTRY; }
|
| bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
|
| bool is_exit() const { return type() == EXIT; }
|
| - bool is_java_script() const { return type() == JAVA_SCRIPT; }
|
| + bool is_optimized() const { return type() == OPTIMIZED; }
|
| bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
|
| bool is_internal() const { return type() == INTERNAL; }
|
| bool is_construct() const { return type() == CONSTRUCT; }
|
| virtual bool is_standard() const { return false; }
|
|
|
| + bool is_java_script() const {
|
| + Type type = this->type();
|
| + return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
|
| + }
|
| +
|
| // Accessors.
|
| Address sp() const { return state_.sp; }
|
| Address fp() const { return state_.fp; }
|
| @@ -200,6 +211,13 @@ class StackFrame BASE_EMBEDDED {
|
| // Get the code object that contains the given pc.
|
| static inline Code* GetContainingCode(Isolate* isolate, Address pc);
|
|
|
| + // Get the code object containing the given pc and fill in the
|
| + // safepoint entry and the number of stack slots. The pc must be at
|
| + // a safepoint.
|
| + static Code* GetSafepointData(Address pc,
|
| + uint8_t** safepoint_entry,
|
| + unsigned* stack_slots);
|
| +
|
| virtual void Iterate(ObjectVisitor* v) const = 0;
|
| static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
|
|
|
| @@ -396,6 +414,36 @@ class StandardFrame: public StackFrame {
|
| };
|
|
|
|
|
| +class FrameSummary BASE_EMBEDDED {
|
| + public:
|
| + FrameSummary(Object* receiver,
|
| + JSFunction* function,
|
| + Code* code,
|
| + int offset,
|
| + bool is_constructor)
|
| + : receiver_(receiver),
|
| + function_(function),
|
| + code_(code),
|
| + offset_(offset),
|
| + is_constructor_(is_constructor) { }
|
| + Handle<Object> receiver() { return receiver_; }
|
| + Handle<JSFunction> function() { return function_; }
|
| + Handle<Code> code() { return code_; }
|
| + Address pc() { return reinterpret_cast<Address>(*code_) + offset_; }
|
| + int offset() { return offset_; }
|
| + bool is_constructor() { return is_constructor_; }
|
| +
|
| + void Print();
|
| +
|
| + private:
|
| + Handle<Object> receiver_;
|
| + Handle<JSFunction> function_;
|
| + Handle<Code> code_;
|
| + int offset_;
|
| + bool is_constructor_;
|
| +};
|
| +
|
| +
|
| class JavaScriptFrame: public StandardFrame {
|
| public:
|
| virtual Type type() const { return JAVA_SCRIPT; }
|
| @@ -434,6 +482,12 @@ class JavaScriptFrame: public StandardFrame {
|
| // Determine the code for the frame.
|
| virtual Code* unchecked_code() const;
|
|
|
| + // Return a list with JSFunctions of this frame.
|
| + virtual void GetFunctions(List<JSFunction*>* functions);
|
| +
|
| + // Build a list with summaries for this frame including all inlined frames.
|
| + virtual void Summarize(List<FrameSummary>* frames);
|
| +
|
| static JavaScriptFrame* cast(StackFrame* frame) {
|
| ASSERT(frame->is_java_script());
|
| return static_cast<JavaScriptFrame*>(frame);
|
| @@ -445,6 +499,10 @@ class JavaScriptFrame: public StandardFrame {
|
|
|
| virtual Address GetCallerStackPointer() const;
|
|
|
| + // Garbage collection support. Iterates over incoming arguments,
|
| + // receiver, and any callee-saved registers.
|
| + void IterateArguments(ObjectVisitor* v) const;
|
| +
|
| private:
|
| inline Object* function_slot_object() const;
|
|
|
| @@ -453,6 +511,31 @@ class JavaScriptFrame: public StandardFrame {
|
| };
|
|
|
|
|
| +class OptimizedFrame : public JavaScriptFrame {
|
| + public:
|
| + virtual Type type() const { return OPTIMIZED; }
|
| +
|
| + // GC support.
|
| + virtual void Iterate(ObjectVisitor* v) const;
|
| +
|
| + // Return a list with JSFunctions of this frame.
|
| + // The functions are ordered bottom-to-top (i.e. functions.last()
|
| + // is the top-most activation)
|
| + virtual void GetFunctions(List<JSFunction*>* functions);
|
| +
|
| + virtual void Summarize(List<FrameSummary>* frames);
|
| +
|
| + DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
|
| +
|
| + protected:
|
| + explicit OptimizedFrame(StackFrameIterator* iterator)
|
| + : JavaScriptFrame(iterator) { }
|
| +
|
| + private:
|
| + friend class StackFrameIterator;
|
| +};
|
| +
|
| +
|
| // Arguments adaptor frames are automatically inserted below
|
| // JavaScript frames when the actual number of parameters does not
|
| // match the formal number of parameters.
|
| @@ -540,7 +623,7 @@ class StackFrameIterator BASE_EMBEDDED {
|
| // An iterator that can start from a given FP address.
|
| // If use_top, then work as usual, if fp isn't NULL, use it,
|
| // otherwise, do nothing.
|
| - StackFrameIterator(bool use_top, Address fp, Address sp);
|
| + StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
|
|
|
| StackFrame* frame() const {
|
| ASSERT(!done());
|
| @@ -603,6 +686,13 @@ class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
|
| if (!done()) Advance();
|
| }
|
|
|
| + JavaScriptFrameIteratorTemp(Isolate* isolate,
|
| + Address fp, Address sp,
|
| + Address low_bound, Address high_bound) :
|
| + iterator_(isolate, fp, sp, low_bound, high_bound) {
|
| + if (!done()) Advance();
|
| + }
|
| +
|
| inline JavaScriptFrame* frame() const;
|
|
|
| bool done() const { return iterator_.done(); }
|
| @@ -640,7 +730,8 @@ class StackTraceFrameIterator: public JavaScriptFrameIterator {
|
|
|
| class SafeStackFrameIterator BASE_EMBEDDED {
|
| public:
|
| - SafeStackFrameIterator(Address fp, Address sp,
|
| + SafeStackFrameIterator(Isolate* isolate,
|
| + Address fp, Address sp,
|
| Address low_bound, Address high_bound);
|
|
|
| StackFrame* frame() const {
|
| @@ -690,7 +781,8 @@ class SafeStackFrameIterator BASE_EMBEDDED {
|
| bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
|
| bool IsValidFrame(StackFrame* frame) const;
|
| bool IsValidCaller(StackFrame* frame);
|
| - static bool IsValidTop(Address low_bound, Address high_bound);
|
| + static bool IsValidTop(Isolate* isolate,
|
| + Address low_bound, Address high_bound);
|
|
|
| // This is a nasty hack to make sure the active count is incremented
|
| // before the constructor for the embedded iterator is invoked. This
|
| @@ -704,6 +796,7 @@ class SafeStackFrameIterator BASE_EMBEDDED {
|
| };
|
|
|
| ActiveCountMaintainer maintainer_;
|
| + // TODO(isolates): this is dangerous.
|
| static int active_count_;
|
| StackAddressValidator stack_validator_;
|
| const bool is_valid_top_;
|
| @@ -721,7 +814,8 @@ typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
|
|
|
| class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
|
| public:
|
| - explicit SafeStackTraceFrameIterator(Address fp, Address sp,
|
| + explicit SafeStackTraceFrameIterator(Isolate* isolate,
|
| + Address fp, Address sp,
|
| Address low_bound, Address high_bound);
|
| void Advance();
|
| };
|
|
|