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.