OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |