| 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 |