mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1087178 - OdinMonkey: explain why 'not stored in cache' (r=bbouvier,janv)
--HG-- extra : rebase_source : d37893913a09d5a5b339e4ae4ee42f873d449d1e
This commit is contained in:
parent
63551eb571
commit
4f56ee7daf
@ -375,7 +375,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
JS::AsmJSCacheResult
|
||||
BlockUntilOpen(AutoClose* aCloser)
|
||||
{
|
||||
MOZ_ASSERT(!mWaiting, "Can only call BlockUntilOpen once");
|
||||
@ -384,7 +384,9 @@ public:
|
||||
mWaiting = true;
|
||||
|
||||
nsresult rv = NS_DispatchToMainThread(this);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return JS::AsmJSCache_InternalError;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
@ -394,7 +396,7 @@ public:
|
||||
}
|
||||
|
||||
if (!mOpened) {
|
||||
return false;
|
||||
return mResult;
|
||||
}
|
||||
|
||||
// Now that we're open, we're guarnateed a Close() call. However, we are
|
||||
@ -402,7 +404,7 @@ public:
|
||||
// is closed, so we do that ourselves and Release() in OnClose().
|
||||
aCloser->Init(this);
|
||||
AddRef();
|
||||
return true;
|
||||
return JS::AsmJSCache_Success;
|
||||
}
|
||||
|
||||
// This method must be called if BlockUntilOpen returns 'true'. AutoClose
|
||||
@ -416,7 +418,8 @@ protected:
|
||||
: mMutex("File::mMutex"),
|
||||
mCondVar(mMutex, "File::mCondVar"),
|
||||
mWaiting(false),
|
||||
mOpened(false)
|
||||
mOpened(false),
|
||||
mResult(JS::AsmJSCache_InternalError)
|
||||
{ }
|
||||
|
||||
~File()
|
||||
@ -428,15 +431,16 @@ protected:
|
||||
void
|
||||
OnOpen()
|
||||
{
|
||||
Notify(true);
|
||||
Notify(JS::AsmJSCache_Success);
|
||||
}
|
||||
|
||||
void
|
||||
OnFailure()
|
||||
OnFailure(JS::AsmJSCacheResult aResult)
|
||||
{
|
||||
FileDescriptorHolder::Finish();
|
||||
MOZ_ASSERT(aResult != JS::AsmJSCache_Success);
|
||||
|
||||
Notify(false);
|
||||
FileDescriptorHolder::Finish();
|
||||
Notify(aResult);
|
||||
}
|
||||
|
||||
void
|
||||
@ -455,7 +459,7 @@ protected:
|
||||
|
||||
private:
|
||||
void
|
||||
Notify(bool aSuccess)
|
||||
Notify(JS::AsmJSCacheResult aResult)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -463,7 +467,8 @@ private:
|
||||
MOZ_ASSERT(mWaiting);
|
||||
|
||||
mWaiting = false;
|
||||
mOpened = aSuccess;
|
||||
mOpened = aResult == JS::AsmJSCache_Success;
|
||||
mResult = aResult;
|
||||
mCondVar.Notify();
|
||||
}
|
||||
|
||||
@ -471,6 +476,7 @@ private:
|
||||
CondVar mCondVar;
|
||||
bool mWaiting;
|
||||
bool mOpened;
|
||||
JS::AsmJSCacheResult mResult;
|
||||
};
|
||||
|
||||
// MainProcessRunnable is a base class shared by (Single|Parent)ProcessRunnable
|
||||
@ -493,6 +499,7 @@ public:
|
||||
mNeedAllowNextSynchronizedOp(false),
|
||||
mPersistence(quota::PERSISTENCE_TYPE_INVALID),
|
||||
mState(eInitial),
|
||||
mResult(JS::AsmJSCache_InternalError),
|
||||
mIsApp(false),
|
||||
mHasUnlimStoragePerm(false),
|
||||
mEnforcingQuota(true)
|
||||
@ -582,7 +589,7 @@ protected:
|
||||
// This method may be overridden, but it must be called from the overrider.
|
||||
// Called by MainProcessRunnable on the main thread after a call to Fail():
|
||||
virtual void
|
||||
OnFailure()
|
||||
OnFailure(JS::AsmJSCacheResult aResult)
|
||||
{
|
||||
FinishOnMainThread();
|
||||
}
|
||||
@ -665,6 +672,7 @@ private:
|
||||
eFinished, // Terminal state
|
||||
};
|
||||
State mState;
|
||||
JS::AsmJSCacheResult mResult;
|
||||
|
||||
bool mIsApp;
|
||||
bool mHasUnlimStoragePerm;
|
||||
@ -850,6 +858,7 @@ MainProcessRunnable::OpenCacheFileForWrite()
|
||||
// enough space.
|
||||
EvictEntries(mDirectory, mGroup, mOrigin, mWriteParams.mSize, mMetadata);
|
||||
if (!mQuotaObject->MaybeAllocateMoreSpace(0, mWriteParams.mSize)) {
|
||||
mResult = JS::AsmJSCache_QuotaExceeded;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -1048,7 +1057,7 @@ MainProcessRunnable::Run()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mState = eFinished;
|
||||
OnFailure();
|
||||
OnFailure(mResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1168,10 +1177,10 @@ private:
|
||||
}
|
||||
|
||||
void
|
||||
OnFailure() MOZ_OVERRIDE
|
||||
OnFailure(JS::AsmJSCacheResult aResult) MOZ_OVERRIDE
|
||||
{
|
||||
MainProcessRunnable::OnFailure();
|
||||
File::OnFailure();
|
||||
MainProcessRunnable::OnFailure(aResult);
|
||||
File::OnFailure(aResult);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1225,7 +1234,7 @@ private:
|
||||
}
|
||||
|
||||
bool
|
||||
Recv__delete__() MOZ_OVERRIDE
|
||||
Recv__delete__(const JS::AsmJSCacheResult& aResult) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(!mFinished);
|
||||
mFinished = true;
|
||||
@ -1267,7 +1276,7 @@ private:
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!SendOnOpenMetadataForRead(aMetadata)) {
|
||||
unused << Send__delete__(this);
|
||||
unused << Send__delete__(this, JS::AsmJSCache_InternalError);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1296,7 +1305,7 @@ private:
|
||||
FileDescriptor::PlatformHandleType handle =
|
||||
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFileDesc));
|
||||
if (!SendOnOpenCacheFile(mFileSize, FileDescriptor(handle))) {
|
||||
unused << Send__delete__(this);
|
||||
unused << Send__delete__(this, JS::AsmJSCache_InternalError);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1316,17 +1325,17 @@ private:
|
||||
}
|
||||
|
||||
void
|
||||
OnFailure() MOZ_OVERRIDE
|
||||
OnFailure(JS::AsmJSCacheResult aResult) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mOpened);
|
||||
|
||||
mFinished = true;
|
||||
|
||||
MainProcessRunnable::OnFailure();
|
||||
MainProcessRunnable::OnFailure(aResult);
|
||||
|
||||
if (!mActorDestroyed) {
|
||||
unused << Send__delete__(this);
|
||||
unused << Send__delete__(this, aResult);
|
||||
}
|
||||
|
||||
mPrincipalHolder = nullptr;
|
||||
@ -1435,12 +1444,12 @@ private:
|
||||
}
|
||||
|
||||
bool
|
||||
Recv__delete__() MOZ_OVERRIDE
|
||||
Recv__delete__(const JS::AsmJSCacheResult& aResult) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mState == eOpening);
|
||||
|
||||
Fail();
|
||||
Fail(aResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1462,13 +1471,13 @@ private:
|
||||
|
||||
private:
|
||||
void
|
||||
Fail()
|
||||
Fail(JS::AsmJSCacheResult aResult)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mState == eInitial || mState == eOpening);
|
||||
|
||||
mState = eFinished;
|
||||
File::OnFailure();
|
||||
File::OnFailure(aResult);
|
||||
}
|
||||
|
||||
nsIPrincipal* const mPrincipal;
|
||||
@ -1507,7 +1516,7 @@ ChildProcessRunnable::Run()
|
||||
// 'this' alive until returning to the event loop.
|
||||
Release();
|
||||
|
||||
Fail();
|
||||
Fail(JS::AsmJSCache_InternalError);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1524,7 +1533,7 @@ ChildProcessRunnable::Run()
|
||||
File::OnClose();
|
||||
|
||||
if (!mActorDestroyed) {
|
||||
unused << Send__delete__(this);
|
||||
unused << Send__delete__(this, JS::AsmJSCache_Success);
|
||||
}
|
||||
|
||||
mState = eFinished;
|
||||
@ -1553,7 +1562,7 @@ DeallocEntryChild(PAsmJSCacheEntryChild* aActor)
|
||||
|
||||
namespace {
|
||||
|
||||
bool
|
||||
JS::AsmJSCacheResult
|
||||
OpenFile(nsIPrincipal* aPrincipal,
|
||||
OpenMode aOpenMode,
|
||||
WriteParams aWriteParams,
|
||||
@ -1576,7 +1585,7 @@ OpenFile(nsIPrincipal* aPrincipal,
|
||||
// in the middle of running JS (eval()) and nested event loops can be
|
||||
// semantically observable.
|
||||
if (NS_IsMainThread()) {
|
||||
return false;
|
||||
return JS::AsmJSCache_SynchronousScript;
|
||||
}
|
||||
|
||||
// If we are in a child process, we need to synchronously call into the
|
||||
@ -1591,11 +1600,16 @@ OpenFile(nsIPrincipal* aPrincipal,
|
||||
aReadParams);
|
||||
}
|
||||
|
||||
if (!file->BlockUntilOpen(aFile)) {
|
||||
return false;
|
||||
JS::AsmJSCacheResult openResult = file->BlockUntilOpen(aFile);
|
||||
if (openResult != JS::AsmJSCache_Success) {
|
||||
return openResult;
|
||||
}
|
||||
|
||||
return file->MapMemory(aOpenMode);
|
||||
if (!file->MapMemory(aOpenMode)) {
|
||||
return JS::AsmJSCache_InternalError;
|
||||
}
|
||||
|
||||
return JS::AsmJSCache_Success;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@ -1621,7 +1635,9 @@ OpenEntryForRead(nsIPrincipal* aPrincipal,
|
||||
|
||||
File::AutoClose file;
|
||||
WriteParams notAWrite;
|
||||
if (!OpenFile(aPrincipal, eOpenForRead, notAWrite, readParams, &file)) {
|
||||
JS::AsmJSCacheResult openResult =
|
||||
OpenFile(aPrincipal, eOpenForRead, notAWrite, readParams, &file);
|
||||
if (openResult != JS::AsmJSCache_Success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1661,7 +1677,7 @@ CloseEntryForRead(size_t aSize,
|
||||
MOZ_ASSERT(aMemory - sizeof(AsmJSCookieType) == file->MappedMemory());
|
||||
}
|
||||
|
||||
bool
|
||||
JS::AsmJSCacheResult
|
||||
OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
bool aInstalled,
|
||||
const char16_t* aBegin,
|
||||
@ -1671,7 +1687,7 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
intptr_t* aFile)
|
||||
{
|
||||
if (size_t(aEnd - aBegin) < sMinCachedModuleLength) {
|
||||
return false;
|
||||
return JS::AsmJSCache_ModuleTooSmall;
|
||||
}
|
||||
|
||||
// Add extra space for the AsmJSCookieType (see OpenEntryForRead).
|
||||
@ -1688,8 +1704,10 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
|
||||
File::AutoClose file;
|
||||
ReadParams notARead;
|
||||
if (!OpenFile(aPrincipal, eOpenForWrite, writeParams, notARead, &file)) {
|
||||
return false;
|
||||
JS::AsmJSCacheResult openResult =
|
||||
OpenFile(aPrincipal, eOpenForWrite, writeParams, notARead, &file);
|
||||
if (openResult != JS::AsmJSCache_Success) {
|
||||
return openResult;
|
||||
}
|
||||
|
||||
// Strip off the AsmJSCookieType from the buffer returned to the caller,
|
||||
@ -1700,7 +1718,7 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
// The caller guarnatees a call to CloseEntryForWrite (on success or
|
||||
// failure) at which point the file will be closed
|
||||
file.Forget(reinterpret_cast<File**>(aFile));
|
||||
return true;
|
||||
return JS::AsmJSCache_Success;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -112,7 +112,7 @@ void
|
||||
CloseEntryForRead(size_t aSize,
|
||||
const uint8_t* aMemory,
|
||||
intptr_t aHandle);
|
||||
bool
|
||||
JS::AsmJSCacheResult
|
||||
OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||
bool aInstalled,
|
||||
const char16_t* aBegin,
|
||||
@ -178,6 +178,13 @@ struct ParamTraits<mozilla::dom::asmjscache::WriteParams>
|
||||
static void Log(const paramType& aParam, std::wstring* aLog);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<JS::AsmJSCacheResult> :
|
||||
public ContiguousEnumSerializer<JS::AsmJSCacheResult,
|
||||
JS::AsmJSCache_MIN,
|
||||
JS::AsmJSCache_LIMIT>
|
||||
{ };
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_dom_asmjscache_asmjscache_h
|
||||
|
@ -5,6 +5,7 @@
|
||||
include protocol PContent;
|
||||
|
||||
using mozilla::dom::asmjscache::Metadata from "mozilla/dom/asmjscache/AsmJSCache.h";
|
||||
using JS::AsmJSCacheResult from "mozilla/dom/asmjscache/AsmJSCache.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -29,7 +30,7 @@ child:
|
||||
OnOpenCacheFile(int64_t fileSize, FileDescriptor fileDesc);
|
||||
|
||||
both:
|
||||
__delete__();
|
||||
__delete__(AsmJSCacheResult result);
|
||||
};
|
||||
|
||||
} // namespace asmjscache
|
||||
|
@ -2703,7 +2703,7 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||
aHandle);
|
||||
}
|
||||
|
||||
static bool
|
||||
static JS::AsmJSCacheResult
|
||||
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
bool aInstalled,
|
||||
const char16_t* aBegin,
|
||||
|
@ -734,7 +734,7 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||
aHandle);
|
||||
}
|
||||
|
||||
static bool
|
||||
static JS::AsmJSCacheResult
|
||||
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
bool aInstalled,
|
||||
const char16_t* aBegin,
|
||||
@ -745,7 +745,7 @@ AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
{
|
||||
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
|
||||
if (!principal) {
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
}
|
||||
|
||||
return asmjscache::OpenEntryForWrite(principal, aInstalled, aBegin, aEnd,
|
||||
|
@ -2134,7 +2134,7 @@ struct ScopedCacheEntryOpenedForWrite
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
JS::AsmJSCacheResult
|
||||
js::StoreAsmJSModuleInCache(AsmJSParser &parser,
|
||||
const AsmJSModule &module,
|
||||
ExclusiveContext *cx)
|
||||
@ -2144,15 +2144,15 @@ js::StoreAsmJSModuleInCache(AsmJSParser &parser,
|
||||
// that can't be serialized. (This is separate from normal profiling and
|
||||
// requires an addon to activate).
|
||||
if (module.numFunctionCounts())
|
||||
return false;
|
||||
return JS::AsmJSCache_Disabled_JitInspector;
|
||||
|
||||
MachineId machineId;
|
||||
if (!machineId.extractCurrentState(cx))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
|
||||
ModuleCharsForStore moduleChars;
|
||||
if (!moduleChars.init(parser))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
|
||||
size_t serializedSize = machineId.serializedSize() +
|
||||
moduleChars.serializedSize() +
|
||||
@ -2160,17 +2160,17 @@ js::StoreAsmJSModuleInCache(AsmJSParser &parser,
|
||||
|
||||
JS::OpenAsmJSCacheEntryForWriteOp open = cx->asmJSCacheOps().openEntryForWrite;
|
||||
if (!open)
|
||||
return false;
|
||||
return JS::AsmJSCache_Disabled_Internal;
|
||||
|
||||
const char16_t *begin = parser.tokenStream.rawBase() + ModuleChars::beginOffset(parser);
|
||||
const char16_t *end = parser.tokenStream.rawBase() + ModuleChars::endOffset(parser);
|
||||
bool installed = parser.options().installedFile;
|
||||
|
||||
ScopedCacheEntryOpenedForWrite entry(cx, serializedSize);
|
||||
if (!open(cx->global(), installed, begin, end, entry.serializedSize,
|
||||
&entry.memory, &entry.handle)) {
|
||||
return false;
|
||||
}
|
||||
JS::AsmJSCacheResult openResult =
|
||||
open(cx->global(), installed, begin, end, serializedSize, &entry.memory, &entry.handle);
|
||||
if (openResult != JS::AsmJSCache_Success)
|
||||
return openResult;
|
||||
|
||||
uint8_t *cursor = entry.memory;
|
||||
cursor = machineId.serialize(cursor);
|
||||
@ -2178,7 +2178,7 @@ js::StoreAsmJSModuleInCache(AsmJSParser &parser,
|
||||
cursor = module.serialize(cursor);
|
||||
|
||||
MOZ_ASSERT(cursor == entry.memory + serializedSize);
|
||||
return true;
|
||||
return JS::AsmJSCache_Success;
|
||||
}
|
||||
|
||||
struct ScopedCacheEntryOpenedForRead
|
||||
|
@ -1538,7 +1538,7 @@ class AsmJSModule
|
||||
};
|
||||
|
||||
// Store the just-parsed module in the cache using AsmJSCacheOps.
|
||||
extern bool
|
||||
extern JS::AsmJSCacheResult
|
||||
StoreAsmJSModuleInCache(AsmJSParser &parser,
|
||||
const AsmJSModule &module,
|
||||
ExclusiveContext *cx);
|
||||
|
@ -1874,7 +1874,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
return module_->addBuiltinThunkCodeRange(builtin, begin->offset(), pret->offset(), end);
|
||||
}
|
||||
|
||||
void buildCompilationTimeReport(bool storedInCache, ScopedJSFreePtr<char> *out) {
|
||||
void buildCompilationTimeReport(JS::AsmJSCacheResult cacheResult, ScopedJSFreePtr<char> *out) {
|
||||
ScopedJSFreePtr<char> slowFuns;
|
||||
#ifndef JS_MORE_DETERMINISTIC
|
||||
int64_t usecAfter = PRMJ_Now();
|
||||
@ -1895,10 +1895,39 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
return;
|
||||
}
|
||||
}
|
||||
const char *cacheString = "";
|
||||
switch (cacheResult) {
|
||||
case JS::AsmJSCache_Success:
|
||||
cacheString = "stored in cache";
|
||||
break;
|
||||
case JS::AsmJSCache_ModuleTooSmall:
|
||||
cacheString = "not stored in cache (too small to benefit)";
|
||||
break;
|
||||
case JS::AsmJSCache_SynchronousScript:
|
||||
cacheString = "unable to cache asm.js in synchronous scripts; try loading "
|
||||
"asm.js via <script async> or createElement('script')";
|
||||
break;
|
||||
case JS::AsmJSCache_QuotaExceeded:
|
||||
cacheString = "not enough temporary storage quota to store in cache";
|
||||
break;
|
||||
case JS::AsmJSCache_Disabled_Internal:
|
||||
cacheString = "caching disabled by internal configuration (consider filing a bug)";
|
||||
break;
|
||||
case JS::AsmJSCache_Disabled_ShellFlags:
|
||||
cacheString = "caching disabled by missing command-line arguments";
|
||||
break;
|
||||
case JS::AsmJSCache_Disabled_JitInspector:
|
||||
cacheString = "caching disabled by active JIT inspector";
|
||||
break;
|
||||
case JS::AsmJSCache_InternalError:
|
||||
cacheString = "unable to store in cache due to internal error (consider filing a bug)";
|
||||
break;
|
||||
case JS::AsmJSCache_LIMIT:
|
||||
MOZ_CRASH("bad AsmJSCacheResult");
|
||||
break;
|
||||
}
|
||||
out->reset(JS_smprintf("total compilation time %dms; %s%s",
|
||||
msTotal,
|
||||
storedInCache ? "stored in cache" : "not stored in cache",
|
||||
slowFuns ? slowFuns.get() : ""));
|
||||
msTotal, cacheString, slowFuns ? slowFuns.get() : ""));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -8619,10 +8648,10 @@ CheckModule(ExclusiveContext *cx, AsmJSParser &parser, ParseNode *stmtList,
|
||||
if (!FinishModule(m, &module))
|
||||
return false;
|
||||
|
||||
bool storedInCache = StoreAsmJSModuleInCache(parser, *module, cx);
|
||||
JS::AsmJSCacheResult cacheResult = StoreAsmJSModuleInCache(parser, *module, cx);
|
||||
module->staticallyLink(cx);
|
||||
|
||||
m.buildCompilationTimeReport(storedInCache, compilationTimeReport);
|
||||
m.buildCompilationTimeReport(cacheResult, compilationTimeReport);
|
||||
*moduleOut = module.forget();
|
||||
return true;
|
||||
}
|
||||
|
@ -5237,6 +5237,21 @@ typedef bool
|
||||
typedef void
|
||||
(* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t *memory, intptr_t handle);
|
||||
|
||||
/* The list of reasons why an asm.js module may not be stored in the cache. */
|
||||
enum AsmJSCacheResult
|
||||
{
|
||||
AsmJSCache_MIN,
|
||||
AsmJSCache_Success = AsmJSCache_MIN,
|
||||
AsmJSCache_ModuleTooSmall,
|
||||
AsmJSCache_SynchronousScript,
|
||||
AsmJSCache_QuotaExceeded,
|
||||
AsmJSCache_Disabled_Internal,
|
||||
AsmJSCache_Disabled_ShellFlags,
|
||||
AsmJSCache_Disabled_JitInspector,
|
||||
AsmJSCache_InternalError,
|
||||
AsmJSCache_LIMIT
|
||||
};
|
||||
|
||||
/*
|
||||
* This callback represents a request by the JS engine to open for writing a
|
||||
* cache entry of the given size for the given global and char range containing
|
||||
@ -5252,7 +5267,7 @@ typedef void
|
||||
* the principal of 'global' where it will not be evicted until the associated
|
||||
* installed JS file is removed.
|
||||
*/
|
||||
typedef bool
|
||||
typedef AsmJSCacheResult
|
||||
(* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
|
||||
const char16_t *begin, const char16_t *end,
|
||||
size_t size, uint8_t **memory, intptr_t *handle);
|
||||
|
@ -5183,32 +5183,32 @@ ShellCloseAsmJSCacheEntryForRead(size_t serializedSize, const uint8_t *memory, i
|
||||
close(handle);
|
||||
}
|
||||
|
||||
static bool
|
||||
static JS::AsmJSCacheResult
|
||||
ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
|
||||
const char16_t *begin, const char16_t *end,
|
||||
size_t serializedSize, uint8_t **memoryOut, intptr_t *handleOut)
|
||||
{
|
||||
if (!jsCachingEnabled || !jsCacheAsmJSPath)
|
||||
return false;
|
||||
return JS::AsmJSCache_Disabled_ShellFlags;
|
||||
|
||||
// Create the cache directory if it doesn't already exist.
|
||||
struct stat dirStat;
|
||||
if (stat(jsCacheDir, &dirStat) == 0) {
|
||||
if (!(dirStat.st_mode & S_IFDIR))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
} else {
|
||||
#ifdef XP_WIN
|
||||
if (mkdir(jsCacheDir) != 0)
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
#else
|
||||
if (mkdir(jsCacheDir, 0777) != 0)
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
#endif
|
||||
}
|
||||
|
||||
ScopedFileDesc fd(open(jsCacheAsmJSPath, O_CREAT|O_RDWR, 0660), ScopedFileDesc::WRITE_LOCK);
|
||||
if (fd == -1)
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
|
||||
// Include extra space for the asmJSCacheCookie.
|
||||
serializedSize += sizeof(uint32_t);
|
||||
@ -5216,14 +5216,14 @@ ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
|
||||
// Resize the file to the appropriate size after zeroing their contents.
|
||||
#ifdef XP_WIN
|
||||
if (chsize(fd, 0))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
if (chsize(fd, serializedSize))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
#else
|
||||
if (ftruncate(fd, 0))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
if (ftruncate(fd, serializedSize))
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
#endif
|
||||
|
||||
// Map the file into memory.
|
||||
@ -5232,16 +5232,16 @@ ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
|
||||
HANDLE fdOsHandle = (HANDLE)_get_osfhandle(fd);
|
||||
HANDLE fileMapping = CreateFileMapping(fdOsHandle, nullptr, PAGE_READWRITE, 0, 0, nullptr);
|
||||
if (!fileMapping)
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
|
||||
memory = MapViewOfFile(fileMapping, FILE_MAP_WRITE, 0, 0, 0);
|
||||
CloseHandle(fileMapping);
|
||||
if (!memory)
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
#else
|
||||
memory = mmap(nullptr, serializedSize, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (memory == MAP_FAILED)
|
||||
return false;
|
||||
return JS::AsmJSCache_InternalError;
|
||||
#endif
|
||||
|
||||
// The embedding added the cookie so strip it off of the buffer returned to
|
||||
@ -5249,7 +5249,7 @@ ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
|
||||
MOZ_ASSERT(*(uint32_t *)memory == 0);
|
||||
*memoryOut = (uint8_t *)memory + sizeof(uint32_t);
|
||||
*handleOut = fd.forget();
|
||||
return true;
|
||||
return JS::AsmJSCache_Success;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user