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

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

Issue 2741793003: Accurate transfer of SerializedScriptValue allocation costs. (Closed)
Patch Set: sanity check diff adjustments Created 3 years, 9 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 StringBuffer<UChar> buffer(stringLength); 102 StringBuffer<UChar> buffer(stringLength);
103 const UChar* src = reinterpret_cast<const UChar*>(data); 103 const UChar* src = reinterpret_cast<const UChar*>(data);
104 UChar* dst = buffer.characters(); 104 UChar* dst = buffer.characters();
105 for (size_t i = 0; i < stringLength; i++) 105 for (size_t i = 0; i < stringLength; i++)
106 dst[i] = ntohs(src[i]); 106 dst[i] = ntohs(src[i]);
107 107
108 return adoptRef(new SerializedScriptValue(String::adopt(buffer))); 108 return adoptRef(new SerializedScriptValue(String::adopt(buffer)));
109 } 109 }
110 110
111 SerializedScriptValue::SerializedScriptValue() 111 SerializedScriptValue::SerializedScriptValue()
112 : m_externallyAllocatedMemory(0), 112 : m_hasRegisteredExternalAllocation(false),
113 m_adjustTransferableExternalAllocationOnContextTransfer(false) {} 113 m_transferablesNeedExternalAllocationRegistration(false) {}
114 114
115 SerializedScriptValue::SerializedScriptValue(const String& wireData) 115 SerializedScriptValue::SerializedScriptValue(const String& wireData)
116 : m_externallyAllocatedMemory(0), 116 : m_hasRegisteredExternalAllocation(false),
117 m_adjustTransferableExternalAllocationOnContextTransfer(false) { 117 m_transferablesNeedExternalAllocationRegistration(false) {
118 size_t byteLength = wireData.length() * 2; 118 size_t byteLength = wireData.length() * 2;
119 m_dataBuffer.reset(static_cast<uint8_t*>(WTF::Partitions::bufferMalloc( 119 m_dataBuffer.reset(static_cast<uint8_t*>(WTF::Partitions::bufferMalloc(
120 byteLength, "SerializedScriptValue buffer"))); 120 byteLength, "SerializedScriptValue buffer")));
121 m_dataBufferSize = byteLength; 121 m_dataBufferSize = byteLength;
122 wireData.copyTo(reinterpret_cast<UChar*>(m_dataBuffer.get()), 0, 122 wireData.copyTo(reinterpret_cast<UChar*>(m_dataBuffer.get()), 0,
123 wireData.length()); 123 wireData.length());
124 } 124 }
125 125
126 SerializedScriptValue::~SerializedScriptValue() { 126 SerializedScriptValue::~SerializedScriptValue() {
127 // If the allocated memory was not registered before, then this class is 127 // If the allocated memory was not registered before, then this class is
128 // likely used in a context other than Worker's onmessage environment and the 128 // likely used in a context other than Worker's onmessage environment and the
129 // presence of current v8 context is not guaranteed. Avoid calling v8 then. 129 // presence of current v8 context is not guaranteed. Avoid calling v8 then.
130 if (m_externallyAllocatedMemory) { 130 if (m_hasRegisteredExternalAllocation) {
131 ASSERT(v8::Isolate::GetCurrent()); 131 ASSERT(v8::Isolate::GetCurrent());
132 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( 132 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
133 -static_cast<int64_t>(m_externallyAllocatedMemory)); 133 -static_cast<int64_t>(dataLengthInBytes()));
134 } 134 }
135 } 135 }
136 136
137 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() { 137 PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() {
138 // UChar rather than uint8_t here to get host endian behavior. 138 // UChar rather than uint8_t here to get host endian behavior.
139 static const UChar kNullData[] = {0xff09, 0x3000}; 139 static const UChar kNullData[] = {0xff09, 0x3000};
140 return create(reinterpret_cast<const char*>(kNullData), sizeof(kNullData)); 140 return create(reinterpret_cast<const char*>(kNullData), sizeof(kNullData));
141 } 141 }
142 142
143 String SerializedScriptValue::toWireString() const { 143 String SerializedScriptValue::toWireString() const {
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 439
440 if (isNeuterable) { 440 if (isNeuterable) {
441 for (const auto& bufferHandle : bufferHandles) 441 for (const auto& bufferHandle : bufferHandles)
442 bufferHandle->Neuter(); 442 bufferHandle->Neuter();
443 } 443 }
444 } 444 }
445 } 445 }
446 return contents; 446 return contents;
447 } 447 }
448 448
449 void SerializedScriptValue::unregisterMemoryAllocatedByCurrentScriptContext() { 449 void SerializedScriptValue::
450 // If the caller is the only one holding a reference then this serialized 450 unregisterMemoryAllocatedWithCurrentScriptContext() {
451 // value hasn't transferred ownership & no unregistration of allocation 451 if (m_hasRegisteredExternalAllocation) {
452 // costs wanted.
453 if (hasOneRef() || m_adjustTransferableExternalAllocationOnContextTransfer)
454 return;
455 if (m_externallyAllocatedMemory) {
456 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( 452 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
457 -static_cast<int64_t>(m_externallyAllocatedMemory)); 453 -static_cast<int64_t>(dataLengthInBytes()));
458 m_externallyAllocatedMemory = 0; 454 m_hasRegisteredExternalAllocation = false;
459 } 455 }
456
460 // TODO: if other transferables start accounting for their external 457 // TODO: if other transferables start accounting for their external
461 // allocations with V8, extend this with corresponding cases. 458 // allocations with V8, extend this with corresponding cases.
462 if (m_arrayBufferContentsArray) { 459 if (m_arrayBufferContentsArray &&
463 for (auto& buffer : *m_arrayBufferContentsArray) { 460 !m_transferablesNeedExternalAllocationRegistration) {
464 buffer.adjustExternalAllocatedMemoryUponContextTransfer( 461 for (auto& buffer : *m_arrayBufferContentsArray)
465 WTF::ArrayBufferContents::Leave); 462 buffer.unregisterExternalAllocationWithCurrentContext();
466 } 463 m_transferablesNeedExternalAllocationRegistration = true;
467 // Mark value as needing re-registration of external allocation
468 // costs in its target context, as handled by
469 // |registerMemoryAllocatedWithCurrentScriptContext()|.
470 m_adjustTransferableExternalAllocationOnContextTransfer = true;
471 } 464 }
472 } 465 }
473 466
474 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() { 467 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() {
475 if (m_externallyAllocatedMemory) 468 if (m_hasRegisteredExternalAllocation)
476 return; 469 return;
477 470
478 m_externallyAllocatedMemory = dataLengthInBytes(); 471 m_hasRegisteredExternalAllocation = true;
479 int64_t diff = static_cast<int64_t>(m_externallyAllocatedMemory); 472 int64_t diff = static_cast<int64_t>(dataLengthInBytes());
480 DCHECK_GE(diff, 0); 473 DCHECK_GE(diff, 0);
481 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(diff); 474 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(diff);
482 if (m_adjustTransferableExternalAllocationOnContextTransfer) { 475
483 DCHECK(m_arrayBufferContentsArray); 476 // Only (re)register allocation cost for transferables if this
484 for (size_t i = 0; i < m_arrayBufferContentsArray->size(); ++i) { 477 // SerializedScriptValue has explicitly unregistered them before.
485 WTF::ArrayBufferContents& buffer = m_arrayBufferContentsArray->at(i); 478 if (m_arrayBufferContentsArray &&
486 buffer.adjustExternalAllocatedMemoryUponContextTransfer( 479 m_transferablesNeedExternalAllocationRegistration) {
487 WTF::ArrayBufferContents::Enter); 480 for (auto& buffer : *m_arrayBufferContentsArray)
488 } 481 buffer.registerExternalAllocationWithCurrentContext();
489 m_adjustTransferableExternalAllocationOnContextTransfer = false;
490 } 482 }
491 } 483 }
492 484
493 } // namespace blink 485 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698