Commit 72dd5738 authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

Revert "Revert "[wasm] Move the ModuleEnv to compiler and make it immutable.""

This reverts commit e79d4f06.

Reason for revert: Fixed compile error

Original change's description:
> Revert "[wasm] Move the ModuleEnv to compiler and make it immutable."
> 
> This reverts commit d04660db.
> 
> Reason for revert: Suspect for blocking the roll:
> https://chromium-review.googlesource.com/c/621191
> 
> See:
> https://build.chromium.org/p/tryserver.chromium.win/builders/win_optional_gpu_tests_rel/builds/13583
> 
> Original change's description:
> > [wasm] Move the ModuleEnv to compiler and make it immutable.
> > 
> > This CL (finally) makes the contract between the compiler and the module
> > environment clear. In order to compile a function, the caller must provide
> > an instance of the compiler::ModuleEnv struct, which contains references
> > to code, function and signature tables, memory start, etc.
> > 
> > R=​mtrofin@chromium.org,ahaas@chromium.org
> > 
> > Bug: 
> > Change-Id: I68e44d5da2c5ad44dad402029c2e57f2d5d25b4f
> > Reviewed-on: https://chromium-review.googlesource.com/613880
> > Reviewed-by: Mircea Trofin <mtrofin@chromium.org>
> > Reviewed-by: Andreas Haas <ahaas@chromium.org>
> > Commit-Queue: Ben Titzer <titzer@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#47418}
> 
> TBR=titzer@chromium.org,mtrofin@chromium.org,ahaas@chromium.org
> 
> Change-Id: I60a369a43121720fbb13ea6c2ec6ca948d60a20b
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://chromium-review.googlesource.com/622547
> Commit-Queue: Michael Achenbach <machenbach@chromium.org>
> Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#47451}

TBR=machenbach@chromium.org,titzer@chromium.org,mtrofin@chromium.org,ahaas@chromium.org

