Add Isolate parameter to Persistent class.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 25 Jan 2013 08:31:46 +0000 (08:31 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 25 Jan 2013 08:31:46 +0000 (08:31 +0000)
BUG=v8:2487

Review URL: https://codereview.chromium.org/12033011

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

30 files changed:
include/v8.h
samples/lineprocessor.cc
samples/process.cc
samples/shell.cc
src/api.cc
src/d8.cc
src/d8.h
src/debug.cc
src/debug.h
src/deoptimizer.cc
src/deoptimizer.h
src/global-handles.cc
src/global-handles.h
src/handles.cc
src/mksnapshot.cc
src/profile-generator.cc
src/profile-generator.h
test/cctest/cctest.h
test/cctest/test-api.cc
test/cctest/test-debug.cc
test/cctest/test-decls.cc
test/cctest/test-heap-profiler.cc
test/cctest/test-heap.cc
test/cctest/test-lockers.cc
test/cctest/test-log.cc
test/cctest/test-mark-compact.cc
test/cctest/test-regexp.cc
test/cctest/test-serialize.cc
test/cctest/test-thread-termination.cc
test/cctest/test-weakmaps.cc

index 5f3e2ed..bf3beff 100644 (file)
@@ -157,6 +157,10 @@ class Isolate;
 typedef void (*WeakReferenceCallback)(Persistent<Value> object,
                                       void* parameter);
 
+// TODO(svenpanne) Temporary definition until Chrome is in sync.
+typedef void (*NearDeathCallback)(Isolate* isolate,
+                                  Persistent<Value> object,
+                                  void* parameter);
 
 // --- Handles ---
 
@@ -389,11 +393,16 @@ template <class T> class Persistent : public Handle<T> {
     return Persistent<S>::Cast(*this);
   }
 
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(static Persistent<T> New(Handle<T> that));
+
   /**
-   * Creates a new persistent handle for an existing local or
-   * persistent handle.
+   * Creates a new persistent handle for an existing local or persistent handle.
    */
-  V8_INLINE(static Persistent<T> New(Handle<T> that));
+  V8_INLINE(static Persistent<T> New(Isolate* isolate, Handle<T> that));
+
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(void Dispose());
 
   /**
    * Releases the storage cell referenced by this persistent handle.
@@ -401,66 +410,87 @@ template <class T> class Persistent : public Handle<T> {
    * This handle's reference, and any other references to the storage
    * cell remain and IsEmpty will still return false.
    */
-  V8_INLINE(void Dispose());
   V8_INLINE(void Dispose(Isolate* isolate));
 
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(void MakeWeak(void* parameters,
+                              WeakReferenceCallback callback));
+
   /**
    * Make the reference to this object weak.  When only weak handles
    * refer to the object, the garbage collector will perform a
-   * callback to the given V8::WeakReferenceCallback function, passing
+   * callback to the given V8::NearDeathCallback function, passing
    * it the object reference and the given parameters.
    */
-  V8_INLINE(void MakeWeak(void* parameters, WeakReferenceCallback callback));
   V8_INLINE(void MakeWeak(Isolate* isolate,
                           void* parameters,
-                          WeakReferenceCallback callback));
+                          NearDeathCallback callback));
+
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(void ClearWeak());
 
   /** Clears the weak reference to this object. */
-  V8_INLINE(void ClearWeak());
+  V8_INLINE(void ClearWeak(Isolate* isolate));
+
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(void MarkIndependent());
 
   /**
-   * Marks the reference to this object independent. Garbage collector
-   * is free to ignore any object groups containing this object.
-   * Weak callback for an independent handle should not
-   * assume that it will be preceded by a global GC prologue callback
-   * or followed by a global GC epilogue callback.
+   * Marks the reference to this object independent. Garbage collector is free
+   * to ignore any object groups containing this object. Weak callback for an
+   * independent handle should not assume that it will be preceded by a global
+   * GC prologue callback or followed by a global GC epilogue callback.
    */
-  V8_INLINE(void MarkIndependent());
   V8_INLINE(void MarkIndependent(Isolate* isolate));
 
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(void MarkPartiallyDependent());
+
   /**
-   * Marks the reference to this object partially dependent. Partially
-   * dependent handles only depend on other partially dependent handles and
-   * these dependencies are provided through object groups. It provides a way
-   * to build smaller object groups for young objects that represent only a
-   * subset of all external dependencies. This mark is automatically cleared
-   * after each garbage collection.
+   * Marks the reference to this object partially dependent. Partially dependent
+   * handles only depend on other partially dependent handles and these
+   * dependencies are provided through object groups. It provides a way to build
+   * smaller object groups for young objects that represent only a subset of all
+   * external dependencies. This mark is automatically cleared after each
+   * garbage collection.
    */
-  V8_INLINE(void MarkPartiallyDependent());
   V8_INLINE(void MarkPartiallyDependent(Isolate* isolate));
 
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(bool IsIndependent() const);
+
   /** Returns true if this handle was previously marked as independent. */
-  V8_INLINE(bool IsIndependent() const);
   V8_INLINE(bool IsIndependent(Isolate* isolate) const);
 
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(bool IsNearDeath() const);
+
   /** Checks if the handle holds the only reference to an object. */
-  V8_INLINE(bool IsNearDeath() const);
+  V8_INLINE(bool IsNearDeath(Isolate* isolate) const);
+
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(bool IsWeak() const);
 
   /** Returns true if the handle's reference is weak.  */
-  V8_INLINE(bool IsWeak() const);
   V8_INLINE(bool IsWeak(Isolate* isolate) const);
 
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(void SetWrapperClassId(uint16_t class_id));
+
   /**
-   * Assigns a wrapper class ID to the handle. See RetainedObjectInfo
-   * interface description in v8-profiler.h for details.
+   * Assigns a wrapper class ID to the handle. See RetainedObjectInfo interface
+   * description in v8-profiler.h for details.
    */
-  V8_INLINE(void SetWrapperClassId(uint16_t class_id));
+  V8_INLINE(void SetWrapperClassId(Isolate* isolate, uint16_t class_id));
+
+  /** Deprecated. Use Isolate version instead. */
+  V8_DEPRECATED(uint16_t WrapperClassId() const);
 
   /**
-   * Returns the class ID previously assigned to this handle or 0 if no class
-   * ID was previously assigned.
+   * Returns the class ID previously assigned to this handle or 0 if no class ID
+   * was previously assigned.
    */
-  V8_INLINE(uint16_t WrapperClassId() const);
+  V8_INLINE(uint16_t WrapperClassId(Isolate* isolate) const);
 
  private:
   friend class ImplementationUtilities;
@@ -3529,31 +3559,17 @@ class V8EXPORT V8 {
  private:
   V8();
 
-  static internal::Object** GlobalizeReference(internal::Object** handle);
-  static void DisposeGlobal(internal::Object** global_handle);
+  static internal::Object** GlobalizeReference(internal::Isolate* isolate,
+                                               internal::Object** handle);
   static void DisposeGlobal(internal::Isolate* isolate,
                             internal::Object** global_handle);
-  static void MakeWeak(internal::Object** global_handle,
-                       void* data,
-                       WeakReferenceCallback);
   static void MakeWeak(internal::Isolate* isolate,
                        internal::Object** global_handle,
                        void* data,
-                       WeakReferenceCallback);
-  static void ClearWeak(internal::Object** global_handle);
-  static void MarkIndependent(internal::Object** global_handle);
-  static void MarkIndependent(internal::Isolate* isolate,
-                              internal::Object** global_handle);
-  static void MarkPartiallyDependent(internal::Object** global_handle);
-  static void MarkPartiallyDependent(internal::Isolate* isolate,
-                                     internal::Object** global_handle);
-  static bool IsGlobalIndependent(internal::Object** global_handle);
-  static bool IsGlobalIndependent(internal::Isolate* isolate,
-                                  internal::Object** global_handle);
-  static bool IsGlobalNearDeath(internal::Object** global_handle);
-  static bool IsGlobalWeak(internal::Object** global_handle);
-  static bool IsGlobalWeak(internal::Isolate* isolate,
-                           internal::Object** global_handle);
+                       WeakReferenceCallback weak_reference_callback,
+                       NearDeathCallback near_death_callback);
+  static void ClearWeak(internal::Isolate* isolate,
+                        internal::Object** global_handle);
 
   template <class T> friend class Handle;
   template <class T> friend class Local;
@@ -3974,9 +3990,7 @@ class V8EXPORT Unlocker {
    */
   V8_INLINE(explicit Unlocker(Isolate* isolate)) { Initialize(isolate); }
 
-  /**
-   * Deprecated. Use Isolate version instead.
-   */
+  /** Deprecated. Use Isolate version instead. */
   V8_DEPRECATED(Unlocker());
 
   ~Unlocker();
@@ -3994,9 +4008,7 @@ class V8EXPORT Locker {
    */
   V8_INLINE(explicit Locker(Isolate* isolate)) { Initialize(isolate); }
 
-  /**
-   * Deprecated. Use Isolate version instead.
-   */
+  /** Deprecated. Use Isolate version instead. */
   V8_DEPRECATED(Locker());
 
   ~Locker();
@@ -4175,14 +4187,17 @@ class Internals {
   static const int kIsolateStateOffset = 0;
   static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize;
   static const int kIsolateRootsOffset = 3 * kApiPointerSize;
-  static const int kNodeClassIdOffset = 1 * kApiPointerSize;
-  static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
   static const int kUndefinedValueRootIndex = 5;
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
   static const int kEmptySymbolRootIndex = 119;
 
+  static const int kNodeClassIdOffset = 1 * kApiPointerSize;
+  static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
+  static const int kNodeStateMask = 0xf;
+  static const int kNodeStateIsWeakValue = 2;
+  static const int kNodeStateIsNearDeathValue = 4;
   static const int kNodeIsIndependentShift = 4;
   static const int kNodeIsPartiallyDependentShift = 5;
 
@@ -4236,6 +4251,17 @@ class Internals {
       *addr = (*addr & ~mask) | (value << shift);
   }
 
+  V8_INLINE(static uint8_t GetNodeState(internal::Object** obj)) {
+    uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
+    return *addr & kNodeStateMask;
+  }
+
+  V8_INLINE(static void UpdateNodeState(internal::Object** obj,
+                                        uint8_t value)) {
+    uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
+    *addr = (*addr & ~kNodeStateMask) | value;
+  }
+
   V8_INLINE(static void SetEmbedderData(v8::Isolate* isolate, void* data)) {
     uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) +
         kIsolateEmbedderDataOffset;
@@ -4303,7 +4329,7 @@ Local<T> Local<T>::New(Handle<T> that) {
 
 
 template <class T>
-  Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
+Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
   if (that.IsEmpty()) return Local<T>();
   T* that_ptr = *that;
   internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
@@ -4314,16 +4340,23 @@ template <class T>
 
 template <class T>
 Persistent<T> Persistent<T>::New(Handle<T> that) {
+  return New(Isolate::GetCurrent(), that);
+}
+
+
+template <class T>
+Persistent<T> Persistent<T>::New(Isolate* isolate, Handle<T> that) {
   if (that.IsEmpty()) return Persistent<T>();
   internal::Object** p = reinterpret_cast<internal::Object**>(*that);
-  return Persistent<T>(reinterpret_cast<T*>(V8::GlobalizeReference(p)));
+  return Persistent<T>(reinterpret_cast<T*>(
+      V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate),
+                             p)));
 }
 
 
 template <class T>
 bool Persistent<T>::IsIndependent() const {
-  if (this->IsEmpty()) return false;
-  return V8::IsGlobalIndependent(reinterpret_cast<internal::Object**>(**this));
+  return IsIndependent(Isolate::GetCurrent());
 }
 
 
@@ -4339,30 +4372,39 @@ bool Persistent<T>::IsIndependent(Isolate* isolate) const {
 
 template <class T>
 bool Persistent<T>::IsNearDeath() const {
+  return IsNearDeath(Isolate::GetCurrent());
+}
+
+
+template <class T>
+bool Persistent<T>::IsNearDeath(Isolate* isolate) const {
+  typedef internal::Internals I;
   if (this->IsEmpty()) return false;
-  return V8::IsGlobalNearDeath(reinterpret_cast<internal::Object**>(**this));
+  if (!I::IsInitialized(isolate)) return false;
+  return I::GetNodeState(reinterpret_cast<internal::Object**>(**this)) ==
+      I::kNodeStateIsNearDeathValue;
 }
 
 
 template <class T>
 bool Persistent<T>::IsWeak() const {
-  if (this->IsEmpty()) return false;
-  return V8::IsGlobalWeak(reinterpret_cast<internal::Object**>(**this));
+  return IsWeak(Isolate::GetCurrent());
 }
 
 
 template <class T>
 bool Persistent<T>::IsWeak(Isolate* isolate) const {
+  typedef internal::Internals I;
   if (this->IsEmpty()) return false;
-  return V8::IsGlobalWeak(reinterpret_cast<internal::Isolate*>(isolate),
-                          reinterpret_cast<internal::Object**>(**this));
+  if (!I::IsInitialized(isolate)) return false;
+  return I::GetNodeState(reinterpret_cast<internal::Object**>(**this)) ==
+      I::kNodeStateIsWeakValue;
 }
 
 
 template <class T>
 void Persistent<T>::Dispose() {
-  if (this->IsEmpty()) return;
-  V8::DisposeGlobal(reinterpret_cast<internal::Object**>(**this));
+  Dispose(Isolate::GetCurrent());
 }
 
 
@@ -4379,28 +4421,39 @@ Persistent<T>::Persistent() : Handle<T>() { }
 
 template <class T>
 void Persistent<T>::MakeWeak(void* parameters, WeakReferenceCallback callback) {
-  V8::MakeWeak(reinterpret_cast<internal::Object**>(**this),
+  Isolate* isolate = Isolate::GetCurrent();
+  V8::MakeWeak(reinterpret_cast<internal::Isolate*>(isolate),
+               reinterpret_cast<internal::Object**>(**this),
                parameters,
-               callback);
+               callback,
+               NULL);
 }
 
 template <class T>
-void Persistent<T>::MakeWeak(Isolate* isolate, void* parameters,
-                             WeakReferenceCallback callback) {
+void Persistent<T>::MakeWeak(Isolate* isolate,
+                             void* parameters,
+                             NearDeathCallback callback) {
   V8::MakeWeak(reinterpret_cast<internal::Isolate*>(isolate),
                reinterpret_cast<internal::Object**>(**this),
                parameters,
+               NULL,
                callback);
 }
 
 template <class T>
 void Persistent<T>::ClearWeak() {
-  V8::ClearWeak(reinterpret_cast<internal::Object**>(**this));
+  ClearWeak(Isolate::GetCurrent());
+}
+
+template <class T>
+void Persistent<T>::ClearWeak(Isolate* isolate) {
+  V8::ClearWeak(reinterpret_cast<internal::Isolate*>(isolate),
+                reinterpret_cast<internal::Object**>(**this));
 }
 
 template <class T>
 void Persistent<T>::MarkIndependent() {
-  V8::MarkIndependent(reinterpret_cast<internal::Object**>(**this));
+  MarkIndependent(Isolate::GetCurrent());
 }
 
 template <class T>
@@ -4409,12 +4462,13 @@ void Persistent<T>::MarkIndependent(Isolate* isolate) {
   if (this->IsEmpty()) return;
   if (!I::IsInitialized(isolate)) return;
   I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(**this),
-                    true, I::kNodeIsIndependentShift);
+                    true,
+                    I::kNodeIsIndependentShift);
 }
 
 template <class T>
 void Persistent<T>::MarkPartiallyDependent() {
-  V8::MarkPartiallyDependent(reinterpret_cast<internal::Object**>(**this));
+  MarkPartiallyDependent(Isolate::GetCurrent());
 }
 
 template <class T>
@@ -4423,12 +4477,20 @@ void Persistent<T>::MarkPartiallyDependent(Isolate* isolate) {
   if (this->IsEmpty()) return;
   if (!I::IsInitialized(isolate)) return;
   I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(**this),
-                    true, I::kNodeIsPartiallyDependentShift);
+                    true,
+                    I::kNodeIsPartiallyDependentShift);
 }
 
 template <class T>
 void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
