зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1838771 - Assert the thread matches between JS::SetNativeStackQuota call and JS::CompileGlobalScriptToStencil for JS::FrontendContext. r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D181201
This commit is contained in:
Родитель
446a595eeb
Коммит
c1cdda9cde
|
@ -125,8 +125,10 @@ oddly_ordered_inclnames = set(
|
|||
"gc/StatsPhasesGenerated.inc", # Included in the body of gc/Statistics.cpp
|
||||
"psapi.h", # Must be included after "util/WindowsWrapper.h" on Windows
|
||||
"machine/endian.h", # Must be included after <sys/types.h> on BSD
|
||||
"process.h", # Windows-specific
|
||||
"winbase.h", # Must precede other system headers(?)
|
||||
"windef.h", # Must precede other system headers(?)
|
||||
"windows.h", # Must precede other system headers(?)
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ JS_PUBLIC_API JS::FrontendContext* NewFrontendContext();
|
|||
// Destroy a front-end context allocated with NewFrontendContext.
|
||||
JS_PUBLIC_API void DestroyFrontendContext(JS::FrontendContext* fc);
|
||||
|
||||
// Set the size of the native stack that should not be exceed. To disable
|
||||
// stack size checking pass 0.
|
||||
//
|
||||
// WARNING: When the stack size checking is enabled, the JS::FrontendContext
|
||||
// can be used only in the thread where JS::SetNativeStackQuota is called.
|
||||
JS_PUBLIC_API void SetNativeStackQuota(JS::FrontendContext* fc,
|
||||
JS::NativeStackSize stackSize);
|
||||
|
||||
|
|
|
@ -154,12 +154,18 @@ already_AddRefed<JS::Stencil> JS::CompileGlobalScriptToStencil(
|
|||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
JS::CompilationStorage& compileStorage) {
|
||||
#ifdef DEBUG
|
||||
fc->assertNativeStackLimitThread();
|
||||
#endif
|
||||
return CompileGlobalScriptToStencilImpl(fc, options, srcBuf, compileStorage);
|
||||
}
|
||||
|
||||
already_AddRefed<JS::Stencil> JS::CompileGlobalScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::SourceText<char16_t>& srcBuf, JS::CompilationStorage& compileStorage) {
|
||||
#ifdef DEBUG
|
||||
fc->assertNativeStackLimitThread();
|
||||
#endif
|
||||
return CompileGlobalScriptToStencilImpl(fc, options, srcBuf, compileStorage);
|
||||
}
|
||||
|
||||
|
@ -167,6 +173,9 @@ already_AddRefed<JS::Stencil> JS::CompileModuleScriptToStencil(
|
|||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& optionsInput,
|
||||
JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
JS::CompilationStorage& compileStorage) {
|
||||
#ifdef DEBUG
|
||||
fc->assertNativeStackLimitThread();
|
||||
#endif
|
||||
return CompileModuleScriptToStencilImpl(fc, optionsInput, srcBuf,
|
||||
compileStorage);
|
||||
}
|
||||
|
@ -174,6 +183,9 @@ already_AddRefed<JS::Stencil> JS::CompileModuleScriptToStencil(
|
|||
already_AddRefed<JS::Stencil> JS::CompileModuleScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& optionsInput,
|
||||
JS::SourceText<char16_t>& srcBuf, JS::CompilationStorage& compileStorage) {
|
||||
#ifdef DEBUG
|
||||
fc->assertNativeStackLimitThread();
|
||||
#endif
|
||||
return CompileModuleScriptToStencilImpl(fc, optionsInput, srcBuf,
|
||||
compileStorage);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
|
||||
#include "frontend/FrontendContext.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <process.h> // GetCurrentThreadId
|
||||
#else
|
||||
# include <pthread.h> // pthread_self
|
||||
#endif
|
||||
|
||||
#include "gc/GC.h"
|
||||
#include "js/AllocPolicy.h" // js::ReportOutOfMemory
|
||||
#include "js/friend/StackLimits.h" // js::ReportOverRecursed
|
||||
|
@ -61,6 +68,10 @@ void FrontendContext::setStackQuota(JS::NativeStackSize stackSize) {
|
|||
stackLimit_ = JS::GetNativeStackLimit(GetNativeStackBase(), stackSize - 1);
|
||||
}
|
||||
#endif // !__wasi__
|
||||
|
||||
#ifdef DEBUG
|
||||
setNativeStackLimitThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FrontendContext::allocateOwnedPool() {
|
||||
|
@ -164,6 +175,10 @@ void FrontendContext::setCurrentJSContext(JSContext* cx) {
|
|||
nameCollectionPool_ = &cx->frontendCollectionPool();
|
||||
scriptDataTableHolder_ = &cx->runtime()->scriptDataTableHolder();
|
||||
stackLimit_ = cx->stackLimitForCurrentPrincipal();
|
||||
|
||||
#ifdef DEBUG
|
||||
setNativeStackLimitThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FrontendContext::convertToRuntimeError(
|
||||
|
@ -196,6 +211,28 @@ void FrontendContext::linkWithJSContext(JSContext* cx) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static size_t GetTid() {
|
||||
# if defined(_WIN32)
|
||||
return size_t(GetCurrentThreadId());
|
||||
# else
|
||||
return size_t(pthread_self());
|
||||
# endif
|
||||
}
|
||||
|
||||
void FrontendContext::setNativeStackLimitThread() {
|
||||
stackLimitThreadId_.emplace(GetTid());
|
||||
}
|
||||
|
||||
void FrontendContext::assertNativeStackLimitThread() {
|
||||
if (!stackLimitThreadId_.isSome()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(*stackLimitThreadId_ == GetTid());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __wasi__
|
||||
void FrontendContext::incWasiRecursionDepth() {
|
||||
if (maybeCx_) {
|
||||
|
|
|
@ -76,8 +76,22 @@ class FrontendContext {
|
|||
|
||||
JS::ImportAssertionVector supportedImportAssertions_;
|
||||
|
||||
// Limit pointer for checking native stack consumption.
|
||||
//
|
||||
// The pointer is calculated based on the stack base of the current thread
|
||||
// except for JS::NativeStackLimitMax. Once such value is set, this
|
||||
// FrontendContext can be used only in the thread.
|
||||
//
|
||||
// In order to enforce this thread rule, setNativeStackLimitThread should
|
||||
// be called when setting the value, and assertNativeStackLimitThread should
|
||||
// be called at each entry-point that might make use of this field.
|
||||
JS::NativeStackLimit stackLimit_ = JS::NativeStackLimitMax;
|
||||
|
||||
#ifdef DEBUG
|
||||
// The thread ID where the native stack limit is set.
|
||||
mozilla::Maybe<size_t> stackLimitThreadId_;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// (optional) Current JSContext to support main-thread-specific
|
||||
// handling for error reporting, GC, and memory allocation.
|
||||
|
@ -177,6 +191,11 @@ class FrontendContext {
|
|||
bool checkWasiRecursionLimit();
|
||||
#endif // __wasi__
|
||||
|
||||
#ifdef DEBUG
|
||||
void setNativeStackLimitThread();
|
||||
void assertNativeStackLimitThread();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void ReportOutOfMemory();
|
||||
void addPendingOutOfMemory();
|
||||
|
|
Загрузка…
Ссылка в новой задаче