Bug 1311466 - Part 10: Implement functionality for preprocessing multiple results, fixed objectStore.getAll() to use it including a new test; r=asuth

This commit is contained in:
Jan Varga 2016-10-26 06:51:33 +02:00
parent f43ddde533
commit 17a0c4983e
11 changed files with 483 additions and 136 deletions

View File

@ -594,10 +594,10 @@ void
DeserializeStructuredCloneFiles(
IDBDatabase* aDatabase,
const nsTArray<SerializedStructuredCloneFile>& aSerializedFiles,
const nsTArray<RefPtr<JS::WasmModule>>* aModules,
const nsTArray<RefPtr<JS::WasmModule>>* aModuleSet,
nsTArray<StructuredCloneFile>& aFiles)
{
MOZ_ASSERT_IF(aModules, !aModules->IsEmpty());
MOZ_ASSERT_IF(aModuleSet, !aModuleSet->IsEmpty());
MOZ_ASSERT(aFiles.IsEmpty());
if (!aSerializedFiles.IsEmpty()) {
@ -690,7 +690,7 @@ DeserializeStructuredCloneFiles(
}
case StructuredCloneFile::eWasmBytecode: {
if (aModules) {
if (aModuleSet) {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t);
StructuredCloneFile* file = aFiles.AppendElement();
@ -698,8 +698,8 @@ DeserializeStructuredCloneFiles(
file->mType = serializedFile.type();
MOZ_ASSERT(moduleIndex < aModules->Length());
file->mWasmModule = aModules->ElementAt(moduleIndex);
MOZ_ASSERT(moduleIndex < aModuleSet->Length());
file->mWasmModule = aModuleSet->ElementAt(moduleIndex);
break;
}
@ -727,7 +727,7 @@ DeserializeStructuredCloneFiles(
}
case StructuredCloneFile::eWasmCompiled: {
if (aModules) {
if (aModuleSet) {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t);
StructuredCloneFile* file = aFiles.AppendElement();
@ -735,8 +735,8 @@ DeserializeStructuredCloneFiles(
file->mType = serializedFile.type();
MOZ_ASSERT(moduleIndex < aModules->Length());
file->mWasmModule = aModules->ElementAt(moduleIndex++);
MOZ_ASSERT(moduleIndex < aModuleSet->Length());
file->mWasmModule = aModuleSet->ElementAt(moduleIndex++);
break;
}
@ -1208,14 +1208,16 @@ class BackgroundRequestChild::PreprocessHelper final
nsCOMPtr<nsIEventTarget> mOwningThread;
nsTArray<StreamPair> mStreamPairs;
nsTArray<RefPtr<JS::WasmModule>> mModules;
nsTArray<RefPtr<JS::WasmModule>> mModuleSet;
BackgroundRequestChild* mActor;
uint32_t mModuleSetIndex;
nsresult mResultCode;
public:
explicit PreprocessHelper(BackgroundRequestChild* aActor)
PreprocessHelper(uint32_t aModuleSetIndex, BackgroundRequestChild* aActor)
: mOwningThread(NS_GetCurrentThread())
, mActor(aActor)
, mModuleSetIndex(aModuleSetIndex)
, mResultCode(NS_OK)
{
AssertIsOnOwningThread();
@ -2521,6 +2523,10 @@ BackgroundMutableFileChild::CreateMutableFile()
BackgroundRequestChild::BackgroundRequestChild(IDBRequest* aRequest)
: BackgroundRequestChildBase(aRequest)
, mTransaction(aRequest->GetTransaction())
, mRunningPreprocessHelpers(0)
, mCurrentModuleSetIndex(0)
, mPreprocessResultCode(NS_OK)
, mGetAll(false)
{
MOZ_ASSERT(mTransaction);
mTransaction->AssertIsOnOwningThread();
@ -2537,33 +2543,75 @@ BackgroundRequestChild::~BackgroundRequestChild()
}
void
BackgroundRequestChild::OnPreprocessFinished(
const nsTArray<RefPtr<JS::WasmModule>>& aModules)
BackgroundRequestChild::MaybeSendContinue()
{
AssertIsOnOwningThread();
MOZ_ASSERT(!aModules.IsEmpty());
MOZ_ASSERT(mPreprocessHelper);
MOZ_ASSERT(!mModules);
MOZ_ASSERT(mRunningPreprocessHelpers > 0);
mModules = new nsTArray<RefPtr<JS::WasmModule>>;
*mModules = Move(aModules);
if (--mRunningPreprocessHelpers == 0) {
PreprocessResponse response;
MOZ_ALWAYS_TRUE(SendContinue(ObjectStoreGetPreprocessResponse()));
if (NS_SUCCEEDED(mPreprocessResultCode)) {
if (mGetAll) {
response = ObjectStoreGetAllPreprocessResponse();
} else {
response = ObjectStoreGetPreprocessResponse();
}
} else {
response = mPreprocessResultCode;
}
mPreprocessHelper = nullptr;
MOZ_ALWAYS_TRUE(SendContinue(response));
}
}
void
BackgroundRequestChild::OnPreprocessFailed(nsresult aErrorCode)
BackgroundRequestChild::OnPreprocessFinished(
uint32_t aModuleSetIndex,
nsTArray<RefPtr<JS::WasmModule>>& aModuleSet)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aModuleSetIndex < mPreprocessHelpers.Length());
MOZ_ASSERT(!aModuleSet.IsEmpty());
MOZ_ASSERT(mPreprocessHelpers[aModuleSetIndex]);
MOZ_ASSERT(mModuleSets[aModuleSetIndex].IsEmpty());
mModuleSets[aModuleSetIndex].SwapElements(aModuleSet);
MaybeSendContinue();
mPreprocessHelpers[aModuleSetIndex] = nullptr;
}
void
BackgroundRequestChild::OnPreprocessFailed(uint32_t aModuleSetIndex,
nsresult aErrorCode)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aModuleSetIndex < mPreprocessHelpers.Length());
MOZ_ASSERT(NS_FAILED(aErrorCode));
MOZ_ASSERT(mPreprocessHelper);
MOZ_ASSERT(!mModules);
MOZ_ASSERT(mPreprocessHelpers[aModuleSetIndex]);
MOZ_ASSERT(mModuleSets[aModuleSetIndex].IsEmpty());
MOZ_ALWAYS_TRUE(SendContinue(aErrorCode));
if (NS_SUCCEEDED(mPreprocessResultCode)) {
mPreprocessResultCode = aErrorCode;
}
mPreprocessHelper = nullptr;
MaybeSendContinue();
mPreprocessHelpers[aModuleSetIndex] = nullptr;
}
const nsTArray<RefPtr<JS::WasmModule>>*
BackgroundRequestChild::GetNextModuleSet(const StructuredCloneReadInfo& aInfo)
{
if (!aInfo.mHasPreprocessInfo) {
return nullptr;
}
MOZ_ASSERT(mCurrentModuleSetIndex < mModuleSets.Length());
MOZ_ASSERT(!mModuleSets[mCurrentModuleSetIndex].IsEmpty());
return &mModuleSets[mCurrentModuleSetIndex++];
}
void
@ -2611,7 +2659,7 @@ BackgroundRequestChild::HandleResponse(
DeserializeStructuredCloneFiles(mTransaction->Database(),
aResponse.files(),
mModules,
GetNextModuleSet(cloneReadInfo),
cloneReadInfo.mFiles);
ResultHelper helper(mRequest, mTransaction, &cloneReadInfo);
@ -2641,15 +2689,16 @@ BackgroundRequestChild::HandleResponse(
StructuredCloneReadInfo* cloneReadInfo = cloneReadInfos.AppendElement();
// Move relevant data into the cloneReadInfo
*cloneReadInfo = Move(serializedCloneInfo);
// Get the files
nsTArray<StructuredCloneFile> files;
DeserializeStructuredCloneFiles(database,
serializedCloneInfo.files(),
nullptr,
GetNextModuleSet(*cloneReadInfo),
files);
// Move relevant data into the cloneReadInfo
*cloneReadInfo = Move(serializedCloneInfo);
cloneReadInfo->mFiles = Move(files);
}
}
@ -2681,6 +2730,91 @@ BackgroundRequestChild::HandleResponse(uint64_t aResponse)
DispatchSuccessEvent(&helper);
}
nsresult
BackgroundRequestChild::HandlePreprocess(
const WasmModulePreprocessInfo& aPreprocessInfo)
{
AssertIsOnOwningThread();
IDBDatabase* database = mTransaction->Database();
mPreprocessHelpers.SetLength(1);
nsTArray<StructuredCloneFile> files;
DeserializeStructuredCloneFiles(database,
aPreprocessInfo.files(),
nullptr,
files);
RefPtr<PreprocessHelper>& preprocessHelper = mPreprocessHelpers[0];
preprocessHelper = new PreprocessHelper(0, this);
nsresult rv = preprocessHelper->Init(files);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = preprocessHelper->Dispatch();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mRunningPreprocessHelpers++;
mModuleSets.SetLength(1);
return NS_OK;
}
nsresult
BackgroundRequestChild::HandlePreprocess(
const nsTArray<WasmModulePreprocessInfo>& aPreprocessInfos)
{
AssertIsOnOwningThread();
IDBDatabase* database = mTransaction->Database();
uint32_t count = aPreprocessInfos.Length();
mPreprocessHelpers.SetLength(count);
// TODO: Since we use the stream transport service, this can spawn 25 threads
// and has the potential to cause some annoying browser hiccups.
// Consider using a single thread or a very small threadpool.
for (uint32_t index = 0; index < count; index++) {
const WasmModulePreprocessInfo& preprocessInfo = aPreprocessInfos[index];
nsTArray<StructuredCloneFile> files;
DeserializeStructuredCloneFiles(database,
preprocessInfo.files(),
nullptr,
files);
RefPtr<PreprocessHelper>& preprocessHelper = mPreprocessHelpers[index];
preprocessHelper = new PreprocessHelper(index, this);
nsresult rv = preprocessHelper->Init(files);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = preprocessHelper->Dispatch();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mRunningPreprocessHelpers++;
}
mModuleSets.SetLength(count);
mGetAll = true;
return NS_OK;
}
void
BackgroundRequestChild::ActorDestroy(ActorDestroyReason aWhy)
{
@ -2688,10 +2822,16 @@ BackgroundRequestChild::ActorDestroy(ActorDestroyReason aWhy)
MaybeCollectGarbageOnIPCMessage();
if (mPreprocessHelper) {
mPreprocessHelper->ClearActor();
for (uint32_t count = mPreprocessHelpers.Length(), index = 0;
index < count;
index++) {
RefPtr<PreprocessHelper>& preprocessHelper = mPreprocessHelpers[index];
mPreprocessHelper = nullptr;
if (preprocessHelper) {
preprocessHelper->ClearActor();
preprocessHelper = nullptr;
}
}
if (mTransaction) {
@ -2802,30 +2942,31 @@ BackgroundRequestChild::RecvPreprocess(const PreprocessParams& aParams)
MaybeCollectGarbageOnIPCMessage();
IDBDatabase* database = mTransaction->Database();
nsresult rv;
if (aParams.type() != PreprocessParams::TObjectStoreGetPreprocessParams) {
MOZ_ASSERT(false, "Fix me!");
return false;
switch (aParams.type()) {
case PreprocessParams::TObjectStoreGetPreprocessParams: {
ObjectStoreGetPreprocessParams params =
aParams.get_ObjectStoreGetPreprocessParams();
rv = HandlePreprocess(params.preprocessInfo());
break;
}
case PreprocessParams::TObjectStoreGetAllPreprocessParams: {
ObjectStoreGetAllPreprocessParams params =
aParams.get_ObjectStoreGetAllPreprocessParams();
rv = HandlePreprocess(params.preprocessInfos());
break;
}
default:
MOZ_CRASH("Unknown params type!");
}
ObjectStoreGetPreprocessParams params =
aParams.get_ObjectStoreGetPreprocessParams();
nsTArray<StructuredCloneFile> files;
DeserializeStructuredCloneFiles(database,
params.preprocessInfo().files(),
nullptr,
files);
mPreprocessHelper = new PreprocessHelper(this);
nsresult rv = mPreprocessHelper->Init(files);
if (NS_WARN_IF(NS_FAILED(rv))) {
return SendContinue(rv);
}
rv = mPreprocessHelper->Dispatch();
if (NS_WARN_IF(NS_FAILED(rv))) {
return SendContinue(rv);
}
@ -2915,9 +3056,11 @@ PreprocessHelper::RunOnOwningThread()
if (mActor) {
if (NS_SUCCEEDED(mResultCode)) {
mActor->OnPreprocessFinished(mModules);
mActor->OnPreprocessFinished(mModuleSetIndex, mModuleSet);
MOZ_ASSERT(mModuleSet.IsEmpty());
} else {
mActor->OnPreprocessFailed(mResultCode);
mActor->OnPreprocessFailed(mModuleSetIndex, mResultCode);
}
}
}
@ -2928,7 +3071,7 @@ PreprocessHelper::RunOnStreamTransportThread()
{
MOZ_ASSERT(!IsOnOwningThread());
MOZ_ASSERT(!mStreamPairs.IsEmpty());
MOZ_ASSERT(mModules.IsEmpty());
MOZ_ASSERT(mModuleSet.IsEmpty());
const uint32_t count = mStreamPairs.Length();
@ -2972,7 +3115,7 @@ PreprocessHelper::RunOnStreamTransportThread()
return NS_ERROR_FAILURE;
}
mModules.AppendElement(module);
mModuleSet.AppendElement(module);
}
mStreamPairs.Clear();

View File

@ -647,8 +647,12 @@ class BackgroundRequestChild final
class PreprocessHelper;
RefPtr<IDBTransaction> mTransaction;
RefPtr<PreprocessHelper> mPreprocessHelper;
nsAutoPtr<nsTArray<RefPtr<JS::WasmModule>>> mModules;
nsTArray<RefPtr<PreprocessHelper>> mPreprocessHelpers;
nsTArray<nsTArray<RefPtr<JS::WasmModule>>> mModuleSets;
uint32_t mRunningPreprocessHelpers;
uint32_t mCurrentModuleSetIndex;
nsresult mPreprocessResultCode;
bool mGetAll;
private:
// Only created by IDBTransaction.
@ -660,10 +664,17 @@ private:
~BackgroundRequestChild();
void
OnPreprocessFinished(const nsTArray<RefPtr<JS::WasmModule>>& aModules);
MaybeSendContinue();
void
OnPreprocessFailed(nsresult aErrorCode);
OnPreprocessFinished(uint32_t aModuleSetIndex,
nsTArray<RefPtr<JS::WasmModule>>& aModuleSet);
void
OnPreprocessFailed(uint32_t aModuleSetIndex, nsresult aErrorCode);
const nsTArray<RefPtr<JS::WasmModule>>*
GetNextModuleSet(const StructuredCloneReadInfo& aInfo);
void
HandleResponse(nsresult aResponse);
@ -686,6 +697,12 @@ private:
void
HandleResponse(uint64_t aResponse);
nsresult
HandlePreprocess(const WasmModulePreprocessInfo& aPreprocessInfo);
nsresult
HandlePreprocess(const nsTArray<WasmModulePreprocessInfo>& aPreprocessInfos);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;

View File

@ -5926,15 +5926,13 @@ protected:
uint32_t aDataIndex,
uint32_t aFileIdsIndex,
FileManager* aFileManager,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm)
StructuredCloneReadInfo* aInfo)
{
return GetStructuredCloneReadInfoFromSource(aStatement,
aDataIndex,
aFileIdsIndex,
aFileManager,
aInfo,
aHasWasm);
aInfo);
}
static nsresult
@ -5944,13 +5942,11 @@ protected:
FileManager* aFileManager,
StructuredCloneReadInfo* aInfo)
{
bool dummy;
return GetStructuredCloneReadInfoFromSource(aValues,
aDataIndex,
aFileIdsIndex,
aFileManager,
aInfo,
&dummy);
aInfo);
}
static nsresult
@ -6014,23 +6010,20 @@ private:
uint32_t aDataIndex,
uint32_t aFileIdsIndex,
FileManager* aFileManager,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm);
StructuredCloneReadInfo* aInfo);
static nsresult
GetStructuredCloneReadInfoFromBlob(const uint8_t* aBlobData,
uint32_t aBlobDataLength,
FileManager* aFileManager,
const nsAString& aFileIds,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm);
StructuredCloneReadInfo* aInfo);
static nsresult
GetStructuredCloneReadInfoFromExternalBlob(uint64_t aIntData,
FileManager* aFileManager,
const nsAString& aFileIds,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm);
StructuredCloneReadInfo* aInfo);
// Not to be overridden by subclasses.
NS_DECL_MOZISTORAGEPROGRESSHANDLER
@ -8347,9 +8340,9 @@ class ObjectStoreGetRequestOp final
const OptionalKeyRange mOptionalKeyRange;
AutoTArray<StructuredCloneReadInfo, 1> mResponse;
PBackgroundParent* mBackgroundParent;
uint32_t mPreprocessInfoCount;
const uint32_t mLimit;
const bool mGetAll;
bool mHasWasm;
private:
// Only created by TransactionBase.
@ -8360,9 +8353,9 @@ private:
~ObjectStoreGetRequestOp()
{ }
template <bool aForPreprocess, typename T>
nsresult
ConvertResponse(uint32_t aIndex,
SerializedStructuredCloneReadInfo& aSerializedInfo);
ConvertResponse(StructuredCloneReadInfo& aInfo, T& aResult);
virtual nsresult
DoDatabaseWork(DatabaseConnection* aConnection) override;
@ -9713,10 +9706,10 @@ nsresult
DeserializeStructuredCloneFiles(FileManager* aFileManager,
const nsAString& aText,
nsTArray<StructuredCloneFile>& aResult,
bool* aHasWasm)
bool* aHasPreprocessInfo)
{
MOZ_ASSERT(!IsOnBackgroundThread());
MOZ_ASSERT(aHasWasm);
MOZ_ASSERT(aHasPreprocessInfo);
nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing>
tokenizer(aText, ' ');
@ -9738,7 +9731,7 @@ DeserializeStructuredCloneFiles(FileManager* aFileManager,
if (file->mType == StructuredCloneFile::eWasmBytecode) {
MOZ_ASSERT(file->mValid);
*aHasWasm = true;
*aHasPreprocessInfo = true;
}
else if (file->mType == StructuredCloneFile::eWasmCompiled) {
if (!directory) {
@ -9773,7 +9766,7 @@ DeserializeStructuredCloneFiles(FileManager* aFileManager,
file->mValid = JS::CompiledWasmModuleAssumptionsMatch(fileDesc,
Move(buildId));
*aHasWasm = true;
*aHasPreprocessInfo = true;
}
}
@ -19351,8 +19344,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
uint32_t aDataIndex,
uint32_t aFileIdsIndex,
FileManager* aFileManager,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm)
StructuredCloneReadInfo* aInfo)
{
MOZ_ASSERT(!IsOnBackgroundThread());
MOZ_ASSERT(aSource);
@ -19395,8 +19387,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
rv = GetStructuredCloneReadInfoFromExternalBlob(intData,
aFileManager,
fileIds,
aInfo,
aHasWasm);
aInfo);
} else {
const uint8_t* blobData;
uint32_t blobDataLength;
@ -19410,8 +19401,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
blobDataLength,
aFileManager,
fileIds,
aInfo,
aHasWasm);
aInfo);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -19427,8 +19417,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
uint32_t aBlobDataLength,
FileManager* aFileManager,
const nsAString& aFileIds,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm)
StructuredCloneReadInfo* aInfo)
{
MOZ_ASSERT(!IsOnBackgroundThread());
MOZ_ASSERT(aFileManager);
@ -19467,7 +19456,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
nsresult rv = DeserializeStructuredCloneFiles(aFileManager,
aFileIds,
aInfo->mFiles,
aHasWasm);
&aInfo->mHasPreprocessInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -19482,8 +19471,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob(
uint64_t aIntData,
FileManager* aFileManager,
const nsAString& aFileIds,
StructuredCloneReadInfo* aInfo,
bool* aHasWasm)
StructuredCloneReadInfo* aInfo)
{
MOZ_ASSERT(!IsOnBackgroundThread());
MOZ_ASSERT(aFileManager);
@ -19500,7 +19488,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob(
rv = DeserializeStructuredCloneFiles(aFileManager,
aFileIds,
aInfo->mFiles,
aHasWasm);
&aInfo->mHasPreprocessInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -25729,6 +25717,9 @@ NormalTransactionOp::RecvContinue(const PreprocessResponse& aResponse)
case PreprocessResponse::TObjectStoreGetPreprocessResponse:
break;
case PreprocessResponse::TObjectStoreGetAllPreprocessResponse:
break;
default:
MOZ_CRASH("Should never get here!");
}
@ -26599,9 +26590,9 @@ ObjectStoreGetRequestOp::ObjectStoreGetRequestOp(TransactionBase* aTransaction,
OptionalKeyRange(aParams.get_ObjectStoreGetParams()
.keyRange()))
, mBackgroundParent(aTransaction->GetBackgroundParent())
, mPreprocessInfoCount(0)
, mLimit(aGetAll ? aParams.get_ObjectStoreGetAllParams().limit() : 1)
, mGetAll(aGetAll)
, mHasWasm(false)
{
MOZ_ASSERT(aParams.type() == RequestParams::TObjectStoreGetParams ||
aParams.type() == RequestParams::TObjectStoreGetAllParams);
@ -26613,30 +26604,46 @@ ObjectStoreGetRequestOp::ObjectStoreGetRequestOp(TransactionBase* aTransaction,
MOZ_ASSERT(mBackgroundParent);
}
nsresult
ObjectStoreGetRequestOp::ConvertResponse(
uint32_t aIndex,
SerializedStructuredCloneReadInfo& aSerializedInfo)
template <typename T>
void MoveData(StructuredCloneReadInfo& aInfo, T& aResult);
template <>
void
MoveData<SerializedStructuredCloneReadInfo>(
StructuredCloneReadInfo& aInfo,
SerializedStructuredCloneReadInfo& aResult)
{
MOZ_ASSERT(aIndex < mResponse.Length());
aResult.data().data = Move(aInfo.mData);
aResult.hasPreprocessInfo() = aInfo.mHasPreprocessInfo;
}
StructuredCloneReadInfo& info = mResponse[aIndex];
template <>
void
MoveData<WasmModulePreprocessInfo>(StructuredCloneReadInfo& aInfo,
WasmModulePreprocessInfo& aResult)
{
}
aSerializedInfo.data().data = Move(info.mData);
template <bool aForPreprocess, typename T>
nsresult
ObjectStoreGetRequestOp::ConvertResponse(StructuredCloneReadInfo& aInfo,
T& aResult)
{
MoveData(aInfo, aResult);
FallibleTArray<SerializedStructuredCloneFile> serializedFiles;
nsresult rv = SerializeStructuredCloneFiles(mBackgroundParent,
mDatabase,
info.mFiles,
/* aForPreprocess */ false,
aInfo.mFiles,
aForPreprocess,
serializedFiles);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(aSerializedInfo.files().IsEmpty());
MOZ_ASSERT(aResult.files().IsEmpty());
aSerializedInfo.files().SwapElements(serializedFiles);
aResult.files().SwapElements(serializedFiles);
return NS_OK;
}
@ -26707,11 +26714,14 @@ ObjectStoreGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
rv = GetStructuredCloneReadInfoFromStatement(stmt, 1, 0,
mDatabase->GetFileManager(),
cloneInfo,
&mHasWasm);
cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (cloneInfo->mHasPreprocessInfo) {
mPreprocessInfoCount++;
}
}
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -26726,7 +26736,7 @@ ObjectStoreGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
bool
ObjectStoreGetRequestOp::HasPreprocessInfo()
{
return mHasWasm;
return mPreprocessInfoCount > 0;
}
nsresult
@ -26736,31 +26746,47 @@ ObjectStoreGetRequestOp::GetPreprocessParams(PreprocessParams& aParams)
MOZ_ASSERT(!mResponse.IsEmpty());
if (mGetAll) {
MOZ_ASSERT(false, "Fix me!");
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
aParams = ObjectStoreGetAllPreprocessParams();
FallibleTArray<WasmModulePreprocessInfo> falliblePreprocessInfos;
if (NS_WARN_IF(!falliblePreprocessInfos.SetLength(mPreprocessInfoCount,
fallible))) {
return NS_ERROR_OUT_OF_MEMORY;
}
uint32_t fallibleIndex = 0;
for (uint32_t count = mResponse.Length(), index = 0;
index < count;
index++) {
StructuredCloneReadInfo& info = mResponse[index];
if (info.mHasPreprocessInfo) {
nsresult rv =
ConvertResponse<true>(info, falliblePreprocessInfos[fallibleIndex++]);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
nsTArray<WasmModulePreprocessInfo>& preprocessInfos =
aParams.get_ObjectStoreGetAllPreprocessParams().preprocessInfos();
falliblePreprocessInfos.SwapElements(preprocessInfos);
return NS_OK;
}
StructuredCloneReadInfo& cloneInfo = mResponse[0];
aParams = ObjectStoreGetPreprocessParams();
FallibleTArray<SerializedStructuredCloneFile> serializedFiles;
nsresult rv = SerializeStructuredCloneFiles(mBackgroundParent,
mDatabase,
cloneInfo.mFiles,
/* aForPreprocess */ true,
serializedFiles);
WasmModulePreprocessInfo& preprocessInfo =
aParams.get_ObjectStoreGetPreprocessParams().preprocessInfo();
nsresult rv = ConvertResponse<true>(mResponse[0], preprocessInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
WasmModulePreprocessInfo preprocessInfo;
MOZ_ASSERT(preprocessInfo.files().IsEmpty());
preprocessInfo.files().SwapElements(serializedFiles);
aParams = ObjectStoreGetPreprocessParams(preprocessInfo);
return NS_OK;
}
@ -26783,7 +26809,8 @@ ObjectStoreGetRequestOp::GetResponse(RequestResponse& aResponse)
for (uint32_t count = mResponse.Length(), index = 0;
index < count;
index++) {
nsresult rv = ConvertResponse(index, fallibleCloneInfos[index]);
nsresult rv =
ConvertResponse<false>(mResponse[index], fallibleCloneInfos[index]);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResponse = rv;
return;
@ -26805,7 +26832,7 @@ ObjectStoreGetRequestOp::GetResponse(RequestResponse& aResponse)
SerializedStructuredCloneReadInfo& serializedInfo =
aResponse.get_ObjectStoreGetResponse().cloneInfo();
nsresult rv = ConvertResponse(0, serializedInfo);
nsresult rv = ConvertResponse<false>(mResponse[0], serializedInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResponse = rv;
}
@ -27347,11 +27374,9 @@ IndexGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
return NS_ERROR_OUT_OF_MEMORY;
}
bool dummy;
rv = GetStructuredCloneReadInfoFromStatement(stmt, 1, 0,
mDatabase->GetFileManager(),
cloneInfo,
&dummy);
cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -27722,13 +27747,11 @@ CursorOpBase::PopulateResponseFromStatement(
switch (mCursor->mType) {
case OpenCursorParams::TObjectStoreOpenCursorParams: {
StructuredCloneReadInfo cloneInfo;
bool dummy;
rv = GetStructuredCloneReadInfoFromStatement(aStmt,
2,
1,
mCursor->mFileManager,
&cloneInfo,
&dummy);
&cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -27767,13 +27790,11 @@ CursorOpBase::PopulateResponseFromStatement(
}
StructuredCloneReadInfo cloneInfo;
bool dummy;
rv = GetStructuredCloneReadInfoFromStatement(aStmt,
4,
3,
mCursor->mFileManager,
&cloneInfo,
&dummy);
&cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -64,6 +64,7 @@ struct StructuredCloneReadInfo
JSStructuredCloneData mData;
nsTArray<StructuredCloneFile> mFiles;
IDBDatabase* mDatabase;
bool mHasPreprocessInfo;
// In IndexedDatabaseInlines.h
inline

View File

@ -49,6 +49,7 @@ StructuredCloneFile::operator==(const StructuredCloneFile& aOther) const
inline
StructuredCloneReadInfo::StructuredCloneReadInfo()
: mDatabase(nullptr)
, mHasPreprocessInfo(false)
{
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
@ -65,6 +66,8 @@ StructuredCloneReadInfo::StructuredCloneReadInfo(
mFiles.SwapElements(aCloneReadInfo.mFiles);
mDatabase = aCloneReadInfo.mDatabase;
aCloneReadInfo.mDatabase = nullptr;
mHasPreprocessInfo = aCloneReadInfo.mHasPreprocessInfo;
aCloneReadInfo.mHasPreprocessInfo = false;
}
inline
@ -72,6 +75,7 @@ StructuredCloneReadInfo::StructuredCloneReadInfo(
SerializedStructuredCloneReadInfo&& aCloneReadInfo)
: mData(Move(aCloneReadInfo.data().data))
, mDatabase(nullptr)
, mHasPreprocessInfo(aCloneReadInfo.hasPreprocessInfo())
{
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
@ -92,6 +96,8 @@ StructuredCloneReadInfo::operator=(StructuredCloneReadInfo&& aCloneReadInfo)
mFiles.SwapElements(aCloneReadInfo.mFiles);
mDatabase = aCloneReadInfo.mDatabase;
aCloneReadInfo.mDatabase = nullptr;
mHasPreprocessInfo = aCloneReadInfo.mHasPreprocessInfo;
aCloneReadInfo.mHasPreprocessInfo = false;
return *this;
}

View File

@ -116,21 +116,32 @@ struct ObjectStoreGetPreprocessParams
WasmModulePreprocessInfo preprocessInfo;
};
struct ObjectStoreGetAllPreprocessParams
{
WasmModulePreprocessInfo[] preprocessInfos;
};
union PreprocessParams
{
ObjectStoreGetPreprocessParams;
ObjectStoreGetAllPreprocessParams;
};
struct ObjectStoreGetPreprocessResponse
{
};
struct ObjectStoreGetAllPreprocessResponse
{
};
// The nsresult is used if an error occurs for any preprocess request type.
// The specific response types are sent on success.
union PreprocessResponse
{
nsresult;
ObjectStoreGetPreprocessResponse;
ObjectStoreGetAllPreprocessResponse;
};
protocol PBackgroundIDBRequest

View File

@ -66,6 +66,7 @@ struct SerializedStructuredCloneReadInfo
{
SerializedStructuredCloneBuffer data;
SerializedStructuredCloneFile[] files;
bool hasPreprocessInfo;
};
struct SerializedStructuredCloneWriteInfo

View File

@ -113,6 +113,7 @@ support-files =
unit/test_transaction_ordering.js
unit/test_unique_index_update.js
unit/test_view_put_get_values.js
unit/test_wasm_getAll.js
unit/test_wasm_put_get_values.js
unit/test_writer_starvation.js
@ -391,6 +392,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_view_put_get_values.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_wasm_getAll.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_wasm_put_get_values.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_serviceworker.html]

View File

@ -0,0 +1,20 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7" src="unit/test_wasm_getAll.js"></script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -0,0 +1,123 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function testSteps()
{
const name =
this.window ? window.location.pathname : "test_wasm_getAll.js";
const objectStoreInfo = { name: "Wasm", options: { autoIncrement: true } };
const values = [ 42, [], [] ];
if (!isWasmSupported()) {
finishTest();
yield undefined;
}
getWasmBinary('(module (func (result i32) (i32.const 1)))');
let binary = yield undefined;
values[1].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 2)))');
binary = yield undefined;
values[1].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 3)))');
binary = yield undefined;
values[1].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 4)))');
binary = yield undefined;
values[2].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 5)))');
binary = yield undefined;
values[2].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 6)))');
binary = yield undefined;
values[2].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 7)))');
binary = yield undefined;
values[2].push(getWasmModule(binary));
getWasmBinary('(module (func (result i32) (i32.const 8)))');
binary = yield undefined;
values[2].push(getWasmModule(binary));
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = continueToNextStepSync;
request.onsuccess = unexpectedSuccessHandler;
yield undefined;
// upgradeneeded
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = continueToNextStepSync;
info("Creating objectStore");
request.result.createObjectStore(objectStoreInfo.name,
objectStoreInfo.options);
yield undefined;
// success
let db = request.result;
db.onerror = errorHandler;
info("Storing values");
let objectStore = db.transaction([objectStoreInfo.name], "readwrite")
.objectStore(objectStoreInfo.name);
let addedCount = 0;
for (let i in values) {
request = objectStore.add(values[i]);
request.onsuccess = function(event) {
if (++addedCount == values.length) {
continueToNextStep();
}
}
}
yield undefined;
info("Getting values");
request = db.transaction(objectStoreInfo.name)
.objectStore(objectStoreInfo.name).getAll();
request.onsuccess = continueToNextStepSync;
yield undefined;
// Can't call yield inside of the verify function.
let resultsToProcess = [];
function verifyResult(result, value) {
if (value instanceof WebAssembly.Module) {
resultsToProcess.push({ result: result, value: value });
} else if (value instanceof Array) {
is(result instanceof Array, true, "Got an array object");
is(result.length, value.length, "Same length");
for (let i in value) {
verifyResult(result[i], value[i]);
}
} else {
is(result, value, "Same value");
}
}
verifyResult(request.result, values);
for (let resultToProcess of resultsToProcess) {
verifyWasmModule(resultToProcess.result, resultToProcess.value);
yield undefined;
}
finishTest();
yield undefined;
}

View File

@ -59,4 +59,5 @@ skip-if = true
# bug 951017: intermittent failure on Android x86 emulator
skip-if = os == "android" && processor == "x86"
[test_view_put_get_values.js]
[test_wasm_getAll.js]
[test_wasm_put_get_values.js]