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