remove phantom naming from the api
since the old style weakness is slated for removal, we might as well reuse the name to limit confusion. additionally I simplified the callback type to a enum to either get internal field values or not this should be a non-breaking change with the exception of PhantomPersistentValueMap, which is unused. R=jochen@chromium.org, erikcorry@chromium.org BUG= Review URL: https://codereview.chromium.org/989153003 Cr-Commit-Position: refs/heads/master@{#27084}
This commit is contained in:
parent
18bf4c27b5
commit
60c1ad026d
@ -12,7 +12,7 @@
|
||||
/**
|
||||
* Support for Persistent containers.
|
||||
*
|
||||
* C++11 embedders can use STL containers with UniquePersistent values,
|
||||
* C++11 embedders can use STL containers with Global values,
|
||||
* but pre-C++11 does not support the required move semantic and hence
|
||||
* may want these container classes.
|
||||
*/
|
||||
@ -22,7 +22,10 @@ typedef uintptr_t PersistentContainerValue;
|
||||
static const uintptr_t kPersistentContainerNotFound = 0;
|
||||
enum PersistentContainerCallbackType {
|
||||
kNotWeak,
|
||||
kWeak
|
||||
// These correspond to v8::WeakCallbackType
|
||||
kWeakWithParameter,
|
||||
kWeakWithInternalFields,
|
||||
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
|
||||
};
|
||||
|
||||
|
||||
@ -101,12 +104,12 @@ class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
|
||||
return K();
|
||||
}
|
||||
static void DisposeCallbackData(WeakCallbackDataType* data) { }
|
||||
static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { }
|
||||
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
class DefaultPhantomPersistentValueMapTraits : public StdMapTraits<K, V> {
|
||||
class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
|
||||
private:
|
||||
template <typename T>
|
||||
struct RemovePointer;
|
||||
@ -114,25 +117,23 @@ class DefaultPhantomPersistentValueMapTraits : public StdMapTraits<K, V> {
|
||||
public:
|
||||
// Weak callback & friends:
|
||||
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
|
||||
typedef PersistentValueMap<
|
||||
K, V, DefaultPhantomPersistentValueMapTraits<K, V> > MapType;
|
||||
typedef void PhantomCallbackDataType;
|
||||
typedef PersistentValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
|
||||
typedef void WeakCallbackInfoType;
|
||||
|
||||
static PhantomCallbackDataType* PhantomCallbackParameter(MapType* map,
|
||||
const K& key,
|
||||
Local<V> value) {
|
||||
return NULL;
|
||||
static WeakCallbackInfoType* WeakCallbackParameter(MapType* map, const K& key,
|
||||
Local<V> value) {
|
||||
return nullptr;
|
||||
}
|
||||
static MapType* MapFromPhantomCallbackData(
|
||||
const PhantomCallbackData<PhantomCallbackDataType>& data) {
|
||||
return NULL;
|
||||
static MapType* MapFromWeakCallbackInfo(
|
||||
const WeakCallbackInfo<WeakCallbackInfoType>& data) {
|
||||
return nullptr;
|
||||
}
|
||||
static K KeyFromPhantomCallbackData(
|
||||
const PhantomCallbackData<PhantomCallbackDataType>& data) {
|
||||
static K KeyFromWeakCallbackInfo(
|
||||
const WeakCallbackInfo<WeakCallbackInfoType>& data) {
|
||||
return K();
|
||||
}
|
||||
static void DisposeCallbackData(PhantomCallbackDataType* data) {}
|
||||
static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) {}
|
||||
static void DisposeCallbackData(WeakCallbackInfoType* data) {}
|
||||
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
@ -143,8 +144,8 @@ class DefaultPhantomPersistentValueMapTraits : public StdMapTraits<K, V> {
|
||||
|
||||
|
||||
/**
|
||||
* A map wrapper that allows using UniquePersistent as a mapped value.
|
||||
* C++11 embedders don't need this class, as they can use UniquePersistent
|
||||
* A map wrapper that allows using Global as a mapped value.
|
||||
* C++11 embedders don't need this class, as they can use Global
|
||||
* directly in std containers.
|
||||
*
|
||||
* The map relies on a backing map, whose type and accessors are described
|
||||
@ -203,7 +204,7 @@ class PersistentValueMapBase {
|
||||
/**
|
||||
* Return value for key and remove it from the map.
|
||||
*/
|
||||
UniquePersistent<V> Remove(const K& key) {
|
||||
Global<V> Remove(const K& key) {
|
||||
return Release(Traits::Remove(&impl_, key)).Pass();
|
||||
}
|
||||
|
||||
@ -255,7 +256,7 @@ class PersistentValueMapBase {
|
||||
private:
|
||||
friend class PersistentValueMapBase;
|
||||
friend class PersistentValueMap<K, V, Traits>;
|
||||
friend class PhantomPersistentValueMap<K, V, Traits>;
|
||||
friend class GlobalValueMap<K, V, Traits>;
|
||||
|
||||
explicit PersistentValueReference(PersistentContainerValue value)
|
||||
: value_(value) { }
|
||||
@ -293,24 +294,23 @@ class PersistentValueMapBase {
|
||||
return reinterpret_cast<V*>(v);
|
||||
}
|
||||
|
||||
static PersistentContainerValue ClearAndLeak(
|
||||
UniquePersistent<V>* persistent) {
|
||||
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
|
||||
V* v = persistent->val_;
|
||||
persistent->val_ = 0;
|
||||
return reinterpret_cast<PersistentContainerValue>(v);
|
||||
}
|
||||
|
||||
static PersistentContainerValue Leak(UniquePersistent<V>* persistent) {
|
||||
static PersistentContainerValue Leak(Global<V>* persistent) {
|
||||
return reinterpret_cast<PersistentContainerValue>(persistent->val_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a container value as UniquePersistent and make sure the weak
|
||||
* Return a container value as Global and make sure the weak
|
||||
* callback is properly disposed of. All remove functionality should go
|
||||
* through this.
|
||||
*/
|
||||
static UniquePersistent<V> Release(PersistentContainerValue v) {
|
||||
UniquePersistent<V> p;
|
||||
static Global<V> Release(PersistentContainerValue v) {
|
||||
Global<V> p;
|
||||
p.val_ = FromVal(v);
|
||||
if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
|
||||
Traits::DisposeCallbackData(
|
||||
@ -351,17 +351,17 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
/**
|
||||
* Put value into map. Depending on Traits::kIsWeak, the value will be held
|
||||
* by the map strongly or weakly.
|
||||
* Returns old value as UniquePersistent.
|
||||
* Returns old value as Global.
|
||||
*/
|
||||
UniquePersistent<V> Set(const K& key, Local<V> value) {
|
||||
UniquePersistent<V> persistent(this->isolate(), value);
|
||||
Global<V> Set(const K& key, Local<V> value) {
|
||||
Global<V> persistent(this->isolate(), value);
|
||||
return SetUnique(key, &persistent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put value into map, like Set(const K&, Local<V>).
|
||||
*/
|
||||
UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) {
|
||||
Global<V> Set(const K& key, Global<V> value) {
|
||||
return SetUnique(key, &value);
|
||||
}
|
||||
|
||||
@ -369,7 +369,7 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
* Put the value into the map, and set the 'weak' callback when demanded
|
||||
* by the Traits class.
|
||||
*/
|
||||
UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
|
||||
Global<V> SetUnique(const K& key, Global<V>* persistent) {
|
||||
if (Traits::kCallbackType != kNotWeak) {
|
||||
Local<V> value(Local<V>::New(this->isolate(), *persistent));
|
||||
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
|
||||
@ -384,8 +384,8 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
* Put a value into the map and update the reference.
|
||||
* Restrictions of GetReference apply here as well.
|
||||
*/
|
||||
UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
|
||||
PersistentValueReference* reference) {
|
||||
Global<V> Set(const K& key, Global<V> value,
|
||||
PersistentValueReference* reference) {
|
||||
*reference = this->Leak(&value);
|
||||
return SetUnique(key, &value);
|
||||
}
|
||||
@ -406,9 +406,9 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
|
||||
|
||||
template <typename K, typename V, typename Traits>
|
||||
class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
public:
|
||||
explicit PhantomPersistentValueMap(Isolate* isolate)
|
||||
explicit GlobalValueMap(Isolate* isolate)
|
||||
: PersistentValueMapBase<K, V, Traits>(isolate) {}
|
||||
|
||||
typedef
|
||||
@ -418,17 +418,17 @@ class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
/**
|
||||
* Put value into map. Depending on Traits::kIsWeak, the value will be held
|
||||
* by the map strongly or weakly.
|
||||
* Returns old value as UniquePersistent.
|
||||
* Returns old value as Global.
|
||||
*/
|
||||
UniquePersistent<V> Set(const K& key, Local<V> value) {
|
||||
UniquePersistent<V> persistent(this->isolate(), value);
|
||||
Global<V> Set(const K& key, Local<V> value) {
|
||||
Global<V> persistent(this->isolate(), value);
|
||||
return SetUnique(key, &persistent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put value into map, like Set(const K&, Local<V>).
|
||||
*/
|
||||
UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) {
|
||||
Global<V> Set(const K& key, Global<V> value) {
|
||||
return SetUnique(key, &value);
|
||||
}
|
||||
|
||||
@ -436,11 +436,16 @@ class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
* Put the value into the map, and set the 'weak' callback when demanded
|
||||
* by the Traits class.
|
||||
*/
|
||||
UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
|
||||
Global<V> SetUnique(const K& key, Global<V>* persistent) {
|
||||
if (Traits::kCallbackType != kNotWeak) {
|
||||
WeakCallbackType callback_type =
|
||||
Traits::kCallbackType == kWeakWithInternalFields
|
||||
? WeakCallbackType::kInternalFields
|
||||
: WeakCallbackType::kParameter;
|
||||
Local<V> value(Local<V>::New(this->isolate(), *persistent));
|
||||
persistent->template SetPhantom<typename Traits::WeakCallbackDataType>(
|
||||
Traits::WeakCallbackParameter(this, key, value), WeakCallback, 0, 1);
|
||||
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
|
||||
Traits::WeakCallbackParameter(this, key, value), WeakCallback,
|
||||
callback_type);
|
||||
}
|
||||
PersistentContainerValue old_value =
|
||||
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
|
||||
@ -451,19 +456,19 @@ class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
* Put a value into the map and update the reference.
|
||||
* Restrictions of GetReference apply here as well.
|
||||
*/
|
||||
UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
|
||||
PersistentValueReference* reference) {
|
||||
Global<V> Set(const K& key, Global<V> value,
|
||||
PersistentValueReference* reference) {
|
||||
*reference = this->Leak(&value);
|
||||
return SetUnique(key, &value);
|
||||
}
|
||||
|
||||
private:
|
||||
static void WeakCallback(
|
||||
const PhantomCallbackData<typename Traits::WeakCallbackDataType>& data) {
|
||||
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
|
||||
if (Traits::kCallbackType != kNotWeak) {
|
||||
PhantomPersistentValueMap<K, V, Traits>* persistentValueMap =
|
||||
Traits::MapFromPhantomCallbackData(data);
|
||||
K key = Traits::KeyFromPhantomCallbackData(data);
|
||||
GlobalValueMap<K, V, Traits>* persistentValueMap =
|
||||
Traits::MapFromWeakCallbackInfo(data);
|
||||
K key = Traits::KeyFromWeakCallbackInfo(data);
|
||||
Traits::Dispose(data.GetIsolate(), persistentValueMap->Remove(key).Pass(),
|
||||
key);
|
||||
Traits::DisposeCallbackData(data.GetParameter());
|
||||
@ -473,11 +478,11 @@ class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
|
||||
|
||||
|
||||
/**
|
||||
* A map that uses UniquePersistent as value and std::map as the backing
|
||||
* A map that uses Global as value and std::map as the backing
|
||||
* implementation. Persistents are held non-weak.
|
||||
*
|
||||
* C++11 embedders don't need this class, as they can use
|
||||
* UniquePersistent directly in std containers.
|
||||
* Global directly in std containers.
|
||||
*/
|
||||
template<typename K, typename V,
|
||||
typename Traits = DefaultPersistentValueMapTraits<K, V> >
|
||||
@ -514,8 +519,8 @@ class DefaultPersistentValueVectorTraits {
|
||||
|
||||
|
||||
/**
|
||||
* A vector wrapper that safely stores UniquePersistent values.
|
||||
* C++11 embedders don't need this class, as they can use UniquePersistent
|
||||
* A vector wrapper that safely stores Global values.
|
||||
* C++11 embedders don't need this class, as they can use Global
|
||||
* directly in std containers.
|
||||
*
|
||||
* This class relies on a backing vector implementation, whose type and methods
|
||||
@ -536,14 +541,14 @@ class PersistentValueVector {
|
||||
* Append a value to the vector.
|
||||
*/
|
||||
void Append(Local<V> value) {
|
||||
UniquePersistent<V> persistent(isolate_, value);
|
||||
Global<V> persistent(isolate_, value);
|
||||
Traits::Append(&impl_, ClearAndLeak(&persistent));
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a persistent's value to the vector.
|
||||
*/
|
||||
void Append(UniquePersistent<V> persistent) {
|
||||
void Append(Global<V> persistent) {
|
||||
Traits::Append(&impl_, ClearAndLeak(&persistent));
|
||||
}
|
||||
|
||||
@ -574,7 +579,7 @@ class PersistentValueVector {
|
||||
void Clear() {
|
||||
size_t length = Traits::Size(&impl_);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
UniquePersistent<V> p;
|
||||
Global<V> p;
|
||||
p.val_ = FromVal(Traits::Get(&impl_, i));
|
||||
}
|
||||
Traits::Clear(&impl_);
|
||||
@ -589,8 +594,7 @@ class PersistentValueVector {
|
||||
}
|
||||
|
||||
private:
|
||||
static PersistentContainerValue ClearAndLeak(
|
||||
UniquePersistent<V>* persistent) {
|
||||
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
|
||||
V* v = persistent->val_;
|
||||
persistent->val_ = 0;
|
||||
return reinterpret_cast<PersistentContainerValue>(v);
|
||||
@ -606,4 +610,4 @@ class PersistentValueVector {
|
||||
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_UTIL_H_
|
||||
#endif // V8_UTIL_H
|
||||
|
127
include/v8.h
127
include/v8.h
@ -121,7 +121,7 @@ template<class K, class V, class T> class PersistentValueMap;
|
||||
template <class K, class V, class T>
|
||||
class PersistentValueMapBase;
|
||||
template <class K, class V, class T>
|
||||
class PhantomPersistentValueMap;
|
||||
class GlobalValueMap;
|
||||
template<class V, class T> class PersistentValueVector;
|
||||
template<class T, class P> class WeakCallbackObject;
|
||||
class FunctionTemplate;
|
||||
@ -147,20 +147,6 @@ template<typename T> class CustomArguments;
|
||||
class PropertyCallbackArguments;
|
||||
class FunctionCallbackArguments;
|
||||
class GlobalHandles;
|
||||
|
||||
template <typename T>
|
||||
class CallbackData {
|
||||
public:
|
||||
V8_INLINE v8::Isolate* GetIsolate() const { return isolate_; }
|
||||
|
||||
explicit CallbackData(v8::Isolate* isolate, T* parameter)
|
||||
: isolate_(isolate), parameter_(parameter) {}
|
||||
V8_INLINE T* GetParameter() const { return parameter_; }
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
T* parameter_;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -478,41 +464,55 @@ template <class T> class Eternal {
|
||||
|
||||
|
||||
template <typename T>
|
||||
class PhantomCallbackData : public internal::CallbackData<T> {
|
||||
class WeakCallbackInfo {
|
||||
public:
|
||||
typedef void (*Callback)(const PhantomCallbackData<T>& data);
|
||||
typedef void (*Callback)(const WeakCallbackInfo<T>& data);
|
||||
|
||||
V8_INLINE void* GetInternalField1() const { return internal_field1_; }
|
||||
V8_INLINE void* GetInternalField2() const { return internal_field2_; }
|
||||
|
||||
PhantomCallbackData(Isolate* isolate, T* parameter, void* internal_field1,
|
||||
void* internal_field2)
|
||||
: internal::CallbackData<T>(isolate, parameter),
|
||||
WeakCallbackInfo(Isolate* isolate, T* parameter, void* internal_field1,
|
||||
void* internal_field2)
|
||||
: isolate_(isolate),
|
||||
parameter_(parameter),
|
||||
internal_field1_(internal_field1),
|
||||
internal_field2_(internal_field2) {}
|
||||
|
||||
V8_INLINE Isolate* GetIsolate() const { return isolate_; }
|
||||
V8_INLINE T* GetParameter() const { return parameter_; }
|
||||
V8_INLINE void* GetInternalField1() const { return internal_field1_; }
|
||||
V8_INLINE void* GetInternalField2() const { return internal_field2_; }
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
T* parameter_;
|
||||
void* internal_field1_;
|
||||
void* internal_field2_;
|
||||
};
|
||||
|
||||
|
||||
template <class T, class P>
|
||||
class WeakCallbackData : public internal::CallbackData<P> {
|
||||
class WeakCallbackData {
|
||||
public:
|
||||
typedef void (*Callback)(const WeakCallbackData<T, P>& data);
|
||||
|
||||
WeakCallbackData(Isolate* isolate, P* parameter, Local<T> handle)
|
||||
: isolate_(isolate), parameter_(parameter), handle_(handle) {}
|
||||
|
||||
V8_INLINE Isolate* GetIsolate() const { return isolate_; }
|
||||
V8_INLINE P* GetParameter() const { return parameter_; }
|
||||
V8_INLINE Local<T> GetValue() const { return handle_; }
|
||||
|
||||
private:
|
||||
friend class internal::GlobalHandles;
|
||||
WeakCallbackData(Isolate* isolate, P* parameter, Local<T> handle)
|
||||
: internal::CallbackData<P>(isolate, parameter), handle_(handle) {}
|
||||
Isolate* isolate_;
|
||||
P* parameter_;
|
||||
Local<T> handle_;
|
||||
};
|
||||
|
||||
|
||||
static const int kNoInternalFieldIndex = -1;
|
||||
// TODO(dcarney): delete this with WeakCallbackData
|
||||
template <class T>
|
||||
using PhantomCallbackData = WeakCallbackInfo<T>;
|
||||
|
||||
|
||||
enum class WeakCallbackType { kParameter, kInternalFields };
|
||||
|
||||
|
||||
/**
|
||||
@ -585,15 +585,17 @@ template <class T> class PersistentBase {
|
||||
* As always, GC-based finalization should *not* be relied upon for any
|
||||
* critical form of resource management!
|
||||
*/
|
||||
template<typename P>
|
||||
V8_INLINE void SetWeak(
|
||||
P* parameter,
|
||||
typename WeakCallbackData<T, P>::Callback callback);
|
||||
template <typename P>
|
||||
V8_INLINE V8_DEPRECATE_SOON(
|
||||
"use WeakCallbackInfo version",
|
||||
void SetWeak(P* parameter,
|
||||
typename WeakCallbackData<T, P>::Callback callback));
|
||||
|
||||
template<typename S, typename P>
|
||||
V8_INLINE void SetWeak(
|
||||
P* parameter,
|
||||
typename WeakCallbackData<S, P>::Callback callback);
|
||||
template <typename S, typename P>
|
||||
V8_INLINE V8_DEPRECATE_SOON(
|
||||
"use WeakCallbackInfo version",
|
||||
void SetWeak(P* parameter,
|
||||
typename WeakCallbackData<S, P>::Callback callback));
|
||||
|
||||
// Phantom persistents work like weak persistents, except that the pointer to
|
||||
// the object being collected is not available in the finalization callback.
|
||||
@ -602,10 +604,17 @@ template <class T> class PersistentBase {
|
||||
// specify a parameter for the callback or the location of two internal
|
||||
// fields in the dying object.
|
||||
template <typename P>
|
||||
V8_INLINE void SetPhantom(P* parameter,
|
||||
typename PhantomCallbackData<P>::Callback callback,
|
||||
int internal_field_index1 = kNoInternalFieldIndex,
|
||||
int internal_field_index2 = kNoInternalFieldIndex);
|
||||
V8_INLINE V8_DEPRECATE_SOON(
|
||||
"use SetWeak",
|
||||
void SetPhantom(P* parameter,
|
||||
typename WeakCallbackInfo<P>::Callback callback,
|
||||
int internal_field_index1 = -1,
|
||||
int internal_field_index2 = -1));
|
||||
|
||||
template <typename P>
|
||||
V8_INLINE void SetWeak(P* parameter,
|
||||
typename WeakCallbackInfo<P>::Callback callback,
|
||||
WeakCallbackType type);
|
||||
|
||||
template<typename P>
|
||||
V8_INLINE P* ClearWeak();
|
||||
@ -5815,8 +5824,6 @@ class V8_EXPORT V8 {
|
||||
private:
|
||||
V8();
|
||||
|
||||
enum WeakHandleType { PhantomHandle, NonphantomHandle };
|
||||
|
||||
static internal::Object** GlobalizeReference(internal::Isolate* isolate,
|
||||
internal::Object** handle);
|
||||
static internal::Object** CopyPersistent(internal::Object** handle);
|
||||
@ -5824,12 +5831,15 @@ class V8_EXPORT V8 {
|
||||
typedef WeakCallbackData<Value, void>::Callback WeakCallback;
|
||||
static void MakeWeak(internal::Object** global_handle, void* data,
|
||||
WeakCallback weak_callback);
|
||||
static void MakePhantom(internal::Object** global_handle, void* data,
|
||||
// Must be 0 or kNoInternalFieldIndex.
|
||||
int internal_field_index1,
|
||||
// Must be 1 or kNoInternalFieldIndex.
|
||||
int internal_field_index2,
|
||||
PhantomCallbackData<void>::Callback weak_callback);
|
||||
static void MakeWeak(internal::Object** global_handle, void* data,
|
||||
WeakCallbackInfo<void>::Callback weak_callback,
|
||||
WeakCallbackType type);
|
||||
static void MakeWeak(internal::Object** global_handle, void* data,
|
||||
// Must be 0 or -1.
|
||||
int internal_field_index1,
|
||||
// Must be 1 or -1.
|
||||
int internal_field_index2,
|
||||
WeakCallbackInfo<void>::Callback weak_callback);
|
||||
static void* ClearWeak(internal::Object** global_handle);
|
||||
static void Eternalize(Isolate* isolate,
|
||||
Value* handle,
|
||||
@ -6776,12 +6786,23 @@ void PersistentBase<T>::SetWeak(
|
||||
template <class T>
|
||||
template <typename P>
|
||||
void PersistentBase<T>::SetPhantom(
|
||||
P* parameter, typename PhantomCallbackData<P>::Callback callback,
|
||||
P* parameter, typename WeakCallbackInfo<P>::Callback callback,
|
||||
int internal_field_index1, int internal_field_index2) {
|
||||
typedef typename PhantomCallbackData<void>::Callback Callback;
|
||||
V8::MakePhantom(reinterpret_cast<internal::Object**>(this->val_), parameter,
|
||||
internal_field_index1, internal_field_index2,
|
||||
reinterpret_cast<Callback>(callback));
|
||||
typedef typename WeakCallbackInfo<void>::Callback Callback;
|
||||
V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), parameter,
|
||||
internal_field_index1, internal_field_index2,
|
||||
reinterpret_cast<Callback>(callback));
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
template <typename P>
|
||||
V8_INLINE void PersistentBase<T>::SetWeak(
|
||||
P* parameter, typename WeakCallbackInfo<P>::Callback callback,
|
||||
WeakCallbackType type) {
|
||||
typedef typename WeakCallbackInfo<void>::Callback Callback;
|
||||
V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), parameter,
|
||||
reinterpret_cast<Callback>(callback), type);
|
||||
}
|
||||
|
||||
|
||||
|
26
src/api.cc
26
src/api.cc
@ -567,21 +567,29 @@ void V8::MakeWeak(i::Object** object, void* parameter,
|
||||
}
|
||||
|
||||
|
||||
void V8::MakePhantom(i::Object** object, void* parameter,
|
||||
int internal_field_index1, int internal_field_index2,
|
||||
PhantomCallbackData<void>::Callback weak_callback) {
|
||||
void V8::MakeWeak(i::Object** object, void* parameter,
|
||||
int internal_field_index1, int internal_field_index2,
|
||||
WeakCallbackInfo<void>::Callback weak_callback) {
|
||||
WeakCallbackType type = WeakCallbackType::kParameter;
|
||||
if (internal_field_index1 == 0) {
|
||||
if (internal_field_index2 == 1) {
|
||||
i::GlobalHandles::MakePhantom(object, parameter, 2, weak_callback);
|
||||
type = WeakCallbackType::kInternalFields;
|
||||
} else {
|
||||
DCHECK_EQ(internal_field_index2, kNoInternalFieldIndex);
|
||||
i::GlobalHandles::MakePhantom(object, parameter, 1, weak_callback);
|
||||
DCHECK_EQ(internal_field_index2, -1);
|
||||
type = WeakCallbackType::kInternalFields;
|
||||
}
|
||||
} else {
|
||||
DCHECK_EQ(internal_field_index1, kNoInternalFieldIndex);
|
||||
DCHECK_EQ(internal_field_index2, kNoInternalFieldIndex);
|
||||
i::GlobalHandles::MakePhantom(object, parameter, 0, weak_callback);
|
||||
DCHECK_EQ(internal_field_index1, -1);
|
||||
DCHECK_EQ(internal_field_index2, -1);
|
||||
}
|
||||
i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
|
||||
}
|
||||
|
||||
|
||||
void V8::MakeWeak(i::Object** object, void* parameter,
|
||||
WeakCallbackInfo<void>::Callback weak_callback,
|
||||
WeakCallbackType type) {
|
||||
i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -608,9 +608,10 @@ DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
|
||||
GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
|
||||
debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
|
||||
typedef PhantomCallbackData<void>::Callback Callback;
|
||||
GlobalHandles::MakePhantom(
|
||||
reinterpret_cast<Object**>(debug_info_.location()), this, 0,
|
||||
reinterpret_cast<Callback>(Debug::HandlePhantomDebugInfo));
|
||||
GlobalHandles::MakeWeak(
|
||||
reinterpret_cast<Object**>(debug_info_.location()), this,
|
||||
reinterpret_cast<Callback>(Debug::HandlePhantomDebugInfo),
|
||||
v8::WeakCallbackType::kParameter);
|
||||
}
|
||||
|
||||
|
||||
|
@ -230,20 +230,20 @@ class GlobalHandles::Node {
|
||||
weak_callback_ = weak_callback;
|
||||
}
|
||||
|
||||
void MakePhantom(void* parameter, int number_of_internal_fields,
|
||||
PhantomCallbackData<void>::Callback phantom_callback) {
|
||||
DCHECK(number_of_internal_fields >= 0);
|
||||
DCHECK(number_of_internal_fields <= 2);
|
||||
DCHECK(phantom_callback != NULL);
|
||||
void MakeWeak(void* parameter,
|
||||
WeakCallbackInfo<void>::Callback phantom_callback,
|
||||
v8::WeakCallbackType type) {
|
||||
DCHECK(phantom_callback != nullptr);
|
||||
DCHECK(IsInUse());
|
||||
CHECK(object_ != NULL);
|
||||
CHECK(object_ != nullptr);
|
||||
set_state(WEAK);
|
||||
if (number_of_internal_fields == 0) {
|
||||
set_weakness_type(PHANTOM_WEAK_0_INTERNAL_FIELDS);
|
||||
} else if (number_of_internal_fields == 1) {
|
||||
set_weakness_type(PHANTOM_WEAK_1_INTERNAL_FIELDS);
|
||||
} else {
|
||||
switch (type) {
|
||||
case v8::WeakCallbackType::kParameter:
|
||||
set_weakness_type(PHANTOM_WEAK);
|
||||
break;
|
||||
case v8::WeakCallbackType::kInternalFields:
|
||||
set_weakness_type(PHANTOM_WEAK_2_INTERNAL_FIELDS);
|
||||
break;
|
||||
}
|
||||
set_parameter(parameter);
|
||||
weak_callback_ = reinterpret_cast<WeakCallback>(phantom_callback);
|
||||
@ -266,29 +266,29 @@ class GlobalHandles::Node {
|
||||
|
||||
v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
|
||||
DCHECK(weakness_type() == PHANTOM_WEAK_0_INTERNAL_FIELDS ||
|
||||
weakness_type() == PHANTOM_WEAK_1_INTERNAL_FIELDS ||
|
||||
DCHECK(weakness_type() == PHANTOM_WEAK ||
|
||||
weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
|
||||
|
||||
Object* internal_field0 = nullptr;
|
||||
Object* internal_field1 = nullptr;
|
||||
if (weakness_type() != PHANTOM_WEAK_0_INTERNAL_FIELDS) {
|
||||
JSObject* jsobject = reinterpret_cast<JSObject*>(object());
|
||||
DCHECK(jsobject->IsJSObject());
|
||||
DCHECK(jsobject->GetInternalFieldCount() >= 1);
|
||||
internal_field0 = jsobject->GetInternalField(0);
|
||||
if (weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS) {
|
||||
DCHECK(jsobject->GetInternalFieldCount() >= 2);
|
||||
internal_field1 = jsobject->GetInternalField(1);
|
||||
if (weakness_type() != PHANTOM_WEAK) {
|
||||
if (object()->IsJSObject()) {
|
||||
JSObject* jsobject = JSObject::cast(object());
|
||||
int field_count = jsobject->GetInternalFieldCount();
|
||||
if (field_count > 0) {
|
||||
internal_field0 = jsobject->GetInternalField(0);
|
||||
if (!internal_field0->IsSmi()) internal_field0 = nullptr;
|
||||
}
|
||||
if (field_count > 1) {
|
||||
internal_field1 = jsobject->GetInternalField(1);
|
||||
if (!internal_field1->IsSmi()) internal_field1 = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Zap with harmless value.
|
||||
*location() = Smi::FromInt(0);
|
||||
typedef PhantomCallbackData<void> Data;
|
||||
|
||||
if (!internal_field0->IsSmi()) internal_field0 = nullptr;
|
||||
if (!internal_field1->IsSmi()) internal_field1 = nullptr;
|
||||
typedef v8::WeakCallbackInfo<void> Data;
|
||||
|
||||
Data data(api_isolate, parameter(), internal_field0, internal_field1);
|
||||
Data::Callback callback =
|
||||
@ -562,14 +562,13 @@ void GlobalHandles::MakeWeak(Object** location, void* parameter,
|
||||
}
|
||||
|
||||
|
||||
typedef PhantomCallbackData<void>::Callback GenericCallback;
|
||||
typedef v8::WeakCallbackInfo<void>::Callback GenericCallback;
|
||||
|
||||
|
||||
void GlobalHandles::MakePhantom(Object** location, void* parameter,
|
||||
int number_of_internal_fields,
|
||||
GenericCallback phantom_callback) {
|
||||
Node::FromLocation(location)
|
||||
->MakePhantom(parameter, number_of_internal_fields, phantom_callback);
|
||||
void GlobalHandles::MakeWeak(Object** location, void* parameter,
|
||||
GenericCallback phantom_callback,
|
||||
v8::WeakCallbackType type) {
|
||||
Node::FromLocation(location)->MakeWeak(parameter, phantom_callback, type);
|
||||
}
|
||||
|
||||
|
||||
@ -633,13 +632,12 @@ void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
|
||||
// In the internal fields case we will need the internal
|
||||
// fields, so we can't zap the handle.
|
||||
if (node->state() == Node::PENDING) {
|
||||
if (node->weakness_type() == PHANTOM_WEAK_0_INTERNAL_FIELDS) {
|
||||
if (node->weakness_type() == PHANTOM_WEAK) {
|
||||
*(node->location()) = Smi::FromInt(0);
|
||||
} else if (node->weakness_type() == NORMAL_WEAK) {
|
||||
v->VisitPointer(node->location());
|
||||
} else {
|
||||
DCHECK(node->weakness_type() == PHANTOM_WEAK_1_INTERNAL_FIELDS ||
|
||||
node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
|
||||
DCHECK(node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
|
||||
}
|
||||
} else {
|
||||
// Node is not pending, so that means the object survived. We still
|
||||
@ -692,13 +690,12 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
|
||||
DCHECK(node->is_in_new_space_list());
|
||||
if ((node->is_independent() || node->is_partially_dependent()) &&
|
||||
node->IsWeakRetainer()) {
|
||||
if (node->weakness_type() == PHANTOM_WEAK_0_INTERNAL_FIELDS) {
|
||||
if (node->weakness_type() == PHANTOM_WEAK) {
|
||||
*(node->location()) = Smi::FromInt(0);
|
||||
} else if (node->weakness_type() == NORMAL_WEAK) {
|
||||
v->VisitPointer(node->location());
|
||||
} else {
|
||||
DCHECK(node->weakness_type() == PHANTOM_WEAK_1_INTERNAL_FIELDS ||
|
||||
node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
|
||||
DCHECK(node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
|
||||
// For this case we only need to trace if it's alive: The tracing of
|
||||
// something that is already alive is just to get the pointer updated
|
||||
// to the new location of the object).
|
||||
|
@ -100,12 +100,11 @@ struct ObjectGroupRetainerInfo {
|
||||
enum WeaknessType {
|
||||
NORMAL_WEAK, // Embedder gets a handle to the dying object.
|
||||
// In the following cases, the embedder gets the parameter they passed in
|
||||
// earlier, and the 0, 1 or 2 first internal fields. Note that the internal
|
||||
// earlier, and 0 or 2 first internal fields. Note that the internal
|
||||
// fields must contain aligned non-V8 pointers. Getting pointers to V8
|
||||
// objects through this interface would be GC unsafe so in that case the
|
||||
// embedder gets a null pointer instead.
|
||||
PHANTOM_WEAK_0_INTERNAL_FIELDS,
|
||||
PHANTOM_WEAK_1_INTERNAL_FIELDS,
|
||||
PHANTOM_WEAK,
|
||||
PHANTOM_WEAK_2_INTERNAL_FIELDS
|
||||
};
|
||||
|
||||
@ -145,9 +144,9 @@ class GlobalHandles {
|
||||
|
||||
// It would be nice to template this one, but it's really hard to get
|
||||
// the template instantiator to work right if you do.
|
||||
static void MakePhantom(Object** location, void* parameter,
|
||||
int number_of_internal_fields,
|
||||
PhantomCallbackData<void>::Callback weak_callback);
|
||||
static void MakeWeak(Object** location, void* parameter,
|
||||
WeakCallbackInfo<void>::Callback weak_callback,
|
||||
v8::WeakCallbackType type);
|
||||
|
||||
void RecordStats(HeapStats* stats);
|
||||
|
||||
@ -349,7 +348,7 @@ class GlobalHandles {
|
||||
|
||||
class GlobalHandles::PendingPhantomCallback {
|
||||
public:
|
||||
typedef PhantomCallbackData<void> Data;
|
||||
typedef v8::WeakCallbackInfo<void> Data;
|
||||
PendingPhantomCallback(Node* node, Data data, Data::Callback callback)
|
||||
: node_(node), data_(data), callback_(callback) {}
|
||||
|
||||
|
@ -6272,7 +6272,7 @@ struct FlagAndPersistent {
|
||||
};
|
||||
|
||||
|
||||
static void SetFlag(const v8::PhantomCallbackData<FlagAndPersistent>& data) {
|
||||
static void SetFlag(const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
|
||||
data.GetParameter()->flag = true;
|
||||
}
|
||||
|
||||
@ -6311,8 +6311,10 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) {
|
||||
|
||||
object_a.flag = false;
|
||||
object_b.flag = false;
|
||||
object_a.handle.SetPhantom(&object_a, &SetFlag);
|
||||
object_b.handle.SetPhantom(&object_b, &SetFlag);
|
||||
object_a.handle.SetWeak(&object_a, &SetFlag,
|
||||
v8::WeakCallbackType::kParameter);
|
||||
object_b.handle.SetWeak(&object_b, &SetFlag,
|
||||
v8::WeakCallbackType::kParameter);
|
||||
CHECK(!object_b.handle.IsIndependent());
|
||||
object_a.handle.MarkIndependent();
|
||||
object_b.handle.MarkIndependent();
|
||||
@ -6367,7 +6369,7 @@ class Trivial2 {
|
||||
|
||||
|
||||
void CheckInternalFields(
|
||||
const v8::PhantomCallbackData<v8::Persistent<v8::Object>>& data) {
|
||||
const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
|
||||
v8::Persistent<v8::Object>* handle = data.GetParameter();
|
||||
handle->Reset();
|
||||
Trivial* t1 = reinterpret_cast<Trivial*>(data.GetInternalField1());
|
||||
@ -6407,8 +6409,8 @@ void InternalFieldCallback(bool global_gc) {
|
||||
reinterpret_cast<Trivial2*>(obj->GetAlignedPointerFromInternalField(1));
|
||||
CHECK_EQ(103, t2->x());
|
||||
|
||||
handle.SetPhantom<v8::Persistent<v8::Object>>(&handle, CheckInternalFields,
|
||||
0, 1);
|
||||
handle.SetWeak<v8::Persistent<v8::Object>>(
|
||||
&handle, CheckInternalFields, v8::WeakCallbackType::kInternalFields);
|
||||
if (!global_gc) {
|
||||
handle.MarkIndependent();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user