V8 Project
v8-util.h
Go to the documentation of this file.
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_UTIL_H_
6 #define V8_UTIL_H_
7 
8 #include "v8.h"
9 #include <map>
10 #include <vector>
11 
12 /**
13  * Support for Persistent containers.
14  *
15  * C++11 embedders can use STL containers with UniquePersistent values,
16  * but pre-C++11 does not support the required move semantic and hence
17  * may want these container classes.
18  */
19 namespace v8 {
20 
25  kWeak
26 };
27 
28 
29 /**
30  * A default trait implemenation for PersistentValueMap which uses std::map
31  * as a backing map.
32  *
33  * Users will have to implement their own weak callbacks & dispose traits.
34  */
35 template<typename K, typename V>
36 class StdMapTraits {
37  public:
38  // STL map & related:
39  typedef std::map<K, PersistentContainerValue> Impl;
40  typedef typename Impl::iterator Iterator;
41 
42  static bool Empty(Impl* impl) { return impl->empty(); }
43  static size_t Size(Impl* impl) { return impl->size(); }
44  static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
45  static Iterator Begin(Impl* impl) { return impl->begin(); }
46  static Iterator End(Impl* impl) { return impl->end(); }
47  static K Key(Iterator it) { return it->first; }
48  static PersistentContainerValue Value(Iterator it) { return it->second; }
49  static PersistentContainerValue Set(Impl* impl, K key,
51  std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
53  if (!res.second) {
54  old_value = res.first->second;
55  res.first->second = value;
56  }
57  return old_value;
58  }
59  static PersistentContainerValue Get(Impl* impl, K key) {
60  Iterator it = impl->find(key);
61  if (it == impl->end()) return kPersistentContainerNotFound;
62  return it->second;
63  }
64  static PersistentContainerValue Remove(Impl* impl, K key) {
65  Iterator it = impl->find(key);
66  if (it == impl->end()) return kPersistentContainerNotFound;
67  PersistentContainerValue value = it->second;
68  impl->erase(it);
69  return value;
70  }
71 };
72 
73 
74 /**
75  * A default trait implementation for PersistentValueMap, which inherits
76  * a std:map backing map from StdMapTraits and holds non-weak persistent
77  * objects and has no special Dispose handling.
78  *
79  * You should not derive from this class, since MapType depends on the
80  * surrounding class, and hence a subclass cannot simply inherit the methods.
81  */
82 template<typename K, typename V>
84  public:
85  // Weak callback & friends:
89  typedef void WeakCallbackDataType;
90 
92  MapType* map, const K& key, Local<V> value) {
93  return NULL;
94  }
97  return NULL;
98  }
101  return K();
102  }
104  static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { }
105 };
106 
107 
108 /**
109  * A map wrapper that allows using UniquePersistent as a mapped value.
110  * C++11 embedders don't need this class, as they can use UniquePersistent
111  * directly in std containers.
112  *
113  * The map relies on a backing map, whose type and accessors are described
114  * by the Traits class. The backing map will handle values of type
115  * PersistentContainerValue, with all conversion into and out of V8
116  * handles being transparently handled by this class.
117  */
118 template<typename K, typename V, typename Traits>
120  public:
121  explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
122 
124 
125  Isolate* GetIsolate() { return isolate_; }
126 
127  /**
128  * Return size of the map.
129  */
130  size_t Size() { return Traits::Size(&impl_); }
131 
132  /**
133  * Return whether the map holds weak persistents.
134  */
135  bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
136 
137  /**
138  * Get value stored in map.
139  */
140  Local<V> Get(const K& key) {
141  return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
142  }
143 
144  /**
145  * Check whether a value is contained in the map.
146  */
147  bool Contains(const K& key) {
148  return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
149  }
150 
151  /**
152  * Get value stored in map and set it in returnValue.
153  * Return true if a value was found.
154  */
155  bool SetReturnValue(const K& key,
156  ReturnValue<Value> returnValue) {
157  return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
158  }
159 
160  /**
161  * Call Isolate::SetReference with the given parent and the map value.
162  */
163  void SetReference(const K& key,
164  const Persistent<Object>& parent) {
166  reinterpret_cast<internal::Object**>(parent.val_),
167  reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
168  }
169 
170  /**
171  * Put value into map. Depending on Traits::kIsWeak, the value will be held
172  * by the map strongly or weakly.
173  * Returns old value as UniquePersistent.
174  */
175  UniquePersistent<V> Set(const K& key, Local<V> value) {
176  UniquePersistent<V> persistent(isolate_, value);
177  return SetUnique(key, &persistent);
178  }
179 
180  /**
181  * Put value into map, like Set(const K&, Local<V>).
182  */
184  return SetUnique(key, &value);
185  }
186 
187  /**
188  * Return value for key and remove it from the map.
189  */
190  UniquePersistent<V> Remove(const K& key) {
191  return Release(Traits::Remove(&impl_, key)).Pass();
192  }
193 
194  /**
195  * Traverses the map repeatedly,
196  * in case side effects of disposal cause insertions.
197  **/
198  void Clear() {
199  typedef typename Traits::Iterator It;
200  HandleScope handle_scope(isolate_);
201  // TODO(dcarney): figure out if this swap and loop is necessary.
202  while (!Traits::Empty(&impl_)) {
203  typename Traits::Impl impl;
204  Traits::Swap(impl_, impl);
205  for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
206  Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
207  Traits::Key(i));
208  }
209  }
210  }
211 
212  /**
213  * Helper class for GetReference/SetWithReference. Do not use outside
214  * that context.
215  */
217  public:
220  : value_(other.value_) { }
221 
222  Local<V> NewLocal(Isolate* isolate) const {
223  return Local<V>::New(isolate, FromVal(value_));
224  }
225  bool IsEmpty() const {
227  }
228  template<typename T>
229  bool SetReturnValue(ReturnValue<T> returnValue) {
230  return SetReturnValueFromVal(&returnValue, value_);
231  }
232  void Reset() {
234  }
235  void operator=(const PersistentValueReference& other) {
236  value_ = other.value_;
237  }
238 
239  private:
240  friend class PersistentValueMap;
241 
243  : value_(value) { }
244 
246  value_ = value;
247  }
248 
250  };
251 
252  /**
253  * Get a reference to a map value. This enables fast, repeated access
254  * to a value stored in the map while the map remains unchanged.
255  *
256  * Careful: This is potentially unsafe, so please use with care.
257  * The value will become invalid if the value for this key changes
258  * in the underlying map, as a result of Set or Remove for the same
259  * key; as a result of the weak callback for the same key; or as a
260  * result of calling Clear() or destruction of the map.
261  */
263  return PersistentValueReference(Traits::Get(&impl_, key));
264  }
265 
266  /**
267  * Put a value into the map and update the reference.
268  * Restrictions of GetReference apply here as well.
269  */
271  PersistentValueReference* reference) {
272  *reference = Leak(&value);
273  return SetUnique(key, &value);
274  }
275 
276  private:
279 
280  /**
281  * Put the value into the map, and set the 'weak' callback when demanded
282  * by the Traits class.
283  */
284  UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
285  if (Traits::kCallbackType != kNotWeak) {
286  Local<V> value(Local<V>::New(isolate_, *persistent));
287  persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
288  Traits::WeakCallbackParameter(this, key, value), WeakCallback);
289  }
290  PersistentContainerValue old_value =
291  Traits::Set(&impl_, key, ClearAndLeak(persistent));
292  return Release(old_value).Pass();
293  }
294 
295  static void WeakCallback(
297  if (Traits::kCallbackType != kNotWeak) {
298  PersistentValueMap<K, V, Traits>* persistentValueMap =
299  Traits::MapFromWeakCallbackData(data);
300  K key = Traits::KeyFromWeakCallbackData(data);
301  Traits::Dispose(data.GetIsolate(),
302  persistentValueMap->Remove(key).Pass(), key);
303  Traits::DisposeCallbackData(data.GetParameter());
304  }
305  }
306 
308  return reinterpret_cast<V*>(v);
309  }
310 
312  ReturnValue<Value>* returnValue, PersistentContainerValue value) {
313  bool hasValue = value != kPersistentContainerNotFound;
314  if (hasValue) {
315  returnValue->SetInternal(
316  *reinterpret_cast<internal::Object**>(FromVal(value)));
317  }
318  return hasValue;
319  }
320 
322  UniquePersistent<V>* persistent) {
323  V* v = persistent->val_;
324  persistent->val_ = 0;
325  return reinterpret_cast<PersistentContainerValue>(v);
326  }
327 
329  UniquePersistent<V>* persistent) {
330  return reinterpret_cast<PersistentContainerValue>(persistent->val_);
331  }
332 
333  /**
334  * Return a container value as UniquePersistent and make sure the weak
335  * callback is properly disposed of. All remove functionality should go
336  * through this.
337  */
340  p.val_ = FromVal(v);
341  if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
342  Traits::DisposeCallbackData(
343  p.template ClearWeak<typename Traits::WeakCallbackDataType>());
344  }
345  return p.Pass();
346  }
347 
349  typename Traits::Impl impl_;
350 };
351 
352 
353 /**
354  * A map that uses UniquePersistent as value and std::map as the backing
355  * implementation. Persistents are held non-weak.
356  *
357  * C++11 embedders don't need this class, as they can use
358  * UniquePersistent directly in std containers.
359  */
360 template<typename K, typename V,
362 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
363  public:
364  explicit StdPersistentValueMap(Isolate* isolate)
365  : PersistentValueMap<K, V, Traits>(isolate) {}
366 };
367 
368 
370  public:
371  typedef std::vector<PersistentContainerValue> Impl;
372 
373  static void Append(Impl* impl, PersistentContainerValue value) {
374  impl->push_back(value);
375  }
376  static bool IsEmpty(const Impl* impl) {
377  return impl->empty();
378  }
379  static size_t Size(const Impl* impl) {
380  return impl->size();
381  }
382  static PersistentContainerValue Get(const Impl* impl, size_t i) {
383  return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
384  }
385  static void ReserveCapacity(Impl* impl, size_t capacity) {
386  impl->reserve(capacity);
387  }
388  static void Clear(Impl* impl) {
389  impl->clear();
390  }
391 };
392 
393 
394 /**
395  * A vector wrapper that safely stores UniquePersistent values.
396  * C++11 embedders don't need this class, as they can use UniquePersistent
397  * directly in std containers.
398  *
399  * This class relies on a backing vector implementation, whose type and methods
400  * are described by the Traits class. The backing map will handle values of type
401  * PersistentContainerValue, with all conversion into and out of V8
402  * handles being transparently handled by this class.
403  */
404 template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
406  public:
407  explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
408 
410  Clear();
411  }
412 
413  /**
414  * Append a value to the vector.
415  */
416  void Append(Local<V> value) {
417  UniquePersistent<V> persistent(isolate_, value);
418  Traits::Append(&impl_, ClearAndLeak(&persistent));
419  }
420 
421  /**
422  * Append a persistent's value to the vector.
423  */
424  void Append(UniquePersistent<V> persistent) {
425  Traits::Append(&impl_, ClearAndLeak(&persistent));
426  }
427 
428  /**
429  * Are there any values in the vector?
430  */
431  bool IsEmpty() const {
432  return Traits::IsEmpty(&impl_);
433  }
434 
435  /**
436  * How many elements are in the vector?
437  */
438  size_t Size() const {
439  return Traits::Size(&impl_);
440  }
441 
442  /**
443  * Retrieve the i-th value in the vector.
444  */
445  Local<V> Get(size_t index) const {
446  return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
447  }
448 
449  /**
450  * Remove all elements from the vector.
451  */
452  void Clear() {
453  size_t length = Traits::Size(&impl_);
454  for (size_t i = 0; i < length; i++) {
456  p.val_ = FromVal(Traits::Get(&impl_, i));
457  }
458  Traits::Clear(&impl_);
459  }
460 
461  /**
462  * Reserve capacity in the vector.
463  * (Efficiency gains depend on the backing implementation.)
464  */
465  void ReserveCapacity(size_t capacity) {
466  Traits::ReserveCapacity(&impl_, capacity);
467  }
468 
469  private:
471  UniquePersistent<V>* persistent) {
472  V* v = persistent->val_;
473  persistent->val_ = 0;
474  return reinterpret_cast<PersistentContainerValue>(v);
475  }
476 
478  return reinterpret_cast<V*>(v);
479  }
480 
482  typename Traits::Impl impl_;
483 };
484 
485 } // namespace v8
486 
487 #endif // V8_UTIL_H_
A default trait implementation for PersistentValueMap, which inherits a std:map backing map from StdM...
Definition: v8-util.h:83
PersistentValueMap< K, V, DefaultPersistentValueMapTraits< K, V > > MapType
Definition: v8-util.h:88
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:86
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:91
static MapType * MapFromWeakCallbackData(const WeakCallbackData< V, WeakCallbackDataType > &data)
Definition: v8-util.h:95
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:103
static K KeyFromWeakCallbackData(const WeakCallbackData< V, WeakCallbackDataType > &data)
Definition: v8-util.h:99
static void Dispose(Isolate *isolate, UniquePersistent< V > value, K key)
Definition: v8-util.h:104
static size_t Size(const Impl *impl)
Definition: v8-util.h:379
static bool IsEmpty(const Impl *impl)
Definition: v8-util.h:376
static void Clear(Impl *impl)
Definition: v8-util.h:388
static PersistentContainerValue Get(const Impl *impl, size_t i)
Definition: v8-util.h:382
static void Append(Impl *impl, PersistentContainerValue value)
Definition: v8-util.h:373
std::vector< PersistentContainerValue > Impl
Definition: v8-util.h:371
static void ReserveCapacity(Impl *impl, size_t capacity)
Definition: v8-util.h:385
A stack-allocated class that governs a number of local handles.
Definition: v8.h:802
Isolate represents an isolated instance of the V8 engine.
Definition: v8.h:4356
void SetReference(const Persistent< T > &parent, const Persistent< S > &child)
Allows the host application to declare implicit references from an object to another object.
Definition: v8.h:6930
A light-weight stack-allocated object handle.
Definition: v8.h:334
static Local< T > New(Isolate *isolate, Handle< T > that)
Create a local handle for the content of another handle.
Definition: v8.h:5987
bool IsWeak() const
Returns true if the handle's reference is weak.
Definition: v8.h:6073
Helper class for GetReference/SetWithReference.
Definition: v8-util.h:216
void operator=(PersistentContainerValue value)
Definition: v8-util.h:245
bool SetReturnValue(ReturnValue< T > returnValue)
Definition: v8-util.h:229
PersistentValueReference(const PersistentValueReference &other)
Definition: v8-util.h:219
PersistentValueReference(PersistentContainerValue value)
Definition: v8-util.h:242
void operator=(const PersistentValueReference &other)
Definition: v8-util.h:235
Local< V > NewLocal(Isolate *isolate) const
Definition: v8-util.h:222
A map wrapper that allows using UniquePersistent as a mapped value.
Definition: v8-util.h:119
size_t Size()
Return size of the map.
Definition: v8-util.h:130
static PersistentContainerValue Leak(UniquePersistent< V > *persistent)
Definition: v8-util.h:328
Local< V > Get(const K &key)
Get value stored in map.
Definition: v8-util.h:140
bool IsWeak()
Return whether the map holds weak persistents.
Definition: v8-util.h:135
Isolate * isolate_
Definition: v8-util.h:348
void SetReference(const K &key, const Persistent< Object > &parent)
Call Isolate::SetReference with the given parent and the map value.
Definition: v8-util.h:163
UniquePersistent< V > Set(const K &key, UniquePersistent< V > value)
Put value into map, like Set(const K&, Local<V>).
Definition: v8-util.h:183
bool Contains(const K &key)
Check whether a value is contained in the map.
Definition: v8-util.h:147
static void WeakCallback(const WeakCallbackData< V, typename Traits::WeakCallbackDataType > &data)
Definition: v8-util.h:295
UniquePersistent< V > Remove(const K &key)
Return value for key and remove it from the map.
Definition: v8-util.h:190
UniquePersistent< V > Set(const K &key, UniquePersistent< V > value, PersistentValueReference *reference)
Put a value into the map and update the reference.
Definition: v8-util.h:270
bool SetReturnValue(const K &key, ReturnValue< Value > returnValue)
Get value stored in map and set it in returnValue.
Definition: v8-util.h:155
PersistentValueReference GetReference(const K &key)
Get a reference to a map value.
Definition: v8-util.h:262
static PersistentContainerValue ClearAndLeak(UniquePersistent< V > *persistent)
Definition: v8-util.h:321
PersistentValueMap(PersistentValueMap &)
Traits::Impl impl_
Definition: v8-util.h:349
static UniquePersistent< V > Release(PersistentContainerValue v)
Return a container value as UniquePersistent and make sure the weak callback is properly disposed of.
Definition: v8-util.h:338
Isolate * GetIsolate()
Definition: v8-util.h:125
static V * FromVal(PersistentContainerValue v)
Definition: v8-util.h:307
void Clear()
Traverses the map repeatedly, in case side effects of disposal cause insertions.
Definition: v8-util.h:198
UniquePersistent< V > SetUnique(const K &key, UniquePersistent< V > *persistent)
Put the value into the map, and set the 'weak' callback when demanded by the Traits class.
Definition: v8-util.h:284
void operator=(PersistentValueMap &)
static bool SetReturnValueFromVal(ReturnValue< Value > *returnValue, PersistentContainerValue value)
Definition: v8-util.h:311
UniquePersistent< V > Set(const K &key, Local< V > value)
Put value into map.
Definition: v8-util.h:175
PersistentValueMap(Isolate *isolate)
Definition: v8-util.h:121
A vector wrapper that safely stores UniquePersistent values.
Definition: v8-util.h:405
void Append(Local< V > value)
Append a value to the vector.
Definition: v8-util.h:416
Local< V > Get(size_t index) const
Retrieve the i-th value in the vector.
Definition: v8-util.h:445
static PersistentContainerValue ClearAndLeak(UniquePersistent< V > *persistent)
Definition: v8-util.h:470
static V * FromVal(PersistentContainerValue v)
Definition: v8-util.h:477
bool IsEmpty() const
Are there any values in the vector?
Definition: v8-util.h:431
PersistentValueVector(Isolate *isolate)
Definition: v8-util.h:407
void Clear()
Remove all elements from the vector.
Definition: v8-util.h:452
void ReserveCapacity(size_t capacity)
Reserve capacity in the vector.
Definition: v8-util.h:465
size_t Size() const
How many elements are in the vector?
Definition: v8-util.h:438
Traits::Impl impl_
Definition: v8-util.h:482
void Append(UniquePersistent< V > persistent)
Append a persistent's value to the vector.
Definition: v8-util.h:424
A PersistentBase which allows copy and assignment.
Definition: v8.h:627
void SetInternal(internal::Object *value)
Definition: v8.h:2636
A default trait implemenation for PersistentValueMap which uses std::map as a backing map.
Definition: v8-util.h:36
static PersistentContainerValue Set(Impl *impl, K key, PersistentContainerValue value)
Definition: v8-util.h:49
static Iterator End(Impl *impl)
Definition: v8-util.h:46
static size_t Size(Impl *impl)
Definition: v8-util.h:43
static bool Empty(Impl *impl)
Definition: v8-util.h:42
static PersistentContainerValue Get(Impl *impl, K key)
Definition: v8-util.h:59
static K Key(Iterator it)
Definition: v8-util.h:47
static Iterator Begin(Impl *impl)
Definition: v8-util.h:45
std::map< K, PersistentContainerValue > Impl
Definition: v8-util.h:39
Impl::iterator Iterator
Definition: v8-util.h:40
static PersistentContainerValue Remove(Impl *impl, K key)
Definition: v8-util.h:64
static PersistentContainerValue Value(Iterator it)
Definition: v8-util.h:48
static void Swap(Impl &a, Impl &b)
Definition: v8-util.h:44
A map that uses UniquePersistent as value and std::map as the backing implementation.
Definition: v8-util.h:362
StdPersistentValueMap(Isolate *isolate)
Definition: v8-util.h:364
A PersistentBase which has move semantics.
Definition: v8.h:723
UniquePersistent Pass()
Pass allows returning uniques from functions, etc.
Definition: v8.h:780
Isolate * GetIsolate() const
Definition: v8.h:421
P * GetParameter() const
Definition: v8.h:423
#define V(NAME, Name, id)
Definition: execution.h:170
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
PersistentContainerCallbackType
Definition: v8-util.h:23
@ kWeak
Definition: v8-util.h:25
@ kNotWeak
Definition: v8-util.h:24
static const uintptr_t kPersistentContainerNotFound
Definition: v8-util.h:22
uintptr_t PersistentContainerValue
Definition: v8-util.h:21