Implemented "no heap access" mode for JSFrame which is used for stack sampling in profiler.

As I discovered that JSFrame accesses SharedFunctionInfo only to calculate caller SP and the latter is not used in profiler's stack sampling, I disabled accessing heap objects in JSFrame when doing stack sampling. This finally made V8's profiling stable when used from Chrome on a real web app.

Review URL: http://codereview.chromium.org/73020

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1694 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ce6d2916
...@@ -80,7 +80,7 @@ int JavaScriptFrame::GetProvidedParametersCount() const { ...@@ -80,7 +80,7 @@ int JavaScriptFrame::GetProvidedParametersCount() const {
Address JavaScriptFrame::GetCallerStackPointer() const { Address JavaScriptFrame::GetCallerStackPointer() const {
int arguments; int arguments;
if (Heap::gc_state() != Heap::NOT_IN_GC) { if (Heap::gc_state() != Heap::NOT_IN_GC || disable_heap_access_) {
// The arguments for cooked frames are traversed as if they were // The arguments for cooked frames are traversed as if they were
// expression stack elements of the calling frame. The reason for // expression stack elements of the calling frame. The reason for
// this rather strange decision is that we cannot access the // this rather strange decision is that we cannot access the
......
...@@ -78,7 +78,7 @@ int JavaScriptFrame::GetProvidedParametersCount() const { ...@@ -78,7 +78,7 @@ int JavaScriptFrame::GetProvidedParametersCount() const {
Address JavaScriptFrame::GetCallerStackPointer() const { Address JavaScriptFrame::GetCallerStackPointer() const {
int arguments; int arguments;
if (Heap::gc_state() != Heap::NOT_IN_GC) { if (Heap::gc_state() != Heap::NOT_IN_GC || disable_heap_access_) {
// The arguments for cooked frames are traversed as if they were // The arguments for cooked frames are traversed as if they were
// expression stack elements of the calling frame. The reason for // expression stack elements of the calling frame. The reason for
// this rather strange decision is that we cannot access the // this rather strange decision is that we cannot access the
......
...@@ -169,19 +169,6 @@ inline bool JavaScriptFrame::has_adapted_arguments() const { ...@@ -169,19 +169,6 @@ inline bool JavaScriptFrame::has_adapted_arguments() const {
} }
inline bool JavaScriptFrame::is_at_function() const {
Object* result = function_slot_object();
// Verify that frame points at correct JS function object.
// We are verifying that function object address and
// the underlying map object address are valid, and that
// function is really a function.
return Heap::Contains(reinterpret_cast<Address>(result)) &&
result->IsHeapObject() &&
Heap::Contains(HeapObject::cast(result)->map()) &&
result->IsJSFunction();
}
inline Object* JavaScriptFrame::function() const { inline Object* JavaScriptFrame::function() const {
Object* result = function_slot_object(); Object* result = function_slot_object();
ASSERT(result->IsJSFunction()); ASSERT(result->IsJSFunction());
......
...@@ -86,6 +86,7 @@ StackFrameIterator::StackFrameIterator(bool use_top, Address fp, Address sp) ...@@ -86,6 +86,7 @@ StackFrameIterator::StackFrameIterator(bool use_top, Address fp, Address sp)
if (use_top || fp != NULL) { if (use_top || fp != NULL) {
Reset(); Reset();
} }
JavaScriptFrame_.DisableHeapAccess();
} }
#undef INITIALIZE_SINGLETON #undef INITIALIZE_SINGLETON
...@@ -231,11 +232,7 @@ bool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame, ...@@ -231,11 +232,7 @@ bool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame,
bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const { bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp()) && return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
// JavaScriptFrame uses function shared info to advance, hence it must
// point to a valid function object.
(!frame->is_java_script() ||
reinterpret_cast<JavaScriptFrame*>(frame)->is_at_function());
} }
...@@ -281,7 +278,7 @@ void SafeStackFrameIterator::Reset() { ...@@ -281,7 +278,7 @@ void SafeStackFrameIterator::Reset() {
SafeStackTraceFrameIterator::SafeStackTraceFrameIterator( SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
Address fp, Address sp, Address low_bound, Address high_bound) : Address fp, Address sp, Address low_bound, Address high_bound) :
SafeJavaScriptFrameIterator(fp, sp, low_bound, high_bound) { SafeJavaScriptFrameIterator(fp, sp, low_bound, high_bound) {
if (!done() && !frame()->is_at_function()) Advance(); if (!done() && !frame()->is_java_script()) Advance();
} }
...@@ -289,7 +286,7 @@ void SafeStackTraceFrameIterator::Advance() { ...@@ -289,7 +286,7 @@ void SafeStackTraceFrameIterator::Advance() {
while (true) { while (true) {
SafeJavaScriptFrameIterator::Advance(); SafeJavaScriptFrameIterator::Advance();
if (done()) return; if (done()) return;
if (frame()->is_at_function()) return; if (frame()->is_java_script()) return;
} }
} }
#endif #endif
......
...@@ -373,7 +373,6 @@ class JavaScriptFrame: public StandardFrame { ...@@ -373,7 +373,6 @@ class JavaScriptFrame: public StandardFrame {
virtual Type type() const { return JAVA_SCRIPT; } virtual Type type() const { return JAVA_SCRIPT; }
// Accessors. // Accessors.
inline bool is_at_function() const;
inline Object* function() const; inline Object* function() const;
inline Object* receiver() const; inline Object* receiver() const;
inline void set_receiver(Object* value); inline void set_receiver(Object* value);
...@@ -414,11 +413,19 @@ class JavaScriptFrame: public StandardFrame { ...@@ -414,11 +413,19 @@ class JavaScriptFrame: public StandardFrame {
protected: protected:
explicit JavaScriptFrame(StackFrameIterator* iterator) explicit JavaScriptFrame(StackFrameIterator* iterator)
: StandardFrame(iterator) { } : StandardFrame(iterator), disable_heap_access_(false) { }
virtual Address GetCallerStackPointer() const; 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: private:
bool disable_heap_access_;
inline Object* function_slot_object() const; inline Object* function_slot_object() const;
friend class StackFrameIterator; friend class StackFrameIterator;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment