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
-~----------~----~----~----~------~----~------~--~---

Reply via email to