Bug 1264642 - Part 5. Make SerializedStructuredClone{Read,Write}Info use SerializedStructuredCloneBuffer. r=baku

MozReview-Commit-ID: KUz3E5Sw5W3
This commit is contained in:
Kan-Ru Chen 2016-06-07 16:49:43 +08:00
Родитель 506dfe6ea3
Коммит 0dbfe2dbcc
6 изменённых файлов: 41 добавлений и 92 удалений

Просмотреть файл

@ -430,8 +430,6 @@ private:
{
bool ok = IDBObjectStore::DeserializeValue(aCx, *aCloneInfo, aResult);
aCloneInfo->mCloneBuffer.clear();
if (NS_WARN_IF(!ok)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}

Просмотреть файл

@ -14840,7 +14840,7 @@ TransactionBase::VerifyRequestParams(const ObjectStoreAddPutParams& aParams)
return false;
}
if (NS_WARN_IF(aParams.cloneInfo().data().IsEmpty())) {
if (NS_WARN_IF(!aParams.cloneInfo().data().data.Size())) {
ASSERT_UNLESS_FUZZING();
return false;
}
@ -14855,13 +14855,13 @@ TransactionBase::VerifyRequestParams(const ObjectStoreAddPutParams& aParams)
return false;
}
if (NS_WARN_IF(cloneInfo.data().Length() < sizeof(uint64_t))) {
if (NS_WARN_IF(cloneInfo.data().data.Size() < sizeof(uint64_t))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(cloneInfo.offsetToKeyProp() >
(cloneInfo.data().Length() - sizeof(uint64_t)))) {
(cloneInfo.data().data.Size() - sizeof(uint64_t)))) {
ASSERT_UNLESS_FUZZING();
return false;
}
@ -19065,7 +19065,9 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
return NS_ERROR_FILE_CORRUPTED;
}
aInfo->mData.SwapElements(uncompressed);
if (!aInfo->mData.WriteBytes(uncompressedBuffer, uncompressed.Length())) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!aFileIds.IsVoid()) {
AutoTArray<int64_t, 10> array;
@ -25427,6 +25429,13 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
MOZ_ASSERT(!keyUnset || mMetadata->mCommonMetadata.autoIncrement(),
"Should have key unless autoIncrement");
const JSStructuredCloneData& data = mParams.cloneInfo().data().data;
size_t cloneDataSize = data.Size();
nsCString cloneData;
cloneData.SetLength(cloneDataSize);
auto iter = data.Iter();
data.ReadBytes(iter, cloneData.BeginWriting(), cloneDataSize);
int64_t autoIncrementNum = 0;
if (mMetadata->mCommonMetadata.autoIncrement()) {
@ -25448,16 +25457,14 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
if (keyUnset && keyPath.IsValid()) {
const SerializedStructuredCloneWriteInfo& cloneInfo = mParams.cloneInfo();
MOZ_ASSERT(cloneInfo.offsetToKeyProp());
MOZ_ASSERT(cloneInfo.data().Length() > sizeof(uint64_t));
MOZ_ASSERT(cloneDataSize > sizeof(uint64_t));
MOZ_ASSERT(cloneInfo.offsetToKeyProp() <=
(cloneInfo.data().Length() - sizeof(uint64_t)));
(cloneDataSize - sizeof(uint64_t)));
// Special case where someone put an object into an autoIncrement'ing
// objectStore with no key in its keyPath set. We needed to figure out
// which row id we would get above before we could set that properly.
uint8_t* keyPropPointer =
const_cast<uint8_t*>(cloneInfo.data().Elements() +
cloneInfo.offsetToKeyProp());
char* keyPropPointer = cloneData.BeginWriting() + cloneInfo.offsetToKeyProp();
uint64_t keyPropValue =
ReinterpretDoubleAsUInt64(static_cast<double>(autoIncrementNum));
@ -25468,9 +25475,8 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
key.BindToStatement(stmt, NS_LITERAL_CSTRING("key"));
// Compress the bytes before adding into the database.
const char* uncompressed =
reinterpret_cast<const char*>(mParams.cloneInfo().data().Elements());
size_t uncompressedLength = mParams.cloneInfo().data().Length();
const char* uncompressed = cloneData.BeginReading();
size_t uncompressedLength = cloneDataSize;
// We don't have a smart pointer class that calls free, so we need to
// manage | compressed | manually.
@ -25802,7 +25808,7 @@ ObjectStoreGetRequestOp::ConvertResponse(
StructuredCloneReadInfo& info = mResponse[aIndex];
info.mData.SwapElements(aSerializedInfo.data());
aSerializedInfo.data().data = Move(info.mData);
FallibleTArray<BlobOrMutableFile> blobs;
nsresult rv = ConvertBlobsToActors(mBackgroundParent,
@ -26525,7 +26531,7 @@ IndexGetRequestOp::GetResponse(RequestResponse& aResponse)
SerializedStructuredCloneReadInfo& serializedInfo =
fallibleCloneInfos[index];
info.mData.SwapElements(serializedInfo.data());
serializedInfo.data().data = Move(info.mData);
FallibleTArray<BlobOrMutableFile> blobs;
nsresult rv = ConvertBlobsToActors(mBackgroundParent,
@ -26559,7 +26565,7 @@ IndexGetRequestOp::GetResponse(RequestResponse& aResponse)
SerializedStructuredCloneReadInfo& serializedInfo =
aResponse.get_IndexGetResponse().cloneInfo();
info.mData.SwapElements(serializedInfo.data());
serializedInfo.data().data = Move(info.mData);
FallibleTArray<BlobOrMutableFile> blobs;
nsresult rv =
@ -26873,7 +26879,7 @@ CursorOpBase::PopulateResponseFromStatement(
auto& responses = mResponse.get_ArrayOfObjectStoreCursorResponse();
auto& response = *responses.AppendElement();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.cloneInfo().data().data = Move(cloneInfo.mData);
response.key() = mCursor->mKey;
mFiles.AppendElement(Move(cloneInfo.mFiles));
@ -26911,7 +26917,7 @@ CursorOpBase::PopulateResponseFromStatement(
mResponse = IndexCursorResponse();
auto& response = mResponse.get_IndexCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.cloneInfo().data().data = Move(cloneInfo.mData);
response.key() = mCursor->mKey;
response.sortKey() = mCursor->mSortKey;
response.objectKey() = mCursor->mObjectKey;

Просмотреть файл

@ -867,15 +867,6 @@ CommonStructuredCloneReadCallback(JSContext* aCx,
aTag);
}
// static
void
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer)
{
if (!aBuffer.empty()) {
aBuffer.clear();
}
}
} // namespace
const JSClass IDBObjectStore::sDummyPropJSClass = {
@ -1042,11 +1033,10 @@ IDBObjectStore::ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo)
// This is kind of tricky, we only want to release stuff on the main thread,
// but we can end up being called on other threads if we have already been
// cleared on the main thread.
if (aReadInfo.mCloneBuffer.empty() && !aReadInfo.mFiles.Length()) {
if (!aReadInfo.mFiles.Length()) {
return;
}
ClearStructuredCloneBuffer(aReadInfo.mCloneBuffer);
aReadInfo.mFiles.Clear();
}
@ -1058,23 +1048,15 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
{
MOZ_ASSERT(aCx);
if (aCloneReadInfo.mData.IsEmpty()) {
if (!aCloneReadInfo.mData.Size()) {
aValue.setUndefined();
return true;
}
char* data = reinterpret_cast<char*>(aCloneReadInfo.mData.Elements());
size_t dataLen = aCloneReadInfo.mData.Length();
MOZ_ASSERT(!(dataLen % sizeof(uint64_t)));
MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t)));
JSAutoRequest ar(aCx);
JSStructuredCloneData buf;
if (!buf.WriteBytes(data, dataLen)) {
return false;
}
static const JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback<ValueDeserializationHelper>,
nullptr,
@ -1086,7 +1068,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
// FIXME: Consider to use StructuredCloneHolder here and in other
// deserializing methods.
if (!JS_ReadStructuredClone(aCx, buf, JS_STRUCTURED_CLONE_VERSION,
if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
JS::StructuredCloneScope::SameProcessSameThread,
aValue, &callbacks, &aCloneReadInfo)) {
return false;
@ -1104,30 +1086,22 @@ IDBObjectStore::DeserializeIndexValue(JSContext* aCx,
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aCx);
if (aCloneReadInfo.mData.IsEmpty()) {
if (!aCloneReadInfo.mData.Size()) {
aValue.setUndefined();
return true;
}
size_t dataLen = aCloneReadInfo.mData.Length();
char* data = reinterpret_cast<char*>(aCloneReadInfo.mData.Elements());
MOZ_ASSERT(!(dataLen % sizeof(uint64_t)));
MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t)));
JSAutoRequest ar(aCx);
JSStructuredCloneData buf;
if (!buf.WriteBytes(data, dataLen)) {
return false;
}
static const JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback<IndexDeserializationHelper>,
nullptr,
nullptr
};
if (!JS_ReadStructuredClone(aCx, buf, JS_STRUCTURED_CLONE_VERSION,
if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
JS::StructuredCloneScope::SameProcessSameThread,
aValue, &callbacks, &aCloneReadInfo)) {
return false;
@ -1147,24 +1121,15 @@ IDBObjectStore::DeserializeUpgradeValue(JSContext* aCx,
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aCx);
if (aCloneReadInfo.mData.IsEmpty()) {
if (!aCloneReadInfo.mData.Size()) {
aValue.setUndefined();
return true;
}
size_t dataLen = aCloneReadInfo.mData.Length();
char* data = reinterpret_cast<char*>(aCloneReadInfo.mData.Elements());
MOZ_ASSERT(!(dataLen % sizeof(uint64_t)));
MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t)));
JSAutoRequest ar(aCx);
JSStructuredCloneData buf;
if (!buf.WriteBytes(data, dataLen)) {
return false;
}
static JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback<UpgradeDeserializationHelper>,
nullptr,
@ -1174,7 +1139,7 @@ IDBObjectStore::DeserializeUpgradeValue(JSContext* aCx,
nullptr
};
if (!JS_ReadStructuredClone(aCx, buf, JS_STRUCTURED_CLONE_VERSION,
if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
JS::StructuredCloneScope::SameProcessSameThread,
aValue, &callbacks, &aCloneReadInfo)) {
return false;
@ -1306,28 +1271,9 @@ IDBObjectStore::AddOrPut(JSContext* aCx,
return nullptr;
}
FallibleTArray<uint8_t> cloneData;
size_t size = cloneWriteInfo.mCloneBuffer.data().Size();
if (NS_WARN_IF(!cloneData.SetLength(size, fallible))) {
aRv = NS_ERROR_OUT_OF_MEMORY;
return nullptr;
}
const char* buf;
auto iter = cloneWriteInfo.mCloneBuffer.data().Iter();
cloneWriteInfo.mCloneBuffer.data().FlattenBytes(iter, &buf, size);
// FIXME Bug XXXXXX Change SerializedStructuredCloneReadInfo and
// SerializedStructuredCloneWriteInfo to use JSStructuredCloneData
// instead of raw buffer.
memcpy(cloneData.Elements(), buf, size);
cloneWriteInfo.mCloneBuffer.clear();
ObjectStoreAddPutParams commonParams;
commonParams.objectStoreId() = Id();
commonParams.cloneInfo().data().SwapElements(cloneData);
commonParams.cloneInfo().data().data = Move(cloneWriteInfo.mCloneBuffer.data());
commonParams.cloneInfo().offsetToKeyProp() = cloneWriteInfo.mOffsetToKeyProp;
commonParams.key() = key;
commonParams.indexUpdateInfos().SwapElements(updateInfo);

Просмотреть файл

@ -45,13 +45,10 @@ struct StructuredCloneFile
struct StructuredCloneReadInfo
{
nsTArray<uint8_t> mData;
JSStructuredCloneData mData;
nsTArray<StructuredCloneFile> mFiles;
IDBDatabase* mDatabase;
// XXX Remove!
JSAutoStructuredCloneBuffer mCloneBuffer;
// In IndexedDatabaseInlines.h
inline
StructuredCloneReadInfo();

Просмотреть файл

@ -54,7 +54,7 @@ StructuredCloneReadInfo::StructuredCloneReadInfo()
inline
StructuredCloneReadInfo::StructuredCloneReadInfo(
SerializedStructuredCloneReadInfo&& aCloneReadInfo)
: mData(Move(aCloneReadInfo.data()))
: mData(Move(aCloneReadInfo.data().data))
, mDatabase(nullptr)
{
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
@ -72,7 +72,6 @@ StructuredCloneReadInfo::operator=(StructuredCloneReadInfo&& aCloneReadInfo)
MOZ_ASSERT(&aCloneReadInfo != this);
mData = Move(aCloneReadInfo.mData);
mCloneBuffer = Move(aCloneReadInfo.mCloneBuffer);
mFiles.Clear();
mFiles.SwapElements(aCloneReadInfo.mFiles);
mDatabase = aCloneReadInfo.mDatabase;

Просмотреть файл

@ -30,6 +30,9 @@ using class mozilla::dom::indexedDB::KeyPath
using mozilla::dom::quota::PersistenceType
from "mozilla/dom/quota/PersistenceType.h";
using mozilla::SerializedStructuredCloneBuffer
from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
namespace indexedDB {
@ -57,13 +60,13 @@ union BlobOrMutableFile
struct SerializedStructuredCloneReadInfo
{
uint8_t[] data;
SerializedStructuredCloneBuffer data;
BlobOrMutableFile[] blobs;
};
struct SerializedStructuredCloneWriteInfo
{
uint8_t[] data;
SerializedStructuredCloneBuffer data;
uint64_t offsetToKeyProp;
};