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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp

Issue 2735823006: Bindings: Manage multiple DOMWrapperWorlds for worklets (Closed)
Patch Set: Created 3 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 | no next file » | 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) 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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698