Commit 41190018 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[asm.js] Use temporary zone for asm.js parsers.

This uses a separate temporary zone for running the asm.js parser, which
can be discarded immediately after the parser finished validating one
module. It reduces the lifetime of all data-structures local to the
parser and only uses the compilation zone to hold the resulting module.

R=clemensh@chromium.org

Change-Id: I5f5a613e0abd24cd85a49ebd97f9ee7cee46b02a
Reviewed-on: https://chromium-review.googlesource.com/506733
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45377}
parent 05696362
...@@ -124,12 +124,11 @@ void Report(Handle<Script> script, int position, Vector<const char> text, ...@@ -124,12 +124,11 @@ void Report(Handle<Script> script, int position, Vector<const char> text,
// Hook to report successful execution of {AsmJs::CompileAsmViaWasm} phase. // Hook to report successful execution of {AsmJs::CompileAsmViaWasm} phase.
void ReportCompilationSuccess(Handle<Script> script, int position, void ReportCompilationSuccess(Handle<Script> script, int position,
double translate_time, double compile_time, double translate_time, double compile_time,
uintptr_t module_size) { size_t module_size) {
if (FLAG_suppress_asm_messages || !FLAG_trace_asm_time) return; if (FLAG_suppress_asm_messages || !FLAG_trace_asm_time) return;
EmbeddedVector<char, 100> text; EmbeddedVector<char, 100> text;
int length = SNPrintF( int length = SNPrintF(
text, text, "success, asm->wasm: %0.3f ms, compile: %0.3f ms, %" PRIuS " bytes",
"success, asm->wasm: %0.3f ms, compile: %0.3f ms, %" PRIuPTR " bytes",
translate_time, compile_time, module_size); translate_time, compile_time, module_size);
CHECK_NE(-1, length); CHECK_NE(-1, length);
text.Truncate(length); text.Truncate(length);
...@@ -164,14 +163,28 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { ...@@ -164,14 +163,28 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
wasm::ZoneBuffer* module = nullptr; wasm::ZoneBuffer* module = nullptr;
wasm::ZoneBuffer* asm_offsets = nullptr; wasm::ZoneBuffer* asm_offsets = nullptr;
Handle<FixedArray> uses_array; Handle<FixedArray> uses_array;
base::ElapsedTimer asm_wasm_timer; Handle<WasmModuleObject> compiled;
asm_wasm_timer.Start();
size_t asm_wasm_zone_start = info->zone()->allocation_size(); // The compilation of asm.js modules is split into two distinct steps:
// [1] The asm.js module source is parsed, validated, and translated to a
// valid WebAssembly module. The result are two vectors representing the
// encoded module as well as encoded source position information.
// [2] The module is handed to WebAssembly which decodes it into an internal
// representation and eventually compiles it to machine code.
double translate_time; // Time (milliseconds) taken to execute step [1].
double compile_time; // Time (milliseconds) taken to execute step [2].
// Step 1: Translate asm.js module to WebAssembly module.
{ {
HistogramTimerScope asm_wasm_time_scope( HistogramTimerScope translate_time_scope(
info->isolate()->counters()->asm_wasm_translation_time()); info->isolate()->counters()->asm_wasm_translation_time());
size_t compile_zone_start = info->zone()->allocation_size();
base::ElapsedTimer translate_timer;
translate_timer.Start();
wasm::AsmJsParser parser(info->isolate(), info->zone(), info->script(), Zone* compile_zone = info->zone();
Zone translate_zone(info->isolate()->allocator(), ZONE_NAME);
wasm::AsmJsParser parser(info->isolate(), &translate_zone, info->script(),
info->literal()->start_position(), info->literal()->start_position(),
info->literal()->end_position()); info->literal()->end_position());
if (!parser.Run()) { if (!parser.Run()) {
...@@ -180,10 +193,9 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { ...@@ -180,10 +193,9 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
parser.failure_message()); parser.failure_message());
return MaybeHandle<FixedArray>(); return MaybeHandle<FixedArray>();
} }
Zone* zone = info->zone(); module = new (compile_zone) wasm::ZoneBuffer(compile_zone);
module = new (zone) wasm::ZoneBuffer(zone);
parser.module_builder()->WriteTo(*module); parser.module_builder()->WriteTo(*module);
asm_offsets = new (zone) wasm::ZoneBuffer(zone); asm_offsets = new (compile_zone) wasm::ZoneBuffer(compile_zone);
parser.module_builder()->WriteAsmJsOffsetTable(*asm_offsets); parser.module_builder()->WriteAsmJsOffsetTable(*asm_offsets);
uses_array = info->isolate()->factory()->NewFixedArray( uses_array = info->isolate()->factory()->NewFixedArray(
static_cast<int>(parser.stdlib_uses()->size())); static_cast<int>(parser.stdlib_uses()->size()));
...@@ -191,38 +203,40 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { ...@@ -191,38 +203,40 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
for (auto i : *parser.stdlib_uses()) { for (auto i : *parser.stdlib_uses()) {
uses_array->set(count++, Smi::FromInt(i)); uses_array->set(count++, Smi::FromInt(i));
} }
} size_t compile_zone_size =
info->zone()->allocation_size() - compile_zone_start;
double asm_wasm_time = asm_wasm_timer.Elapsed().InMillisecondsF(); size_t translate_zone_size = translate_zone.allocation_size();
size_t asm_wasm_zone = info->zone()->allocation_size() - asm_wasm_zone_start; translate_time = translate_timer.Elapsed().InMillisecondsF();
if (FLAG_trace_asm_parser) { if (FLAG_trace_asm_parser) {
PrintF("[asm.js translation successful: time=%0.3fms, zone=%" PRIuS "KB]\n", PrintF(
asm_wasm_time, asm_wasm_zone / KB); "[asm.js translation successful: time=%0.3fms, "
"translate_zone=%" PRIuS "KB, compile_zone+=%" PRIuS "KB]\n",
translate_time, translate_zone_size / KB, compile_zone_size / KB);
}
} }
Vector<const byte> asm_offsets_vec(asm_offsets->begin(), // Step 2: Compile and decode the WebAssembly module.
static_cast<int>(asm_offsets->size())); {
base::ElapsedTimer compile_timer; base::ElapsedTimer compile_timer;
compile_timer.Start(); compile_timer.Start();
wasm::ErrorThrower thrower(info->isolate(), "AsmJs::Compile"); wasm::ErrorThrower thrower(info->isolate(), "AsmJs::Compile");
MaybeHandle<JSObject> compiled = SyncCompileTranslatedAsmJs( MaybeHandle<WasmModuleObject> maybe_compiled = SyncCompileTranslatedAsmJs(
info->isolate(), &thrower, info->isolate(), &thrower,
wasm::ModuleWireBytes(module->begin(), module->end()), info->script(), wasm::ModuleWireBytes(module->begin(), module->end()), info->script(),
asm_offsets_vec); Vector<const byte>(asm_offsets->begin(), asm_offsets->size()));
DCHECK(!compiled.is_null()); DCHECK(!maybe_compiled.is_null());
DCHECK(!thrower.error()); DCHECK(!thrower.error());
double compile_time = compile_timer.Elapsed().InMillisecondsF(); compile_time = compile_timer.Elapsed().InMillisecondsF();
DCHECK_GE(module->end(), module->begin()); compiled = maybe_compiled.ToHandleChecked();
uintptr_t wasm_size = module->end() - module->begin(); }
// The result is a compiled module and serialized standard library uses.
Handle<FixedArray> result = Handle<FixedArray> result =
info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount); info->isolate()->factory()->NewFixedArray(kWasmDataEntryCount);
result->set(kWasmDataCompiledModule, *compiled.ToHandleChecked()); result->set(kWasmDataCompiledModule, *compiled);
result->set(kWasmDataUsesArray, *uses_array); result->set(kWasmDataUsesArray, *uses_array);
ReportCompilationSuccess(info->script(), info->literal()->position(), ReportCompilationSuccess(info->script(), info->literal()->position(),
asm_wasm_time, compile_time, wasm_size); translate_time, compile_time, module->size());
return result; return result;
} }
......
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