Commit 2f5d90a8 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[d8] Add a stress-background-compile mode

Adds a stress-background-compile mode which runs compilation on a background
thread at the same time as compiling on the main thread to flush out races.
This is added as one of the variants, removing stress_asm_validation since this
is no longer a useful variant.

BUG=v8:5203

Change-Id: I73dd9f21d9b6da4a4cb39c05061aa24116e6c5ad
Reviewed-on: https://chromium-review.googlesource.com/741746
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarSergiy Byelozyorov <sergiyb@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49376}
parent 69f897d5
......@@ -285,6 +285,13 @@ Worker* GetWorkerFromInternalField(Isolate* isolate, Local<Object> object) {
return worker;
}
base::Thread::Options GetThreadOptions(const char* name) {
// On some systems (OSX 10.6) the stack size default is 0.5Mb or less
// which is not enough to parse the big literal expressions used in tests.
// The stack size should be at least StackGuard::kLimitSize + some
// OS-specific padding for thread startup code. 2Mbytes seems to be enough.
return base::Thread::Options(name, 2 * MB);
}
} // namespace
......@@ -501,6 +508,53 @@ bool CounterMap::Match(void* key1, void* key2) {
return strcmp(name1, name2) == 0;
}
// Dummy external source stream which returns the whole source in one go.
class DummySourceStream : public v8::ScriptCompiler::ExternalSourceStream {
public:
explicit DummySourceStream(Local<String> source) : done_(false) {
source_length_ = source->Utf8Length();
source_buffer_.reset(new uint8_t[source_length_]);
source->WriteUtf8(reinterpret_cast<char*>(source_buffer_.get()),
source_length_);
}
virtual size_t GetMoreData(const uint8_t** src) {
if (done_) {
return 0;
}
*src = source_buffer_.release();
done_ = true;
return source_length_;
}
private:
int source_length_;
std::unique_ptr<uint8_t[]> source_buffer_;
bool done_;
};
class BackgroundCompileThread : public base::Thread {
public:
BackgroundCompileThread(Isolate* isolate, Local<String> source)
: base::Thread(GetThreadOptions("BackgroundCompileThread")),
source_(source),
streamed_source_(new DummySourceStream(source),
v8::ScriptCompiler::StreamedSource::UTF8),
task_(v8::ScriptCompiler::StartStreamingScript(isolate,
&streamed_source_)) {}
void Run() override { task_->Run(); }
v8::ScriptCompiler::StreamedSource* streamed_source() {
return &streamed_source_;
}
private:
Local<String> source_;
v8::ScriptCompiler::StreamedSource streamed_source_;
std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task_;
};
ScriptCompiler::CachedData* CompileForCachedData(
Local<String> source, Local<Value> name,
......@@ -606,13 +660,36 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Context> realm =
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm);
MaybeLocal<Script> maybe_script;
if (options.stress_background_compile) {
// Start a background thread compiling the script.
BackgroundCompileThread background_compile_thread(isolate, source);
background_compile_thread.Start();
// In parallel, compile on the main thread to flush out any data races.
{
TryCatch ignore_try_catch(isolate);
Shell::CompileString(isolate, source, name, options.compile_options);
}
// Join with background thread and finalize compilation.
background_compile_thread.Join();
ScriptOrigin origin(name);
maybe_script = v8::ScriptCompiler::Compile(
isolate->GetCurrentContext(),
background_compile_thread.streamed_source(), source, origin);
} else {
maybe_script =
Shell::CompileString(isolate, source, name, options.compile_options);
}
Local<Script> script;
if (!Shell::CompileString(isolate, source, name, options.compile_options)
.ToLocal(&script)) {
if (!maybe_script.ToLocal(&script)) {
// Print errors that happened during compilation.
if (report_exceptions) ReportException(isolate, &try_catch);
return false;
}
maybe_result = script->Run(realm);
if (!EmptyMessageQueues(isolate)) success = false;
data->realm_current_ = data->realm_switch_;
......@@ -2442,14 +2519,8 @@ Local<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) {
return Shell::ReadFile(isolate, name);
}
base::Thread::Options SourceGroup::GetThreadOptions() {
// On some systems (OSX 10.6) the stack size default is 0.5Mb or less
// which is not enough to parse the big literal expressions used in tests.
// The stack size should be at least StackGuard::kLimitSize + some
// OS-specific padding for thread startup code. 2Mbytes seems to be enough.
return base::Thread::Options("IsolateThread", 2 * MB);
}
SourceGroup::IsolateThread::IsolateThread(SourceGroup* group)
: base::Thread(GetThreadOptions("IsolateThread")), group_(group) {}
void SourceGroup::ExecuteInThread() {
Isolate::CreateParams create_params;
......@@ -2720,6 +2791,13 @@ bool Shell::SetOptions(int argc, char* argv[]) {
} else if (strcmp(argv[i], "--stress-deopt") == 0) {
options.stress_deopt = true;
argv[i] = nullptr;
} else if (strcmp(argv[i], "--stress-background-compile") == 0) {
options.stress_background_compile = true;
argv[i] = nullptr;
} else if (strcmp(argv[i], "--nostress-background-compile") == 0 ||
strcmp(argv[i], "--no-stress-background-compile") == 0) {
options.stress_background_compile = false;
argv[i] = nullptr;
} else if (strcmp(argv[i], "--mock-arraybuffer-allocator") == 0) {
options.mock_arraybuffer_allocator = true;
argv[i] = nullptr;
......
......@@ -120,8 +120,7 @@ class SourceGroup {
private:
class IsolateThread : public base::Thread {
public:
explicit IsolateThread(SourceGroup* group)
: base::Thread(GetThreadOptions()), group_(group) {}
explicit IsolateThread(SourceGroup* group);
virtual void Run() {
group_->ExecuteInThread();
......@@ -131,7 +130,6 @@ class SourceGroup {
SourceGroup* group_;
};
static base::Thread::Options GetThreadOptions();
void ExecuteInThread();
base::Semaphore next_semaphore_;
......@@ -297,6 +295,7 @@ class ShellOptions {
enable_inspector(false),
num_isolates(1),
compile_options(v8::ScriptCompiler::kNoCompileOptions),
stress_background_compile(false),
isolate_sources(nullptr),
icu_data_file(nullptr),
natives_blob(nullptr),
......@@ -329,6 +328,7 @@ class ShellOptions {
bool enable_inspector;
int num_isolates;
v8::ScriptCompiler::CompileOptions compile_options;
bool stress_background_compile;
SourceGroup* isolate_sources;
const char* icu_data_file;
const char* natives_blob;
......
......@@ -28,10 +28,11 @@
// Flags: --expose-gc --send-idle-notification
// Flags: --expose-natives-as natives
// Flags: --noharmony-shipping
// Flags: --nostress-opt
// Flags: --nostress-opt --nostress-background-compile
// --nostress-opt is specified because in stress mode the compilation cache
// may hold on to old copies of scripts (see bug 1641).
// --nostress-opt and --nostress-background-compilation is specified because in
// stress mode the compilation cache may hold on to old copies of scripts (see
// bug 1641).
// Note: this test checks that that the number of scripts reported as native
// by Debug.scripts() is the same as a number of core native scripts.
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --print-ast
// Flags: --print-ast --no-stress-background-compile
// Ensures that the --print-ast flag doesn't crash.
function foo(a) {
......
......@@ -115,12 +115,6 @@
'run-json-stringify': [SKIP],
}], # 'gcov_coverage'
##############################################################################
['variant == stress_asm_wasm', {
# Stack size too large with asm.js validator.
'fast/js/excessive-comma-usage': [SKIP],
}], # variant == stress_asm_wasm
##############################################################################
['variant == wasm_traps', {
'*': [SKIP],
......
......@@ -13,7 +13,7 @@ ALL_VARIANT_FLAGS = {
# would not force optimization too. It turns into a Nop. Please see
# https://chromium-review.googlesource.com/c/452620/ for more discussion.
"nooptimization": [["--noopt"]],
"stress_asm_wasm": [["--validate-asm", "--stress-validate-asm", "--suppress-asm-messages"]],
"stress_background_compile": [["--background-compile", "--stress-background-compile"]],
"wasm_traps": [["--wasm_trap_handler", "--invoke-weak-callbacks"]],
}
......@@ -28,9 +28,9 @@ FAST_VARIANT_FLAGS = {
# would not force optimization too. It turns into a Nop. Please see
# https://chromium-review.googlesource.com/c/452620/ for more discussion.
"nooptimization": [["--noopt"]],
"stress_asm_wasm": [["--validate-asm", "--stress-validate-asm", "--suppress-asm-messages"]],
"stress_background_compile": [["--background-compile", "--stress-background-compile"]],
"wasm_traps": [["--wasm_trap_handler", "--invoke-weak-callbacks"]],
}
ALL_VARIANTS = set(["default", "stress", "stress_incremental_marking",
"nooptimization", "stress_asm_wasm", "wasm_traps"])
"nooptimization", "stress_background_compile", "wasm_traps"])
......@@ -36,7 +36,7 @@ MORE_VARIANTS = [
"stress",
"stress_incremental_marking",
"nooptimization",
"stress_asm_wasm",
"stress_background_compile",
"wasm_traps",
]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment