Reviewers: loislo, Sven Panne,

Description:
Get rid of Isolate::safe_stack_iterator_counter

This change removes per-isolate counter of active SafeStackFrameIterators. The counter is used by stack frames implementations to avoid accessing pointers to
heap objects when traversing stack for CPU profiler (so called "safe" mode).
Each StackFrame instance is owned by single iterator and has a pointer to it so we can simply mark the iterator as "safe" or not and read the field in the stack
frames instead of going into the isolate.

BUG=None

Please review this at https://codereview.chromium.org/17585008/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/frames.h
  M src/frames.cc
  M src/isolate.h


Index: src/frames.cc
diff --git a/src/frames.cc b/src/frames.cc
index 3cf02f4007c076799324137d80406a3268ffefe3..e1c0892fdf4ae9d97e20672ac9afbdcddf2d8c1f 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -93,14 +93,16 @@ StackFrameIterator::StackFrameIterator(Isolate* isolate)
       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
       frame_(NULL), handler_(NULL),
       thread_(isolate_->thread_local_top()),
- fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { + fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler),
+      is_safe_iterator_(false) {
   Reset();
 }
 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
     : isolate_(isolate),
       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
       frame_(NULL), handler_(NULL), thread_(t),
- fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { + fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler),
+      is_safe_iterator_(false) {
   Reset();
 }
 StackFrameIterator::StackFrameIterator(Isolate* isolate,
@@ -111,7 +113,8 @@ StackFrameIterator::StackFrameIterator(Isolate* isolate,
       thread_(use_top ? isolate_->thread_local_top() : NULL),
       fp_(use_top ? NULL : fp), sp_(sp),
       advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
-               &StackFrameIterator::AdvanceWithoutHandler) {
+               &StackFrameIterator::AdvanceWithoutHandler),
+      is_safe_iterator_(true) {
   if (use_top || fp != NULL) {
     Reset();
   }
@@ -166,7 +169,7 @@ void StackFrameIterator::Reset() {
     state.sp = sp_;
     state.pc_address = ResolveReturnAddressLocation(
         reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
-    type = StackFrame::ComputeType(isolate(), &state);
+    type = StackFrame::ComputeType(this, &state);
   }
   if (SingletonFor(type) == NULL) return;
   frame_ = SingletonFor(type, &state);
@@ -268,24 +271,9 @@ bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) {
 }


-SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer(
-    Isolate* isolate)
-    : isolate_(isolate) {
-  isolate_->set_safe_stack_iterator_counter(
-      isolate_->safe_stack_iterator_counter() + 1);
-}
-
-
-SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() {
-  isolate_->set_safe_stack_iterator_counter(
-      isolate_->safe_stack_iterator_counter() - 1);
-}
-
-
 SafeStackFrameIterator::SafeStackFrameIterator(
     Isolate* isolate,
     Address fp, Address sp, Address low_bound, Address high_bound) :
-    maintainer_(isolate),
     stack_validator_(low_bound, high_bound),
     is_valid_top_(IsValidTop(isolate, low_bound, high_bound)),
     is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)),
@@ -294,10 +282,6 @@ SafeStackFrameIterator::SafeStackFrameIterator(
   if (!done()) Advance();
 }

-bool SafeStackFrameIterator::is_active(Isolate* isolate) {
-  return isolate->safe_stack_iterator_counter() > 0;
-}
-

 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate,
Address low_bound, Address high_bound) {
@@ -435,7 +419,8 @@ void StackFrame::SetReturnAddressLocationResolver(
 }


-StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
+StackFrame::Type StackFrame::ComputeType(const StackFrameIterator* iterator,
+                                         State* state) {
   ASSERT(state->fp != NULL);
   if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
     return ARGUMENTS_ADAPTOR;
@@ -450,8 +435,9 @@ StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
     // frames as normal JavaScript frames to avoid having to look
     // into the heap to determine the state. This is safe as long
     // as nobody tries to GC...
-    if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT;
- Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind();
+    if (iterator->is_safe_iterator_) return JAVA_SCRIPT;
+    Code::Kind kind = GetContainingCode(iterator->isolate(),
+                                        *(state->pc_address))->kind();
     ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
     return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
   }
@@ -459,10 +445,16 @@ StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
 }


