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

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

Issue 56973002: Fix memory leak on serializing neutered ArrayBuffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Restructure serialization method for simpler unwinding Created 7 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 { 732 {
733 v8::HandleScope scope(m_isolate); 733 v8::HandleScope scope(m_isolate);
734 m_writer.writeVersion(); 734 m_writer.writeVersion();
735 StateBase* state = doSerialize(value, 0); 735 StateBase* state = doSerialize(value, 0);
736 while (state) 736 while (state)
737 state = state->advance(*this); 737 state = state->advance(*this);
738 return m_status; 738 return m_status;
739 } 739 }
740 740
741 // Functions used by serialization states. 741 // Functions used by serialization states.
742 StateBase* doSerialize(v8::Handle<v8::Value> value, StateBase* next); 742 StateBase* doSerialize(v8::Handle<v8::Value>, StateBase* next);
743
744 // The serializer workhorse, no stack depth check.
745 StateBase* doSerializeImpl(v8::Handle<v8::Value>, StateBase* next);
746
747 StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBa se* next)
748 {
749 return doSerializeImpl(arrayBuffer, next);
750 }
743 751
744 StateBase* checkException(StateBase* state) 752 StateBase* checkException(StateBase* state)
745 { 753 {
746 return m_tryCatch.HasCaught() ? handleError(JSException, state) : 0; 754 return m_tryCatch.HasCaught() ? handleError(JSException, state) : 0;
747 } 755 }
748 756
749 StateBase* reportFailure(StateBase* state) 757 StateBase* reportFailure(StateBase* state)
750 { 758 {
751 return handleError(JSFailure, state); 759 return handleError(JSFailure, state);
752 } 760 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 { 1140 {
1133 ASSERT(!object.IsEmpty()); 1141 ASSERT(!object.IsEmpty());
1134 ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object); 1142 ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(object);
1135 if (!arrayBufferView) 1143 if (!arrayBufferView)
1136 return 0; 1144 return 0;
1137 if (!arrayBufferView->buffer()) 1145 if (!arrayBufferView->buffer())
1138 return handleError(DataCloneError, next); 1146 return handleError(DataCloneError, next);
1139 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_writer.getIsolate()); 1147 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), v8::Handle<v8::Object>(), m_writer.getIsolate());
1140 if (underlyingBuffer.IsEmpty()) 1148 if (underlyingBuffer.IsEmpty())
1141 return handleError(DataCloneError, next); 1149 return handleError(DataCloneError, next);
1142 StateBase* stateOut = doSerialize(underlyingBuffer, 0); 1150 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1143 if (stateOut) 1151 if (stateOut)
1144 return handleError(DataCloneError, next); 1152 return stateOut;
1145 m_writer.writeArrayBufferView(*arrayBufferView); 1153 m_writer.writeArrayBufferView(*arrayBufferView);
1146 // This should be safe: we serialize something that we know to be a wrap per (see 1154 // This should be safe: we serialize something that we know to be a wrap per (see
1147 // the toV8 call above), so the call to doSerialize above should neither cause 1155 // the toV8 call above), hence doSerializeArrayBuffer() will not consume stack
1148 // the stack to overflow nor should it have the potential to reach this 1156 // (but might fail and unwind our current stack.)
Dmitry Lomov (no reviews) 2013/11/05 10:56:10 Keep the statement "the call to doSerializeArrayBu
1149 // ArrayBufferView again. We do need to grey the underlying buffer befor e we grey 1157 //
1150 // its view, however; ArrayBuffers may be shared, so they need to be giv en reference IDs, 1158 // We do need to grey the underlying buffer before we grey its view, how ever;
1151 // and an ArrayBufferView cannot be constructed without a corresponding ArrayBuffer 1159 // ArrayBuffers may be shared, so they need to be given reference IDs, a nd an
1160 // ArrayBufferView cannot be constructed without a corresponding ArrayBu ffer
1152 // (or without an additional tag that would allow us to do two-stage con struction 1161 // (or without an additional tag that would allow us to do two-stage con struction
1153 // like we do for Objects and Arrays). 1162 // like we do for Objects and Arrays).
1154 greyObject(object); 1163 greyObject(object);
1155 return 0; 1164 return 0;
1156 } 1165 }
1157 1166
1158 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next) 1167 StateBase* writeArrayBuffer(v8::Handle<v8::Value> value, StateBase* next)
1159 { 1168 {
1160 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( )); 1169 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(value.As<v8::Object>( ));
1161 if (!arrayBuffer) 1170 if (!arrayBuffer)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 Status m_status; 1235 Status m_status;
1227 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; 1236 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool;
1228 ObjectPool m_objectPool; 1237 ObjectPool m_objectPool;
1229 ObjectPool m_transferredMessagePorts; 1238 ObjectPool m_transferredMessagePorts;
1230 ObjectPool m_transferredArrayBuffers; 1239 ObjectPool m_transferredArrayBuffers;
1231 uint32_t m_nextObjectReference; 1240 uint32_t m_nextObjectReference;
1232 BlobDataHandleMap& m_blobDataHandles; 1241 BlobDataHandleMap& m_blobDataHandles;
1233 v8::Isolate* m_isolate; 1242 v8::Isolate* m_isolate;
1234 }; 1243 };
1235 1244
1236 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat eBase* next) 1245 Serializer::StateBase* Serializer::doSerializeImpl(v8::Handle<v8::Value> value, StateBase* next)
1237 { 1246 {
1238 if (m_execDepth + (next ? next->execDepth() : 0) > 1) {
1239 m_writer.writeNull();
1240 return 0;
1241 }
1242 m_writer.writeReferenceCount(m_nextObjectReference); 1247 m_writer.writeReferenceCount(m_nextObjectReference);
1243 uint32_t objectReference; 1248 uint32_t objectReference;
1244 uint32_t arrayBufferIndex; 1249 uint32_t arrayBufferIndex;
1245 WrapperWorldType currentWorldType = worldType(m_isolate); 1250 WrapperWorldType currentWorldType = worldType(m_isolate);
1246 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) 1251 if ((value->IsObject() || value->IsDate() || value->IsRegExp())
1247 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { 1252 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
1248 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs 1253 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs
1249 // that we grey and write below). 1254 // that we grey and write below).
1250 ASSERT(!value->IsString()); 1255 ASSERT(!value->IsString());
1251 m_writer.writeObjectReference(objectReference); 1256 m_writer.writeObjectReference(objectReference);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 else if (value->IsObject()) { 1314 else if (value->IsObject()) {
1310 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError()) 1315 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError())
1311 return handleError(DataCloneError, next); 1316 return handleError(DataCloneError, next);
1312 return startObjectState(jsObject, next); 1317 return startObjectState(jsObject, next);
1313 } else 1318 } else
1314 return handleError(DataCloneError, next); 1319 return handleError(DataCloneError, next);
1315 } 1320 }
1316 return 0; 1321 return 0;
1317 } 1322 }
1318 1323
1324 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat eBase* next)
1325 {
1326 if (m_execDepth + (next ? next->execDepth() : 0) > 1) {
1327 m_writer.writeNull();
1328 return 0;
1329 }
1330 return doSerializeImpl(value, next);
1331 }
1332
1319 // Interface used by Reader to create objects of composite types. 1333 // Interface used by Reader to create objects of composite types.
1320 class CompositeCreator { 1334 class CompositeCreator {
1321 public: 1335 public:
1322 virtual ~CompositeCreator() { } 1336 virtual ~CompositeCreator() { }
1323 1337
1324 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; 1338 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0;
1325 virtual uint32_t objectReferenceCount() = 0; 1339 virtual uint32_t objectReferenceCount() = 0;
1326 virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0; 1340 virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0;
1327 virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle< v8::Value>*) = 0; 1341 virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle< v8::Value>*) = 0;
1328 virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Val ue>*) = 0; 1342 virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Val ue>*) = 0;
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 // If the allocated memory was not registered before, then this class is lik ely 2569 // If the allocated memory was not registered before, then this class is lik ely
2556 // used in a context other then Worker's onmessage environment and the prese nce of 2570 // used in a context other then Worker's onmessage environment and the prese nce of
2557 // current v8 context is not guaranteed. Avoid calling v8 then. 2571 // current v8 context is not guaranteed. Avoid calling v8 then.
2558 if (m_externallyAllocatedMemory) { 2572 if (m_externallyAllocatedMemory) {
2559 ASSERT(v8::Isolate::GetCurrent()); 2573 ASSERT(v8::Isolate::GetCurrent());
2560 v8::V8::AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemo ry); 2574 v8::V8::AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemo ry);
2561 } 2575 }
2562 } 2576 }
2563 2577
2564 } // namespace WebCore 2578 } // namespace WebCore
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698