Change-Id: Ie0efa6204c41b2cb672586a7ac0a622ca13ce5fe
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/622033
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: 's avatarMircea Trofin <mtrofin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47453}
parent fe4d0686
This diff is collapsed.
......@@ -32,33 +32,67 @@ class SourcePositionTable;
namespace wasm {
struct DecodeStruct;
class SignatureMap;
// Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
typedef compiler::Node TFNode;
typedef compiler::JSGraph TFGraph;
} // namespace wasm
namespace compiler {
// The {ModuleEnv} encapsulates the module data that is used by the
// {WasmGraphBuilder} during graph building. It represents the parameters to
// which the compiled code should be specialized, including which code to call
// for direct calls {function_code}, which tables to use for indirect calls
// {function_tables}, memory start address and size {mem_start, mem_size},
// globals start address {globals_start}, as well as signature maps
// {signature_maps} and the module itself {module}.
// ModuleEnvs are shareable across multiple compilations.
struct ModuleEnv {
// A pointer to the decoded module's static representation.
const wasm::WasmModule* module;
// The function tables are FixedArrays of code used to dispatch indirect
// calls. (the same length as module.function_tables)
const std::vector<Handle<FixedArray>> function_tables;
// The signatures tables are FixedArrays of SMIs used to check signatures
// match at runtime.
// (the same length as module.function_tables)
const std::vector<Handle<FixedArray>> signature_tables;
// Signature maps canonicalize {FunctionSig*} to indexes. New entries can be
// added to a signature map during graph building.
// Normally, these signature maps correspond to the signature maps in the
// function tables stored in the {module}.
const std::vector<wasm::SignatureMap*> signature_maps;
// Contains the code objects to call for each indirect call.
// (the same length as module.functions)
const std::vector<Handle<Code>> function_code;
// If the default code is not a null handle, always use it for direct calls.
const Handle<Code> default_function_code;
// Address of the start of memory.
const uintptr_t mem_start;
// Size of memory in bytes.
const uint32_t mem_size;
// Address of the start of the globals region.
const uintptr_t globals_start;
};
class WasmCompilationUnit final {
public:
// Use the following constructors if you know you are running on the
// foreground thread.
WasmCompilationUnit(Isolate* isolate, const wasm::ModuleWireBytes& wire_bytes,
const wasm::ModuleEnv* module_env,
const wasm::WasmFunction* function,
Handle<Code> centry_stub);
WasmCompilationUnit(Isolate* isolate, const wasm::ModuleEnv* module_env,
wasm::FunctionBody body, wasm::WasmName name, int index,
ModuleEnv* env, const wasm::WasmFunction* function,
Handle<Code> centry_stub);
WasmCompilationUnit(Isolate* isolate, ModuleEnv* env, wasm::FunctionBody body,
wasm::WasmName name, int index, Handle<Code> centry_stub);
// Use the following constructors if the compilation may run on a background
// thread.
WasmCompilationUnit(Isolate* isolate, const wasm::ModuleWireBytes& wire_bytes,
const wasm::ModuleEnv* module_env,
const wasm::WasmFunction* function,
ModuleEnv* env, const wasm::WasmFunction* function,
Handle<Code> centry_stub,
const std::shared_ptr<Counters>& async_counters);
WasmCompilationUnit(Isolate* isolate, const wasm::ModuleEnv* module_env,
wasm::FunctionBody body, wasm::WasmName name, int index,
Handle<Code> centry_stub,
WasmCompilationUnit(Isolate* isolate, ModuleEnv* env, wasm::FunctionBody body,
wasm::WasmName name, int index, Handle<Code> centry_stub,
const std::shared_ptr<Counters>& async_counters);
int func_index() const { return func_index_; }
......@@ -68,8 +102,8 @@ class WasmCompilationUnit final {
static MaybeHandle<Code> CompileWasmFunction(
wasm::ErrorThrower* thrower, Isolate* isolate,
const wasm::ModuleWireBytes& wire_bytes,
const wasm::ModuleEnv* module_env, const wasm::WasmFunction* function);
const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
const wasm::WasmFunction* function);
void set_memory_cost(size_t memory_cost) { memory_cost_ = memory_cost; }
size_t memory_cost() const { return memory_cost_; }
......@@ -78,7 +112,7 @@ class WasmCompilationUnit final {
SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
Isolate* isolate_;
const wasm::ModuleEnv* module_env_;
ModuleEnv* env_;
wasm::FunctionBody func_body_;
wasm::WasmName func_name_;
Counters* counters_;
......@@ -137,8 +171,8 @@ typedef ZoneVector<Node*> NodeVector;
class WasmGraphBuilder {
public:
WasmGraphBuilder(
const wasm::ModuleEnv* module_env, Zone* z, JSGraph* g,
Handle<Code> centry_stub_, wasm::FunctionSig* sig,
ModuleEnv* env, Zone* z, JSGraph* g, Handle<Code> centry_stub_,
wasm::FunctionSig* sig,
compiler::SourcePositionTable* source_position_table = nullptr);
Node** Buffer(size_t count) {
......@@ -284,19 +318,19 @@ class WasmGraphBuilder {
bool has_simd() const { return has_simd_; }
const wasm::ModuleEnv* module_env() const { return module_env_; }
void SetRuntimeExceptionSupport(bool value) {
has_runtime_exception_support_ = value;
}
const wasm::WasmModule* module() { return env_ ? env_->module : nullptr; }
private:
static const int kDefaultBufferSize = 16;
Zone* zone_;
JSGraph* jsgraph_;
Node* centry_stub_node_;
const wasm::ModuleEnv* module_env_ = nullptr;
ModuleEnv* env_ = nullptr;
Node* mem_buffer_ = nullptr;
Node* mem_size_ = nullptr;
NodeVector signature_tables_;
......
......@@ -619,11 +619,7 @@ class WasmFullDecoder : public WasmDecoder {
: WasmFullDecoder(zone, module, nullptr, body) {}
WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
: WasmFullDecoder(zone,
builder->module_env() == nullptr
? nullptr
: builder->module_env()->module(),
builder, body) {}
: WasmFullDecoder(zone, builder->module(), builder, body) {}
bool Decode() {
if (FLAG_wasm_code_fuzzer_gen_test) {
......
This diff is collapsed.
......@@ -27,7 +27,8 @@ class ModuleCompiler {
// In {CompileToModuleObject}, it will transfer ownership to the generated
// {WasmModuleWrapper}. If this method is not called, ownership may be
// reclaimed by explicitely releasing the {module_} field.
ModuleCompiler(Isolate* isolate, std::unique_ptr<WasmModule> module);
ModuleCompiler(Isolate* isolate, std::unique_ptr<WasmModule> module,
Handle<Code> centry_stub);
// The actual runnable task that performs compilations in the background.
class CompilationTask : public CancelableTask {
......@@ -48,7 +49,7 @@ class ModuleCompiler {
~CompilationUnitBuilder() { DCHECK(units_.empty()); }
void AddUnit(const ModuleEnv* module_env, const WasmFunction* function,
void AddUnit(compiler::ModuleEnv* module_env, const WasmFunction* function,
uint32_t buffer_offset, Vector<const uint8_t> bytes,
WasmName name) {
units_.emplace_back(new compiler::WasmCompilationUnit(
......@@ -128,9 +129,7 @@ class ModuleCompiler {
size_t InitializeCompilationUnits(const std::vector<WasmFunction>& functions,
const ModuleWireBytes& wire_bytes,
const ModuleEnv* module_env);
void ReopenHandlesInDeferredScope();
compiler::ModuleEnv* module_env);
void RestartCompilationTasks();
......@@ -143,17 +142,18 @@ class ModuleCompiler {
int* func_index);
void CompileInParallel(const ModuleWireBytes& wire_bytes,
const ModuleEnv* module_env,
compiler::ModuleEnv* module_env,
std::vector<Handle<Code>>& results,
ErrorThrower* thrower);
void CompileSequentially(const ModuleWireBytes& wire_bytes,
const ModuleEnv* module_env,
compiler::ModuleEnv* module_env,
std::vector<Handle<Code>>& results,
ErrorThrower* thrower);
void ValidateSequentially(const ModuleWireBytes& wire_bytes,
const ModuleEnv* module_env, ErrorThrower* thrower);
compiler::ModuleEnv* module_env,
ErrorThrower* thrower);
MaybeHandle<WasmModuleObject> CompileToModuleObject(
ErrorThrower* thrower, const ModuleWireBytes& wire_bytes,
......@@ -346,7 +346,7 @@ class AsyncCompileJob {
Handle<Context> context_;
Handle<JSPromise> module_promise_;
std::unique_ptr<ModuleCompiler> compiler_;
std::unique_ptr<ModuleEnv> module_env_;
std::unique_ptr<compiler::ModuleEnv> module_env_;
std::vector<DeferredHandles*> deferred_handles_;
Handle<WasmModuleObject> module_object_;
......@@ -365,8 +365,6 @@ class AsyncCompileJob {
}
Counters* counters() const { return async_counters().get(); }
void ReopenHandlesInDeferredScope();
void AsyncCompileFailed(ErrorThrower& thrower);
void AsyncCompileSucceeded(Handle<Object> result);
......
......@@ -12,6 +12,11 @@
namespace v8 {
namespace internal {
namespace compiler {
struct ModuleEnv;
}
namespace wasm {
const uint32_t kWasmMagic = 0x6d736100;
......@@ -106,7 +111,7 @@ V8_EXPORT_PRIVATE FunctionResult SyncDecodeWasmFunction(
const byte* function_end);
V8_EXPORT_PRIVATE FunctionResult
AsyncDecodeWasmFunction(Isolate* isolate, Zone* zone, const ModuleEnv* env,
AsyncDecodeWasmFunction(Isolate* isolate, Zone* zone, compiler::ModuleEnv* env,
const byte* function_start, const byte* function_end,
const std::shared_ptr<Counters> async_counters);
......
......@@ -95,7 +95,6 @@ void CodeSpecialization::RelocateMemoryReferences(Address old_start,
uint32_t new_size) {
DCHECK(old_mem_start == nullptr && old_mem_size == 0 &&
new_mem_start == nullptr && new_mem_size == 0);
DCHECK(old_start != new_start || old_size != new_size);
old_mem_start = old_start;
old_mem_size = old_size;
new_mem_start = new_start;
......@@ -104,14 +103,12 @@ void CodeSpecialization::RelocateMemoryReferences(Address old_start,
void CodeSpecialization::RelocateGlobals(Address old_start, Address new_start) {
DCHECK(old_globals_start == 0 && new_globals_start == 0);
DCHECK(old_start != 0 || new_start != 0);
old_globals_start = old_start;
new_globals_start = new_start;
}
void CodeSpecialization::PatchTableSize(uint32_t old_size, uint32_t new_size) {
DCHECK(old_function_table_size == 0 && new_function_table_size == 0);
DCHECK(old_size != 0 || new_size != 0);
old_function_table_size = old_size;
new_function_table_size = new_size;
}
......
......@@ -212,48 +212,42 @@ void RecordLazyCodeStats(Code* code, Counters* counters) {
counters->wasm_reloc_size()->Increment(code->relocation_info()->length());
}
ModuleEnv CreateModuleEnvFromRuntimeObject(
compiler::ModuleEnv CreateModuleEnvFromCompiledModule(
Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
DisallowHeapAllocation no_gc;
// Store a vector of handles to be embedded in the generated code.
// TODO(clemensh): For concurrent compilation, these will have to live in a
// DeferredHandleScope.
wasm::ModuleEnv module_env(compiled_module->module(),
BUILTIN_CODE(isolate, WasmCompileLazy));
// We set unchecked because the data on the compiled module
// is authoritative.
module_env.SetMemSizeUnchecked(compiled_module->has_embedded_mem_size()
? compiled_module->embedded_mem_size()
: 0);
module_env.set_mem_start(
reinterpret_cast<byte*>(compiled_module->has_embedded_mem_start()
? compiled_module->embedded_mem_start()
: 0));
module_env.set_globals_start(reinterpret_cast<byte*>(
compiled_module->has_globals_start() ? compiled_module->globals_start()
: 0));
DCHECK_EQ(compiled_module->has_function_tables(),
compiled_module->has_signature_tables());
if (compiled_module->has_function_tables()) {
// TODO(clemensh): For concurrent compilation, these will have to live in a
// DeferredHandleScope.
FixedArray* function_tables = compiled_module->ptr_to_function_tables();
FixedArray* signature_tables = compiled_module->ptr_to_signature_tables();
DCHECK_EQ(function_tables->length(), signature_tables->length());
DCHECK_EQ(function_tables->length(), module_env.function_tables().size());
for (uint32_t i = 0, e = static_cast<uint32_t>(
module_env.function_tables().size());
i < e; ++i) {
int index = static_cast<int>(i);
module_env.SetFunctionTable(
i, handle(FixedArray::cast(function_tables->get(index))),
handle(FixedArray::cast(signature_tables->get(index))));
}
WasmModule* module = compiled_module->module();
std::vector<Handle<FixedArray>> function_tables;
std::vector<Handle<FixedArray>> signature_tables;
std::vector<SignatureMap*> signature_maps;
int num_function_tables = static_cast<int>(module->function_tables.size());
for (int i = 0; i < num_function_tables; i++) {
FixedArray* ft = compiled_module->ptr_to_function_tables();
FixedArray* st = compiled_module->ptr_to_signature_tables();
// TODO(clemensh): defer these handles for concurrent compilation.
function_tables.push_back(handle(FixedArray::cast(ft->get(i))));
signature_tables.push_back(handle(FixedArray::cast(st->get(i))));
signature_maps.push_back(&module->function_tables[i].map);
}
return module_env;
std::vector<Handle<Code>> empty_code;
compiler::ModuleEnv result = {
module, // --
function_tables, // --
signature_tables, // --
signature_maps, // --
empty_code, // --
BUILTIN_CODE(isolate, WasmCompileLazy), // --
reinterpret_cast<uintptr_t>( // --
compiled_module->GetEmbeddedMemStartOrNull()), // --
compiled_module->GetEmbeddedMemSizeOrZero(), // --
reinterpret_cast<uintptr_t>( // --
compiled_module->GetGlobalsStartOrNull()) // --
};
return result;
}
} // namespace
......@@ -804,9 +798,10 @@ MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs(
// Transfer ownership to the {WasmModuleWrapper} generated in
// {CompileToModuleObject}.
ModuleCompiler helper(isolate, std::move(result.val));
return helper.CompileToModuleObject(thrower, bytes, asm_js_script,
asm_js_offset_table_bytes);
Handle<Code> centry_stub = CEntryStub(isolate, 1).GetCode();
ModuleCompiler compiler(isolate, std::move(result.val), centry_stub);
return compiler.CompileToModuleObject(thrower, bytes, asm_js_script,
asm_js_offset_table_bytes);
}
MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate,
......@@ -826,9 +821,10 @@ MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate,
// Transfer ownership to the {WasmModuleWrapper} generated in
// {CompileToModuleObject}.
ModuleCompiler helper(isolate, std::move(result.val));
return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(),
Vector<const byte>());
Handle<Code> centry_stub = CEntryStub(isolate, 1).GetCode();
ModuleCompiler compiler(isolate, std::move(result.val), centry_stub);
return compiler.CompileToModuleObject(thrower, bytes, Handle<Script>(),
Vector<const byte>());
}
MaybeHandle<WasmInstanceObject> wasm::SyncInstantiate(
......@@ -1001,12 +997,12 @@ void LazyCompilationOrchestrator::CompileFunction(
return;
}
wasm::ModuleEnv module_env =
CreateModuleEnvFromRuntimeObject(isolate, compiled_module);
compiler::ModuleEnv module_env =
CreateModuleEnvFromCompiledModule(isolate, compiled_module);
const uint8_t* module_start = compiled_module->module_bytes()->GetChars();
const WasmFunction* func = &module_env.module()->functions[func_index];
const WasmFunction* func = &module_env.module->functions[func_index];
wasm::FunctionBody body{func->sig, func->code.offset(),
module_start + func->code.offset(),
module_start + func->code.end_offset()};
......
......@@ -280,142 +280,6 @@ struct V8_EXPORT_PRIVATE ModuleWireBytes {
const Vector<const byte> module_bytes_;
};
// Specialization parameters the compiler needs to use when compiling the wasm
// functions of a module.
// We currently only produce code specialized to an instance. Even when
// compiling without instantiating, we still need to pick *a* value for these
// parameters.
class V8_EXPORT_PRIVATE ModuleEnv {
public:
MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(ModuleEnv);
ModuleEnv(WasmModule* module, Handle<Code> default_function_code)
: module_(module),
function_tables_(module->function_tables.size()),
signature_tables_(module->function_tables.size()),
default_function_code_(default_function_code),
mem_size_(module->initial_pages * WasmModule::kPageSize) {}
WasmModule* module() const { return module_; }
uint32_t mem_size() const { return mem_size_; }
void set_mem_size(uint32_t mem_size) {
DCHECK_EQ(0, mem_size % WasmModule::kPageSize);
mem_size_ = mem_size;
}
byte* mem_start() const { return mem_start_; }
void set_mem_start(byte* mem_start) { mem_start_ = mem_start; }
byte* globals_start() const { return globals_start_; }
void set_globals_start(byte* globals_start) {
globals_start_ = globals_start;
}
const std::vector<Handle<FixedArray>>& function_tables() const {
return function_tables_;
}
const std::vector<Handle<FixedArray>>& signature_tables() const {
return signature_tables_;
}
void SetFunctionTable(uint32_t index, Handle<FixedArray> function_table,
Handle<FixedArray> signature_table) {
DCHECK(IsValidTable(index));
DCHECK_EQ(function_tables_.size(), signature_tables_.size());
function_tables_[index] = function_table;
signature_tables_[index] = signature_table;
}
bool IsValidGlobal(uint32_t index) const {
return index < module_->globals.size();
}
bool IsValidFunction(uint32_t index) const {
return index < module_->functions.size();
}
bool IsValidSignature(uint32_t index) const {
return index < module_->signatures.size();
}
bool IsValidTable(uint32_t index) const {
return index < module_->function_tables.size();
}
ValueType GetGlobalType(uint32_t index) const {
DCHECK(IsValidGlobal(index));
return module_->globals[index].type;
}
FunctionSig* GetFunctionSignature(uint32_t index) const {
DCHECK(IsValidFunction(index));
// This const_cast preserves design intent, because
// FunctionSig is an immutable type.
return const_cast<FunctionSig*>(module_->functions[index].sig);
}
FunctionSig* GetSignature(uint32_t index) const {
DCHECK(IsValidSignature(index));
// This const_cast preserves design intent, because
// FunctionSig is an immutable type.
return const_cast<FunctionSig*>(module_->signatures[index]);
}
const WasmIndirectFunctionTable* GetTable(uint32_t index) const {
DCHECK(IsValidTable(index));
return &module_->function_tables[index];
}
bool is_asm_js() const { return module_->is_asm_js(); }
bool is_wasm() const { return module_->is_wasm(); }
Handle<Code> GetFunctionCode(uint32_t index) const {
if (index < function_code_.size()) {
return function_code_[index];
}
return default_function_code_;
}
// TODO(mtrofin): this is async compilation-specific. Move this out.
void ReopenHandles(Isolate* isolate) {
for (auto& table : function_tables_) {
table = handle(*table, isolate);
}
for (auto& table : signature_tables_) {
table = handle(*table, isolate);
}
for (auto& code : function_code_) {
code = handle(*code, isolate);
}
default_function_code_ = handle(*default_function_code_, isolate);
}
// Intentionally set a memory size that may not conform to
// the wasm invariant that it should be divisible by kPageSize - for test.
void SetMemSizeUnchecked(uint32_t size) { mem_size_ = size; }
protected:
// The derived class is responsible for correctly setting up the
// state. This is currently used by test, where we set up the state
// gradually, and also sometimes intentionally invalidating some
// invariants.
ModuleEnv() = default;
// decoded wasm module.
WasmModule* module_ = nullptr;
// indirect function tables.
std::vector<Handle<FixedArray>> function_tables_;
// indirect signature tables.
std::vector<Handle<FixedArray>> signature_tables_;
// a user of the compiler may choose to pre-populate this
// with code objects to be used instead of the default
std::vector<Handle<Code>> function_code_;
private:
Handle<Code> default_function_code_;
// size of the linear memory.
uint32_t mem_size_ = 0;
// start of linear memory.
byte* mem_start_ = nullptr;
// start of the globals area.
byte* globals_start_ = nullptr;
};
// A helper for printing out the names of functions.
struct WasmFunctionName {
WasmFunctionName(const WasmFunction* function, WasmName name)
......
......@@ -796,7 +796,10 @@ void WasmSharedModuleData::PrepareForLazyCompilation(
Handle<WasmCompiledModule> WasmCompiledModule::New(
Isolate* isolate, Handle<WasmSharedModuleData> shared,
Handle<FixedArray> code_table, const ModuleEnv& module_env) {
Handle<FixedArray> code_table,
const std::vector<Handle<FixedArray>>& function_tables,
const std::vector<Handle<FixedArray>>& signature_tables) {
DCHECK_EQ(function_tables.size(), signature_tables.size());
Handle<FixedArray> ret =
isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED);
// WasmCompiledModule::cast would fail since fields are not set yet.
......@@ -806,25 +809,6 @@ Handle<WasmCompiledModule> WasmCompiledModule::New(
compiled_module->set_shared(shared);
compiled_module->set_native_context(isolate->native_context());
compiled_module->set_code_table(code_table);
size_t function_table_count = shared->module()->function_tables.size();
if (function_table_count > 0) {
DCHECK_EQ(module_env.function_tables().size(),
module_env.signature_tables().size());
DCHECK_EQ(module_env.function_tables().size(), function_table_count);
int count_as_int = static_cast<int>(function_table_count);
Handle<FixedArray> sig_tables =
isolate->factory()->NewFixedArray(count_as_int, TENURED);
Handle<FixedArray> func_tables =
isolate->factory()->NewFixedArray(count_as_int, TENURED);
for (int i = 0; i < count_as_int; ++i) {
size_t index = static_cast<size_t>(i);
sig_tables->set(i, *(module_env.signature_tables()[index]));
func_tables->set(i, *(module_env.function_tables()[index]));
}
compiled_module->set_signature_tables(sig_tables);
compiled_module->set_empty_function_tables(func_tables);
compiled_module->set_function_tables(func_tables);
}
// TODO(mtrofin): we copy these because the order of finalization isn't
// reliable, and we need these at Reset (which is called at
// finalization). If the order were reliable, and top-down, we could instead
......@@ -832,6 +816,22 @@ Handle<WasmCompiledModule> WasmCompiledModule::New(
compiled_module->set_initial_pages(shared->module()->initial_pages);
compiled_module->set_num_imported_functions(
shared->module()->num_imported_functions);
int num_function_tables = static_cast<int>(function_tables.size());
if (num_function_tables > 0) {
Handle<FixedArray> st =
isolate->factory()->NewFixedArray(num_function_tables, TENURED);
Handle<FixedArray> ft =
isolate->factory()->NewFixedArray(num_function_tables, TENURED);
for (int i = 0; i < num_function_tables; ++i) {
st->set(i, *(signature_tables[i]));
ft->set(i, *(function_tables[i]));
}
compiled_module->set_signature_tables(st);
compiled_module->set_empty_function_tables(ft);
compiled_module->set_function_tables(ft);
}
// TODO(mtrofin): copy the rest of the specialization parameters over.
// We're currently OK because we're only using defaults.
return compiled_module;
......@@ -871,7 +871,7 @@ void WasmCompiledModule::Reset(Isolate* isolate,
Object* undefined = *isolate->factory()->undefined_value();
Object* fct_obj = compiled_module->ptr_to_code_table();
if (fct_obj != nullptr && fct_obj != undefined) {
uint32_t old_mem_size = compiled_module->mem_size();
uint32_t old_mem_size = compiled_module->GetEmbeddedMemSizeOrZero();
// We use default_mem_size throughout, as the mem size of an uninstantiated
// module, because if we can statically prove a memory access is over
// bounds, we'll codegen a trap. See {WasmGraphBuilder::BoundsCheckMem}
......@@ -1069,11 +1069,6 @@ void WasmCompiledModule::ReinitializeAfterDeserialization(
DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared));
}
uint32_t WasmCompiledModule::mem_size() const {
DCHECK(has_embedded_mem_size() == has_embedded_mem_start());
return has_embedded_mem_start() ? embedded_mem_size() : default_mem_size();
}
uint32_t WasmCompiledModule::default_mem_size() const {
return initial_pages() * WasmModule::kPageSize;
}
......
......@@ -386,7 +386,7 @@ class WasmCompiledModule : public FixedArray {
MACRO(OBJECT, FixedArray, weak_exported_functions) \
MACRO(OBJECT, FixedArray, function_tables) \
MACRO(OBJECT, FixedArray, signature_tables) \
MACRO(CONST_OBJECT, FixedArray, empty_function_tables) \
MACRO(OBJECT, FixedArray, empty_function_tables) \
MACRO(LARGE_NUMBER, size_t, embedded_mem_start) \
MACRO(LARGE_NUMBER, size_t, globals_start) \
MACRO(LARGE_NUMBER, uint32_t, embedded_mem_size) \
......@@ -417,32 +417,31 @@ class WasmCompiledModule : public FixedArray {
};
public:
static Handle<WasmCompiledModule> New(Isolate* isolate,
Handle<WasmSharedModuleData> shared,
Handle<FixedArray> code_table,
const wasm::ModuleEnv& module_env);
static Handle<WasmCompiledModule> New(
Isolate* isolate, Handle<WasmSharedModuleData> shared,
Handle<FixedArray> code_table,
const std::vector<Handle<FixedArray>>& function_tables,
const std::vector<Handle<FixedArray>>& signature_tables);
static Handle<WasmCompiledModule> Clone(Isolate* isolate,
Handle<WasmCompiledModule> module);
static void Reset(Isolate* isolate, WasmCompiledModule* module);
Address GetEmbeddedMemStartOrNull() const {
DisallowHeapAllocation no_gc;
if (has_embedded_mem_start()) {
return reinterpret_cast<Address>(embedded_mem_start());
}
return nullptr;
return has_embedded_mem_start()
? reinterpret_cast<Address>(embedded_mem_start())
: nullptr;
}
Address GetGlobalsStartOrNull() const {
DisallowHeapAllocation no_gc;
if (has_globals_start()) {
return reinterpret_cast<Address>(globals_start());
}
return nullptr;
return has_globals_start() ? reinterpret_cast<Address>(globals_start())
: nullptr;
}
uint32_t GetEmbeddedMemSizeOrZero() const {
return has_embedded_mem_size() ? embedded_mem_size() : 0;
}
uint32_t mem_size() const;
uint32_t default_mem_size() const;
void ResetSpecializationMemInfoIfNeeded();
......
......@@ -141,7 +141,7 @@ Handle<JSObject> MakeFakeBreakpoint(Isolate* isolate, int position) {
void SetBreakpoint(WasmRunnerBase& runner, int function_index, int byte_offset,
int expected_set_byte_offset = -1) {
int func_offset =
runner.module().module()->functions[function_index].code.offset();
runner.module().GetFunctionAt(function_index)->code.offset();
int code_offset = func_offset + byte_offset;
if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset;
Handle<WasmInstanceObject> instance = runner.module().instance_object();
......
This diff is collapsed.
......@@ -14,6 +14,7 @@ function instantiate(buffer, ffi) {
}
(function BasicTest() {
print("BasicTest");
let builder = new WasmModuleBuilder();
builder.addMemory(1, 2, false);
builder.addFunction("foo", kSig_i_v)
......@@ -26,6 +27,7 @@ function instantiate(buffer, ffi) {
})();
(function ImportTest() {
print("ImportTest");
let builder = new WasmModuleBuilder();
var index = builder.addImport("", "print", makeSig_v_x(kWasmI32));
builder.addFunction("foo", kSig_v_v)
......@@ -39,6 +41,7 @@ function instantiate(buffer, ffi) {
})();
(function LocalsTest() {
print("LocalsTest");
let builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_i)
.addLocals({i32_count: 1})
......@@ -52,6 +55,7 @@ function instantiate(buffer, ffi) {
})();
(function LocalsTest2() {
print("LocalsTest2");
// TODO(titzer): i64 only works on 64-bit platforms.
var types = [
{locals: {i32_count: 1}, type: kWasmI32},
......@@ -75,6 +79,7 @@ function instantiate(buffer, ffi) {
})();
(function CallTest() {
print("CallTest");
let builder = new WasmModuleBuilder();
builder.addFunction("add", kSig_i_ii)
.addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
......@@ -88,6 +93,7 @@ function instantiate(buffer, ffi) {
})();
(function IndirectCallTest() {
print("IndirectCallTest");
let builder = new WasmModuleBuilder();
builder.addFunction("add", kSig_i_ii)
.addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
......@@ -104,6 +110,7 @@ function instantiate(buffer, ffi) {
})();
(function DataSegmentTest() {
print("DataSegmentTest");
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false);
builder.addFunction("load", kSig_i_i)
......@@ -118,6 +125,7 @@ function instantiate(buffer, ffi) {
(function BasicTestWithUint8Array() {
print("BasicTestWithUint8Array");
let builder = new WasmModuleBuilder();
builder.addMemory(1, 2, false);
builder.addFunction("foo", kSig_i_v)
......@@ -144,6 +152,7 @@ function instantiate(buffer, ffi) {
})();
(function ImportTestTwoLevel() {
print("ImportTestTwoLevel");
let builder = new WasmModuleBuilder();
var index = builder.addImport("mod", "print", makeSig_v_x(kWasmI32));
builder.addFunction("foo", kSig_v_v)
......
......@@ -985,16 +985,11 @@ TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type2) {
class WasmFunctionVerifyTest : public TestWithIsolateAndZone {
public:
WasmFunctionVerifyTest() : env(&module, Handle<Code>::null()) {}
WasmFunctionVerifyTest() {}
virtual ~WasmFunctionVerifyTest() {}
const ModuleEnv* get_env() const { return &env; }
Vector<const byte> get_bytes() const { return bytes; }
private:
WasmModule module;
Vector<const byte> bytes;
ModuleEnv env;
DISALLOW_COPY_AND_ASSIGN(WasmFunctionVerifyTest);
};
......@@ -1013,9 +1008,8 @@ TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) {
kExprEnd // body
};
FunctionResult result =
SyncDecodeWasmFunction(isolate(), zone(), get_bytes(),
get_env()->module(), data, data + sizeof(data));
FunctionResult result = SyncDecodeWasmFunction(
isolate(), zone(), bytes, &module, data, data + sizeof(data));
EXPECT_OK(result);
if (result.val && result.ok()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment