Bug 1361900: Part 2 - Add process types field to cached script data. r=erahm

MozReview-Commit-ID: Gvh672XD0ar

--HG--
extra : rebase_source : 022d4a8d3116ae1817189d1f03c3180087997487
This commit is contained in:
Kris Maglione 2017-05-03 17:21:31 -07:00
Родитель 49ed37ac3d
Коммит 4b6d93f595
4 изменённых файлов: 88 добавлений и 2 удалений

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

@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/EnumSet.h"
#include "mozilla/Range.h"
#include "mozilla/Result.h"
#include "mozilla/Unused.h"
@ -55,6 +56,22 @@ public:
return buf;
}
void
codeUint8(const uint8_t& val)
{
*write(sizeof val) = val;
}
template<typename T>
void
codeUint8(const EnumSet<T>& val)
{
// EnumSets are always represented as uint32_t values, so we need to
// assert that the value actually fits in a uint8 before writing it.
uint32_t value = val.serialize();
codeUint8(CheckedUint8(value).value());
}
void
codeUint16(const uint16_t& val)
{
@ -105,6 +122,26 @@ public:
return buf;
}
bool
codeUint8(uint8_t& val)
{
if (checkCapacity(sizeof val)) {
val = *read(sizeof val);
}
return !error_;
}
template<typename T>
bool
codeUint8(EnumSet<T>& val)
{
uint8_t value;
if (codeUint8(value)) {
val.deserialize(value);
}
return !error_;
}
bool
codeUint16(uint16_t& val)
{

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

@ -13,6 +13,8 @@
#include "mozilla/Logging.h"
#include "mozilla/Services.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "MainThreadUtils.h"
@ -41,6 +43,9 @@ static LazyLogModule gLog("ScriptPreloader");
using mozilla::dom::AutoJSAPI;
using namespace mozilla::loader;
ProcessType ScriptPreloader::sProcessType;
nsresult
ScriptPreloader::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize)
@ -85,6 +90,15 @@ ScriptPreloader::GetSingleton()
}
ProcessType
ScriptPreloader::GetChildProcessType(const nsAString& remoteType)
{
if (remoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE)) {
return ProcessType::Extension;
}
return ProcessType::Web;
}
namespace {
struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI
@ -120,6 +134,12 @@ ScriptPreloader::ScriptPreloader()
: mMonitor("[ScriptPreloader.mMonitor]")
, mSaveMonitor("[ScriptPreloader.mSaveMonitor]")
{
if (XRE_IsParentProcess()) {
sProcessType = ProcessType::Parent;
} else {
sProcessType = GetChildProcessType(dom::ContentChild::GetSingleton()->GetRemoteType());
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
MOZ_RELEASE_ASSERT(obs);
obs->AddObserver(this, DELAYED_STARTUP_TOPIC, false);
@ -241,7 +261,7 @@ ScriptPreloader::GetCacheFile(const char* leafName)
return Move(cacheFile);
}
static const uint8_t MAGIC[] = "mozXDRcache";
static const uint8_t MAGIC[] = "mozXDRcachev001";
Result<Ok, nsresult>
ScriptPreloader::OpenCache()
@ -353,7 +373,8 @@ ScriptPreloader::InitCache()
JS::CompileOptions options(cx, JSVERSION_LATEST);
for (auto script : mRestoredScripts) {
if (script->mSize > MIN_OFFTHREAD_SIZE &&
if (script->mProcessTypes.contains(CurrentProcessType()) &&
script->mSize > MIN_OFFTHREAD_SIZE &&
JS::CanCompileOffThread(cx, options, script->mSize)) {
DecodeScriptOffThread(cx, script);
} else {
@ -443,6 +464,7 @@ ScriptPreloader::PrepareCacheWrite()
// - Its cache key.
// - The offset of its XDR data within the XDR data block.
// - The size of its XDR data in the XDR data block.
// - A bit field describing which process types the script is used in.
//
// - A block of XDR data for the encoded scripts, with each script's data at
// an offset from the start of the block, as specified above.
@ -564,10 +586,13 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
mSavedScripts.insertBack(restored);
MOZ_ASSERT(script);
restored->mProcesses += CurrentProcessType();
restored->mScript = script;
restored->mReadyToExecute = true;
} else if (!exists) {
auto cachedScript = new CachedScript(url, cachePath, script);
cachedScript->mProcesses += CurrentProcessType();
mSavedScripts.insertBack(cachedScript);
mScripts.Put(cachePath, cachedScript);
}

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

@ -6,6 +6,8 @@
#ifndef ScriptPreloader_h
#define ScriptPreloader_h
#include "mozilla/CheckedInt.h"
#include "mozilla/EnumSet.h"
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Maybe.h"
@ -27,6 +29,12 @@
namespace mozilla {
namespace loader {
class InputBuffer;
enum class ProcessType : uint8_t {
Parent,
Web,
Extension,
};
}
using namespace mozilla::loader;
@ -45,6 +53,8 @@ public:
static ScriptPreloader& GetSingleton();
static ProcessType GetChildProcessType(const nsAString& remoteType);
// Retrieves the script with the given cache key from the script cache.
// Returns null if the script is not cached.
JSScript* GetCachedScript(JSContext* cx, const nsCString& name);
@ -59,6 +69,11 @@ public:
void Trace(JSTracer* trc);
static ProcessType CurrentProcessType()
{
return sProcessType;
}
protected:
virtual ~ScriptPreloader() = default;
@ -126,6 +141,7 @@ private:
buffer.codeString(mCachePath);
buffer.codeUint32(mOffset);
buffer.codeUint32(mSize);
buffer.codeUint8(mProcessTypes);
}
// Returns the XDR data generated for this script during this session. See
@ -180,6 +196,9 @@ private:
// has not yet been finalized on the main thread.
void* mToken = nullptr;
// The set of processes in which this script has been used.
EnumSet<ProcessType> mProcessTypes{};
// The read-only XDR data for this script, which was either read from an
// existing cache file, or generated by encoding a script which was
// compiled during this session.
@ -277,6 +296,9 @@ private:
bool mSaveComplete = false;
bool mDataPrepared = false;
// The process type of the current process.
static ProcessType sProcessType;
nsCOMPtr<nsIFile> mProfD;
nsCOMPtr<nsIThread> mSaveThread;

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

@ -43,5 +43,7 @@ LOCAL_INCLUDES += [
'/dom/base',
]
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-shadow']