Explicitly declare temporary cooked frames state
authorpeter.rybin@gmail.com <peter.rybin@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Sat, 20 Mar 2010 22:37:15 +0000 (22:37 +0000)
committerpeter.rybin@gmail.com <peter.rybin@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Sat, 20 Mar 2010 22:37:15 +0000 (22:37 +0000)
Review URL: http://codereview.chromium.org/995006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4199 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/frames.cc
src/liveedit.cc
src/top.cc
src/top.h
src/v8threads.cc
src/v8threads.h

index 227fa67..415459e 100644 (file)
@@ -329,9 +329,6 @@ bool StackFrame::HasHandler() const {
 
 
 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {
-  // Only cooking frames when the collector is compacting and thus moving code
-  // around.
-  ASSERT(MarkCompactCollector::IsCompacting());
   ASSERT(!thread->stack_is_cooked());
   for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
     it.frame()->Cook();
@@ -341,9 +338,6 @@ void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {
 
 
 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) {
-  // Only uncooking frames when the collector is compacting and thus moving code
-  // around.
-  ASSERT(MarkCompactCollector::HasCompacted());
   ASSERT(thread->stack_is_cooked());
   for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
     it.frame()->Uncook();
index 4533f9c..55308ab 100644 (file)
@@ -391,6 +391,26 @@ class ReferenceCollectorVisitor : public ObjectVisitor {
   ZoneList<RelocInfo> reloc_infos_;
 };
 
+
+class FrameCookingThreadVisitor : public ThreadVisitor {
+ public:
+  void VisitThread(ThreadLocalTop* top) {
+    StackFrame::CookFramesForThread(top);
+  }
+};
+
+class FrameUncookingThreadVisitor : public ThreadVisitor {
+ public:
+  void VisitThread(ThreadLocalTop* top) {
+    StackFrame::UncookFramesForThread(top);
+  }
+};
+
+static void IterateAllThreads(ThreadVisitor* visitor) {
+  Top::IterateThread(visitor);
+  ThreadManager::IterateThreads(visitor);
+}
+
 // Finds all references to original and replaces them with substitution.
 static void ReplaceCodeObject(Code* original, Code* substitution) {
   ASSERT(!Heap::InNewSpace(substitution));
@@ -405,9 +425,15 @@ static void ReplaceCodeObject(Code* original, Code* substitution) {
   // Iterate over all roots. Stack frames may have pointer into original code,
   // so temporary replace the pointers with offset numbers
   // in prologue/epilogue.
-  ThreadManager::MarkCompactPrologue(true);
-  Heap::IterateStrongRoots(&visitor, VISIT_ALL);
-  ThreadManager::MarkCompactEpilogue(true);
+  {
+    FrameCookingThreadVisitor cooking_visitor;
+    IterateAllThreads(&cooking_visitor);
+
+    Heap::IterateStrongRoots(&visitor, VISIT_ALL);
+
+    FrameUncookingThreadVisitor uncooking_visitor;
+    IterateAllThreads(&uncooking_visitor);
+  }
 
   // Now iterate over all pointers of all objects, including code_target
   // implicit pointers.
index 3efd1fc..0fcf458 100644 (file)
@@ -88,6 +88,17 @@ char* Top::Iterate(ObjectVisitor* v, char* thread_storage) {
 }
 
 
+void Top::IterateThread(ThreadVisitor* v) {
+  v->VisitThread(&thread_local_);
+}
+
+
+void Top::IterateThread(ThreadVisitor* v, char* t) {
+  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
+  v->VisitThread(thread);
+}
+
+
 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
   v->VisitPointer(&(thread->pending_exception_));
   v->VisitPointer(&(thread->pending_message_obj_));
index e20a2a0..d263777 100644 (file)
--- a/src/top.h
+++ b/src/top.h
@@ -40,6 +40,7 @@ namespace internal {
 // Top has static variables used for JavaScript execution.
 
 class SaveContext;  // Forward declaration.
+class ThreadVisitor;  // Defined in v8threads.h
 
 class ThreadLocalTop BASE_EMBEDDED {
  public:
@@ -319,6 +320,8 @@ class Top {
   static void Iterate(ObjectVisitor* v);
   static void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
   static char* Iterate(ObjectVisitor* v, char* t);
+  static void IterateThread(ThreadVisitor* v);
+  static void IterateThread(ThreadVisitor* v, char* t);
 
   // Returns the global object of the current context. It could be
   // a builtin object, or a js global object.
index 80a7cd9..02292f6 100644 (file)
@@ -331,6 +331,17 @@ void ThreadManager::Iterate(ObjectVisitor* v) {
 }
 
 
+void ThreadManager::IterateThreads(ThreadVisitor* v) {
+  for (ThreadState* state = ThreadState::FirstInUse();
+       state != NULL;
+       state = state->Next()) {
+    char* data = state->data();
+    data += HandleScopeImplementer::ArchiveSpacePerThread();
+    Top::IterateThread(v, data);
+  }
+}
+
+
 void ThreadManager::MarkCompactPrologue(bool is_compacting) {
   for (ThreadState* state = ThreadState::FirstInUse();
        state != NULL;
index 0684053..d70aa3c 100644 (file)
@@ -79,6 +79,20 @@ class ThreadState {
 };
 
 
+// Defined in top.h
+class ThreadLocalTop;
+
+
+class ThreadVisitor {
+ public:
+  // ThreadLocalTop may be only available during this call.
+  virtual void VisitThread(ThreadLocalTop* top) = 0;
+
+ protected:
+  virtual ~ThreadVisitor() {}
+};
+
+
 class ThreadManager : public AllStatic {
  public:
   static void Lock();
@@ -90,6 +104,7 @@ class ThreadManager : public AllStatic {
   static bool IsArchived();
 
   static void Iterate(ObjectVisitor* v);
+  static void IterateThreads(ThreadVisitor* v);
   static void MarkCompactPrologue(bool is_compacting);
   static void MarkCompactEpilogue(bool is_compacting);
   static bool IsLockedByCurrentThread() { return mutex_owner_.IsSelf(); }