Backed out 5 changesets (bug 1797024, bug 1786834) for causing build bustages on ParserAtom.cpp. CLOSED TREE

Backed out changeset ea88488b0626 (bug 1797024)
Backed out changeset c4fcaed9709c (bug 1797024)
Backed out changeset 149d939edcea (bug 1797024)
Backed out changeset 3280c912570a (bug 1786834)
Backed out changeset ba594d0b12b0 (bug 1786834)
This commit is contained in:
Stanca Serban 2022-11-11 08:09:23 +02:00
Родитель 80da629315
Коммит baf169c748
23 изменённых файлов: 293 добавлений и 252 удалений

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

@ -191,7 +191,7 @@ bool js::SetSourceOptions(JSContext* cx, ErrorContext* ec, ScriptSource* source,
if (!chars) {
return false;
}
if (!source->setSourceMapURL(ec, std::move(chars))) {
if (!source->setSourceMapURL(cx, ec, std::move(chars))) {
return false;
}
}

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

@ -528,7 +528,7 @@ bool DebuggerSource::CallData::setSourceMapURL() {
}
AutoReportFrontendContext ec(cx);
if (!ss->setSourceMapURL(&ec, std::move(chars))) {
if (!ss->setSourceMapURL(cx, &ec, std::move(chars))) {
return false;
}

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

@ -214,7 +214,7 @@ class MOZ_STACK_CLASS ScriptCompiler : public SourceAwareCompiler<Unit> {
return true;
}
return stencilOut->source->assignSource(ec, input.options, srcBuf);
return stencilOut->source->assignSource(cx, ec, input.options, srcBuf);
}
[[nodiscard]] static bool TrySmoosh(
@ -634,7 +634,7 @@ bool SourceAwareCompiler<Unit>::createSourceAndParser(JSContext* cx,
errorContext = ec;
if (!compilationState_.source->assignSource(ec, options, sourceBuffer_)) {
if (!compilationState_.source->assignSource(cx, ec, options, sourceBuffer_)) {
return false;
}
@ -1132,7 +1132,7 @@ static GetCachedResult GetCachedLazyFunctionStencilMaybeInstantiate(
}
if (output.is<UniquePtr<ExtensibleCompilationStencil>>()) {
auto extensible = cx->make_unique<ExtensibleCompilationStencil>(input);
auto extensible = cx->make_unique<ExtensibleCompilationStencil>(cx, input);
if (!extensible) {
return GetCachedResult::Error;
}

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

@ -1282,10 +1282,11 @@ struct ExtensibleCompilationStencil {
RefPtr<StencilAsmJSContainer> asmJS;
explicit ExtensibleCompilationStencil(ScriptSource* source);
explicit ExtensibleCompilationStencil(JSContext* cx, ScriptSource* source);
explicit ExtensibleCompilationStencil(CompilationInput& input);
ExtensibleCompilationStencil(const JS::ReadOnlyCompileOptions& options,
ExtensibleCompilationStencil(JSContext* cx, CompilationInput& input);
ExtensibleCompilationStencil(JSContext* cx,
const JS::ReadOnlyCompileOptions& options,
RefPtr<ScriptSource> source);
ExtensibleCompilationStencil(ExtensibleCompilationStencil&& other) noexcept

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

@ -18,8 +18,7 @@
#include "util/Text.h" // AsciiDigitToNumber
#include "util/Unicode.h"
#include "vm/JSContext.h"
#include "vm/MutexIDs.h" // mutexid
#include "vm/Printer.h" // Sprinter, QuoteString
#include "vm/Printer.h" // Sprinter, QuoteString
#include "vm/Runtime.h"
#include "vm/SelfHosting.h" // ExtendedUnclonedSelfHostedFunctionNamePrefix
#include "vm/StaticStrings.h"
@ -326,7 +325,8 @@ void ParserAtomsTable::dumpCharsNoQuote(js::GenericPrinter& out,
}
#endif
ParserAtomsTable::ParserAtomsTable(LifoAlloc& alloc) : alloc_(&alloc) {}
ParserAtomsTable::ParserAtomsTable(JSRuntime* rt, LifoAlloc& alloc)
: wellKnownTable_(*rt->commonParserNames), alloc_(&alloc) {}
TaggedParserAtomIndex ParserAtomsTable::addEntry(ErrorContext* ec,
EntryMap::AddPtr& addPtr,
@ -376,15 +376,14 @@ TaggedParserAtomIndex ParserAtomsTable::internAscii(ErrorContext* ec,
TaggedParserAtomIndex ParserAtomsTable::internLatin1(
ErrorContext* ec, const Latin1Char* latin1Ptr, uint32_t length) {
// Check for tiny strings which are abundant in minified code.
if (auto tiny = WellKnownParserAtoms::getSingleton().lookupTinyIndex(
latin1Ptr, length)) {
if (auto tiny = wellKnownTable_.lookupTinyIndex(latin1Ptr, length)) {
return tiny;
}
// Check for well-known atom.
InflatedChar16Sequence<Latin1Char> seq(latin1Ptr, length);
SpecificParserAtomLookup<Latin1Char> lookup(seq);
if (auto wk = WellKnownParserAtoms::getSingleton().lookupChar16Seq(lookup)) {
if (auto wk = wellKnownTable_.lookupChar16Seq(lookup)) {
return wk;
}
@ -542,8 +541,7 @@ static inline bool IsLatin1(mozilla::Utf8Unit c1, mozilla::Utf8Unit c2) {
TaggedParserAtomIndex ParserAtomsTable::internUtf8(
ErrorContext* ec, const mozilla::Utf8Unit* utf8Ptr, uint32_t nbyte) {
if (auto tiny = WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(
utf8Ptr, nbyte)) {
if (auto tiny = wellKnownTable_.lookupTinyIndexUTF8(utf8Ptr, nbyte)) {
return tiny;
}
@ -564,7 +562,7 @@ TaggedParserAtomIndex ParserAtomsTable::internUtf8(
// NOTE: Well-known are all ASCII so have been handled above.
InflatedChar16Sequence<mozilla::Utf8Unit> seq(utf8Ptr, nbyte);
SpecificParserAtomLookup<mozilla::Utf8Unit> lookup(seq);
MOZ_ASSERT(!WellKnownParserAtoms::getSingleton().lookupChar16Seq(lookup));
MOZ_ASSERT(!wellKnownTable_.lookupChar16Seq(lookup));
EntryMap::AddPtr addPtr = entryMap_.lookupForAdd(lookup);
if (addPtr) {
return addPtr->value();
@ -590,15 +588,14 @@ TaggedParserAtomIndex ParserAtomsTable::internChar16(ErrorContext* ec,
const char16_t* char16Ptr,
uint32_t length) {
// Check for tiny strings which are abundant in minified code.
if (auto tiny = WellKnownParserAtoms::getSingleton().lookupTinyIndex(
char16Ptr, length)) {
if (auto tiny = wellKnownTable_.lookupTinyIndex(char16Ptr, length)) {
return tiny;
}
// Check against well-known.
InflatedChar16Sequence<char16_t> seq(char16Ptr, length);
SpecificParserAtomLookup<char16_t> lookup(seq);
if (auto wk = WellKnownParserAtoms::getSingleton().lookupChar16Seq(lookup)) {
if (auto wk = wellKnownTable_.lookupChar16Seq(lookup)) {
return wk;
}
@ -1211,16 +1208,6 @@ bool InstantiateMarkedAtomsAsPermanent(JSContext* cx, ErrorContext* ec,
return true;
}
/* static */
WellKnownParserAtoms WellKnownParserAtoms::singleton_;
WellKnownParserAtoms::WellKnownParserAtoms()
#ifdef DEBUG
: initLock_(mutexid::WellKnownParserAtomsInit)
#endif
{
}
template <typename CharT>
TaggedParserAtomIndex WellKnownParserAtoms::lookupChar16Seq(
const SpecificParserAtomLookup<CharT>& lookup) const {
@ -1251,7 +1238,8 @@ TaggedParserAtomIndex WellKnownParserAtoms::lookupTinyIndexUTF8(
return lookupTinyIndex(reinterpret_cast<const Latin1Char*>(utf8Ptr), nbyte);
}
bool WellKnownParserAtoms::initSingle(const WellKnownAtomInfo& info,
bool WellKnownParserAtoms::initSingle(JSContext* cx,
const WellKnownAtomInfo& info,
TaggedParserAtomIndex index) {
unsigned int len = info.length;
const Latin1Char* str = reinterpret_cast<const Latin1Char*>(info.content);
@ -1271,67 +1259,6 @@ bool WellKnownParserAtoms::initSingle(const WellKnownAtomInfo& info,
// Save name for returning after moving entry into set.
if (!wellKnownMap_.putNew(lookup, &info, index)) {
return false;
}
return true;
}
bool WellKnownParserAtoms::init() {
#ifdef DEBUG
LockGuard<Mutex> guard(initLock_);
MOZ_ASSERT(!initialized_);
initialized_ = true;
#endif
MOZ_ASSERT(wellKnownMap_.empty());
// Add well-known strings to the HashMap. The HashMap is used for dynamic
// lookups later and does not change once this init method is complete.
#define COMMON_NAME_INIT_(_, NAME, _2) \
if (!initSingle(GetWellKnownAtomInfo(WellKnownAtomId::NAME), \
TaggedParserAtomIndex::WellKnown::NAME())) { \
return false; \
}
FOR_EACH_NONTINY_COMMON_PROPERTYNAME(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
#define COMMON_NAME_INIT_(NAME, _) \
if (!initSingle(GetWellKnownAtomInfo(WellKnownAtomId::NAME), \
TaggedParserAtomIndex::WellKnown::NAME())) { \
return false; \
}
JS_FOR_EACH_PROTOTYPE(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
#define COMMON_NAME_INIT_(NAME) \
if (!initSingle(GetWellKnownAtomInfo(WellKnownAtomId::NAME), \
TaggedParserAtomIndex::WellKnown::NAME())) { \
return false; \
}
JS_FOR_EACH_WELL_KNOWN_SYMBOL(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
return true;
}
void WellKnownParserAtoms::free() {
initialized_ = false;
wellKnownMap_.clear();
}
/* static */ bool WellKnownParserAtoms::initSingleton() {
return singleton_.init();
}
/* static */ void WellKnownParserAtoms::freeSingleton() { singleton_.free(); }
} /* namespace frontend */
} /* namespace js */
bool JSRuntime::initializeParserAtoms(JSContext* cx) {
if (parentRuntime) {
return true;
}
if (!js::frontend::WellKnownParserAtoms::initSingleton()) {
js::ReportOutOfMemory(cx);
return false;
}
@ -1339,8 +1266,57 @@ bool JSRuntime::initializeParserAtoms(JSContext* cx) {
return true;
}
bool WellKnownParserAtoms::init(JSContext* cx) {
// Add well-known strings to the HashMap. The HashMap is used for dynamic
// lookups later and does not change once this init method is complete.
#define COMMON_NAME_INIT_(_, NAME, _2) \
if (!initSingle(cx, GetWellKnownAtomInfo(WellKnownAtomId::NAME), \
TaggedParserAtomIndex::WellKnown::NAME())) { \
return false; \
}
FOR_EACH_NONTINY_COMMON_PROPERTYNAME(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
#define COMMON_NAME_INIT_(NAME, _) \
if (!initSingle(cx, GetWellKnownAtomInfo(WellKnownAtomId::NAME), \
TaggedParserAtomIndex::WellKnown::NAME())) { \
return false; \
}
JS_FOR_EACH_PROTOTYPE(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
#define COMMON_NAME_INIT_(NAME) \
if (!initSingle(cx, GetWellKnownAtomInfo(WellKnownAtomId::NAME), \
TaggedParserAtomIndex::WellKnown::NAME())) { \
return false; \
}
JS_FOR_EACH_WELL_KNOWN_SYMBOL(COMMON_NAME_INIT_)
#undef COMMON_NAME_INIT_
return true;
}
} /* namespace frontend */
} /* namespace js */
bool JSRuntime::initializeParserAtoms(JSContext* cx) {
MOZ_ASSERT(!commonParserNames);
if (parentRuntime) {
commonParserNames = parentRuntime->commonParserNames;
return true;
}
UniquePtr<js::frontend::WellKnownParserAtoms> names(
js_new<js::frontend::WellKnownParserAtoms>());
if (!names || !names->init(cx)) {
return false;
}
commonParserNames = names.release();
return true;
}
void JSRuntime::finishParserAtoms() {
if (!parentRuntime) {
js::frontend::WellKnownParserAtoms::freeSingleton();
js_delete(commonParserNames.ref());
}
}

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

@ -25,13 +25,13 @@
#include "js/TypeDecls.h" // Latin1Char
#include "js/Utility.h" // UniqueChars
#include "js/Vector.h" // Vector
#include "threading/Mutex.h" // Mutex
#include "util/Text.h" // InflatedChar16Sequence
#include "vm/CommonPropertyNames.h"
#include "vm/StaticStrings.h"
#include "vm/WellKnownAtom.h" // WellKnownAtomId, WellKnownAtomInfo
struct JS_PUBLIC_API JSContext;
struct JSRuntime;
class JSAtom;
class JSString;
@ -572,34 +572,18 @@ using ParserAtomSpan = mozilla::Span<ParserAtom*>;
* constant time.
*/
class WellKnownParserAtoms {
static WellKnownParserAtoms singleton_;
#ifdef DEBUG
js::Mutex initLock_ MOZ_UNANNOTATED;
bool initialized_ = false;
#endif
WellKnownParserAtoms();
public:
// Common property and prototype names are tracked in a hash table. This table
// does not key for any items already in a direct-indexing tiny atom table.
using EntryMap = HashMap<const WellKnownAtomInfo*, TaggedParserAtomIndex,
WellKnownAtomInfoHasher, js::SystemAllocPolicy>;
EntryMap wellKnownMap_;
bool initSingle(const WellKnownAtomInfo& info, TaggedParserAtomIndex index);
bool init();
void free();
bool initSingle(JSContext* cx, const WellKnownAtomInfo& info,
TaggedParserAtomIndex index);
public:
static bool initSingleton();
static void freeSingleton();
static WellKnownParserAtoms& getSingleton() {
MOZ_ASSERT(!singleton_.wellKnownMap_.empty());
return singleton_;
}
bool init(JSContext* cx);
// Maximum length of any well known atoms. This can be increased if needed.
static constexpr size_t MaxWellKnownLength = 32;
@ -675,6 +659,8 @@ class ParserAtomsTable {
friend struct CompilationStencil;
private:
const WellKnownParserAtoms& wellKnownTable_;
LifoAlloc* alloc_;
// The ParserAtom are owned by the LifoAlloc.
@ -684,7 +670,7 @@ class ParserAtomsTable {
ParserAtomVector entries_;
public:
explicit ParserAtomsTable(LifoAlloc& alloc);
ParserAtomsTable(JSRuntime* rt, LifoAlloc& alloc);
ParserAtomsTable(ParserAtomsTable&&) = default;
ParserAtomsTable& operator=(ParserAtomsTable&& other) noexcept {
entryMap_ = std::move(other.entryMap_);

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

@ -2760,29 +2760,31 @@ bool CompilationStencil::deserializeStencils(JSContext* cx, ErrorContext* ec,
return true;
}
ExtensibleCompilationStencil::ExtensibleCompilationStencil(ScriptSource* source)
ExtensibleCompilationStencil::ExtensibleCompilationStencil(JSContext* cx,
ScriptSource* source)
: alloc(CompilationStencil::LifoAllocChunkSize),
source(source),
parserAtoms(alloc) {}
parserAtoms(cx->runtime(), alloc) {}
ExtensibleCompilationStencil::ExtensibleCompilationStencil(
CompilationInput& input)
JSContext* cx, CompilationInput& input)
: canLazilyParse(CanLazilyParse(input.options)),
alloc(CompilationStencil::LifoAllocChunkSize),
source(input.source),
parserAtoms(alloc) {}
parserAtoms(cx->runtime(), alloc) {}
ExtensibleCompilationStencil::ExtensibleCompilationStencil(
const JS::ReadOnlyCompileOptions& options, RefPtr<ScriptSource> source)
JSContext* cx, const JS::ReadOnlyCompileOptions& options,
RefPtr<ScriptSource> source)
: canLazilyParse(CanLazilyParse(options)),
alloc(CompilationStencil::LifoAllocChunkSize),
source(std::move(source)),
parserAtoms(alloc) {}
parserAtoms(cx->runtime(), alloc) {}
CompilationState::CompilationState(JSContext* cx,
LifoAllocScope& parserAllocScope,
CompilationInput& input)
: ExtensibleCompilationStencil(input),
: ExtensibleCompilationStencil(cx, input),
directives(input.options.forceStrictMode()),
usedNames(cx),
parserAllocScope(parserAllocScope),

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

@ -1238,7 +1238,7 @@ XDRResult StencilXDR::codeSource(XDRState<mode>* xdr,
}
MOZ_TRY(xdr->codeCharsZ(chars));
if (mode == XDR_DECODE) {
if (!source->setFilename(ec, std::move(chars.ref<UniqueChars>()))) {
if (!source->setFilename(cx, ec, std::move(chars.ref<UniqueChars>()))) {
return xdr->fail(JS::TranscodeResult::Throw);
}
}
@ -1268,7 +1268,7 @@ XDRResult StencilXDR::codeSource(XDRState<mode>* xdr,
MOZ_TRY(xdr->codeCharsZ(chars));
if (mode == XDR_DECODE) {
if (!source->setSourceMapURL(
ec, std::move(chars.ref<UniqueTwoByteChars>()))) {
cx, ec, std::move(chars.ref<UniqueTwoByteChars>()))) {
return xdr->fail(JS::TranscodeResult::Throw);
}
}

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

@ -702,7 +702,7 @@ static bool ParseZealModeName(CharRange text, uint32_t* modeOut) {
};
static const ModeInfo zealModes[] = {{"None", 0},
# define ZEAL_MODE(name, value) {#name, strlen(#name), value},
# define ZEAL_MODE(name, value) {# name, strlen(# name), value},
JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE)
# undef ZEAL_MODE
};
@ -781,7 +781,7 @@ bool GCRuntime::parseAndSetZeal(const char* str) {
const char* js::gc::AllocKindName(AllocKind kind) {
static const char* const names[] = {
# define EXPAND_THING_NAME(allocKind, _1, _2, _3, _4, _5, _6) #allocKind,
# define EXPAND_THING_NAME(allocKind, _1, _2, _3, _4, _5, _6) # allocKind,
FOR_EACH_ALLOCKIND(EXPAND_THING_NAME)
# undef EXPAND_THING_NAME
};
@ -2126,8 +2126,8 @@ void GCRuntime::purgeRuntime() {
rt->caches().purge();
if (rt->isMainRuntime()) {
SharedImmutableStringsCache::getSingleton().purge();
if (auto cache = rt->maybeThisRuntimeSharedImmutableStrings()) {
cache->purge();
}
MOZ_ASSERT(unmarkGrayStack.empty());

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

@ -321,7 +321,7 @@ static bool addScriptToFinalWarmUpCountMap(JSContext* cx, HandleScript script) {
}
SharedImmutableString sfilename =
SharedImmutableStringsCache::getSingleton().getOrCreate(
cx->runtime()->sharedImmutableStrings().getOrCreate(
script->filename(), strlen(script->filename()));
if (!sfilename) {
ReportOutOfMemory(cx);

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

@ -9,8 +9,8 @@
#include <utility> // std::initializer_list
#include <vector> // std::vector
#include "frontend/ParserAtom.h" // js::frontend::ParserAtomsTable, js::frontend::WellKnownParserAtoms
#include "js/TypeDecls.h" // JS::Latin1Char
#include "frontend/ParserAtom.h" // js::frontend::ParserAtomsTable
#include "js/TypeDecls.h" // JS::Latin1Char
#include "jsapi-tests/tests.h"
#include "vm/ErrorContext.h" // AutoReportFrontendContext
@ -23,7 +23,7 @@ BEGIN_TEST(testParserAtom_empty) {
js::AutoReportFrontendContext ec(cx);
js::LifoAlloc alloc(512);
ParserAtomsTable atomTable(alloc);
ParserAtomsTable atomTable(cx->runtime(), alloc);
const char ascii[] = {};
const JS::Latin1Char latin1[] = {};
@ -46,11 +46,10 @@ BEGIN_TEST(testParserAtom_tiny1_ASCII) {
using js::frontend::ParserAtom;
using js::frontend::ParserAtomsTable;
using js::frontend::ParserAtomVector;
using js::frontend::WellKnownParserAtoms;
js::AutoReportFrontendContext ec(cx);
js::LifoAlloc alloc(512);
ParserAtomsTable atomTable(alloc);
ParserAtomsTable atomTable(cx->runtime(), alloc);
char16_t a = 'a';
const char ascii[] = {'a'};
@ -58,7 +57,7 @@ BEGIN_TEST(testParserAtom_tiny1_ASCII) {
const mozilla::Utf8Unit utf8[] = {mozilla::Utf8Unit('a')};
char16_t char16[] = {'a'};
auto refIndex = WellKnownParserAtoms::getSingleton().lookupTinyIndex(&a, 1);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(&a, 1);
CHECK(refIndex);
CHECK(atomTable.internAscii(&ec, ascii, 1) == refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
@ -74,11 +73,10 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
using js::frontend::ParserAtom;
using js::frontend::ParserAtomsTable;
using js::frontend::ParserAtomVector;
using js::frontend::WellKnownParserAtoms;
js::AutoReportFrontendContext ec(cx);
js::LifoAlloc alloc(512);
ParserAtomsTable atomTable(alloc);
ParserAtomsTable atomTable(cx->runtime(), alloc);
{
char16_t euro = 0x0080;
@ -88,8 +86,7 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
mozilla::Utf8Unit(static_cast<unsigned char>(0x80))};
char16_t char16[] = {0x0080};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(&euro, 1);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(&euro, 1);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
CHECK(atomTable.internUtf8(&ec, utf8, 2) == refIndex);
@ -105,7 +102,7 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
char16_t char16[] = {0x00BD};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(&frac12, 1);
cx->runtime()->commonParserNames->lookupTinyIndex(&frac12, 1);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
CHECK(atomTable.internUtf8(&ec, utf8, 2) == refIndex);
@ -121,7 +118,7 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
char16_t char16[] = {0x00BF};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(&iquest, 1);
cx->runtime()->commonParserNames->lookupTinyIndex(&iquest, 1);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
CHECK(atomTable.internUtf8(&ec, utf8, 2) == refIndex);
@ -137,7 +134,7 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
char16_t char16[] = {0x00C0};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(&agrave, 1);
cx->runtime()->commonParserNames->lookupTinyIndex(&agrave, 1);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
CHECK(atomTable.internUtf8(&ec, utf8, 2) == refIndex);
@ -152,8 +149,7 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xA6))};
char16_t char16[] = {0x00E6};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(&ae, 1);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(&ae, 1);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
CHECK(atomTable.internUtf8(&ec, utf8, 2) == refIndex);
@ -168,8 +164,7 @@ BEGIN_TEST(testParserAtom_tiny1_nonASCII) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xBF))};
char16_t char16[] = {0x00FF};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(&yuml, 1);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(&yuml, 1);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
CHECK(atomTable.internUtf8(&ec, utf8, 2) == refIndex);
@ -188,18 +183,17 @@ END_TEST(testParserAtom_tiny1_nonASCII)
BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
using js::frontend::ParserAtom;
using js::frontend::ParserAtomsTable;
using js::frontend::WellKnownParserAtoms;
js::AutoReportFrontendContext ec(cx);
js::LifoAlloc alloc(512);
ParserAtomsTable atomTable(alloc);
ParserAtomsTable atomTable(cx->runtime(), alloc);
{
const mozilla::Utf8Unit utf8[] = {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC1)),
mozilla::Utf8Unit(static_cast<unsigned char>(0x80))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -207,7 +201,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC2)),
mozilla::Utf8Unit(static_cast<unsigned char>(0x7F))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -217,7 +211,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0x80))};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2);
cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
}
@ -229,7 +223,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xBF))};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2);
cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
}
@ -239,7 +233,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC2)),
mozilla::Utf8Unit(static_cast<unsigned char>(0xC0))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -247,7 +241,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC3)),
mozilla::Utf8Unit(static_cast<unsigned char>(0x7F))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -257,7 +251,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0x80))};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2);
cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
}
@ -269,7 +263,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xBF))};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2);
cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2);
CHECK(refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 1) == refIndex);
}
@ -279,7 +273,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC3)),
mozilla::Utf8Unit(static_cast<unsigned char>(0xC0))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -287,7 +281,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC4)),
mozilla::Utf8Unit(static_cast<unsigned char>(0x7F))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -295,7 +289,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC4)),
mozilla::Utf8Unit(static_cast<unsigned char>(0x80))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -303,7 +297,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC4)),
mozilla::Utf8Unit(static_cast<unsigned char>(0xBF))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
{
@ -311,7 +305,7 @@ BEGIN_TEST(testParserAtom_tiny1_invalidUTF8) {
mozilla::Utf8Unit(static_cast<unsigned char>(0xC4)),
mozilla::Utf8Unit(static_cast<unsigned char>(0xC0))};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndexUTF8(utf8, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndexUTF8(utf8, 2));
}
return true;
@ -323,11 +317,10 @@ BEGIN_TEST(testParserAtom_tiny2) {
using js::frontend::ParserAtom;
using js::frontend::ParserAtomsTable;
using js::frontend::ParserAtomVector;
using js::frontend::WellKnownParserAtoms;
js::AutoReportFrontendContext ec(cx);
js::LifoAlloc alloc(512);
ParserAtomsTable atomTable(alloc);
ParserAtomsTable atomTable(cx->runtime(), alloc);
const char ascii[] = {'a', '0'};
JS::Latin1Char latin1[] = {'a', '0'};
@ -335,8 +328,7 @@ BEGIN_TEST(testParserAtom_tiny2) {
mozilla::Utf8Unit('0')};
char16_t char16[] = {'a', '0'};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 2);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 2);
CHECK(refIndex);
CHECK(atomTable.internAscii(&ec, ascii, 2) == refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 2) == refIndex);
@ -346,7 +338,7 @@ BEGIN_TEST(testParserAtom_tiny2) {
// Note: If Latin1-Extended characters become supported, then UTF-8 behaviour
// should be tested.
char16_t ae0[] = {0x00E6, '0'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ae0, 2));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ae0, 2));
return true;
}
@ -357,11 +349,10 @@ BEGIN_TEST(testParserAtom_int) {
using js::frontend::ParserAtom;
using js::frontend::ParserAtomsTable;
using js::frontend::ParserAtomVector;
using js::frontend::WellKnownParserAtoms;
js::AutoReportFrontendContext ec(cx);
js::LifoAlloc alloc(512);
ParserAtomsTable atomTable(alloc);
ParserAtomsTable atomTable(cx->runtime(), alloc);
{
const char ascii[] = {'1', '0', '0'};
@ -370,8 +361,7 @@ BEGIN_TEST(testParserAtom_int) {
mozilla::Utf8Unit('1'), mozilla::Utf8Unit('0'), mozilla::Utf8Unit('0')};
char16_t char16[] = {'1', '0', '0'};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3);
CHECK(refIndex);
CHECK(atomTable.internAscii(&ec, ascii, 3) == refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 3) == refIndex);
@ -386,8 +376,7 @@ BEGIN_TEST(testParserAtom_int) {
mozilla::Utf8Unit('2'), mozilla::Utf8Unit('5'), mozilla::Utf8Unit('5')};
char16_t char16[] = {'2', '5', '5'};
auto refIndex =
WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3);
auto refIndex = cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3);
CHECK(refIndex);
CHECK(atomTable.internAscii(&ec, ascii, 3) == refIndex);
CHECK(atomTable.internLatin1(&ec, latin1, 3) == refIndex);
@ -398,37 +387,37 @@ BEGIN_TEST(testParserAtom_int) {
{
const char ascii[] = {'0', '9', '9'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3));
}
{
const char ascii[] = {'0', 'F', 'F'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3));
}
{
const char ascii[] = {'1', '0', 'A'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3));
}
{
const char ascii[] = {'1', '0', 'a'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3));
}
{
const char ascii[] = {'2', '5', '6'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3));
}
{
const char ascii[] = {'3', '0', '0'};
CHECK(!WellKnownParserAtoms::getSingleton().lookupTinyIndex(ascii, 3));
CHECK(!cx->runtime()->commonParserNames->lookupTinyIndex(ascii, 3));
}
return true;

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

