Fix bug 1433: clear the global thread table when an isolate is disposed.
authorvitalyr@chromium.org <vitalyr@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 7 Jun 2011 18:33:03 +0000 (18:33 +0000)
committervitalyr@chromium.org <vitalyr@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 7 Jun 2011 18:33:03 +0000 (18:33 +0000)
R=ager@chromium.org
BUG=v8:1433
TEST=test-lockers/Regress1433

Review URL: http://codereview.chromium.org/7129002

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

src/isolate.cc
src/isolate.h
test/cctest/test-lockers.cc

index 12c9753..1d8a825 100644 (file)
@@ -1307,6 +1307,7 @@ char* Isolate::RestoreThread(char* from) {
   if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
     RuntimeProfiler::IsolateEnteredJS(this);
   }
+  ASSERT(context() == NULL || context()->IsContext());
 #endif
   return from + sizeof(ThreadLocalTop);
 }
@@ -1350,6 +1351,16 @@ void Isolate::ThreadDataTable::Remove(Isolate* isolate,
 }
 
 
+void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
+  PerIsolateThreadData* data = list_;
+  while (data != NULL) {
+    PerIsolateThreadData* next = data->next_;
+    if (data->isolate() == isolate) Remove(data);
+    data = next;
+  }
+}
+
+
 #ifdef DEBUG
 #define TRACE_ISOLATE(tag)                                              \
   do {                                                                  \
@@ -1464,6 +1475,10 @@ void Isolate::TearDown() {
 
   Deinit();
 
+  { ScopedLock lock(process_wide_mutex_);
+    thread_data_table_->RemoveAllThreads(this);
+  }
+
   if (!IsDefaultIsolate()) {
     delete this;
   }
index 28bc44b..bc78c6d 100644 (file)
@@ -529,6 +529,7 @@ class Isolate {
   // Access to top context (where the current function object was created).
   Context* context() { return thread_local_top_.context_; }
   void set_context(Context* context) {
+    ASSERT(context == NULL || context->IsContext());
     thread_local_top_.context_ = context;
   }
   Context** context_address() { return &thread_local_top_.context_; }
@@ -1003,6 +1004,7 @@ class Isolate {
     void Insert(PerIsolateThreadData* data);
     void Remove(Isolate* isolate, ThreadId thread_id);
     void Remove(PerIsolateThreadData* data);
+    void RemoveAllThreads(Isolate* isolate);
 
    private:
     PerIsolateThreadData* list_;
index 5b33f2e..1b46887 100644 (file)
@@ -607,3 +607,23 @@ TEST(LockUnlockLockDefaultIsolateMultithreaded) {
   }
   StartJoinAndDeleteThreads(threads);
 }
+
+
+TEST(Regress1433) {
+  for (int i = 0; i < 10; i++) {
+    v8::Isolate* isolate = v8::Isolate::New();
+    {
+      v8::Locker lock(isolate);
+      v8::Isolate::Scope isolate_scope(isolate);
+      v8::HandleScope handle_scope;
+      v8::Persistent<Context> context = v8::Context::New();
+      v8::Context::Scope context_scope(context);
+      v8::Handle<String> source = v8::String::New("1+1");
+      v8::Handle<Script> script = v8::Script::Compile(source);
+      v8::Handle<Value> result = script->Run();
+      v8::String::AsciiValue ascii(result);
+      context.Dispose();
+    }
+    isolate->Dispose();
+  }
+}