From 386b67862ffd5350b0e7af5be1415b4d3f578915 Mon Sep 17 00:00:00 2001 From: "peter.rybin@gmail.com" Date: Sat, 20 Mar 2010 22:37:15 +0000 Subject: [PATCH] Explicitly declare temporary cooked frames state 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 | 6 ------ src/liveedit.cc | 32 +++++++++++++++++++++++++++++--- src/top.cc | 11 +++++++++++ src/top.h | 3 +++ src/v8threads.cc | 11 +++++++++++ src/v8threads.h | 15 +++++++++++++++ 6 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/frames.cc b/src/frames.cc index 227fa67..415459e 100644 --- a/src/frames.cc +++ b/src/frames.cc @@ -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(); diff --git a/src/liveedit.cc b/src/liveedit.cc index 4533f9c..55308ab 100644 --- a/src/liveedit.cc +++ b/src/liveedit.cc @@ -391,6 +391,26 @@ class ReferenceCollectorVisitor : public ObjectVisitor { ZoneList 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. diff --git a/src/top.cc b/src/top.cc index 3efd1fc..0fcf458 100644 --- a/src/top.cc +++ b/src/top.cc @@ -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(t); + v->VisitThread(thread); +} + + void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { v->VisitPointer(&(thread->pending_exception_)); v->VisitPointer(&(thread->pending_message_obj_)); diff --git a/src/top.h b/src/top.h index e20a2a0..d263777 100644 --- 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. diff --git a/src/v8threads.cc b/src/v8threads.cc index 80a7cd9..02292f6 100644 --- a/src/v8threads.cc +++ b/src/v8threads.cc @@ -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; diff --git a/src/v8threads.h b/src/v8threads.h index 0684053..d70aa3c 100644 --- a/src/v8threads.h +++ b/src/v8threads.h @@ -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(); } -- 2.7.4