Bug 1388756 - Move helper thread types out of the OOM namespace. r=jonco

--HG--
extra : rebase_source : 2ec28160c41db48b2fa043f3d36e75d32832b26f
extra : histedit_source : d93bebede5edd065bb0cbcdebc509bbe3ab26d1c
This commit is contained in:
Lars T Hansen 2017-08-11 10:11:35 +02:00
parent 38b8fb111d
commit b0a78cb977
7 changed files with 50 additions and 44 deletions

View File

@ -49,13 +49,11 @@ JS_Assert(const char* s, const char* file, int ln);
#else
namespace js {
namespace oom {
/*
* To make testing OOM in certain helper threads more effective,
* allow restricting the OOM testing to a certain helper thread
* type. This allows us to fail e.g. in off-thread script parsing
* without causing an OOM in the active thread first.
* Thread types are used to tag threads for certain kinds of testing (see
* below), and also used to characterize threads in the thread scheduler (see
* js/src/vm/HelperThreads.cpp).
*/
enum ThreadType {
THREAD_TYPE_NONE = 0, // 0
@ -71,9 +69,16 @@ enum ThreadType {
THREAD_TYPE_MAX // Used to check shell function arguments
};
namespace oom {
/*
* Getter/Setter functions to encapsulate mozilla::ThreadLocal,
* implementation is in jsutil.cpp.
* Theads are tagged only in certain debug contexts. Notably, to make testing
* OOM in certain helper threads more effective, we allow restricting the OOM
* testing to a certain helper thread type. This allows us to fail e.g. in
* off-thread script parsing without causing an OOM in the active thread first.
*
* Getter/Setter functions to encapsulate mozilla::ThreadLocal, implementation
* is in jsutil.cpp.
*/
# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
extern bool InitThreadType(void);

View File

@ -1369,7 +1369,7 @@ static bool
OOMThreadTypes(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setInt32(js::oom::THREAD_TYPE_MAX);
args.rval().setInt32(js::THREAD_TYPE_MAX);
return true;
}
@ -1402,11 +1402,11 @@ SetupOOMFailure(JSContext* cx, bool failAlways, unsigned argc, Value* vp)
return false;
}
uint32_t targetThread = js::oom::THREAD_TYPE_COOPERATING;
uint32_t targetThread = js::THREAD_TYPE_COOPERATING;
if (args.length() > 1 && !ToUint32(cx, args[1], &targetThread))
return false;
if (targetThread == js::oom::THREAD_TYPE_NONE || targetThread >= js::oom::THREAD_TYPE_MAX) {
if (targetThread == js::THREAD_TYPE_NONE || targetThread >= js::THREAD_TYPE_MAX) {
JS_ReportErrorASCII(cx, "Invalid thread type specified");
return false;
}
@ -1486,13 +1486,13 @@ OOMTest(JSContext* cx, unsigned argc, Value* vp)
bool verbose = EnvVarIsDefined("OOM_VERBOSE");
unsigned threadStart = oom::THREAD_TYPE_COOPERATING;
unsigned threadEnd = oom::THREAD_TYPE_MAX;
unsigned threadStart = THREAD_TYPE_COOPERATING;
unsigned threadEnd = THREAD_TYPE_MAX;
// Test a single thread type if specified by the OOM_THREAD environment variable.
int threadOption = 0;
if (EnvVarAsInt("OOM_THREAD", &threadOption)) {
if (threadOption < oom::THREAD_TYPE_COOPERATING || threadOption > oom::THREAD_TYPE_MAX) {
if (threadOption < THREAD_TYPE_COOPERATING || threadOption > THREAD_TYPE_MAX) {
JS_ReportErrorASCII(cx, "OOM_THREAD value out of range.");
return false;
}

View File

@ -381,7 +381,7 @@ BEGIN_TEST(testHashMapLookupWithDefaultOOM)
{
uint32_t timeToFail;
for (timeToFail = 1; timeToFail < 1000; timeToFail++) {
js::oom::SimulateOOMAfter(timeToFail, js::oom::THREAD_TYPE_COOPERATING, false);
js::oom::SimulateOOMAfter(timeToFail, js::THREAD_TYPE_COOPERATING, false);
LookupWithDefaultUntilResize();
}

View File

@ -36,7 +36,7 @@ const uint32_t maxAllocsPerTest = 100;
testName = name; \
printf("Test %s: started\n", testName); \
for (oomAfter = 1; oomAfter < maxAllocsPerTest; ++oomAfter) { \
js::oom::SimulateOOMAfter(oomAfter, js::oom::THREAD_TYPE_COOPERATING, true)
js::oom::SimulateOOMAfter(oomAfter, js::THREAD_TYPE_COOPERATING, true)
#define OOM_TEST_FINISHED \
{ \

View File

@ -62,7 +62,7 @@ GetThreadType(void) {
void
SimulateOOMAfter(uint64_t allocations, uint32_t thread, bool always) {
MOZ_ASSERT(counter + allocations > counter);
MOZ_ASSERT(thread > js::oom::THREAD_TYPE_NONE && thread < js::oom::THREAD_TYPE_MAX);
MOZ_ASSERT(thread > js::THREAD_TYPE_NONE && thread < js::THREAD_TYPE_MAX);
targetThread = thread;
maxAllocations = counter + allocations;
failAlways = always;

View File

@ -16,6 +16,7 @@
#include "frontend/BytecodeCompiler.h"
#include "gc/GCInternals.h"
#include "jit/IonBuilder.h"
#include "js/Utility.h"
#include "threading/CpuCount.h"
#include "vm/Debugger.h"
#include "vm/ErrorReporting.h"
@ -1027,7 +1028,7 @@ struct MOZ_RAII AutoSetContextRuntime
};
static inline bool
IsHelperThreadSimulatingOOM(js::oom::ThreadType threadType)
IsHelperThreadSimulatingOOM(js::ThreadType threadType)
{
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
return js::oom::targetThread == threadType;
@ -1039,7 +1040,7 @@ IsHelperThreadSimulatingOOM(js::oom::ThreadType threadType)
size_t
GlobalHelperThreadState::maxIonCompilationThreads() const
{
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_ION))
if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_ION))
return 1;
return threadCount;
}
@ -1053,7 +1054,7 @@ GlobalHelperThreadState::maxUnpausedIonCompilationThreads() const
size_t
GlobalHelperThreadState::maxWasmCompilationThreads() const
{
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_WASM))
if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_WASM))
return 1;
return cpuCount;
}
@ -1061,7 +1062,7 @@ GlobalHelperThreadState::maxWasmCompilationThreads() const
size_t
GlobalHelperThreadState::maxParseThreads() const
{
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_PARSE))
if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_PARSE))
return 1;
// Don't allow simultaneous off thread parses, to reduce contention on the
@ -1074,7 +1075,7 @@ GlobalHelperThreadState::maxParseThreads() const
size_t
GlobalHelperThreadState::maxCompressionThreads() const
{
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_COMPRESS))
if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_COMPRESS))
return 1;
// Compression is triggered on major GCs to compress ScriptSources. It is
@ -1085,7 +1086,7 @@ GlobalHelperThreadState::maxCompressionThreads() const
size_t
GlobalHelperThreadState::maxGCHelperThreads() const
{
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_GCHELPER))
if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_GCHELPER))
return 1;
return threadCount;
}
@ -1093,7 +1094,7 @@ GlobalHelperThreadState::maxGCHelperThreads() const
size_t
GlobalHelperThreadState::maxGCParallelThreads() const
{
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_GCPARALLEL))
if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_GCPARALLEL))
return 1;
return threadCount;
}
@ -2182,7 +2183,7 @@ HelperThread::threadLoop()
while (true) {
MOZ_ASSERT(idle());
js::oom::ThreadType task;
js::ThreadType task;
while (true) {
if (terminate)
return;
@ -2197,25 +2198,25 @@ HelperThread::threadLoop()
// and execution is not well-defined.
if (HelperThreadState().canStartGCParallelTask(lock))
task = js::oom::THREAD_TYPE_GCPARALLEL;
task = js::THREAD_TYPE_GCPARALLEL;
else if (HelperThreadState().canStartGCHelperTask(lock))
task = js::oom::THREAD_TYPE_GCHELPER;
task = js::THREAD_TYPE_GCHELPER;
else if (HelperThreadState().pendingIonCompileHasSufficientPriority(lock))
task = js::oom::THREAD_TYPE_ION;
task = js::THREAD_TYPE_ION;
else if (HelperThreadState().canStartWasmCompile(lock))
task = js::oom::THREAD_TYPE_WASM;
task = js::THREAD_TYPE_WASM;
else if (HelperThreadState().canStartPromiseTask(lock))
task = js::oom::THREAD_TYPE_PROMISE_TASK;
task = js::THREAD_TYPE_PROMISE_TASK;
else if (HelperThreadState().canStartParseTask(lock))
task = js::oom::THREAD_TYPE_PARSE;
task = js::THREAD_TYPE_PARSE;
else if (HelperThreadState().canStartCompressionTask(lock))
task = js::oom::THREAD_TYPE_COMPRESS;
task = js::THREAD_TYPE_COMPRESS;
else if (HelperThreadState().canStartIonFreeTask(lock))
task = js::oom::THREAD_TYPE_ION_FREE;
task = js::THREAD_TYPE_ION_FREE;
else
task = js::oom::THREAD_TYPE_NONE;
task = js::THREAD_TYPE_NONE;
if (task != js::oom::THREAD_TYPE_NONE)
if (task != js::THREAD_TYPE_NONE)
break;
HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
@ -2223,33 +2224,33 @@ HelperThread::threadLoop()
js::oom::SetThreadType(task);
switch (task) {
case js::oom::THREAD_TYPE_GCPARALLEL:
case js::THREAD_TYPE_GCPARALLEL:
handleGCParallelWorkload(lock);
break;
case js::oom::THREAD_TYPE_GCHELPER:
case js::THREAD_TYPE_GCHELPER:
handleGCHelperWorkload(lock);
break;
case js::oom::THREAD_TYPE_ION:
case js::THREAD_TYPE_ION:
handleIonWorkload(lock);
break;
case js::oom::THREAD_TYPE_WASM:
case js::THREAD_TYPE_WASM:
handleWasmWorkload(lock);
break;
case js::oom::THREAD_TYPE_PROMISE_TASK:
case js::THREAD_TYPE_PROMISE_TASK:
handlePromiseTaskWorkload(lock);
break;
case js::oom::THREAD_TYPE_PARSE:
case js::THREAD_TYPE_PARSE:
handleParseWorkload(lock);
break;
case js::oom::THREAD_TYPE_COMPRESS:
case js::THREAD_TYPE_COMPRESS:
handleCompressionWorkload(lock);
break;
case js::oom::THREAD_TYPE_ION_FREE:
case js::THREAD_TYPE_ION_FREE:
handleIonFreeWorkload(lock);
break;
default:
MOZ_CRASH("No task to perform");
}
js::oom::SetThreadType(js::oom::THREAD_TYPE_NONE);
js::oom::SetThreadType(js::THREAD_TYPE_NONE);
}
}

View File

@ -98,7 +98,7 @@ JS::detail::InitWithFailureDiagnostic(bool isDebugBuild)
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
RETURN_IF_FAIL(js::oom::InitThreadType());
js::oom::SetThreadType(js::oom::THREAD_TYPE_COOPERATING);
js::oom::SetThreadType(js::THREAD_TYPE_COOPERATING);
#endif
RETURN_IF_FAIL(js::Mutex::Init());