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

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

Issue 2826263002: Make DOMArrayBuffer::Transfer neuter v8::ArrayBuffers (Closed)
Patch Set: add test and use to_transfer Created 3 years, 7 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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 size_t result_size = (data_buffer_size_ + 1) & ~1; 265 size_t result_size = (data_buffer_size_ + 1) & ~1;
266 result.Resize(result_size); 266 result.Resize(result_size);
267 memcpy(result.data(), data_buffer_.get(), data_buffer_size_); 267 memcpy(result.data(), data_buffer_.get(), data_buffer_size_);
268 268
269 if (result_size > data_buffer_size_) { 269 if (result_size > data_buffer_size_) {
270 DCHECK_EQ(result_size, data_buffer_size_ + 1); 270 DCHECK_EQ(result_size, data_buffer_size_ + 1);
271 result[data_buffer_size_] = 0; 271 result[data_buffer_size_] = 0;
272 } 272 }
273 } 273 }
274 274
275 static void AccumulateArrayBuffersForAllWorlds(
276 v8::Isolate* isolate,
277 DOMArrayBuffer* object,
278 Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) {
279 Vector<RefPtr<DOMWrapperWorld>> worlds;
280 DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
281 for (const auto& world : worlds) {
282 v8::Local<v8::Object> wrapper = world->DomDataStore().Get(object, isolate);
283 if (!wrapper.IsEmpty())
284 buffers.push_back(v8::Local<v8::ArrayBuffer>::Cast(wrapper));
285 }
286 }
287
288 std::unique_ptr<SerializedScriptValue::ImageBitmapContentsArray> 275 std::unique_ptr<SerializedScriptValue::ImageBitmapContentsArray>
289 SerializedScriptValue::TransferImageBitmapContents( 276 SerializedScriptValue::TransferImageBitmapContents(
290 v8::Isolate* isolate, 277 v8::Isolate* isolate,
291 const ImageBitmapArray& image_bitmaps, 278 const ImageBitmapArray& image_bitmaps,
292 ExceptionState& exception_state) { 279 ExceptionState& exception_state) {
293 if (!image_bitmaps.size()) 280 if (!image_bitmaps.size())
294 return nullptr; 281 return nullptr;
295 282
296 for (size_t i = 0; i < image_bitmaps.size(); ++i) { 283 for (size_t i = 0; i < image_bitmaps.size(); ++i) {
297 if (image_bitmaps[i]->IsNeutered()) { 284 if (image_bitmaps[i]->IsNeutered()) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 " is already neutered."); 460 " is already neutered.");
474 return nullptr; 461 return nullptr;
475 } 462 }
476 } 463 }
477 464
478 std::unique_ptr<ArrayBufferContentsArray> contents = 465 std::unique_ptr<ArrayBufferContentsArray> contents =
479 WTF::WrapUnique(new ArrayBufferContentsArray(array_buffers.size())); 466 WTF::WrapUnique(new ArrayBufferContentsArray(array_buffers.size()));
480 467
481 HeapHashSet<Member<DOMArrayBufferBase>> visited; 468 HeapHashSet<Member<DOMArrayBufferBase>> visited;
482 for (auto it = array_buffers.begin(); it != array_buffers.end(); ++it) { 469 for (auto it = array_buffers.begin(); it != array_buffers.end(); ++it) {
483 DOMArrayBufferBase* array_buffer = *it; 470 DOMArrayBufferBase* array_buffer_base = *it;
484 if (visited.Contains(array_buffer)) 471 if (visited.Contains(array_buffer_base))
485 continue; 472 continue;
486 visited.insert(array_buffer); 473 visited.insert(array_buffer_base);
487 474
488 size_t index = std::distance(array_buffers.begin(), it); 475 size_t index = std::distance(array_buffers.begin(), it);
489 if (array_buffer->IsShared()) { 476 if (array_buffer_base->IsShared()) {
490 if (!array_buffer->ShareContentsWith(contents->at(index))) { 477 DOMSharedArrayBuffer* shared_array_buffer =
478 static_cast<DOMSharedArrayBuffer*>(array_buffer_base);
479 if (!shared_array_buffer->ShareContentsWith(contents->at(index))) {
491 exception_state.ThrowDOMException(kDataCloneError, 480 exception_state.ThrowDOMException(kDataCloneError,
492 "SharedArrayBuffer at index " + 481 "SharedArrayBuffer at index " +
493 String::Number(index) + 482 String::Number(index) +
494 " could not be transferred."); 483 " could not be transferred.");
495 return nullptr; 484 return nullptr;
496 } 485 }
497 } else { 486 } else {
498 Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles; 487 DOMArrayBuffer* array_buffer =
499 v8::HandleScope handle_scope(isolate); 488 static_cast<DOMArrayBuffer*>(array_buffer_base);
500 AccumulateArrayBuffersForAllWorlds(
501 isolate, static_cast<DOMArrayBuffer*>(it->Get()), buffer_handles);
502 bool is_neuterable = true;
503 for (const auto& buffer_handle : buffer_handles)
504 is_neuterable &= buffer_handle->IsNeuterable();
505 489
506 DOMArrayBufferBase* to_transfer = array_buffer; 490 if (!array_buffer->Transfer(isolate, contents->at(index))) {
507 if (!is_neuterable) {
508 to_transfer =
509 DOMArrayBuffer::Create(array_buffer->Buffer()->Data(),
510 array_buffer->Buffer()->ByteLength());
511 }
512 if (!to_transfer->Transfer(contents->at(index))) {
513 exception_state.ThrowDOMException( 491 exception_state.ThrowDOMException(
514 kDataCloneError, "ArrayBuffer at index " + String::Number(index) + 492 kDataCloneError, "ArrayBuffer at index " + String::Number(index) +
515 " could not be transferred."); 493 " could not be transferred.");
516 return nullptr; 494 return nullptr;
517 } 495 }
518
519 if (is_neuterable) {
520 for (const auto& buffer_handle : buffer_handles)
521 buffer_handle->Neuter();
522 }
523 } 496 }
524 } 497 }
525 return contents; 498 return contents;
526 } 499 }
527 500
528 void SerializedScriptValue:: 501 void SerializedScriptValue::
529 UnregisterMemoryAllocatedWithCurrentScriptContext() { 502 UnregisterMemoryAllocatedWithCurrentScriptContext() {
530 if (has_registered_external_allocation_) { 503 if (has_registered_external_allocation_) {
531 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( 504 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
532 -static_cast<int64_t>(DataLengthInBytes())); 505 -static_cast<int64_t>(DataLengthInBytes()));
(...skipping 22 matching lines...) Expand all
555 // Only (re)register allocation cost for transferables if this 528 // Only (re)register allocation cost for transferables if this
556 // SerializedScriptValue has explicitly unregistered them before. 529 // SerializedScriptValue has explicitly unregistered them before.
557 if (array_buffer_contents_array_ && 530 if (array_buffer_contents_array_ &&
558 transferables_need_external_allocation_registration_) { 531 transferables_need_external_allocation_registration_) {
559 for (auto& buffer : *array_buffer_contents_array_) 532 for (auto& buffer : *array_buffer_contents_array_)
560 buffer.RegisterExternalAllocationWithCurrentContext(); 533 buffer.RegisterExternalAllocationWithCurrentContext();
561 } 534 }
562 } 535 }
563 536
564 } // namespace blink 537 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698