mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 520309, startupcache client mozJSComponentLoader, r=dwitte a=bsmedberg
This commit is contained in:
parent
fba716bbcd
commit
f0f5cb9f08
@ -75,16 +75,22 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "jsxdrapi.h"
|
#include "jsxdrapi.h"
|
||||||
#include "jsprf.h"
|
#include "jsprf.h"
|
||||||
#include "nsIFastLoadFileControl.h"
|
|
||||||
// For reporting errors with the console service
|
// For reporting errors with the console service
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
|
#include "nsIStorageStream.h"
|
||||||
|
#include "nsIStringStream.h"
|
||||||
#include "prmem.h"
|
#include "prmem.h"
|
||||||
#include "plbase64.h"
|
#include "plbase64.h"
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
#include "nsILocalFileWin.h"
|
#include "nsILocalFileWin.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_ENABLE_LIBXUL
|
||||||
|
#include "mozilla/scache/StartupCache.h"
|
||||||
|
#include "mozilla/scache/StartupCacheUtils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MOZ_SHARK) || defined(MOZ_CALLGRIND) || defined(MOZ_VTUNE) || defined(MOZ_TRACEVIS)
|
#if defined(MOZ_SHARK) || defined(MOZ_CALLGRIND) || defined(MOZ_VTUNE) || defined(MOZ_TRACEVIS)
|
||||||
#include "jsdbgapi.h"
|
#include "jsdbgapi.h"
|
||||||
#endif
|
#endif
|
||||||
@ -107,9 +113,6 @@ static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;
|
|||||||
#define XPC_SERIALIZATION_BUFFER_SIZE (64 * 1024)
|
#define XPC_SERIALIZATION_BUFFER_SIZE (64 * 1024)
|
||||||
#define XPC_DESERIALIZATION_BUFFER_SIZE (12 * 8192)
|
#define XPC_DESERIALIZATION_BUFFER_SIZE (12 * 8192)
|
||||||
|
|
||||||
// Inactivity delay before closing our fastload file stream.
|
|
||||||
static const int kFastLoadWriteDelay = 10000; // 10 seconds
|
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
// NSPR_LOG_MODULES=JSComponentLoader:5
|
// NSPR_LOG_MODULES=JSComponentLoader:5
|
||||||
static PRLogModuleInfo *gJSCLLog;
|
static PRLogModuleInfo *gJSCLLog;
|
||||||
@ -388,59 +391,6 @@ ReportOnCaller(JSCLContextHelper &helper,
|
|||||||
return OutputError(cx, format, ap);
|
return OutputError(cx, format, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsXPCFastLoadIO, nsIFastLoadFileIO)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXPCFastLoadIO::GetInputStream(nsIInputStream **_retval)
|
|
||||||
{
|
|
||||||
if (! mInputStream) {
|
|
||||||
nsCOMPtr<nsIInputStream> fileInput;
|
|
||||||
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInput),
|
|
||||||
mFile);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = NS_NewBufferedInputStream(getter_AddRefs(mInputStream),
|
|
||||||
fileInput,
|
|
||||||
XPC_DESERIALIZATION_BUFFER_SIZE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
mTruncateOutputFile = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*_retval = mInputStream);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXPCFastLoadIO::GetOutputStream(nsIOutputStream **_retval)
|
|
||||||
{
|
|
||||||
if (! mOutputStream) {
|
|
||||||
PRInt32 ioFlags = PR_WRONLY;
|
|
||||||
if (mTruncateOutputFile) {
|
|
||||||
ioFlags |= PR_CREATE_FILE | PR_TRUNCATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIOutputStream> fileOutput;
|
|
||||||
nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOutput),
|
|
||||||
mFile, ioFlags, 0644);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = NS_NewBufferedOutputStream(getter_AddRefs(mOutputStream),
|
|
||||||
fileOutput,
|
|
||||||
XPC_SERIALIZATION_BUFFER_SIZE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*_retval = mOutputStream);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXPCFastLoadIO::DisableTruncate()
|
|
||||||
{
|
|
||||||
mTruncateOutputFile = false;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
|
ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
|
||||||
JSScript **script)
|
JSScript **script)
|
||||||
@ -566,9 +516,6 @@ mozJSComponentLoader::~mozJSComponentLoader()
|
|||||||
UnloadModules();
|
UnloadModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(!mFastLoadTimer,
|
|
||||||
"Fastload file should have been closed via xpcom-shutdown");
|
|
||||||
|
|
||||||
sSelf = nsnull;
|
sSelf = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,9 +531,9 @@ nsresult
|
|||||||
mozJSComponentLoader::ReallyInit()
|
mozJSComponentLoader::ReallyInit()
|
||||||
{
|
{
|
||||||
NS_TIME_FUNCTION;
|
NS_TIME_FUNCTION;
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the JSRuntime from the runtime svc, if possible.
|
* Get the JSRuntime from the runtime svc, if possible.
|
||||||
* We keep a reference around, because it's a Bad Thing if the runtime
|
* We keep a reference around, because it's a Bad Thing if the runtime
|
||||||
@ -634,23 +581,10 @@ mozJSComponentLoader::ReallyInit()
|
|||||||
if (!mInProgressImports.Init(32))
|
if (!mInProgressImports.Init(32))
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
// Set up our fastload file
|
|
||||||
nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv);
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
rv = flSvc->NewFastLoadFile("XPC", getter_AddRefs(mFastLoadFile));
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
LOG(("Could not get fastload file location\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for xpcom-shutdown so that we can close out our fastload file
|
|
||||||
// at that point (after that we can no longer create an input stream).
|
|
||||||
nsCOMPtr<nsIObserverService> obsSvc =
|
nsCOMPtr<nsIObserverService> obsSvc =
|
||||||
do_GetService(kObserverServiceContractID, &rv);
|
do_GetService(kObserverServiceContractID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = obsSvc->AddObserver(this, "xpcom-shutdown-loaders", PR_FALSE);
|
rv = obsSvc->AddObserver(this, "xpcom-shutdown-loaders", PR_FALSE);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
@ -932,245 +866,66 @@ class JSScriptHolder
|
|||||||
JSScript *mScript;
|
JSScript *mScript;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FastLoadStateHolder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit FastLoadStateHolder(nsIFastLoadService *service);
|
|
||||||
~FastLoadStateHolder() { pop(); }
|
|
||||||
|
|
||||||
void pop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCOMPtr<nsIFastLoadService> mService;
|
|
||||||
nsCOMPtr<nsIFastLoadFileIO> mIO;
|
|
||||||
nsCOMPtr<nsIObjectInputStream> mInputStream;
|
|
||||||
nsCOMPtr<nsIObjectOutputStream> mOutputStream;
|
|
||||||
};
|
|
||||||
|
|
||||||
FastLoadStateHolder::FastLoadStateHolder(nsIFastLoadService *service)
|
|
||||||
{
|
|
||||||
if (!service)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mService = service;
|
|
||||||
service->GetFileIO(getter_AddRefs(mIO));
|
|
||||||
service->GetInputStream(getter_AddRefs(mInputStream));
|
|
||||||
service->GetOutputStream(getter_AddRefs(mOutputStream));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FastLoadStateHolder::pop()
|
|
||||||
{
|
|
||||||
if (!mService)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mService->SetFileIO(mIO);
|
|
||||||
mService->SetInputStream(mInputStream);
|
|
||||||
mService->SetOutputStream(mOutputStream);
|
|
||||||
|
|
||||||
mService = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
void
|
#ifdef MOZ_ENABLE_LIBXUL
|
||||||
mozJSComponentLoader::CloseFastLoad(nsITimer *timer, void *closure)
|
|
||||||
{
|
|
||||||
static_cast<mozJSComponentLoader*>(closure)->CloseFastLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mozJSComponentLoader::CloseFastLoad()
|
|
||||||
{
|
|
||||||
// Close our fastload streams
|
|
||||||
LOG(("Closing fastload file\n"));
|
|
||||||
if (mFastLoadOutput) {
|
|
||||||
nsresult rv = mFastLoadOutput->Close();
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
flSvc->CacheChecksum(mFastLoadFile, mFastLoadOutput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mFastLoadOutput = nsnull;
|
|
||||||
}
|
|
||||||
if (mFastLoadInput) {
|
|
||||||
mFastLoadInput->Close();
|
|
||||||
mFastLoadInput = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
mFastLoadIO = nsnull;
|
|
||||||
mFastLoadTimer = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
mozJSComponentLoader::StartFastLoad(nsIFastLoadService *flSvc)
|
mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
|
||||||
{
|
|
||||||
if (!mFastLoadFile || !flSvc) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now set our IO object as current, and create our streams.
|
|
||||||
if (!mFastLoadIO) {
|
|
||||||
mFastLoadIO = new nsXPCFastLoadIO(mFastLoadFile);
|
|
||||||
NS_ENSURE_TRUE(mFastLoadIO, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = flSvc->SetFileIO(mFastLoadIO);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!mFastLoadInput && !mFastLoadOutput) {
|
|
||||||
// First time accessing the fastload file
|
|
||||||
PRBool exists;
|
|
||||||
mFastLoadFile->Exists(&exists);
|
|
||||||
if (exists) {
|
|
||||||
LOG(("trying to use existing fastload file\n"));
|
|
||||||
|
|
||||||
rv = flSvc->NewInputStream(mFastLoadFile, getter_AddRefs(mFastLoadInput));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
LOG(("opened fastload file for reading\n"));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFastLoadReadControl>
|
|
||||||
readControl(do_QueryInterface(mFastLoadInput));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
/* Get the JS bytecode version number and validate it. */
|
|
||||||
PRUint32 version;
|
|
||||||
rv = mFastLoadInput->Read32(&version);
|
|
||||||
if (NS_SUCCEEDED(rv) && version != JSXDR_BYTECODE_VERSION) {
|
|
||||||
LOG(("Bad JS bytecode version\n"));
|
|
||||||
rv = NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
LOG(("Invalid fastload file detected, removing it\n"));
|
|
||||||
if (mFastLoadInput) {
|
|
||||||
mFastLoadInput->Close();
|
|
||||||
mFastLoadInput = nsnull;
|
|
||||||
}
|
|
||||||
mFastLoadIO->SetInputStream(nsnull);
|
|
||||||
mFastLoadFile->Remove(PR_FALSE);
|
|
||||||
exists = PR_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exists) {
|
|
||||||
LOG(("Creating new fastload file\n"));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIOutputStream> output;
|
|
||||||
rv = mFastLoadIO->GetOutputStream(getter_AddRefs(output));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = flSvc->NewOutputStream(output,
|
|
||||||
getter_AddRefs(mFastLoadOutput));
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
rv = mFastLoadOutput->Write32(JSXDR_BYTECODE_VERSION);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
LOG(("Fatal error, could not create fastload file\n"));
|
|
||||||
|
|
||||||
if (mFastLoadOutput) {
|
|
||||||
mFastLoadOutput->Close();
|
|
||||||
mFastLoadOutput = nsnull;
|
|
||||||
} else {
|
|
||||||
output->Close();
|
|
||||||
}
|
|
||||||
mFastLoadIO->SetOutputStream(nsnull);
|
|
||||||
mFastLoadFile->Remove(PR_FALSE);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flSvc->SetInputStream(mFastLoadInput);
|
|
||||||
flSvc->SetOutputStream(mFastLoadOutput);
|
|
||||||
|
|
||||||
// Start our update timer. This allows us to keep the stream open
|
|
||||||
// when many components are loaded in succession, but close it once
|
|
||||||
// there has been a period of inactivity.
|
|
||||||
|
|
||||||
if (!mFastLoadTimer) {
|
|
||||||
mFastLoadTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = mFastLoadTimer->InitWithFuncCallback(&mozJSComponentLoader::CloseFastLoad,
|
|
||||||
this,
|
|
||||||
kFastLoadWriteDelay,
|
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
} else {
|
|
||||||
// Note, that since CloseFastLoad nulls out mFastLoadTimer,
|
|
||||||
// SetDelay() will only be called on a timer that hasn't fired.
|
|
||||||
rv = mFastLoadTimer->SetDelay(kFastLoadWriteDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
mozJSComponentLoader::ReadScript(nsIFastLoadService *flSvc,
|
|
||||||
const char *nativePath, nsIURI *uri,
|
|
||||||
JSContext *cx, JSScript **script)
|
JSContext *cx, JSScript **script)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(flSvc, "fastload not initialized");
|
nsresult rv;
|
||||||
|
|
||||||
nsresult rv = flSvc->StartMuxedDocument(uri, nativePath,
|
nsCAutoString spec;
|
||||||
nsIFastLoadService::NS_FASTLOAD_READ);
|
rv = uri->GetSpec(spec);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsAutoArrayPtr<char> buf;
|
||||||
|
PRUint32 len;
|
||||||
|
rv = cache->GetBuffer(spec.get(), getter_Transfers(buf),
|
||||||
|
&len);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv; // don't warn since NOT_AVAILABLE is an ok error
|
return rv; // don't warn since NOT_AVAILABLE is an ok error
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(("Found %s in fastload file\n", nativePath));
|
LOG(("Found %s in startupcache\n", spec.get()));
|
||||||
|
nsCOMPtr<nsIObjectInputStream> ois;
|
||||||
nsCOMPtr<nsIURI> oldURI;
|
rv = NS_NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(ois));
|
||||||
rv = flSvc->SelectMuxedDocument(uri, getter_AddRefs(oldURI));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
buf.forget();
|
||||||
|
|
||||||
NS_ASSERTION(mFastLoadInput,
|
return ReadScriptFromStream(cx, ois, script);
|
||||||
"FASTLOAD_READ should only succeed with an input stream");
|
|
||||||
|
|
||||||
rv = ReadScriptFromStream(cx, mFastLoadInput, script);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
rv = flSvc->EndMuxedDocument(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
mozJSComponentLoader::WriteScript(nsIFastLoadService *flSvc, JSScript *script,
|
mozJSComponentLoader::WriteScript(StartupCache* cache, JSScript *script,
|
||||||
nsIFile *component, const char *nativePath,
|
nsIFile *component, nsIURI *uri, JSContext *cx)
|
||||||
nsIURI *uri, JSContext *cx)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(flSvc, "fastload not initialized");
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (!mFastLoadOutput) {
|
nsCAutoString spec;
|
||||||
// Trying to read a URI that was not in the fastload file will have
|
rv = uri->GetSpec(spec);
|
||||||
// created an output stream for us. But, if we haven't tried to
|
|
||||||
// load anything that was missing, it will still be null.
|
|
||||||
rv = flSvc->GetOutputStream(getter_AddRefs(mFastLoadOutput));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(mFastLoadOutput, "must have an output stream here");
|
|
||||||
|
|
||||||
LOG(("Writing %s to fastload\n", nativePath));
|
|
||||||
rv = flSvc->AddDependency(component);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = flSvc->StartMuxedDocument(uri, nativePath,
|
LOG(("Writing %s to startupcache\n", spec.get()));
|
||||||
nsIFastLoadService::NS_FASTLOAD_WRITE);
|
nsCOMPtr<nsIObjectOutputStream> oos;
|
||||||
|
nsCOMPtr<nsIStorageStream> storageStream;
|
||||||
|
rv = NS_NewObjectOutputWrappedStorageStream(getter_AddRefs(oos),
|
||||||
|
getter_AddRefs(storageStream));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> oldURI;
|
rv = WriteScriptToStream(cx, script, oos);
|
||||||
rv = flSvc->SelectMuxedDocument(uri, getter_AddRefs(oldURI));
|
oos->Close();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = WriteScriptToStream(cx, script, mFastLoadOutput);
|
nsAutoArrayPtr<char> buf;
|
||||||
|
PRUint32 len;
|
||||||
|
rv = NS_NewBufferFromStorageStream(storageStream, getter_Transfers(buf),
|
||||||
|
&len);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return flSvc->EndMuxedDocument(uri);
|
rv = cache->PutBuffer(spec.get(), buf, len);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
#endif //MOZ_ENABLE_LIBXUL
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||||
@ -1263,60 +1018,31 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Before compiling the script, first check to see if we have it in
|
|
||||||
// the fastload file. Note: as a rule, fastload errors are not fatal
|
|
||||||
// to loading the script, since we can always slow-load.
|
|
||||||
nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv);
|
|
||||||
|
|
||||||
// Save the old state and restore it upon return
|
|
||||||
FastLoadStateHolder flState(flSvc);
|
|
||||||
PRBool fastLoading = PR_FALSE;
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
rv = StartFastLoad(flSvc);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
fastLoading = PR_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JSScript *script = nsnull;
|
JSScript *script = nsnull;
|
||||||
|
|
||||||
if (fastLoading) {
|
#ifdef MOZ_ENABLE_LIBXUL
|
||||||
rv = ReadScript(flSvc, nativePath.get(), aURI, cx, &script);
|
// Before compiling the script, first check to see if we have it in
|
||||||
if (NS_SUCCEEDED(rv)) {
|
// the startupcache. Note: as a rule, startupcache errors are not fatal
|
||||||
LOG(("Successfully loaded %s from fastload\n", nativePath.get()));
|
// to loading the script, since we can always slow-load.
|
||||||
fastLoading = PR_FALSE; // no need to write out the script
|
|
||||||
} else if (rv == NS_ERROR_NOT_AVAILABLE) {
|
PRBool writeToCache = PR_FALSE;
|
||||||
// This is ok, it just means the script is not yet in the
|
StartupCache* cache = StartupCache::GetSingleton();
|
||||||
// fastload file.
|
|
||||||
rv = NS_OK;
|
|
||||||
} else {
|
|
||||||
LOG(("Failed to deserialize %s\n", nativePath.get()));
|
|
||||||
|
|
||||||
// Remove the fastload file, it may be corrupted.
|
if (cache) {
|
||||||
LOG(("Invalid fastload file detected, removing it\n"));
|
rv = ReadScript(cache, aURI, cx, &script);
|
||||||
nsCOMPtr<nsIObjectOutputStream> objectOutput;
|
if (NS_SUCCEEDED(rv)) {
|
||||||
flSvc->GetOutputStream(getter_AddRefs(objectOutput));
|
LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
|
||||||
if (objectOutput) {
|
} else {
|
||||||
flSvc->SetOutputStream(nsnull);
|
// This is ok, it just means the script is not yet in the
|
||||||
objectOutput->Close();
|
// cache. Could mean that the cache was corrupted and got removed,
|
||||||
}
|
// but either way we're going to write this out.
|
||||||
nsCOMPtr<nsIObjectInputStream> objectInput;
|
writeToCache = PR_TRUE;
|
||||||
flSvc->GetInputStream(getter_AddRefs(objectInput));
|
|
||||||
if (objectInput) {
|
|
||||||
flSvc->SetInputStream(nsnull);
|
|
||||||
objectInput->Close();
|
|
||||||
}
|
|
||||||
if (mFastLoadFile) {
|
|
||||||
mFastLoadFile->Remove(PR_FALSE);
|
|
||||||
}
|
|
||||||
fastLoading = PR_FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!script) {
|
||||||
if (!script || NS_FAILED(rv)) {
|
// The script wasn't in the cache , so compile it now.
|
||||||
// The script wasn't in the fastload cache, so compile it now.
|
|
||||||
LOG(("Slow loading %s\n", nativePath.get()));
|
LOG(("Slow loading %s\n", nativePath.get()));
|
||||||
|
|
||||||
// If |exception| is non-null, then our caller wants us to propagate
|
// If |exception| is non-null, then our caller wants us to propagate
|
||||||
@ -1475,21 +1201,20 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
|||||||
nativePath.get());
|
nativePath.get());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fastLoading) {
|
#ifdef MOZ_ENABLE_LIBXUL
|
||||||
// We successfully compiled the script, so cache it in fastload.
|
if (writeToCache) {
|
||||||
rv = WriteScript(flSvc, script, aComponentFile, nativePath.get(), aURI, cx);
|
// We successfully compiled the script, so cache it.
|
||||||
|
rv = WriteScript(cache, script, aComponentFile, aURI, cx);
|
||||||
|
|
||||||
// Don't treat failure to write as fatal, since we might be working
|
// Don't treat failure to write as fatal, since we might be working
|
||||||
// with a read-only fastload file.
|
// with a read-only cache.
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
LOG(("Successfully wrote to fastload\n"));
|
LOG(("Successfully wrote to cache\n"));
|
||||||
} else {
|
} else {
|
||||||
LOG(("Failed to write to fastload\n"));
|
LOG(("Failed to write to cache\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Restore the old state of the fastload service.
|
|
||||||
flState.pop();
|
|
||||||
|
|
||||||
// Assign aGlobal here so that it's available to recursive imports.
|
// Assign aGlobal here so that it's available to recursive imports.
|
||||||
// See bug 384168.
|
// See bug 384168.
|
||||||
@ -1819,14 +1544,7 @@ NS_IMETHODIMP
|
|||||||
mozJSComponentLoader::Observe(nsISupports *subject, const char *topic,
|
mozJSComponentLoader::Observe(nsISupports *subject, const char *topic,
|
||||||
const PRUnichar *data)
|
const PRUnichar *data)
|
||||||
{
|
{
|
||||||
if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
if (!strcmp(topic, "xpcom-shutdown-loaders")) {
|
||||||
if (mFastLoadTimer) {
|
|
||||||
mFastLoadTimer->Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseFastLoad();
|
|
||||||
}
|
|
||||||
else if (!strcmp(topic, "xpcom-shutdown-loaders")) {
|
|
||||||
UnloadModules();
|
UnloadModules();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -57,6 +57,12 @@
|
|||||||
#ifndef XPCONNECT_STANDALONE
|
#ifndef XPCONNECT_STANDALONE
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MOZ_ENABLE_LIBXUL
|
||||||
|
#include "mozilla/scache/StartupCache.h"
|
||||||
|
|
||||||
|
using namespace mozilla::scache;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "xpcIJSGetFactory.h"
|
#include "xpcIJSGetFactory.h"
|
||||||
|
|
||||||
/* 6bd13476-1dd2-11b2-bbef-f0ccb5fa64b6 (thanks, mozbot) */
|
/* 6bd13476-1dd2-11b2-bbef-f0ccb5fa64b6 (thanks, mozbot) */
|
||||||
@ -127,23 +133,16 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
|||||||
char **location,
|
char **location,
|
||||||
jsval *exception);
|
jsval *exception);
|
||||||
|
|
||||||
nsresult StartFastLoad(nsIFastLoadService *flSvc);
|
#ifdef MOZ_ENABLE_LIBXUL
|
||||||
nsresult ReadScript(nsIFastLoadService *flSvc, const char *nativePath,
|
nsresult ReadScript(StartupCache *cache, nsIURI *uri,
|
||||||
nsIURI *uri, JSContext *cx, JSScript **script);
|
JSContext *cx, JSScript **script);
|
||||||
nsresult WriteScript(nsIFastLoadService *flSvc, JSScript *script,
|
nsresult WriteScript(StartupCache *cache, JSScript *script,
|
||||||
nsIFile *component, const char *nativePath,
|
nsIFile *component, nsIURI *uri, JSContext *cx);
|
||||||
nsIURI *uri, JSContext *cx);
|
#endif
|
||||||
static void CloseFastLoad(nsITimer *timer, void *closure);
|
|
||||||
void CloseFastLoad();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIComponentManager> mCompMgr;
|
nsCOMPtr<nsIComponentManager> mCompMgr;
|
||||||
nsCOMPtr<nsIJSRuntimeService> mRuntimeService;
|
nsCOMPtr<nsIJSRuntimeService> mRuntimeService;
|
||||||
nsCOMPtr<nsIThreadJSContextStack> mContextStack;
|
nsCOMPtr<nsIThreadJSContextStack> mContextStack;
|
||||||
nsCOMPtr<nsIFile> mFastLoadFile;
|
|
||||||
nsRefPtr<nsXPCFastLoadIO> mFastLoadIO;
|
|
||||||
nsCOMPtr<nsIObjectInputStream> mFastLoadInput;
|
|
||||||
nsCOMPtr<nsIObjectOutputStream> mFastLoadOutput;
|
|
||||||
nsCOMPtr<nsITimer> mFastLoadTimer;
|
|
||||||
#ifndef XPCONNECT_STANDALONE
|
#ifndef XPCONNECT_STANDALONE
|
||||||
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
|
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user