+#ifdef DEBUG
+bool StackFrame::is_safe_iteration() const {
+  return iterator_->is_safe_iterator_;
+}
+#endif
+

 StackFrame::Type StackFrame::GetCallerState(State* state) const {
   ComputeCallerState(state);
-  return ComputeType(isolate(), state);
+  return ComputeType(iterator_, state);
 }


@@ -622,7 +614,7 @@ bool StandardFrame::IsExpressionInsideHandler(int n) const {
 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
   // Make sure that we're not doing "safe" stack frame iteration. We cannot
   // possibly find pointers in optimized frames in that state.
-  ASSERT(!SafeStackFrameIterator::is_active(isolate()));
+  ASSERT(!is_safe_iteration());

   // Compute the safepoint information.
   unsigned stack_slots = 0;
@@ -754,7 +746,7 @@ Code* JavaScriptFrame::unchecked_code() const {


 int JavaScriptFrame::GetNumberOfIncomingArguments() const {
-  ASSERT(!SafeStackFrameIterator::is_active(isolate()) &&
+  ASSERT(!is_safe_iteration() &&
          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);

   JSFunction* function = JSFunction::cast(this->function());
Index: src/frames.h
diff --git a/src/frames.h b/src/frames.h
index 1a78d09b15fc114eddde1b29b1ecf6fbe3e6c282..92ef45b31e1aa77f4f1aaed635c57d0cdf7c8e9a 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -321,7 +321,11 @@ class StackFrame BASE_EMBEDDED {
   inline StackHandler* top_handler() const;

   // Compute the stack frame type for the given state.
-  static Type ComputeType(Isolate* isolate, State* state);
+ static Type ComputeType(const StackFrameIterator* iterator, State* state);
+
+#ifdef DEBUG
+  bool is_safe_iteration() const;
+#endif

  private:
   const StackFrameIterator* iterator_;
@@ -782,11 +786,6 @@ class StackFrameIterator BASE_EMBEDDED {
   // An iterator that iterates over a given thread's stack.
   StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);

-  // 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(Isolate* isolate, bool use_top, Address fp, Address sp);
-
   StackFrame* frame() const {
     ASSERT(!done());
     return frame_;
@@ -798,6 +797,12 @@ class StackFrameIterator BASE_EMBEDDED {
   void Advance() { (this->*advance_)(); }

  private:
+  // 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. This constructor is used to create
+  // StackFrameIterator for "safe" stack iteration.
+ StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
+
   // Go back to the first frame.
   void Reset();

@@ -811,6 +816,7 @@ class StackFrameIterator BASE_EMBEDDED {
   Address fp_;
   Address sp_;
   void (StackFrameIterator::*advance_)();
+  const bool is_safe_iterator_;

   StackHandler* handler() const {
     ASSERT(!done());
@@ -879,8 +885,6 @@ class SafeStackFrameIterator BASE_EMBEDDED {
   bool done() const { return iteration_done_ || iterator_.done(); }
   void Advance();

-  static bool is_active(Isolate* isolate);
-
  private:
   void AdvanceOneFrame();

@@ -921,20 +925,6 @@ class SafeStackFrameIterator BASE_EMBEDDED {
   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
-  // 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:
-    explicit ActiveCountMaintainer(Isolate* isolate);
-    ~ActiveCountMaintainer();
-   private:
-    Isolate* isolate_;
-  };
-
-  ActiveCountMaintainer maintainer_;
   StackAddressValidator stack_validator_;
   const bool is_valid_top_;
   const bool is_valid_fp_;
Index: src/isolate.h
diff --git a/src/isolate.h b/src/isolate.h
index 0552ef7f8085b60f8b3d349580424b05255092ec..b1e2b07835e2a781988ccd3ac5d0c6a1c78712fe 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -368,8 +368,6 @@ typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache; /* AstNode state. */ \ V(int, ast_node_id, 0) \ V(unsigned, ast_node_count, 0) \ - /* SafeStackFrameIterator activations count. */ \ - V(int, safe_stack_iterator_counter, 0) \ V(bool, observer_delivery_pending, false) \ V(HStatistics*, hstatistics, NULL) \ V(HTracer*, htracer, NULL) \


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to