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 ---
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.
* 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;
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;
*/
V8_INLINE(explicit Unlocker(Isolate* isolate)) { Initialize(isolate); }
- /**
- * Deprecated. Use Isolate version instead.
- */
+ /** Deprecated. Use Isolate version instead. */
V8_DEPRECATED(Unlocker());
~Unlocker();
*/
V8_INLINE(explicit Locker(Isolate* isolate)) { Initialize(isolate); }
- /**
- * Deprecated. Use Isolate version instead.
- */
+ /** Deprecated. Use Isolate version instead. */
V8_DEPRECATED(Locker());
~Locker();
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;
*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;
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);
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());
}
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());
}
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>
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>
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;
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);
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);
// 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_;
// 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;
// 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);
}
// 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_;
// 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_;
result = RunMain(argc, argv);
if (run_shell) RunShell(context);
context->Exit();
- context.Dispose();
+ context.Dispose(context->GetIsolate());
}
v8::V8::Dispose();
return result;
}
-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");
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...
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(
}
-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);
}
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(
Shell::ExecuteString(str, String::New(filename), false, false);
}
- thread_context.Dispose();
+ thread_context.Dispose(thread_context->GetIsolate());
ptr = next_line;
}
}
Context::Scope cscope(context);
Execute(isolate);
}
- context.Dispose();
+ context.Dispose(isolate);
if (Shell::options.send_idle_notification) {
const int kLongIdlePauseInMs = 1000;
V8::ContextDisposedNotification();
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();
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);
};
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();
}
}
-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 =
script_cache->collected_scripts_.Add(id);
// Clear the weak handle.
- obj.Dispose();
+ obj.Dispose(isolate);
obj.Clear();
}
}
-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
// 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);
}
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_;
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
}
-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_;
code_ = Handle<Code>::cast(global_handles->Create(code));
global_handles->MakeWeak(reinterpret_cast<Object**>(code_.location()),
this,
+ NULL,
Deoptimizer::HandleWeakDeoptimizedCode);
}
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.
}
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
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
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);
}
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) {
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) {
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;
}
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.
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.
}
-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);
}
// 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);
// 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();
}
// 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()));
// 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.
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);
}
-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);
}
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);
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_; }
private:
v8::Persistent<v8::Context> context_;
+ v8::Isolate* isolate_;
};
CHECK(!env->InContext());
CHECK(env->GetIsolate() == v8::Isolate::GetCurrent());
- env.Dispose();
+ env.Dispose(env->GetIsolate());
}
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);
}
};
-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;
{
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));
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.
{
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());
THREADED_TEST(ApiObjectGroupsCycle) {
HandleScope scope;
LocalContext env;
+ v8::Isolate* iso = env->GetIsolate();
WeakCallCounter counter(1234);
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
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
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.
{
i::FLAG_gc_global = false;
HandleScope scope;
LocalContext env;
+ v8::Isolate* iso = env->GetIsolate();
WeakCallCounter counter(1234);
{
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 };
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.
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")));
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);
}
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);
}
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), xValue);
- xValue.Dispose();
+ xValue.Dispose(context->GetIsolate());
xValue = v8::Persistent<Value>();
}
}
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), xValue);
- xValue.Dispose();
+ xValue.Dispose(context->GetIsolate());
xValue = v8::Persistent<Value>();
}
}
CompileRun("var obj = { x : 0 }; delete obj.x;");
context1->Exit();
- context1.Dispose();
+ context1.Dispose(context1->GetIsolate());
}
// 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);
}
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());
}
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,
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;
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));
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;
}
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);
}
-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();
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)();
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);
}
}
-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;
}
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);
}
context1->Exit();
- context1.Dispose();
+ context1.Dispose(context1->GetIsolate());
context0->Exit();
- context0.Dispose();
+ context0.Dispose(context0->GetIsolate());
}
CHECK(try_catch.HasCaught());
}
- env2.Dispose();
+ env2.Dispose(env2->GetIsolate());
}
CHECK(!access_f3->Run()->Equals(v8_num(101)));
CHECK(access_f3->Run()->IsUndefined());
}
- other.Dispose();
+ other.Dispose(other->GetIsolate());
}
CHECK(v->IsNumber());
CHECK_EQ(3, v->Int32Value());
- env2.Dispose();
+ env2.Dispose(env2->GetIsolate());
}
CHECK(result->IsFalse());
}
- env2.Dispose();
+ env2.Dispose(env2->GetIsolate());
}
"return true;})()");
CHECK(result->IsTrue());
}
- env2.Dispose();
+ env2.Dispose(env2->GetIsolate());
}
CHECK(r->IsUndefined());
}
- env2.Dispose();
- env3.Dispose();
+ env2.Dispose(env2->GetIsolate());
+ env3.Dispose(env3->GetIsolate());
}
CHECK(result->IsInt32());
CHECK_EQ(42, result->Int32Value());
- env2.Dispose();
- env3.Dispose();
+ env2.Dispose(env2->GetIsolate());
+ env3.Dispose(env3->GetIsolate());
}
context1->Exit();
context0->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
context1->Exit();
context0->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
context1->Exit();
context0->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
context1->Exit();
context0->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
context1->Exit();
context0->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
context1->Exit();
context0->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
CHECK(catcher.HasCaught());
context1->Exit();
- context1.Dispose();
- context0.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context0.Dispose(context0->GetIsolate());
}
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);
}
v8::Handle<String> str(value->ToString());
CHECK(!str.IsEmpty());
env->Exit();
- env.Dispose();
+ env.Dispose(env->GetIsolate());
}
LocalContext outer;
{ v8::Persistent<v8::Context> inner = v8::Context::New();
inner->Enter();
- inner.Dispose();
+ inner.Dispose(inner->GetIsolate());
inner.Clear();
inner->Exit();
}
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());
context1->Exit();
// Dispose the contexts to allow them to be garbage collected.
- context0.Dispose();
- context1.Dispose();
+ context0.Dispose(context0->GetIsolate());
+ context1.Dispose(context1->GetIsolate());
}
"ReferenceError: G is not defined");
ctx2->Exit();
ctx1->Exit();
- ctx1.Dispose();
+ ctx1.Dispose(ctx1->GetIsolate());
}
- ctx2.Dispose();
+ ctx2.Dispose(ctx2->GetIsolate());
}
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();
ctx->Enter();
CreateGarbageInOldSpace();
ctx->Exit();
- ctx.Dispose();
+ ctx.Dispose(ctx->GetIsolate());
v8::V8::ContextDisposedNotification();
v8::V8::IdleNotification(kLongIdlePauseInMs);
}
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();
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();
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();
CHECK_GE(2, gc_count);
CHECK_EQ(1, GetGlobalObjectsCount());
- other_context.Dispose();
+ other_context.Dispose(other_context->GetIsolate());
v8::V8::ContextDisposedNotification();
}
{
v8::Isolate::Scope iscope(isolate2);
- context2.Dispose();
+ context2.Dispose(context2->GetIsolate());
}
- context1.Dispose();
+ context1.Dispose(context1->GetIsolate());
isolate1->Exit();
v8::V8::SetFatalErrorHandler(StoringErrorCallback);
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_;
}
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);
}
CheckContextId(instance2, 2);
}
- context1.Dispose();
- context2.Dispose();
- context3.Dispose();
+ context1.Dispose(context1->GetIsolate());
+ context2.Dispose(context2->GetIsolate());
+ context3.Dispose(context3->GetIsolate());
}
CHECK(function->CreationContext() == context);
CheckContextId(function, 1);
- context.Dispose();
+ context.Dispose(context->GetIsolate());
}
Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
CHECK(result6->Equals(Undefined()));
- context.Dispose();
+ context.Dispose(context->GetIsolate());
}
// Calling with no base.
TestReceiver(o, context->Global(), "(1,func)()");
- foreign_context.Dispose();
+ foreign_context.Dispose(foreign_context->GetIsolate());
}
}
inline ~DebugLocalContext() {
context_->Exit();
- context_.Dispose();
+ context_.Dispose(context_->GetIsolate());
}
inline v8::Context* operator->() { return *context_; }
inline v8::Context* operator*() { return *context_; }
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);
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>();
virtual ~DeclarationContext() {
if (is_initialized_) {
context_->Exit();
- context_.Dispose();
+ context_.Dispose(context_->GetIsolate());
}
}
virtual ~SimpleContext() {
context_->Exit();
- context_.Dispose();
+ context_.Dispose(context_->GetIsolate());
}
void Check(const char* source,
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"));
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]);
}
}
-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);
}
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());
}
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.
// 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());
}
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);
}
global_handles->MakeWeak(h2.location(),
reinterpret_cast<void*>(1234),
+ NULL,
&TestWeakGlobalHandleCallback);
// Scavenge treats weak pointers as normal roots.
global_handles->MakeWeak(h2.location(),
reinterpret_cast<void*>(1234),
+ NULL,
&TestWeakGlobalHandleCallback);
CHECK(!GlobalHandles::IsNearDeath(h1.location()));
CHECK(!GlobalHandles::IsNearDeath(h2.location()));
global_handles->MakeWeak(h.location(),
reinterpret_cast<void*>(1234),
+ NULL,
&TestWeakGlobalHandleCallback);
// Scanvenge does not recognize weak reference.
// 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.
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());
}
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());
}
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());
}
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());
}
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();
}
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();
}
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);
CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
- obj.Dispose();
+ obj.Dispose(v8::Isolate::GetCurrent());
}
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);
CHECK_NE(NULL,
StrNStr(log.start(), prop2_getter_record.start(), log.length()));
- obj.Dispose();
+ obj.Dispose(v8::Isolate::GetCurrent());
}
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) {
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 =
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.
// 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.
// 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);
}
~ContextInitializer() {
env_->Exit();
- env_.Dispose();
+ env_.Dispose(env_->GetIsolate());
}
private:
v8::Persistent<v8::Context> env_;
// 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);
}
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);
Object* raw_context = *(v8::Utils::OpenHandle(*env));
- env.Dispose();
+ env.Dispose(env->GetIsolate());
FileByteSink startup_sink(startup_name.start());
StartupSerializer startup_serializer(&startup_sink);
// 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());
}
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());
}
thread.Join();
delete semaphore;
semaphore = NULL;
- context.Dispose();
+ context.Dispose(context->GetIsolate());
}
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_; }
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) {
// 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());
}
}
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);
}
v8::HandleScope scope;
global_handles->MakeWeak(key.location(),
reinterpret_cast<void*>(1234),
+ NULL,
&WeakPointerCallback);
}
CHECK(global_handles->IsWeak(key.location()));