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

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

Issue 204343006: Provide default traits for PersistentValueMap (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Provide default implementations for StrongMapTraits methods, plus some minor style fixes. 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 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_UTIL_H_ 28 #ifndef V8_UTIL_H_
29 #define V8_UTIL_H_ 29 #define V8_UTIL_H_
30 30
31 #include "v8.h" 31 #include "v8.h"
32 #include <map>
32 33
33 /** 34 /**
34 * Support for Persistent containers. 35 * Support for Persistent containers.
35 * 36 *
36 * C++11 embedders can use STL containers with UniquePersistent values, 37 * C++11 embedders can use STL containers with UniquePersistent values,
37 * but pre-C++11 does not support the required move semantic and hence 38 * but pre-C++11 does not support the required move semantic and hence
38 * may want these container classes. 39 * may want these container classes.
39 */ 40 */
40 namespace v8 { 41 namespace v8 {
41 42
42 typedef uintptr_t PersistentContainerValue; 43 typedef uintptr_t PersistentContainerValue;
43 static const uintptr_t kPersistentContainerNotFound = 0; 44 static const uintptr_t kPersistentContainerNotFound = 0;
44 45
46
47 /**
48 * A default trait implemenation for PersistentValueMap which uses std::map
49 * as a backing map.
50 *
51 * Users will have to implement their own weak callbacks & dispose traits.
52 */
53 template<typename K, typename V>
54 class StdMapTraits {
55 public:
56 // STL map & related:
57 typedef std::map<K, PersistentContainerValue> Impl;
58 typedef typename Impl::iterator Iterator;
59
60 static bool Empty(Impl* impl) { return impl->empty(); }
61 static size_t Size(Impl* impl) { return impl->size(); }
62 static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
63 static Iterator Begin(Impl* impl) { return impl->begin(); }
64 static Iterator End(Impl* impl) { return impl->end(); }
65 static K Key(Iterator it) { return it->first; }
66 static PersistentContainerValue Value(Iterator it) { return it->second; }
67 static PersistentContainerValue Set(Impl* impl, K key,
68 PersistentContainerValue value) {
69 std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
70 PersistentContainerValue old_value = kPersistentContainerNotFound;
71 if (!res.second) {
72 old_value = res.first->second;
73 res.first->second = value;
74 }
75 return old_value;
76 }
77 static PersistentContainerValue Get(Impl* impl, K key) {
78 Iterator it = impl->find(key);
79 if (it == impl->end()) return kPersistentContainerNotFound;
80 return it->second;
81 }
82 static PersistentContainerValue Remove(Impl* impl, K key) {
83 Iterator it = impl->find(key);
84 if (it == impl->end()) return kPersistentContainerNotFound;
85 PersistentContainerValue value = it->second;
86 impl->erase(it);
87 return value;
88 }
89 };
90
91
92 /**
93 * A default trait implementation for PersistentValueMap, which inherits
94 * a std:map backing map from StdMapTraits and holds non-weak persistent
95 * objects.
96 *
97 * Users have to implement their own dispose trait.
98 */
99 template<typename K, typename V>
100 class StrongMapTraits : public StdMapTraits<K, V> {
101 public:
102 // Weak callback & friends:
103 static const bool kIsWeak = false;
104 typedef typename StdMapTraits<K, V>::Impl Impl;
105 typedef void WeakCallbackDataType;
106 static WeakCallbackDataType* WeakCallbackParameter(
107 Impl* impl, const K& key, Local<V> value);
108 static Impl* ImplFromWeakCallbackData(
109 const WeakCallbackData<V, WeakCallbackDataType>& data);
110 static K KeyFromWeakCallbackData(
111 const WeakCallbackData<V, WeakCallbackDataType>& data);
112 static void DisposeCallbackData(WeakCallbackDataType* data);
113 };
114
115
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
45 /** 130 /**
46 * A map wrapper that allows using UniquePersistent as a mapped value. 131 * A map wrapper that allows using UniquePersistent as a mapped value.
47 * C++11 embedders don't need this class, as they can use UniquePersistent 132 * C++11 embedders don't need this class, as they can use UniquePersistent
48 * directly in std containers. 133 * directly in std containers.
49 * 134 *
50 * The map relies on a backing map, whose type and accessors are described 135 * The map relies on a backing map, whose type and accessors are described
51 * by the Traits class. The backing map will handle values of type 136 * by the Traits class. The backing map will handle values of type
52 * PersistentContainerValue, with all conversion into and out of V8 137 * PersistentContainerValue, with all conversion into and out of V8
53 * handles being transparently handled by this class. 138 * handles being transparently handled by this class.
54 */ 139 */
55 template<class K, class V, class Traits> 140 template<typename K, typename V, typename Traits>
56 class PersistentValueMap { 141 class PersistentValueMap {
57 public: 142 public:
58 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {} 143 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
59 144
60 V8_INLINE ~PersistentValueMap() { Clear(); } 145 V8_INLINE ~PersistentValueMap() { Clear(); }
61 146
62 V8_INLINE Isolate* GetIsolate() { return isolate_; } 147 V8_INLINE Isolate* GetIsolate() { return isolate_; }
63 148
64 /** 149 /**
65 * Return size of the map. 150 * Return size of the map.
66 */ 151 */
67 V8_INLINE size_t Size() { return Traits::Size(&impl_); } 152 V8_INLINE size_t Size() { return Traits::Size(&impl_); }
68 153
69 /** 154 /**
155 * Return whether the map holds weak persistents.
156 */
157 V8_INLINE bool IsWeak() { return Traits::kIsWeak; }
158
159 /**
70 * Get value stored in map. 160 * Get value stored in map.
71 */ 161 */
72 V8_INLINE Local<V> Get(const K& key) { 162 V8_INLINE Local<V> Get(const K& key) {
73 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key))); 163 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
74 } 164 }
75 165
76 /** 166 /**
77 * Check whether a value is contained in the map. 167 * Check whether a value is contained in the map.
78 */ 168 */
79 V8_INLINE bool Contains(const K& key) { 169 V8_INLINE bool Contains(const K& key) {
80 return Traits::Get(&impl_, key) != 0; 170 return Traits::Get(&impl_, key) != 0;
81 } 171 }
82 172
83 /** 173 /**
84 * Get value stored in map and set it in returnValue. 174 * Get value stored in map and set it in returnValue.
85 * Return true if a value was found. 175 * Return true if a value was found.
86 */ 176 */
87 V8_INLINE bool SetReturnValue(const K& key, 177 V8_INLINE bool SetReturnValue(const K& key,
88 ReturnValue<Value>& returnValue); 178 ReturnValue<Value>& returnValue) {
179 PersistentContainerValue value = 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 }
89 187
90 /** 188 /**
91 * Call Isolate::SetReference with the given parent and the map value. 189 * Call Isolate::SetReference with the given parent and the map value.
92 */ 190 */
93 V8_INLINE void SetReference(const K& key, 191 V8_INLINE void SetReference(const K& key,
94 const v8::Persistent<v8::Object>& parent) { 192 const Persistent<Object>& parent) {
95 GetIsolate()->SetReference( 193 GetIsolate()->SetReference(
96 reinterpret_cast<internal::Object**>(parent.val_), 194 reinterpret_cast<internal::Object**>(parent.val_),
97 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); 195 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
98 } 196 }
99 197
100 /** 198 /**
101 * Put value into map. Depending on Traits::kIsWeak, the value will be held 199 * Put value into map. Depending on Traits::kIsWeak, the value will be held
102 * by the map strongly or weakly. 200 * by the map strongly or weakly.
103 * Returns old value as UniquePersistent. 201 * Returns old value as UniquePersistent.
104 */ 202 */
(...skipping 13 matching lines...) Expand all
118 * Return value for key and remove it from the map. 216 * Return value for key and remove it from the map.
119 */ 217 */
120 V8_INLINE UniquePersistent<V> Remove(const K& key) { 218 V8_INLINE UniquePersistent<V> Remove(const K& key) {
121 return Release(Traits::Remove(&impl_, key)).Pass(); 219 return Release(Traits::Remove(&impl_, key)).Pass();
122 } 220 }
123 221
124 /** 222 /**
125 * Traverses the map repeatedly, 223 * Traverses the map repeatedly,
126 * in case side effects of disposal cause insertions. 224 * in case side effects of disposal cause insertions.
127 **/ 225 **/
128 void Clear(); 226 void Clear() {
227 typedef typename Traits::Iterator It;
228 HandleScope handle_scope(isolate_);
229 // TODO(dcarney): figure out if this swap and loop is necessary.
230 while (!Traits::Empty(&impl_)) {
231 typename Traits::Impl impl;
232 Traits::Swap(impl_, impl);
233 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
234 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
235 Traits::Key(i));
236 }
237 }
238 }
129 239
130 private: 240 private:
131 PersistentValueMap(PersistentValueMap&); 241 PersistentValueMap(PersistentValueMap&);
132 void operator=(PersistentValueMap&); 242 void operator=(PersistentValueMap&);
133 243
134 /** 244 /**
135 * Put the value into the map, and set the 'weak' callback when demanded 245 * Put the value into the map, and set the 'weak' callback when demanded
136 * by the Traits class. 246 * by the Traits class.
137 */ 247 */
138 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { 248 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
139 if (Traits::kIsWeak) { 249 if (Traits::kIsWeak) {
140 Local<V> value(Local<V>::New(isolate_, *persistent)); 250 Local<V> value(Local<V>::New(isolate_, *persistent));
141 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 251 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
142 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback); 252 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
143 } 253 }
144 PersistentContainerValue old_value = 254 PersistentContainerValue old_value =
145 Traits::Set(&impl_, key, ClearAndLeak(persistent)); 255 Traits::Set(&impl_, key, ClearAndLeak(persistent));
146 return Release(old_value).Pass(); 256 return Release(old_value).Pass();
147 } 257 }
148 258
149 static void WeakCallback( 259 static void WeakCallback(
150 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data); 260 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
261 if (Traits::kIsWeak) {
262 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
263 K key = Traits::KeyFromWeakCallbackData(data);
264 PersistentContainerValue value = Traits::Remove(impl, key);
265 Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key);
266 }
267 }
268
151 V8_INLINE static V* FromVal(PersistentContainerValue v) { 269 V8_INLINE static V* FromVal(PersistentContainerValue v) {
152 return reinterpret_cast<V*>(v); 270 return reinterpret_cast<V*>(v);
153 } 271 }
272
154 V8_INLINE static PersistentContainerValue ClearAndLeak( 273 V8_INLINE static PersistentContainerValue ClearAndLeak(
155 UniquePersistent<V>* persistent) { 274 UniquePersistent<V>* persistent) {
156 V* v = persistent->val_; 275 V* v = persistent->val_;
157 persistent->val_ = 0; 276 persistent->val_ = 0;
158 return reinterpret_cast<PersistentContainerValue>(v); 277 return reinterpret_cast<PersistentContainerValue>(v);
159 } 278 }
160 279
161 /** 280 /**
162 * Return a container value as UniquePersistent and make sure the weak 281 * Return a container value as UniquePersistent and make sure the weak
163 * callback is properly disposed of. All remove functionality should go 282 * callback is properly disposed of. All remove functionality should go
164 * through this. 283 * through this.
165 */ 284 */
166 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) { 285 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
167 UniquePersistent<V> p; 286 UniquePersistent<V> p;
168 p.val_ = FromVal(v); 287 p.val_ = FromVal(v);
169 if (Traits::kIsWeak && !p.IsEmpty()) { 288 if (Traits::kIsWeak && !p.IsEmpty()) {
170 Traits::DisposeCallbackData( 289 Traits::DisposeCallbackData(
171 p.template ClearWeak<typename Traits::WeakCallbackDataType>()); 290 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
172 } 291 }
173 return p.Pass(); 292 return p.Pass();
174 } 293 }
175 294
176 Isolate* isolate_; 295 Isolate* isolate_;
177 typename Traits::Impl impl_; 296 typename Traits::Impl impl_;
178 }; 297 };
179 298
180 template <class K, class V, class Traits>
181 bool PersistentValueMap<K, V, Traits>::SetReturnValue(const K& key,
182 ReturnValue<Value>& returnValue) {
183 PersistentContainerValue value = Traits::Get(&impl_, key);
184 bool hasValue = value != 0;
185 if (hasValue) {
186 returnValue.SetInternal(
187 *reinterpret_cast<internal::Object**>(FromVal(value)));
188 }
189 return hasValue;
190 }
191 299
192 template <class K, class V, class Traits> 300 /**
193 void PersistentValueMap<K, V, Traits>::Clear() { 301 * A map that uses UniquePersistent as value and std::map as the backing
194 typedef typename Traits::Iterator It; 302 * implementation. Persistents are held non-weak.
195 HandleScope handle_scope(isolate_); 303 *
196 // TODO(dcarney): figure out if this swap and loop is necessary. 304 * C++11 embedders don't need this class, as they can use
197 while (!Traits::Empty(&impl_)) { 305 * UniquePersistent directly in std containers.
198 typename Traits::Impl impl; 306 */
199 Traits::Swap(impl_, impl); 307 template<typename K, typename V,
200 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { 308 typename Traits = DefaultPersistentValueMapTraits<K, V> >
201 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl, 309 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
202 Traits::Key(i)); 310 public:
203 } 311 explicit StdPersistentValueMap(Isolate* isolate)
204 } 312 : PersistentValueMap<K, V, Traits>(isolate) {}
313 };
314
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;
205 } 331 }
206 332
207 333
208 template <class K, class V, class Traits> 334 template<typename K, typename V>
209 void PersistentValueMap<K, V, Traits>::WeakCallback( 335 typename StrongMapTraits<K, V>::Impl*
210 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { 336 StrongMapTraits<K, V>::ImplFromWeakCallbackData(
211 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data); 337 const WeakCallbackData<V, WeakCallbackDataType>& data) {
212 K key = Traits::KeyFromWeakCallbackData(data); 338 return NULL;
213 PersistentContainerValue value = Traits::Remove(impl, key); 339 }
214 Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key); 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) {
215 } 351 }
216 352
217 } // namespace v8 353 } // namespace v8
218 354
219 #endif // V8_UTIL_H_ 355 #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