Author: [email protected]
Date: Mon Apr 13 16:12:04 2009
New Revision: 1694
Modified:
branches/bleeding_edge/src/frames-arm.cc
branches/bleeding_edge/src/frames-ia32.cc
branches/bleeding_edge/src/frames-inl.h
branches/bleeding_edge/src/frames.cc
branches/bleeding_edge/src/frames.h
Log:
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
Modified: branches/bleeding_edge/src/frames-arm.cc
==============================================================================
--- branches/bleeding_edge/src/frames-arm.cc (original)
+++ branches/bleeding_edge/src/frames-arm.cc Mon Apr 13 16:12:04 2009
@@ -80,7 +80,7 @@
Address JavaScriptFrame::GetCallerStackPointer() const {
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
// expression stack elements of the calling frame. The reason for
// this rather strange decision is that we cannot access the
Modified: branches/bleeding_edge/src/frames-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/frames-ia32.cc (original)
+++ branches/bleeding_edge/src/frames-ia32.cc Mon Apr 13 16:12:04 2009
@@ -78,7 +78,7 @@
Address JavaScriptFrame::GetCallerStackPointer() const {
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
// expression stack elements of the calling frame. The reason for
// this rather strange decision is that we cannot access the
Modified: branches/bleeding_edge/src/frames-inl.h
==============================================================================
--- branches/bleeding_edge/src/frames-inl.h (original)
+++ branches/bleeding_edge/src/frames-inl.h Mon Apr 13 16:12:04 2009
@@ -169,19 +169,6 @@
}
-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 {
Object* result = function_slot_object();
ASSERT(result->IsJSFunction());
Modified: branches/bleeding_edge/src/frames.cc
==============================================================================
--- branches/bleeding_edge/src/frames.cc (original)
+++ branches/bleeding_edge/src/frames.cc Mon Apr 13 16:12:04 2009
@@ -86,6 +86,7 @@
if (use_top || fp != NULL) {
Reset();
}
+ JavaScriptFrame_.DisableHeapAccess();
}
#undef INITIALIZE_SINGLETON
@@ -231,11 +232,7 @@
bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
- 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());
+ return IsValidStackAddress(frame->sp()) &&
IsValidStackAddress(frame->fp());
}
@@ -281,7 +278,7 @@
SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
Address fp, Address sp, Address low_bound, Address 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 @@
while (true) {
SafeJavaScriptFrameIterator::Advance();
if (done()) return;
- if (frame()->is_at_function()) return;
+ if (frame()->is_java_script()) return;
}
}
#endif
Modified: branches/bleeding_edge/src/frames.h
==============================================================================
--- branches/bleeding_edge/src/frames.h (original)
+++ branches/bleeding_edge/src/frames.h Mon Apr 13 16:12:04 2009
@@ -373,7 +373,6 @@
virtual Type type() const { return JAVA_SCRIPT; }
// Accessors.
- inline bool is_at_function() const;
inline Object* function() const;
inline Object* receiver() const;
inline void set_receiver(Object* value);
@@ -414,11 +413,19 @@
protected:
explicit JavaScriptFrame(StackFrameIterator* iterator)
- : StandardFrame(iterator) { }
+ : StandardFrame(iterator), disable_heap_access_(false) { }
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;
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---