mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Bug 963588 - asmjscache: place cache entries apps that request AOT compilation in persistent storage (r=janv)
--HG-- extra : rebase_source : 95bc3d02cb1a7f2728d2615e8b992e0a2b2397f1
This commit is contained in:
parent
a05a9b8736
commit
b7edb7cae1
@ -25,6 +25,7 @@
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
@ -489,6 +490,7 @@ public:
|
||||
mOpenMode(aOpenMode),
|
||||
mWriteParams(aWriteParams),
|
||||
mNeedAllowNextSynchronizedOp(false),
|
||||
mPersistence(quota::PERSISTENCE_TYPE_INVALID),
|
||||
mState(eInitial)
|
||||
{
|
||||
MOZ_ASSERT(IsMainProcess());
|
||||
@ -501,11 +503,12 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
// This method is called by the derived class (either on the JS compilation
|
||||
// thread or the main thread) when a cache entry has been selected to open.
|
||||
// This method is called by the derived class on the main thread when a
|
||||
// cache entry has been selected to open.
|
||||
void
|
||||
OpenForRead(unsigned aModuleIndex)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mState == eWaitingToOpenCacheFileForRead);
|
||||
MOZ_ASSERT(mOpenMode == eOpenForRead);
|
||||
|
||||
@ -514,6 +517,31 @@ protected:
|
||||
DispatchToIOThread();
|
||||
}
|
||||
|
||||
// This method is called by the derived class on the main thread when no cache
|
||||
// entry was found to open. If we just tried a lookup in persistent storage
|
||||
// then we might still get a hit in temporary storage (for an asm.js module
|
||||
// that wasn't compiled at install-time).
|
||||
void
|
||||
CacheMiss()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mState == eFailedToReadMetadata ||
|
||||
mState == eWaitingToOpenCacheFileForRead);
|
||||
MOZ_ASSERT(mOpenMode == eOpenForRead);
|
||||
|
||||
if (mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY) {
|
||||
Fail();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try again with a clean slate. InitOnMainThread will see that mPersistence
|
||||
// is initialized and switch to temporary storage.
|
||||
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT);
|
||||
FinishOnMainThread();
|
||||
mState = eInitial;
|
||||
NS_DispatchToMainThread(this);
|
||||
}
|
||||
|
||||
// This method is called by the derived class (either on the JS compilation
|
||||
// thread or the main thread) when the JS engine is finished reading/writing
|
||||
// the cache entry.
|
||||
@ -602,6 +630,7 @@ private:
|
||||
|
||||
// State initialized during eInitial:
|
||||
bool mNeedAllowNextSynchronizedOp;
|
||||
quota::PersistenceType mPersistence;
|
||||
nsCString mGroup;
|
||||
nsCString mOrigin;
|
||||
nsCString mStorageId;
|
||||
@ -618,6 +647,7 @@ private:
|
||||
eInitial, // Just created, waiting to be dispatched to main thread
|
||||
eWaitingToOpenMetadata, // Waiting to be called back from WaitForOpenAllowed
|
||||
eReadyToReadMetadata, // Waiting to read the metadata file on the IO thread
|
||||
eFailedToReadMetadata, // Waiting to be dispatched to main thread after fail
|
||||
eSendingMetadataForRead, // Waiting to send OnOpenMetadataForRead
|
||||
eWaitingToOpenCacheFileForRead, // Waiting to hear back from child
|
||||
eReadyToOpenCacheFileForRead, // Waiting to open cache file for read
|
||||
@ -643,10 +673,56 @@ MainProcessRunnable::InitOnMainThread()
|
||||
&mOrigin, nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
QuotaManager::GetStorageId(quota::PERSISTENCE_TYPE_TEMPORARY,
|
||||
mOrigin, quota::Client::ASMJS,
|
||||
NS_LITERAL_STRING("asmjs"),
|
||||
mStorageId);
|
||||
bool isApp = mPrincipal->GetAppStatus() !=
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
|
||||
if (mOpenMode == eOpenForWrite) {
|
||||
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_INVALID);
|
||||
if (mWriteParams.mInstalled) {
|
||||
// If we are performing install-time caching of an app, we'd like to store
|
||||
// the cache entry in persistent storage so the entry is never evicted,
|
||||
// but we need to verify that the app has unlimited storage permissions
|
||||
// first. Unlimited storage permissions justify us in skipping all quota
|
||||
// checks when storing the cache entry and avoids all the issues around
|
||||
// the persistent quota prompt.
|
||||
MOZ_ASSERT(isApp);
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> pm =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(pm, NS_ERROR_UNEXPECTED);
|
||||
|
||||
uint32_t permission;
|
||||
rv = pm->TestPermissionFromPrincipal(mPrincipal,
|
||||
PERMISSION_STORAGE_UNLIMITED,
|
||||
&permission);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// If app doens't have the unlimited storage permission, we can still
|
||||
// cache in temporary for a likely good first-run experience.
|
||||
mPersistence = permission == nsIPermissionManager::ALLOW_ACTION
|
||||
? quota::PERSISTENCE_TYPE_PERSISTENT
|
||||
: quota::PERSISTENCE_TYPE_TEMPORARY;
|
||||
} else {
|
||||
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
|
||||
}
|
||||
} else {
|
||||
// For the reasons described above, apps may have cache entries in both
|
||||
// persistent and temporary storage. At lookup time we don't know how and
|
||||
// where the given script was cached, so start the search in persistent
|
||||
// storage and, if that fails, search in temporary storage. (Non-apps can
|
||||
// only be stored in temporary storage.)
|
||||
if (mPersistence == quota::PERSISTENCE_TYPE_INVALID) {
|
||||
mPersistence = isApp ? quota::PERSISTENCE_TYPE_PERSISTENT
|
||||
: quota::PERSISTENCE_TYPE_TEMPORARY;
|
||||
} else {
|
||||
MOZ_ASSERT(isApp);
|
||||
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT);
|
||||
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
|
||||
}
|
||||
}
|
||||
|
||||
QuotaManager::GetStorageId(mPersistence, mOrigin, quota::Client::ASMJS,
|
||||
NS_LITERAL_STRING("asmjs"), mStorageId);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -660,8 +736,12 @@ MainProcessRunnable::ReadMetadata()
|
||||
QuotaManager* qm = QuotaManager::Get();
|
||||
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
|
||||
|
||||
nsresult rv = qm->EnsureOriginIsInitialized(quota::PERSISTENCE_TYPE_TEMPORARY,
|
||||
mGroup, mOrigin, true,
|
||||
// Only track quota for temporary storage. For persistent storage, we've
|
||||
// already checked that we have unlimited-storage permissions.
|
||||
bool trackQuota = mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY;
|
||||
|
||||
nsresult rv = qm->EnsureOriginIsInitialized(mPersistence, mGroup, mOrigin,
|
||||
trackQuota,
|
||||
getter_AddRefs(mDirectory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -730,21 +810,26 @@ MainProcessRunnable::OpenCacheFileForWrite()
|
||||
QuotaManager* qm = QuotaManager::Get();
|
||||
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
|
||||
|
||||
// Create the QuotaObject before all file IO to get maximum assertion coverage
|
||||
// in QuotaManager against concurrent removal, etc.
|
||||
mQuotaObject = qm->GetQuotaObject(quota::PERSISTENCE_TYPE_TEMPORARY,
|
||||
mGroup, mOrigin, file);
|
||||
NS_ENSURE_STATE(mQuotaObject);
|
||||
// If we are allocating in temporary storage, ask the QuotaManager if we're
|
||||
// within the quota. If we are allocating in persistent storage, we've already
|
||||
// checked that we have the unlimited-storage permission, so there is nothing
|
||||
// to check.
|
||||
if (mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY) {
|
||||
// Create the QuotaObject before all file IO and keep it alive until caching
|
||||
// completes to get maximum assertion coverage in QuotaManager against
|
||||
// concurrent removal, etc.
|
||||
mQuotaObject = qm->GetQuotaObject(mPersistence, mGroup, mOrigin, file);
|
||||
NS_ENSURE_STATE(mQuotaObject);
|
||||
|
||||
// Let the QuotaManager know we're about to consume more storage. The
|
||||
// QuotaManager may veto this or evict other storage. If allocation failed, it
|
||||
// might be because mOrigin is using too much space (MaybeAllocateMoreSpace
|
||||
// will not evict our origin since it is active). Try to make some space by
|
||||
// evicting entries until there is enough space.
|
||||
if (!mQuotaObject->MaybeAllocateMoreSpace(0, mWriteParams.mSize)) {
|
||||
EvictEntries(mDirectory, mGroup, mOrigin, mWriteParams.mSize, mMetadata);
|
||||
if (!mQuotaObject->MaybeAllocateMoreSpace(0, mWriteParams.mSize)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
// If the request fails, it might be because mOrigin is using too much
|
||||
// space (MaybeAllocateMoreSpace will not evict our own origin since it is
|
||||
// active). Try to make some space by evicting LRU entries until there is
|
||||
// enough space.
|
||||
EvictEntries(mDirectory, mGroup, mOrigin, mWriteParams.mSize, mMetadata);
|
||||
if (!mQuotaObject->MaybeAllocateMoreSpace(0, mWriteParams.mSize)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -780,11 +865,13 @@ MainProcessRunnable::OpenCacheFileForRead()
|
||||
QuotaManager* qm = QuotaManager::Get();
|
||||
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
|
||||
|
||||
// Create the QuotaObject before all file IO to get maximum assertion coverage
|
||||
// in QuotaManager against concurrent removal, etc.
|
||||
mQuotaObject = qm->GetQuotaObject(quota::PERSISTENCE_TYPE_TEMPORARY,
|
||||
mGroup, mOrigin, file);
|
||||
NS_ENSURE_STATE(mQuotaObject);
|
||||
if (mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY) {
|
||||
// Even though it's not strictly necessary, create the QuotaObject before
|
||||
// all file IO and keep it alive until caching completes to get maximum
|
||||
// assertion coverage in QuotaManager against concurrent removal, etc.
|
||||
mQuotaObject = qm->GetQuotaObject(mPersistence, mGroup, mOrigin, file);
|
||||
NS_ENSURE_STATE(mQuotaObject);
|
||||
}
|
||||
|
||||
rv = file->GetFileSize(&mFileSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -824,7 +911,8 @@ MainProcessRunnable::FinishOnMainThread()
|
||||
QuotaManager* qm = QuotaManager::Get();
|
||||
if (qm) {
|
||||
qm->AllowNextSynchronizedOp(OriginOrPatternString::FromOrigin(mOrigin),
|
||||
Nullable<PersistenceType>(), mStorageId);
|
||||
Nullable<PersistenceType>(mPersistence),
|
||||
mStorageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -849,8 +937,8 @@ MainProcessRunnable::Run()
|
||||
mState = eWaitingToOpenMetadata;
|
||||
rv = QuotaManager::Get()->WaitForOpenAllowed(
|
||||
OriginOrPatternString::FromOrigin(mOrigin),
|
||||
Nullable<PersistenceType>(), mStorageId,
|
||||
this);
|
||||
Nullable<PersistenceType>(mPersistence),
|
||||
mStorageId, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
Fail();
|
||||
return NS_OK;
|
||||
@ -873,7 +961,8 @@ MainProcessRunnable::Run()
|
||||
|
||||
rv = ReadMetadata();
|
||||
if (NS_FAILED(rv)) {
|
||||
Fail();
|
||||
mState = eFailedToReadMetadata;
|
||||
NS_DispatchToMainThread(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -894,6 +983,13 @@ MainProcessRunnable::Run()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case eFailedToReadMetadata: {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
CacheMiss();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case eSendingMetadataForRead: {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mOpenMode == eOpenForRead);
|
||||
@ -1029,12 +1125,11 @@ private:
|
||||
OnOpenMetadataForRead(const Metadata& aMetadata) MOZ_OVERRIDE
|
||||
{
|
||||
uint32_t moduleIndex;
|
||||
if (!FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
|
||||
MainProcessRunnable::Fail();
|
||||
return;
|
||||
if (FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
|
||||
MainProcessRunnable::OpenForRead(moduleIndex);
|
||||
} else {
|
||||
MainProcessRunnable::CacheMiss();
|
||||
}
|
||||
|
||||
MainProcessRunnable::OpenForRead(moduleIndex);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1160,6 +1255,13 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RecvCacheMiss() MOZ_OVERRIDE
|
||||
{
|
||||
MainProcessRunnable::CacheMiss();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
OnOpenCacheFile() MOZ_OVERRIDE
|
||||
{
|
||||
@ -1283,13 +1385,11 @@ private:
|
||||
MOZ_ASSERT(mState == eOpening);
|
||||
|
||||
uint32_t moduleIndex;
|
||||
if (!FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
|
||||
Fail();
|
||||
Send__delete__(this);
|
||||
return true;
|
||||
if (FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
|
||||
return SendSelectCacheFileToRead(moduleIndex);
|
||||
}
|
||||
|
||||
return SendSelectCacheFileToRead(moduleIndex);
|
||||
return SendCacheMiss();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1541,6 +1641,7 @@ CloseEntryForRead(JS::Handle<JSObject*> global,
|
||||
|
||||
bool
|
||||
OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
bool aInstalled,
|
||||
const jschar* aBegin,
|
||||
const jschar* aEnd,
|
||||
size_t aSize,
|
||||
@ -1557,6 +1658,7 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
static_assert(sNumFastHashChars < sMinCachedModuleLength, "HashString safe");
|
||||
|
||||
WriteParams writeParams;
|
||||
writeParams.mInstalled = aInstalled;
|
||||
writeParams.mSize = aSize;
|
||||
writeParams.mFastHash = HashString(aBegin, sNumFastHashChars);
|
||||
writeParams.mNumChars = aEnd - aBegin;
|
||||
@ -1642,6 +1744,9 @@ public:
|
||||
const nsACString& aOrigin,
|
||||
UsageInfo* aUsageInfo) MOZ_OVERRIDE
|
||||
{
|
||||
if (!aUsageInfo) {
|
||||
return NS_OK;
|
||||
}
|
||||
return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aUsageInfo);
|
||||
}
|
||||
|
||||
@ -1670,8 +1775,9 @@ public:
|
||||
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool more;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&more))) && more) {
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||
hasMore && !aUsageInfo->Canceled()) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -1689,6 +1795,7 @@ public:
|
||||
// usage which represents implicit storage allocation.
|
||||
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1809,6 +1916,7 @@ ParamTraits<WriteParams>::Write(Message* aMsg, const paramType& aParam)
|
||||
WriteParam(aMsg, aParam.mFastHash);
|
||||
WriteParam(aMsg, aParam.mNumChars);
|
||||
WriteParam(aMsg, aParam.mFullHash);
|
||||
WriteParam(aMsg, aParam.mInstalled);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1818,7 +1926,8 @@ ParamTraits<WriteParams>::Read(const Message* aMsg, void** aIter,
|
||||
return ReadParam(aMsg, aIter, &aResult->mSize) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mFastHash) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mNumChars) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mFullHash);
|
||||
ReadParam(aMsg, aIter, &aResult->mFullHash) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mInstalled);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1828,6 +1937,7 @@ ParamTraits<WriteParams>::Log(const paramType& aParam, std::wstring* aLog)
|
||||
LogParam(aParam.mFastHash, aLog);
|
||||
LogParam(aParam.mNumChars, aLog);
|
||||
LogParam(aParam.mFullHash, aLog);
|
||||
LogParam(aParam.mInstalled, aLog);
|
||||
}
|
||||
|
||||
} // namespace IPC
|
||||
|
@ -66,12 +66,14 @@ struct WriteParams
|
||||
int64_t mFastHash;
|
||||
int64_t mNumChars;
|
||||
int64_t mFullHash;
|
||||
bool mInstalled;
|
||||
|
||||
WriteParams()
|
||||
: mSize(0),
|
||||
mFastHash(0),
|
||||
mNumChars(0),
|
||||
mFullHash(0)
|
||||
mFullHash(0),
|
||||
mInstalled(false)
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -113,6 +115,7 @@ CloseEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||
intptr_t aHandle);
|
||||
bool
|
||||
OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
bool aInstalled,
|
||||
const jschar* aBegin,
|
||||
const jschar* aEnd,
|
||||
size_t aSize,
|
||||
|
@ -21,6 +21,7 @@ child:
|
||||
OnOpenMetadataForRead(Metadata metadata);
|
||||
parent:
|
||||
SelectCacheFileToRead(uint32_t moduleIndex);
|
||||
CacheMiss();
|
||||
|
||||
child:
|
||||
// Once the cache file has been opened, the child is notified and sent an
|
||||
|
@ -2987,6 +2987,7 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||
|
||||
static bool
|
||||
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
bool aInstalled,
|
||||
const jschar* aBegin,
|
||||
const jschar* aEnd,
|
||||
size_t aSize,
|
||||
@ -2994,8 +2995,8 @@ AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
intptr_t* aHandle)
|
||||
{
|
||||
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
|
||||
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
|
||||
aHandle);
|
||||
return asmjscache::OpenEntryForWrite(principal, aInstalled, aBegin, aEnd,
|
||||
aSize, aMemory, aHandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -21,8 +21,6 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#define PERMISSION_INDEXEDDB_UNLIMITED "indexedDB-unlimited"
|
||||
|
||||
#define TOPIC_QUOTA_PROMPT "indexedDB-quota-prompt"
|
||||
#define TOPIC_QUOTA_RESPONSE "indexedDB-quota-response"
|
||||
#define TOPIC_QUOTA_CANCEL "indexedDB-quota-cancel"
|
||||
@ -129,7 +127,7 @@ CheckQuotaHelper::GetQuotaPermission(nsIPrincipal* aPrincipal)
|
||||
|
||||
uint32_t permission;
|
||||
nsresult rv = pm->TestPermissionFromPrincipal(aPrincipal,
|
||||
PERMISSION_INDEXEDDB_UNLIMITED,
|
||||
PERMISSION_STORAGE_UNLIMITED,
|
||||
&permission);
|
||||
NS_ENSURE_SUCCESS(rv, nsIPermissionManager::DENY_ACTION);
|
||||
|
||||
@ -167,7 +165,7 @@ CheckQuotaHelper::Run()
|
||||
NS_ENSURE_STATE(permissionManager);
|
||||
|
||||
rv = permissionManager->AddFromPrincipal(sop->GetPrincipal(),
|
||||
PERMISSION_INDEXEDDB_UNLIMITED,
|
||||
PERMISSION_STORAGE_UNLIMITED,
|
||||
mPromptResult,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -21,6 +21,7 @@
|
||||
using namespace mozilla::dom::quota;
|
||||
|
||||
#define DSSTORE_FILE_NAME ".DS_Store"
|
||||
#define PERMISSION_STORAGE_UNLIMITED "indexedDB-unlimited"
|
||||
|
||||
BEGIN_QUOTA_NAMESPACE
|
||||
|
||||
|
@ -742,6 +742,7 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||
|
||||
static bool
|
||||
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
bool aInstalled,
|
||||
const jschar* aBegin,
|
||||
const jschar* aEnd,
|
||||
size_t aSize,
|
||||
@ -753,8 +754,8 @@ AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
return false;
|
||||
}
|
||||
|
||||
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
|
||||
aHandle);
|
||||
return asmjscache::OpenEntryForWrite(principal, aInstalled, aBegin, aEnd,
|
||||
aSize, aMemory, aHandle);
|
||||
}
|
||||
|
||||
struct WorkerThreadRuntimePrivate : public PerThreadAtomCache
|
||||
|
@ -1216,10 +1216,13 @@ js::StoreAsmJSModuleInCache(AsmJSParser &parser,
|
||||
|
||||
const jschar *begin = parser.tokenStream.rawBase() + ModuleChars::beginOffset(parser);
|
||||
const jschar *end = parser.tokenStream.rawBase() + ModuleChars::endOffset(parser);
|
||||
bool installed = parser.options().installedFile;
|
||||
|
||||
ScopedCacheEntryOpenedForWrite entry(cx, serializedSize);
|
||||
if (!open(cx->global(), begin, end, entry.serializedSize, &entry.memory, &entry.handle))
|
||||
if (!open(cx->global(), installed, begin, end, entry.serializedSize,
|
||||
&entry.memory, &entry.handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *cursor = entry.memory;
|
||||
cursor = machineId.serialize(cursor);
|
||||
|
@ -3491,6 +3491,7 @@ class JS_FRIEND_API(ReadOnlyCompileOptions)
|
||||
werrorOption(false),
|
||||
asmJSOption(false),
|
||||
forceAsync(false),
|
||||
installedFile(false),
|
||||
sourcePolicy(SAVE_SOURCE),
|
||||
introductionType(nullptr),
|
||||
introductionLineno(0),
|
||||
@ -3530,6 +3531,7 @@ class JS_FRIEND_API(ReadOnlyCompileOptions)
|
||||
bool werrorOption;
|
||||
bool asmJSOption;
|
||||
bool forceAsync;
|
||||
bool installedFile; // 'true' iff pre-compiling js file in packaged app
|
||||
enum SourcePolicy {
|
||||
NO_SOURCE,
|
||||
LAZY_SOURCE,
|
||||
@ -4884,9 +4886,16 @@ typedef void
|
||||
* outparams. If the callback returns 'true', the JS engine guarantees a call
|
||||
* to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
|
||||
* handle.
|
||||
*
|
||||
* If 'installed' is true, then the cache entry is associated with a permanently
|
||||
* installed JS file (e.g., in a packaged webapp). This information allows the
|
||||
* embedding to store the cache entry in a installed location associated with
|
||||
* the principal of 'global' where it will not be evicted until the associated
|
||||
* installed JS file is removed.
|
||||
*/
|
||||
typedef bool
|
||||
(* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, const jschar *begin, const jschar *end,
|
||||
(* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
|
||||
const jschar *begin, const jschar *end,
|
||||
size_t size, uint8_t **memory, intptr_t *handle);
|
||||
typedef void
|
||||
(* CloseAsmJSCacheEntryForWriteOp)(HandleObject global, size_t size, uint8_t *memory,
|
||||
|
@ -5351,7 +5351,8 @@ ShellCloseAsmJSCacheEntryForRead(HandleObject global, size_t serializedSize, con
|
||||
}
|
||||
|
||||
static bool
|
||||
ShellOpenAsmJSCacheEntryForWrite(HandleObject global, const jschar *begin, const jschar *end,
|
||||
ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
|
||||
const jschar *begin, const jschar *end,
|
||||
size_t serializedSize, uint8_t **memoryOut, intptr_t *handleOut)
|
||||
{
|
||||
if (!jsCachingEnabled || !jsCacheAsmJSPath)
|
||||
|
Loading…
x
Reference in New Issue
Block a user