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

Side by Side Diff: Source/bindings/v8/DOMWrapperMap.h

Issue 180363004: Convert DOMWrapperMap to use PersistentValueMap (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 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
« no previous file with comments | « no previous file | Source/bindings/v8/V8NPObject.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 14 matching lines...) Expand all
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #ifndef DOMWrapperMap_h 31 #ifndef DOMWrapperMap_h
32 #define DOMWrapperMap_h 32 #define DOMWrapperMap_h
33 33
34 #include "bindings/v8/UnsafePersistent.h" 34 #include "bindings/v8/UnsafePersistent.h"
35 #include "bindings/v8/V8NPObject.h"
35 #include "bindings/v8/WrapperTypeInfo.h" 36 #include "bindings/v8/WrapperTypeInfo.h"
36 #include <v8.h> 37 #include <v8.h>
37 #include "wtf/HashMap.h" 38 #include "wtf/HashMap.h"
39 #include <stdio.h>
38 40
39 namespace WebCore { 41 namespace WebCore {
40 42
41 template<class KeyType> 43 template<class KeyType>
42 class DOMWrapperMap { 44 class DOMWrapperMap {
43 public: 45 public:
44 typedef HashMap<KeyType*, UnsafePersistent<v8::Object> > MapType;
45
46 explicit DOMWrapperMap(v8::Isolate* isolate) 46 explicit DOMWrapperMap(v8::Isolate* isolate)
47 : m_isolate(isolate) 47 : m_isolate(isolate)
48 , m_map(isolate)
48 { 49 {
49 } 50 }
50 51
51 v8::Handle<v8::Object> newLocal(KeyType* key, v8::Isolate* isolate) 52 v8::Handle<v8::Object> newLocal(KeyType* key, v8::Isolate* isolate)
52 { 53 {
53 return m_map.get(key).newLocal(isolate); 54 return v8::Local<v8::Object>::New(isolate, m_map.Get(key));
dcarney 2014/03/07 09:38:24 Get already returns a local, no need to double wra
vogelheim 2014/03/07 18:01:34 Done.
54 } 55 }
55 56
56 bool setReturnValueFrom(v8::ReturnValue<v8::Value> returnValue, KeyType* key ) 57 bool setReturnValueFrom(v8::ReturnValue<v8::Value> returnValue, KeyType* key )
57 { 58 {
58 typename MapType::iterator it = m_map.find(key); 59 v8::Local<v8::Object> value = m_map.Get(key);
dcarney 2014/03/07 09:38:24 we don't want to create a local for setting a retu
vogelheim 2014/03/07 18:01:34 Done.
59 if (it == m_map.end()) 60 bool hasValue = !value.IsEmpty();
60 return false; 61 if (hasValue) {
61 returnValue.Set(*(it->value.persistent())); 62 returnValue.Set(value);
62 return true; 63 }
64 return hasValue;
63 } 65 }
64 66
65 void setReference(const v8::Persistent<v8::Object>& parent, KeyType* key, v8 ::Isolate* isolate) 67 void setReference(const v8::Persistent<v8::Object>& parent, KeyType* key, v8 ::Isolate* isolate)
66 { 68 {
67 m_map.get(key).setReferenceFrom(parent, isolate); 69 v8::Persistent<v8::Object> ref(isolate, m_map.Get(key));
dcarney 2014/03/07 09:38:24 push to PersistentValueMap
vogelheim 2014/03/07 18:01:34 Done.
70 isolate->SetReference(parent, ref);
68 } 71 }
69 72
70 bool containsKey(KeyType* key) 73 bool containsKey(KeyType* key)
71 { 74 {
72 return m_map.find(key) != m_map.end(); 75 return !m_map.Get(key).IsEmpty();
dcarney 2014/03/07 09:38:24 too expensive - push to PersistentValueMap
vogelheim 2014/03/07 18:01:34 Done.
73 } 76 }
74 77
75 bool containsKeyAndValue(KeyType* key, v8::Handle<v8::Object> value) 78 bool containsKeyAndValue(KeyType* key, v8::Handle<v8::Object> value)
76 { 79 {
77 typename MapType::iterator it = m_map.find(key); 80 v8::Local<v8::Object> mapValue = m_map.Get(key);
dcarney 2014/03/07 09:38:24 this function is stupid and only used in an assert
vogelheim 2014/03/07 18:01:34 Done. Actually, it drops out with this change, si
78 if (it == m_map.end()) 81 return !mapValue.IsEmpty() && (mapValue == value);
79 return false;
80 return *(it->value.persistent()) == value;
81 } 82 }
82 83
83 void set(KeyType* key, v8::Handle<v8::Object> wrapper, const WrapperConfigur ation& configuration) 84 void set(KeyType* key, v8::Handle<v8::Object> wrapper, const WrapperConfigur ation& configuration)
84 { 85 {
85 ASSERT(static_cast<KeyType*>(toNative(wrapper)) == key); 86 ASSERT(static_cast<KeyType*>(toNative(wrapper)) == key);
86 v8::Persistent<v8::Object> persistent(m_isolate, wrapper); 87 ASSERT(!wrapper.IsEmpty());
dcarney 2014/03/07 09:38:24 this is asserted in the line above, drop
vogelheim 2014/03/07 18:01:34 Done.
87 configuration.configureWrapper(&persistent); 88 m_map.SetWithConfig(key, v8::Local<v8::Object>::New(m_isolate, wrapper),
dcarney 2014/03/07 09:38:24 no need for local::new
vogelheim 2014/03/07 18:01:34 Done.
88 persistent.SetWeak(this, &setWeakCallback); 89 configuration.classId, configuration.lifetime);
89 typename MapType::AddResult result = m_map.add(key, UnsafePersistent<v8: :Object>());
90 ASSERT(result.isNewEntry);
91 // FIXME: Stop handling this case once duplicate wrappers are guaranteed not to be created.
92 if (!result.isNewEntry)
93 result.storedValue->value.dispose();
94 result.storedValue->value = UnsafePersistent<v8::Object>(persistent);
95 } 90 }
96 91
97 void clear() 92 void clear()
98 { 93 {
99 v8::HandleScope scope(m_isolate); 94 m_map.Clear();
100 while (!m_map.isEmpty()) {
101 // Swap out m_map on each iteration to ensure any wrappers added due to side effects of the loop are cleared.
102 MapType map;
103 map.swap(m_map);
104 for (typename MapType::iterator it = map.begin(); it != map.end(); + +it) {
105 releaseObject(it->value.newLocal(m_isolate));
106 it->value.dispose();
107 }
108 }
109 } 95 }
110 96
111 void removeAndDispose(KeyType* key) 97 void removeAndDispose(KeyType* key)
112 { 98 {
113 typename MapType::iterator it = m_map.find(key); 99 m_map.Remove(key);
114 ASSERT_WITH_SECURITY_IMPLICATION(it != m_map.end());
115 it->value.dispose();
116 m_map.remove(it);
117 } 100 }
118 101
119 private: 102 private:
120 static void setWeakCallback(const v8::WeakCallbackData<v8::Object, DOMWrappe rMap<KeyType> >&); 103 class PersistentValueMapTraits {
104 public:
105 typedef HashMap<KeyType*, v8::PersistentContainerValue> Impl;
106 typedef typename Impl::iterator Iterator;
107
108 class WeakCallbackDataType {
dcarney 2014/03/07 09:38:24 WeakCallbackDataType should just be a point to the
vogelheim 2014/03/07 18:01:34 Done. I find this a weird design, though. This cl
109 public:
110 WeakCallbackDataType(Impl* impl, KeyType* key, v8::Local<v8::Object> & value)
111 : m_impl(impl)
112 , m_key(key)
113 , m_value(value)
114 { }
115 Impl* m_impl;
116 KeyType* m_key;
117 v8::Local<v8::Object> m_value;
118 };
119
120 static const bool kIsWeak = true;
121
122 // Container API: Size/Empty/Swap/Begin/End/Value/Set/Get/Remove
123 static size_t Size(const Impl* impl) { return impl->size(); }
124 static bool Empty(Impl* impl) { return impl->isEmpty(); }
125 static void Swap(Impl& impl, Impl& other) { impl.swap(other); }
126
127 static Iterator Begin(Impl* impl) { return impl->begin(); }
128 static Iterator End(Impl* impl) { return impl->end(); }
129 static v8::PersistentContainerValue Value(Iterator& iter)
130 {
131 return iter->value;
132 }
133 static KeyType* Key(Iterator& iter) { return iter->key; }
134
135 static v8::PersistentContainerValue Set(
136 Impl* impl, KeyType* key, v8::PersistentContainerValue value)
137 {
138 v8::PersistentContainerValue oldValue = Get(impl, key);
dcarney 2014/03/07 09:38:24 this function seems inefficient - is there a way t
vogelheim 2014/03/07 18:01:34 Done.
139 impl->add(key, value);
140 return oldValue;
141 }
142
143 static v8::PersistentContainerValue Get(const Impl* impl, KeyType* key)
144 {
145 return impl->get(key);
146 }
147
148 static v8::PersistentContainerValue Remove(Impl* impl, KeyType* key)
149 {
150 return impl->take(key);
151 }
152
153 // Dispose callbacks:
154 static void DisposeByValue(v8::UniquePersistent<v8::Object> value, v8::I solate* isolate) { }
155 static void DisposeByKey(Impl* impl, KeyType* key) { }
156
157 // WeakCallbackDataType, create/dispose, conversion, callback.
158 static WeakCallbackDataType* WeakCallbackParameter(Impl* impl, KeyType* key, v8::Local<v8::Object>& value)
159 {
160 // ??? value is unused?
161 return new WeakCallbackDataType(impl, key, value);
dcarney 2014/03/07 09:38:24 just return 'this'
vogelheim 2014/03/07 18:01:34 Done. (Actually impl, but hat's probably what you
162 }
163
164 static void DisposeCallbackData(WeakCallbackDataType* callbackData)
165 {
166 delete callbackData;
dcarney 2014/03/07 09:38:24 should be empty
vogelheim 2014/03/07 18:01:34 Done.
167 }
168
169 static Impl* ImplFromWeakCallbackData(
170 v8::WeakCallbackData<v8::Object, WeakCallbackDataType> data)
171 {
172 return data.GetParameter()->m_impl;
173 }
174
175 static KeyType* KeyFromWeakCallbackData(
176 v8::WeakCallbackData<v8::Object, WeakCallbackDataType> data)
177 {
178 return data.GetParameter()->m_key;
179 }
180 };
121 181
122 v8::Isolate* m_isolate; 182 v8::Isolate* m_isolate;
123 MapType m_map; 183 v8::PersistentValueMap<KeyType*, v8::Object, PersistentValueMapTraits> m_map ;
124 }; 184 };
125 185
126 template<> 186 template <>
127 inline void DOMWrapperMap<void>::setWeakCallback(const v8::WeakCallbackData<v8:: Object, DOMWrapperMap<void> >& data) 187 inline void DOMWrapperMap<void>::PersistentValueMapTraits::DisposeByValue(
188 v8::UniquePersistent<v8::Object> value,
189 v8::Isolate* isolate)
128 { 190 {
129 void* key = static_cast<void*>(toNative(data.GetValue())); 191 releaseObject(v8::Local<v8::Object>::New(isolate, value));
130 ASSERT(*data.GetParameter()->m_map.get(key).persistent() == data.GetValue()) ; 192 }
131 data.GetParameter()->removeAndDispose(key); 193
132 releaseObject(data.GetValue()); 194 template <>
195 inline void DOMWrapperMap<NPObject>::PersistentValueMapTraits::DisposeByKey(
196 DOMWrapperMap<NPObject>::PersistentValueMapTraits::Impl* impl,
197 NPObject* key)
dcarney 2014/03/07 09:38:24 this needs to go to the file where it's currently
vogelheim 2014/03/07 18:01:34 Done. For my understanding: Why? I thought it rat
198 {
199 DOMWrapperMapDisposeHelper(key);
133 } 200 }
134 201
135 } // namespace WebCore 202 } // namespace WebCore
136 203
137 #endif // DOMWrapperMap_h 204 #endif // DOMWrapperMap_h
OLDNEW
« no previous file with comments | « no previous file | Source/bindings/v8/V8NPObject.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698