2016-01-14 09:48:45 +00:00
|
|
|
// Copyright 2016 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#ifndef WASM_RUN_UTILS_H
|
|
|
|
#define WASM_RUN_UTILS_H
|
|
|
|
|
[wasm] Introduce the TrapIf and TrapUnless operators to generate trap code.
Some instructions in WebAssembly trap for some inputs, which means that the
execution is terminated and (at least at the moment) a JavaScript exception is
thrown. Examples for traps are out-of-bounds memory accesses, or integer
divisions by zero.
Without the TrapIf and TrapUnless operators trap check in WebAssembly introduces 5
TurboFan nodes (branch, if_true, if_false, trap-reason constant, trap-position
constant), in addition to the trap condition itself. Additionally, each
WebAssembly function has four TurboFan nodes (merge, effect_phi, 2 phis) whose
number of inputs is linear to the number of trap checks in the function.
Especially for functions with high numbers of trap checks we observe a
significant slowdown in compilation time, down to 0.22 MiB/s in the sqlite
benchmark instead of the average of 3 MiB/s in other benchmarks. By introducing
a TrapIf common operator only a single node is necessary per trap check, in
addition to the trap condition. Also the nodes which are shared between trap
checks (merge, effect_phi, 2 phis) would disappear. First measurements suggest a
speedup of 30-50% on average.
This CL only implements TrapIf and TrapUnless on x64. The implementation is also
hidden behind the --wasm-trap-if flag.
Please take a special look at how the source position is transfered from the
instruction selector to the code generator, and at the context that is used for
the runtime call.
R=titzer@chromium.org
Review-Url: https://codereview.chromium.org/2562393002
Cr-Commit-Position: refs/heads/master@{#41720}
2016-12-15 13:31:29 +00:00
|
|
|
#include <setjmp.h>
|
2016-01-14 09:48:45 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2016-12-16 10:13:11 +00:00
|
|
|
#include <array>
|
2016-07-25 11:12:42 +00:00
|
|
|
#include <memory>
|
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "src/base/utils/random-number-generator.h"
|
[wasm] Initialize parallel jobs with less memory.
Avoid constructing zones and large zone objects when initializing
WasmCompilationUnit. The main reason we did that is so we can cache
the CEntryStub node, which requires a code object, obtainable only
on the main thread. We need that value, however, on background threads,
which is also where we need the aforementioned large objects. We only
need that for the WasmCompilationUnits being currently compiled, which
is a number proportional to the number of background threads provided
by the embedder. Specifically, one zone is needed only for the duration
of the background compilation, while the second zone needs to survive
past that, so the compilation results may be committed to the GC heap
as Code objects.
The problem with these large objects is that the first allocation
in a Zone is at minimum 8KB. We used to allocate 2 zones. For
modules with 200K functions, that means 3.2GB of memory pre-allocated
before any of it is actually needed.
This change attaches a Handle to the CEntryStub on the WasmCompilationUnits,
and delays zone creation to when needed. The change also adds a way to
cache CEntryStubs in a JSGraph from a given Code handle - limited to the
scenario needed by wasm (and removable once we get wasm off the GC heap,
which subsumes removing this dependency on CEntryStubs)
An additional constraint for this change is that we want it to be easily
back-mergeable to address chromium:723899.
For the wasm payload in question, collecting the max memory used by d8
using /usr/bin/time --format='(%Xtext+%Ddata %Mmax)', we get the
following numbers (in KB):
- unchanged: 3307480
- patch 1: 1807140 (45% reduction)
- patch 3: 1230320 (62% reduction from first)
- patch 5/6: 519368 (84% reduction from first)
Bug: chomium:732010, chromium:723899
Change-Id: I45b96792daf8a9c8dc47d45fb52da75945a41401
Reviewed-on: https://chromium-review.googlesource.com/530193
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45880}
2017-06-12 16:39:57 +00:00
|
|
|
#include "src/code-stubs.h"
|
This CL enables precise source positions for all V8 compilers. It merges compiler::SourcePosition and internal::SourcePosition to a single class used throughout the codebase. The new internal::SourcePosition instances store an id identifying an inlined function in addition to a script offset.
SourcePosition::InliningId() refers to a the new table DeoptimizationInputData::InliningPositions(), which provides the following data for every inlining id:
- The inlined SharedFunctionInfo as an offset into DeoptimizationInfo::LiteralArray
- The SourcePosition of the inlining. Recursively, this yields the full inlining stack.
Before the Code object is created, the same information can be found in CompilationInfo::inlined_functions().
If SourcePosition::InliningId() is SourcePosition::kNotInlined, it refers to the outer (non-inlined) function.
So every SourcePosition has full information about its inlining stack, as long as the corresponding Code object is known. The internal represenation of a source position is a positive 64bit integer.
All compilers create now appropriate source positions for inlined functions. In the case of Turbofan, this required using AstGraphBuilderWithPositions for inlined functions too. So this class is now moved to a header file.
At the moment, the additional information in source positions is only used in --trace-deopt and --code-comments. The profiler needs to be updated, at the moment it gets the correct script offsets from the deopt info, but the wrong script id from the reconstructed deopt stack, which can lead to wrong outputs. This should be resolved by making the profiler use the new inlining information for deopts.
I activated the inlined deoptimization tests in test-cpu-profiler.cc for Turbofan, changing them to a case where the deopt stack and the inlining position agree. It is currently still broken for other cases.
The following additional changes were necessary:
- The source position table (internal::SourcePositionTableBuilder etc.) supports now 64bit source positions. Encoding source positions in a single 64bit int together with the difference encoding in the source position table results in very little overhead for the inlining id, since only 12% of the source positions in Octane have a changed inlining id.
- The class HPositionInfo was effectively dead code and is now removed.
- SourcePosition has new printing and information facilities, including computing a full inlining stack.
- I had to rename compiler/source-position.{h,cc} to compiler/compiler-source-position-table.{h,cc} to avoid clashes with the new src/source-position.cc file.
- I wrote the new wrapper PodArray for ByteArray. It is a template working with any POD-type. This is used in DeoptimizationInputData::InliningPositions().
- I removed HInlinedFunctionInfo and HGraph::inlined_function_infos, because they were only used for the now obsolete Crankshaft inlining ids.
- Crankshaft managed a list of inlined functions in Lithium: LChunk::inlined_functions. This is an analog structure to CompilationInfo::inlined_functions. So I removed LChunk::inlined_functions and made Crankshaft use CompilationInfo::inlined_functions instead, because this was necessary to register the offsets into the literal array in a uniform way. This is a safe change because LChunk::inlined_functions has no other uses and the functions in CompilationInfo::inlined_functions have a strictly longer lifespan, being created earlier (in Hydrogen already).
BUG=v8:5432
Review-Url: https://codereview.chromium.org/2451853002
Cr-Commit-Position: refs/heads/master@{#40975}
2016-11-14 17:21:37 +00:00
|
|
|
#include "src/compiler/compiler-source-position-table.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "src/compiler/graph-visualizer.h"
|
2016-02-04 09:40:55 +00:00
|
|
|
#include "src/compiler/int64-lowering.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "src/compiler/js-graph.h"
|
2016-02-18 09:55:25 +00:00
|
|
|
#include "src/compiler/node.h"
|
|
|
|
#include "src/compiler/pipeline.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "src/compiler/wasm-compiler.h"
|
2016-10-10 19:00:31 +00:00
|
|
|
#include "src/compiler/zone-stats.h"
|
2017-03-13 22:12:23 +00:00
|
|
|
#include "src/trap-handler/trap-handler.h"
|
2016-12-21 12:42:06 +00:00
|
|
|
#include "src/wasm/function-body-decoder.h"
|
2017-04-25 10:13:10 +00:00
|
|
|
#include "src/wasm/local-decl-encoder.h"
|
[wasm] Introduce the TrapIf and TrapUnless operators to generate trap code.
Some instructions in WebAssembly trap for some inputs, which means that the
execution is terminated and (at least at the moment) a JavaScript exception is
thrown. Examples for traps are out-of-bounds memory accesses, or integer
divisions by zero.
Without the TrapIf and TrapUnless operators trap check in WebAssembly introduces 5
TurboFan nodes (branch, if_true, if_false, trap-reason constant, trap-position
constant), in addition to the trap condition itself. Additionally, each
WebAssembly function has four TurboFan nodes (merge, effect_phi, 2 phis) whose
number of inputs is linear to the number of trap checks in the function.
Especially for functions with high numbers of trap checks we observe a
significant slowdown in compilation time, down to 0.22 MiB/s in the sqlite
benchmark instead of the average of 3 MiB/s in other benchmarks. By introducing
a TrapIf common operator only a single node is necessary per trap check, in
addition to the trap condition. Also the nodes which are shared between trap
checks (merge, effect_phi, 2 phis) would disappear. First measurements suggest a
speedup of 30-50% on average.
This CL only implements TrapIf and TrapUnless on x64. The implementation is also
hidden behind the --wasm-trap-if flag.
Please take a special look at how the source position is transfered from the
instruction selector to the code generator, and at the context that is used for
the runtime call.
R=titzer@chromium.org
Review-Url: https://codereview.chromium.org/2562393002
Cr-Commit-Position: refs/heads/master@{#41720}
2016-12-15 13:31:29 +00:00
|
|
|
#include "src/wasm/wasm-external-refs.h"
|
2016-05-25 08:32:37 +00:00
|
|
|
#include "src/wasm/wasm-interpreter.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "src/wasm/wasm-js.h"
|
|
|
|
#include "src/wasm/wasm-module.h"
|
2016-11-11 11:12:31 +00:00
|
|
|
#include "src/wasm/wasm-objects.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "src/wasm/wasm-opcodes.h"
|
2017-05-31 13:31:52 +00:00
|
|
|
#include "src/zone/accounting-allocator.h"
|
2016-09-20 16:07:25 +00:00
|
|
|
#include "src/zone/zone.h"
|
2016-02-18 09:55:25 +00:00
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "test/cctest/cctest.h"
|
2016-02-18 09:55:25 +00:00
|
|
|
#include "test/cctest/compiler/call-tester.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
#include "test/cctest/compiler/graph-builder-tester.h"
|
2017-05-31 13:31:52 +00:00
|
|
|
#include "test/common/wasm/flag-utils.h"
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2016-02-18 15:58:02 +00:00
|
|
|
static const uint32_t kMaxFunctions = 10;
|
|
|
|
|
2016-05-25 08:32:37 +00:00
|
|
|
enum WasmExecutionMode { kExecuteInterpreted, kExecuteCompiled };
|
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
// TODO(titzer): check traps more robustly in tests.
|
|
|
|
// Currently, in tests, we just return 0xdeadbeef from the function in which
|
|
|
|
// the trap occurs if the runtime context is not available to throw a JavaScript
|
|
|
|
// exception.
|
|
|
|
#define CHECK_TRAP32(x) \
|
|
|
|
CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF)
|
|
|
|
#define CHECK_TRAP64(x) \
|
|
|
|
CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
|
|
|
|
#define CHECK_TRAP(x) CHECK_TRAP32(x)
|
|
|
|
|
2016-02-18 09:55:25 +00:00
|
|
|
#define WASM_WRAPPER_RETURN_VALUE 8754
|
|
|
|
|
2016-02-23 16:30:27 +00:00
|
|
|
#define BUILD(r, ...) \
|
|
|
|
do { \
|
|
|
|
byte code[] = {__VA_ARGS__}; \
|
|
|
|
r.Build(code, code + arraysize(code)); \
|
|
|
|
} while (false)
|
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
namespace {
|
|
|
|
using namespace v8::base;
|
|
|
|
using namespace v8::internal;
|
|
|
|
using namespace v8::internal::compiler;
|
|
|
|
using namespace v8::internal::wasm;
|
|
|
|
|
|
|
|
const uint32_t kMaxGlobalsSize = 128;
|
|
|
|
|
2017-08-07 17:17:06 +00:00
|
|
|
// A buildable ModuleEnv. Globals are pre-set, however, memory and code may be
|
|
|
|
// progressively added by a test. In turn, we piecemeal update the runtime
|
|
|
|
// objects, i.e. {WasmInstanceObject}, {WasmCompiledModule} and, if necessary,
|
|
|
|
// the interpreter.
|
2017-08-19 07:12:40 +00:00
|
|
|
class TestingModule {
|
2016-01-14 09:48:45 +00:00
|
|
|
public:
|
2017-08-19 07:12:40 +00:00
|
|
|
explicit TestingModule(Zone* zone, WasmExecutionMode mode = kExecuteCompiled)
|
2017-08-17 17:38:18 +00:00
|
|
|
: test_module_ptr_(&test_module_),
|
|
|
|
isolate_(CcTest::InitIsolateOnce()),
|
2016-05-25 08:32:37 +00:00
|
|
|
global_offset(0),
|
2017-08-17 17:38:18 +00:00
|
|
|
mem_start_(nullptr),
|
|
|
|
mem_size_(0),
|
2017-04-28 08:04:11 +00:00
|
|
|
interpreter_(nullptr) {
|
2017-01-12 20:32:27 +00:00
|
|
|
WasmJs::Install(isolate_);
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.globals_size = kMaxGlobalsSize;
|
2017-08-17 17:38:18 +00:00
|
|
|
memset(globals_data_, 0, sizeof(globals_data_));
|
2016-12-19 15:03:13 +00:00
|
|
|
instance_object_ = InitInstanceObject();
|
2017-04-28 08:04:11 +00:00
|
|
|
if (mode == kExecuteInterpreted) {
|
2017-08-07 17:17:06 +00:00
|
|
|
interpreter_ = WasmDebugInfo::SetupForTesting(instance_object_);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
void ChangeOriginToAsmjs() { test_module_.set_origin(kAsmJsOrigin); }
|
2016-10-27 16:02:24 +00:00
|
|
|
|
2016-06-16 22:21:30 +00:00
|
|
|
byte* AddMemory(uint32_t size) {
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
CHECK(!test_module_.has_memory);
|
2017-08-17 17:38:18 +00:00
|
|
|
CHECK_NULL(mem_start_);
|
|
|
|
CHECK_EQ(0, mem_size_);
|
2017-04-28 08:04:11 +00:00
|
|
|
DCHECK(!instance_object_->has_memory_buffer());
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.has_memory = true;
|
|
|
|
bool enable_guard_regions = EnableGuardRegions() && test_module_.is_wasm();
|
2017-04-28 08:04:11 +00:00
|
|
|
uint32_t alloc_size =
|
|
|
|
enable_guard_regions ? RoundUp(size, OS::CommitPageSize()) : size;
|
|
|
|
Handle<JSArrayBuffer> new_buffer =
|
|
|
|
wasm::NewArrayBuffer(isolate_, alloc_size, enable_guard_regions);
|
|
|
|
CHECK(!new_buffer.is_null());
|
|
|
|
instance_object_->set_memory_buffer(*new_buffer);
|
2017-08-17 17:38:18 +00:00
|
|
|
mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store());
|
|
|
|
mem_size_ = size;
|
|
|
|
CHECK(size == 0 || mem_start_);
|
|
|
|
memset(mem_start_, 0, size);
|
2017-08-07 17:17:06 +00:00
|
|
|
Handle<WasmCompiledModule> compiled_module =
|
|
|
|
handle(instance_object_->compiled_module());
|
|
|
|
Factory* factory = CcTest::i_isolate()->factory();
|
|
|
|
// It's not really necessary we recreate the Number objects,
|
|
|
|
// if we happened to have one, but this is a reasonable inefficiencly,
|
|
|
|
// given this is test.
|
|
|
|
WasmCompiledModule::recreate_embedded_mem_size(compiled_module, factory,
|
2017-08-17 17:38:18 +00:00
|
|
|
mem_size_);
|
2017-08-07 17:17:06 +00:00
|
|
|
WasmCompiledModule::recreate_embedded_mem_start(
|
2017-08-17 17:38:18 +00:00
|
|
|
compiled_module, factory, reinterpret_cast<size_t>(mem_start_));
|
2017-08-07 17:17:06 +00:00
|
|
|
|
|
|
|
if (interpreter_) {
|
2017-08-17 17:38:18 +00:00
|
|
|
interpreter_->UpdateMemory(mem_start_, mem_size_);
|
2017-08-07 17:17:06 +00:00
|
|
|
}
|
2017-08-17 17:38:18 +00:00
|
|
|
return mem_start_;
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 15:15:40 +00:00
|
|
|
size_t CodeTableLength() const { return function_code_.size(); }
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
template <typename T>
|
2016-06-16 22:21:30 +00:00
|
|
|
T* AddMemoryElems(uint32_t count) {
|
2016-01-14 09:48:45 +00:00
|
|
|
AddMemory(count * sizeof(T));
|
|
|
|
return raw_mem_start<T>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2016-12-16 10:13:11 +00:00
|
|
|
T* AddGlobal(
|
2016-12-21 13:43:00 +00:00
|
|
|
ValueType type = WasmOpcodes::ValueTypeFor(MachineTypeForC<T>())) {
|
2016-07-21 12:34:28 +00:00
|
|
|
const WasmGlobal* global = AddGlobal(type);
|
2017-08-17 17:38:18 +00:00
|
|
|
return reinterpret_cast<T*>(globals_data_ + global->offset);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
byte AddSignature(FunctionSig* sig) {
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.signatures.push_back(sig);
|
2017-08-17 17:38:18 +00:00
|
|
|
size_t size = test_module_.signatures.size();
|
2016-01-14 09:48:45 +00:00
|
|
|
CHECK(size < 127);
|
|
|
|
return static_cast<byte>(size - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T* raw_mem_start() {
|
2017-08-17 17:38:18 +00:00
|
|
|
DCHECK(mem_start_);
|
|
|
|
return reinterpret_cast<T*>(mem_start_);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T* raw_mem_end() {
|
2017-08-17 17:38:18 +00:00
|
|
|
DCHECK(mem_start_);
|
|
|
|
return reinterpret_cast<T*>(mem_start_ + mem_size_);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T raw_mem_at(int i) {
|
2017-08-17 17:38:18 +00:00
|
|
|
DCHECK(mem_start_);
|
|
|
|
return ReadMemory(&(reinterpret_cast<T*>(mem_start_)[i]));
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T raw_val_at(int i) {
|
2017-08-17 17:38:18 +00:00
|
|
|
return ReadMemory(reinterpret_cast<T*>(mem_start_ + i));
|
2016-06-29 09:25:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void WriteMemory(T* p, T val) {
|
|
|
|
WriteLittleEndianValue<T>(p, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T ReadMemory(T* p) {
|
|
|
|
return ReadLittleEndianValue<T>(p);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Zero-initialize the memory.
|
|
|
|
void BlankMemory() {
|
|
|
|
byte* raw = raw_mem_start<byte>();
|
2017-08-17 17:38:18 +00:00
|
|
|
memset(raw, 0, mem_size_);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Pseudo-randomly intialize the memory.
|
|
|
|
void RandomizeMemory(unsigned int seed = 88) {
|
|
|
|
byte* raw = raw_mem_start<byte>();
|
|
|
|
byte* end = raw_mem_end<byte>();
|
|
|
|
v8::base::RandomNumberGenerator rng;
|
|
|
|
rng.SetSeed(seed);
|
|
|
|
rng.NextBytes(raw, end - raw);
|
|
|
|
}
|
|
|
|
|
2017-08-10 12:45:45 +00:00
|
|
|
void SetMaxMemPages(uint32_t maximum_pages) {
|
|
|
|
test_module_.maximum_pages = maximum_pages;
|
2017-01-11 17:24:00 +00:00
|
|
|
}
|
|
|
|
|
2016-12-19 15:03:13 +00:00
|
|
|
uint32_t AddFunction(FunctionSig* sig, Handle<Code> code, const char* name) {
|
2017-08-17 17:38:18 +00:00
|
|
|
if (test_module_.functions.size() == 0) {
|
2016-02-18 15:58:02 +00:00
|
|
|
// TODO(titzer): Reserving space here to avoid the underlying WasmFunction
|
|
|
|
// structs from moving.
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.functions.reserve(kMaxFunctions);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
2017-08-17 17:38:18 +00:00
|
|
|
uint32_t index = static_cast<uint32_t>(test_module_.functions.size());
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.functions.push_back(
|
|
|
|
{sig, index, 0, {0, 0}, {0, 0}, false, false});
|
2016-12-19 15:03:13 +00:00
|
|
|
if (name) {
|
|
|
|
Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.functions.back().name = {
|
2017-06-12 11:59:14 +00:00
|
|
|
AddBytes(name_vec), static_cast<uint32_t>(name_vec.length())};
|
2016-12-19 15:03:13 +00:00
|
|
|
}
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
function_code_.push_back(code);
|
2016-05-25 08:32:37 +00:00
|
|
|
if (interpreter_) {
|
2017-08-17 17:38:18 +00:00
|
|
|
interpreter_->AddFunctionForTesting(&test_module_.functions.back());
|
2016-05-25 08:32:37 +00:00
|
|
|
}
|
2016-02-18 15:58:02 +00:00
|
|
|
DCHECK_LT(index, kMaxFunctions); // limited for testing.
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
Revert "[wasm] Reland "[wasm] redirect wasm calls to js functions through a GCed table""
This reverts commit 649b1e70e73dbdc98fe9655f454f0ace0113c990.
Reason for revert: A1 Jetstream bots are still failing.
Original change's description:
> [wasm] Reland "[wasm] redirect wasm calls to js functions through a GCed table"
>
> This reverts commit 25f03308a7c34df996e93178ba4d29de8949349a.
>
> Reason for revert: Fix the cause of bot failure and reland
>
> Original change's description:
> > Revert "[wasm] redirect wasm calls to js functions through a GCed table"
> >
> > This reverts commit eb65f35e96a417b7792400a3867560248d9809f2.
> >
> > Reason for revert: Broke jetstream benchmark on android.
> >
> > BUG=chromium:750828
> >
> > Original change's description:
> > > [wasm] redirect wasm calls to js functions through a GCed table
> > >
> > > With this patch, rather than embedding the JSReceiver address directly
> > > in the WasmToJS wrappers, we put that in a fixed array with global handle
> > > scope and instead embed the location of the handle and the index in the
> > > wrapper. This ensures that the wrapper doesn't need to be patched if the
> > > GC kicks in. This is needed to get the WASM code off the GCed heap.
> > >
> > > R=mtrofin@chromium.org
> > >
> > > Bug:
> > > Change-Id: Ie5a77a78cdecec51b04f702c63b8e4285e6a2d8d
> > > Reviewed-on: https://chromium-review.googlesource.com/581682
> > > Commit-Queue: Aseem Garg <aseemgarg@chromium.org>
> > > Reviewed-by: Mircea Trofin <mtrofin@chromium.org>
> > > Cr-Commit-Position: refs/heads/master@{#46884}
> >
> > TBR=mtrofin@chromium.org,aseemgarg@google.com,aseemgarg@chromium.org,clemensh@chromium.org
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Change-Id: I26f49ee0a1fe73cc5d8852ded87b56638be39ebf
> > Reviewed-on: https://chromium-review.googlesource.com/596268
> > Commit-Queue: Aseem Garg <aseemgarg@chromium.org>
> > Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#47059}
>
> R=mtrofin@chromium.org,aseemgarg@google.com,aseemgarg@chromium.org,clemensh@chromium.org,sullivan@chromium.org
>
> Change-Id: I29ef35f6e612a706d9f571da3e7beb1da8b5052b
> Bug: chromium:750828
> Reviewed-on: https://chromium-review.googlesource.com/597010
> Commit-Queue: Aseem Garg <aseemgarg@chromium.org>
> Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#47177}
TBR=bradnelson@chromium.org,sullivan@chromium.org,mtrofin@chromium.org,aseemgarg@google.com,aseemgarg@chromium.org,clemensh@chromium.org
Bug: chromium:750828
Change-Id: I04b12c0eb0705ad809822a7d7461423be77d942a
Reviewed-on: https://chromium-review.googlesource.com/606867
Commit-Queue: Aseem Garg <aseemgarg@chromium.org>
Reviewed-by: Aseem Garg <aseemgarg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47231}
2017-08-08 19:01:16 +00:00
|
|
|
uint32_t AddJsFunction(FunctionSig* sig, const char* source) {
|
2016-04-19 12:23:00 +00:00
|
|
|
Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
|
|
|
*v8::Local<v8::Function>::Cast(CompileRun(source))));
|
2016-12-19 15:03:13 +00:00
|
|
|
uint32_t index = AddFunction(sig, Handle<Code>::null(), nullptr);
|
2016-12-09 10:29:53 +00:00
|
|
|
Handle<Code> code = CompileWasmToJSWrapper(
|
|
|
|
isolate_, jsfunc, sig, index, Handle<String>::null(),
|
2017-08-17 17:38:18 +00:00
|
|
|
Handle<String>::null(), test_module_.origin());
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
function_code_[index] = code;
|
2016-04-19 12:23:00 +00:00
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
Handle<JSFunction> WrapCode(uint32_t index) {
|
|
|
|
// Wrap the code so it can be called as a JS function.
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
Handle<Code> code = function_code_[index];
|
2016-07-12 21:37:07 +00:00
|
|
|
Handle<Code> ret_code =
|
2017-08-17 17:38:18 +00:00
|
|
|
compiler::CompileJSToWasmWrapper(isolate_, &test_module_, code, index);
|
2016-11-11 11:12:31 +00:00
|
|
|
Handle<JSFunction> ret = WasmExportedFunction::New(
|
2017-01-20 13:50:09 +00:00
|
|
|
isolate_, instance_object(), MaybeHandle<String>(),
|
|
|
|
static_cast<int>(index),
|
2017-08-17 17:38:18 +00:00
|
|
|
static_cast<int>(test_module_.functions[index].sig->parameter_count()),
|
2016-12-06 15:33:28 +00:00
|
|
|
ret_code);
|
2017-01-20 13:50:09 +00:00
|
|
|
|
|
|
|
// Add weak reference to exported functions.
|
|
|
|
Handle<WasmCompiledModule> compiled_module(
|
|
|
|
instance_object()->compiled_module(), isolate_);
|
|
|
|
Handle<FixedArray> old_arr = compiled_module->weak_exported_functions();
|
|
|
|
Handle<FixedArray> new_arr =
|
|
|
|
isolate_->factory()->NewFixedArray(old_arr->length() + 1);
|
|
|
|
old_arr->CopyTo(0, *new_arr, 0, old_arr->length());
|
|
|
|
Handle<WeakCell> weak_fn = isolate_->factory()->NewWeakCell(ret);
|
|
|
|
new_arr->set(old_arr->length(), *weak_fn);
|
|
|
|
compiled_module->set_weak_exported_functions(new_arr);
|
|
|
|
|
2016-06-28 23:47:30 +00:00
|
|
|
return ret;
|
2016-04-19 12:23:00 +00:00
|
|
|
}
|
|
|
|
|
2016-02-18 15:58:02 +00:00
|
|
|
void SetFunctionCode(uint32_t index, Handle<Code> code) {
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
function_code_[index] = code;
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
void AddIndirectFunctionTable(uint16_t* function_indexes,
|
|
|
|
uint32_t table_size) {
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.function_tables.emplace_back();
|
|
|
|
WasmIndirectFunctionTable& table = test_module_.function_tables.back();
|
2017-08-10 12:45:45 +00:00
|
|
|
table.initial_size = table_size;
|
|
|
|
table.maximum_size = table_size;
|
|
|
|
table.has_maximum_size = true;
|
2016-07-28 04:56:56 +00:00
|
|
|
for (uint32_t i = 0; i < table_size; ++i) {
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
table.values.push_back(function_indexes[i]);
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
table.map.FindOrInsert(test_module_.functions[function_indexes[i]].sig);
|
2016-01-21 16:10:53 +00:00
|
|
|
}
|
2016-07-28 04:56:56 +00:00
|
|
|
|
2017-08-19 07:24:52 +00:00
|
|
|
function_tables_.push_back(isolate_->factory()->NewFixedArray(table_size));
|
|
|
|
signature_tables_.push_back(isolate_->factory()->NewFixedArray(table_size));
|
2016-01-21 16:10:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PopulateIndirectFunctionTable() {
|
2017-04-28 08:04:11 +00:00
|
|
|
if (interpret()) return;
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
// Initialize the fixed arrays in instance->function_tables.
|
2017-08-17 17:38:18 +00:00
|
|
|
for (uint32_t i = 0; i < function_tables_.size(); i++) {
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
WasmIndirectFunctionTable& table = test_module_.function_tables[i];
|
2017-08-19 07:24:52 +00:00
|
|
|
Handle<FixedArray> function_table = function_tables_[i];
|
|
|
|
Handle<FixedArray> signature_table = signature_tables_[i];
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
int table_size = static_cast<int>(table.values.size());
|
|
|
|
for (int j = 0; j < table_size; j++) {
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
WasmFunction& function = test_module_.functions[table.values[j]];
|
2017-01-10 19:07:34 +00:00
|
|
|
signature_table->set(j, Smi::FromInt(table.map.Find(function.sig)));
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
function_table->set(j, *function_code_[function.func_index]);
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
}
|
2016-01-21 16:10:53 +00:00
|
|
|
}
|
|
|
|
}
|
2016-07-12 21:37:07 +00:00
|
|
|
|
2016-12-19 17:22:55 +00:00
|
|
|
uint32_t AddBytes(Vector<const byte> bytes) {
|
2016-12-20 14:34:07 +00:00
|
|
|
Handle<SeqOneByteString> old_bytes(
|
|
|
|
instance_object_->compiled_module()->module_bytes(), isolate_);
|
2016-12-19 17:22:55 +00:00
|
|
|
uint32_t old_size = static_cast<uint32_t>(old_bytes->length());
|
2017-04-07 14:37:30 +00:00
|
|
|
// Avoid placing strings at offset 0, this might be interpreted as "not
|
|
|
|
// set", e.g. for function names.
|
|
|
|
uint32_t bytes_offset = old_size ? old_size : 1;
|
|
|
|
ScopedVector<byte> new_bytes(bytes_offset + bytes.length());
|
2016-12-19 17:22:55 +00:00
|
|
|
memcpy(new_bytes.start(), old_bytes->GetChars(), old_size);
|
2017-04-07 14:37:30 +00:00
|
|
|
memcpy(new_bytes.start() + bytes_offset, bytes.start(), bytes.length());
|
2016-12-19 17:22:55 +00:00
|
|
|
Handle<SeqOneByteString> new_bytes_str = Handle<SeqOneByteString>::cast(
|
|
|
|
isolate_->factory()->NewStringFromOneByte(new_bytes).ToHandleChecked());
|
2016-12-20 14:34:07 +00:00
|
|
|
instance_object_->compiled_module()->shared()->set_module_bytes(
|
|
|
|
*new_bytes_str);
|
2017-04-07 14:37:30 +00:00
|
|
|
return bytes_offset;
|
2016-12-19 17:22:55 +00:00
|
|
|
}
|
|
|
|
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
WasmFunction* GetFunctionAt(int index) {
|
|
|
|
return &test_module_.functions[index];
|
|
|
|
}
|
2016-01-21 16:10:53 +00:00
|
|
|
|
2016-05-25 08:32:37 +00:00
|
|
|
WasmInterpreter* interpreter() { return interpreter_; }
|
2017-04-28 08:04:11 +00:00
|
|
|
bool interpret() { return interpreter_ != nullptr; }
|
2016-12-16 10:13:11 +00:00
|
|
|
Isolate* isolate() { return isolate_; }
|
2016-12-19 15:03:13 +00:00
|
|
|
Handle<WasmInstanceObject> instance_object() { return instance_object_; }
|
2017-08-17 17:38:18 +00:00
|
|
|
Handle<Code> GetFunctionCode(int index) { return function_code_[index]; }
|
|
|
|
void SetFunctionCode(int index, Handle<Code> code) {
|
|
|
|
function_code_[index] = code;
|
|
|
|
}
|
|
|
|
Address globals_start() { return reinterpret_cast<Address>(globals_data_); }
|
|
|
|
|
|
|
|
compiler::ModuleEnv CreateModuleEnv() {
|
|
|
|
std::vector<SignatureMap*> signature_maps;
|
|
|
|
for (size_t i = 0; i < test_module_.function_tables.size(); i++) {
|
|
|
|
auto& function_table = test_module_.function_tables[i];
|
|
|
|
signature_maps.push_back(&function_table.map);
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
&test_module_,
|
|
|
|
function_tables_,
|
|
|
|
signature_tables_,
|
|
|
|
signature_maps,
|
|
|
|
function_code_,
|
|
|
|
Handle<Code>::null(),
|
|
|
|
reinterpret_cast<uintptr_t>(mem_start_),
|
|
|
|
mem_size_,
|
|
|
|
reinterpret_cast<uintptr_t>(globals_data_),
|
|
|
|
};
|
|
|
|
}
|
2016-05-25 08:32:37 +00:00
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
private:
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
WasmModule test_module_;
|
2017-08-17 17:38:18 +00:00
|
|
|
WasmModule* test_module_ptr_;
|
2016-05-20 08:04:43 +00:00
|
|
|
Isolate* isolate_;
|
2016-01-14 09:48:45 +00:00
|
|
|
uint32_t global_offset;
|
2017-08-17 17:38:18 +00:00
|
|
|
byte* mem_start_;
|
|
|
|
uint32_t mem_size_;
|
|
|
|
std::vector<Handle<Code>> function_code_;
|
2017-08-19 07:24:52 +00:00
|
|
|
std::vector<Handle<FixedArray>> function_tables_;
|
|
|
|
std::vector<Handle<FixedArray>> signature_tables_;
|
2017-08-17 17:38:18 +00:00
|
|
|
V8_ALIGNED(8) byte globals_data_[kMaxGlobalsSize];
|
2016-05-25 08:32:37 +00:00
|
|
|
WasmInterpreter* interpreter_;
|
2016-12-19 15:03:13 +00:00
|
|
|
Handle<WasmInstanceObject> instance_object_;
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
const WasmGlobal* AddGlobal(ValueType type) {
|
2016-07-21 12:34:28 +00:00
|
|
|
byte size = WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(type));
|
2016-01-14 09:48:45 +00:00
|
|
|
global_offset = (global_offset + size - 1) & ~(size - 1); // align
|
[wasm] Consolidate ownership of instantiation/specialization parameters
This CL consolidates ownership of parameters used to compile code (which
we always specialize) in 2 places:
- ModuleEnv for compile-time data
- WasmCompiledModule for runtime data
The parameters in question are: memory size and start; globals start;
address of indirect function tables (and their signatures, respectively);
and address to be used for wasm call sites.
Ideally, we'd collapse this down to one place, however, we need
specialization data to survive serialization. We can achieve this we get off
the GC heap and use a different wasm code serializer.
The CL:
- removes aliasing of parts of the specialization data, and moves
to using ModuleEnv as a token of passing around compile-time data, instead
of a mixture of ModuleEnv, WasmInstance, and some other structures. ModuleEnv
is responsible for providing a consistent view of the specialization data,
e.g. valid memory sizes (multiples of page size), and matching sized function
tables and signatures.
- removes WasmInstance, as its data is now contained by ModuleEnv.
- removes ModuleBytesEnv. We now pass the wire bytes explicitly. They can't
always be assumed as present (e.g. streaming compilation), and probably more
refactoring may need to happen once streaming compilation lands and we
better understand our dependencies.
Change-Id: Id7e6f2cf29e51b5756eee8b6f8827fb1f375e5c3
Reviewed-on: https://chromium-review.googlesource.com/592531
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47229}
2017-08-08 15:04:29 +00:00
|
|
|
test_module_.globals.push_back(
|
2016-10-06 15:43:10 +00:00
|
|
|
{type, true, WasmInitExpr(), global_offset, false, false});
|
2016-01-14 09:48:45 +00:00
|
|
|
global_offset += size;
|
|
|
|
// limit number of globals.
|
|
|
|
CHECK_LT(global_offset, kMaxGlobalsSize);
|
2017-08-17 17:38:18 +00:00
|
|
|
return &test_module_.globals.back();
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
2016-12-19 15:03:13 +00:00
|
|
|
|
|
|
|
Handle<WasmInstanceObject> InitInstanceObject() {
|
2016-12-20 14:34:07 +00:00
|
|
|
Handle<SeqOneByteString> empty_string = Handle<SeqOneByteString>::cast(
|
|
|
|
isolate_->factory()->NewStringFromOneByte({}).ToHandleChecked());
|
2017-02-21 17:23:38 +00:00
|
|
|
// The lifetime of the wasm module is tied to this object's, and we cannot
|
|
|
|
// rely on the mechanics of Managed<T>.
|
2017-08-17 17:38:18 +00:00
|
|
|
Handle<Foreign> module_wrapper = isolate_->factory()->NewForeign(
|
|
|
|
reinterpret_cast<Address>(&test_module_ptr_));
|
2016-12-20 14:34:07 +00:00
|
|
|
Handle<Script> script =
|
|
|
|
isolate_->factory()->NewScript(isolate_->factory()->empty_string());
|
|
|
|
script->set_type(Script::TYPE_WASM);
|
|
|
|
Handle<WasmSharedModuleData> shared_module_data =
|
|
|
|
WasmSharedModuleData::New(isolate_, module_wrapper, empty_string,
|
|
|
|
script, Handle<ByteArray>::null());
|
2017-01-20 13:50:09 +00:00
|
|
|
Handle<FixedArray> code_table = isolate_->factory()->NewFixedArray(0);
|
2017-04-05 05:58:47 +00:00
|
|
|
|
2017-08-17 17:38:18 +00:00
|
|
|
Handle<WasmCompiledModule> compiled_module =
|
|
|
|
WasmCompiledModule::New(isolate_, shared_module_data, code_table,
|
|
|
|
function_tables_, signature_tables_);
|
2017-08-07 17:17:06 +00:00
|
|
|
// This method is called when we initialize TestEnvironment. We don't
|
|
|
|
// have a memory yet, so we won't create it here. We'll update the
|
|
|
|
// interpreter when we get a memory. We do have globals, though.
|
|
|
|
WasmCompiledModule::recreate_globals_start(
|
|
|
|
compiled_module, isolate_->factory(),
|
2017-08-17 17:38:18 +00:00
|
|
|
reinterpret_cast<size_t>(globals_data_));
|
2017-01-20 13:50:09 +00:00
|
|
|
Handle<FixedArray> weak_exported = isolate_->factory()->NewFixedArray(0);
|
|
|
|
compiled_module->set_weak_exported_functions(weak_exported);
|
2016-12-19 15:03:13 +00:00
|
|
|
DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
|
|
|
|
return WasmInstanceObject::New(isolate_, compiled_module);
|
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
};
|
|
|
|
|
2016-03-07 21:04:07 +00:00
|
|
|
inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
|
2016-04-26 12:46:03 +00:00
|
|
|
FunctionSig* sig,
|
|
|
|
SourcePositionTable* source_position_table,
|
2017-07-26 20:12:27 +00:00
|
|
|
const byte* start, const byte* end,
|
|
|
|
bool runtime_exception_support = false) {
|
[wasm] Initialize parallel jobs with less memory.
Avoid constructing zones and large zone objects when initializing
WasmCompilationUnit. The main reason we did that is so we can cache
the CEntryStub node, which requires a code object, obtainable only
on the main thread. We need that value, however, on background threads,
which is also where we need the aforementioned large objects. We only
need that for the WasmCompilationUnits being currently compiled, which
is a number proportional to the number of background threads provided
by the embedder. Specifically, one zone is needed only for the duration
of the background compilation, while the second zone needs to survive
past that, so the compilation results may be committed to the GC heap
as Code objects.
The problem with these large objects is that the first allocation
in a Zone is at minimum 8KB. We used to allocate 2 zones. For
modules with 200K functions, that means 3.2GB of memory pre-allocated
before any of it is actually needed.
This change attaches a Handle to the CEntryStub on the WasmCompilationUnits,
and delays zone creation to when needed. The change also adds a way to
cache CEntryStubs in a JSGraph from a given Code handle - limited to the
scenario needed by wasm (and removable once we get wasm off the GC heap,
which subsumes removing this dependency on CEntryStubs)
An additional constraint for this change is that we want it to be easily
back-mergeable to address chromium:723899.
For the wasm payload in question, collecting the max memory used by d8
using /usr/bin/time --format='(%Xtext+%Ddata %Mmax)', we get the
following numbers (in KB):
- unchanged: 3307480
- patch 1: 1807140 (45% reduction)
- patch 3: 1230320 (62% reduction from first)
- patch 5/6: 519368 (84% reduction from first)
Bug: chomium:732010, chromium:723899
Change-Id: I45b96792daf8a9c8dc47d45fb52da75945a41401
Reviewed-on: https://chromium-review.googlesource.com/530193
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45880}
2017-06-12 16:39:57 +00:00
|
|
|
compiler::WasmGraphBuilder builder(
|
|
|
|
module, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(), sig,
|
|
|
|
source_position_table);
|
2017-07-26 20:12:27 +00:00
|
|
|
builder.SetRuntimeExceptionSupport(runtime_exception_support);
|
|
|
|
|
2016-06-29 11:39:44 +00:00
|
|
|
DecodeResult result =
|
2017-01-04 05:14:04 +00:00
|
|
|
BuildTFGraph(zone->allocator(), &builder, sig, start, end);
|
2016-01-14 09:48:45 +00:00
|
|
|
if (result.failed()) {
|
2016-09-27 20:46:10 +00:00
|
|
|
if (!FLAG_trace_wasm_decoder) {
|
|
|
|
// Retry the compilation with the tracing flag on, to help in debugging.
|
|
|
|
FLAG_trace_wasm_decoder = true;
|
2017-01-04 05:14:04 +00:00
|
|
|
result = BuildTFGraph(zone->allocator(), &builder, sig, start, end);
|
2016-09-27 20:46:10 +00:00
|
|
|
}
|
|
|
|
|
2017-04-28 11:21:00 +00:00
|
|
|
uint32_t pc = result.error_offset();
|
2016-01-14 09:48:45 +00:00
|
|
|
std::ostringstream str;
|
2017-04-10 10:48:48 +00:00
|
|
|
str << "Verification failed; pc = +" << pc
|
2017-04-28 11:21:00 +00:00
|
|
|
<< ", msg = " << result.error_msg().c_str();
|
2016-01-14 09:48:45 +00:00
|
|
|
FATAL(str.str().c_str());
|
|
|
|
}
|
2017-08-04 11:43:19 +00:00
|
|
|
builder.LowerInt64();
|
2017-03-15 13:24:54 +00:00
|
|
|
if (!CpuFeatures::SupportsWasmSimd128()) {
|
2016-11-21 23:03:05 +00:00
|
|
|
builder.SimdScalarLoweringForTesting();
|
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
class WasmFunctionWrapper : private GraphAndBuilders {
|
2016-02-18 09:55:25 +00:00
|
|
|
public:
|
2016-12-16 10:13:11 +00:00
|
|
|
explicit WasmFunctionWrapper(Zone* zone, int num_params)
|
|
|
|
: GraphAndBuilders(zone), inner_code_node_(nullptr), signature_(nullptr) {
|
2016-02-18 15:18:41 +00:00
|
|
|
// One additional parameter for the pointer to the return value memory.
|
2016-12-16 10:13:11 +00:00
|
|
|
Signature<MachineType>::Builder sig_builder(zone, 1, num_params + 1);
|
2016-02-18 09:55:25 +00:00
|
|
|
|
|
|
|
sig_builder.AddReturn(MachineType::Int32());
|
2016-12-16 10:13:11 +00:00
|
|
|
for (int i = 0; i < num_params + 1; i++) {
|
2016-02-18 09:55:25 +00:00
|
|
|
sig_builder.AddParam(MachineType::Pointer());
|
|
|
|
}
|
|
|
|
signature_ = sig_builder.Build();
|
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
void Init(CallDescriptor* descriptor, MachineType return_type,
|
|
|
|
Vector<MachineType> param_types) {
|
|
|
|
DCHECK_NOT_NULL(descriptor);
|
|
|
|
DCHECK_EQ(signature_->parameter_count(), param_types.length() + 1);
|
|
|
|
|
|
|
|
// Create the TF graph for the wrapper.
|
2016-02-18 09:55:25 +00:00
|
|
|
|
|
|
|
// Function, effect, and control.
|
2016-12-16 10:13:11 +00:00
|
|
|
Node** parameters = zone()->NewArray<Node*>(param_types.length() + 3);
|
2016-02-18 09:55:25 +00:00
|
|
|
graph()->SetStart(graph()->NewNode(common()->Start(6)));
|
|
|
|
Node* effect = graph()->start();
|
|
|
|
int parameter_count = 0;
|
|
|
|
|
|
|
|
// Dummy node which gets replaced in SetInnerCode.
|
|
|
|
inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
|
|
|
|
parameters[parameter_count++] = inner_code_node_;
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
int param_idx = 0;
|
|
|
|
for (MachineType t : param_types) {
|
|
|
|
DCHECK_NE(MachineType::None(), t);
|
2016-02-18 09:55:25 +00:00
|
|
|
parameters[parameter_count] = graph()->NewNode(
|
2016-12-16 10:13:11 +00:00
|
|
|
machine()->Load(t),
|
|
|
|
graph()->NewNode(common()->Parameter(param_idx++), graph()->start()),
|
2016-02-18 09:55:25 +00:00
|
|
|
graph()->NewNode(common()->Int32Constant(0)), effect,
|
|
|
|
graph()->start());
|
|
|
|
effect = parameters[parameter_count++];
|
|
|
|
}
|
|
|
|
|
|
|
|
parameters[parameter_count++] = effect;
|
|
|
|
parameters[parameter_count++] = graph()->start();
|
|
|
|
Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count,
|
|
|
|
parameters);
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
if (!return_type.IsNone()) {
|
|
|
|
effect = graph()->NewNode(
|
|
|
|
machine()->Store(StoreRepresentation(
|
|
|
|
return_type.representation(), WriteBarrierKind::kNoWriteBarrier)),
|
|
|
|
graph()->NewNode(common()->Parameter(param_types.length()),
|
|
|
|
graph()->start()),
|
|
|
|
graph()->NewNode(common()->Int32Constant(0)), call, effect,
|
|
|
|
graph()->start());
|
|
|
|
}
|
2016-11-02 13:15:39 +00:00
|
|
|
Node* zero = graph()->NewNode(common()->Int32Constant(0));
|
2016-02-18 09:55:25 +00:00
|
|
|
Node* r = graph()->NewNode(
|
2016-11-02 13:15:39 +00:00
|
|
|
common()->Return(), zero,
|
2016-02-18 09:55:25 +00:00
|
|
|
graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)),
|
|
|
|
effect, graph()->start());
|
2017-03-17 12:20:34 +00:00
|
|
|
graph()->SetEnd(graph()->NewNode(common()->End(1), r));
|
2016-02-18 09:55:25 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
template <typename ReturnType, typename... ParamTypes>
|
|
|
|
void Init(CallDescriptor* descriptor) {
|
|
|
|
std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
|
|
|
|
{MachineTypeForC<ParamTypes>()...}};
|
|
|
|
Vector<MachineType> param_vec(param_machine_types.data(),
|
|
|
|
param_machine_types.size());
|
|
|
|
Init(descriptor, MachineTypeForC<ReturnType>(), param_vec);
|
|
|
|
}
|
|
|
|
|
2016-02-18 09:55:25 +00:00
|
|
|
void SetInnerCode(Handle<Code> code_handle) {
|
|
|
|
NodeProperties::ChangeOp(inner_code_node_,
|
|
|
|
common()->HeapConstant(code_handle));
|
|
|
|
}
|
|
|
|
|
|
|
|
Handle<Code> GetWrapperCode() {
|
|
|
|
if (code_.is_null()) {
|
|
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
|
|
|
|
|
|
|
CallDescriptor* descriptor =
|
|
|
|
Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
|
|
|
|
|
2016-02-18 15:18:41 +00:00
|
|
|
if (kPointerSize == 4) {
|
2016-12-16 10:13:11 +00:00
|
|
|
size_t num_params = signature_->parameter_count();
|
2016-02-18 15:18:41 +00:00
|
|
|
// One additional parameter for the pointer of the return value.
|
2016-12-16 10:13:11 +00:00
|
|
|
Signature<MachineRepresentation>::Builder rep_builder(zone(), 1,
|
|
|
|
num_params + 1);
|
2016-02-18 15:18:41 +00:00
|
|
|
|
|
|
|
rep_builder.AddReturn(MachineRepresentation::kWord32);
|
2016-12-16 10:13:11 +00:00
|
|
|
for (size_t i = 0; i < num_params + 1; i++) {
|
2016-02-18 15:18:41 +00:00
|
|
|
rep_builder.AddParam(MachineRepresentation::kWord32);
|
|
|
|
}
|
|
|
|
Int64Lowering r(graph(), machine(), common(), zone(),
|
|
|
|
rep_builder.Build());
|
|
|
|
r.LowerGraph();
|
|
|
|
}
|
|
|
|
|
2016-08-26 09:03:39 +00:00
|
|
|
CompilationInfo info(ArrayVector("testing"), isolate, graph()->zone(),
|
|
|
|
Code::ComputeFlags(Code::STUB));
|
2016-02-18 09:55:25 +00:00
|
|
|
code_ =
|
|
|
|
Pipeline::GenerateCodeForTesting(&info, descriptor, graph(), nullptr);
|
|
|
|
CHECK(!code_.is_null());
|
|
|
|
#ifdef ENABLE_DISASSEMBLER
|
|
|
|
if (FLAG_print_opt_code) {
|
|
|
|
OFStream os(stdout);
|
|
|
|
code_->Disassemble("wasm wrapper", os);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return code_;
|
|
|
|
}
|
|
|
|
|
|
|
|
Signature<MachineType>* signature() const { return signature_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Node* inner_code_node_;
|
|
|
|
Handle<Code> code_;
|
|
|
|
Signature<MachineType>* signature_;
|
|
|
|
};
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2017-06-09 12:21:52 +00:00
|
|
|
// A helper for compiling wasm functions for testing.
|
2016-12-16 10:13:11 +00:00
|
|
|
// It contains the internal state for compilation (i.e. TurboFan graph) and
|
|
|
|
// interpretation (by adding to the interpreter manually).
|
|
|
|
class WasmFunctionCompiler : private GraphAndBuilders {
|
2016-01-14 09:48:45 +00:00
|
|
|
public:
|
2017-08-19 07:12:40 +00:00
|
|
|
Isolate* isolate() { return testing_module_->isolate(); }
|
2016-01-14 09:48:45 +00:00
|
|
|
Graph* graph() const { return main_graph_; }
|
|
|
|
Zone* zone() const { return graph()->zone(); }
|
|
|
|
CommonOperatorBuilder* common() { return &main_common_; }
|
|
|
|
MachineOperatorBuilder* machine() { return &main_machine_; }
|
2016-12-16 10:13:11 +00:00
|
|
|
CallDescriptor* descriptor() {
|
2016-02-18 09:55:25 +00:00
|
|
|
if (descriptor_ == nullptr) {
|
2017-06-27 15:38:52 +00:00
|
|
|
descriptor_ = compiler::GetWasmCallDescriptor(zone(), sig);
|
2016-02-18 09:55:25 +00:00
|
|
|
}
|
2016-12-16 10:13:11 +00:00
|
|
|
return descriptor_;
|
2016-02-18 09:55:25 +00:00
|
|
|
}
|
2016-05-25 08:32:37 +00:00
|
|
|
uint32_t function_index() { return function_->func_index; }
|
2016-01-14 09:48:45 +00:00
|
|
|
|
|
|
|
void Build(const byte* start, const byte* end) {
|
2017-01-15 21:18:53 +00:00
|
|
|
size_t locals_size = local_decls.Size();
|
|
|
|
size_t total_size = end - start + locals_size + 1;
|
|
|
|
byte* buffer = static_cast<byte*>(zone()->New(total_size));
|
|
|
|
// Prepend the local decls to the code.
|
|
|
|
local_decls.Emit(buffer);
|
|
|
|
// Emit the code.
|
|
|
|
memcpy(buffer + locals_size, start, end - start);
|
|
|
|
// Append an extra end opcode.
|
|
|
|
buffer[total_size - 1] = kExprEnd;
|
|
|
|
|
|
|
|
start = buffer;
|
|
|
|
end = buffer + total_size;
|
2016-12-19 17:22:55 +00:00
|
|
|
|
|
|
|
CHECK_GE(kMaxInt, end - start);
|
|
|
|
int len = static_cast<int>(end - start);
|
2017-08-19 07:12:40 +00:00
|
|
|
function_->code = {
|
|
|
|
testing_module_->AddBytes(Vector<const byte>(start, len)),
|
|
|
|
static_cast<uint32_t>(len)};
|
2016-12-19 17:22:55 +00:00
|
|
|
|
2016-05-25 08:32:37 +00:00
|
|
|
if (interpreter_) {
|
|
|
|
// Add the code to the interpreter.
|
2017-03-14 15:54:43 +00:00
|
|
|
interpreter_->SetFunctionCodeForTesting(function_, start, end);
|
2016-05-25 08:32:37 +00:00
|
|
|
}
|
2016-12-16 10:13:11 +00:00
|
|
|
|
|
|
|
// Build the TurboFan graph.
|
2017-08-19 07:12:40 +00:00
|
|
|
compiler::ModuleEnv module_env = testing_module_->CreateModuleEnv();
|
2017-08-17 17:38:18 +00:00
|
|
|
TestBuildingGraph(zone(), &jsgraph, &module_env, sig,
|
2017-07-26 20:12:27 +00:00
|
|
|
&source_position_table_, start, end,
|
|
|
|
runtime_exception_support_);
|
2016-12-16 10:13:11 +00:00
|
|
|
Handle<Code> code = Compile();
|
2017-08-19 07:12:40 +00:00
|
|
|
testing_module_->SetFunctionCode(function_index(), code);
|
2017-01-20 13:50:09 +00:00
|
|
|
|
|
|
|
// Add to code table.
|
|
|
|
Handle<WasmCompiledModule> compiled_module(
|
2017-08-19 07:12:40 +00:00
|
|
|
testing_module_->instance_object()->compiled_module(), isolate());
|
2017-01-20 13:50:09 +00:00
|
|
|
Handle<FixedArray> code_table = compiled_module->code_table();
|
2017-02-21 18:21:31 +00:00
|
|
|
if (static_cast<int>(function_index()) >= code_table->length()) {
|
|
|
|
Handle<FixedArray> new_arr = isolate()->factory()->NewFixedArray(
|
|
|
|
static_cast<int>(function_index()) + 1);
|
|
|
|
code_table->CopyTo(0, *new_arr, 0, code_table->length());
|
|
|
|
code_table = new_arr;
|
2017-04-05 05:58:47 +00:00
|
|
|
compiled_module->ReplaceCodeTableForTesting(code_table);
|
2017-02-21 18:21:31 +00:00
|
|
|
}
|
|
|
|
DCHECK(code_table->get(static_cast<int>(function_index()))
|
|
|
|
->IsUndefined(isolate()));
|
|
|
|
code_table->set(static_cast<int>(function_index()), *code);
|
2017-03-15 01:13:05 +00:00
|
|
|
if (trap_handler::UseTrapHandler()) {
|
|
|
|
UnpackAndRegisterProtectedInstructions(isolate(), code_table);
|
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
byte AllocateLocal(ValueType type) {
|
2016-05-17 17:53:46 +00:00
|
|
|
uint32_t index = local_decls.AddLocals(1, type);
|
2016-03-07 21:04:07 +00:00
|
|
|
byte result = static_cast<byte>(index);
|
|
|
|
DCHECK_EQ(index, result);
|
|
|
|
return result;
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
void SetSigIndex(int sig_index) { function_->sig_index = sig_index; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
friend class WasmRunnerBase;
|
|
|
|
|
|
|
|
explicit WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
|
2017-08-19 07:12:40 +00:00
|
|
|
TestingModule* module, const char* name,
|
2017-07-26 20:12:27 +00:00
|
|
|
bool runtime_exception_support)
|
2016-12-16 10:13:11 +00:00
|
|
|
: GraphAndBuilders(zone),
|
2017-08-19 07:12:40 +00:00
|
|
|
jsgraph(module->isolate(), this->graph(), this->common(), nullptr,
|
2016-12-16 10:13:11 +00:00
|
|
|
nullptr, this->machine()),
|
|
|
|
sig(sig),
|
|
|
|
descriptor_(nullptr),
|
2017-08-19 07:12:40 +00:00
|
|
|
testing_module_(module),
|
2016-12-16 10:13:11 +00:00
|
|
|
local_decls(zone, sig),
|
|
|
|
source_position_table_(this->graph()),
|
2017-08-19 07:12:40 +00:00
|
|
|
interpreter_(module->interpreter()),
|
2017-07-26 20:12:27 +00:00
|
|
|
runtime_exception_support_(runtime_exception_support) {
|
2016-12-16 10:13:11 +00:00
|
|
|
// Get a new function from the testing module.
|
2017-08-19 07:12:40 +00:00
|
|
|
int index = module->AddFunction(sig, Handle<Code>::null(), name);
|
|
|
|
function_ = testing_module_->GetFunctionAt(index);
|
2016-12-16 10:13:11 +00:00
|
|
|
}
|
|
|
|
|
2016-02-18 15:58:02 +00:00
|
|
|
Handle<Code> Compile() {
|
2016-12-16 10:13:11 +00:00
|
|
|
CallDescriptor* desc = descriptor();
|
2016-02-18 15:18:41 +00:00
|
|
|
if (kPointerSize == 4) {
|
2017-06-27 15:38:52 +00:00
|
|
|
desc = compiler::GetI32WasmCallDescriptor(this->zone(), desc);
|
2016-02-18 15:18:41 +00:00
|
|
|
}
|
2017-03-03 09:47:39 +00:00
|
|
|
EmbeddedVector<char, 16> comp_name;
|
|
|
|
int comp_name_len = SNPrintF(comp_name, "wasm#%u", this->function_index());
|
|
|
|
comp_name.Truncate(comp_name_len);
|
|
|
|
CompilationInfo info(comp_name, this->isolate(), this->zone(),
|
2016-04-19 12:54:10 +00:00
|
|
|
Code::ComputeFlags(Code::WASM_FUNCTION));
|
2016-07-25 11:12:42 +00:00
|
|
|
std::unique_ptr<CompilationJob> job(Pipeline::NewWasmCompilationJob(
|
2017-06-29 01:14:44 +00:00
|
|
|
&info, &jsgraph, desc, &source_position_table_, nullptr,
|
|
|
|
ModuleOrigin::kAsmJsOrigin));
|
2016-08-22 11:48:59 +00:00
|
|
|
if (job->ExecuteJob() != CompilationJob::SUCCEEDED ||
|
|
|
|
job->FinalizeJob() != CompilationJob::SUCCEEDED)
|
2016-04-29 12:24:58 +00:00
|
|
|
return Handle<Code>::null();
|
|
|
|
|
|
|
|
Handle<Code> code = info.code();
|
|
|
|
|
2016-12-19 15:03:13 +00:00
|
|
|
// Deopt data holds <WeakCell<wasm_instance>, func_index>.
|
2016-04-29 12:24:58 +00:00
|
|
|
DCHECK(code->deoptimization_data() == nullptr ||
|
|
|
|
code->deoptimization_data()->length() == 0);
|
|
|
|
Handle<FixedArray> deopt_data =
|
|
|
|
isolate()->factory()->NewFixedArray(2, TENURED);
|
2016-12-19 15:03:13 +00:00
|
|
|
Handle<Object> weak_instance =
|
2017-08-19 07:12:40 +00:00
|
|
|
isolate()->factory()->NewWeakCell(testing_module_->instance_object());
|
2016-12-19 15:03:13 +00:00
|
|
|
deopt_data->set(0, *weak_instance);
|
2016-05-25 08:32:37 +00:00
|
|
|
deopt_data->set(1, Smi::FromInt(static_cast<int>(function_index())));
|
2016-04-29 12:24:58 +00:00
|
|
|
code->set_deoptimization_data(*deopt_data);
|
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
#ifdef ENABLE_DISASSEMBLER
|
2016-04-29 12:24:58 +00:00
|
|
|
if (FLAG_print_opt_code) {
|
2016-01-14 09:48:45 +00:00
|
|
|
OFStream os(stdout);
|
2016-04-26 12:46:03 +00:00
|
|
|
code->Disassemble("wasm code", os);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-04-26 12:46:03 +00:00
|
|
|
return code;
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
JSGraph jsgraph;
|
|
|
|
FunctionSig* sig;
|
|
|
|
// The call descriptor is initialized when the function is compiled.
|
|
|
|
CallDescriptor* descriptor_;
|
2017-08-19 07:12:40 +00:00
|
|
|
TestingModule* testing_module_;
|
2016-12-16 10:13:11 +00:00
|
|
|
Vector<const char> debug_name_;
|
|
|
|
WasmFunction* function_;
|
|
|
|
LocalDeclEncoder local_decls;
|
|
|
|
SourcePositionTable source_position_table_;
|
|
|
|
WasmInterpreter* interpreter_;
|
2017-07-26 20:12:27 +00:00
|
|
|
bool runtime_exception_support_ = false;
|
2016-12-15 16:51:11 +00:00
|
|
|
};
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
// A helper class to build a module around Wasm bytecode, generate machine
|
2016-01-14 09:48:45 +00:00
|
|
|
// code, and run that code.
|
2016-12-16 10:13:11 +00:00
|
|
|
class WasmRunnerBase : public HandleAndZoneScope {
|
2016-01-14 09:48:45 +00:00
|
|
|
public:
|
2017-07-26 20:12:27 +00:00
|
|
|
explicit WasmRunnerBase(WasmExecutionMode execution_mode, int num_params,
|
|
|
|
bool runtime_exception_support)
|
2016-12-16 10:13:11 +00:00
|
|
|
: zone_(&allocator_, ZONE_NAME),
|
2017-08-19 07:12:40 +00:00
|
|
|
module_(&zone_, execution_mode),
|
2017-07-26 20:12:27 +00:00
|
|
|
wrapper_(&zone_, num_params),
|
|
|
|
runtime_exception_support_(runtime_exception_support) {}
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2016-02-18 15:58:02 +00:00
|
|
|
// Builds a graph from the given Wasm code and generates the machine
|
2016-01-14 09:48:45 +00:00
|
|
|
// code and call wrapper for that graph. This method must not be called
|
|
|
|
// more than once.
|
|
|
|
void Build(const byte* start, const byte* end) {
|
2016-02-18 15:58:02 +00:00
|
|
|
CHECK(!compiled_);
|
|
|
|
compiled_ = true;
|
2016-12-16 10:13:11 +00:00
|
|
|
functions_[0]->Build(start, end);
|
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
// Resets the state for building the next function.
|
|
|
|
// The main function called will always be the first function.
|
|
|
|
template <typename ReturnType, typename... ParamTypes>
|
2016-12-19 15:03:13 +00:00
|
|
|
WasmFunctionCompiler& NewFunction(const char* name = nullptr) {
|
|
|
|
return NewFunction(CreateSig<ReturnType, ParamTypes...>(), name);
|
2016-12-16 10:13:11 +00:00
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
// Resets the state for building the next function.
|
|
|
|
// The main function called will be the last generated function.
|
|
|
|
// Returns the index of the previously built function.
|
2016-12-19 15:03:13 +00:00
|
|
|
WasmFunctionCompiler& NewFunction(FunctionSig* sig,
|
|
|
|
const char* name = nullptr) {
|
2017-07-26 20:12:27 +00:00
|
|
|
functions_.emplace_back(new WasmFunctionCompiler(
|
2017-08-19 07:12:40 +00:00
|
|
|
&zone_, sig, &module_, name, runtime_exception_support_));
|
2016-12-16 10:13:11 +00:00
|
|
|
return *functions_.back();
|
2016-05-25 08:32:37 +00:00
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
byte AllocateLocal(ValueType type) {
|
2016-12-16 10:13:11 +00:00
|
|
|
return functions_[0]->AllocateLocal(type);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 13:50:09 +00:00
|
|
|
uint32_t function_index() { return functions_[0]->function_index(); }
|
2016-12-16 10:13:11 +00:00
|
|
|
WasmFunction* function() { return functions_[0]->function_; }
|
2017-04-28 08:04:11 +00:00
|
|
|
WasmInterpreter* interpreter() {
|
|
|
|
DCHECK(interpret());
|
|
|
|
return functions_[0]->interpreter_;
|
|
|
|
}
|
2016-12-16 10:13:11 +00:00
|
|
|
bool possible_nondeterminism() { return possible_nondeterminism_; }
|
2017-08-19 07:12:40 +00:00
|
|
|
TestingModule& module() { return module_; }
|
2016-12-16 10:13:11 +00:00
|
|
|
Zone* zone() { return &zone_; }
|
|
|
|
|
2017-08-19 07:12:40 +00:00
|
|
|
bool interpret() { return module_.interpret(); }
|
2017-04-28 08:04:11 +00:00
|
|
|
|
2017-08-07 11:40:21 +00:00
|
|
|
template <typename ReturnType, typename... ParamTypes>
|
|
|
|
FunctionSig* CreateSig() {
|
|
|
|
std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
|
|
|
|
{MachineTypeForC<ParamTypes>()...}};
|
|
|
|
Vector<MachineType> param_vec(param_machine_types.data(),
|
|
|
|
param_machine_types.size());
|
|
|
|
return CreateSig(MachineTypeForC<ReturnType>(), param_vec);
|
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
private:
|
|
|
|
FunctionSig* CreateSig(MachineType return_type,
|
|
|
|
Vector<MachineType> param_types) {
|
|
|
|
int return_count = return_type.IsNone() ? 0 : 1;
|
|
|
|
int param_count = param_types.length();
|
|
|
|
|
|
|
|
// Allocate storage array in zone.
|
2016-12-21 13:43:00 +00:00
|
|
|
ValueType* sig_types =
|
|
|
|
zone_.NewArray<ValueType>(return_count + param_count);
|
2016-12-16 10:13:11 +00:00
|
|
|
|
|
|
|
// Convert machine types to local types, and check that there are no
|
|
|
|
// MachineType::None()'s in the parameters.
|
|
|
|
int idx = 0;
|
2016-12-21 13:43:00 +00:00
|
|
|
if (return_count) sig_types[idx++] = WasmOpcodes::ValueTypeFor(return_type);
|
2016-12-16 10:13:11 +00:00
|
|
|
for (MachineType param : param_types) {
|
|
|
|
CHECK_NE(MachineType::None(), param);
|
2016-12-21 13:43:00 +00:00
|
|
|
sig_types[idx++] = WasmOpcodes::ValueTypeFor(param);
|
2016-12-15 16:51:11 +00:00
|
|
|
}
|
2016-12-16 10:13:11 +00:00
|
|
|
return new (&zone_) FunctionSig(return_count, param_count, sig_types);
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
protected:
|
|
|
|
v8::internal::AccountingAllocator allocator_;
|
|
|
|
Zone zone_;
|
2017-08-19 07:12:40 +00:00
|
|
|
TestingModule module_;
|
2016-12-16 10:13:11 +00:00
|
|
|
std::vector<std::unique_ptr<WasmFunctionCompiler>> functions_;
|
|
|
|
WasmFunctionWrapper wrapper_;
|
|
|
|
bool compiled_ = false;
|
|
|
|
bool possible_nondeterminism_ = false;
|
2017-07-26 20:12:27 +00:00
|
|
|
bool runtime_exception_support_ = false;
|
2016-12-16 10:13:11 +00:00
|
|
|
|
|
|
|
public:
|
2017-02-10 13:11:40 +00:00
|
|
|
// This field has to be static. Otherwise, gcc complains about the use in
|
2016-12-16 10:13:11 +00:00
|
|
|
// the lambda context below.
|
2017-02-10 13:11:40 +00:00
|
|
|
static bool trap_happened;
|
2016-12-16 10:13:11 +00:00
|
|
|
};
|
[wasm] Introduce the TrapIf and TrapUnless operators to generate trap code.
Some instructions in WebAssembly trap for some inputs, which means that the
execution is terminated and (at least at the moment) a JavaScript exception is
thrown. Examples for traps are out-of-bounds memory accesses, or integer
divisions by zero.
Without the TrapIf and TrapUnless operators trap check in WebAssembly introduces 5
TurboFan nodes (branch, if_true, if_false, trap-reason constant, trap-position
constant), in addition to the trap condition itself. Additionally, each
WebAssembly function has four TurboFan nodes (merge, effect_phi, 2 phis) whose
number of inputs is linear to the number of trap checks in the function.
Especially for functions with high numbers of trap checks we observe a
significant slowdown in compilation time, down to 0.22 MiB/s in the sqlite
benchmark instead of the average of 3 MiB/s in other benchmarks. By introducing
a TrapIf common operator only a single node is necessary per trap check, in
addition to the trap condition. Also the nodes which are shared between trap
checks (merge, effect_phi, 2 phis) would disappear. First measurements suggest a
speedup of 30-50% on average.
This CL only implements TrapIf and TrapUnless on x64. The implementation is also
hidden behind the --wasm-trap-if flag.
Please take a special look at how the source position is transfered from the
instruction selector to the code generator, and at the context that is used for
the runtime call.
R=titzer@chromium.org
Review-Url: https://codereview.chromium.org/2562393002
Cr-Commit-Position: refs/heads/master@{#41720}
2016-12-15 13:31:29 +00:00
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
template <typename ReturnType, typename... ParamTypes>
|
|
|
|
class WasmRunner : public WasmRunnerBase {
|
|
|
|
public:
|
2016-12-19 15:03:13 +00:00
|
|
|
explicit WasmRunner(WasmExecutionMode execution_mode,
|
2017-07-26 20:12:27 +00:00
|
|
|
const char* main_fn_name = "main",
|
|
|
|
bool runtime_exception_support = false)
|
|
|
|
: WasmRunnerBase(execution_mode, sizeof...(ParamTypes),
|
|
|
|
runtime_exception_support) {
|
2016-12-19 15:03:13 +00:00
|
|
|
NewFunction<ReturnType, ParamTypes...>(main_fn_name);
|
2016-12-16 10:13:11 +00:00
|
|
|
if (!interpret()) {
|
|
|
|
wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor());
|
|
|
|
}
|
[wasm] Introduce the TrapIf and TrapUnless operators to generate trap code.
Some instructions in WebAssembly trap for some inputs, which means that the
execution is terminated and (at least at the moment) a JavaScript exception is
thrown. Examples for traps are out-of-bounds memory accesses, or integer
divisions by zero.
Without the TrapIf and TrapUnless operators trap check in WebAssembly introduces 5
TurboFan nodes (branch, if_true, if_false, trap-reason constant, trap-position
constant), in addition to the trap condition itself. Additionally, each
WebAssembly function has four TurboFan nodes (merge, effect_phi, 2 phis) whose
number of inputs is linear to the number of trap checks in the function.
Especially for functions with high numbers of trap checks we observe a
significant slowdown in compilation time, down to 0.22 MiB/s in the sqlite
benchmark instead of the average of 3 MiB/s in other benchmarks. By introducing
a TrapIf common operator only a single node is necessary per trap check, in
addition to the trap condition. Also the nodes which are shared between trap
checks (merge, effect_phi, 2 phis) would disappear. First measurements suggest a
speedup of 30-50% on average.
This CL only implements TrapIf and TrapUnless on x64. The implementation is also
hidden behind the --wasm-trap-if flag.
Please take a special look at how the source position is transfered from the
instruction selector to the code generator, and at the context that is used for
the runtime call.
R=titzer@chromium.org
Review-Url: https://codereview.chromium.org/2562393002
Cr-Commit-Position: refs/heads/master@{#41720}
2016-12-15 13:31:29 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
ReturnType Call(ParamTypes... p) {
|
|
|
|
DCHECK(compiled_);
|
|
|
|
if (interpret()) return CallInterpreter(p...);
|
|
|
|
|
2016-12-16 15:32:09 +00:00
|
|
|
ReturnType return_value = static_cast<ReturnType>(0xdeadbeefdeadbeef);
|
2017-02-10 13:11:40 +00:00
|
|
|
WasmRunnerBase::trap_happened = false;
|
|
|
|
auto trap_callback = []() -> void {
|
|
|
|
WasmRunnerBase::trap_happened = true;
|
|
|
|
set_trap_callback_for_testing(nullptr);
|
|
|
|
};
|
|
|
|
set_trap_callback_for_testing(trap_callback);
|
|
|
|
|
2017-08-19 07:12:40 +00:00
|
|
|
wrapper_.SetInnerCode(module_.GetFunctionCode(0));
|
2017-02-10 13:11:40 +00:00
|
|
|
CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
|
|
|
|
wrapper_.GetWrapperCode(), wrapper_.signature());
|
|
|
|
int32_t result = runner.Call(static_cast<void*>(&p)...,
|
|
|
|
static_cast<void*>(&return_value));
|
|
|
|
CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
|
|
|
|
return WasmRunnerBase::trap_happened
|
|
|
|
? static_cast<ReturnType>(0xdeadbeefdeadbeef)
|
|
|
|
: return_value;
|
2016-05-25 08:32:37 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
ReturnType CallInterpreter(ParamTypes... p) {
|
2016-06-09 14:22:05 +00:00
|
|
|
WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
|
|
|
|
thread->Reset();
|
2017-07-14 13:49:01 +00:00
|
|
|
std::array<WasmValue, sizeof...(p)> args{{WasmValue(p)...}};
|
2017-03-14 15:54:43 +00:00
|
|
|
thread->InitFrame(function(), args.data());
|
2017-07-14 13:58:25 +00:00
|
|
|
WasmInterpreter::HeapObjectsScope heap_objects_scope(
|
2017-08-19 07:12:40 +00:00
|
|
|
interpreter(), module().instance_object());
|
2016-06-09 14:22:05 +00:00
|
|
|
if (thread->Run() == WasmInterpreter::FINISHED) {
|
2017-07-14 13:49:01 +00:00
|
|
|
WasmValue val = thread->GetReturnValue();
|
2016-10-20 14:27:23 +00:00
|
|
|
possible_nondeterminism_ |= thread->PossibleNondeterminism();
|
2016-05-25 08:32:37 +00:00
|
|
|
return val.to<ReturnType>();
|
2016-06-09 14:22:05 +00:00
|
|
|
} else if (thread->state() == WasmInterpreter::TRAPPED) {
|
2016-05-25 08:32:37 +00:00
|
|
|
// TODO(titzer): return the correct trap code
|
|
|
|
int64_t result = 0xdeadbeefdeadbeef;
|
|
|
|
return static_cast<ReturnType>(result);
|
|
|
|
} else {
|
|
|
|
// TODO(titzer): falling off end
|
2016-12-16 10:13:11 +00:00
|
|
|
return ReturnType{0};
|
2016-05-25 08:32:37 +00:00
|
|
|
}
|
2016-01-14 09:48:45 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-12-16 10:13:11 +00:00
|
|
|
// Declare static variable.
|
2017-02-10 13:11:40 +00:00
|
|
|
bool WasmRunnerBase::trap_happened;
|
[wasm] Introduce the TrapIf and TrapUnless operators to generate trap code.
Some instructions in WebAssembly trap for some inputs, which means that the
execution is terminated and (at least at the moment) a JavaScript exception is
thrown. Examples for traps are out-of-bounds memory accesses, or integer
divisions by zero.
Without the TrapIf and TrapUnless operators trap check in WebAssembly introduces 5
TurboFan nodes (branch, if_true, if_false, trap-reason constant, trap-position
constant), in addition to the trap condition itself. Additionally, each
WebAssembly function has four TurboFan nodes (merge, effect_phi, 2 phis) whose
number of inputs is linear to the number of trap checks in the function.
Especially for functions with high numbers of trap checks we observe a
significant slowdown in compilation time, down to 0.22 MiB/s in the sqlite
benchmark instead of the average of 3 MiB/s in other benchmarks. By introducing
a TrapIf common operator only a single node is necessary per trap check, in
addition to the trap condition. Also the nodes which are shared between trap
checks (merge, effect_phi, 2 phis) would disappear. First measurements suggest a
speedup of 30-50% on average.
This CL only implements TrapIf and TrapUnless on x64. The implementation is also
hidden behind the --wasm-trap-if flag.
Please take a special look at how the source position is transfered from the
instruction selector to the code generator, and at the context that is used for
the runtime call.
R=titzer@chromium.org
Review-Url: https://codereview.chromium.org/2562393002
Cr-Commit-Position: refs/heads/master@{#41720}
2016-12-15 13:31:29 +00:00
|
|
|
|
2016-05-18 15:56:11 +00:00
|
|
|
// A macro to define tests that run in different engine configurations.
|
2016-05-25 08:32:37 +00:00
|
|
|
#define WASM_EXEC_TEST(name) \
|
|
|
|
void RunWasm_##name(WasmExecutionMode execution_mode); \
|
|
|
|
TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
|
|
|
|
TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \
|
|
|
|
void RunWasm_##name(WasmExecutionMode execution_mode)
|
2016-05-18 15:56:11 +00:00
|
|
|
|
2017-03-13 22:12:23 +00:00
|
|
|
#define WASM_EXEC_TEST_WITH_TRAP(name) \
|
|
|
|
void RunWasm_##name(WasmExecutionMode execution_mode); \
|
|
|
|
TEST(RunWasmCompiled_##name) { \
|
|
|
|
if (trap_handler::UseTrapHandler()) { \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
RunWasm_##name(kExecuteCompiled); \
|
|
|
|
} \
|
|
|
|
TEST(RunWasmInterpreted_##name) { \
|
|
|
|
if (trap_handler::UseTrapHandler()) { \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
RunWasm_##name(kExecuteInterpreted); \
|
|
|
|
} \
|
[wasm] Introduce the TrapIf and TrapUnless operators to generate trap code.
Some instructions in WebAssembly trap for some inputs, which means that the
execution is terminated and (at least at the moment) a JavaScript exception is
thrown. Examples for traps are out-of-bounds memory accesses, or integer
divisions by zero.
Without the TrapIf and TrapUnless operators trap check in WebAssembly introduces 5
TurboFan nodes (branch, if_true, if_false, trap-reason constant, trap-position
constant), in addition to the trap condition itself. Additionally, each
WebAssembly function has four TurboFan nodes (merge, effect_phi, 2 phis) whose
number of inputs is linear to the number of trap checks in the function.
Especially for functions with high numbers of trap checks we observe a
significant slowdown in compilation time, down to 0.22 MiB/s in the sqlite
benchmark instead of the average of 3 MiB/s in other benchmarks. By introducing
a TrapIf common operator only a single node is necessary per trap check, in
addition to the trap condition. Also the nodes which are shared between trap
checks (merge, effect_phi, 2 phis) would disappear. First measurements suggest a
speedup of 30-50% on average.
This CL only implements TrapIf and TrapUnless on x64. The implementation is also
hidden behind the --wasm-trap-if flag.
Please take a special look at how the source position is transfered from the
instruction selector to the code generator, and at the context that is used for
the runtime call.
R=titzer@chromium.org
Review-Url: https://codereview.chromium.org/2562393002
Cr-Commit-Position: refs/heads/master@{#41720}
2016-12-15 13:31:29 +00:00
|
|
|
void RunWasm_##name(WasmExecutionMode execution_mode)
|
|
|
|
|
2016-01-14 09:48:45 +00:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
#endif
|