@ -51,7 +51,9 @@ static void getString(CacheAndIndex* cacheAndIndex) {
}
BEGIN_TEST(testSharedImmutableStringsCache) {
auto& cache = js::SharedImmutableStringsCache::getSingleton();
auto maybeCache = js::SharedImmutableStringsCache::Create();
CHECK(maybeCache.isSome());
auto& cache = *maybeCache;
js::Vector<js::Thread> threads(cx);
CHECK(threads.reserve(NUM_THREADS));

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

@ -100,7 +100,7 @@ JS_PUBLIC_API bool JS::StartIncrementalEncoding(JSContext* cx,
stencil = nullptr;
} else {
initial = cx->make_unique<frontend::ExtensibleCompilationStencil>(
stencil->source);
cx, stencil->source);
if (!initial) {
return false;
}

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

@ -673,7 +673,8 @@ struct DelazifyTask : public mozilla::LinkedListElement<DelazifyTask>,
// optimization and the VM should remain working even without this
// optimization in place.
static UniquePtr<DelazifyTask> Create(
JSRuntime* runtime, const JS::ContextOptions& contextOptions,
JSContext* cx, JSRuntime* runtime,
const JS::ContextOptions& contextOptions,
const JS::ReadOnlyCompileOptions& options,
const frontend::CompilationStencil& stencil);

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

@ -648,9 +648,11 @@ void ParseTask::scheduleDelazifyTask(AutoLockHelperThreadState& lock) {
{
AutoSetHelperThreadContext usesContext(contextOptions, lock);
AutoUnlockHelperThreadState unlock(lock);
JSContext* cx = TlsContext.get();
AutoSetContextRuntime ascr(runtime);
task = DelazifyTask::Create(runtime, contextOptions, options, *stencil_);
task =
DelazifyTask::Create(cx, runtime, contextOptions, options, *stencil_);
if (!task) {
return;
}
@ -871,7 +873,7 @@ void js::StartOffThreadDelazification(
JSRuntime* runtime = cx->runtime();
UniquePtr<DelazifyTask> task;
task = DelazifyTask::Create(runtime, cx->options(), options, stencil);
task = DelazifyTask::Create(cx, runtime, cx->options(), options, stencil);
if (!task) {
return;
}
@ -999,7 +1001,7 @@ bool LargeFirstDelazification::insert(ScriptIndex index,
}
UniquePtr<DelazifyTask> DelazifyTask::Create(
JSRuntime* runtime, const JS::ContextOptions& contextOptions,
JSContext* cx, JSRuntime* runtime, const JS::ContextOptions& contextOptions,
const JS::ReadOnlyCompileOptions& options,
const frontend::CompilationStencil& stencil) {
UniquePtr<DelazifyTask> task;
@ -1018,7 +1020,7 @@ UniquePtr<DelazifyTask> DelazifyTask::Create(
// Clone the extensible stencil to be used for eager delazification.
auto initial = task->ec_.getAllocator()
->make_unique<frontend::ExtensibleCompilationStencil>(
options, stencil.source);
cx, options, stencil.source);
if (!initial || !initial->cloneFrom(&task->ec_, stencil)) {
// In case of errors, skip this and delazify on-demand.
return nullptr;

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

@ -1326,7 +1326,7 @@ template <typename Unit>
[[nodiscard]] bool ScriptSource::setUncompressedSourceHelper(
JSContext* cx, EntryUnits<Unit>&& source, size_t length,
SourceRetrievable retrievable) {
auto& cache = SharedImmutableStringsCache::getSingleton();
auto& cache = cx->runtime()->sharedImmutableStrings();
auto uniqueChars = SourceTypeTraits<Unit>::toCacheable(std::move(source));
auto deduped = cache.getOrCreate(std::move(uniqueChars), length);
@ -1444,7 +1444,7 @@ template <typename Unit>
MOZ_ASSERT(data.is<Missing>(), "shouldn't be double-initializing");
MOZ_ASSERT(compressed != nullptr);
auto& cache = SharedImmutableStringsCache::getSingleton();
auto& cache = cx->runtime()->sharedImmutableStrings();
auto deduped = cache.getOrCreate(std::move(compressed), rawLength);
if (!deduped) {
ReportOutOfMemory(cx);
@ -1476,7 +1476,7 @@ template bool ScriptSource::initializeWithUnretrievableCompressedSource<
size_t sourceLength);
template <typename Unit>
bool ScriptSource::assignSource(ErrorContext* ec,
bool ScriptSource::assignSource(JSContext* cx, ErrorContext* ec,
const ReadOnlyCompileOptions& options,
SourceText<Unit>& srcBuf) {
MOZ_ASSERT(data.is<Missing>(),
@ -1494,7 +1494,8 @@ bool ScriptSource::assignSource(ErrorContext* ec,
return true;
}
auto& cache = SharedImmutableStringsCache::getSingleton();
JSRuntime* runtime = cx->runtime();
auto& cache = runtime->sharedImmutableStrings();
auto deduped = cache.getOrCreate(srcBuf.get(), srcBuf.length(), [&srcBuf]() {
using CharT = typename SourceTypeTraits<Unit>::CharT;
return srcBuf.ownsUnits()
@ -1511,10 +1512,10 @@ bool ScriptSource::assignSource(ErrorContext* ec,
return true;
}
template bool ScriptSource::assignSource(ErrorContext* ec,
template bool ScriptSource::assignSource(JSContext* cx, ErrorContext* ec,
const ReadOnlyCompileOptions& options,
SourceText<char16_t>& srcBuf);
template bool ScriptSource::assignSource(ErrorContext* ec,
template bool ScriptSource::assignSource(JSContext* cx, ErrorContext* ec,
const ReadOnlyCompileOptions& options,
SourceText<Utf8Unit>& srcBuf);
@ -1598,7 +1599,7 @@ void SourceCompressionTask::workEncodingSpecific() {
return;
}
auto& strings = SharedImmutableStringsCache::getSingleton();
auto& strings = runtime_->sharedImmutableStrings();
resultString_ = strings.getOrCreate(std::move(compressed), totalBytes);
}
@ -1873,7 +1874,7 @@ bool ScriptSource::initFromOptions(JSContext* cx, ErrorContext* ec,
if (!formatted) {
return false;
}
if (!setFilename(ec, std::move(formatted))) {
if (!setFilename(cx, ec, std::move(formatted))) {
return false;
}
} else if (options.filename()) {
@ -1894,25 +1895,28 @@ bool ScriptSource::initFromOptions(JSContext* cx, ErrorContext* ec,
// Use the SharedImmutableString map to deduplicate input string. The input
// string must be null-terminated.
template <typename SharedT, typename CharT>
static SharedT GetOrCreateStringZ(ErrorContext* ec,
static SharedT GetOrCreateStringZ(JSContext* cx, ErrorContext* ec,
UniquePtr<CharT[], JS::FreePolicy>&& str) {
JSRuntime* rt = cx->runtime();
size_t lengthWithNull = std::char_traits<CharT>::length(str.get()) + 1;
auto res = SharedImmutableStringsCache::getSingleton().getOrCreate(
std::move(str), lengthWithNull);
auto res =
rt->sharedImmutableStrings().getOrCreate(std::move(str), lengthWithNull);
if (!res) {
ReportOutOfMemory(ec);
}
return res;
}
SharedImmutableString ScriptSource::getOrCreateStringZ(ErrorContext* ec,
SharedImmutableString ScriptSource::getOrCreateStringZ(JSContext* cx,
ErrorContext* ec,
UniqueChars&& str) {
return GetOrCreateStringZ<SharedImmutableString>(ec, std::move(str));
return GetOrCreateStringZ<SharedImmutableString>(cx, ec, std::move(str));
}
SharedImmutableTwoByteString ScriptSource::getOrCreateStringZ(
ErrorContext* ec, UniqueTwoByteChars&& str) {
return GetOrCreateStringZ<SharedImmutableTwoByteString>(ec, std::move(str));
JSContext* cx, ErrorContext* ec, UniqueTwoByteChars&& str) {
return GetOrCreateStringZ<SharedImmutableTwoByteString>(cx, ec,
std::move(str));
}
bool ScriptSource::setFilename(JSContext* cx, ErrorContext* ec,
@ -1921,12 +1925,13 @@ bool ScriptSource::setFilename(JSContext* cx, ErrorContext* ec,
if (!owned) {
return false;
}
return setFilename(ec, std::move(owned));
return setFilename(cx, ec, std::move(owned));
}
bool ScriptSource::setFilename(ErrorContext* ec, UniqueChars&& filename) {
bool ScriptSource::setFilename(JSContext* cx, ErrorContext* ec,
UniqueChars&& filename) {
MOZ_ASSERT(!filename_);
filename_ = getOrCreateStringZ(ec, std::move(filename));
filename_ = getOrCreateStringZ(cx, ec, std::move(filename));
return bool(filename_);
}
@ -1936,13 +1941,13 @@ bool ScriptSource::setIntroducerFilename(JSContext* cx, ErrorContext* ec,
if (!owned) {
return false;
}
return setIntroducerFilename(ec, std::move(owned));
return setIntroducerFilename(cx, ec, std::move(owned));
}
bool ScriptSource::setIntroducerFilename(ErrorContext* ec,
bool ScriptSource::setIntroducerFilename(JSContext* cx, ErrorContext* ec,
UniqueChars&& filename) {
MOZ_ASSERT(!introducerFilename_);
introducerFilename_ = getOrCreateStringZ(ec, std::move(filename));
introducerFilename_ = getOrCreateStringZ(cx, ec, std::move(filename));
return bool(introducerFilename_);
}
@ -1971,7 +1976,7 @@ bool ScriptSource::setDisplayURL(JSContext* cx, ErrorContext* ec,
return true;
}
displayURL_ = getOrCreateStringZ(ec, std::move(url));
displayURL_ = getOrCreateStringZ(cx, ec, std::move(url));
return bool(displayURL_);
}
@ -1981,16 +1986,17 @@ bool ScriptSource::setSourceMapURL(JSContext* cx, ErrorContext* ec,
if (!owned) {
return false;
}
return setSourceMapURL(ec, std::move(owned));
return setSourceMapURL(cx, ec, std::move(owned));
}
bool ScriptSource::setSourceMapURL(ErrorContext* ec, UniqueTwoByteChars&& url) {
bool ScriptSource::setSourceMapURL(JSContext* cx, ErrorContext* ec,
UniqueTwoByteChars&& url) {
MOZ_ASSERT(url);
if (url[0] == '\0') {
return true;
}
sourceMapURL_ = getOrCreateStringZ(ec, std::move(url));
sourceMapURL_ = getOrCreateStringZ(cx, ec, std::move(url));
return bool(sourceMapURL_);
}

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

@ -651,8 +651,10 @@ class ScriptSource {
*/
static constexpr size_t MinimumCompressibleLength = 256;
SharedImmutableString getOrCreateStringZ(ErrorContext* ec, UniqueChars&& str);
SharedImmutableTwoByteString getOrCreateStringZ(ErrorContext* ec,
SharedImmutableString getOrCreateStringZ(JSContext* cx, ErrorContext* ec,
UniqueChars&& str);
SharedImmutableTwoByteString getOrCreateStringZ(JSContext* cx,
ErrorContext* ec,
UniqueTwoByteChars&& str);
private:
@ -667,7 +669,7 @@ class ScriptSource {
// Assign source data from |srcBuf| to this recently-created |ScriptSource|.
template <typename Unit>
[[nodiscard]] bool assignSource(ErrorContext* ec,
[[nodiscard]] bool assignSource(JSContext* cx, ErrorContext* ec,
const JS::ReadOnlyCompileOptions& options,
JS::SourceText<Unit>& srcBuf);
@ -993,14 +995,15 @@ class ScriptSource {
}
[[nodiscard]] bool setFilename(JSContext* cx, ErrorContext* ec,
const char* filename);
[[nodiscard]] bool setFilename(ErrorContext* ec, UniqueChars&& filename);
[[nodiscard]] bool setFilename(JSContext* cx, ErrorContext* ec,
UniqueChars&& filename);
const char* introducerFilename() const {
return introducerFilename_ ? introducerFilename_.chars() : filename();
}
[[nodiscard]] bool setIntroducerFilename(JSContext* cx, ErrorContext* ec,
const char* filename);
[[nodiscard]] bool setIntroducerFilename(ErrorContext* ec,
[[nodiscard]] bool setIntroducerFilename(JSContext* cx, ErrorContext* ec,
UniqueChars&& filename);
bool hasIntroductionType() const { return introductionType_; }
@ -1022,7 +1025,7 @@ class ScriptSource {
// Source maps
[[nodiscard]] bool setSourceMapURL(JSContext* cx, ErrorContext* ec,
const char16_t* url);
[[nodiscard]] bool setSourceMapURL(ErrorContext* ec,
[[nodiscard]] bool setSourceMapURL(JSContext* cx, ErrorContext* ec,
UniqueTwoByteChars&& url);
bool hasSourceMapURL() const { return bool(sourceMapURL_); }
const char16_t* sourceMapURL() { return sourceMapURL_.chars(); }

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

@ -20,7 +20,6 @@
_(ShellContextWatchdog, 100) \
_(ShellWorkerThreads, 100) \
_(ShellObjectMailbox, 100) \
_(WellKnownParserAtomsInit, 100) \
\
_(WasmInitBuiltinThunks, 250) \
_(WasmLazyStubsTier1, 250) \

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

@ -21,7 +21,6 @@
#include "jsmath.h"
#include "frontend/CompilationStencil.h"
#include "frontend/ParserAtom.h" // frontend::WellKnownParserAtoms
#include "gc/GC.h"
#include "gc/PublicIterators.h"
#include "jit/IonCompileTask.h"
@ -40,8 +39,7 @@
#include "vm/JSObject.h"
#include "vm/JSScript.h"
#include "vm/PromiseObject.h" // js::PromiseObject
#include "vm/SharedImmutableStringsCache.h"
#include "vm/Warnings.h" // js::WarnNumberUC
#include "vm/Warnings.h" // js::WarnNumberUC
#include "wasm/WasmSignalHandlers.h"
#include "debugger/DebugAPI-inl.h"
@ -208,6 +206,13 @@ bool JSRuntime::init(JSContext* cx, uint32_t maxbytes) {
// Also see the comment in JS::Realm::init().
js::ResetTimeZoneInternal(ResetTimeZoneMode::DontResetIfOffsetUnchanged);
if (!parentRuntime) {
sharedImmutableStrings_ = js::SharedImmutableStringsCache::Create();
if (!sharedImmutableStrings_) {
return false;
}
}
return true;
}
@ -321,6 +326,8 @@ void JSRuntime::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
rtSizes->atomsTable += mallocSizeOf(staticStrings);
rtSizes->atomsTable += mallocSizeOf(commonNames);
rtSizes->atomsTable += permanentAtoms()->sizeOfIncludingThis(mallocSizeOf);
rtSizes->atomsTable +=
commonParserNames.ref()->sizeOfIncludingThis(mallocSizeOf);
rtSizes->selfHostStencil =
selfHostStencilInput_->sizeOfIncludingThis(mallocSizeOf) +
@ -341,13 +348,9 @@ void JSRuntime::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
gc.nursery().sizeOfMallocedBuffers(mallocSizeOf);
gc.storeBuffer().addSizeOfExcludingThis(mallocSizeOf, &rtSizes->gc);
if (isMainRuntime()) {
if (sharedImmutableStrings_) {
rtSizes->sharedImmutableStringsCache +=
js::SharedImmutableStringsCache::getSingleton().sizeOfExcludingThis(
mallocSizeOf);
rtSizes->atomsTable +=
js::frontend::WellKnownParserAtoms::getSingleton().sizeOfIncludingThis(
mallocSizeOf);
sharedImmutableStrings_->sizeOfExcludingThis(mallocSizeOf);
}
#ifdef JS_HAS_INTL_API

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

@ -51,6 +51,7 @@
#include "vm/GeckoProfiler.h"
#include "vm/JSScript.h"
#include "vm/OffThreadPromiseRuntimeState.h" // js::OffThreadPromiseRuntimeState
#include "vm/SharedImmutableStringsCache.h"
#include "vm/SharedStencil.h" // js::SharedImmutableScriptDataTable
#include "vm/Stack.h"
#include "wasm/WasmTypeDecls.h"
@ -108,6 +109,7 @@ class Simulator;
namespace frontend {
struct CompilationInput;
struct CompilationStencil;
class WellKnownParserAtoms;
} // namespace frontend
// [SMDOC] JS Engine Threading
@ -783,6 +785,26 @@ struct JSRuntime {
js::WriteOnceData<const char*> numGrouping;
#endif
private:
mozilla::Maybe<js::SharedImmutableStringsCache> sharedImmutableStrings_;
public:
// If this particular JSRuntime has a SharedImmutableStringsCache, return a
// pointer to it, otherwise return nullptr.
js::SharedImmutableStringsCache* maybeThisRuntimeSharedImmutableStrings() {
return sharedImmutableStrings_.isSome() ? &*sharedImmutableStrings_
: nullptr;
}
// Get a reference to this JSRuntime's or its parent's
// SharedImmutableStringsCache.
js::SharedImmutableStringsCache& sharedImmutableStrings() {
MOZ_ASSERT_IF(parentRuntime, !sharedImmutableStrings_);
MOZ_ASSERT_IF(!parentRuntime, sharedImmutableStrings_);
return parentRuntime ? parentRuntime->sharedImmutableStrings()
: *sharedImmutableStrings_;
}
private:
js::WriteOnceData<bool> beingDestroyed_;
@ -851,6 +873,7 @@ struct JSRuntime {
// Cached pointers to various permanent property names.
js::WriteOnceData<JSAtomState*> commonNames;
js::WriteOnceData<js::frontend::WellKnownParserAtoms*> commonParserNames;
// All permanent atoms in the runtime, other than those in staticStrings.
// Access to this does not require a lock because it is frozen and thus

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

@ -14,10 +14,11 @@ namespace js {
template <typename IntoOwnedChars>
[[nodiscard]] SharedImmutableString SharedImmutableStringsCache::getOrCreate(
const char* chars, size_t length, IntoOwnedChars intoOwnedChars) {
MOZ_ASSERT(inner_);
MOZ_ASSERT(chars);
Hasher::Lookup lookup(Hasher::hashLongString(chars, length), chars, length);
auto locked = inner_.lock();
auto locked = inner_->lock();
auto entry = locked->set.lookupForAdd(lookup);
if (!entry) {
OwnedChars ownedChars(intoOwnedChars());
@ -26,7 +27,7 @@ template <typename IntoOwnedChars>
}
MOZ_ASSERT(ownedChars.get() == chars ||
memcmp(ownedChars.get(), chars, length) == 0);
auto box = StringBox::Create(std::move(ownedChars), length, &inner_);
auto box = StringBox::Create(std::move(ownedChars), length, this->inner_);
if (!box || !locked->set.add(entry, std::move(box))) {
return SharedImmutableString();
}
@ -41,12 +42,13 @@ template <typename IntoOwnedTwoByteChars>
SharedImmutableStringsCache::getOrCreate(
const char16_t* chars, size_t length,
IntoOwnedTwoByteChars intoOwnedTwoByteChars) {
MOZ_ASSERT(inner_);
MOZ_ASSERT(chars);
auto hash = Hasher::hashLongString(reinterpret_cast<const char*>(chars),
length * sizeof(char16_t));
Hasher::Lookup lookup(hash, chars, length);
auto locked = inner_.lock();
auto locked = inner_->lock();
auto entry = locked->set.lookupForAdd(lookup);
if (!entry) {
OwnedTwoByteChars ownedTwoByteChars(intoOwnedTwoByteChars());
@ -58,7 +60,7 @@ SharedImmutableStringsCache::getOrCreate(
memcmp(ownedTwoByteChars.get(), chars, length * sizeof(char16_t)) == 0);
OwnedChars ownedChars(reinterpret_cast<char*>(ownedTwoByteChars.release()));
auto box = StringBox::Create(std::move(ownedChars),
length * sizeof(char16_t), &inner_);
length * sizeof(char16_t), this->inner_);
if (!box || !locked->set.add(entry, std::move(box))) {
return SharedImmutableTwoByteString();
}

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

@ -10,9 +10,6 @@
namespace js {
/* static */
SharedImmutableStringsCache SharedImmutableStringsCache::singleton_;
SharedImmutableString::SharedImmutableString(
SharedImmutableStringsCache::StringBox* box)
: box_(box) {

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

@ -39,8 +39,6 @@ class SharedImmutableTwoByteString;
* data stored within the cache when this lock is acquired.
*/
class SharedImmutableStringsCache {
static SharedImmutableStringsCache singleton_;
friend class SharedImmutableString;
friend class SharedImmutableTwoByteString;
struct Hasher;
@ -137,10 +135,13 @@ class SharedImmutableStringsCache {
size_t length);
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
auto locked = inner_.lock();
MOZ_ASSERT(inner_);
size_t n = mallocSizeOf(inner_);
auto locked = inner_->lock();
// Size of the table.
size_t n = locked->set.shallowSizeOfExcludingThis(mallocSizeOf);
n += locked->set.shallowSizeOfExcludingThis(mallocSizeOf);
// Sizes of the strings and their boxes.
for (auto r = locked->set.all(); !r.empty(); r.popFront()) {
@ -153,29 +154,69 @@ class SharedImmutableStringsCache {
return n;
}
static SharedImmutableStringsCache& getSingleton() { return singleton_; }
/**
* Construct a new cache of shared, immutable strings. Returns
* `mozilla::Nothing` on out of memory failure.
*/
static mozilla::Maybe<SharedImmutableStringsCache> Create() {
auto inner =
js_new<ExclusiveData<Inner>>(mutexid::SharedImmutableStringsCache);
if (!inner) {
return mozilla::Nothing();
}
private:
SharedImmutableStringsCache()
: inner_(mutexid::SharedImmutableStringsCache) {}
auto locked = inner->lock();
return mozilla::Some(SharedImmutableStringsCache(locked));
}
public:
SharedImmutableStringsCache(const SharedImmutableStringsCache& rhs) = delete;
SharedImmutableStringsCache(SharedImmutableStringsCache&& rhs) = delete;
SharedImmutableStringsCache(SharedImmutableStringsCache&& rhs)
: inner_(rhs.inner_) {
MOZ_ASSERT(inner_);
rhs.inner_ = nullptr;
}
SharedImmutableStringsCache& operator=(SharedImmutableStringsCache&& rhs) =
delete;
SharedImmutableStringsCache& operator=(SharedImmutableStringsCache&& rhs) {
MOZ_ASSERT(this != &rhs, "self move not allowed");
new (this) SharedImmutableStringsCache(std::move(rhs));
return *this;
}
SharedImmutableStringsCache& operator=(const SharedImmutableStringsCache&) =
delete;
~SharedImmutableStringsCache() = default;
SharedImmutableStringsCache clone() {
MOZ_ASSERT(inner_);
auto locked = inner_->lock();
return SharedImmutableStringsCache(locked);
}
~SharedImmutableStringsCache() {
if (!inner_) {
return;
}
bool shouldDestroy = false;
{
// ~ExclusiveData takes the lock, so be sure to drop the lock before
// attempting to destroy the inner.
auto locked = inner_->lock();
MOZ_ASSERT(locked->refcount > 0);
locked->refcount--;
if (locked->refcount == 0) {
shouldDestroy = true;
}
}
if (shouldDestroy) {
js_delete(inner_);
}
}
/**
* Purge the cache of all refcount == 0 entries.
*/
void purge() {
auto locked = inner_.lock();
auto locked = inner_->lock();
MOZ_ASSERT(locked->refcount > 0);
for (Inner::Set::Enum e(locked->set); !e.empty(); e.popFront()) {
if (e.front()->refcount == 0) {
@ -290,21 +331,29 @@ class SharedImmutableStringsCache {
}
};
// The `Inner` struct contains the actual cached contents and shared between
// the `SharedImmutableStringsCache` singleton and all
// The `Inner` struct contains the actual cached contents, and is reference
// counted and shared between all `SharedImmutableStringsCache` and
// `SharedImmutable[TwoByte]String` holders.
struct Inner {
using Set = HashSet<StringBox::Ptr, Hasher, SystemAllocPolicy>;
size_t refcount;
Set set;
Inner() : set() {}
Inner() : refcount(0), set() {}
Inner(const Inner&) = delete;
Inner& operator=(const Inner&) = delete;
~Inner() { MOZ_ASSERT(refcount == 0); }
};
ExclusiveData<Inner> inner_;
const ExclusiveData<Inner>* inner_;
explicit SharedImmutableStringsCache(ExclusiveData<Inner>::Guard& locked)
: inner_(locked.parent()) {
locked->refcount++;
}
};
/**