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

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

Issue 2414333003: WebMessaging: Send transferable ArrayBuffers by copy-and-neuter semantics (Closed)
Patch Set: remake Created 4 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 const LChar* src = m_data.characters8(); 142 const LChar* src = m_data.characters8();
143 for (size_t i = 0; i < length; i++) 143 for (size_t i = 0; i < length; i++)
144 dst[i] = htons(static_cast<UChar>(src[i])); 144 dst[i] = htons(static_cast<UChar>(src[i]));
145 } else { 145 } else {
146 const UChar* src = m_data.characters16(); 146 const UChar* src = m_data.characters16();
147 for (size_t i = 0; i < length; i++) 147 for (size_t i = 0; i < length; i++)
148 dst[i] = htons(src[i]); 148 dst[i] = htons(src[i]);
149 } 149 }
150 } 150 }
151 151
152 static void acculumateArrayBuffersForAllWorlds( 152 static void accumulateArrayBuffersForAllWorlds(
153 v8::Isolate* isolate, 153 v8::Isolate* isolate,
154 DOMArrayBuffer* object, 154 DOMArrayBuffer* object,
155 Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) { 155 Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) {
156 if (isMainThread()) { 156 if (isMainThread()) {
157 Vector<RefPtr<DOMWrapperWorld>> worlds; 157 Vector<RefPtr<DOMWrapperWorld>> worlds;
158 DOMWrapperWorld::allWorldsInMainThread(worlds); 158 DOMWrapperWorld::allWorldsInMainThread(worlds);
159 for (size_t i = 0; i < worlds.size(); i++) { 159 for (size_t i = 0; i < worlds.size(); i++) {
160 v8::Local<v8::Object> wrapper = 160 v8::Local<v8::Object> wrapper =
161 worlds[i]->domDataStore().get(object, isolate); 161 worlds[i]->domDataStore().get(object, isolate);
162 if (!wrapper.IsEmpty()) 162 if (!wrapper.IsEmpty())
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 223 }
224 visited.add(offscreenCanvases[i].get()); 224 visited.add(offscreenCanvases[i].get());
225 offscreenCanvases[i].get()->setNeutered(); 225 offscreenCanvases[i].get()->setNeutered();
226 } 226 }
227 } 227 }
228 228
229 void SerializedScriptValue::transferArrayBuffers( 229 void SerializedScriptValue::transferArrayBuffers(
230 v8::Isolate* isolate, 230 v8::Isolate* isolate,
231 const ArrayBufferArray& arrayBuffers, 231 const ArrayBufferArray& arrayBuffers,
232 ExceptionState& exceptionState) { 232 ExceptionState& exceptionState) {
233 if (!arrayBuffers.size()) 233 m_arrayBufferContentsArray =
234 return; 234 transferArrayBufferContents(isolate, arrayBuffers, exceptionState);
235
236 for (size_t i = 0; i < arrayBuffers.size(); ++i) {
237 if (arrayBuffers[i]->isNeutered()) {
238 exceptionState.throwDOMException(
239 DataCloneError, "ArrayBuffer at index " + String::number(i) +
240 " is already neutered.");
241 return;
242 }
243 }
244
245 std::unique_ptr<ArrayBufferContentsArray> contents =
246 wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size()));
247
248 HeapHashSet<Member<DOMArrayBufferBase>> visited;
249 for (size_t i = 0; i < arrayBuffers.size(); ++i) {
250 if (visited.contains(arrayBuffers[i]))
251 continue;
252 visited.add(arrayBuffers[i]);
253
254 if (arrayBuffers[i]->isShared()) {
255 bool result = arrayBuffers[i]->shareContentsWith(contents->at(i));
256 if (!result) {
257 exceptionState.throwDOMException(
258 DataCloneError, "SharedArrayBuffer at index " + String::number(i) +
259 " could not be transferred.");
260 return;
261 }
262 } else {
263 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles;
264 v8::HandleScope handleScope(isolate);
265 acculumateArrayBuffersForAllWorlds(
266 isolate, static_cast<DOMArrayBuffer*>(arrayBuffers[i].get()),
267 bufferHandles);
268 bool isNeuterable = true;
269 for (size_t j = 0; j < bufferHandles.size(); ++j)
270 isNeuterable &= bufferHandles[j]->IsNeuterable();
271
272 DOMArrayBufferBase* toTransfer = arrayBuffers[i];
273 if (!isNeuterable)
274 toTransfer =
275 DOMArrayBuffer::create(arrayBuffers[i]->buffer()->data(),
276 arrayBuffers[i]->buffer()->byteLength());
277 bool result = toTransfer->transfer(contents->at(i));
278 if (!result) {
279 exceptionState.throwDOMException(
280 DataCloneError, "ArrayBuffer at index " + String::number(i) +
281 " could not be transferred.");
282 return;
283 }
284
285 if (isNeuterable)
286 for (size_t j = 0; j < bufferHandles.size(); ++j)
287 bufferHandles[j]->Neuter();
288 }
289 }
290 m_arrayBufferContentsArray = std::move(contents);
291 } 235 }
292 236
293 v8::Local<v8::Value> SerializedScriptValue::deserialize( 237 v8::Local<v8::Value> SerializedScriptValue::deserialize(
294 MessagePortArray* messagePorts) { 238 MessagePortArray* messagePorts) {
295 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); 239 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
296 } 240 }
297 241
298 v8::Local<v8::Value> SerializedScriptValue::deserialize( 242 v8::Local<v8::Value> SerializedScriptValue::deserialize(
299 v8::Isolate* isolate, 243 v8::Isolate* isolate,
300 MessagePortArray* messagePorts, 244 MessagePortArray* messagePorts,
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 transferables.offscreenCanvases.append(offscreenCanvas); 339 transferables.offscreenCanvases.append(offscreenCanvas);
396 } else { 340 } else {
397 exceptionState.throwTypeError("Value at index " + String::number(i) + 341 exceptionState.throwTypeError("Value at index " + String::number(i) +
398 " does not have a transferable type."); 342 " does not have a transferable type.");
399 return false; 343 return false;
400 } 344 }
401 } 345 }
402 return true; 346 return true;
403 } 347 }
404 348
349 std::unique_ptr<ArrayBufferContentsArray>
350 SerializedScriptValue::transferArrayBufferContents(
351 v8::Isolate* isolate,
352 const ArrayBufferArray& arrayBuffers,
353 ExceptionState& exceptionState) {
354 if (!arrayBuffers.size())
355 return nullptr;
356
357 for (size_t i = 0; i < arrayBuffers.size(); ++i) {
haraken 2016/10/19 09:49:28 Can we use an iterator? An index-based access is s
nhiroki 2016/10/20 07:44:02 Done. (Just to confirm: The out-of-range check in
358 if (arrayBuffers[i]->isNeutered()) {
359 exceptionState.throwDOMException(
360 DataCloneError, "ArrayBuffer at index " + String::number(i) +
361 " is already neutered.");
362 return nullptr;
363 }
364 }
365
366 std::unique_ptr<ArrayBufferContentsArray> contents =
367 wrapUnique(new ArrayBufferContentsArray(arrayBuffers.size()));
368
369 HeapHashSet<Member<DOMArrayBufferBase>> visited;
370 for (size_t i = 0; i < arrayBuffers.size(); ++i) {
haraken 2016/10/19 09:49:28 Ditto.
nhiroki 2016/10/20 07:44:02 Done.
371 if (visited.contains(arrayBuffers[i]))
372 continue;
373 visited.add(arrayBuffers[i]);
374
375 if (arrayBuffers[i]->isShared()) {
376 bool result = arrayBuffers[i]->shareContentsWith(contents->at(i));
377 if (!result) {
378 exceptionState.throwDOMException(
379 DataCloneError, "SharedArrayBuffer at index " + String::number(i) +
380 " could not be transferred.");
381 return nullptr;
382 }
383 } else {
384 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles;
385 v8::HandleScope handleScope(isolate);
386 accumulateArrayBuffersForAllWorlds(
387 isolate, static_cast<DOMArrayBuffer*>(arrayBuffers[i].get()),
388 bufferHandles);
389 bool isNeuterable = true;
390 for (size_t j = 0; j < bufferHandles.size(); ++j)
haraken 2016/10/19 09:49:28 Ditto.
nhiroki 2016/10/20 07:44:02 Done.
391 isNeuterable &= bufferHandles[j]->IsNeuterable();
392
393 DOMArrayBufferBase* toTransfer = arrayBuffers[i];
394 if (!isNeuterable) {
395 toTransfer =
396 DOMArrayBuffer::create(arrayBuffers[i]->buffer()->data(),
397 arrayBuffers[i]->buffer()->byteLength());
398 }
399 bool result = toTransfer->transfer(contents->at(i));
400 if (!result) {
401 exceptionState.throwDOMException(
402 DataCloneError, "ArrayBuffer at index " + String::number(i) +
403 " could not be transferred.");
404 return nullptr;
405 }
406
407 if (isNeuterable)
408 for (size_t j = 0; j < bufferHandles.size(); ++j)
haraken 2016/10/19 09:49:28 Ditto.
nhiroki 2016/10/20 07:44:02 Done.
409 bufferHandles[j]->Neuter();
410 }
411 }
412 return contents;
413 }
414
405 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() { 415 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() {
406 if (m_externallyAllocatedMemory) 416 if (m_externallyAllocatedMemory)
407 return; 417 return;
408 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); 418 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length());
409 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( 419 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
410 m_externallyAllocatedMemory); 420 m_externallyAllocatedMemory);
411 } 421 }
412 422
413 bool SerializedScriptValue::containsTransferableArrayBuffer() const {
414 return m_arrayBufferContentsArray && !m_arrayBufferContentsArray->isEmpty();
415 }
416
417 } // namespace blink 423 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698