Commit 6ea3575c authored by mtrofin's avatar mtrofin Committed by Commit bot

[wasm] further simplification of WasmCompiledModule

Calculate memory size from the available heap. This avoids
the bugs due to some numbers being stored as objects (by-ref)
and thus needing special handling when cloning.

This leaves all the rest of the numbers as read-only.

Further simplified by representing globals size as a Smi.

BUG=

Committed: https://crrev.com/7ced1bdc9df2315ccc07dd17c12736aebf40cb57
Review-Url: https://codereview.chromium.org/2381393002
Cr-Original-Commit-Position: refs/heads/master@{#39923}
Cr-Commit-Position: refs/heads/master@{#39925}
parent 77b7be0c
...@@ -851,8 +851,11 @@ void PatchDirectCalls(Handle<FixedArray> old_functions, ...@@ -851,8 +851,11 @@ void PatchDirectCalls(Handle<FixedArray> old_functions,
static void ResetCompiledModule(Isolate* isolate, JSObject* owner, static void ResetCompiledModule(Isolate* isolate, JSObject* owner,
WasmCompiledModule* compiled_module) { WasmCompiledModule* compiled_module) {
Object* undefined = *isolate->factory()->undefined_value(); Object* undefined = *isolate->factory()->undefined_value();
uint32_t old_mem_size = compiled_module->mem_size(); uint32_t old_mem_size = compiled_module->has_heap()
Object* mem_start = compiled_module->ptr_to_mem_start(); ? compiled_module->mem_size()
: compiled_module->default_mem_size();
uint32_t default_mem_size = compiled_module->default_mem_size();
Object* mem_start = compiled_module->ptr_to_heap();
Address old_mem_address = nullptr; Address old_mem_address = nullptr;
Address globals_start = Address globals_start =
GetGlobalStartAddressFromCodeTemplate(undefined, owner); GetGlobalStartAddressFromCodeTemplate(undefined, owner);
...@@ -877,8 +880,8 @@ static void ResetCompiledModule(Isolate* isolate, JSObject* owner, ...@@ -877,8 +880,8 @@ static void ResetCompiledModule(Isolate* isolate, JSObject* owner,
RelocInfo::Mode mode = it.rinfo()->rmode(); RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmMemoryReference(mode) || if (RelocInfo::IsWasmMemoryReference(mode) ||
RelocInfo::IsWasmMemorySizeReference(mode)) { RelocInfo::IsWasmMemorySizeReference(mode)) {
it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr, it.rinfo()->update_wasm_memory_reference(
old_mem_size, old_mem_size); old_mem_address, nullptr, old_mem_size, default_mem_size);
changed = true; changed = true;
} else { } else {
CHECK(RelocInfo::IsWasmGlobalReference(mode)); CHECK(RelocInfo::IsWasmGlobalReference(mode));
...@@ -893,7 +896,7 @@ static void ResetCompiledModule(Isolate* isolate, JSObject* owner, ...@@ -893,7 +896,7 @@ static void ResetCompiledModule(Isolate* isolate, JSObject* owner,
} }
} }
compiled_module->reset_weak_owning_instance(); compiled_module->reset_weak_owning_instance();
compiled_module->reset_mem_start(); compiled_module->reset_heap();
} }
static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
...@@ -1050,7 +1053,8 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( ...@@ -1050,7 +1053,8 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
// and information needed at instantiation time. This object needs to be // and information needed at instantiation time. This object needs to be
// serializable. Instantiation may occur off a deserialized version of this // serializable. Instantiation may occur off a deserialized version of this
// object. // object.
Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate); Handle<WasmCompiledModule> ret = WasmCompiledModule::New(
isolate, min_mem_pages, globals_size, mem_export, origin);
ret->set_code_table(code_table); ret->set_code_table(code_table);
if (!indirect_table.is_null()) { if (!indirect_table.is_null()) {
ret->set_indirect_function_tables(indirect_table.ToHandleChecked()); ret->set_indirect_function_tables(indirect_table.ToHandleChecked());
...@@ -1124,12 +1128,8 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( ...@@ -1124,12 +1128,8 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
Handle<ByteArray> function_name_table = Handle<ByteArray> function_name_table =
BuildFunctionNamesTable(isolate, module_env.module); BuildFunctionNamesTable(isolate, module_env.module);
ret->set_function_names(function_name_table); ret->set_function_names(function_name_table);
ret->set_min_required_memory(min_mem_pages);
if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret); if (data_segments.size() > 0) SaveDataSegmentInfo(factory, this, ret);
ret->set_globals_size(globals_size); DCHECK_EQ(ret->default_mem_size(), temp_instance.mem_size);
ret->set_export_memory(mem_export);
ret->set_origin(origin);
ret->set_mem_size(temp_instance.mem_size);
return ret; return ret;
} }
...@@ -1249,7 +1249,6 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -1249,7 +1249,6 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
UNREACHABLE(); UNREACHABLE();
} }
} }
compiled_module->set_mem_size(original->mem_size());
RecordStats(isolate, code_table); RecordStats(isolate, code_table);
} else { } else {
// There was no owner, so we can reuse the original. // There was no owner, so we can reuse the original.
...@@ -1273,7 +1272,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -1273,7 +1272,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
MaybeHandle<JSArrayBuffer> old_memory; MaybeHandle<JSArrayBuffer> old_memory;
// TODO(titzer): handle imported memory properly. // TODO(titzer): handle imported memory properly.
uint32_t min_mem_pages = compiled_module->min_required_memory(); uint32_t min_mem_pages = compiled_module->min_memory_pages();
isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); isolate->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages);
// TODO(wasm): re-enable counter for max_mem_pages when we use that field. // TODO(wasm): re-enable counter for max_mem_pages when we use that field.
...@@ -1288,16 +1287,16 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -1288,16 +1287,16 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number()); uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number());
LoadDataSegments(compiled_module, mem_start, mem_size); LoadDataSegments(compiled_module, mem_start, mem_size);
uint32_t old_mem_size = compiled_module->mem_size(); uint32_t old_mem_size = compiled_module->has_heap()
? compiled_module->mem_size()
: compiled_module->default_mem_size();
Address old_mem_start = Address old_mem_start =
compiled_module->has_mem_start() compiled_module->has_heap()
? static_cast<Address>( ? static_cast<Address>(compiled_module->heap()->backing_store())
compiled_module->mem_start()->backing_store())
: nullptr; : nullptr;
RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size,
mem_size); mem_size);
compiled_module->set_mem_size(mem_size); compiled_module->set_heap(memory);
compiled_module->set_mem_start(memory);
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
...@@ -1537,6 +1536,26 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, ...@@ -1537,6 +1536,26 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
return instance; return instance;
} }
Handle<WasmCompiledModule> WasmCompiledModule::New(Isolate* isolate,
uint32_t min_memory_pages,
uint32_t globals_size,
bool export_memory,
ModuleOrigin origin) {
Handle<FixedArray> ret =
isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED);
// Globals size is expected to fit into an int without overflow. This is not
// supported by the spec at the moment, however, we don't support array
// buffer sizes over 1g, so, for now, we avoid alocating a HeapNumber for
// the globals size. The CHECK guards this assumption.
CHECK_GE(static_cast<int>(globals_size), 0);
ret->set(kID_min_memory_pages,
Smi::FromInt(static_cast<int>(min_memory_pages)));
ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size)));
ret->set(kID_export_memory, Smi::FromInt(static_cast<int>(export_memory)));
ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin)));
return handle(WasmCompiledModule::cast(*ret));
}
compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone,
uint32_t index) { uint32_t index) {
DCHECK(IsValidFunction(index)); DCHECK(IsValidFunction(index));
...@@ -1761,11 +1780,9 @@ void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) { ...@@ -1761,11 +1780,9 @@ void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
DCHECK(IsWasmObject(*instance)); DCHECK(IsWasmObject(*instance));
instance->SetInternalField(kWasmMemArrayBuffer, buffer); instance->SetInternalField(kWasmMemArrayBuffer, buffer);
Object* module = instance->GetInternalField(kWasmCompiledModule); WasmCompiledModule* module =
if (module->IsFixedArray()) { WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule));
WasmCompiledModule::cast(module)->set_mem_size( module->set_ptr_to_heap(buffer);
buffer->byte_length()->Number());
}
} }
namespace testing { namespace testing {
......
...@@ -374,19 +374,6 @@ class WasmCompiledModule : public FixedArray { ...@@ -374,19 +374,6 @@ class WasmCompiledModule : public FixedArray {
#define WCM_SMALL_NUMBER(TYPE, NAME) \ #define WCM_SMALL_NUMBER(TYPE, NAME) \
TYPE NAME() const { \ TYPE NAME() const { \
return static_cast<TYPE>(Smi::cast(get(kID_##NAME))->value()); \ return static_cast<TYPE>(Smi::cast(get(kID_##NAME))->value()); \
} \
\
void set_##NAME(TYPE value) { \
set(kID_##NAME, Smi::FromInt(static_cast<int>(value))); \
}
#define WCM_LARGE_NUMBER(TYPE, NAME) \
TYPE NAME() const { \
return static_cast<TYPE>(HeapNumber::cast(get(kID_##NAME))->value()); \
} \
\
void set_##NAME(TYPE value) { \
HeapNumber::cast(get(kID_##NAME))->set_value(static_cast<double>(value)); \
} }
#define WCM_WEAK_LINK(TYPE, NAME) \ #define WCM_WEAK_LINK(TYPE, NAME) \
...@@ -404,12 +391,11 @@ class WasmCompiledModule : public FixedArray { ...@@ -404,12 +391,11 @@ class WasmCompiledModule : public FixedArray {
MACRO(OBJECT, FixedArray, indirect_function_tables) \ MACRO(OBJECT, FixedArray, indirect_function_tables) \
MACRO(OBJECT, String, module_bytes) \ MACRO(OBJECT, String, module_bytes) \
MACRO(OBJECT, ByteArray, function_names) \ MACRO(OBJECT, ByteArray, function_names) \
MACRO(LARGE_NUMBER, uint32_t, min_required_memory) \ MACRO(SMALL_NUMBER, uint32_t, min_memory_pages) \
MACRO(OBJECT, FixedArray, data_segments_info) \ MACRO(OBJECT, FixedArray, data_segments_info) \
MACRO(OBJECT, ByteArray, data_segments) \ MACRO(OBJECT, ByteArray, data_segments) \
MACRO(LARGE_NUMBER, uint32_t, globals_size) \ MACRO(SMALL_NUMBER, uint32_t, globals_size) \
MACRO(LARGE_NUMBER, uint32_t, mem_size) \ MACRO(OBJECT, JSArrayBuffer, heap) \
MACRO(OBJECT, JSArrayBuffer, mem_start) \
MACRO(SMALL_NUMBER, bool, export_memory) \ MACRO(SMALL_NUMBER, bool, export_memory) \
MACRO(SMALL_NUMBER, ModuleOrigin, origin) \ MACRO(SMALL_NUMBER, ModuleOrigin, origin) \
MACRO(WEAK_LINK, WasmCompiledModule, next_instance) \ MACRO(WEAK_LINK, WasmCompiledModule, next_instance) \
...@@ -425,34 +411,28 @@ class WasmCompiledModule : public FixedArray { ...@@ -425,34 +411,28 @@ class WasmCompiledModule : public FixedArray {
}; };
public: public:
static Handle<WasmCompiledModule> New(Isolate* isolate) { static Handle<WasmCompiledModule> New(Isolate* isolate,
Handle<FixedArray> ret = uint32_t min_memory_pages,
isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); uint32_t globals_size,
Handle<HeapNumber> number; bool export_memory,
#define WCM_INIT_OBJECT(IGNORE1, IGNORE2) ModuleOrigin origin);
#define WCM_INIT_WEAK_LINK(IGNORE1, IGNORE2)
#define WCM_INIT_SMALL_NUMBER(IGNORE1, IGNORE2)
#define WCM_INIT_LARGE_NUMBER(IGNORE, NAME) \
number = isolate->factory()->NewHeapNumber(0.0, MUTABLE, TENURED); \
ret->set(kID_##NAME, *number);
#define INITIALIZER(KIND, TYPE, NAME) WCM_INIT_##KIND(TYPE, NAME)
WCM_PROPERTY_TABLE(INITIALIZER)
#undef INITIALIZER
return handle(WasmCompiledModule::cast(*ret));
}
static Handle<WasmCompiledModule> Clone(Isolate* isolate, static Handle<WasmCompiledModule> Clone(Isolate* isolate,
Handle<WasmCompiledModule> module) { Handle<WasmCompiledModule> module) {
Handle<WasmCompiledModule> ret = Handle<WasmCompiledModule>::cast( Handle<WasmCompiledModule> ret = Handle<WasmCompiledModule>::cast(
isolate->factory()->CopyFixedArray(module)); isolate->factory()->CopyFixedArray(module));
Handle<HeapNumber> number =
isolate->factory()->NewHeapNumber(0.0, MUTABLE, TENURED);
ret->set(kID_mem_size, *number);
ret->set_mem_size(module->mem_size());
return ret; return ret;
} }
uint32_t mem_size() const {
DCHECK(has_heap());
return heap()->byte_length()->Number();
}
uint32_t default_mem_size() const {
return min_memory_pages() * WasmModule::kPageSize;
}
#define DECLARATION(KIND, TYPE, NAME) WCM_##KIND(TYPE, NAME) #define DECLARATION(KIND, TYPE, NAME) WCM_##KIND(TYPE, NAME)
WCM_PROPERTY_TABLE(DECLARATION) WCM_PROPERTY_TABLE(DECLARATION)
#undef DECLARATION #undef DECLARATION
......
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