+  SetWrapperClassId(Isolate::GetCurrent(), class_id);
+}
+
+template <class T>
+void Persistent<T>::SetWrapperClassId(Isolate* isolate, uint16_t class_id) {
   typedef internal::Internals I;
+  if (this->IsEmpty()) return;
+  if (!I::IsInitialized(isolate)) return;
   internal::Object** obj = reinterpret_cast<internal::Object**>(**this);
   uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
   *reinterpret_cast<uint16_t*>(addr) = class_id;
@@ -4436,7 +4498,14 @@ void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
 
 template <class T>
 uint16_t Persistent<T>::WrapperClassId() const {
+  return WrapperClassId(Isolate::GetCurrent());
+}
+
+template <class T>
+uint16_t Persistent<T>::WrapperClassId(Isolate* isolate) const {
   typedef internal::Internals I;
+  if (this->IsEmpty()) return 0;
+  if (!I::IsInitialized(isolate)) return 0;
   internal::Object** obj = reinterpret_cast<internal::Object**>(**this);
   uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
   return *reinterpret_cast<uint16_t*>(addr);
index 4fc28b7..6549f4c 100644 (file)
@@ -212,9 +212,10 @@ int RunMain(int argc, char* argv[]) {
   v8::Context::Scope context_scope(context);
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  debug_message_context = v8::Persistent<v8::Context>::New(context);
+  debug_message_context =
+      v8::Persistent<v8::Context>::New(context->GetIsolate(), context);
 
-  v8::Locker locker(v8::Isolate::GetCurrent());
+  v8::Locker locker(context->GetIsolate());
 
   if (support_callback) {
     v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
index ae6a550..c3d1773 100644 (file)
@@ -116,11 +116,13 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
 
   // Utility methods for wrapping C++ objects as JavaScript objects,
   // and going back again.
-  static Handle<Object> WrapMap(map<string, string>* obj);
+  Handle<Object> WrapMap(map<string, string>* obj);
   static map<string, string>* UnwrapMap(Handle<Object> obj);
-  static Handle<Object> WrapRequest(HttpRequest* obj);
+  Handle<Object> WrapRequest(HttpRequest* obj);
   static HttpRequest* UnwrapRequest(Handle<Object> obj);
 
+  Isolate* GetIsolate() { return context_->GetIsolate(); }
+
   Handle<String> script_;
   Persistent<Context> context_;
   Persistent<Function> process_;
@@ -187,7 +189,7 @@ bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
 
   // Store the function in a Persistent handle, since we also want
   // that to remain after this call returns
-  process_ = Persistent<Function>::New(process_fun);
+  process_ = Persistent<Function>::New(GetIsolate(), process_fun);
 
   // All done; all went well
   return true;
@@ -273,8 +275,9 @@ JsHttpRequestProcessor::~JsHttpRequestProcessor() {
   // Dispose the persistent handles.  When noone else has any
   // references to the objects stored in the handles they will be
   // automatically reclaimed.
-  context_.Dispose();
-  process_.Dispose();
+  v8::Isolate* isolate = GetIsolate();
+  context_.Dispose(isolate);
+  process_.Dispose(isolate);
 }
 
 
@@ -296,7 +299,7 @@ Handle<Object> JsHttpRequestProcessor::WrapMap(map<string, string>* obj) {
   // It only has to be created once, which we do on demand.
   if (map_template_.IsEmpty()) {
     Handle<ObjectTemplate> raw_template = MakeMapTemplate();
-    map_template_ = Persistent<ObjectTemplate>::New(raw_template);
+    map_template_ = Persistent<ObjectTemplate>::New(GetIsolate(), raw_template);
   }
   Handle<ObjectTemplate> templ = map_template_;
 
@@ -401,7 +404,8 @@ Handle<Object> JsHttpRequestProcessor::WrapRequest(HttpRequest* request) {
   // It only has to be created once, which we do on demand.
   if (request_template_.IsEmpty()) {
     Handle<ObjectTemplate> raw_template = MakeRequestTemplate();
-    request_template_ = Persistent<ObjectTemplate>::New(raw_template);
+    request_template_ =
+        Persistent<ObjectTemplate>::New(GetIsolate(), raw_template);
   }
   Handle<ObjectTemplate> templ = request_template_;
 
index 62f4045..e9057f9 100644 (file)
@@ -79,7 +79,7 @@ int main(int argc, char* argv[]) {
     result = RunMain(argc, argv);
     if (run_shell) RunShell(context);
     context->Exit();
-    context.Dispose();
+    context.Dispose(context->GetIsolate());
   }
   v8::V8::Dispose();
   return result;
index 1561f24..d3d472d 100644 (file)
@@ -626,95 +626,34 @@ bool SetResourceConstraints(ResourceConstraints* constraints) {
 }
 
 
-i::Object** V8::GlobalizeReference(i::Object** obj) {
-  i::Isolate* isolate = i::Isolate::Current();
+i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
   if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL;
   LOG_API(isolate, "Persistent::New");
-  i::Handle<i::Object> result =
-      isolate->global_handles()->Create(*obj);
+  i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
   return result.location();
 }
 
 
-void V8::MakeWeak(i::Object** object, void* parameters,
-                  WeakReferenceCallback callback) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "MakeWeak");
-  isolate->global_handles()->MakeWeak(object, parameters,
-                                      callback);
-}
-
-
-void V8::MakeWeak(i::Isolate* isolate, i::Object** object,
-                  void* parameters, WeakReferenceCallback callback) {
+void V8::MakeWeak(i::Isolate* isolate,
+                  i::Object** object,
+                  void* parameters,
+                  WeakReferenceCallback weak_reference_callback,
+                  NearDeathCallback near_death_callback) {
   ASSERT(isolate == i::Isolate::Current());
   LOG_API(isolate, "MakeWeak");
-  isolate->global_handles()->MakeWeak(object, parameters,
-                                      callback);
+  isolate->global_handles()->MakeWeak(object,
+                                      parameters,
+                                      weak_reference_callback,
+                                      near_death_callback);
 }
 
 
-void V8::ClearWeak(i::Object** obj) {
-  i::Isolate* isolate = i::Isolate::Current();
+void V8::ClearWeak(i::Isolate* isolate, i::Object** obj) {
   LOG_API(isolate, "ClearWeak");
   isolate->global_handles()->ClearWeakness(obj);
 }
 
 
-void V8::MarkIndependent(i::Object** object) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "MarkIndependent");
-  isolate->global_handles()->MarkIndependent(object);
-}
-
-
-void V8::MarkPartiallyDependent(i::Object** object) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "MarkPartiallyDependent");
-  isolate->global_handles()->MarkPartiallyDependent(object);
-}
-
-
-bool V8::IsGlobalIndependent(i::Object** obj) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "IsGlobalIndependent");
-  if (!isolate->IsInitialized()) return false;
-  return i::GlobalHandles::IsIndependent(obj);
-}
-
-
-bool V8::IsGlobalNearDeath(i::Object** obj) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "IsGlobalNearDeath");
-  if (!isolate->IsInitialized()) return false;
-  return i::GlobalHandles::IsNearDeath(obj);
-}
-
-
-bool V8::IsGlobalWeak(i::Object** obj) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "IsGlobalWeak");
-  if (!isolate->IsInitialized()) return false;
-  return i::GlobalHandles::IsWeak(obj);
-}
-
-
-bool V8::IsGlobalWeak(i::Isolate* isolate, i::Object** obj) {
-  ASSERT(isolate == i::Isolate::Current());
-  LOG_API(isolate, "IsGlobalWeak");
-  if (!isolate->IsInitialized()) return false;
-  return i::GlobalHandles::IsWeak(obj);
-}
-
-
-void V8::DisposeGlobal(i::Object** obj) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "DisposeGlobal");
-  if (!isolate->IsInitialized()) return;
-  isolate->global_handles()->Destroy(obj);
-}
-
-
 void V8::DisposeGlobal(i::Isolate* isolate, i::Object** obj) {
   ASSERT(isolate == i::Isolate::Current());
   LOG_API(isolate, "DisposeGlobal");
index 407488f..6d63ef1 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -95,14 +95,14 @@ class Symbols {
   explicit Symbols(Isolate* isolate) : isolate_(isolate) {
     HandleScope scope;
 #define INIT_SYMBOL(name, value) \
-    name##_ = Persistent<String>::New(String::NewSymbol(value));
+    name##_ = Persistent<String>::New(isolate, String::NewSymbol(value));
     FOR_EACH_SYMBOL(INIT_SYMBOL)
 #undef INIT_SYMBOL
     isolate->SetData(this);
   }
 
   ~Symbols() {
-#define DISPOSE_SYMBOL(name, value) name##_.Dispose();
+#define DISPOSE_SYMBOL(name, value) name##_.Dispose(isolate_);
     FOR_EACH_SYMBOL(DISPOSE_SYMBOL)
 #undef DISPOSE_SYMBOL
     isolate_->SetData(NULL);  // Not really needed, just to be sure...
@@ -399,9 +399,10 @@ Handle<Value> Shell::CreateExternalArrayBuffer(Isolate* isolate,
   memset(data, 0, length);
 
   buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True());
-  Persistent<Object> persistent_array = Persistent<Object>::New(buffer);
-  persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
-  persistent_array.MarkIndependent();
+  Persistent<Object> persistent_array =
+      Persistent<Object>::New(isolate, buffer);
+  persistent_array.MakeWeak(isolate, data, ExternalArrayWeakCallback);
+  persistent_array.MarkIndependent(isolate);
   V8::AdjustAmountOfExternalAllocatedMemory(length);
 
   buffer->SetIndexedPropertiesToExternalArrayData(
@@ -826,14 +827,15 @@ Handle<Value> Shell::ArraySet(const Arguments& args) {
 }
 
 
-void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
+void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate,
+                                      Persistent<Value> object,
+                                      void* data) {
   HandleScope scope;
-  Isolate* isolate = Isolate::GetCurrent();
   int32_t length =
       object->ToObject()->Get(Symbols::byteLength(isolate))->Uint32Value();
   V8::AdjustAmountOfExternalAllocatedMemory(-length);
   delete[] static_cast<uint8_t*>(data);
-  object.Dispose();
+  object.Dispose(isolate);
 }
 
 
@@ -1442,9 +1444,10 @@ Handle<Value> Shell::ReadBuffer(const Arguments& args) {
   Isolate* isolate = args.GetIsolate();
   Handle<Object> buffer = Object::New();
   buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True());
-  Persistent<Object> persistent_buffer = Persistent<Object>::New(buffer);
-  persistent_buffer.MakeWeak(data, ExternalArrayWeakCallback);
-  persistent_buffer.MarkIndependent();
+  Persistent<Object> persistent_buffer =
+      Persistent<Object>::New(isolate, buffer);
+  persistent_buffer.MakeWeak(isolate, data, ExternalArrayWeakCallback);
+  persistent_buffer.MarkIndependent(isolate);
   V8::AdjustAmountOfExternalAllocatedMemory(length);
 
   buffer->SetIndexedPropertiesToExternalArrayData(
@@ -1565,7 +1568,7 @@ void ShellThread::Run() {
       Shell::ExecuteString(str, String::New(filename), false, false);
     }
 
-    thread_context.Dispose();
+    thread_context.Dispose(thread_context->GetIsolate());
     ptr = next_line;
   }
 }
@@ -1649,7 +1652,7 @@ void SourceGroup::ExecuteInThread() {
         Context::Scope cscope(context);
         Execute(isolate);
       }
-      context.Dispose();
+      context.Dispose(isolate);
       if (Shell::options.send_idle_notification) {
         const int kLongIdlePauseInMs = 1000;
         V8::ContextDisposedNotification();
@@ -1858,7 +1861,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
       options.isolate_sources[0].Execute(isolate);
     }
     if (!options.last_run) {
-      context.Dispose();
+      context.Dispose(isolate);
       if (options.send_idle_notification) {
         const int kLongIdlePauseInMs = 1000;
         V8::ContextDisposedNotification();
index 63efd66..1c3ce0a 100644 (file)
--- a/src/d8.h
+++ b/src/d8.h
@@ -404,7 +404,9 @@ class Shell : public i::AllStatic {
   static Handle<Value> CreateExternalArray(const Arguments& args,
                                            ExternalArrayType type,
                                            int32_t element_size);
-  static void ExternalArrayWeakCallback(Persistent<Value> object, void* data);
+  static void ExternalArrayWeakCallback(Isolate* isolate,
+                                        Persistent<Value> object,
+                                        void* data);
 };
 
 
index 7baed88..866839d 100644 (file)
@@ -617,10 +617,10 @@ void ScriptCache::Add(Handle<Script> script) {
   Handle<Script> script_ =
       Handle<Script>::cast(
           (global_handles->Create(*script)));
-  global_handles->MakeWeak(
-      reinterpret_cast<Object**>(script_.location()),
-      this,
-      ScriptCache::HandleWeakScript);
+  global_handles->MakeWeak(reinterpret_cast<Object**>(script_.location()),
+                           this,
+                           NULL,
+                           ScriptCache::HandleWeakScript);
   entry->value = script_.location();
 }
 
@@ -663,7 +663,9 @@ void ScriptCache::Clear() {
 }
 
 
-void ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) {
+void ScriptCache::HandleWeakScript(v8::Isolate* isolate,
+                                   v8::Persistent<v8::Value> obj,
+                                   void* data) {
   ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data);
   // Find the location of the global handle.
   Script** location =
@@ -676,7 +678,7 @@ void ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) {
   script_cache->collected_scripts_.Add(id);
 
   // Clear the weak handle.
-  obj.Dispose();
+  obj.Dispose(isolate);
   obj.Clear();
 }
 
@@ -696,8 +698,10 @@ void Debug::SetUp(bool create_heap_objects) {
 }
 
 
-void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
-  Debug* debug = Isolate::Current()->debug();
+void Debug::HandleWeakDebugInfo(v8::Isolate* isolate,
+                                v8::Persistent<v8::Value> obj,
+                                void* data) {
+  Debug* debug = reinterpret_cast<Isolate*>(isolate)->debug();
   DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
   // We need to clear all breakpoints associated with the function to restore
   // original code and avoid patching the code twice later because
@@ -721,10 +725,10 @@ DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
   // Globalize the request debug info object and make it weak.
   debug_info_ = Handle<DebugInfo>::cast(
       (global_handles->Create(debug_info)));
-  global_handles->MakeWeak(
-      reinterpret_cast<Object**>(debug_info_.location()),
-      this,
-      Debug::HandleWeakDebugInfo);
+  global_handles->MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
+                           this,
+                           NULL,
+                           Debug::HandleWeakDebugInfo);
 }
 
 
index 4363df9..0558afd 100644 (file)
@@ -189,7 +189,9 @@ class ScriptCache : private HashMap {
   void Clear();
 
   // Weak handle callback for scripts in the cache.
-  static void HandleWeakScript(v8::Persistent<v8::Value> obj, void* data);
+  static void HandleWeakScript(v8::Isolate* isolate,
+                               v8::Persistent<v8::Value> obj,
+                               void* data);
 
   // List used during GC to temporarily store id's of collected scripts.
   List<int> collected_scripts_;
@@ -384,7 +386,9 @@ class Debug {
   static const int kEstimatedNofBreakPointsInFunction = 16;
 
   // Passed to MakeWeak.
-  static void HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data);
+  static void HandleWeakDebugInfo(v8::Isolate* isolate,
+                                  v8::Persistent<v8::Value> obj,
+                                  void* data);
 
   friend class Debugger;
   friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
index bc0c61c..3d07ca9 100644 (file)
@@ -456,11 +456,13 @@ void Deoptimizer::DeoptimizeAllFunctionsWith(OptimizedFunctionFilter* filter) {
 }
 
 
-void Deoptimizer::HandleWeakDeoptimizedCode(v8::Persistent<v8::Value> obj,
+void Deoptimizer::HandleWeakDeoptimizedCode(v8::Isolate* isolate,
+                                            v8::Persistent<v8::Value> obj,
                                             void* parameter) {
   DeoptimizingCodeListNode* node =
       reinterpret_cast<DeoptimizingCodeListNode*>(parameter);
-  DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+  DeoptimizerData* data =
+      reinterpret_cast<Isolate*>(isolate)->deoptimizer_data();
   data->RemoveDeoptimizingCode(*node->code());
 #ifdef DEBUG
   for (DeoptimizingCodeListNode* current = data->deoptimizing_code_list_;
@@ -1913,6 +1915,7 @@ DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) {
   code_ = Handle<Code>::cast(global_handles->Create(code));
   global_handles->MakeWeak(reinterpret_cast<Object**>(code_.location()),
                            this,
+                           NULL,
                            Deoptimizer::HandleWeakDeoptimizedCode);
 }
 
index 870fdb2..0c2252e 100644 (file)
@@ -372,8 +372,9 @@ class Deoptimizer : public Malloced {
       MacroAssembler* masm, int count, BailoutType type);
 
   // Weak handle callback for deoptimizing code objects.
-  static void HandleWeakDeoptimizedCode(
-      v8::Persistent<v8::Value> obj, void* data);
+  static void HandleWeakDeoptimizedCode(v8::Isolate* isolate,
+                                        v8::Persistent<v8::Value> obj,
+                                        void* data);
 
   // Deoptimize function assuming that function->next_function_link() points
   // to a list that contains all functions that share the same optimized code.
index 23b3918..6377af6 100644 (file)
@@ -60,12 +60,16 @@ class GlobalHandles::Node {
   }
 
   Node() {
-    ASSERT(OFFSET_OF(Node, flags_) == Internals::kNodeFlagsOffset);
-    ASSERT(OFFSET_OF(Node, class_id_) == Internals::kNodeClassIdOffset);
-    ASSERT(static_cast<int>(IsIndependent::kShift) ==
-           Internals::kNodeIsIndependentShift);
-    ASSERT(static_cast<int>(IsPartiallyDependent::kShift) ==
-           Internals::kNodeIsPartiallyDependentShift);
+    STATIC_ASSERT(offsetof(Node, class_id_) == Internals::kNodeClassIdOffset);
+    STATIC_ASSERT(offsetof(Node, flags_) == Internals::kNodeFlagsOffset);
+    STATIC_ASSERT(static_cast<int>(NodeState::kMask) ==
+                  Internals::kNodeStateMask);
+    STATIC_ASSERT(WEAK == Internals::kNodeStateIsWeakValue);
+    STATIC_ASSERT(NEAR_DEATH == Internals::kNodeStateIsNearDeathValue);
+    STATIC_ASSERT(static_cast<int>(IsIndependent::kShift) ==
+                  Internals::kNodeIsIndependentShift);
+    STATIC_ASSERT(static_cast<int>(IsPartiallyDependent::kShift) ==
+                  Internals::kNodeIsPartiallyDependentShift);
   }
 
 #ifdef DEBUG
@@ -79,7 +83,8 @@ class GlobalHandles::Node {
     set_partially_dependent(false);
     set_in_new_space_list(false);
     parameter_or_next_free_.next_free = NULL;
-    callback_ = NULL;
+    weak_reference_callback_ = NULL;
+    near_death_callback_ = NULL;
   }
 #endif
 
@@ -100,7 +105,8 @@ class GlobalHandles::Node {
     set_partially_dependent(false);
     set_state(NORMAL);
     parameter_or_next_free_.parameter = NULL;
-    callback_ = NULL;
+    weak_reference_callback_ = NULL;
+    near_death_callback_ = NULL;
     IncreaseBlockUses(global_handles);
   }
 
@@ -189,7 +195,8 @@ class GlobalHandles::Node {
   void clear_partially_dependent() { set_partially_dependent(false); }
 
   // Callback accessor.
-  WeakReferenceCallback callback() { return callback_; }
+  // TODO(svenpanne) Re-enable or nuke later.
+  // WeakReferenceCallback callback() { return callback_; }
 
   // Callback parameter accessors.
   void set_parameter(void* parameter) {
@@ -213,11 +220,13 @@ class GlobalHandles::Node {
 
   void MakeWeak(GlobalHandles* global_handles,
                 void* parameter,
-                WeakReferenceCallback callback) {
+                WeakReferenceCallback weak_reference_callback,
+                NearDeathCallback near_death_callback) {
     ASSERT(state() != FREE);
     set_state(WEAK);
     set_parameter(parameter);
-    callback_ = callback;
+    weak_reference_callback_ = weak_reference_callback;
+    near_death_callback_ = near_death_callback;
   }
 
   void ClearWeakness(GlobalHandles* global_handles) {
@@ -229,8 +238,8 @@ class GlobalHandles::Node {
   bool PostGarbageCollectionProcessing(Isolate* isolate,
                                        GlobalHandles* global_handles) {
     if (state() != Node::PENDING) return false;
-    WeakReferenceCallback func = callback();
-    if (func == NULL) {
+    if (weak_reference_callback_ == NULL &&
+        near_death_callback_ == NULL) {
       Release(global_handles);
       return false;
     }
@@ -248,7 +257,14 @@ class GlobalHandles::Node {
              ExternalTwoByteString::cast(object_)->resource() != NULL);
       // Leaving V8.
       VMState state(isolate, EXTERNAL);
-      func(object, par);
+      if (weak_reference_callback_ != NULL) {
+        weak_reference_callback_(object, par);
+      }
+      if (near_death_callback_ != NULL) {
+        near_death_callback_(reinterpret_cast<v8::Isolate*>(isolate),
+                             object,
+                             par);
+      }
     }
     // Absence of explicit cleanup or revival of weak handle
     // in most of the cases would lead to memory leak.
@@ -284,7 +300,8 @@ class GlobalHandles::Node {
   uint8_t flags_;
 
   // Handle specific callback.
-  WeakReferenceCallback callback_;
+  WeakReferenceCallback weak_reference_callback_;
+  NearDeathCallback near_death_callback_;
 
   // Provided data for callback.  In FREE state, this is used for
   // the free list link.
@@ -450,10 +467,16 @@ void GlobalHandles::Destroy(Object** location) {
 }
 
 
-void GlobalHandles::MakeWeak(Object** location, void* parameter,
-                             WeakReferenceCallback callback) {
-  ASSERT(callback != NULL);
-  Node::FromLocation(location)->MakeWeak(this, parameter, callback);
+void GlobalHandles::MakeWeak(Object** location,
+                             void* parameter,
+                             WeakReferenceCallback weak_reference_callback,
+                             NearDeathCallback near_death_callback) {
+  ASSERT((weak_reference_callback != NULL) !=
+         (near_death_callback != NULL));
+  Node::FromLocation(location)->MakeWeak(this,
+                                         parameter,
+                                         weak_reference_callback,
+                                         near_death_callback);
 }
 
 
index 18bfc11..9900144 100644 (file)
@@ -126,7 +126,8 @@ class GlobalHandles {
   // reason is that Smi::FromInt(0) does not change during garage collection.
   void MakeWeak(Object** location,
                 void* parameter,
-                WeakReferenceCallback callback);
+                WeakReferenceCallback weak_reference_callback,
+                NearDeathCallback near_death_callback);
 
   void RecordStats(HeapStats* stats);
 
index c0dea20..e97dcad 100644 (file)
@@ -350,14 +350,16 @@ Handle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info) {
 // collector will call the weak callback on the global handle
 // associated with the wrapper and get rid of both the wrapper and the
 // handle.
-static void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
+static void ClearWrapperCache(v8::Isolate* v8_isolate,
+                              Persistent<v8::Value> handle,
+                              void*) {
   Handle<Object> cache = Utils::OpenHandle(*handle);
   JSValue* wrapper = JSValue::cast(*cache);
   Foreign* foreign = Script::cast(wrapper->value())->wrapper();
   ASSERT(foreign->foreign_address() ==
          reinterpret_cast<Address>(cache.location()));
   foreign->set_foreign_address(0);
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
   isolate->global_handles()->Destroy(cache.location());
   isolate->counters()->script_wrappers()->Decrement();
 }
@@ -390,7 +392,9 @@ Handle<JSValue> GetScriptWrapper(Handle<Script> script) {
   // for future use. The cache will automatically be cleared by the
   // garbage collector when it is not used anymore.
   Handle<Object> handle = isolate->global_handles()->Create(*result);
-  isolate->global_handles()->MakeWeak(handle.location(), NULL,
+  isolate->global_handles()->MakeWeak(handle.location(),
+                                      NULL,
+                                      NULL,
                                       &ClearWrapperCache);
   script->wrapper()->set_foreign_address(
       reinterpret_cast<Address>(handle.location()));
index d777551..a3665e9 100644 (file)
@@ -384,7 +384,7 @@ int main(int argc, char** argv) {
   // context even after we have disposed of the context.
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags, "mksnapshot");
   i::Object* raw_context = *(v8::Utils::OpenHandle(*context));
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
   CppByteSink sink(argv[1]);
   // This results in a somewhat smaller snapshot, probably because it gets rid
   // of some things that are cached between garbage collections.
index a4e6596..0c7dc14 100644 (file)
@@ -66,7 +66,9 @@ int TokenEnumerator::GetTokenId(Object* token) {
   Handle<Object> handle = isolate->global_handles()->Create(token);
   // handle.location() points to a memory cell holding a pointer
   // to a token object in the V8's heap.
-  isolate->global_handles()->MakeWeak(handle.location(), this,
+  isolate->global_handles()->MakeWeak(handle.location(),
+                                      this,
+                                      NULL,
                                       TokenRemovedCallback);
   token_locations_.Add(handle.location());
   token_removed_.Add(false);
@@ -74,11 +76,12 @@ int TokenEnumerator::GetTokenId(Object* token) {
 }
 
 
-void TokenEnumerator::TokenRemovedCallback(v8::Persistent<v8::Value> handle,
+void TokenEnumerator::TokenRemovedCallback(v8::Isolate* isolate,
+                                           v8::Persistent<v8::Value> handle,
                                            void* parameter) {
   reinterpret_cast<TokenEnumerator*>(parameter)->TokenRemoved(
       Utils::OpenHandle(*handle).location());
-  handle.Dispose();
+  handle.Dispose(isolate);
 }
 
 
index f306659..086e5c6 100644 (file)
@@ -45,7 +45,8 @@ class TokenEnumerator {
   static const int kInheritsSecurityToken = -2;
 
  private:
-  static void TokenRemovedCallback(v8::Persistent<v8::Value> handle,
+  static void TokenRemovedCallback(v8::Isolate* isolate,
+                                   v8::Persistent<v8::Value> handle,
                                    void* parameter);
   void TokenRemoved(Object** token_location);
 
index f9f3b42..44690b3 100644 (file)
@@ -179,11 +179,13 @@ class LocalContext {
                v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>())
     : context_(v8::Context::New(extensions, global_template, global_object)) {
     context_->Enter();
+    // We can't do this later perhaps because of a fatal error.
+    isolate_ = context_->GetIsolate();
   }
 
   virtual ~LocalContext() {
     context_->Exit();
-    context_.Dispose();
+    context_.Dispose(isolate_);
   }
 
   v8::Context* operator->() { return *context_; }
@@ -196,6 +198,7 @@ class LocalContext {
 
  private:
   v8::Persistent<v8::Context> context_;
+  v8::Isolate* isolate_;
 };
 
 
index ca027df..341459e 100644 (file)
@@ -181,7 +181,7 @@ THREADED_TEST(IsolateOfContext) {
   CHECK(!env->InContext());
   CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
 
-  env.Dispose();
+  env.Dispose(env->GetIsolate());
 }
 
 
@@ -2317,22 +2317,23 @@ THREADED_TEST(External) {
 
 
 THREADED_TEST(GlobalHandle) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
   v8::Persistent<String> global;
   {
     v8::HandleScope scope;
     Local<String> str = v8_str("str");
-    global = v8::Persistent<String>::New(str);
+    global = v8::Persistent<String>::New(isolate, str);
   }
   CHECK_EQ(global->Length(), 3);
-  global.Dispose();
+  global.Dispose(isolate);
 
   {
     v8::HandleScope scope;
     Local<String> str = v8_str("str");
-    global = v8::Persistent<String>::New(str);
+    global = v8::Persistent<String>::New(isolate, str);
   }
   CHECK_EQ(global->Length(), 3);
-  global.Dispose(v8::Isolate::GetCurrent());
+  global.Dispose(isolate);
 }
 
 
@@ -2358,17 +2359,20 @@ class WeakCallCounter {
 };
 
 
-static void WeakPointerCallback(Persistent<Value> handle, void* id) {
+static void WeakPointerCallback(v8::Isolate* isolate,
+                                Persistent<Value> handle,
+                                void* id) {
   WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id);
   CHECK_EQ(1234, counter->id());
   counter->increment();
-  handle.Dispose();
+  handle.Dispose(isolate);
 }
 
 
 THREADED_TEST(ApiObjectGroups) {
   HandleScope scope;
   LocalContext env;
+  v8::Isolate* iso = env->GetIsolate();
 
   Persistent<Object> g1s1;
   Persistent<Object> g1s2;
@@ -2381,22 +2385,22 @@ THREADED_TEST(ApiObjectGroups) {
 
   {
     HandleScope scope;
-    g1s1 = Persistent<Object>::New(Object::New());
-    g1s2 = Persistent<Object>::New(Object::New());
-    g1c1 = Persistent<Object>::New(Object::New());
-    g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g1s1 = Persistent<Object>::New(iso, Object::New());
+    g1s2 = Persistent<Object>::New(iso, Object::New());
+    g1c1 = Persistent<Object>::New(iso, Object::New());
+    g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
-    g2s1 = Persistent<Object>::New(Object::New());
-    g2s2 = Persistent<Object>::New(Object::New());
-    g2c1 = Persistent<Object>::New(Object::New());
-    g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g2s1 = Persistent<Object>::New(iso, Object::New());
+    g2s2 = Persistent<Object>::New(iso, Object::New());
+    g2c1 = Persistent<Object>::New(iso, Object::New());
+    g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
   }
 
-  Persistent<Object> root = Persistent<Object>::New(g1s1);  // make a root.
+  Persistent<Object> root = Persistent<Object>::New(iso, g1s1);  // make a root.
 
   // Connect group 1 and 2, make a cycle.
   CHECK(g1s2->Set(0, g2s2));
@@ -2419,11 +2423,11 @@ THREADED_TEST(ApiObjectGroups) {
   CHECK_EQ(0, counter.NumberOfWeakCalls());
 
   // Weaken the root.
-  root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+  root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
   // But make children strong roots---all the objects (except for children)
   // should be collectable now.
-  g1c1.ClearWeak();
-  g2c1.ClearWeak();
+  g1c1.ClearWeak(iso);
+  g2c1.ClearWeak(iso);
 
   // Groups are deleted, rebuild groups.
   {
@@ -2443,8 +2447,8 @@ THREADED_TEST(ApiObjectGroups) {
   CHECK_EQ(5, counter.NumberOfWeakCalls());
 
   // And now make children weak again and collect them.
-  g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+  g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+  g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
   HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
   CHECK_EQ(7, counter.NumberOfWeakCalls());
@@ -2454,6 +2458,7 @@ THREADED_TEST(ApiObjectGroups) {
 THREADED_TEST(ApiObjectGroupsCycle) {
   HandleScope scope;
   LocalContext env;
+  v8::Isolate* iso = env->GetIsolate();
 
   WeakCallCounter counter(1234);
 
@@ -2466,41 +2471,38 @@ THREADED_TEST(ApiObjectGroupsCycle) {
   Persistent<Object> g4s1;
   Persistent<Object> g4s2;
 
-  v8::Isolate* isolate = v8::Isolate::GetCurrent();
   {
     HandleScope scope;
-    g1s1 = Persistent<Object>::New(Object::New());
-    g1s2 = Persistent<Object>::New(Object::New());
-    g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g1s1.IsWeak());
-    CHECK(g1s2.IsWeak());
-
-    g2s1 = Persistent<Object>::New(Object::New());
-    g2s2 = Persistent<Object>::New(Object::New());
-    g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g2s1.IsWeak());
-    CHECK(g2s2.IsWeak());
-
-    g3s1 = Persistent<Object>::New(Object::New());
-    g3s2 = Persistent<Object>::New(Object::New());
-    g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g3s1.IsWeak());
-    CHECK(g3s2.IsWeak());
-
-    g4s1 = Persistent<Object>::New(Object::New());
-    g4s2 = Persistent<Object>::New(Object::New());
-    g4s1.MakeWeak(isolate,
-                  reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g4s2.MakeWeak(isolate,
-                  reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    CHECK(g4s1.IsWeak(isolate));
-    CHECK(g4s2.IsWeak(isolate));
-  }
-
-  Persistent<Object> root = Persistent<Object>::New(g1s1);  // make a root.
+    g1s1 = Persistent<Object>::New(iso, Object::New());
+    g1s2 = Persistent<Object>::New(iso, Object::New());
+    g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    CHECK(g1s1.IsWeak(iso));
+    CHECK(g1s2.IsWeak(iso));
+
+    g2s1 = Persistent<Object>::New(iso, Object::New());
+    g2s2 = Persistent<Object>::New(iso, Object::New());
+    g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    CHECK(g2s1.IsWeak(iso));
+    CHECK(g2s2.IsWeak(iso));
+
+    g3s1 = Persistent<Object>::New(iso, Object::New());
+    g3s2 = Persistent<Object>::New(iso, Object::New());
+    g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    CHECK(g3s1.IsWeak(iso));
+    CHECK(g3s2.IsWeak(iso));
+
+    g4s1 = Persistent<Object>::New(iso, Object::New());
+    g4s2 = Persistent<Object>::New(iso, Object::New());
+    g4s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g4s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    CHECK(g4s1.IsWeak(iso));
+    CHECK(g4s2.IsWeak(iso));
+  }
+
+  Persistent<Object> root = Persistent<Object>::New(iso, g1s1);  // make a root.
 
   // Connect groups.  We're building the following cycle:
   // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
@@ -2520,7 +2522,7 @@ THREADED_TEST(ApiObjectGroupsCycle) {
     V8::AddImplicitReferences(g2s1, g2_children, 1);
     V8::AddObjectGroup(g3_objects, 2);
     V8::AddImplicitReferences(g3s1, g3_children, 1);
-    V8::AddObjectGroup(isolate, g4_objects, 2);
+    V8::AddObjectGroup(iso, g4_objects, 2);
     V8::AddImplicitReferences(g4s1, g4_children, 1);
   }
   // Do a single full GC
@@ -2530,7 +2532,7 @@ THREADED_TEST(ApiObjectGroupsCycle) {
   CHECK_EQ(0, counter.NumberOfWeakCalls());
 
   // Weaken the root.
-  root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+  root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
   // Groups are deleted, rebuild groups.
   {
@@ -2566,6 +2568,7 @@ TEST(ApiObjectGroupsCycleForScavenger) {
   i::FLAG_gc_global = false;
   HandleScope scope;
   LocalContext env;
+  v8::Isolate* iso = env->GetIsolate();
 
   WeakCallCounter counter(1234);
 
@@ -2578,36 +2581,36 @@ TEST(ApiObjectGroupsCycleForScavenger) {
 
   {
     HandleScope scope;
-    g1s1 = Persistent<Object>::New(Object::New());
-    g1s2 = Persistent<Object>::New(Object::New());
-    g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g1s1 = Persistent<Object>::New(iso, Object::New());
+    g1s2 = Persistent<Object>::New(iso, Object::New());
+    g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
-    g2s1 = Persistent<Object>::New(Object::New());
-    g2s2 = Persistent<Object>::New(Object::New());
-    g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g2s1 = Persistent<Object>::New(iso, Object::New());
+    g2s2 = Persistent<Object>::New(iso, Object::New());
+    g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
-    g3s1 = Persistent<Object>::New(Object::New());
-    g3s2 = Persistent<Object>::New(Object::New());
-    g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-    g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g3s1 = Persistent<Object>::New(iso, Object::New());
+    g3s2 = Persistent<Object>::New(iso, Object::New());
+    g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+    g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
   }
 
   // Make a root.
-  Persistent<Object> root = Persistent<Object>::New(g1s1);
-  root.MarkPartiallyDependent();
+  Persistent<Object> root = Persistent<Object>::New(iso, g1s1);
+  root.MarkPartiallyDependent(iso);
 
   // Connect groups.  We're building the following cycle:
   // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
   // groups.
   {
-    g1s1.MarkPartiallyDependent();
-    g1s2.MarkPartiallyDependent();
-    g2s1.MarkPartiallyDependent();
-    g2s2.MarkPartiallyDependent();
-    g3s1.MarkPartiallyDependent();
-    g3s2.MarkPartiallyDependent();
+    g1s1.MarkPartiallyDependent(iso);
+    g1s2.MarkPartiallyDependent(iso);
+    g2s1.MarkPartiallyDependent(iso);
+    g2s2.MarkPartiallyDependent(iso);
+    g3s1.MarkPartiallyDependent(iso);
+    g3s2.MarkPartiallyDependent(iso);
     Persistent<Value> g1_objects[] = { g1s1, g1s2 };
     Persistent<Value> g2_objects[] = { g2s1, g2s2 };
     Persistent<Value> g3_objects[] = { g3s1, g3s2 };
@@ -2625,8 +2628,8 @@ TEST(ApiObjectGroupsCycleForScavenger) {
   CHECK_EQ(0, counter.NumberOfWeakCalls());
 
   // Weaken the root.
-  root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
-  root.MarkPartiallyDependent();
+  root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+  root.MarkPartiallyDependent(iso);
 
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   // Groups are deleted, rebuild groups.
@@ -3759,6 +3762,7 @@ TEST(TryCatchNested) {
 THREADED_TEST(Equality) {
   v8::HandleScope scope;
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
   // Check that equality works at all before relying on CHECK_EQ
   CHECK(v8_str("a")->Equals(v8_str("a")));
   CHECK(!v8_str("a")->Equals(v8_str("b")));
@@ -3782,9 +3786,10 @@ THREADED_TEST(Equality) {
   CHECK(!v8::False()->StrictEquals(v8::Undefined()));
 
   v8::Handle<v8::Object> obj = v8::Object::New();
-  v8::Persistent<v8::Object> alias = v8::Persistent<v8::Object>::New(obj);
+  v8::Persistent<v8::Object> alias =
+      v8::Persistent<v8::Object>::New(isolate, obj);
   CHECK(alias->StrictEquals(obj));
-  alias.Dispose();
+  alias.Dispose(isolate);
 }
 
 
@@ -4082,7 +4087,7 @@ static void SetXValue(Local<String> name,
   CHECK_EQ(info.Data(), v8_str("donut"));
   CHECK_EQ(name, v8_str("x"));
   CHECK(xValue.IsEmpty());
-  xValue = v8::Persistent<Value>::New(value);
+  xValue = v8::Persistent<Value>::New(info.GetIsolate(), value);
 }
 
 
@@ -4097,7 +4102,7 @@ THREADED_TEST(SimplePropertyWrite) {
     CHECK(xValue.IsEmpty());
     script->Run();
     CHECK_EQ(v8_num(4), xValue);
-    xValue.Dispose();
+    xValue.Dispose(context->GetIsolate());
     xValue = v8::Persistent<Value>();
   }
 }
@@ -4114,7 +4119,7 @@ THREADED_TEST(SetterOnly) {
     CHECK(xValue.IsEmpty());
     script->Run();
     CHECK_EQ(v8_num(4), xValue);
-    xValue.Dispose();
+    xValue.Dispose(context->GetIsolate());
     xValue = v8::Persistent<Value>();
   }
 }
@@ -4224,7 +4229,7 @@ THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) {
   CompileRun("var obj = { x : 0 }; delete obj.x;");
   context1->Exit();
 
-  context1.Dispose();
+  context1.Dispose(context1->GetIsolate());
 }
 
 
@@ -4977,17 +4982,17 @@ template <typename T> static void USE(T) { }
 
 
 // This test is not intended to be run, just type checked.
-static inline void PersistentHandles() {
+static inline void PersistentHandles(v8::Isolate* isolate) {
   USE(PersistentHandles);
   Local<String> str = v8_str("foo");
-  v8::Persistent<String> p_str = v8::Persistent<String>::New(str);
+  v8::Persistent<String> p_str = v8::Persistent<String>::New(isolate, str);
   USE(p_str);
   Local<Script> scr = Script::Compile(v8_str(""));
-  v8::Persistent<Script> p_scr = v8::Persistent<Script>::New(scr);
+  v8::Persistent<Script> p_scr = v8::Persistent<Script>::New(isolate, scr);
   USE(p_scr);
   Local<ObjectTemplate> templ = ObjectTemplate::New();
   v8::Persistent<ObjectTemplate> p_templ =
-    v8::Persistent<ObjectTemplate>::New(templ);
+    v8::Persistent<ObjectTemplate>::New(isolate, templ);
   USE(p_templ);
 }
 
@@ -5006,7 +5011,7 @@ THREADED_TEST(GlobalObjectTemplate) {
   v8::Persistent<Context> context = Context::New(0, global_template);
   Context::Scope context_scope(context);
   Script::Compile(v8_str("JSNI_Log('LOG')"))->Run();
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
@@ -5475,29 +5480,30 @@ class Snorkel {
 
 class Whammy {
  public:
-  Whammy() {
-    cursor_ = 0;
-  }
-  ~Whammy() {
-    script_.Dispose();
-  }
+  explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
+  ~Whammy() { script_.Dispose(isolate_); }
   v8::Handle<Script> getScript() {
-    if (script_.IsEmpty())
-      script_ = v8::Persistent<Script>::New(v8_compile("({}).blammo"));
+    if (script_.IsEmpty()) {
+      script_ = v8::Persistent<Script>::New(isolate_,
+                                            v8_compile("({}).blammo"));
+    }
     return Local<Script>(*script_);
   }
 
  public:
   static const int kObjectCount = 256;
   int cursor_;
+  v8::Isolate* isolate_;
   v8::Persistent<v8::Object> objects_[kObjectCount];
   v8::Persistent<Script> script_;
 };
 
-static void HandleWeakReference(v8::Persistent<v8::Value> obj, void* data) {
+static void HandleWeakReference(v8::Isolate* isolate,
+                                v8::Persistent<v8::Value> obj,
+                                void* data) {
   Snorkel* snorkel = reinterpret_cast<Snorkel*>(data);
   delete snorkel;
-  obj.ClearWeak();
+  obj.ClearWeak(isolate);
 }
 
 v8::Handle<Value> WhammyPropertyGetter(Local<String> name,
@@ -5508,10 +5514,11 @@ v8::Handle<Value> WhammyPropertyGetter(Local<String> name,
   v8::Persistent<v8::Object> prev = whammy->objects_[whammy->cursor_];
 
   v8::Handle<v8::Object> obj = v8::Object::New();
-  v8::Persistent<v8::Object> global = v8::Persistent<v8::Object>::New(obj);
+  v8::Persistent<v8::Object> global =
+      v8::Persistent<v8::Object>::New(info.GetIsolate(), obj);
   if (!prev.IsEmpty()) {
     prev->Set(v8_str("next"), obj);
-    prev.MakeWeak(new Snorkel(), &HandleWeakReference);
+    prev.MakeWeak(info.GetIsolate(), new Snorkel(), &HandleWeakReference);
     whammy->objects_[whammy->cursor_].Clear();
   }
   whammy->objects_[whammy->cursor_] = global;
@@ -5522,7 +5529,7 @@ v8::Handle<Value> WhammyPropertyGetter(Local<String> name,
 THREADED_TEST(WeakReference) {
   v8::HandleScope handle_scope;
   v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New();
-  Whammy* whammy = new Whammy();
+  Whammy* whammy = new Whammy(v8::Isolate::GetCurrent());
   templ->SetNamedPropertyHandler(WhammyPropertyGetter,
                                  0, 0, 0, 0,
                                  v8::External::New(whammy));
@@ -5545,12 +5552,14 @@ THREADED_TEST(WeakReference) {
   v8::Handle<Value> result = CompileRun(code);
   CHECK_EQ(4.0, result->NumberValue());
   delete whammy;
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
-static void DisposeAndSetFlag(v8::Persistent<v8::Value> obj, void* data) {
-  obj.Dispose();
+static void DisposeAndSetFlag(v8::Isolate* isolate,
+                              v8::Persistent<v8::Value> obj,
+                              void* data) {
+  obj.Dispose(isolate);
   obj.Clear();
   *(reinterpret_cast<bool*>(data)) = true;
 }
@@ -5558,27 +5567,25 @@ static void DisposeAndSetFlag(v8::Persistent<v8::Value> obj, void* data) {
 
 THREADED_TEST(IndependentWeakHandle) {
   v8::Persistent<Context> context = Context::New();
+  v8::Isolate* iso = context->GetIsolate();
   Context::Scope context_scope(context);
 
   v8::Persistent<v8::Object> object_a, object_b;
 
   {
     v8::HandleScope handle_scope;
-    object_a = v8::Persistent<v8::Object>::New(v8::Object::New());
-    object_b = v8::Persistent<v8::Object>::New(v8::Object::New());
+    object_a = v8::Persistent<v8::Object>::New(iso, v8::Object::New());
+    object_b = v8::Persistent<v8::Object>::New(iso, v8::Object::New());
   }
 
-  v8::Isolate* isolate = v8::Isolate::GetCurrent();
   bool object_a_disposed = false;
   bool object_b_disposed = false;
-  object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
-  object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag);
-  CHECK(!object_a.IsIndependent());
-  CHECK(!object_b.IsIndependent(isolate));
-  object_a.MarkIndependent();
-  object_b.MarkIndependent(isolate);
-  CHECK(object_a.IsIndependent());
-  CHECK(object_b.IsIndependent(isolate));
+  object_a.MakeWeak(iso, &object_a_disposed, &DisposeAndSetFlag);
+  object_b.MakeWeak(iso, &object_b_disposed, &DisposeAndSetFlag);
+  CHECK(!object_b.IsIndependent(iso));
+  object_a.MarkIndependent(iso);
+  object_b.MarkIndependent(iso);
+  CHECK(object_b.IsIndependent(iso));
   HEAP->PerformScavenge();
   CHECK(object_a_disposed);
   CHECK(object_b_disposed);
@@ -5595,16 +5602,20 @@ static void InvokeMarkSweep() {
 }
 
 
-static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) {
-  obj.Dispose();
+static void ForceScavenge(v8::Isolate* isolate,
+                          v8::Persistent<v8::Value> obj,
+                          void* data) {
+  obj.Dispose(isolate);
   obj.Clear();
   *(reinterpret_cast<bool*>(data)) = true;
   InvokeScavenge();
 }
 
 
-static void ForceMarkSweep(v8::Persistent<v8::Value> obj, void* data) {
-  obj.Dispose();
+static void ForceMarkSweep(v8::Isolate* isolate,
+                           v8::Persistent<v8::Value> obj,
+                           void* data) {
+  obj.Dispose(isolate);
   obj.Clear();
   *(reinterpret_cast<bool*>(data)) = true;
   InvokeMarkSweep();
@@ -5613,10 +5624,11 @@ static void ForceMarkSweep(v8::Persistent<v8::Value> obj, void* data) {
 
 THREADED_TEST(GCFromWeakCallbacks) {
   v8::Persistent<Context> context = Context::New();
+  v8::Isolate* isolate = context->GetIsolate();
   Context::Scope context_scope(context);
 
   static const int kNumberOfGCTypes = 2;
-  v8::WeakReferenceCallback gc_forcing_callback[kNumberOfGCTypes] =
+  v8::NearDeathCallback gc_forcing_callback[kNumberOfGCTypes] =
       {&ForceScavenge, &ForceMarkSweep};
 
   typedef void (*GCInvoker)();
@@ -5627,11 +5639,11 @@ THREADED_TEST(GCFromWeakCallbacks) {
       v8::Persistent<v8::Object> object;
       {
         v8::HandleScope handle_scope;
-        object = v8::Persistent<v8::Object>::New(v8::Object::New());
+        object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
       }
       bool disposed = false;
-      object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]);
-      object.MarkIndependent();
+      object.MakeWeak(isolate, &disposed, gc_forcing_callback[inner_gc]);
+      object.MarkIndependent(isolate);
       invoke_gc[outer_gc]();
       CHECK(disposed);
     }
@@ -5639,8 +5651,10 @@ THREADED_TEST(GCFromWeakCallbacks) {
 }
 
 
-static void RevivingCallback(v8::Persistent<v8::Value> obj, void* data) {
-  obj.ClearWeak();
+static void RevivingCallback(v8::Isolate* isolate,
+                             v8::Persistent<v8::Value> obj,
+                             void* data) {
+  obj.ClearWeak(isolate);
   *(reinterpret_cast<bool*>(data)) = true;
 }
 
@@ -5648,18 +5662,19 @@ static void RevivingCallback(v8::Persistent<v8::Value> obj, void* data) {
 THREADED_TEST(IndependentHandleRevival) {
   v8::Persistent<Context> context = Context::New();
   Context::Scope context_scope(context);
+  v8::Isolate* isolate = context->GetIsolate();
 
   v8::Persistent<v8::Object> object;
   {
     v8::HandleScope handle_scope;
-    object = v8::Persistent<v8::Object>::New(v8::Object::New());
+    object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
     object->Set(v8_str("x"), v8::Integer::New(1));
     v8::Local<String> y_str = v8_str("y");
     object->Set(y_str, y_str);
   }
   bool revived = false;
-  object.MakeWeak(&revived, &RevivingCallback);
-  object.MarkIndependent();
+  object.MakeWeak(isolate, &revived, &RevivingCallback);
+  object.MarkIndependent(isolate);
   HEAP->PerformScavenge();
   CHECK(revived);
   HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
@@ -6755,10 +6770,10 @@ TEST(SecurityHandler) {
   }
 
   context1->Exit();
-  context1.Dispose();
+  context1.Dispose(context1->GetIsolate());
 
   context0->Exit();
-  context0.Dispose();
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -6802,7 +6817,7 @@ THREADED_TEST(SecurityChecks) {
     CHECK(try_catch.HasCaught());
   }
 
-  env2.Dispose();
+  env2.Dispose(env2->GetIsolate());
 }
 
 
@@ -6871,7 +6886,7 @@ THREADED_TEST(SecurityChecksForPrototypeChain) {
     CHECK(!access_f3->Run()->Equals(v8_num(101)));
     CHECK(access_f3->Run()->IsUndefined());
   }
-  other.Dispose();
+  other.Dispose(other->GetIsolate());
 }
 
 
@@ -6904,7 +6919,7 @@ THREADED_TEST(CrossDomainDelete) {
   CHECK(v->IsNumber());
   CHECK_EQ(3, v->Int32Value());
 
-  env2.Dispose();
+  env2.Dispose(env2->GetIsolate());
 }
 
 
@@ -6939,7 +6954,7 @@ THREADED_TEST(CrossDomainIsPropertyEnumerable) {
     CHECK(result->IsFalse());
   }
 
-  env2.Dispose();
+  env2.Dispose(env2->GetIsolate());
 }
 
 
@@ -6972,7 +6987,7 @@ THREADED_TEST(CrossDomainForIn) {
                    "return true;})()");
     CHECK(result->IsTrue());
   }
-  env2.Dispose();
+  env2.Dispose(env2->GetIsolate());
 }
 
 
@@ -7035,8 +7050,8 @@ TEST(ContextDetachGlobal) {
     CHECK(r->IsUndefined());
   }
 
-  env2.Dispose();
-  env3.Dispose();
+  env2.Dispose(env2->GetIsolate());
+  env3.Dispose(env3->GetIsolate());
 }
 
 
@@ -7114,8 +7129,8 @@ TEST(DetachAndReattachGlobal) {
   CHECK(result->IsInt32());
   CHECK_EQ(42, result->Int32Value());
 
-  env2.Dispose();
-  env3.Dispose();
+  env2.Dispose(env2->GetIsolate());
+  env3.Dispose(env3->GetIsolate());
 }
 
 
@@ -7405,8 +7420,8 @@ TEST(AccessControl) {
 
   context1->Exit();
   context0->Exit();
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -7534,8 +7549,8 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) {
 
   context1->Exit();
   context0->Exit();
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -7618,8 +7633,8 @@ THREADED_TEST(CrossDomainAccessors) {
 
   context1->Exit();
   context0->Exit();
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -7753,8 +7768,8 @@ TEST(AccessControlIC) {
 
   context1->Exit();
   context0->Exit();
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -7828,8 +7843,8 @@ THREADED_TEST(AccessControlFlatten) {
 
   context1->Exit();
   context0->Exit();
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -7920,8 +7935,8 @@ THREADED_TEST(AccessControlInterceptorIC) {
 
   context1->Exit();
   context0->Exit();
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -8811,8 +8826,8 @@ THREADED_TEST(EvalInDetachedGlobal) {
   CHECK(catcher.HasCaught());
   context1->Exit();
 
-  context1.Dispose();
-  context0.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context0.Dispose(context0->GetIsolate());
 }
 
 
@@ -11329,79 +11344,90 @@ TEST(DontLeakGlobalObjects) {
 v8::Persistent<v8::Object> some_object;
 v8::Persistent<v8::Object> bad_handle;
 
-void NewPersistentHandleCallback(v8::Persistent<v8::Value> handle, void*) {
+void NewPersistentHandleCallback(v8::Isolate* isolate,
+                                 v8::Persistent<v8::Value> handle,
+                                 void*) {
   v8::HandleScope scope;
-  bad_handle = v8::Persistent<v8::Object>::New(some_object);
-  handle.Dispose();
+  bad_handle = v8::Persistent<v8::Object>::New(isolate, some_object);
+  handle.Dispose(isolate);
 }
 
 
 THREADED_TEST(NewPersistentHandleFromWeakCallback) {
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
 
   v8::Persistent<v8::Object> handle1, handle2;
   {
     v8::HandleScope scope;
-    some_object = v8::Persistent<v8::Object>::New(v8::Object::New());
-    handle1 = v8::Persistent<v8::Object>::New(v8::Object::New());
-    handle2 = v8::Persistent<v8::Object>::New(v8::Object::New());
+    some_object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+    handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+    handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
   }
   // Note: order is implementation dependent alas: currently
   // global handle nodes are processed by PostGarbageCollectionProcessing
   // in reverse allocation order, so if second allocated handle is deleted,
   // weak callback of the first handle would be able to 'reallocate' it.
-  handle1.MakeWeak(NULL, NewPersistentHandleCallback);
-  handle2.Dispose();
+  handle1.MakeWeak(isolate, NULL, NewPersistentHandleCallback);
+  handle2.Dispose(isolate);
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 }
 
 
 v8::Persistent<v8::Object> to_be_disposed;
 
-void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) {
-  to_be_disposed.Dispose();
+void DisposeAndForceGcCallback(v8::Isolate* isolate,
+                               v8::Persistent<v8::Value> handle,
+                               void*) {
+  to_be_disposed.Dispose(isolate);
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
-  handle.Dispose();
+  handle.Dispose(isolate);
 }
 
 
 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
 
   v8::Persistent<v8::Object> handle1, handle2;
   {
     v8::HandleScope scope;
-    handle1 = v8::Persistent<v8::Object>::New(v8::Object::New());
-    handle2 = v8::Persistent<v8::Object>::New(v8::Object::New());
+    handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+    handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
   }
-  handle1.MakeWeak(NULL, DisposeAndForceGcCallback);
+  handle1.MakeWeak(isolate, NULL, DisposeAndForceGcCallback);
   to_be_disposed = handle2;
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 }
 
-void DisposingCallback(v8::Persistent<v8::Value> handle, void*) {
-  handle.Dispose();
+void DisposingCallback(v8::Isolate* isolate,
+                       v8::Persistent<v8::Value> handle,
+                       void*) {
+  handle.Dispose(isolate);
 }
 
-void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) {
+void HandleCreatingCallback(v8::Isolate* isolate,
+                            v8::Persistent<v8::Value> handle,
+                            void*) {
   v8::HandleScope scope;
-  v8::Persistent<v8::Object>::New(v8::Object::New());
-  handle.Dispose();
+  v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+  handle.Dispose(isolate);
 }
 
 
 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
 
   v8::Persistent<v8::Object> handle1, handle2, handle3;
   {
     v8::HandleScope scope;
-    handle3 = v8::Persistent<v8::Object>::New(v8::Object::New());
-    handle2 = v8::Persistent<v8::Object>::New(v8::Object::New());
-    handle1 = v8::Persistent<v8::Object>::New(v8::Object::New());
+    handle3 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+    handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+    handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
   }
-  handle2.MakeWeak(NULL, DisposingCallback);
-  handle3.MakeWeak(NULL, HandleCreatingCallback);
+  handle2.MakeWeak(isolate, NULL, DisposingCallback);
+  handle3.MakeWeak(isolate, NULL, HandleCreatingCallback);
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 }
 
@@ -11447,7 +11473,7 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
   v8::Handle<String> str(value->ToString());
   CHECK(!str.IsEmpty());
   env->Exit();
-  env.Dispose();
+  env.Dispose(env->GetIsolate());
 }
 
 
@@ -11769,7 +11795,7 @@ THREADED_TEST(DisposeEnteredContext) {
   LocalContext outer;
   { v8::Persistent<v8::Context> inner = v8::Context::New();
     inner->Enter();
-    inner.Dispose();
+    inner.Dispose(inner->GetIsolate());
     inner.Clear();
     inner->Exit();
   }
@@ -11782,12 +11808,14 @@ THREADED_TEST(DisposeEnteredContext) {
 THREADED_TEST(Regress54) {
   v8::HandleScope outer;
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
   static v8::Persistent<v8::ObjectTemplate> templ;
   if (templ.IsEmpty()) {
     v8::HandleScope inner;
     v8::Handle<v8::ObjectTemplate> local = v8::ObjectTemplate::New();
     local->SetInternalFieldCount(1);
-    templ = v8::Persistent<v8::ObjectTemplate>::New(inner.Close(local));
+    templ =
+        v8::Persistent<v8::ObjectTemplate>::New(isolate, inner.Close(local));
   }
   v8::Handle<v8::Object> result = templ->NewInstance();
   CHECK_EQ(1, result->InternalFieldCount());
@@ -12476,8 +12504,8 @@ THREADED_TEST(CrossContextNew) {
   context1->Exit();
 
   // Dispose the contexts to allow them to be garbage collected.
-  context0.Dispose();
-  context1.Dispose();
+  context0.Dispose(context0->GetIsolate());
+  context1.Dispose(context1->GetIsolate());
 }
 
 
@@ -13292,9 +13320,9 @@ TEST(InlinedFunctionAcrossContexts) {
         "ReferenceError: G is not defined");
     ctx2->Exit();
     ctx1->Exit();
-    ctx1.Dispose();
+    ctx1.Dispose(ctx1->GetIsolate());
   }
-  ctx2.Dispose();
+  ctx2.Dispose(ctx2->GetIsolate());
 }
 
 
@@ -13353,9 +13381,9 @@ THREADED_TEST(GetCallingContext) {
   calling_context2->Exit();
 
   // Dispose the contexts to allow them to be garbage collected.
-  calling_context0.Dispose();
-  calling_context1.Dispose();
-  calling_context2.Dispose();
+  calling_context0.Dispose(calling_context0->GetIsolate());
+  calling_context1.Dispose(calling_context1->GetIsolate());
+  calling_context2.Dispose(calling_context2->GetIsolate());
   calling_context0.Clear();
   calling_context1.Clear();
   calling_context2.Clear();
@@ -15077,7 +15105,7 @@ TEST(Regress2107) {
     ctx->Enter();
     CreateGarbageInOldSpace();
     ctx->Exit();
-    ctx.Dispose();
+    ctx.Dispose(ctx->GetIsolate());
     v8::V8::ContextDisposedNotification();
     v8::V8::IdleNotification(kLongIdlePauseInMs);
   }
@@ -15429,7 +15457,7 @@ TEST(Regress528) {
     CompileRun(source_simple);
     context->Exit();
   }
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
   v8::V8::ContextDisposedNotification();
   for (gc_count = 1; gc_count < 10; gc_count++) {
     other_context->Enter();
@@ -15452,7 +15480,7 @@ TEST(Regress528) {
     CompileRun(source_eval);
     context->Exit();
   }
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
   v8::V8::ContextDisposedNotification();
   for (gc_count = 1; gc_count < 10; gc_count++) {
     other_context->Enter();
@@ -15480,7 +15508,7 @@ TEST(Regress528) {
     CHECK_EQ(1, message->GetLineNumber());
     context->Exit();
   }
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
   v8::V8::ContextDisposedNotification();
   for (gc_count = 1; gc_count < 10; gc_count++) {
     other_context->Enter();
@@ -15492,7 +15520,7 @@ TEST(Regress528) {
   CHECK_GE(2, gc_count);
   CHECK_EQ(1, GetGlobalObjectsCount());
 
-  other_context.Dispose();
+  other_context.Dispose(other_context->GetIsolate());
   v8::V8::ContextDisposedNotification();
 }
 
@@ -16282,10 +16310,10 @@ TEST(RunTwoIsolatesOnSingleThread) {
 
   {
     v8::Isolate::Scope iscope(isolate2);
-    context2.Dispose();
+    context2.Dispose(context2->GetIsolate());
   }
 
-  context1.Dispose();
+  context1.Dispose(context1->GetIsolate());
   isolate1->Exit();
 
   v8::V8::SetFatalErrorHandler(StoringErrorCallback);
@@ -16659,7 +16687,7 @@ class Visitor42 : public v8::PersistentHandleVisitor {
       CHECK(value->IsObject());
       v8::Persistent<v8::Object> visited =
           v8::Persistent<v8::Object>::Cast(value);
-      CHECK_EQ(42, visited.WrapperClassId());
+      CHECK_EQ(42, visited.WrapperClassId(v8::Isolate::GetCurrent()));
       CHECK_EQ(object_, visited);
       ++counter_;
     }
@@ -16673,55 +16701,58 @@ class Visitor42 : public v8::PersistentHandleVisitor {
 TEST(PersistentHandleVisitor) {
   v8::HandleScope scope;
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
   v8::Persistent<v8::Object> object =
-      v8::Persistent<v8::Object>::New(v8::Object::New());
-  CHECK_EQ(0, object.WrapperClassId());
-  object.SetWrapperClassId(42);
-  CHECK_EQ(42, object.WrapperClassId());
+      v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+  CHECK_EQ(0, object.WrapperClassId(isolate));
+  object.SetWrapperClassId(isolate, 42);
+  CHECK_EQ(42, object.WrapperClassId(isolate));
 
   Visitor42 visitor(object);
   v8::V8::VisitHandlesWithClassIds(&visitor);
   CHECK_EQ(1, visitor.counter_);
 
-  object.Dispose();
+  object.Dispose(isolate);
 }
 
 
 TEST(WrapperClassId) {
   v8::HandleScope scope;
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
   v8::Persistent<v8::Object> object =
-      v8::Persistent<v8::Object>::New(v8::Object::New());
-  CHECK_EQ(0, object.WrapperClassId());
-  object.SetWrapperClassId(65535);
-  CHECK_EQ(65535, object.WrapperClassId());
-  object.Dispose();
+      v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+  CHECK_EQ(0, object.WrapperClassId(isolate));
+  object.SetWrapperClassId(isolate, 65535);
+  CHECK_EQ(65535, object.WrapperClassId(isolate));
+  object.Dispose(isolate);
 }
 
 
 TEST(PersistentHandleInNewSpaceVisitor) {
   v8::HandleScope scope;
   LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
   v8::Persistent<v8::Object> object1 =
-      v8::Persistent<v8::Object>::New(v8::Object::New());
-  CHECK_EQ(0, object1.WrapperClassId());
-  object1.SetWrapperClassId(42);
-  CHECK_EQ(42, object1.WrapperClassId());
+      v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+  CHECK_EQ(0, object1.WrapperClassId(isolate));
+  object1.SetWrapperClassId(isolate, 42);
+  CHECK_EQ(42, object1.WrapperClassId(isolate));
 
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 
   v8::Persistent<v8::Object> object2 =
-      v8::Persistent<v8::Object>::New(v8::Object::New());
-  CHECK_EQ(0, object2.WrapperClassId());
-  object2.SetWrapperClassId(42);
-  CHECK_EQ(42, object2.WrapperClassId());
+      v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+  CHECK_EQ(0, object2.WrapperClassId(isolate));
+  object2.SetWrapperClassId(isolate, 42);
+  CHECK_EQ(42, object2.WrapperClassId(isolate));
 
   Visitor42 visitor(object2);
-  v8::V8::VisitHandlesForPartialDependence(v8::Isolate::GetCurrent(), &visitor);
+  v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
   CHECK_EQ(1, visitor.counter_);
 
-  object1.Dispose();
-  object2.Dispose();
+  object1.Dispose(isolate);
+  object2.Dispose(isolate);
 }
 
 
@@ -16951,9 +16982,9 @@ THREADED_TEST(CreationContext) {
     CheckContextId(instance2, 2);
   }
 
-  context1.Dispose();
-  context2.Dispose();
-  context3.Dispose();
+  context1.Dispose(context1->GetIsolate());
+  context2.Dispose(context2->GetIsolate());
+  context3.Dispose(context3->GetIsolate());
 }
 
 
@@ -16971,7 +17002,7 @@ THREADED_TEST(CreationContextOfJsFunction) {
   CHECK(function->CreationContext() == context);
   CheckContextId(function, 1);
 
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
@@ -17347,7 +17378,7 @@ THREADED_TEST(Regress93759) {
   Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
   CHECK(result6->Equals(Undefined()));
 
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
@@ -17475,7 +17506,7 @@ THREADED_TEST(ForeignFunctionReceiver) {
   // Calling with no base.
   TestReceiver(o, context->Global(), "(1,func)()");
 
-  foreign_context.Dispose();
+  foreign_context.Dispose(foreign_context->GetIsolate());
 }
 
 
index 1e4261c..deabe7f 100644 (file)
@@ -137,7 +137,7 @@ class DebugLocalContext {
   }
   inline ~DebugLocalContext() {
     context_->Exit();
-    context_.Dispose();
+    context_.Dispose(context_->GetIsolate());
   }
   inline v8::Context* operator->() { return *context_; }
   inline v8::Context* operator*() { return *context_; }
@@ -4231,7 +4231,7 @@ TEST(NoBreakWhenBootstrapping) {
     const char* extension_names[] = { "simpletest" };
     v8::ExtensionConfiguration extensions(1, extension_names);
     v8::Persistent<v8::Context> context = v8::Context::New(&extensions);
-    context.Dispose();
+    context.Dispose(context->GetIsolate());
   }
   // Check that no DebugBreak events occured during the context creation.
   CHECK_EQ(0, break_point_hit_count);
@@ -7069,7 +7069,7 @@ TEST(DebugEventContext) {
   expected_context = v8::Context::New();
   v8::Context::Scope context_scope(expected_context);
   v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run();
-  expected_context.Dispose();
+  expected_context.Dispose(expected_context->GetIsolate());
   expected_context.Clear();
   v8::Debug::SetDebugEventListener(NULL);
   expected_context_data = v8::Handle<v8::Value>();
index d379fbb..efdc394 100644 (file)
@@ -53,7 +53,7 @@ class DeclarationContext {
   virtual ~DeclarationContext() {
     if (is_initialized_) {
       context_->Exit();
-      context_.Dispose();
+      context_.Dispose(context_->GetIsolate());
     }
   }
 
@@ -701,7 +701,7 @@ class SimpleContext {
 
   virtual ~SimpleContext() {
     context_->Exit();
-    context_.Dispose();
+    context_.Dispose(context_->GetIsolate());
   }
 
   void Check(const char* source,
index 29fb1c1..a8a45b7 100644 (file)
@@ -1045,20 +1045,21 @@ static const v8::HeapGraphNode* GetNode(const v8::HeapGraphNode* parent,
 TEST(HeapSnapshotRetainedObjectInfo) {
   v8::HandleScope scope;
   LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
 
   v8::HeapProfiler::DefineWrapperClass(
       1, TestRetainedObjectInfo::WrapperInfoCallback);
   v8::HeapProfiler::DefineWrapperClass(
       2, TestRetainedObjectInfo::WrapperInfoCallback);
   v8::Persistent<v8::String> p_AAA =
-      v8::Persistent<v8::String>::New(v8_str("AAA"));
-  p_AAA.SetWrapperClassId(1);
+      v8::Persistent<v8::String>::New(isolate, v8_str("AAA"));
+  p_AAA.SetWrapperClassId(isolate, 1);
   v8::Persistent<v8::String> p_BBB =
-      v8::Persistent<v8::String>::New(v8_str("BBB"));
-  p_BBB.SetWrapperClassId(1);
+      v8::Persistent<v8::String>::New(isolate, v8_str("BBB"));
+  p_BBB.SetWrapperClassId(isolate, 1);
   v8::Persistent<v8::String> p_CCC =
-      v8::Persistent<v8::String>::New(v8_str("CCC"));
-  p_CCC.SetWrapperClassId(2);
+      v8::Persistent<v8::String>::New(isolate, v8_str("CCC"));
+  p_CCC.SetWrapperClassId(isolate, 2);
   CHECK_EQ(0, TestRetainedObjectInfo::instances.length());
   const v8::HeapSnapshot* snapshot =
       v8::HeapProfiler::TakeSnapshot(v8_str("retained"));
@@ -1107,8 +1108,9 @@ class GraphWithImplicitRefs {
   explicit GraphWithImplicitRefs(LocalContext* env) {
     CHECK_EQ(NULL, instance_);
     instance_ = this;
+    v8::Isolate* isolate = (*env)->GetIsolate();
     for (int i = 0; i < kObjectsCount; i++) {
-      objects_[i] = v8::Persistent<v8::Object>::New(v8::Object::New());
+      objects_[i] = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
     }
     (*env)->Global()->Set(v8_str("root_object"), objects_[0]);
   }
@@ -1478,8 +1480,10 @@ bool HasWeakGlobalHandle() {
 }
 
 
-static void PersistentHandleCallback(v8::Persistent<v8::Value> handle, void*) {
-  handle.Dispose();
+static void PersistentHandleCallback(v8::Isolate* isolate,
+                                     v8::Persistent<v8::Value> handle,
+                                     void*) {
+  handle.Dispose(isolate);
 }
 
 
@@ -1490,8 +1494,8 @@ TEST(WeakGlobalHandle) {
   CHECK(!HasWeakGlobalHandle());
 
   v8::Persistent<v8::Object> handle =
-      v8::Persistent<v8::Object>::New(v8::Object::New());
-  handle.MakeWeak(NULL, PersistentHandleCallback);
+      v8::Persistent<v8::Object>::New(env->GetIsolate(), v8::Object::New());
+  handle.MakeWeak(env->GetIsolate(), NULL, PersistentHandleCallback);
 
   CHECK(HasWeakGlobalHandle());
 }
@@ -1564,6 +1568,7 @@ TEST(NoDebugObjectInSnapshot) {
 TEST(PersistentHandleCount) {
   v8::HandleScope scope;
   LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
 
   // V8 also uses global handles internally, so we can't test for an absolute
   // number.
@@ -1571,26 +1576,26 @@ TEST(PersistentHandleCount) {
 
   // Create some persistent handles.
   v8::Persistent<v8::String> p_AAA =
-      v8::Persistent<v8::String>::New(v8_str("AAA"));
+      v8::Persistent<v8::String>::New(isolate, v8_str("AAA"));
   CHECK_EQ(global_handle_count + 1,
            v8::HeapProfiler::GetPersistentHandleCount());
   v8::Persistent<v8::String> p_BBB =
-      v8::Persistent<v8::String>::New(v8_str("BBB"));
+      v8::Persistent<v8::String>::New(isolate, v8_str("BBB"));
   CHECK_EQ(global_handle_count + 2,
            v8::HeapProfiler::GetPersistentHandleCount());
   v8::Persistent<v8::String> p_CCC =
-      v8::Persistent<v8::String>::New(v8_str("CCC"));
+      v8::Persistent<v8::String>::New(isolate, v8_str("CCC"));
   CHECK_EQ(global_handle_count + 3,
            v8::HeapProfiler::GetPersistentHandleCount());
 
   // Dipose the persistent handles in a different order.
-  p_AAA.Dispose();
+  p_AAA.Dispose(env->GetIsolate());
   CHECK_EQ(global_handle_count + 2,
            v8::HeapProfiler::GetPersistentHandleCount());
-  p_CCC.Dispose();
+  p_CCC.Dispose(env->GetIsolate());
   CHECK_EQ(global_handle_count + 1,
            v8::HeapProfiler::GetPersistentHandleCount());
-  p_BBB.Dispose();
+  p_BBB.Dispose(env->GetIsolate());
   CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount());
 }
 
index 88ff1d4..c9b64ae 100644 (file)
@@ -358,10 +358,11 @@ TEST(GlobalHandles) {
 
 static bool WeakPointerCleared = false;
 
-static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle,
+static void TestWeakGlobalHandleCallback(v8::Isolate* isolate,
+                                         v8::Persistent<v8::Value> handle,
                                          void* id) {
   if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true;
-  handle.Dispose();
+  handle.Dispose(isolate);
 }
 
 
@@ -386,6 +387,7 @@ TEST(WeakGlobalHandlesScavenge) {
 
   global_handles->MakeWeak(h2.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &TestWeakGlobalHandleCallback);
 
   // Scavenge treats weak pointers as normal roots.
@@ -429,6 +431,7 @@ TEST(WeakGlobalHandlesMark) {
 
   global_handles->MakeWeak(h2.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &TestWeakGlobalHandleCallback);
   CHECK(!GlobalHandles::IsNearDeath(h1.location()));
   CHECK(!GlobalHandles::IsNearDeath(h2.location()));
@@ -462,6 +465,7 @@ TEST(DeleteWeakGlobalHandle) {
 
   global_handles->MakeWeak(h.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &TestWeakGlobalHandleCallback);
 
   // Scanvenge does not recognize weak reference.
@@ -1314,7 +1318,7 @@ TEST(TestInternalWeakLists) {
 
   // Dispose the native contexts one by one.
   for (int i = 0; i < kNumTestContexts; i++) {
-    ctx[i].Dispose();
+    ctx[i].Dispose(ctx[i]->GetIsolate());
     ctx[i].Clear();
 
     // Scavenge treats these references as strong.
@@ -1617,12 +1621,12 @@ TEST(LeakNativeContextViaMap) {
     ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
     ctx2->Exit();
     ctx1->Exit();
-    ctx1.Dispose();
+    ctx1.Dispose(ctx1->GetIsolate());
     v8::V8::ContextDisposedNotification();
   }
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
-  ctx2.Dispose();
+  ctx2.Dispose(ctx2->GetIsolate());
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(0, NumberOfGlobalObjects());
 }
@@ -1655,12 +1659,12 @@ TEST(LeakNativeContextViaFunction) {
     ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
     ctx2->Exit();
     ctx1->Exit();
-    ctx1.Dispose();
+    ctx1.Dispose(ctx1->GetIsolate());
     v8::V8::ContextDisposedNotification();
   }
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
-  ctx2.Dispose();
+  ctx2.Dispose(ctx2->GetIsolate());
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(0, NumberOfGlobalObjects());
 }
@@ -1691,12 +1695,12 @@ TEST(LeakNativeContextViaMapKeyed) {
     ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
     ctx2->Exit();
     ctx1->Exit();
-    ctx1.Dispose();
+    ctx1.Dispose(ctx1->GetIsolate());
     v8::V8::ContextDisposedNotification();
   }
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
-  ctx2.Dispose();
+  ctx2.Dispose(ctx2->GetIsolate());
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(0, NumberOfGlobalObjects());
 }
@@ -1731,12 +1735,12 @@ TEST(LeakNativeContextViaMapProto) {
     ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
     ctx2->Exit();
     ctx1->Exit();
-    ctx1.Dispose();
+    ctx1.Dispose(ctx1->GetIsolate());
     v8::V8::ContextDisposedNotification();
   }
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
-  ctx2.Dispose();
+  ctx2.Dispose(ctx2->GetIsolate());
   HEAP->CollectAllAvailableGarbage();
   CHECK_EQ(0, NumberOfGlobalObjects());
 }
index 3e93110..b0f2b62 100644 (file)
@@ -649,7 +649,7 @@ TEST(Regress1433) {
       v8::Handle<Script> script = v8::Script::Compile(source);
       v8::Handle<Value> result = script->Run();
       v8::String::AsciiValue ascii(result);
-      context.Dispose();
+      context.Dispose(isolate);
     }
     isolate->Dispose();
   }
@@ -677,7 +677,7 @@ class IsolateGenesisThread : public JoinableThread {
       v8::ExtensionConfiguration extensions(count_, extension_names_);
       v8::Persistent<v8::Context> context = v8::Context::New(&extensions);
       CHECK(i::Isolate::Current()->has_installed_extensions());
-      context.Dispose();
+      context.Dispose(isolate);
     }
     isolate->Dispose();
   }
index 892a542..9883bfa 100644 (file)
@@ -370,7 +370,8 @@ TEST(LogCallbacks) {
   ScopedLoggerInitializer initialize_logger(false);
 
   v8::Persistent<v8::FunctionTemplate> obj =
-      v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+      v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(),
+                                                v8::FunctionTemplate::New());
   obj->SetClassName(v8_str("Obj"));
   v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate();
   v8::Local<v8::Signature> signature = v8::Signature::New(obj);
@@ -397,7 +398,7 @@ TEST(LogCallbacks) {
 
   CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
 
-  obj.Dispose();
+  obj.Dispose(v8::Isolate::GetCurrent());
 }
 
 
@@ -420,7 +421,8 @@ TEST(LogAccessorCallbacks) {
   ScopedLoggerInitializer initialize_logger(false);
 
   v8::Persistent<v8::FunctionTemplate> obj =
-      v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+      v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(),
+                                                v8::FunctionTemplate::New());
   obj->SetClassName(v8_str("Obj"));
   v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate();
   inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter);
@@ -454,7 +456,7 @@ TEST(LogAccessorCallbacks) {
   CHECK_NE(NULL,
            StrNStr(log.start(), prop2_getter_record.start(), log.length()));
 
-  obj.Dispose();
+  obj.Dispose(v8::Isolate::GetCurrent());
 }
 
 
index 682b327..949e413 100644 (file)
@@ -304,10 +304,12 @@ TEST(GCCallback) {
 
 
 static int NumberOfWeakCalls = 0;
-static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) {
+static void WeakPointerCallback(v8::Isolate* isolate,
+                                v8::Persistent<v8::Value> handle,
+                                void* id) {
   ASSERT(id == reinterpret_cast<void*>(1234));
   NumberOfWeakCalls++;
-  handle.Dispose();
+  handle.Dispose(isolate);
 }
 
 TEST(ObjectGroups) {
@@ -326,12 +328,15 @@ TEST(ObjectGroups) {
       global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
   global_handles->MakeWeak(g1s1.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
   global_handles->MakeWeak(g1s2.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
   global_handles->MakeWeak(g1c1.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
 
   Handle<Object> g2s1 =
@@ -342,12 +347,15 @@ TEST(ObjectGroups) {
     global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked());
   global_handles->MakeWeak(g2s1.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
   global_handles->MakeWeak(g2s2.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
   global_handles->MakeWeak(g2c1.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
 
   Handle<Object> root = global_handles->Create(*g1s1);  // make a root.
@@ -377,6 +385,7 @@ TEST(ObjectGroups) {
   // Weaken the root.
   global_handles->MakeWeak(root.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
   // But make children strong roots---all the objects (except for children)
   // should be collectable now.
@@ -405,9 +414,11 @@ TEST(ObjectGroups) {
   // And now make children weak again and collect them.
   global_handles->MakeWeak(g1c1.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
   global_handles->MakeWeak(g2c1.location(),
                            reinterpret_cast<void*>(1234),
+                           NULL,
                            &WeakPointerCallback);
 
   HEAP->CollectGarbage(OLD_POINTER_SPACE);
index ac605a8..083bbcc 100644 (file)
@@ -714,7 +714,7 @@ class ContextInitializer {
   }
   ~ContextInitializer() {
     env_->Exit();
-    env_.Dispose();
+    env_.Dispose(env_->GetIsolate());
   }
  private:
   v8::Persistent<v8::Context> env_;
index b647090..888c842 100644 (file)
@@ -251,7 +251,7 @@ static void Serialize() {
   // will clear the pending fixups array, which would otherwise contain GC roots
   // that would confuse the serialization/deserialization process.
   v8::Persistent<v8::Context> env = v8::Context::New();
-  env.Dispose();
+  env.Dispose(env->GetIsolate());
   WriteToFile(FLAG_testing_serialization_file);
 }
 
@@ -390,7 +390,7 @@ TEST(PartialSerialization) {
     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
 
     env->Exit();
-    env.Dispose();
+    env.Dispose(env->GetIsolate());
 
     FileByteSink startup_sink(startup_name.start());
     StartupSerializer startup_serializer(&startup_sink);
@@ -518,7 +518,7 @@ TEST(ContextSerialization) {
 
     Object* raw_context = *(v8::Utils::OpenHandle(*env));
 
-    env.Dispose();
+    env.Dispose(env->GetIsolate());
 
     FileByteSink startup_sink(startup_name.start());
     StartupSerializer startup_serializer(&startup_sink);
index 7712a2c..b249c7a 100644 (file)
@@ -134,7 +134,7 @@ TEST(TerminateOnlyV8ThreadFromThreadItself) {
   // Test that we can run the code again after thread termination.
   CHECK(!v8::V8::IsExecutionTerminating());
   v8::Script::Compile(source)->Run();
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
@@ -154,7 +154,7 @@ TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
   CHECK(!v8::V8::IsExecutionTerminating());
   // Test that we can run the code again after thread termination.
   v8::Script::Compile(source)->Run();
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
@@ -194,7 +194,7 @@ TEST(TerminateOnlyV8ThreadFromOtherThread) {
   thread.Join();
   delete semaphore;
   semaphore = NULL;
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 
@@ -214,7 +214,7 @@ class LoopingThread : public v8::internal::Thread {
     v8::Handle<v8::String> source =
         v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
     v8::Script::Compile(source)->Run();
-    context.Dispose();
+    context.Dispose(context->GetIsolate());
   }
 
   int GetV8ThreadId() { return v8_thread_id_; }
@@ -326,7 +326,7 @@ TEST(TerminateLoadICException) {
   CHECK(!v8::V8::IsExecutionTerminating());
   call_count = 0;
   v8::Script::Compile(source)->Run();
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
 
 v8::Handle<v8::Value> ReenterAfterTermination(const v8::Arguments& args) {
@@ -370,5 +370,5 @@ TEST(TerminateAndReenterFromThreadItself) {
   // Check we can run JS again after termination.
   CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }"
                                             "f()"))->Run()->IsTrue());
-  context.Dispose();
+  context.Dispose(context->GetIsolate());
 }
index 7c98c57..edbd94c 100644 (file)
@@ -57,10 +57,12 @@ static void PutIntoWeakMap(Handle<JSWeakMap> weakmap,
 }
 
 static int NumberOfWeakCalls = 0;
-static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) {
+static void WeakPointerCallback(v8::Isolate* isolate,
+                                v8::Persistent<v8::Value> handle,
+                                void* id) {
   ASSERT(id == reinterpret_cast<void*>(1234));
   NumberOfWeakCalls++;
-  handle.Dispose();
+  handle.Dispose(isolate);
 }
 
 
@@ -102,6 +104,7 @@ TEST(Weakness) {
     v8::HandleScope scope;
     global_handles->MakeWeak(key.location(),
                              reinterpret_cast<void*>(1234),
+                             NULL,
                              &WeakPointerCallback);
   }
   CHECK(global_handles->IsWeak(key.location()));