mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 06:22:20 +00:00
Backed out 14 changesets (bug 1693184, bug 1693611, bug 1693625) for causing failures on test_script_loader_js_cache.html.
Backed out changeset 6f384df0be5c (bug 1693184) Backed out changeset 5353d36c4846 (bug 1693625) Backed out changeset 0069d43ee2c4 (bug 1693611) Backed out changeset 8fd50eba1621 (bug 1693611) Backed out changeset 4928193b996f (bug 1693611) Backed out changeset 7bf683fab589 (bug 1693611) Backed out changeset a4ff4b030aaa (bug 1693611) Backed out changeset 565bee5296ac (bug 1693611) Backed out changeset faacbf1943b6 (bug 1693611) Backed out changeset 72fc08b6245d (bug 1693611) Backed out changeset 6f06ff0ebbc3 (bug 1693611) Backed out changeset fb2c167165b8 (bug 1693611) Backed out changeset 0d66ecd8acd4 (bug 1693611) Backed out changeset 0e435a571803 (bug 1693611)
This commit is contained in:
parent
942ec256fe
commit
81636eb525
@ -16,8 +16,9 @@
|
||||
#include "frontend/BytecodeCompiler.h" // IsIdentifier
|
||||
#include "frontend/CompilationStencil.h"
|
||||
#include "frontend/NameCollections.h"
|
||||
#include "util/StringBuffer.h" // StringBuffer
|
||||
#include "util/Text.h" // AsciiDigitToNumber
|
||||
#include "frontend/StencilXdr.h" // CanCopyDataToDisk
|
||||
#include "util/StringBuffer.h" // StringBuffer
|
||||
#include "util/Text.h" // AsciiDigitToNumber
|
||||
#include "util/Unicode.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/Printer.h" // Sprinter, QuoteString
|
||||
@ -973,6 +974,37 @@ bool WellKnownParserAtoms::init(JSContext* cx) {
|
||||
} /* namespace frontend */
|
||||
} /* namespace js */
|
||||
|
||||
// XDR code.
|
||||
namespace js {
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRParserAtom(XDRState<mode>* xdr, ParserAtom** atomp) {
|
||||
static_assert(CanCopyDataToDisk<ParserAtom>::value,
|
||||
"ParserAtom cannot be bulk-copied to disk.");
|
||||
|
||||
MOZ_TRY(xdr->align32());
|
||||
|
||||
const ParserAtom* header;
|
||||
if (mode == XDR_ENCODE) {
|
||||
header = *atomp;
|
||||
} else {
|
||||
MOZ_TRY(xdr->peekData(&header));
|
||||
}
|
||||
|
||||
const uint32_t CharSize =
|
||||
header->hasLatin1Chars() ? sizeof(JS::Latin1Char) : sizeof(char16_t);
|
||||
uint32_t totalLength = sizeof(ParserAtom) + (CharSize * header->length());
|
||||
|
||||
MOZ_TRY(xdr->borrowedData(atomp, totalLength));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template XDRResult XDRParserAtom(XDRState<XDR_ENCODE>* xdr, ParserAtom** atomp);
|
||||
template XDRResult XDRParserAtom(XDRState<XDR_DECODE>* xdr, ParserAtom** atomp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
bool JSRuntime::initializeParserAtoms(JSContext* cx) {
|
||||
MOZ_ASSERT(!commonParserNames);
|
||||
|
||||
|
@ -1387,7 +1387,7 @@ bool CompilationStencil::deserializeStencils(JSContext* cx,
|
||||
*succeededOut = false;
|
||||
}
|
||||
MOZ_ASSERT(parserAtomData.empty());
|
||||
XDRStencilDecoder decoder(cx, range);
|
||||
XDRStencilDecoder decoder(cx, &input.options, range);
|
||||
|
||||
XDRResult res = decoder.codeStencil(input, *this);
|
||||
if (res.isErr()) {
|
||||
@ -3502,7 +3502,7 @@ JS::TranscodeResult JS::DecodeStencil(JSContext* cx,
|
||||
if (!stencil) {
|
||||
return TranscodeResult::Throw;
|
||||
}
|
||||
XDRStencilDecoder decoder(cx, range);
|
||||
XDRStencilDecoder decoder(cx, &options, range);
|
||||
XDRResult res = decoder.codeStencil(input.get(), *stencil);
|
||||
if (res.isErr()) {
|
||||
return res.unwrapErr();
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <type_traits> // std::has_unique_object_representations
|
||||
#include <utility> // std::forward
|
||||
|
||||
#include "ds/LifoAlloc.h" // LifoAlloc
|
||||
#include "frontend/CompilationStencil.h" // CompilationStencil
|
||||
#include "frontend/ScriptIndex.h" // ScriptIndex
|
||||
#include "vm/JSScript.h" // js::CheckCompileOptionsMatch
|
||||
@ -99,14 +98,14 @@ static XDRResult XDRVectorContent(XDRState<mode>* xdr, Vector<T, N, AP>& vec) {
|
||||
}
|
||||
|
||||
template <XDRMode mode, typename T>
|
||||
static XDRResult XDRSpanInitialized(XDRState<mode>* xdr, LifoAlloc& alloc,
|
||||
mozilla::Span<T>& span, uint32_t size) {
|
||||
static XDRResult XDRSpanInitialized(XDRState<mode>* xdr, mozilla::Span<T>& span,
|
||||
uint32_t size) {
|
||||
MOZ_ASSERT_IF(mode == XDR_ENCODE, size == span.size());
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
MOZ_ASSERT(span.empty());
|
||||
if (size > 0) {
|
||||
auto* p = alloc.template newArrayUninitialized<T>(size);
|
||||
auto* p = xdr->stencilAlloc().template newArrayUninitialized<T>(size);
|
||||
if (!p) {
|
||||
js::ReportOutOfMemory(xdr->cx());
|
||||
return xdr->fail(JS::TranscodeResult::Throw);
|
||||
@ -159,34 +158,28 @@ static XDRResult XDRSpanContent(XDRState<mode>* xdr, mozilla::Span<T>& span) {
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeBigInt(XDRState<mode>* xdr,
|
||||
BigIntStencil& stencil) {
|
||||
uint32_t size;
|
||||
static XDRResult XDRStencilModuleMetadata(XDRState<mode>* xdr,
|
||||
StencilModuleMetadata& stencil) {
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.requestedModules));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.importEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.localExportEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.indirectExportEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.starExportEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.functionDecls));
|
||||
|
||||
uint8_t isAsync = 0;
|
||||
if (mode == XDR_ENCODE) {
|
||||
size = stencil.source_.size();
|
||||
if (stencil.isAsync) {
|
||||
isAsync = stencil.isAsync ? 1 : 0;
|
||||
}
|
||||
}
|
||||
MOZ_TRY(xdr->codeUint32(&size));
|
||||
|
||||
return XDRSpanContent(xdr, stencil.source_, size);
|
||||
}
|
||||
MOZ_TRY(xdr->codeUint8(&isAsync));
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeObjLiteral(XDRState<mode>* xdr,
|
||||
ObjLiteralStencil& stencil) {
|
||||
uint8_t flags = 0;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
flags = stencil.flags_.serialize();
|
||||
}
|
||||
MOZ_TRY(xdr->codeUint8(&flags));
|
||||
if (mode == XDR_DECODE) {
|
||||
stencil.flags_.deserialize(flags);
|
||||
stencil.isAsync = isAsync == 1;
|
||||
}
|
||||
|
||||
MOZ_TRY(xdr->codeUint32(&stencil.propertyCount_));
|
||||
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.code_));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
@ -200,7 +193,7 @@ template <typename ScopeT>
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeScopeData(
|
||||
/* static */ XDRResult StencilXDR::ScopeData(
|
||||
XDRState<mode>* xdr, ScopeStencil& stencil,
|
||||
BaseParserScopeData*& baseScopeData) {
|
||||
// WasmInstanceScope & WasmFunctionScope should not appear in stencils.
|
||||
@ -238,10 +231,42 @@ template <XDRMode mode>
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::ObjLiteral(XDRState<mode>* xdr,
|
||||
ObjLiteralStencil& stencil) {
|
||||
uint8_t flags = 0;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
flags = stencil.flags_.serialize();
|
||||
}
|
||||
MOZ_TRY(xdr->codeUint8(&flags));
|
||||
if (mode == XDR_DECODE) {
|
||||
stencil.flags_.deserialize(flags);
|
||||
}
|
||||
|
||||
MOZ_TRY(xdr->codeUint32(&stencil.propertyCount_));
|
||||
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.code_));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::BigInt(XDRState<mode>* xdr,
|
||||
BigIntStencil& stencil) {
|
||||
uint32_t size;
|
||||
if (mode == XDR_ENCODE) {
|
||||
size = stencil.source_.size();
|
||||
}
|
||||
MOZ_TRY(xdr->codeUint32(&size));
|
||||
|
||||
return XDRSpanContent(xdr, stencil.source_, size);
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */
|
||||
XDRResult StencilXDR::codeSharedData(XDRState<mode>* xdr,
|
||||
RefPtr<SharedImmutableScriptData>& sisd) {
|
||||
XDRResult StencilXDR::SharedData(XDRState<mode>* xdr,
|
||||
RefPtr<SharedImmutableScriptData>& sisd) {
|
||||
if (mode == XDR_ENCODE) {
|
||||
MOZ_TRY(XDRImmutableScriptData<mode>(xdr, sisd->isd_));
|
||||
} else {
|
||||
@ -258,18 +283,26 @@ XDRResult StencilXDR::codeSharedData(XDRState<mode>* xdr,
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// Called from js::XDRScript.
|
||||
template /* static */ XDRResult StencilXDR::codeSharedData(
|
||||
XDRState<XDR_ENCODE>* xdr, RefPtr<SharedImmutableScriptData>& sisd);
|
||||
template /* static */ XDRResult StencilXDR::codeSharedData(
|
||||
XDRState<XDR_DECODE>* xdr, RefPtr<SharedImmutableScriptData>& sisd);
|
||||
template
|
||||
/* static */
|
||||
XDRResult
|
||||
StencilXDR::SharedData(XDRState<XDR_ENCODE>* xdr,
|
||||
RefPtr<SharedImmutableScriptData>& sisd);
|
||||
|
||||
template
|
||||
/* static */
|
||||
XDRResult
|
||||
StencilXDR::SharedData(XDRState<XDR_DECODE>* xdr,
|
||||
RefPtr<SharedImmutableScriptData>& sisd);
|
||||
|
||||
namespace js {
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeSharedDataContainer(
|
||||
XDRState<mode>* xdr, SharedDataContainer& sharedData) {
|
||||
XDRResult XDRSharedDataContainer(XDRState<mode>* xdr,
|
||||
SharedDataContainer& sharedData) {
|
||||
if (mode == XDR_ENCODE) {
|
||||
if (sharedData.isBorrow()) {
|
||||
return codeSharedDataContainer(xdr, *sharedData.asBorrow());
|
||||
return XDRSharedDataContainer(xdr, *sharedData.asBorrow());
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,7 +331,7 @@ template <XDRMode mode>
|
||||
if (mode == XDR_ENCODE) {
|
||||
ref = sharedData.asSingle();
|
||||
}
|
||||
MOZ_TRY(codeSharedData<mode>(xdr, ref));
|
||||
MOZ_TRY(StencilXDR::SharedData<mode>(xdr, ref));
|
||||
if (mode == XDR_DECODE) {
|
||||
sharedData.setSingle(ref.forget());
|
||||
}
|
||||
@ -324,7 +357,7 @@ template <XDRMode mode>
|
||||
MOZ_TRY(xdr->codeUint8(&exists));
|
||||
|
||||
if (exists) {
|
||||
MOZ_TRY(codeSharedData<mode>(xdr, entry));
|
||||
MOZ_TRY(StencilXDR::SharedData<mode>(xdr, entry));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -354,7 +387,7 @@ template <XDRMode mode>
|
||||
uint32_t index = iter.get().key().index;
|
||||
auto& data = iter.get().value();
|
||||
MOZ_TRY(xdr->codeUint32(&index));
|
||||
MOZ_TRY(codeSharedData<mode>(xdr, data));
|
||||
MOZ_TRY(StencilXDR::SharedData<mode>(xdr, data));
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
@ -362,7 +395,7 @@ template <XDRMode mode>
|
||||
MOZ_TRY(xdr->codeUint32(&index.index));
|
||||
|
||||
RefPtr<SharedImmutableScriptData> data;
|
||||
MOZ_TRY(codeSharedData<mode>(xdr, data));
|
||||
MOZ_TRY(StencilXDR::SharedData<mode>(xdr, data));
|
||||
|
||||
if (!map.putNew(index, data)) {
|
||||
js::ReportOutOfMemory(xdr->cx());
|
||||
@ -378,120 +411,6 @@ template <XDRMode mode>
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeParserAtom(XDRState<mode>* xdr,
|
||||
ParserAtom** atomp) {
|
||||
static_assert(CanCopyDataToDisk<ParserAtom>::value,
|
||||
"ParserAtom cannot be bulk-copied to disk.");
|
||||
|
||||
MOZ_TRY(xdr->align32());
|
||||
|
||||
const ParserAtom* header;
|
||||
if (mode == XDR_ENCODE) {
|
||||
header = *atomp;
|
||||
} else {
|
||||
MOZ_TRY(xdr->peekData(&header));
|
||||
}
|
||||
|
||||
const uint32_t CharSize =
|
||||
header->hasLatin1Chars() ? sizeof(JS::Latin1Char) : sizeof(char16_t);
|
||||
uint32_t totalLength = sizeof(ParserAtom) + (CharSize * header->length());
|
||||
|
||||
MOZ_TRY(xdr->borrowedData(atomp, totalLength));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult XDRAtomCount(XDRState<mode>* xdr, uint32_t* atomCount) {
|
||||
return xdr->codeUint32(atomCount);
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeParserAtomSpan(
|
||||
XDRState<mode>* xdr, LifoAlloc& alloc, ParserAtomSpan& parserAtomData) {
|
||||
if (mode == XDR_ENCODE) {
|
||||
uint32_t atomVectorLength = parserAtomData.size();
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomVectorLength));
|
||||
|
||||
uint32_t atomCount = 0;
|
||||
for (const auto& entry : parserAtomData) {
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
if (entry->isUsedByStencil()) {
|
||||
atomCount++;
|
||||
}
|
||||
}
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
||||
|
||||
for (uint32_t i = 0; i < atomVectorLength; i++) {
|
||||
auto& entry = parserAtomData[i];
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
if (entry->isUsedByStencil()) {
|
||||
MOZ_TRY(xdr->codeUint32(&i));
|
||||
MOZ_TRY(codeParserAtom(xdr, &entry));
|
||||
}
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
uint32_t atomVectorLength;
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomVectorLength));
|
||||
|
||||
frontend::ParserAtomSpanBuilder builder(xdr->cx()->runtime(), parserAtomData);
|
||||
if (!builder.allocate(xdr->cx(), alloc, atomVectorLength)) {
|
||||
return xdr->fail(JS::TranscodeResult::Throw);
|
||||
}
|
||||
|
||||
uint32_t atomCount;
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
||||
|
||||
for (uint32_t i = 0; i < atomCount; i++) {
|
||||
frontend::ParserAtom* entry = nullptr;
|
||||
uint32_t index;
|
||||
MOZ_TRY(xdr->codeUint32(&index));
|
||||
MOZ_TRY(codeParserAtom(xdr, &entry));
|
||||
if (mode == XDR_DECODE) {
|
||||
if (index >= atomVectorLength) {
|
||||
return xdr->fail(JS::TranscodeResult::Failure_BadDecode);
|
||||
}
|
||||
}
|
||||
builder.set(frontend::ParserAtomIndex(index), entry);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeModuleMetadata(
|
||||
XDRState<mode>* xdr, StencilModuleMetadata& stencil) {
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.requestedModules));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.importEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.localExportEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.indirectExportEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.starExportEntries));
|
||||
MOZ_TRY(XDRVectorContent(xdr, stencil.functionDecls));
|
||||
|
||||
uint8_t isAsync = 0;
|
||||
if (mode == XDR_ENCODE) {
|
||||
if (stencil.isAsync) {
|
||||
isAsync = stencil.isAsync ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_TRY(xdr->codeUint8(&isAsync));
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
stencil.isAsync = isAsync == 1;
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRCompilationStencilSpanSize(
|
||||
XDRState<mode>* xdr, uint32_t* scriptSize, uint32_t* gcThingSize,
|
||||
@ -573,45 +492,15 @@ XDRResult XDRCompilationStencilSpanSize(
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// Marker between each section inside CompilationStencil.
|
||||
//
|
||||
// These values should meet the following requirement:
|
||||
// * No same value (differ more than single bit flip)
|
||||
// * Bit pattern that won't frequently appear inside other XDR data
|
||||
//
|
||||
// Currently they're randomly chosen prime numbers that doesn't have same
|
||||
// byte pattern.
|
||||
enum class SectionMarker : uint32_t {
|
||||
ParserAtomData = 0xD9C098D3,
|
||||
ScopeData = 0x892C25EF,
|
||||
ScopeNames = 0x638C4FB3,
|
||||
RegExpData = 0xB030C2AF,
|
||||
BigIntData = 0x4B24F449,
|
||||
ObjLiteralData = 0x9AFAAE45,
|
||||
SharedData = 0xAAD52687,
|
||||
GCThingData = 0x1BD8F533,
|
||||
ScriptData = 0x840458FF,
|
||||
ScriptExtra = 0xA90E489D,
|
||||
ModuleMetadata = 0x94FDCE6D,
|
||||
};
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult CodeMarker(XDRState<mode>* xdr, SectionMarker marker) {
|
||||
return xdr->codeMarker(uint32_t(marker));
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
/* static */ XDRResult StencilXDR::codeCompilationStencil(
|
||||
XDRState<mode>* xdr, CompilationStencil& stencil) {
|
||||
XDRResult XDRCompilationStencil(XDRState<mode>* xdr,
|
||||
CompilationStencil& stencil) {
|
||||
MOZ_ASSERT(!stencil.asmJS);
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
stencil.hasExternalDependency = true;
|
||||
}
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ParserAtomData));
|
||||
MOZ_TRY(codeParserAtomSpan(xdr, stencil.alloc, stencil.parserAtomData));
|
||||
|
||||
MOZ_TRY(xdr->codeUint32(&stencil.functionKey));
|
||||
|
||||
uint32_t scriptSize, gcThingSize, scopeSize, scriptExtraSize;
|
||||
@ -635,45 +524,33 @@ template <XDRMode mode>
|
||||
// All of the vector-indexed data elements referenced by the
|
||||
// main script tree must be materialized first.
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ScopeData));
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.scopeData, scopeSize));
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ScopeNames));
|
||||
MOZ_TRY(
|
||||
XDRSpanInitialized(xdr, stencil.alloc, stencil.scopeNames, scopeSize));
|
||||
MOZ_TRY(XDRSpanInitialized(xdr, stencil.scopeNames, scopeSize));
|
||||
MOZ_ASSERT(stencil.scopeData.size() == stencil.scopeNames.size());
|
||||
for (uint32_t i = 0; i < scopeSize; i++) {
|
||||
MOZ_TRY(codeScopeData(xdr, stencil.scopeData[i], stencil.scopeNames[i]));
|
||||
MOZ_TRY(StencilXDR::ScopeData(xdr, stencil.scopeData[i],
|
||||
stencil.scopeNames[i]));
|
||||
}
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::RegExpData));
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.regExpData, regExpSize));
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::BigIntData));
|
||||
MOZ_TRY(
|
||||
XDRSpanInitialized(xdr, stencil.alloc, stencil.bigIntData, bigIntSize));
|
||||
MOZ_TRY(XDRSpanInitialized(xdr, stencil.bigIntData, bigIntSize));
|
||||
for (auto& entry : stencil.bigIntData) {
|
||||
MOZ_TRY(codeBigInt(xdr, entry));
|
||||
MOZ_TRY(StencilXDR::BigInt(xdr, entry));
|
||||
}
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ObjLiteralData));
|
||||
MOZ_TRY(XDRSpanInitialized(xdr, stencil.alloc, stencil.objLiteralData,
|
||||
objLiteralSize));
|
||||
MOZ_TRY(XDRSpanInitialized(xdr, stencil.objLiteralData, objLiteralSize));
|
||||
for (auto& entry : stencil.objLiteralData) {
|
||||
MOZ_TRY(codeObjLiteral(xdr, entry));
|
||||
MOZ_TRY(StencilXDR::ObjLiteral(xdr, entry));
|
||||
}
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::SharedData));
|
||||
MOZ_TRY(codeSharedDataContainer(xdr, stencil.sharedData));
|
||||
MOZ_TRY(XDRSharedDataContainer(xdr, stencil.sharedData));
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::GCThingData));
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.gcThingData, gcThingSize));
|
||||
|
||||
// Now serialize the vector of ScriptStencils.
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ScriptData));
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.scriptData, scriptSize));
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ScriptExtra));
|
||||
MOZ_TRY(XDRSpanContent(xdr, stencil.scriptExtra, scriptExtraSize));
|
||||
|
||||
// We don't support coding non-initial CompilationStencil.
|
||||
@ -688,33 +565,42 @@ template <XDRMode mode>
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_TRY(CodeMarker(xdr, SectionMarker::ModuleMetadata));
|
||||
MOZ_TRY(codeModuleMetadata(xdr, *stencil.moduleMetadata));
|
||||
MOZ_TRY(XDRStencilModuleMetadata(xdr, *stencil.moduleMetadata));
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template /* static */ XDRResult StencilXDR::codeCompilationStencil(
|
||||
XDRState<XDR_ENCODE>* xdr, CompilationStencil& stencil);
|
||||
template XDRResult XDRCompilationStencil(XDRState<XDR_ENCODE>* xdr,
|
||||
CompilationStencil& stencil);
|
||||
|
||||
template /* static */ XDRResult StencilXDR::codeCompilationStencil(
|
||||
XDRState<XDR_DECODE>* xdr, CompilationStencil& stencil);
|
||||
template XDRResult XDRCompilationStencil(XDRState<XDR_DECODE>* xdr,
|
||||
CompilationStencil& stencil);
|
||||
|
||||
/* static */ XDRResult StencilXDR::checkCompilationStencil(
|
||||
XDRStencilEncoder* encoder, const CompilationStencil& stencil) {
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRCheckCompilationStencil(XDRState<mode>* xdr,
|
||||
CompilationStencil& stencil) {
|
||||
if (stencil.asmJS) {
|
||||
return encoder->fail(JS::TranscodeResult::Failure_AsmJSNotSupported);
|
||||
return xdr->fail(JS::TranscodeResult::Failure_AsmJSNotSupported);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/* static */ XDRResult StencilXDR::checkCompilationStencil(
|
||||
const ExtensibleCompilationStencil& stencil) {
|
||||
template XDRResult XDRCheckCompilationStencil(XDRState<XDR_ENCODE>* xdr,
|
||||
CompilationStencil& stencil);
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRCheckCompilationStencil(XDRState<mode>* xdr,
|
||||
ExtensibleCompilationStencil& stencil) {
|
||||
if (stencil.asmJS) {
|
||||
return mozilla::Err(JS::TranscodeResult::Failure_AsmJSNotSupported);
|
||||
return xdr->fail(JS::TranscodeResult::Failure_AsmJSNotSupported);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template XDRResult XDRCheckCompilationStencil(
|
||||
XDRState<XDR_ENCODE>* xdr, ExtensibleCompilationStencil& stencil);
|
||||
|
||||
} // namespace js
|
||||
|
@ -7,19 +7,12 @@
|
||||
#ifndef frontend_StencilXdr_h
|
||||
#define frontend_StencilXdr_h
|
||||
|
||||
#include "mozilla/RefPtr.h" // RefPtr
|
||||
|
||||
#include "frontend/CompilationStencil.h" // SharedDataContainer
|
||||
#include "frontend/ObjLiteral.h" // ObjLiteralStencil
|
||||
#include "frontend/ParserAtom.h" // ParserAtom, ParserAtomSpan
|
||||
#include "frontend/Stencil.h" // BitIntStencil, ScopeStencil, BaseParserScopeData
|
||||
#include "vm/SharedStencil.h" // SharedImmutableScriptData
|
||||
#include "vm/Xdr.h" // XDRMode, XDRResult, XDRState
|
||||
#include "frontend/ObjLiteral.h" // ObjLiteralStencil
|
||||
#include "frontend/Stencil.h" // *Stencil
|
||||
#include "vm/Scope.h" // Scope, ScopeKindString
|
||||
#include "vm/Xdr.h" // XDRMode, XDRResult, XDREncoder
|
||||
|
||||
namespace js {
|
||||
|
||||
class LifoAlloc;
|
||||
|
||||
namespace frontend {
|
||||
|
||||
// Check that we can copy data to disk and restore it in another instance of
|
||||
@ -48,44 +41,18 @@ struct CanCopyDataToDisk {
|
||||
class StencilXDR {
|
||||
public:
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeBigInt(XDRState<mode>* xdr, BigIntStencil& stencil);
|
||||
static XDRResult ScopeData(XDRState<mode>* xdr, ScopeStencil& stencil,
|
||||
BaseParserScopeData*& baseScopeData);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeObjLiteral(XDRState<mode>* xdr,
|
||||
ObjLiteralStencil& stencil);
|
||||
static XDRResult ObjLiteral(XDRState<mode>* xdr, ObjLiteralStencil& stencil);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeScopeData(XDRState<mode>* xdr, ScopeStencil& stencil,
|
||||
BaseParserScopeData*& baseScopeData);
|
||||
static XDRResult BigInt(XDRState<mode>* xdr, BigIntStencil& stencil);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeSharedData(XDRState<mode>* xdr,
|
||||
RefPtr<SharedImmutableScriptData>& sisd);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeSharedDataContainer(XDRState<mode>* xdr,
|
||||
SharedDataContainer& sharedData);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeParserAtom(XDRState<mode>* xdr, ParserAtom** atomp);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeParserAtomSpan(XDRState<mode>* xdr, LifoAlloc& alloc,
|
||||
ParserAtomSpan& parserAtomData);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeModuleMetadata(XDRState<mode>* xdr,
|
||||
StencilModuleMetadata& stencil);
|
||||
|
||||
static XDRResult checkCompilationStencil(XDRStencilEncoder* encoder,
|
||||
const CompilationStencil& stencil);
|
||||
|
||||
static XDRResult checkCompilationStencil(
|
||||
const ExtensibleCompilationStencil& stencil);
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult codeCompilationStencil(XDRState<mode>* xdr,
|
||||
CompilationStencil& stencil);
|
||||
static XDRResult SharedData(js::XDRState<mode>* xdr,
|
||||
RefPtr<SharedImmutableScriptData>& sisd);
|
||||
};
|
||||
|
||||
} /* namespace frontend */
|
||||
|
@ -5726,7 +5726,7 @@ static JS::TranscodeResult DecodeStencil(JSContext* cx,
|
||||
frontend::CompilationInput& input,
|
||||
frontend::CompilationStencil& stencil,
|
||||
size_t cursorIndex) {
|
||||
XDRStencilDecoder decoder(cx, buffer, cursorIndex);
|
||||
XDRStencilDecoder decoder(cx, &input.options, buffer, cursorIndex);
|
||||
|
||||
if (!input.initForGlobal(cx)) {
|
||||
return JS::TranscodeResult::Throw;
|
||||
|
@ -820,7 +820,7 @@ void ScriptDecodeTask::parse(JSContext* cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
XDRStencilDecoder decoder(cx, range);
|
||||
XDRStencilDecoder decoder(cx, &options, range);
|
||||
XDRResult res = decoder.codeStencil(*stencilInput_, *stencil_);
|
||||
if (!res.isOk()) {
|
||||
stencil_.reset();
|
||||
|
@ -1206,7 +1206,7 @@ XDRResult js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
|
||||
// NOTE: The script data is rooted by the script.
|
||||
MOZ_TRY(PrivateScriptData::XDR<mode>(xdr, script, sourceObject,
|
||||
scriptEnclosingScope, funOrMod));
|
||||
MOZ_TRY(frontend::StencilXDR::codeSharedData<mode>(xdr, script->sharedData_));
|
||||
MOZ_TRY(frontend::StencilXDR::SharedData<mode>(xdr, script->sharedData_));
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
if (!SharedImmutableScriptData::shareScriptData(cx, script->sharedData_)) {
|
||||
@ -2699,7 +2699,7 @@ bool ScriptSource::startIncrementalEncoding(
|
||||
// Remove the reference to the source, to avoid the circular reference.
|
||||
initial->source = nullptr;
|
||||
|
||||
xdrEncoder_ = js::MakeUnique<XDRIncrementalStencilEncoder>();
|
||||
xdrEncoder_ = js::MakeUnique<XDRIncrementalStencilEncoder>(cx);
|
||||
if (!xdrEncoder_) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
@ -2710,7 +2710,7 @@ bool ScriptSource::startIncrementalEncoding(
|
||||
mozilla::MakeScopeExit([&] { xdrEncoder_.reset(nullptr); });
|
||||
|
||||
XDRResult res = xdrEncoder_->setInitial(
|
||||
cx, options,
|
||||
options,
|
||||
std::forward<UniquePtr<frontend::ExtensibleCompilationStencil>>(initial));
|
||||
if (res.isErr()) {
|
||||
// On encoding failure, let failureCase destroy encoder and return true
|
||||
@ -2729,7 +2729,7 @@ bool ScriptSource::addDelazificationToIncrementalEncoding(
|
||||
auto failureCase =
|
||||
mozilla::MakeScopeExit([&] { xdrEncoder_.reset(nullptr); });
|
||||
|
||||
XDRResult res = xdrEncoder_->addDelazification(cx, stencil);
|
||||
XDRResult res = xdrEncoder_->addDelazification(stencil);
|
||||
if (res.isErr()) {
|
||||
// On encoding failure, let failureCase destroy encoder and return true
|
||||
// to avoid failing any currently executing script.
|
||||
@ -2749,7 +2749,7 @@ bool ScriptSource::xdrFinalizeEncoder(JSContext* cx,
|
||||
|
||||
auto cleanup = mozilla::MakeScopeExit([&] { xdrEncoder_.reset(nullptr); });
|
||||
|
||||
XDRResult res = xdrEncoder_->linearize(cx, buffer, this);
|
||||
XDRResult res = xdrEncoder_->linearize(buffer, this);
|
||||
if (res.isErr()) {
|
||||
if (JS::IsTranscodeFailureResult(res.unwrapErr())) {
|
||||
JS_ReportErrorASCII(cx, "XDR encoding failure");
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "builtin/ModuleObject.h"
|
||||
#include "debugger/DebugAPI.h"
|
||||
#include "frontend/CompilationStencil.h" // frontend::{CompilationStencil, ExtensibleCompilationStencil, CompilationStencilMerger, BorrowingCompilationStencil}
|
||||
#include "frontend/StencilXdr.h" // frontend::StencilXDR
|
||||
#include "frontend/ParserAtom.h" // frontend::ParserAtom
|
||||
#include "js/BuildId.h" // JS::BuildIdCharVector
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSScript.h"
|
||||
@ -284,6 +284,67 @@ XDRResult XDRState<mode>::codeModuleObject(MutableHandleModuleObject modp) {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult XDRAtomCount(XDRState<mode>* xdr, uint32_t* atomCount) {
|
||||
return xdr->codeUint32(atomCount);
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
static XDRResult XDRParserAtomTable(XDRState<mode>* xdr,
|
||||
frontend::CompilationStencil& stencil) {
|
||||
if (mode == XDR_ENCODE) {
|
||||
uint32_t atomVectorLength = stencil.parserAtomData.size();
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomVectorLength));
|
||||
|
||||
uint32_t atomCount = 0;
|
||||
for (const auto& entry : stencil.parserAtomData) {
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
if (entry->isUsedByStencil()) {
|
||||
atomCount++;
|
||||
}
|
||||
}
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
||||
|
||||
for (uint32_t i = 0; i < atomVectorLength; i++) {
|
||||
auto& entry = stencil.parserAtomData[i];
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
if (entry->isUsedByStencil()) {
|
||||
MOZ_TRY(xdr->codeUint32(&i));
|
||||
MOZ_TRY(XDRParserAtom(xdr, &entry));
|
||||
}
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
uint32_t atomVectorLength;
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomVectorLength));
|
||||
|
||||
if (!xdr->frontendAtoms().allocate(xdr->cx(), xdr->stencilAlloc(),
|
||||
atomVectorLength)) {
|
||||
return xdr->fail(JS::TranscodeResult::Throw);
|
||||
}
|
||||
|
||||
uint32_t atomCount;
|
||||
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
||||
MOZ_ASSERT(!xdr->hasAtomTable());
|
||||
|
||||
for (uint32_t i = 0; i < atomCount; i++) {
|
||||
frontend::ParserAtom* entry = nullptr;
|
||||
uint32_t index;
|
||||
MOZ_TRY(xdr->codeUint32(&index));
|
||||
MOZ_TRY(XDRParserAtom(xdr, &entry));
|
||||
xdr->frontendAtoms().set(frontend::ParserAtomIndex(index), entry);
|
||||
}
|
||||
xdr->finishAtomTable();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRState<mode>::codeScript(MutableHandleScript scriptp) {
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx());
|
||||
@ -319,6 +380,7 @@ static XDRResult XDRStencilHeader(
|
||||
|
||||
MOZ_TRY(VersionCheck(xdr, XDRFormatType::Stencil));
|
||||
MOZ_TRY(ScriptSource::XDR(xdr, maybeOptions, source));
|
||||
MOZ_TRY(xdr->align32());
|
||||
|
||||
return Ok();
|
||||
}
|
||||
@ -336,42 +398,25 @@ static bool IsOptionCompatibleWithEncoding(
|
||||
}
|
||||
|
||||
XDRResult XDRStencilEncoder::codeStencil(
|
||||
const JS::ReadOnlyCompileOptions* options,
|
||||
const RefPtr<ScriptSource>& source,
|
||||
const frontend::CompilationStencil& stencil) {
|
||||
frontend::CompilationInput& input, frontend::CompilationStencil& stencil) {
|
||||
#ifdef DEBUG
|
||||
auto sanityCheck = mozilla::MakeScopeExit(
|
||||
[&] { MOZ_ASSERT(validateResultCode(cx(), resultCode())); });
|
||||
#endif
|
||||
|
||||
if (options) {
|
||||
if (!IsOptionCompatibleWithEncoding(*options)) {
|
||||
return fail(JS::TranscodeResult::Failure);
|
||||
}
|
||||
if (!IsOptionCompatibleWithEncoding(input.options)) {
|
||||
return fail(JS::TranscodeResult::Failure);
|
||||
}
|
||||
|
||||
MOZ_TRY(frontend::StencilXDR::checkCompilationStencil(this, stencil));
|
||||
MOZ_TRY(XDRCheckCompilationStencil(this, stencil));
|
||||
|
||||
MOZ_TRY(XDRStencilHeader(this, options,
|
||||
const_cast<RefPtr<ScriptSource>&>(source)));
|
||||
MOZ_TRY(frontend::StencilXDR::codeCompilationStencil(
|
||||
this, const_cast<frontend::CompilationStencil&>(stencil)));
|
||||
MOZ_TRY(XDRStencilHeader(this, &input.options, stencil.source));
|
||||
MOZ_TRY(XDRParserAtomTable(this, stencil));
|
||||
MOZ_TRY(XDRCompilationStencil(this, stencil));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
XDRResult XDRStencilEncoder::codeStencil(
|
||||
const frontend::CompilationInput& input,
|
||||
const frontend::CompilationStencil& stencil) {
|
||||
return codeStencil(&input.options, stencil.source, stencil);
|
||||
}
|
||||
|
||||
XDRResult XDRStencilEncoder::codeStencil(
|
||||
const RefPtr<ScriptSource>& source,
|
||||
const frontend::CompilationStencil& stencil) {
|
||||
return codeStencil(nullptr, source, stencil);
|
||||
}
|
||||
|
||||
XDRIncrementalStencilEncoder::~XDRIncrementalStencilEncoder() {
|
||||
if (merger_) {
|
||||
js_delete(merger_);
|
||||
@ -379,48 +424,77 @@ XDRIncrementalStencilEncoder::~XDRIncrementalStencilEncoder() {
|
||||
}
|
||||
|
||||
XDRResult XDRIncrementalStencilEncoder::setInitial(
|
||||
JSContext* cx, const JS::ReadOnlyCompileOptions& options,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
UniquePtr<frontend::ExtensibleCompilationStencil>&& initial) {
|
||||
#ifdef DEBUG
|
||||
auto sanityCheck = mozilla::MakeScopeExit(
|
||||
[&] { MOZ_ASSERT(validateResultCode(cx(), resultCode())); });
|
||||
#endif
|
||||
|
||||
if (!IsOptionCompatibleWithEncoding(options)) {
|
||||
return mozilla::Err(JS::TranscodeResult::Failure);
|
||||
return fail(JS::TranscodeResult::Failure);
|
||||
}
|
||||
|
||||
MOZ_TRY(frontend::StencilXDR::checkCompilationStencil(*initial));
|
||||
MOZ_TRY(XDRCheckCompilationStencil(this, *initial));
|
||||
|
||||
merger_ = cx->new_<frontend::CompilationStencilMerger>();
|
||||
merger_ = cx()->new_<frontend::CompilationStencilMerger>();
|
||||
if (!merger_) {
|
||||
return mozilla::Err(JS::TranscodeResult::Throw);
|
||||
return fail(JS::TranscodeResult::Throw);
|
||||
}
|
||||
|
||||
if (!merger_->setInitial(
|
||||
cx, std::forward<UniquePtr<frontend::ExtensibleCompilationStencil>>(
|
||||
initial))) {
|
||||
return mozilla::Err(JS::TranscodeResult::Throw);
|
||||
cx(), std::forward<UniquePtr<frontend::ExtensibleCompilationStencil>>(
|
||||
initial))) {
|
||||
return fail(JS::TranscodeResult::Throw);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
XDRResult XDRIncrementalStencilEncoder::addDelazification(
|
||||
JSContext* cx, const frontend::CompilationStencil& delazification) {
|
||||
if (!merger_->addDelazification(cx, delazification)) {
|
||||
return mozilla::Err(JS::TranscodeResult::Throw);
|
||||
const frontend::CompilationStencil& delazification) {
|
||||
#ifdef DEBUG
|
||||
auto sanityCheck = mozilla::MakeScopeExit(
|
||||
[&] { MOZ_ASSERT(validateResultCode(cx(), resultCode())); });
|
||||
#endif
|
||||
|
||||
if (!merger_->addDelazification(cx(), delazification)) {
|
||||
return fail(JS::TranscodeResult::Throw);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
XDRResult XDRIncrementalStencilEncoder::linearize(JSContext* cx,
|
||||
JS::TranscodeBuffer& buffer,
|
||||
XDRResult XDRIncrementalStencilEncoder::linearize(JS::TranscodeBuffer& buffer,
|
||||
ScriptSource* ss) {
|
||||
XDRStencilEncoder encoder(cx, buffer);
|
||||
#ifdef DEBUG
|
||||
auto sanityCheck = mozilla::MakeScopeExit(
|
||||
[&] { MOZ_ASSERT(validateResultCode(cx(), resultCode())); });
|
||||
#endif
|
||||
|
||||
// NOTE: If buffer is empty, buffer.begin() doesn't point valid buffer.
|
||||
MOZ_ASSERT_IF(!buffer.empty(),
|
||||
JS::IsTranscodingBytecodeAligned(buffer.begin()));
|
||||
MOZ_ASSERT(JS::IsTranscodingBytecodeOffsetAligned(buffer.length()));
|
||||
|
||||
// Use the output buffer directly. The caller may have already have data in
|
||||
// the buffer so ensure we skip over it.
|
||||
XDRBuffer<XDR_ENCODE> outputBuf(cx(), buffer, buffer.length());
|
||||
|
||||
switchToBuffer(&outputBuf);
|
||||
|
||||
RefPtr<ScriptSource> source(ss);
|
||||
MOZ_TRY(XDRStencilHeader(this, nullptr, source));
|
||||
|
||||
{
|
||||
frontend::BorrowingCompilationStencil borrowingStencil(
|
||||
merger_->getResult());
|
||||
MOZ_TRY(encoder.codeStencil(source, borrowingStencil));
|
||||
MOZ_TRY(XDRParserAtomTable(this, borrowingStencil));
|
||||
MOZ_TRY(XDRCompilationStencil(this, borrowingStencil));
|
||||
}
|
||||
|
||||
switchToBuffer(&mainBuf);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
@ -433,8 +507,14 @@ XDRResult XDRStencilDecoder::codeStencil(
|
||||
[&] { MOZ_ASSERT(validateResultCode(cx(), resultCode())); });
|
||||
#endif
|
||||
|
||||
frontend::ParserAtomSpanBuilder parserAtomBuilder(cx()->runtime(),
|
||||
stencil.parserAtomData);
|
||||
parserAtomBuilder_ = &parserAtomBuilder;
|
||||
stencilAlloc_ = &stencil.alloc;
|
||||
|
||||
MOZ_TRY(XDRStencilHeader(this, &input.options, stencil.source));
|
||||
MOZ_TRY(frontend::StencilXDR::codeCompilationStencil(this, stencil));
|
||||
MOZ_TRY(XDRParserAtomTable(this, stencil));
|
||||
MOZ_TRY(XDRCompilationStencil(this, stencil));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "jsfriendapi.h"
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#include "frontend/ParserAtom.h"
|
||||
#include "js/CompileOptions.h"
|
||||
#include "js/Transcoding.h"
|
||||
#include "js/TypeDecls.h"
|
||||
@ -238,6 +239,10 @@ class XDRState : public XDRCoderBase {
|
||||
|
||||
virtual bool hasAtomTable() const { return false; }
|
||||
virtual XDRAtomTable& atomTable() { MOZ_CRASH("does not have atomTable"); }
|
||||
virtual frontend::ParserAtomSpanBuilder& frontendAtoms() {
|
||||
MOZ_CRASH("does not have frontendAtoms");
|
||||
}
|
||||
virtual LifoAlloc& stencilAlloc() { MOZ_CRASH("does not have stencilAlloc"); }
|
||||
virtual void finishAtomTable() { MOZ_CRASH("does not have atomTable"); }
|
||||
|
||||
template <typename T = mozilla::Ok>
|
||||
@ -548,33 +553,56 @@ class XDROffThreadDecoder : public XDRDecoder {
|
||||
* b. ScriptSource
|
||||
* d. Alignment padding
|
||||
* 2. Stencil
|
||||
* a. CompilationStencil
|
||||
* a. ParseAtomTable
|
||||
* b. CompilationStencil
|
||||
*/
|
||||
|
||||
/*
|
||||
* The stencil decoder accepts `range` as input.
|
||||
* The stencil decoder accepts `options` and `range` as input, along
|
||||
* with a freshly initialized `parserAtoms` table.
|
||||
*
|
||||
* The decoded stencils are outputted to the default-initialized
|
||||
* `stencil` parameter of `codeStencil` method.
|
||||
* `stencil` parameter of `codeStencil` method, and decoded atoms are
|
||||
* interned into the `parserAtoms` parameter of the ctor.
|
||||
*
|
||||
* The decoded stencils borrow the input `buffer`/`range`, and the consumer
|
||||
* has to keep the buffer alive while the decoded stencils are alive.
|
||||
*/
|
||||
class XDRStencilDecoder : public XDRDecoderBase {
|
||||
public:
|
||||
XDRStencilDecoder(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor)
|
||||
: XDRDecoderBase(cx, buffer, cursor) {
|
||||
XDRStencilDecoder(JSContext* cx, const JS::ReadOnlyCompileOptions* options,
|
||||
JS::TranscodeBuffer& buffer, size_t cursor)
|
||||
: XDRDecoderBase(cx, buffer, cursor), options_(options) {
|
||||
MOZ_ASSERT(JS::IsTranscodingBytecodeAligned(buffer.begin()));
|
||||
MOZ_ASSERT(JS::IsTranscodingBytecodeOffsetAligned(cursor));
|
||||
MOZ_ASSERT(options_);
|
||||
}
|
||||
|
||||
XDRStencilDecoder(JSContext* cx, const JS::TranscodeRange& range)
|
||||
: XDRDecoderBase(cx, range) {
|
||||
XDRStencilDecoder(JSContext* cx, const JS::ReadOnlyCompileOptions* options,
|
||||
const JS::TranscodeRange& range)
|
||||
: XDRDecoderBase(cx, range), options_(options) {
|
||||
MOZ_ASSERT(JS::IsTranscodingBytecodeAligned(range.begin().get()));
|
||||
MOZ_ASSERT(options_);
|
||||
}
|
||||
|
||||
bool hasAtomTable() const override { return hasFinishedAtomTable_; }
|
||||
frontend::ParserAtomSpanBuilder& frontendAtoms() override {
|
||||
return *parserAtomBuilder_;
|
||||
}
|
||||
LifoAlloc& stencilAlloc() override { return *stencilAlloc_; }
|
||||
void finishAtomTable() override { hasFinishedAtomTable_ = true; }
|
||||
|
||||
bool hasOptions() const override { return true; }
|
||||
const JS::ReadOnlyCompileOptions& options() override { return *options_; }
|
||||
|
||||
XDRResult codeStencil(frontend::CompilationInput& input,
|
||||
frontend::CompilationStencil& stencil);
|
||||
|
||||
private:
|
||||
const JS::ReadOnlyCompileOptions* options_;
|
||||
bool hasFinishedAtomTable_ = false;
|
||||
frontend::ParserAtomSpanBuilder* parserAtomBuilder_ = nullptr;
|
||||
LifoAlloc* stencilAlloc_ = nullptr;
|
||||
};
|
||||
|
||||
class XDRStencilEncoder : public XDREncoder {
|
||||
@ -587,35 +615,33 @@ class XDRStencilEncoder : public XDREncoder {
|
||||
MOZ_ASSERT(JS::IsTranscodingBytecodeOffsetAligned(buffer.length()));
|
||||
}
|
||||
|
||||
private:
|
||||
XDRResult codeStencil(const JS::ReadOnlyCompileOptions* options,
|
||||
const RefPtr<ScriptSource>& source,
|
||||
const frontend::CompilationStencil& stencil);
|
||||
|
||||
public:
|
||||
XDRResult codeStencil(const frontend::CompilationInput& input,
|
||||
const frontend::CompilationStencil& stencil);
|
||||
|
||||
XDRResult codeStencil(const RefPtr<ScriptSource>& source,
|
||||
const frontend::CompilationStencil& stencil);
|
||||
XDRResult codeStencil(frontend::CompilationInput& input,
|
||||
frontend::CompilationStencil& stencil);
|
||||
};
|
||||
|
||||
class XDRIncrementalStencilEncoder {
|
||||
class XDRIncrementalStencilEncoder : public XDREncoder {
|
||||
// The target buffer isn't available until linearize.
|
||||
// Hold dummy buffer to initialize XDREncoder.
|
||||
JS::TranscodeBuffer dummy_;
|
||||
|
||||
frontend::CompilationStencilMerger* merger_ = nullptr;
|
||||
|
||||
public:
|
||||
XDRIncrementalStencilEncoder() = default;
|
||||
explicit XDRIncrementalStencilEncoder(JSContext* cx)
|
||||
: XDREncoder(cx, dummy_, 0) {}
|
||||
|
||||
~XDRIncrementalStencilEncoder();
|
||||
virtual ~XDRIncrementalStencilEncoder();
|
||||
|
||||
XDRResult linearize(JSContext* cx, JS::TranscodeBuffer& buffer,
|
||||
js::ScriptSource* ss);
|
||||
XDRResult linearize(JS::TranscodeBuffer& buffer, js::ScriptSource* ss);
|
||||
|
||||
XDRResult setInitial(
|
||||
JSContext* cx, const JS::ReadOnlyCompileOptions& options,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
UniquePtr<frontend::ExtensibleCompilationStencil>&& initial);
|
||||
XDRResult addDelazification(
|
||||
JSContext* cx, const frontend::CompilationStencil& delazification);
|
||||
const frontend::CompilationStencil& delazification);
|
||||
|
||||
private:
|
||||
void switchToBuffer(XDRBuffer<XDR_ENCODE>* target) { buf = target; }
|
||||
};
|
||||
|
||||
template <XDRMode mode>
|
||||
@ -627,6 +653,21 @@ XDRResult XDRAtom(XDRState<mode>* xdr, js::MutableHandleAtom atomp);
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRAtomData(XDRState<mode>* xdr, js::MutableHandleAtom atomp);
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRParserAtom(XDRState<mode>* xdr, frontend::ParserAtom** atomp);
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRCompilationStencil(XDRState<mode>* xdr,
|
||||
frontend::CompilationStencil& stencil);
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRCheckCompilationStencil(XDRState<mode>* xdr,
|
||||
frontend::CompilationStencil& stencil);
|
||||
|
||||
template <XDRMode mode>
|
||||
XDRResult XDRCheckCompilationStencil(
|
||||
XDRState<mode>* xdr, frontend::ExtensibleCompilationStencil& stencil);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* vm_Xdr_h */
|
||||
|
Loading…
x
Reference in New Issue
Block a user