Commit 18d816e9 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Clean up fields and methods in NativeModule

1) The code table never grows, so store it in a heap-allocated byte
   array instead of an std::vector.
2) Rename {functions_count} to {num_functions} for consistency with
   {num_imported_functions} and occurences in other data structures.

R=mstarzinger@chromium.org

Bug: v8:7754
Change-Id: Id9d66545ed7aa675d663dad5936a9ef6d44ace7d
Reviewed-on: https://chromium-review.googlesource.com/1066014
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53488}
parent c96ac82c
......@@ -1949,8 +1949,8 @@ bool LiftoffCompilationUnit::ExecuteCompilation() {
compiler::GetWasmCallDescriptor(&zone, wasm_unit_->func_body_.sig);
base::Optional<TimedHistogramScope> liftoff_compile_time_scope(
base::in_place, wasm_unit_->counters_->liftoff_compile_time());
wasm::WasmCode* const* code_table_entry =
wasm_unit_->native_module_->code_table().data() + wasm_unit_->func_index_;
wasm::WasmCode** code_table_entry =
&wasm_unit_->native_module_->code_table()[wasm_unit_->func_index_];
DCHECK(!protected_instructions_);
protected_instructions_.reset(
new std::vector<trap_handler::ProtectedInstructionData>());
......
......@@ -685,7 +685,7 @@ const wasm::WasmCode* LazyCompileDirectCall(Isolate* isolate,
int32_t callee_func_index =
ExtractDirectCallIndex(decoder, func_bytes + byte_pos);
DCHECK_LT(callee_func_index,
wasm_caller->native_module()->function_count());
wasm_caller->native_module()->num_functions());
// {caller_ret_offset} points to one instruction after the call.
// Remember the last called function before that offset.
if (offset < caller_ret_offset) {
......@@ -871,7 +871,7 @@ bool compile_lazy(const WasmModule* module) {
void FlushICache(const wasm::NativeModule* native_module) {
for (uint32_t i = native_module->num_imported_functions(),
e = native_module->function_count();
e = native_module->num_functions();
i < e; ++i) {
const wasm::WasmCode* code = native_module->code(i);
if (code == nullptr) continue;
......@@ -907,7 +907,7 @@ void RecordStats(const wasm::WasmCode* code, Counters* counters) {
void RecordStats(const wasm::NativeModule* native_module, Counters* counters) {
for (uint32_t i = native_module->num_imported_functions(),
e = native_module->function_count();
e = native_module->num_functions();
i < e; ++i) {
const wasm::WasmCode* code = native_module->code(i);
if (code != nullptr) RecordStats(code, counters);
......
......@@ -374,7 +374,7 @@ NativeModule::NativeModule(uint32_t num_functions, uint32_t num_imports,
bool can_request_more, VirtualMemory* code_space,
WasmCodeManager* code_manager, ModuleEnv& env)
: instance_id(next_id_.Increment(1)),
code_table_(num_functions),
num_functions_(num_functions),
num_imported_functions_(num_imports),
compilation_state_(NewCompilationState(
reinterpret_cast<Isolate*>(code_manager->isolate_), env)),
......@@ -382,31 +382,32 @@ NativeModule::NativeModule(uint32_t num_functions, uint32_t num_imports,
wasm_code_manager_(code_manager),
can_request_more_memory_(can_request_more),
use_trap_handler_(env.use_trap_handler) {
if (num_functions > 0) {
code_table_.reset(new WasmCode*[num_functions]);
memset(code_table_.get(), 0, num_functions * sizeof(WasmCode*));
}
VirtualMemory my_mem;
owned_code_space_.push_back(my_mem);
owned_code_space_.back().TakeControl(code_space);
owned_code_.reserve(num_functions);
}
void NativeModule::ResizeCodeTableForTesting(size_t num_functions,
size_t max_functions) {
DCHECK_LE(num_functions, max_functions);
if (num_imported_functions_ == num_functions) {
// For some tests, the code table might have been initialized to store
// a number of imported functions on creation. If that is the case,
// we need to retroactively reserve the space.
DCHECK_EQ(code_table_.capacity(), num_imported_functions_);
DCHECK_EQ(code_table_.size(), num_imported_functions_);
DCHECK_EQ(num_functions, 1);
code_table_.reserve(max_functions);
} else {
DCHECK_GT(num_functions, function_count());
if (code_table_.capacity() == 0) {
code_table_.reserve(max_functions);
}
DCHECK_EQ(code_table_.capacity(), max_functions);
code_table_.resize(num_functions);
}
void NativeModule::ReserveCodeTableForTesting(uint32_t max_functions) {
DCHECK_LE(num_functions_, max_functions);
WasmCode** new_table = new WasmCode*[max_functions];
memset(new_table, 0, max_functions * sizeof(*new_table));
memcpy(new_table, code_table_.get(), num_functions_ * sizeof(*new_table));
code_table_.reset(new_table);
}
void NativeModule::SetNumFunctionsForTesting(uint32_t num_functions) {
num_functions_ = num_functions;
}
void NativeModule::SetCodeForTesting(uint32_t index, WasmCode* code) {
DCHECK_LT(index, num_functions_);
DCHECK_LT(num_imported_functions_, index);
code_table_[index] = code;
}
WasmCode* NativeModule::AddOwnedCode(
......@@ -467,15 +468,13 @@ WasmCode* NativeModule::AddInterpreterEntry(Handle<Code> code, uint32_t index) {
void NativeModule::SetLazyBuiltin(Handle<Code> code) {
WasmCode* lazy_builtin = AddAnonymousCode(code, WasmCode::kLazyStub);
for (uint32_t i = num_imported_functions(), e = function_count(); i < e;
++i) {
for (uint32_t i = num_imported_functions_, e = num_functions_; i < e; ++i) {
code_table_[i] = lazy_builtin;
}
}
void NativeModule::SetRuntimeStubs(Isolate* isolate) {
DCHECK(runtime_stub_table_.empty());
runtime_stub_table_.resize(WasmCode::kRuntimeStubCount);
DCHECK_NULL(runtime_stub_table_[0]); // Only called once.
#define COPY_BUILTIN(Name) \
runtime_stub_table_[WasmCode::k##Name] = \
AddAnonymousCode(isolate->builtins()->builtin_handle(Builtins::k##Name), \
......@@ -764,29 +763,24 @@ Address NativeModule::GetCallTargetForFunction(uint32_t func_index) {
return wasm_code->instruction_start();
}
#if DEBUG
auto num_imported_functions =
shared_module_data()->module()->num_imported_functions;
if (func_index < num_imported_functions) {
DCHECK(!wasm_code->IsAnonymous());
}
#endif
DCHECK_IMPLIES(func_index < num_imported_functions_,
!wasm_code->IsAnonymous());
if (!wasm_code->IsAnonymous()) {
// If the function wasn't imported, its index should match.
DCHECK_IMPLIES(func_index >= num_imported_functions,
DCHECK_IMPLIES(func_index >= num_imported_functions_,
func_index == wasm_code->index());
return wasm_code->instruction_start();
}
if (!lazy_compile_stubs_.get()) {
lazy_compile_stubs_ =
base::make_unique<std::vector<WasmCode*>>(function_count());
if (lazy_compile_stubs_ == nullptr) {
lazy_compile_stubs_.reset(new WasmCode*[num_functions_]);
memset(lazy_compile_stubs_.get(), 0, num_functions_ * sizeof(WasmCode*));
}
WasmCode* cloned_code = lazy_compile_stubs_.get()->at(func_index);
WasmCode* cloned_code = lazy_compile_stubs_[func_index];
if (cloned_code == nullptr) {
cloned_code = CloneCode(wasm_code, WasmCode::kNoFlushICache);
RelocateCode(cloned_code, wasm_code, WasmCode::kFlushICache);
cloned_code->index_ = Just(func_index);
lazy_compile_stubs_.get()->at(func_index) = cloned_code;
lazy_compile_stubs_[func_index] = cloned_code;
}
DCHECK_EQ(func_index, cloned_code->index());
return cloned_code->instruction_start();
......@@ -824,8 +818,7 @@ WasmCode* NativeModule::CloneCode(const WasmCode* original_code,
}
void NativeModule::UnpackAndRegisterProtectedInstructions() {
for (uint32_t i = num_imported_functions(), e = function_count(); i < e;
++i) {
for (uint32_t i = num_imported_functions_, e = num_functions_; i < e; ++i) {
WasmCode* wasm_code = code(i);
if (wasm_code == nullptr) continue;
wasm_code->RegisterTrapHandlerData();
......@@ -833,8 +826,7 @@ void NativeModule::UnpackAndRegisterProtectedInstructions() {
}
void NativeModule::ReleaseProtectedInstructions() {
for (uint32_t i = num_imported_functions(), e = function_count(); i < e;
++i) {
for (uint32_t i = num_imported_functions_, e = num_functions_; i < e; ++i) {
WasmCode* wasm_code = code(i);
if (wasm_code->HasTrapHandlerIndex()) {
CHECK_LT(wasm_code->trap_handler_index(),
......
......@@ -263,28 +263,15 @@ class V8_EXPORT_PRIVATE NativeModule final {
// resolved during relocation.
void SetRuntimeStubs(Isolate* isolate);
// function_count is WasmModule::functions.size().
uint32_t function_count() const {
DCHECK_LE(code_table_.size(), std::numeric_limits<uint32_t>::max());
return static_cast<uint32_t>(code_table_.size());
}
WasmCode* code(uint32_t index) const {
DCHECK_LT(index, function_count());
DCHECK_LE(num_imported_functions(), index);
DCHECK_LT(index, num_functions_);
DCHECK_LE(num_imported_functions_, index);
return code_table_[index];
}
// TODO(clemensh): Remove this method once we have the jump table
// (crbug.com/v8/7758).
void SetCodeForTesting(uint32_t index, WasmCode* code) {
DCHECK_LT(index, function_count());
DCHECK_LE(num_imported_functions(), index);
code_table_[index] = code;
}
bool has_code(uint32_t index) const {
DCHECK_LT(index, function_count());
DCHECK_LT(index, num_functions_);
DCHECK_LE(num_imported_functions_, index);
return code_table_[index] != nullptr;
}
......@@ -308,7 +295,9 @@ class V8_EXPORT_PRIVATE NativeModule final {
// For cctests, where we build both WasmModule and the runtime objects
// on the fly, and bypass the instance builder pipeline.
void ResizeCodeTableForTesting(size_t num_functions, size_t max_functions);
void ReserveCodeTableForTesting(uint32_t max_functions);
void SetNumFunctionsForTesting(uint32_t num_functions);
void SetCodeForTesting(uint32_t index, WasmCode* code);
CompilationState* compilation_state() { return compilation_state_.get(); }
......@@ -317,8 +306,11 @@ class V8_EXPORT_PRIVATE NativeModule final {
WasmSharedModuleData* shared_module_data() const;
void SetSharedModuleData(Handle<WasmSharedModuleData>);
uint32_t num_functions() const { return num_functions_; }
uint32_t num_imported_functions() const { return num_imported_functions_; }
const std::vector<WasmCode*>& code_table() const { return code_table_; }
Vector<WasmCode*> code_table() const {
return {code_table_.get(), num_functions_};
}
bool use_trap_handler() const { return use_trap_handler_; }
void set_lazy_compile_frozen(bool frozen) { lazy_compile_frozen_ = frozen; }
bool lazy_compile_frozen() const { return lazy_compile_frozen_; }
......@@ -363,10 +355,12 @@ class V8_EXPORT_PRIVATE NativeModule final {
// according to the codes instruction start address to allow lookups.
std::vector<std::unique_ptr<WasmCode>> owned_code_;
std::vector<WasmCode*> code_table_;
std::vector<WasmCode*> runtime_stub_table_;
std::unique_ptr<std::vector<WasmCode*>> lazy_compile_stubs_;
uint32_t num_functions_;
uint32_t num_imported_functions_;
std::unique_ptr<WasmCode* []> code_table_;
std::unique_ptr<WasmCode* []> lazy_compile_stubs_;
WasmCode* runtime_stub_table_[WasmCode::kRuntimeStubCount] = {nullptr};
// Maps from instruction start of an immovable code object to instruction
// start of the trampoline.
......
......@@ -562,7 +562,7 @@ Handle<FixedArray> GetOrCreateInterpretedFunctions(
int num_functions = debug_info->wasm_instance()
->compiled_module()
->GetNativeModule()
->function_count();
->num_functions();
Handle<FixedArray> new_arr = isolate->factory()->NewFixedArray(num_functions);
debug_info->set_interpreted_functions(*new_arr);
return new_arr;
......@@ -603,7 +603,7 @@ void RedirectCallsitesInInstance(Isolate* isolate, WasmInstanceObject* instance,
wasm::NativeModule* native_module =
instance->compiled_module()->GetNativeModule();
for (uint32_t i = native_module->num_imported_functions(),
e = native_module->function_count();
e = native_module->num_functions();
i < e; ++i) {
wasm::WasmCode* code = native_module->code(i);
RedirectCallsitesInCode(isolate, code, map);
......
......@@ -1561,10 +1561,10 @@ void WasmCompiledModule::LogWasmCodes(Isolate* isolate) {
if (native_module == nullptr) return;
// TODO(titzer): we skip the logging of the import wrappers
// here, but they should be included somehow.
const uint32_t start =
const uint32_t num_imported_functions =
native_module->shared_module_data()->module()->num_imported_functions;
const uint32_t number_of_codes = native_module->function_count();
for (uint32_t i = start; i < number_of_codes; i++) {
const uint32_t num_functions = native_module->num_functions();
for (uint32_t i = num_imported_functions; i < num_functions; i++) {
wasm::WasmCode* code = native_module->code(i);
if (code == nullptr) continue;
code->LogCode(isolate);
......
......@@ -277,7 +277,7 @@ size_t NativeModuleSerializer::MeasureCode(const WasmCode* code) const {
size_t NativeModuleSerializer::Measure() const {
size_t size = kHeaderSize;
uint32_t first_wasm_fn = native_module_->num_imported_functions();
uint32_t total_fns = native_module_->function_count();
uint32_t total_fns = native_module_->num_functions();
for (uint32_t i = first_wasm_fn; i < total_fns; ++i) {
size += kCodeHeaderSize;
size += MeasureCode(native_module_->code(i));
......@@ -286,7 +286,7 @@ size_t NativeModuleSerializer::Measure() const {
}
void NativeModuleSerializer::WriteHeader(Writer* writer) {
writer->Write(native_module_->function_count());
writer->Write(native_module_->num_functions());
writer->Write(native_module_->num_imported_functions());
}
......@@ -385,7 +385,7 @@ bool NativeModuleSerializer::Write(Writer* writer) {
WriteHeader(writer);
uint32_t total_fns = native_module_->function_count();
uint32_t total_fns = native_module_->num_functions();
uint32_t first_wasm_fn = native_module_->num_imported_functions();
for (uint32_t i = first_wasm_fn; i < total_fns; ++i) {
const WasmCode* code = native_module_->code(i);
......@@ -443,7 +443,7 @@ bool NativeModuleDeserializer::Read(Reader* reader) {
read_called_ = true;
if (!ReadHeader(reader)) return false;
uint32_t total_fns = native_module_->function_count();
uint32_t total_fns = native_module_->num_functions();
uint32_t first_wasm_fn = native_module_->num_imported_functions();
for (uint32_t i = first_wasm_fn; i < total_fns; ++i) {
if (!ReadCode(i, reader)) return false;
......@@ -454,7 +454,7 @@ bool NativeModuleDeserializer::Read(Reader* reader) {
bool NativeModuleDeserializer::ReadHeader(Reader* reader) {
size_t functions = reader->Read<uint32_t>();
size_t imports = reader->Read<uint32_t>();
return functions == native_module_->function_count() &&
return functions == native_module_->num_functions() &&
imports == native_module_->num_imported_functions();
}
......@@ -538,8 +538,8 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
case RelocInfo::WASM_CODE_TABLE_ENTRY: {
DCHECK(FLAG_wasm_tier_up);
DCHECK(ret->is_liftoff());
WasmCode* const* code_table_entry =
native_module_->code_table().data() + ret->index();
WasmCode** code_table_entry =
&native_module_->code_table()[ret->index()];
iter.rinfo()->set_wasm_code_table_entry(
reinterpret_cast<Address>(code_table_entry), SKIP_ICACHE_FLUSH);
break;
......
......@@ -48,8 +48,9 @@ TestingModuleBuilder::TestingModuleBuilder(
maybe_import_index, test_module_->origin,
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler
: kNoTrapHandler);
native_module_->ResizeCodeTableForTesting(maybe_import_index + 1,
kMaxFunctions);
if (native_module_->num_functions() <= maybe_import_index) {
native_module_->SetNumFunctionsForTesting(maybe_import_index + 1);
}
auto wasm_to_js_wrapper = native_module_->AddCodeCopy(
code, wasm::WasmCode::kWasmToJsWrapper, maybe_import_index);
......@@ -99,8 +100,8 @@ uint32_t TestingModuleBuilder::AddFunction(FunctionSig* sig, const char* name) {
test_module_->functions.reserve(kMaxFunctions);
}
uint32_t index = static_cast<uint32_t>(test_module_->functions.size());
if (native_module_) {
native_module_->ResizeCodeTableForTesting(index + 1, kMaxFunctions);
if (native_module_ && native_module_->num_functions() <= index) {
native_module_->SetNumFunctionsForTesting(index + 1);
}
test_module_->functions.push_back({sig, index, 0, {0, 0}, false, false});
if (name) {
......@@ -231,6 +232,7 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
// 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.
native_module_ = compiled_module->GetNativeModule();
native_module_->ReserveCodeTableForTesting(kMaxFunctions);
DCHECK(compiled_module->IsWasmCompiledModule());
auto instance =
......
......@@ -98,7 +98,7 @@ class TestingModuleBuilder {
byte* AddMemory(uint32_t size);
size_t CodeTableLength() const { return native_module_->function_count(); }
size_t CodeTableLength() const { return native_module_->num_functions(); }
template <typename T>
T* AddMemoryElems(uint32_t count) {
......
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