OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 return WTF::wrapUnique(new DOMObjectHolder(isolate, object, wrapper)); | 74 return WTF::wrapUnique(new DOMObjectHolder(isolate, object, wrapper)); |
75 } | 75 } |
76 | 76 |
77 private: | 77 private: |
78 DOMObjectHolder(v8::Isolate* isolate, T* object, v8::Local<v8::Value> wrapper) | 78 DOMObjectHolder(v8::Isolate* isolate, T* object, v8::Local<v8::Value> wrapper) |
79 : DOMObjectHolderBase(isolate, wrapper), m_object(object) {} | 79 : DOMObjectHolderBase(isolate, wrapper), m_object(object) {} |
80 | 80 |
81 Persistent<T> m_object; | 81 Persistent<T> m_object; |
82 }; | 82 }; |
83 | 83 |
84 using WorldMap = HashMap<int, DOMWrapperWorld*>; | |
85 | |
86 static WorldMap& workerWorldMap() { | |
87 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<WorldMap>, map, | |
88 new ThreadSpecific<WorldMap>); | |
89 return *map; | |
90 } | |
91 | |
84 unsigned DOMWrapperWorld::isolatedWorldCount = 0; | 92 unsigned DOMWrapperWorld::isolatedWorldCount = 0; |
85 | 93 |
86 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(v8::Isolate* isolate, | 94 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(v8::Isolate* isolate, |
87 int worldId) { | 95 int worldId) { |
88 return adoptRef(new DOMWrapperWorld(isolate, worldId)); | 96 return adoptRef(new DOMWrapperWorld(isolate, worldId)); |
89 } | 97 } |
90 | 98 |
91 DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate, int worldId) | 99 DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate, int worldId) |
92 : m_worldId(worldId), | 100 : m_worldId(worldId), |
93 m_domDataStore( | 101 m_domDataStore( |
94 WTF::wrapUnique(new DOMDataStore(isolate, isMainWorld()))) { | 102 WTF::wrapUnique(new DOMDataStore(isolate, isMainWorld()))) { |
95 if (worldId == WorkerWorldId) { | 103 if (worldId == WorkerWorldId) { |
96 workerWorld() = this; | 104 WorldMap& map = workerWorldMap(); |
105 DCHECK(!map.contains(worldId)); | |
106 map.insert(worldId, this); | |
Yuki
2017/03/07 10:17:16
Does this support multiple worlds in a thread?
II
nhiroki
2017/03/07 10:45:14
You're right. This doesn't make sense. Is it ok to
nhiroki
2017/03/07 10:51:40
Or, how about separating WorldIdConstants into tag
Yuki
2017/03/07 11:51:26
I'm personally okay to introduce IsolatedWorldIdLi
| |
97 } | 107 } |
98 } | 108 } |
99 | 109 |
100 DOMWrapperWorld& DOMWrapperWorld::mainWorld() { | 110 DOMWrapperWorld& DOMWrapperWorld::mainWorld() { |
101 ASSERT(isMainThread()); | 111 ASSERT(isMainThread()); |
102 DEFINE_STATIC_REF( | 112 DEFINE_STATIC_REF( |
103 DOMWrapperWorld, cachedMainWorld, | 113 DOMWrapperWorld, cachedMainWorld, |
104 (DOMWrapperWorld::create(v8::Isolate::GetCurrent(), MainWorldId))); | 114 (DOMWrapperWorld::create(v8::Isolate::GetCurrent(), MainWorldId))); |
105 return *cachedMainWorld; | 115 return *cachedMainWorld; |
106 } | 116 } |
107 | 117 |
108 DOMWrapperWorld*& DOMWrapperWorld::workerWorld() { | |
109 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<DOMWrapperWorld*>, workerWorld, | |
110 new ThreadSpecific<DOMWrapperWorld*>); | |
111 return *workerWorld; | |
112 } | |
113 | |
114 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::fromWorldId(v8::Isolate* isolate, | 118 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::fromWorldId(v8::Isolate* isolate, |
115 int worldId) { | 119 int worldId) { |
116 if (worldId == MainWorldId) | 120 if (worldId == MainWorldId) |
117 return &mainWorld(); | 121 return &mainWorld(); |
118 return ensureIsolatedWorld(isolate, worldId); | 122 return ensureIsolatedWorld(isolate, worldId); |
119 } | 123 } |
120 | 124 |
121 typedef HashMap<int, DOMWrapperWorld*> WorldMap; | |
122 static WorldMap& isolatedWorldMap() { | 125 static WorldMap& isolatedWorldMap() { |
123 ASSERT(isMainThread()); | 126 ASSERT(isMainThread()); |
124 DEFINE_STATIC_LOCAL(WorldMap, map, ()); | 127 DEFINE_STATIC_LOCAL(WorldMap, map, ()); |
125 return map; | 128 return map; |
126 } | 129 } |
127 | 130 |
128 void DOMWrapperWorld::allWorldsInMainThread( | 131 void DOMWrapperWorld::allWorldsInMainThread( |
129 Vector<RefPtr<DOMWrapperWorld>>& worlds) { | 132 Vector<RefPtr<DOMWrapperWorld>>& worlds) { |
130 ASSERT(isMainThread()); | 133 ASSERT(isMainThread()); |
131 worlds.push_back(&mainWorld()); | 134 worlds.push_back(&mainWorld()); |
132 WorldMap& isolatedWorlds = isolatedWorldMap(); | 135 for (auto worldById : workerWorldMap()) |
133 for (WorldMap::iterator it = isolatedWorlds.begin(); | 136 worlds.push_back(worldById.value); |
134 it != isolatedWorlds.end(); ++it) | 137 for (auto worldById : isolatedWorldMap()) |
135 worlds.push_back(it->value); | 138 worlds.push_back(worldById.value); |
136 } | 139 } |
137 | 140 |
138 void DOMWrapperWorld::markWrappersInAllWorlds( | 141 void DOMWrapperWorld::markWrappersInAllWorlds( |
139 ScriptWrappable* scriptWrappable, | 142 ScriptWrappable* scriptWrappable, |
140 const ScriptWrappableVisitor* visitor) { | 143 const ScriptWrappableVisitor* visitor) { |
141 // Handle marking in per-worker wrapper worlds. | 144 if (isMainThread()) |
142 if (!isMainThread()) { | 145 scriptWrappable->markWrapper(visitor); |
143 DCHECK(ThreadState::current()->isolate()); | 146 |
144 DOMWrapperWorld* worker = workerWorld(); | 147 // Marking for the per-worker-or-worklet wrapper worlds. Worklets can be |
145 if (worker) { | 148 // created on the main thread, so we iterate the worker worlds even if we're |
146 DOMDataStore& dataStore = worker->domDataStore(); | 149 // on the main thread. |
147 if (dataStore.containsWrapper(scriptWrappable)) { | 150 DCHECK(ThreadState::current()->isolate()); |
148 dataStore.markWrapper(scriptWrappable); | 151 WorldMap& workerWorlds = workerWorldMap(); |
149 } | 152 for (auto& world : workerWorlds.values()) { |
150 } | 153 DOMDataStore& dataStore = world->domDataStore(); |
151 return; | 154 if (dataStore.containsWrapper(scriptWrappable)) |
155 dataStore.markWrapper(scriptWrappable); | |
152 } | 156 } |
153 | 157 |
154 scriptWrappable->markWrapper(visitor); | 158 // The isolated worlds should exist only on the main thread. |
159 if (!isMainThread()) | |
160 return; | |
161 | |
162 // Marking for the isolated worlds. | |
155 WorldMap& isolatedWorlds = isolatedWorldMap(); | 163 WorldMap& isolatedWorlds = isolatedWorldMap(); |
156 for (auto& world : isolatedWorlds.values()) { | 164 for (auto& world : isolatedWorlds.values()) { |
157 DOMDataStore& dataStore = world->domDataStore(); | 165 DOMDataStore& dataStore = world->domDataStore(); |
158 if (dataStore.containsWrapper(scriptWrappable)) { | 166 if (dataStore.containsWrapper(scriptWrappable)) |
159 // Marking for the isolated worlds | |
160 dataStore.markWrapper(scriptWrappable); | 167 dataStore.markWrapper(scriptWrappable); |
161 } | |
162 } | 168 } |
163 } | 169 } |
164 | 170 |
165 DOMWrapperWorld::~DOMWrapperWorld() { | 171 DOMWrapperWorld::~DOMWrapperWorld() { |
166 ASSERT(!isMainWorld()); | 172 ASSERT(!isMainWorld()); |
167 | 173 |
168 dispose(); | 174 dispose(); |
169 | 175 |
170 if (!isIsolatedWorld()) | 176 if (!isIsolatedWorld()) |
171 return; | 177 return; |
172 | 178 |
173 WorldMap& map = isolatedWorldMap(); | 179 WorldMap& map = isolatedWorldMap(); |
174 WorldMap::iterator it = map.find(m_worldId); | 180 WorldMap::iterator it = map.find(m_worldId); |
175 if (it == map.end()) { | 181 if (it == map.end()) { |
176 ASSERT_NOT_REACHED(); | 182 ASSERT_NOT_REACHED(); |
177 return; | 183 return; |
178 } | 184 } |
179 ASSERT(it->value == this); | 185 ASSERT(it->value == this); |
180 | 186 |
181 map.remove(it); | 187 map.remove(it); |
182 isolatedWorldCount--; | 188 isolatedWorldCount--; |
183 } | 189 } |
184 | 190 |
185 void DOMWrapperWorld::dispose() { | 191 void DOMWrapperWorld::dispose() { |
186 m_domObjectHolders.clear(); | 192 m_domObjectHolders.clear(); |
187 m_domDataStore.reset(); | 193 m_domDataStore.reset(); |
188 if (isWorkerWorld()) | 194 if (isWorkerWorld()) { |
189 workerWorld() = nullptr; | 195 WorldMap& map = workerWorldMap(); |
196 DCHECK(map.contains(m_worldId)); | |
197 map.remove(m_worldId); | |
198 } | |
190 } | 199 } |
191 | 200 |
192 #if DCHECK_IS_ON() | 201 #if DCHECK_IS_ON() |
193 static bool isIsolatedWorldId(int worldId) { | 202 static bool isIsolatedWorldId(int worldId) { |
194 return MainWorldId < worldId && worldId < IsolatedWorldIdLimit; | 203 return MainWorldId < worldId && worldId < IsolatedWorldIdLimit; |
195 } | 204 } |
196 #endif | 205 #endif |
197 | 206 |
198 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld( | 207 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld( |
199 v8::Isolate* isolate, | 208 v8::Isolate* isolate, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 m_domObjectHolders.erase(holderBase); | 318 m_domObjectHolders.erase(holderBase); |
310 } | 319 } |
311 | 320 |
312 void DOMWrapperWorld::weakCallbackForDOMObjectHolder( | 321 void DOMWrapperWorld::weakCallbackForDOMObjectHolder( |
313 const v8::WeakCallbackInfo<DOMObjectHolderBase>& data) { | 322 const v8::WeakCallbackInfo<DOMObjectHolderBase>& data) { |
314 DOMObjectHolderBase* holderBase = data.GetParameter(); | 323 DOMObjectHolderBase* holderBase = data.GetParameter(); |
315 holderBase->world()->unregisterDOMObjectHolder(holderBase); | 324 holderBase->world()->unregisterDOMObjectHolder(holderBase); |
316 } | 325 } |
317 | 326 |
318 } // namespace blink | 327 } // namespace blink |
OLD | NEW |