зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1773324 - Intro OffThreadErrorContext for off-thread compilation r=arai
DummyTokenStreams created when handling RegEx should be happening at JS runtime, so on main thread (unless maybe workers?); so GeneralErrorContext is appropriate there. Differential Revision: https://phabricator.services.mozilla.com/D150644
This commit is contained in:
Родитель
7e781e6879
Коммит
442eab3d26
|
@ -342,8 +342,9 @@ bool js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res,
|
|||
static bool CheckPatternSyntaxSlow(JSContext* cx, Handle<JSAtom*> pattern,
|
||||
RegExpFlags flags) {
|
||||
LifoAllocScope allocScope(&cx->tempLifoAlloc());
|
||||
GeneralErrorContext ec(cx);
|
||||
CompileOptions options(cx);
|
||||
frontend::DummyTokenStream dummyTokenStream(cx, options);
|
||||
frontend::DummyTokenStream dummyTokenStream(cx, &ec, options);
|
||||
return irregexp::CheckPatternSyntax(cx, dummyTokenStream, pattern, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -277,6 +277,7 @@ bool ConvertRegExpData(JSContext* cx, const SmooshResult& result,
|
|||
return false;
|
||||
}
|
||||
|
||||
GeneralErrorContext ec(cx);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
SmooshRegExpItem& item = result.regexps.data[i];
|
||||
auto s = smoosh_get_slice_at(result, item.pattern);
|
||||
|
@ -314,7 +315,7 @@ bool ConvertRegExpData(JSContext* cx, const SmooshResult& result,
|
|||
|
||||
mozilla::Range<const char16_t> range(pattern.get(), length);
|
||||
|
||||
TokenStreamAnyChars ts(cx, compilationState.input.options,
|
||||
TokenStreamAnyChars ts(cx, &ec, compilationState.input.options,
|
||||
/* smg = */ nullptr);
|
||||
|
||||
// See Parser<FullParseHandler, Unit>::newRegExp.
|
||||
|
|
|
@ -162,7 +162,7 @@ ParserBase::ParserBase(JSContext* cx, ErrorContext* ec,
|
|||
const ReadOnlyCompileOptions& options,
|
||||
bool foldConstants, CompilationState& compilationState)
|
||||
: ParserSharedBase(cx, compilationState, ParserSharedBase::Kind::Parser),
|
||||
anyChars(cx, options, this),
|
||||
anyChars(cx, ec, options, this),
|
||||
ss(nullptr),
|
||||
foldConstants_(foldConstants),
|
||||
ec_(ec),
|
||||
|
|
|
@ -490,11 +490,11 @@ SourceCoords::LineToken SourceCoords::lineToken(uint32_t offset) const {
|
|||
return LineToken(indexFromOffset(offset), offset);
|
||||
}
|
||||
|
||||
TokenStreamAnyChars::TokenStreamAnyChars(JSContext* cx,
|
||||
TokenStreamAnyChars::TokenStreamAnyChars(JSContext* cx, ErrorContext* ec,
|
||||
const ReadOnlyCompileOptions& options,
|
||||
StrictModeGetter* smg)
|
||||
: cx(cx),
|
||||
ec(cx),
|
||||
ec(ec),
|
||||
options_(options),
|
||||
strictModeGetter_(smg),
|
||||
filename_(options.filename()),
|
||||
|
@ -610,7 +610,7 @@ void TokenStreamAnyChars::reportErrorNoOffsetVA(unsigned errorNumber,
|
|||
ErrorMetadata metadata;
|
||||
computeErrorMetadataNoOffset(&metadata);
|
||||
|
||||
ReportCompileErrorLatin1(&ec, cx, std::move(metadata), nullptr, errorNumber,
|
||||
ReportCompileErrorLatin1(ec, cx, std::move(metadata), nullptr, errorNumber,
|
||||
args);
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1041,7 @@ MOZ_COLD void TokenStreamChars<Utf8Unit, AnyCharsAccess>::internalEncodingError(
|
|||
break;
|
||||
}
|
||||
|
||||
ReportCompileErrorLatin1(&anyChars.ec, anyChars.cx, std::move(err),
|
||||
ReportCompileErrorLatin1(anyChars.ec, anyChars.cx, std::move(err),
|
||||
std::move(notes), errorNumber, &args);
|
||||
} while (false);
|
||||
|
||||
|
|
|
@ -562,7 +562,7 @@ class TokenStreamAnyChars : public TokenStreamShared {
|
|||
|
||||
JSContext* const cx;
|
||||
|
||||
mutable GeneralErrorContext ec;
|
||||
ErrorContext* const ec;
|
||||
|
||||
/** Options used for parsing/tokenizing. */
|
||||
const JS::ReadOnlyCompileOptions& options_;
|
||||
|
@ -721,7 +721,8 @@ class TokenStreamAnyChars : public TokenStreamShared {
|
|||
// End of fields.
|
||||
|
||||
public:
|
||||
TokenStreamAnyChars(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
|
||||
TokenStreamAnyChars(JSContext* cx, ErrorContext* ec,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
StrictModeGetter* smg);
|
||||
|
||||
template <typename Unit, class AnyCharsAccess>
|
||||
|
@ -874,7 +875,7 @@ class TokenStreamAnyChars : public TokenStreamShared {
|
|||
|
||||
char16_t* sourceMapURL() { return sourceMapURL_.get(); }
|
||||
|
||||
ErrorContext* context() const { return &ec; }
|
||||
ErrorContext* context() const { return ec; }
|
||||
JSContext* allocator() const { return cx; }
|
||||
|
||||
using LineToken = SourceCoords::LineToken;
|
||||
|
@ -2550,7 +2551,7 @@ class MOZ_STACK_CLASS TokenStreamSpecific
|
|||
private:
|
||||
// Implement ErrorReportMixin.
|
||||
|
||||
ErrorContext* getContext() const override { return &anyCharsAccess().ec; }
|
||||
ErrorContext* getContext() const override { return anyCharsAccess().ec; }
|
||||
|
||||
JSAllocator* getAllocator() const override { return anyCharsAccess().cx; }
|
||||
|
||||
|
@ -2931,18 +2932,19 @@ class MOZ_STACK_CLASS TokenStream
|
|||
using Unit = char16_t;
|
||||
|
||||
public:
|
||||
TokenStream(JSContext* cx, ParserAtomsTable* parserAtoms,
|
||||
TokenStream(JSContext* cx, ErrorContext* ec, ParserAtomsTable* parserAtoms,
|
||||
const JS::ReadOnlyCompileOptions& options, const Unit* units,
|
||||
size_t length, StrictModeGetter* smg)
|
||||
: TokenStreamAnyChars(cx, options, smg),
|
||||
: TokenStreamAnyChars(cx, ec, options, smg),
|
||||
TokenStreamSpecific<Unit, TokenStreamAnyCharsAccess>(
|
||||
cx, parserAtoms, options, units, length) {}
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS DummyTokenStream final : public TokenStream {
|
||||
public:
|
||||
DummyTokenStream(JSContext* cx, const JS::ReadOnlyCompileOptions& options)
|
||||
: TokenStream(cx, nullptr, options, nullptr, 0, nullptr) {}
|
||||
DummyTokenStream(JSContext* cx, ErrorContext* ec,
|
||||
const JS::ReadOnlyCompileOptions& options)
|
||||
: TokenStream(cx, ec, nullptr, options, nullptr, 0, nullptr) {}
|
||||
};
|
||||
|
||||
template <class TokenStreamSpecific>
|
||||
|
|
|
@ -598,8 +598,9 @@ bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re,
|
|||
FlatStringReader patternBytes(cx, pattern);
|
||||
if (!RegExpParser::ParseRegExp(cx->isolate, &zone, &patternBytes, flags,
|
||||
&data)) {
|
||||
GeneralErrorContext ec(cx);
|
||||
JS::CompileOptions options(cx);
|
||||
DummyTokenStream dummyTokenStream(cx, options);
|
||||
DummyTokenStream dummyTokenStream(cx, &ec, options);
|
||||
ReportSyntaxError(dummyTokenStream, data, pattern);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -29,26 +29,17 @@ using JS::UniqueTwoByteChars;
|
|||
|
||||
GeneralErrorContext::GeneralErrorContext(JSContext* cx) : cx_(cx) {}
|
||||
|
||||
bool GeneralErrorContext::addPendingError(CompileError** error) {
|
||||
if (cx_->isHelperThreadContext()) {
|
||||
return cx_->addPendingCompileError(error);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool GeneralErrorContext::addPendingError(CompileError** error) { return true; }
|
||||
|
||||
void GeneralErrorContext::reportError(CompileError* err) {
|
||||
// On the main thread, report the error immediately. When compiling off
|
||||
// thread, save the error so that the thread finishing the parse can report
|
||||
// it later.
|
||||
// On the main thread, report the error immediately.
|
||||
|
||||
if (MOZ_UNLIKELY(!cx_->runtime()->hasInitializedSelfHosting())) {
|
||||
selfHosting_ErrorReporter(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cx_->isHelperThreadContext()) {
|
||||
err->throwError(cx_);
|
||||
}
|
||||
err->throwError(cx_);
|
||||
}
|
||||
|
||||
void GeneralErrorContext::reportWarning(CompileError* err) {
|
||||
|
@ -57,6 +48,26 @@ void GeneralErrorContext::reportWarning(CompileError* err) {
|
|||
}
|
||||
}
|
||||
|
||||
OffThreadErrorContext::OffThreadErrorContext(JSContext* cx) : cx_(cx) {}
|
||||
|
||||
bool OffThreadErrorContext::addPendingError(CompileError** error) {
|
||||
// When compiling off thread, save the error so that the thread finishing the
|
||||
// parse can report it later.
|
||||
return cx_->addPendingCompileError(error);
|
||||
}
|
||||
|
||||
void OffThreadErrorContext::reportError(CompileError* err) {
|
||||
if (MOZ_UNLIKELY(
|
||||
!cx_->runtime()
|
||||
->hasInitializedSelfHosting())) { // TODO can SelfHosting run on
|
||||
// helper threads?
|
||||
selfHosting_ErrorReporter(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OffThreadErrorContext::reportWarning(CompileError* err) {}
|
||||
|
||||
void js::CallWarningReporter(JSContext* cx, JSErrorReport* reportp) {
|
||||
MOZ_ASSERT(reportp->isWarning());
|
||||
|
||||
|
|
|
@ -107,6 +107,19 @@ class GeneralErrorContext : public ErrorContext {
|
|||
virtual void reportWarning(js::CompileError* err) override;
|
||||
};
|
||||
|
||||
class OffThreadErrorContext : public ErrorContext {
|
||||
private:
|
||||
JSContext* cx_;
|
||||
|
||||
public:
|
||||
explicit OffThreadErrorContext(JSContext* cx);
|
||||
|
||||
bool addPendingError(js::CompileError** error) override;
|
||||
|
||||
virtual void reportError(js::CompileError* err) override;
|
||||
virtual void reportWarning(js::CompileError* err) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Report a compile error during script processing prior to execution of the
|
||||
* script.
|
||||
|
|
|
@ -722,7 +722,7 @@ void CompileToStencilTask<Unit>::parse(JSContext* cx) {
|
|||
return;
|
||||
}
|
||||
|
||||
GeneralErrorContext ec(cx); // TODO helper thread ErrorContext
|
||||
OffThreadErrorContext ec(cx);
|
||||
js::LifoAlloc tempLifoAlloc(JSContext::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
|
||||
stencil_ = frontend::CompileGlobalScriptToStencil(
|
||||
cx, &ec, tempLifoAlloc, *stencilInput_, data, scopeKind);
|
||||
|
|
|
@ -206,8 +206,9 @@ RegExpObject* RegExpObject::createSyntaxChecked(JSContext* cx,
|
|||
|
||||
RegExpObject* RegExpObject::create(JSContext* cx, Handle<JSAtom*> source,
|
||||
RegExpFlags flags, NewObjectKind newKind) {
|
||||
GeneralErrorContext ec(cx);
|
||||
CompileOptions dummyOptions(cx);
|
||||
frontend::DummyTokenStream dummyTokenStream(cx, dummyOptions);
|
||||
frontend::DummyTokenStream dummyTokenStream(cx, &ec, dummyOptions);
|
||||
|
||||
LifoAllocScope allocScope(&cx->tempLifoAlloc());
|
||||
if (!irregexp::CheckPatternSyntax(cx, dummyTokenStream, source, flags)) {
|
||||
|
@ -1231,8 +1232,9 @@ JS_PUBLIC_API bool JS::CheckRegExpSyntax(JSContext* cx, const char16_t* chars,
|
|||
AssertHeapIsIdle();
|
||||
CHECK_THREAD(cx);
|
||||
|
||||
GeneralErrorContext ec(cx);
|
||||
CompileOptions dummyOptions(cx);
|
||||
frontend::DummyTokenStream dummyTokenStream(cx, dummyOptions);
|
||||
frontend::DummyTokenStream dummyTokenStream(cx, &ec, dummyOptions);
|
||||
|
||||
LifoAllocScope allocScope(&cx->tempLifoAlloc());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче