Bug 1773324 - Support pending errors in OffThreadErrorContext r=arai

I could get rid of OffThreadErrorContext::cx_ by subclassing from
MallocProvider, but I don't think that would work since
OffThreadErrorContext has a vtable and MallocProvider does a
static_cast to get the client pointer.

OffThreadFrontendErrors moved to ErrorContext.h to avoid
recursive header inclusion.

Differential Revision: https://phabricator.services.mozilla.com/D150645
This commit is contained in:
Bryan Thrall 2022-07-25 18:57:32 +00:00
Родитель 242e75b195
Коммит 7334acea14
14 изменённых файлов: 111 добавлений и 53 удалений

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

@ -9,6 +9,7 @@
#include "mozilla/Atomics.h"
#include "mozilla/Casting.h"
#include "mozilla/FloatingPoint.h"
#include "vm/ErrorContext.h"
#ifdef JS_HAS_INTL_API
# include "mozilla/intl/ICU4CLibrary.h"
# include "mozilla/intl/Locale.h"

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

@ -53,6 +53,7 @@
#include "vm/BytecodeUtil.h" // for JSDVG_SEARCH_STACK
#include "vm/Compartment.h" // for Compartment
#include "vm/EnvironmentObject.h" // for IsGlobalLexicalEnvironment
#include "vm/ErrorContext.h" // for GeneralErrorContext
#include "vm/GeneratorObject.h" // for AbstractGeneratorObject
#include "vm/GlobalObject.h" // for GlobalObject
#include "vm/Interpreter.h" // for Call, ExecuteKernel

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

@ -17,6 +17,7 @@
#include "frontend/BytecodeEmitter.h"
#include "frontend/EitherParser.h"
#include "frontend/ErrorReporter.h"
#include "vm/ErrorContext.h"
#include "vm/ErrorReporting.h"
#ifdef JS_ENABLE_SMOOSH
# include "frontend/Frontend2.h" // Smoosh

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

@ -36,6 +36,7 @@
#include "vm/BigIntType.h" // ParseBigIntLiteral, BigIntLiteralIsZero
#include "vm/BindingKind.h" // BindingKind
#include "vm/EnvironmentObject.h"
#include "vm/ErrorContext.h"
#include "vm/GeneratorAndAsyncKind.h" // GeneratorKind, FunctionAsyncKind
#include "vm/HelperThreads.h" // js::StartOffThreadParseScript
#include "vm/HelperThreadState.h"

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

@ -211,6 +211,7 @@
#include "js/UniquePtr.h"
#include "js/Vector.h"
#include "util/Unicode.h"
#include "vm/ErrorContext.h"
#include "vm/ErrorReporting.h"
struct JS_PUBLIC_API JSContext;

66
js/src/vm/ErrorContext.h Normal file
Просмотреть файл

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef vm_ErrorContext_h
#define vm_ErrorContext_h
#include "vm/ErrorReporting.h"
namespace js {
struct OffThreadFrontendErrors {
OffThreadFrontendErrors() : overRecursed(false), outOfMemory(false) {}
// Any errors or warnings produced during compilation. These are reported
// when finishing the script.
Vector<UniquePtr<CompileError>, 0, SystemAllocPolicy> errors;
bool overRecursed;
bool outOfMemory;
};
class ErrorContext {
public:
virtual ~ErrorContext() = default;
virtual bool addPendingError(js::CompileError** error) = 0;
virtual void reportError(js::CompileError* err) = 0;
virtual void reportWarning(js::CompileError* err) = 0;
};
class GeneralErrorContext : public ErrorContext {
private:
JSContext* cx_;
public:
explicit GeneralErrorContext(JSContext* cx);
bool addPendingError(js::CompileError** error) override;
virtual void reportError(js::CompileError* err) override;
virtual void reportWarning(js::CompileError* err) override;
};
class OffThreadErrorContext : public ErrorContext {
private:
JSAllocator* alloc_;
js::OffThreadFrontendErrors errors_;
public:
explicit OffThreadErrorContext(JSAllocator* alloc);
bool addPendingError(js::CompileError** error) override;
virtual void reportError(js::CompileError* err) override;
virtual void reportWarning(js::CompileError* err) override;
void ReportOutOfMemory();
void addPendingOutOfMemory();
void setAllocator(JSAllocator* alloc) { alloc_ = alloc; }
};
} // namespace js
#endif /* vm_ErrorContext_h */

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

@ -15,6 +15,7 @@
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/Printf.h" // JS_vsmprintf
#include "js/Warnings.h" // JS::WarningReporter
#include "vm/ErrorContext.h" // GeneralErrorContext, OffThreadErrorContext
#include "vm/GlobalObject.h"
#include "vm/JSContext.h"
#include "vm/SelfHosting.h" // selfHosting_ErrorReporter
@ -48,26 +49,48 @@ void GeneralErrorContext::reportWarning(CompileError* err) {
}
}
OffThreadErrorContext::OffThreadErrorContext(JSContext* cx) : cx_(cx) {}
OffThreadErrorContext::OffThreadErrorContext(JSAllocator* alloc)
: alloc_(alloc) {}
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);
auto errorPtr = alloc_->make_unique<js::CompileError>();
if (!errorPtr) {
return false;
}
if (!errors_.errors.append(std::move(errorPtr))) {
ReportOutOfMemory();
return false;
}
*error = errors_.errors.back().get();
return true;
}
void OffThreadErrorContext::reportError(CompileError* err) {
if (MOZ_UNLIKELY(
!cx_->runtime()
->hasInitializedSelfHosting())) { // TODO can SelfHosting run on
// helper threads?
selfHosting_ErrorReporter(err);
return;
}
// TODO Bug 1773324 - restore selfHosting_ErrorReporter if needed
}
void OffThreadErrorContext::reportWarning(CompileError* err) {}
void OffThreadErrorContext::ReportOutOfMemory() {
/*
* OOMs are non-deterministic, especially across different execution modes
* (e.g. interpreter vs JIT). When doing differential testing, print to
* stderr so that the fuzzers can detect this.
*/
if (js::SupportDifferentialTesting()) {
fprintf(stderr, "ReportOutOfMemory called\n");
}
return addPendingOutOfMemory();
}
void OffThreadErrorContext::addPendingOutOfMemory() {
// Keep in sync with recoverFromOutOfMemory.
errors_.outOfMemory = true;
}
void js::CallWarningReporter(JSContext* cx, JSErrorReport* reportp) {
MOZ_ASSERT(reportp->isWarning());

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

@ -18,6 +18,8 @@
namespace js {
class ErrorContext;
/**
* Use this type instead of JSContext when the object is only used for its
* ability to allocate memory (via its MallocProvider methods).
@ -85,41 +87,6 @@ class MOZ_STACK_CLASS ReportExceptionClosure final
/** Send a JSErrorReport to the warningReporter callback. */
extern void CallWarningReporter(JSContext* cx, JSErrorReport* report);
class ErrorContext {
public:
virtual ~ErrorContext() = default;
virtual bool addPendingError(js::CompileError** error) = 0;
virtual void reportError(js::CompileError* err) = 0;
virtual void reportWarning(js::CompileError* err) = 0;
};
class GeneralErrorContext : public ErrorContext {
private:
JSContext* cx_;
public:
explicit GeneralErrorContext(JSContext* cx);
bool addPendingError(js::CompileError** error) override;
virtual void reportError(js::CompileError* err) override;
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.

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

@ -27,6 +27,7 @@
#include "js/TypeDecls.h"
#include "threading/ConditionVariable.h"
#include "threading/Thread.h"
#include "vm/ErrorContext.h"
#include "vm/HelperThreads.h"
#include "vm/HelperThreadTask.h"
#include "vm/JSContext.h"
@ -522,15 +523,6 @@ struct MOZ_RAII AutoSetContextRuntime {
~AutoSetContextRuntime() { TlsContext.get()->setRuntime(nullptr); }
};
struct OffThreadFrontendErrors {
OffThreadFrontendErrors() : overRecursed(false), outOfMemory(false) {}
// Any errors or warnings produced during compilation. These are reported
// when finishing the script.
Vector<UniquePtr<CompileError>, 0, SystemAllocPolicy> errors;
bool overRecursed;
bool outOfMemory;
};
struct ParseTask : public mozilla::LinkedListElement<ParseTask>,
public JS::OffThreadToken,
public HelperThreadTask {

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

@ -33,6 +33,7 @@
#include "js/Utility.h"
#include "threading/CpuCount.h"
#include "util/NativeStack.h"
#include "vm/ErrorContext.h"
#include "vm/ErrorReporting.h"
#include "vm/HelperThreadState.h"
#include "vm/InternalThreadPool.h"

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

@ -56,6 +56,7 @@
#include "util/Text.h"
#include "util/WindowsWrapper.h"
#include "vm/BytecodeUtil.h" // JSDVG_IGNORE_STACK
#include "vm/ErrorContext.h"
#include "vm/ErrorObject.h"
#include "vm/ErrorReporting.h"
#include "vm/HelperThreadState.h"

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

@ -23,6 +23,7 @@
#include "js/RootingAPI.h" // JS::MutableHandle
#include "js/Value.h" // JS::Value
#include "vm/EnvironmentObject.h" // js::ModuleEnvironmentObject
#include "vm/ErrorContext.h" // js::GeneralErrorContext
#include "vm/JSContext.h" // CHECK_THREAD, JSContext
#include "vm/JSObject.h" // JSObject
#include "vm/Runtime.h" // JSRuntime

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

@ -24,6 +24,7 @@
#include "builtin/Array.h"
#include "builtin/BigInt.h"
#include "vm/ErrorContext.h"
#ifdef JS_HAS_INTL_API
# include "builtin/intl/Collator.h"
# include "builtin/intl/DateTimeFormat.h"

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

@ -50,6 +50,7 @@
#include "util/DifferentialTesting.h"
#include "util/StringBuffer.h"
#include "util/Text.h"
#include "vm/ErrorContext.h"
#include "vm/ErrorReporting.h"
#include "vm/FunctionFlags.h" // js::FunctionFlags
#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind