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

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

Issue 1097773004: Sharing of SharedArrayBuffer via PostMessage transfer (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: update for non-split typedarray hierarchy Created 5 years, 6 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 21 matching lines...) Expand all
32 #include "bindings/core/v8/SerializedScriptValue.h" 32 #include "bindings/core/v8/SerializedScriptValue.h"
33 33
34 #include "bindings/core/v8/DOMDataStore.h" 34 #include "bindings/core/v8/DOMDataStore.h"
35 #include "bindings/core/v8/DOMWrapperWorld.h" 35 #include "bindings/core/v8/DOMWrapperWorld.h"
36 #include "bindings/core/v8/ExceptionState.h" 36 #include "bindings/core/v8/ExceptionState.h"
37 #include "bindings/core/v8/ScriptState.h" 37 #include "bindings/core/v8/ScriptState.h"
38 #include "bindings/core/v8/ScriptValueSerializer.h" 38 #include "bindings/core/v8/ScriptValueSerializer.h"
39 #include "bindings/core/v8/SerializedScriptValueFactory.h" 39 #include "bindings/core/v8/SerializedScriptValueFactory.h"
40 #include "bindings/core/v8/V8ArrayBuffer.h" 40 #include "bindings/core/v8/V8ArrayBuffer.h"
41 #include "bindings/core/v8/V8MessagePort.h" 41 #include "bindings/core/v8/V8MessagePort.h"
42 #include "bindings/core/v8/V8SharedArrayBuffer.h"
42 #include "core/dom/ExceptionCode.h" 43 #include "core/dom/ExceptionCode.h"
43 #include "platform/SharedBuffer.h" 44 #include "platform/SharedBuffer.h"
44 #include "platform/blob/BlobData.h" 45 #include "platform/blob/BlobData.h"
45 #include "platform/heap/Handle.h" 46 #include "platform/heap/Handle.h"
46 #include "wtf/Assertions.h" 47 #include "wtf/Assertions.h"
47 #include "wtf/ByteOrder.h" 48 #include "wtf/ByteOrder.h"
48 #include "wtf/Vector.h" 49 #include "wtf/Vector.h"
49 #include "wtf/text/StringBuffer.h" 50 #include "wtf/text/StringBuffer.h"
50 #include "wtf/text/StringHash.h" 51 #include "wtf/text/StringHash.h"
51 52
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 if (!wrapper.IsEmpty()) 94 if (!wrapper.IsEmpty())
94 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); 95 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper));
95 } 96 }
96 } else { 97 } else {
97 v8::Local<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDat aStore().get(object, isolate); 98 v8::Local<v8::Object> wrapper = DOMWrapperWorld::current(isolate).domDat aStore().get(object, isolate);
98 if (!wrapper.IsEmpty()) 99 if (!wrapper.IsEmpty())
99 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); 100 buffers.append(v8::Local<v8::ArrayBuffer>::Cast(wrapper));
100 } 101 }
101 } 102 }
102 103
103 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::createArrayBuffers(v8::Isolate* isolate, ArrayBufferArray& arrayBuffers, Exce ptionState& exceptionState) 104 PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu e::createArrayBuffers(v8::Isolate* isolate, ArrayBufferArray& arrayBuffers, Shar edArrayBufferArray& sharedArrayBuffers, ExceptionState& exceptionState)
104 { 105 {
105 ASSERT(arrayBuffers.size()); 106 size_t bufferCount = arrayBuffers.size() + sharedArrayBuffers.size();
107 ASSERT(bufferCount > 0);
106 108
107 for (size_t i = 0; i < arrayBuffers.size(); i++) { 109 for (size_t i = 0; i < arrayBuffers.size(); i++) {
108 if (arrayBuffers[i]->isNeutered()) { 110 if (arrayBuffers[i]->isNeutered()) {
109 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " is already neutered."); 111 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " is already neutered.");
110 return nullptr; 112 return nullptr;
111 } 113 }
112 } 114 }
113 115
114 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(arrayBuffers.size())); 116 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContents Array(bufferCount));
115 117
116 HashSet<DOMArrayBuffer*> visited; 118 HashSet<DOMArrayBuffer*> visited;
117 for (size_t i = 0; i < arrayBuffers.size(); i++) { 119 for (size_t i = 0; i < arrayBuffers.size(); i++) {
118 if (visited.contains(arrayBuffers[i].get())) 120 if (visited.contains(arrayBuffers[i].get()))
119 continue; 121 continue;
120 visited.add(arrayBuffers[i].get()); 122 visited.add(arrayBuffers[i].get());
121 123
122 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles; 124 Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles;
123 v8::HandleScope handleScope(isolate); 125 v8::HandleScope handleScope(isolate);
124 acculumateArrayBuffersForAllWorlds(isolate, arrayBuffers[i].get(), buffe rHandles); 126 acculumateArrayBuffersForAllWorlds(isolate, arrayBuffers[i].get(), buffe rHandles);
125 bool isNeuterable = true; 127 bool isNeuterable = true;
126 for (size_t j = 0; j < bufferHandles.size(); j++) 128 for (size_t j = 0; j < bufferHandles.size(); j++)
127 isNeuterable &= bufferHandles[j]->IsNeuterable(); 129 isNeuterable &= bufferHandles[j]->IsNeuterable();
128 130
129 RefPtr<DOMArrayBuffer> toTransfer = arrayBuffers[i]; 131 RefPtr<DOMArrayBuffer> toTransfer = arrayBuffers[i];
130 if (!isNeuterable) 132 if (!isNeuterable)
131 toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer()); 133 toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer());
132 bool result = toTransfer->transfer(contents->at(i)); 134 bool result = toTransfer->transfer(contents->at(i));
133 if (!result) { 135 if (!result) {
134 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " could not be transferred."); 136 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at ind ex " + String::number(i) + " could not be transferred.");
135 return nullptr; 137 return nullptr;
136 } 138 }
137 139
138 if (isNeuterable) 140 if (isNeuterable)
139 for (size_t j = 0; j < bufferHandles.size(); j++) 141 for (size_t j = 0; j < bufferHandles.size(); j++)
140 bufferHandles[j]->Neuter(); 142 bufferHandles[j]->Neuter();
141 } 143 }
144
145 HashSet<DOMSharedArrayBuffer*> sharedVisited;
146 size_t offset = arrayBuffers.size();
147 for (size_t i = 0; i < sharedArrayBuffers.size(); i++) {
148 if (sharedVisited.contains(sharedArrayBuffers[i].get()))
149 continue;
150 sharedVisited.add(sharedArrayBuffers[i].get());
151
152 bool result = sharedArrayBuffers[i]->transfer(contents->at(i + offset));
153 if (!result) {
154 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuffer at index " + String::number(i) + " could not be transferred.");
155 return nullptr;
156 }
157 }
158
142 return contents.release(); 159 return contents.release();
143 } 160 }
144 161
145 SerializedScriptValue::SerializedScriptValue(const String& wireData) 162 SerializedScriptValue::SerializedScriptValue(const String& wireData)
146 : m_externallyAllocatedMemory(0) 163 : m_externallyAllocatedMemory(0)
147 { 164 {
148 m_data = wireData.isolatedCopy(); 165 m_data = wireData.isolatedCopy();
149 } 166 }
150 167
151 v8::Local<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messag ePorts) 168 v8::Local<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messag ePorts)
152 { 169 {
153 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0); 170 return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
154 } 171 }
155 172
156 v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me ssagePortArray* messagePorts, const WebBlobInfoArray* blobInfo) 173 v8::Local<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, Me ssagePortArray* messagePorts, const WebBlobInfoArray* blobInfo)
157 { 174 {
158 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m essagePorts, blobInfo); 175 return SerializedScriptValueFactory::instance().deserialize(this, isolate, m essagePorts, blobInfo);
159 } 176 }
160 177
161 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local <v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState) 178 bool SerializedScriptValue::extractTransferables(v8::Isolate* isolate, v8::Local <v8::Value> value, int argumentIndex, MessagePortArray& ports, ArrayBufferArray& arrayBuffers, SharedArrayBufferArray& sharedArrayBuffers, ExceptionState& excep tionState)
162 { 179 {
163 if (isUndefinedOrNull(value)) { 180 if (isUndefinedOrNull(value)) {
164 ports.resize(0); 181 ports.resize(0);
165 arrayBuffers.resize(0); 182 arrayBuffers.resize(0);
183 sharedArrayBuffers.resize(0);
166 return true; 184 return true;
167 } 185 }
168 186
169 uint32_t length = 0; 187 uint32_t length = 0;
170 if (value->IsArray()) { 188 if (value->IsArray()) {
171 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value); 189 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
172 length = array->Length(); 190 length = array->Length();
173 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { 191 } else if (!toV8Sequence(value, length, isolate, exceptionState)) {
174 if (!exceptionState.hadException()) 192 if (!exceptionState.hadException())
175 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum entOrValue(argumentIndex + 1)); 193 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum entOrValue(argumentIndex + 1));
(...skipping 21 matching lines...) Expand all
197 return false; 215 return false;
198 } 216 }
199 ports.append(port.release()); 217 ports.append(port.release());
200 } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) { 218 } else if (V8ArrayBuffer::hasInstance(transferrable, isolate)) {
201 RefPtr<DOMArrayBuffer> arrayBuffer = V8ArrayBuffer::toImpl(v8::Local <v8::Object>::Cast(transferrable)); 219 RefPtr<DOMArrayBuffer> arrayBuffer = V8ArrayBuffer::toImpl(v8::Local <v8::Object>::Cast(transferrable));
202 if (arrayBuffers.contains(arrayBuffer)) { 220 if (arrayBuffers.contains(arrayBuffer)) {
203 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer."); 221 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is a duplicate of an earlier ArrayBuffer.");
204 return false; 222 return false;
205 } 223 }
206 arrayBuffers.append(arrayBuffer.release()); 224 arrayBuffers.append(arrayBuffer.release());
225 } else if (V8SharedArrayBuffer::hasInstance(transferrable, isolate)) {
226 RefPtr<DOMSharedArrayBuffer> sharedArrayBuffer = V8SharedArrayBuffer ::toImpl(v8::Handle<v8::Object>::Cast(transferrable));
227 if (sharedArrayBuffers.contains(sharedArrayBuffer)) {
228 exceptionState.throwDOMException(DataCloneError, "SharedArrayBuf fer at index " + String::number(i) + " is a duplicate of an earlier SharedArrayB uffer.");
229 return false;
230 }
231 sharedArrayBuffers.append(sharedArrayBuffer.release());
207 } else { 232 } else {
208 exceptionState.throwTypeError("Value at index " + String::number(i) + " does not have a transferable type."); 233 exceptionState.throwTypeError("Value at index " + String::number(i) + " does not have a transferable type.");
209 return false; 234 return false;
210 } 235 }
211 } 236 }
212 return true; 237 return true;
213 } 238 }
214 239
215 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext() 240 void SerializedScriptValue::registerMemoryAllocatedWithCurrentScriptContext()
216 { 241 {
217 if (m_externallyAllocatedMemory) 242 if (m_externallyAllocatedMemory)
218 return; 243 return;
219 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length()); 244 m_externallyAllocatedMemory = static_cast<intptr_t>(m_data.length());
220 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall yAllocatedMemory); 245 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externall yAllocatedMemory);
221 } 246 }
222 247
223 SerializedScriptValue::~SerializedScriptValue() 248 SerializedScriptValue::~SerializedScriptValue()
224 { 249 {
225 // If the allocated memory was not registered before, then this class is lik ely 250 // If the allocated memory was not registered before, then this class is lik ely
226 // used in a context other then Worker's onmessage environment and the prese nce of 251 // used in a context other then Worker's onmessage environment and the prese nce of
227 // current v8 context is not guaranteed. Avoid calling v8 then. 252 // current v8 context is not guaranteed. Avoid calling v8 then.
228 if (m_externallyAllocatedMemory) { 253 if (m_externallyAllocatedMemory) {
229 ASSERT(v8::Isolate::GetCurrent()); 254 ASSERT(v8::Isolate::GetCurrent());
230 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory); 255 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_exte rnallyAllocatedMemory);
231 } 256 }
232 } 257 }
233 258
234 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, ArrayBuff erArray& arrayBuffers, ExceptionState& exceptionState) 259 void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, ArrayBuff erArray& arrayBuffers, SharedArrayBufferArray& sharedArrayBuffers, ExceptionStat e& exceptionState)
235 { 260 {
236 m_arrayBufferContentsArray = createArrayBuffers(isolate, arrayBuffers, excep tionState); 261 m_arrayBufferContentsArray = createArrayBuffers(isolate, arrayBuffers, share dArrayBuffers, exceptionState);
237 } 262 }
238 263
239 } // namespace blink 264 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698