Reviewers: Sven Panne,

Description:
Fix handle zapping interaction with NoHandleAllocation.

This makes sure that closed handle scopes are properly zapped even if an
enclosing NoHandleAllocation shrunk the limit. It also unifies the code
that performs scope closing for internal and external handle scopes.

[email protected]
TEST=cctest/test-api/NestedLockersNoTryCatch

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

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

Affected files:
  M src/api.h
  M src/api.cc
  M src/handles-inl.h
  M src/handles.h
  M test/cctest/test-api.cc


Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index a5ef0543b5579cf87a5cba52f37bbe82c161bc16..e037c11a63250210f2a36fa1f08a912b04de97c0 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -683,19 +683,7 @@ HandleScope::~HandleScope() {


 void HandleScope::Leave() {
-  v8::ImplementationUtilities::HandleScopeData* current =
-      isolate_->handle_scope_data();
-  current->level--;
-  ASSERT(current->level >= 0);
-  current->next = prev_next_;
-  if (current->limit != prev_limit_) {
-    current->limit = prev_limit_;
-    i::HandleScope::DeleteExtensions(isolate_);
-  }
-
-#ifdef ENABLE_EXTRA_CHECKS
-  i::HandleScope::ZapRange(prev_next_, prev_limit_);
-#endif
+  return i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
 }


Index: src/api.h
diff --git a/src/api.h b/src/api.h
index 12d6e3d08229343644b3f571933c15543b90c19b..62380ce651249d86548c37679c9b2deb248c1bfd 100644
--- a/src/api.h
+++ b/src/api.h
@@ -637,7 +637,12 @@ void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
     internal::Object** block_limit = block_start + kHandleBlockSize;
 #ifdef DEBUG
// NoHandleAllocation may make the prev_limit to point inside the block.
-    if (block_start <= prev_limit && prev_limit <= block_limit) break;
+    if (block_start <= prev_limit && prev_limit <= block_limit) {
+#ifdef ENABLE_EXTRA_CHECKS
+      internal::HandleScope::ZapRange(prev_limit, block_limit);
+#endif
+      break;
+    }
 #else
     if (prev_limit == block_limit) break;
 #endif
Index: src/handles-inl.h
diff --git a/src/handles-inl.h b/src/handles-inl.h
index 4f5e9fe720e0b68710ee9e2e6dc23709513c6f89..14687e3bd28086ff8d79935511b383e04ea27037 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -122,31 +122,37 @@ HandleScope::HandleScope(Isolate* isolate) {


 HandleScope::~HandleScope() {
-  CloseScope();
+  CloseScope(isolate_, prev_next_, prev_limit_);
 }

-void HandleScope::CloseScope() {
+
+void HandleScope::CloseScope(Isolate* isolate,
+                             Object** prev_next,
+                             Object** prev_limit) {
   v8::ImplementationUtilities::HandleScopeData* current =
-      isolate_->handle_scope_data();
-  current->next = prev_next_;
+      isolate->handle_scope_data();
+
+  current->next = prev_next;
   current->level--;
-  if (current->limit != prev_limit_) {
-    current->limit = prev_limit_;
-    DeleteExtensions(isolate_);
+  if (current->limit != prev_limit) {
+    current->limit = prev_limit;
+    DeleteExtensions(isolate);
   }
+
 #ifdef ENABLE_EXTRA_CHECKS
-  ZapRange(prev_next_, prev_limit_);
+  ZapRange(prev_next, prev_limit);
 #endif
 }


 template <typename T>
 Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) {
-  T* value = *handle_value;
-  // Throw away all handles in the current scope.
-  CloseScope();
   v8::ImplementationUtilities::HandleScopeData* current =
       isolate_->handle_scope_data();
+
+  T* value = *handle_value;
+  // Throw away all handles in the current scope.
+  CloseScope(isolate_, prev_next_, prev_limit_);
   // Allocate one handle in the parent scope.
   ASSERT(current->level > 0);
   Handle<T> result(CreateHandle<T>(isolate_, value));
@@ -180,15 +186,14 @@ T** HandleScope::CreateHandle(Isolate* isolate, T* value) {
 #ifdef DEBUG
 inline NoHandleAllocation::NoHandleAllocation(Isolate* isolate)
     : isolate_(isolate) {
-  v8::ImplementationUtilities::HandleScopeData* current =
-      isolate_->handle_scope_data();
-
   active_ = !isolate->optimizing_compiler_thread()->IsOptimizerThread();
   if (active_) {
     // Shrink the current handle scope to make it impossible to do
     // handle allocations without an explicit handle scope.
+    v8::ImplementationUtilities::HandleScopeData* current =
+        isolate_->handle_scope_data();
+    limit_ = current->limit;
     current->limit = current->next;
-
     level_ = current->level;
     current->level = 0;
   }
@@ -199,10 +204,12 @@ inline NoHandleAllocation::~NoHandleAllocation() {
   if (active_) {
     // Restore state in current handle scope to re-enable handle
     // allocations.
-    v8::ImplementationUtilities::HandleScopeData* data =
+    v8::ImplementationUtilities::HandleScopeData* current =
         isolate_->handle_scope_data();
-    ASSERT_EQ(0, data->level);
-    data->level = level_;
+    ASSERT_EQ(0, current->level);
+    current->level = level_;
+    ASSERT_EQ(current->next, current->limit);
+    current->limit = limit_;
   }
 }

Index: src/handles.h
diff --git a/src/handles.h b/src/handles.h
index 938d43b8a4e8ba418f85b7eb5ccd2a5ccfb6aad3..29ece281e0984d3fe9224860b3aa2703911cddd1 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -155,18 +155,21 @@ class HandleScope {
   void* operator new(size_t size);
   void operator delete(void* size_t);

-  inline void CloseScope();
-
   Isolate* isolate_;
   Object** prev_next_;
   Object** prev_limit_;

+  // Close the handle scope resetting limits to a previous state.
+  static inline void CloseScope(Isolate* isolate,
+                                Object** prev_next,
+                                Object** prev_limit);
+
   // Extend the handle scope making room for more handles.
   static internal::Object** Extend(Isolate* isolate);

 #ifdef ENABLE_EXTRA_CHECKS
   // Zaps the handles in the half-open interval [start, end).
-  static void ZapRange(internal::Object** start, internal::Object** end);
+  static void ZapRange(Object** start, Object** end);
 #endif

   friend class v8::HandleScope;
@@ -337,6 +340,7 @@ class NoHandleAllocation BASE_EMBEDDED {
   inline ~NoHandleAllocation();
  private:
   Isolate* isolate_;
+  Object** limit_;
   int level_;
   bool active_;
 #endif
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index e52dde37c994fea3d04b3444bb5cc8a6cf8d0836..36ce60b5ba648c3c8992a378cbc831e2fe5b1922 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -12056,7 +12056,7 @@ static v8::Handle<Value> ThrowInJSNoCatch(const v8::Arguments& args) {
     v8::HandleScope scope(args.GetIsolate());
     v8::Handle<Value> value = CompileRun(code);
     CHECK(value.IsEmpty());
-    return v8_str("foo");
+    return scope.Close(v8_str("foo"));
   }
 }



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