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

Side by Side Diff: include/v8-util.h

Issue 212893007: Amend PersistentValueMap. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Re-upload after rebase. 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 PersistentContainerValue value = it->second; 85 PersistentContainerValue value = it->second;
86 impl->erase(it); 86 impl->erase(it);
87 return value; 87 return value;
88 } 88 }
89 }; 89 };
90 90
91 91
92 /** 92 /**
93 * A default trait implementation for PersistentValueMap, which inherits 93 * A default trait implementation for PersistentValueMap, which inherits
94 * a std:map backing map from StdMapTraits and holds non-weak persistent 94 * a std:map backing map from StdMapTraits and holds non-weak persistent
95 * objects. 95 * objects and has no special Dispose handling.
96 * 96 *
97 * Users have to implement their own dispose trait. 97 * You should not derive from this class, since MapType depends on the
98 * surrounding class, and hence a subclass cannot simply inherit the methods.
98 */ 99 */
99 template<typename K, typename V> 100 template<typename K, typename V>
100 class StrongMapTraits : public StdMapTraits<K, V> { 101 class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
101 public: 102 public:
102 // Weak callback & friends: 103 // Weak callback & friends:
103 static const bool kIsWeak = false; 104 static const bool kIsWeak = false;
104 typedef typename StdMapTraits<K, V>::Impl Impl; 105 typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
106 MapType;
105 typedef void WeakCallbackDataType; 107 typedef void WeakCallbackDataType;
108
106 static WeakCallbackDataType* WeakCallbackParameter( 109 static WeakCallbackDataType* WeakCallbackParameter(
107 Impl* impl, const K& key, Local<V> value); 110 MapType* map, const K& key, Local<V> value) {
108 static Impl* ImplFromWeakCallbackData( 111 return NULL;
109 const WeakCallbackData<V, WeakCallbackDataType>& data); 112 }
113 static MapType* MapFromWeakCallbackData(
114 const WeakCallbackData<V, WeakCallbackDataType>& data) {
115 return NULL;
116 }
110 static K KeyFromWeakCallbackData( 117 static K KeyFromWeakCallbackData(
111 const WeakCallbackData<V, WeakCallbackDataType>& data); 118 const WeakCallbackData<V, WeakCallbackDataType>& data) {
112 static void DisposeCallbackData(WeakCallbackDataType* data); 119 return K();
120 }
121 static void DisposeCallbackData(WeakCallbackDataType* data) { }
122 static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { }
113 }; 123 };
114 124
115 125
116 /**
117 * A default trait implementation for PersistentValueMap, with a std::map
118 * backing map, non-weak persistents as values, and no special dispose
119 * handling. Can be used as-is.
120 */
121 template<typename K, typename V>
122 class DefaultPersistentValueMapTraits : public StrongMapTraits<K, V> {
123 public:
124 typedef typename StrongMapTraits<K, V>::Impl Impl;
125 static void Dispose(Isolate* isolate, UniquePersistent<V> value,
126 Impl* impl, K key) { }
127 };
128
129
130 /** 126 /**
131 * A map wrapper that allows using UniquePersistent as a mapped value. 127 * A map wrapper that allows using UniquePersistent as a mapped value.
132 * C++11 embedders don't need this class, as they can use UniquePersistent 128 * C++11 embedders don't need this class, as they can use UniquePersistent
133 * directly in std containers. 129 * directly in std containers.
134 * 130 *
135 * The map relies on a backing map, whose type and accessors are described 131 * The map relies on a backing map, whose type and accessors are described
136 * by the Traits class. The backing map will handle values of type 132 * by the Traits class. The backing map will handle values of type
137 * PersistentContainerValue, with all conversion into and out of V8 133 * PersistentContainerValue, with all conversion into and out of V8
138 * handles being transparently handled by this class. 134 * handles being transparently handled by this class.
139 */ 135 */
(...skipping 20 matching lines...) Expand all
160 * Get value stored in map. 156 * Get value stored in map.
161 */ 157 */
162 V8_INLINE Local<V> Get(const K& key) { 158 V8_INLINE Local<V> Get(const K& key) {
163 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key))); 159 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
164 } 160 }
165 161
166 /** 162 /**
167 * Check whether a value is contained in the map. 163 * Check whether a value is contained in the map.
168 */ 164 */
169 V8_INLINE bool Contains(const K& key) { 165 V8_INLINE bool Contains(const K& key) {
170 return Traits::Get(&impl_, key) != 0; 166 return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
171 } 167 }
172 168
173 /** 169 /**
174 * Get value stored in map and set it in returnValue. 170 * Get value stored in map and set it in returnValue.
175 * Return true if a value was found. 171 * Return true if a value was found.
176 */ 172 */
177 V8_INLINE bool SetReturnValue(const K& key, 173 V8_INLINE bool SetReturnValue(const K& key,
178 ReturnValue<Value>& returnValue) { 174 ReturnValue<Value> returnValue) {
179 PersistentContainerValue value = Traits::Get(&impl_, key); 175 return SetReturnValueFromVal(returnValue, Traits::Get(&impl_, key));
180 bool hasValue = value != 0;
181 if (hasValue) {
182 returnValue.SetInternal(
183 *reinterpret_cast<internal::Object**>(FromVal(value)));
184 }
185 return hasValue;
186 } 176 }
187 177
188 /** 178 /**
189 * Call Isolate::SetReference with the given parent and the map value. 179 * Call Isolate::SetReference with the given parent and the map value.
190 */ 180 */
191 V8_INLINE void SetReference(const K& key, 181 V8_INLINE void SetReference(const K& key,
192 const Persistent<Object>& parent) { 182 const Persistent<Object>& parent) {
193 GetIsolate()->SetReference( 183 GetIsolate()->SetReference(
194 reinterpret_cast<internal::Object**>(parent.val_), 184 reinterpret_cast<internal::Object**>(parent.val_),
195 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); 185 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
(...skipping 28 matching lines...) Expand all
224 * in case side effects of disposal cause insertions. 214 * in case side effects of disposal cause insertions.
225 **/ 215 **/
226 void Clear() { 216 void Clear() {
227 typedef typename Traits::Iterator It; 217 typedef typename Traits::Iterator It;
228 HandleScope handle_scope(isolate_); 218 HandleScope handle_scope(isolate_);
229 // TODO(dcarney): figure out if this swap and loop is necessary. 219 // TODO(dcarney): figure out if this swap and loop is necessary.
230 while (!Traits::Empty(&impl_)) { 220 while (!Traits::Empty(&impl_)) {
231 typename Traits::Impl impl; 221 typename Traits::Impl impl;
232 Traits::Swap(impl_, impl); 222 Traits::Swap(impl_, impl);
233 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { 223 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
234 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl, 224 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
235 Traits::Key(i)); 225 Traits::Key(i));
236 } 226 }
237 } 227 }
238 } 228 }
239 229
230 /**
231 * Helper class for GetReference/SetWithReference. Do not use outside
232 * that context.
233 */
234 class PersistentValueReference {
235 public:
236 PersistentValueReference() : value_(kPersistentContainerNotFound) { }
237 Local<V> NewLocal(Isolate* isolate) const {
238 return Local<V>::New(isolate, FromVal(value_));
239 }
240 bool IsEmpty() const {
241 return value_ == kPersistentContainerNotFound;
242 }
243 template<typename T>
244 bool SetReturnValue(ReturnValue<T> returnValue) {
245 return SetReturnValueFromVal(returnValue, value_);
246 }
247 void Reset() {
248 value_ = kPersistentContainerNotFound;
249 }
250 void operator=(const PersistentValueReference& other) {
251 value_ = other.value_;
252 }
253
254 private:
255 friend class PersistentValueMap;
256 explicit PersistentValueReference(PersistentContainerValue value)
dcarney 2014/03/27 07:45:22 expose copy constructor
vogelheim 2014/03/27 14:43:54 Done.
257 : value_(value) { }
258
259 PersistentContainerValue value_;
260 };
261
262 /**
263 * Helper for V8ValueCache: Get a reference to a map value.
dcarney 2014/03/27 07:45:22 don't mention v8valuecache
vogelheim 2014/03/27 14:43:54 Done.
264 * This enables fast, repeated access to a value stored in the map
265 * while the map remains unchanged.
266 *
267 * Careful: This is potentially unsafe, in that *any* change to the
dcarney 2014/03/27 07:45:22 there are limited actions that invalidates these :
vogelheim 2014/03/27 14:43:54 Done. I'm not entirely convinced of it, though: T
268 * map may invalidate the reference.
269 */
270 V8_INLINE PersistentValueReference GetReference(const K& key) {
271 return PersistentValueReference(Traits::Get(&impl_, key));
272 }
273
274 /**
275 * Helper for V8ValueCache: Set a new persistent in the map, and
276 * also return a reference to it.
277 * This enables fast, repeated access to a value stored in the map
278 * while the map remains unchanged.
279 *
280 * Careful: This is potentially unsafe, in that *any* change to the
281 * map may invalidate the reference.
282 */
283 V8_INLINE PersistentValueReference SetWithReference(
dcarney 2014/03/27 07:45:22 no need for this function since it calls just Set
vogelheim 2014/03/27 14:43:54 Removed.
284 const K& key, UniquePersistent<V> value) {
285 Set(key, value.Pass());
286 return GetReference(key);
287 }
288
240 private: 289 private:
241 PersistentValueMap(PersistentValueMap&); 290 PersistentValueMap(PersistentValueMap&);
242 void operator=(PersistentValueMap&); 291 void operator=(PersistentValueMap&);
243 292
244 /** 293 /**
245 * Put the value into the map, and set the 'weak' callback when demanded 294 * Put the value into the map, and set the 'weak' callback when demanded
246 * by the Traits class. 295 * by the Traits class.
247 */ 296 */
248 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { 297 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
249 if (Traits::kIsWeak) { 298 if (Traits::kIsWeak) {
250 Local<V> value(Local<V>::New(isolate_, *persistent)); 299 Local<V> value(Local<V>::New(isolate_, *persistent));
251 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 300 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
252 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback); 301 Traits::WeakCallbackParameter(this, key, value), WeakCallback);
253 } 302 }
254 PersistentContainerValue old_value = 303 PersistentContainerValue old_value =
255 Traits::Set(&impl_, key, ClearAndLeak(persistent)); 304 Traits::Set(&impl_, key, ClearAndLeak(persistent));
256 return Release(old_value).Pass(); 305 return Release(old_value).Pass();
257 } 306 }
258 307
259 static void WeakCallback( 308 static void WeakCallback(
260 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { 309 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
261 if (Traits::kIsWeak) { 310 if (Traits::kIsWeak) {
262 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data); 311 PersistentValueMap<K, V, Traits>* persistentValueMap =
312 Traits::MapFromWeakCallbackData(data);
263 K key = Traits::KeyFromWeakCallbackData(data); 313 K key = Traits::KeyFromWeakCallbackData(data);
264 PersistentContainerValue value = Traits::Remove(impl, key); 314 Traits::Dispose(data.GetIsolate(),
265 Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key); 315 persistentValueMap->Remove(key).Pass(), key);
266 } 316 }
267 } 317 }
268 318
269 V8_INLINE static V* FromVal(PersistentContainerValue v) { 319 V8_INLINE static V* FromVal(PersistentContainerValue v) {
270 return reinterpret_cast<V*>(v); 320 return reinterpret_cast<V*>(v);
271 } 321 }
272 322
323 V8_INLINE static bool SetReturnValueFromVal(
324 ReturnValue<Value>& returnValue, PersistentContainerValue value) {
325 bool hasValue = value != kPersistentContainerNotFound;
326 if (hasValue) {
327 returnValue.SetInternal(
328 *reinterpret_cast<internal::Object**>(FromVal(value)));
329 }
330 return hasValue;
331 }
332
273 V8_INLINE static PersistentContainerValue ClearAndLeak( 333 V8_INLINE static PersistentContainerValue ClearAndLeak(
274 UniquePersistent<V>* persistent) { 334 UniquePersistent<V>* persistent) {
275 V* v = persistent->val_; 335 V* v = persistent->val_;
276 persistent->val_ = 0; 336 persistent->val_ = 0;
277 return reinterpret_cast<PersistentContainerValue>(v); 337 return reinterpret_cast<PersistentContainerValue>(v);
278 } 338 }
279 339
280 /** 340 /**
281 * Return a container value as UniquePersistent and make sure the weak 341 * Return a container value as UniquePersistent and make sure the weak
282 * callback is properly disposed of. All remove functionality should go 342 * callback is properly disposed of. All remove functionality should go
(...skipping 22 matching lines...) Expand all
305 * UniquePersistent directly in std containers. 365 * UniquePersistent directly in std containers.
306 */ 366 */
307 template<typename K, typename V, 367 template<typename K, typename V,
308 typename Traits = DefaultPersistentValueMapTraits<K, V> > 368 typename Traits = DefaultPersistentValueMapTraits<K, V> >
309 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { 369 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
310 public: 370 public:
311 explicit StdPersistentValueMap(Isolate* isolate) 371 explicit StdPersistentValueMap(Isolate* isolate)
312 : PersistentValueMap<K, V, Traits>(isolate) {} 372 : PersistentValueMap<K, V, Traits>(isolate) {}
313 }; 373 };
314 374
315
316 /**
317 * Empty default implementations for StrongTraits methods.
318 *
319 * These should not be necessary, since they're only used in code that
320 * is surrounded by if(Traits::kIsWeak), which for StrongMapTraits is
321 * compile-time false. Most compilers can live without them; however
322 * the compiler we use from 64-bit Win differs.
323 *
324 * TODO(vogelheim): Remove these once they're no longer necessary.
325 */
326 template<typename K, typename V>
327 typename StrongMapTraits<K, V>::WeakCallbackDataType*
328 StrongMapTraits<K, V>::WeakCallbackParameter(
329 Impl* impl, const K& key, Local<V> value) {
330 return NULL;
331 }
332
333
334 template<typename K, typename V>
335 typename StrongMapTraits<K, V>::Impl*
336 StrongMapTraits<K, V>::ImplFromWeakCallbackData(
337 const WeakCallbackData<V, WeakCallbackDataType>& data) {
338 return NULL;
339 }
340
341
342 template<typename K, typename V>
343 K StrongMapTraits<K, V>::KeyFromWeakCallbackData(
344 const WeakCallbackData<V, WeakCallbackDataType>& data) {
345 return K();
346 }
347
348
349 template<typename K, typename V>
350 void StrongMapTraits<K, V>::DisposeCallbackData(WeakCallbackDataType* data) {
351 }
352
353 } // namespace v8 375 } // namespace v8
354 376
355 #endif // V8_UTIL_H_ 377 #endif // V8_UTIL_H_
OLDNEW
« 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