Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: include/v8-util.h

Issue 212893007: Amend PersistentValueMap. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address feedback comments, round 2. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include/v8-util.h
diff --git a/include/v8-util.h b/include/v8-util.h
index 3f8cc6d269d0a6598944720980771210de49b73c..219fe76aae6b328381b0f4e02d062c362a365335 100644
--- a/include/v8-util.h
+++ b/include/v8-util.h
@@ -42,6 +42,10 @@ namespace v8 {
typedef uintptr_t PersistentContainerValue;
static const uintptr_t kPersistentContainerNotFound = 0;
+enum PersistentContainerCallbackType {
+ kNotWeak,
+ kWeak
+};
/**
@@ -92,38 +96,34 @@ class StdMapTraits {
/**
* A default trait implementation for PersistentValueMap, which inherits
* a std:map backing map from StdMapTraits and holds non-weak persistent
- * objects.
+ * objects and has no special Dispose handling.
*
- * Users have to implement their own dispose trait.
+ * You should not derive from this class, since MapType depends on the
+ * surrounding class, and hence a subclass cannot simply inherit the methods.
*/
template<typename K, typename V>
-class StrongMapTraits : public StdMapTraits<K, V> {
+class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
public:
// Weak callback & friends:
- static const bool kIsWeak = false;
- typedef typename StdMapTraits<K, V>::Impl Impl;
+ static const PersistentContainerCallbackType kCallbackType = kNotWeak;
+ typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
+ MapType;
typedef void WeakCallbackDataType;
+
static WeakCallbackDataType* WeakCallbackParameter(
- Impl* impl, const K& key, Local<V> value);
- static Impl* ImplFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data);
+ MapType* map, const K& key, Local<V> value) {
+ return NULL;
+ }
+ static MapType* MapFromWeakCallbackData(
+ const WeakCallbackData<V, WeakCallbackDataType>& data) {
+ return NULL;
+ }
static K KeyFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data);
- static void DisposeCallbackData(WeakCallbackDataType* data);
-};
-
-
-/**
- * A default trait implementation for PersistentValueMap, with a std::map
- * backing map, non-weak persistents as values, and no special dispose
- * handling. Can be used as-is.
- */
-template<typename K, typename V>
-class DefaultPersistentValueMapTraits : public StrongMapTraits<K, V> {
- public:
- typedef typename StrongMapTraits<K, V>::Impl Impl;
- static void Dispose(Isolate* isolate, UniquePersistent<V> value,
- Impl* impl, K key) { }
+ const WeakCallbackData<V, WeakCallbackDataType>& data) {
+ return K();
+ }
+ static void DisposeCallbackData(WeakCallbackDataType* data) { }
+ static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { }
};
@@ -154,7 +154,7 @@ class PersistentValueMap {
/**
* Return whether the map holds weak persistents.
*/
- V8_INLINE bool IsWeak() { return Traits::kIsWeak; }
+ V8_INLINE bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
/**
* Get value stored in map.
@@ -167,7 +167,7 @@ class PersistentValueMap {
* Check whether a value is contained in the map.
*/
V8_INLINE bool Contains(const K& key) {
- return Traits::Get(&impl_, key) != 0;
+ return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
}
/**
@@ -175,14 +175,8 @@ class PersistentValueMap {
* Return true if a value was found.
*/
V8_INLINE bool SetReturnValue(const K& key,
- ReturnValue<Value>& returnValue) {
- PersistentContainerValue value = Traits::Get(&impl_, key);
- bool hasValue = value != 0;
- if (hasValue) {
- returnValue.SetInternal(
- *reinterpret_cast<internal::Object**>(FromVal(value)));
- }
- return hasValue;
+ ReturnValue<Value> returnValue) {
+ return SetReturnValueFromVal(returnValue, Traits::Get(&impl_, key));
}
/**
@@ -231,12 +225,76 @@ class PersistentValueMap {
typename Traits::Impl impl;
Traits::Swap(impl_, impl);
for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
- Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
- Traits::Key(i));
+ Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
+ Traits::Key(i));
}
}
}
+ /**
+ * Helper class for GetReference/SetWithReference. Do not use outside
+ * that context.
+ */
+ class PersistentValueReference {
+ public:
+ PersistentValueReference() : value_(kPersistentContainerNotFound) { }
+ PersistentValueReference(const PersistentValueReference& other)
+ : value_(other.value_) { }
+
+ Local<V> NewLocal(Isolate* isolate) const {
+ return Local<V>::New(isolate, FromVal(value_));
+ }
+ bool IsEmpty() const {
+ return value_ == kPersistentContainerNotFound;
+ }
+ template<typename T>
+ bool SetReturnValue(ReturnValue<T> returnValue) {
+ return SetReturnValueFromVal(returnValue, value_);
+ }
+ void Reset() {
+ value_ = kPersistentContainerNotFound;
+ }
+ void operator=(const PersistentValueReference& other) {
+ value_ = other.value_;
+ }
+
+ private:
+ friend class PersistentValueMap;
+
+ explicit PersistentValueReference(PersistentContainerValue value)
+ : value_(value) { }
+
+ void operator=(PersistentContainerValue value) {
+ value_ = value;
+ }
+
+ PersistentContainerValue value_;
+ };
+
+ /**
+ * Get a reference to a map value. This enables fast, repeated access
+ * to a value stored in the map while the map remains unchanged.
+ *
+ * Careful: This is potentially unsafe, so please use with care.
+ * The value will become invalid if the value for this key changes
+ * in the underlying map, as a result of Set or Remove for the same
+ * key; as a result of the weak callback for the same key; or as a
+ * result of calling Clear() or destruction of the map.
+ */
+ V8_INLINE PersistentValueReference GetReference(const K& key) {
+ return PersistentValueReference(Traits::Get(&impl_, key));
+ }
+
+ /**
+ * 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) {
+ *reference = Leak(&value);
+ return SetUnique(key, &value);
+ }
+
private:
PersistentValueMap(PersistentValueMap&);
void operator=(PersistentValueMap&);
@@ -246,10 +304,10 @@ class PersistentValueMap {
* by the Traits class.
*/
UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
- if (Traits::kIsWeak) {
+ if (Traits::kCallbackType != kNotWeak) {
Local<V> value(Local<V>::New(isolate_, *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
- Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
+ Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
Traits::Set(&impl_, key, ClearAndLeak(persistent));
@@ -258,11 +316,12 @@ class PersistentValueMap {
static void WeakCallback(
const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
- if (Traits::kIsWeak) {
- typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
+ if (Traits::kCallbackType != kNotWeak) {
+ PersistentValueMap<K, V, Traits>* persistentValueMap =
+ Traits::MapFromWeakCallbackData(data);
K key = Traits::KeyFromWeakCallbackData(data);
- PersistentContainerValue value = Traits::Remove(impl, key);
- Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key);
+ Traits::Dispose(data.GetIsolate(),
+ persistentValueMap->Remove(key).Pass(), key);
}
}
@@ -270,6 +329,16 @@ class PersistentValueMap {
return reinterpret_cast<V*>(v);
}
+ V8_INLINE static bool SetReturnValueFromVal(
+ ReturnValue<Value>& returnValue, PersistentContainerValue value) {
+ bool hasValue = value != kPersistentContainerNotFound;
+ if (hasValue) {
+ returnValue.SetInternal(
+ *reinterpret_cast<internal::Object**>(FromVal(value)));
+ }
+ return hasValue;
+ }
+
V8_INLINE static PersistentContainerValue ClearAndLeak(
UniquePersistent<V>* persistent) {
V* v = persistent->val_;
@@ -277,6 +346,11 @@ class PersistentValueMap {
return reinterpret_cast<PersistentContainerValue>(v);
}
+ V8_INLINE static PersistentContainerValue Leak(
+ UniquePersistent<V>* persistent) {
+ return reinterpret_cast<PersistentContainerValue>(persistent->val_);
+ }
+
/**
* Return a container value as UniquePersistent and make sure the weak
* callback is properly disposed of. All remove functionality should go
@@ -285,7 +359,7 @@ class PersistentValueMap {
V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
UniquePersistent<V> p;
p.val_ = FromVal(v);
- if (Traits::kIsWeak && !p.IsEmpty()) {
+ if (Traits::kCallbackType != kNotWeak && !p.IsEmpty()) {
Traits::DisposeCallbackData(
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
}
@@ -312,44 +386,6 @@ class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
: PersistentValueMap<K, V, Traits>(isolate) {}
};
-
-/**
- * Empty default implementations for StrongTraits methods.
- *
- * These should not be necessary, since they're only used in code that
- * is surrounded by if(Traits::kIsWeak), which for StrongMapTraits is
- * compile-time false. Most compilers can live without them; however
- * the compiler we use from 64-bit Win differs.
- *
- * TODO(vogelheim): Remove these once they're no longer necessary.
- */
-template<typename K, typename V>
-typename StrongMapTraits<K, V>::WeakCallbackDataType*
- StrongMapTraits<K, V>::WeakCallbackParameter(
- Impl* impl, const K& key, Local<V> value) {
- return NULL;
-}
-
-
-template<typename K, typename V>
-typename StrongMapTraits<K, V>::Impl*
- StrongMapTraits<K, V>::ImplFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data) {
- return NULL;
-}
-
-
-template<typename K, typename V>
-K StrongMapTraits<K, V>::KeyFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data) {
- return K();
-}
-
-
-template<typename K, typename V>
-void StrongMapTraits<K, V>::DisposeCallbackData(WeakCallbackDataType* data) {
-}
-
} // namespace v8
#endif // V8_UTIL_H_
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698