Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Unified Diff: src/wasm/wasm-module.cc

Issue 2591653002: [wasm] Introduce WasmSharedModuleData and refactor other objects (Closed)
Patch Set: Fix SLOW_DCHECK Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wasm/wasm-module.cc
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
index 9691d6bf1543609fea896905f271702ade5e7b05..21f76754bac4719e4ec772887acf2c7c222f314d 100644
--- a/src/wasm/wasm-module.cc
+++ b/src/wasm/wasm-module.cc
@@ -282,7 +282,7 @@ Address GetGlobalStartAddressFromCodeTemplate(Object* undefined,
Address old_address = nullptr;
if (instance->has_globals_buffer()) {
old_address =
- static_cast<Address>(instance->get_globals_buffer()->backing_store());
+ static_cast<Address>(instance->globals_buffer()->backing_store());
}
return old_address;
}
@@ -551,12 +551,12 @@ static void MemoryInstanceFinalizer(Isolate* isolate,
// If the memory object is destroyed, nothing needs to be done here.
if (!instance->has_memory_object()) return;
Handle<WasmInstanceWrapper> instance_wrapper =
- handle(instance->get_instance_wrapper());
+ handle(instance->instance_wrapper());
DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
DCHECK(instance_wrapper->has_instance());
bool has_prev = instance_wrapper->has_previous();
bool has_next = instance_wrapper->has_next();
- Handle<WasmMemoryObject> memory_object(instance->get_memory_object());
+ Handle<WasmMemoryObject> memory_object(instance->memory_object());
if (!has_prev && !has_next) {
memory_object->ResetInstancesLink(isolate);
@@ -592,10 +592,10 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
WasmInstanceObject* owner = reinterpret_cast<WasmInstanceObject*>(*p);
Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
- // Is a link to shared memory instances exists, update the list of memory
+ // If a link to shared memory instances exists, update the list of memory
// instances before the instance is destroyed.
if (owner->has_instance_wrapper()) MemoryInstanceFinalizer(isolate, owner);
- WasmCompiledModule* compiled_module = owner->get_compiled_module();
+ WasmCompiledModule* compiled_module = owner->compiled_module();
TRACE("Finalizing %d {\n", compiled_module->instance_id());
DCHECK(compiled_module->has_weak_wasm_module());
WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module();
@@ -670,6 +670,34 @@ std::pair<int, int> GetFunctionOffsetAndLength(
static_cast<int>(func.code_end_offset - func.code_start_offset)};
}
+Handle<Script> CreateWasmScript(Isolate* isolate,
+ const ModuleWireBytes& wire_bytes) {
+ Handle<Script> script =
+ isolate->factory()->NewScript(isolate->factory()->empty_string());
+ script->set_type(Script::TYPE_WASM);
+
+ int hash = StringHasher::HashSequentialString(
+ reinterpret_cast<const char*>(wire_bytes.module_bytes.start()),
+ wire_bytes.module_bytes.length(), kZeroHashSeed);
+
+ const int kBufferSize = 50;
+ char buffer[kBufferSize];
+ int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash);
+ DCHECK(url_chars >= 0 && url_chars < kBufferSize);
+ MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte(
+ Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars),
+ TENURED);
+ script->set_source_url(*url_str.ToHandleChecked());
+
+ int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash);
+ DCHECK(name_chars >= 0 && name_chars < kBufferSize);
+ MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte(
+ Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars),
+ TENURED);
+ script->set_name(*name_str.ToHandleChecked());
+
+ return script;
+}
} // namespace
Handle<JSArrayBuffer> wasm::NewArrayBuffer(Isolate* isolate, size_t size,
@@ -804,7 +832,9 @@ WasmModule::WasmModule(Zone* owned)
MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper,
- ErrorThrower* thrower, const ModuleWireBytes& wire_bytes) const {
+ ErrorThrower* thrower, const ModuleWireBytes& wire_bytes,
+ Handle<Script> asm_js_script,
+ Vector<const byte> asm_js_offset_table_bytes) const {
Factory* factory = isolate->factory();
MaybeHandle<WasmCompiledModule> nothing;
@@ -885,12 +915,40 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
}
}
+ // Create heap objects for script, module bytes and asm.js offset table to be
+ // stored in the shared module data.
+ Handle<Script> script;
+ Handle<ByteArray> asm_js_offset_table;
+ if (asm_js_script.is_null()) {
+ script = CreateWasmScript(isolate, wire_bytes);
+ } else {
+ script = asm_js_script;
+ asm_js_offset_table =
+ isolate->factory()->NewByteArray(asm_js_offset_table_bytes.length());
+ asm_js_offset_table->copy_in(0, asm_js_offset_table_bytes.start(),
+ asm_js_offset_table_bytes.length());
+ }
+ // TODO(wasm): only save the sections necessary to deserialize a
+ // {WasmModule}. E.g. function bodies could be omitted.
+ Handle<String> module_bytes =
+ factory->NewStringFromOneByte(wire_bytes.module_bytes, TENURED)
+ .ToHandleChecked();
+ DCHECK(module_bytes->IsSeqOneByteString());
+
+ // Create the shared module data.
+ // TODO(clemensh): For the same module (same bytes / same hash), we should
+ // only have one WasmSharedModuleData. Otherwise, we might only set
+ // breakpoints on a (potentially empty) subset of the instances.
+
+ Handle<WasmSharedModuleData> shared = WasmSharedModuleData::New(
+ isolate, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes),
+ script, asm_js_offset_table);
+
// Create the compiled module object, and populate with compiled functions
// and information needed at instantiation time. This object needs to be
// serializable. Instantiation may occur off a deserialized version of this
// object.
- Handle<WasmCompiledModule> ret =
- WasmCompiledModule::New(isolate, module_wrapper);
+ Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate, shared);
ret->set_code_table(code_table);
ret->set_min_mem_pages(min_mem_pages);
ret->set_max_mem_pages(max_mem_pages);
@@ -899,6 +957,13 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
ret->set_empty_function_tables(function_tables);
}
+ // If we created a wasm script, finish it now and make it public to the
+ // debugger.
+ if (asm_js_script.is_null()) {
+ script->set_wasm_compiled_module(*ret);
+ isolate->debug()->OnAfterCompile(script);
+ }
+
// Compile JS->WASM wrappers for exported functions.
int func_index = 0;
for (auto exp : export_table) {
@@ -913,16 +978,6 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
func_index++;
}
- {
- // TODO(wasm): only save the sections necessary to deserialize a
- // {WasmModule}. E.g. function bodies could be omitted.
- Handle<String> module_bytes_string =
- factory->NewStringFromOneByte(wire_bytes.module_bytes, TENURED)
- .ToHandleChecked();
- DCHECK(module_bytes_string->IsSeqOneByteString());
- ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string));
- }
-
return ret;
}
@@ -1114,9 +1169,7 @@ class WasmInstanceBuilder {
}
compiled_module_->set_code_table(code_table);
}
- module_ = reinterpret_cast<WasmModuleWrapper*>(
- *compiled_module_->module_wrapper())
- ->get();
+ module_ = compiled_module_->module();
//--------------------------------------------------------------------------
// Allocate the instance object.
@@ -1236,7 +1289,7 @@ class WasmInstanceBuilder {
//--------------------------------------------------------------------------
DCHECK(wasm::IsWasmInstance(*instance));
if (instance->has_memory_object()) {
- instance->get_memory_object()->AddInstance(isolate_, instance);
+ instance->memory_object()->AddInstance(isolate_, instance);
}
//--------------------------------------------------------------------------
@@ -1300,7 +1353,7 @@ class WasmInstanceBuilder {
// we want all the publishing to happen free from GC interruptions, and
// so we do it in
// one GC-free scope afterwards.
- original = handle(owner.ToHandleChecked()->get_compiled_module());
+ original = handle(owner.ToHandleChecked()->compiled_module());
link_to_original = factory->NewWeakCell(original.ToHandleChecked());
}
// Publish the new instance to the instances chain.
@@ -1445,7 +1498,8 @@ class WasmInstanceBuilder {
// Load data segments into the memory.
void LoadDataSegments(Address mem_addr, size_t mem_size) {
- Handle<SeqOneByteString> module_bytes = compiled_module_->module_bytes();
+ Handle<SeqOneByteString> module_bytes(compiled_module_->module_bytes(),
+ isolate_);
for (const WasmDataSegment& segment : module_->data_segments) {
uint32_t source_size = segment.source_size;
// Segments of size == 0 are just nops.
@@ -1560,7 +1614,7 @@ class WasmInstanceBuilder {
TableInstance& table_instance = table_instances_[num_imported_tables];
table_instance.table_object = Handle<WasmTableObject>::cast(value);
table_instance.js_wrappers = Handle<FixedArray>(
- table_instance.table_object->get_functions(), isolate_);
+ table_instance.table_object->functions(), isolate_);
// TODO(titzer): import table size must match exactly for now.
int table_size = table_instance.js_wrappers->length();
@@ -1608,7 +1662,7 @@ class WasmInstanceBuilder {
auto memory = Handle<WasmMemoryObject>::cast(value);
DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory));
instance->set_memory_object(*memory);
- memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_);
+ memory_ = Handle<JSArrayBuffer>(memory->buffer(), isolate_);
break;
}
case kExternalGlobal: {
@@ -1789,15 +1843,14 @@ class WasmInstanceBuilder {
Handle<WasmMemoryObject> memory_object;
if (!instance->has_memory_object()) {
// If there was no imported WebAssembly.Memory object, create one.
- Handle<JSArrayBuffer> buffer(instance->get_memory_buffer(),
- isolate_);
+ Handle<JSArrayBuffer> buffer(instance->memory_buffer(), isolate_);
memory_object = WasmMemoryObject::New(
isolate_, buffer,
(module_->max_mem_pages != 0) ? module_->max_mem_pages : -1);
instance->set_memory_object(*memory_object);
} else {
- memory_object = Handle<WasmMemoryObject>(
- instance->get_memory_object(), isolate_);
+ memory_object =
+ Handle<WasmMemoryObject>(instance->memory_object(), isolate_);
DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory_object));
memory_object->ResetInstancesLink(isolate_);
}
@@ -1985,29 +2038,15 @@ bool wasm::IsWasmInstance(Object* object) {
Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
WasmCompiledModule* compiled_module =
- WasmInstanceObject::cast(*instance)->get_compiled_module();
- DCHECK(compiled_module->has_script());
- return compiled_module->script();
-}
-
-Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) {
- auto instance = Handle<WasmInstanceObject>::cast(object);
- if (instance->has_debug_info()) {
- Handle<WasmDebugInfo> info(instance->get_debug_info(),
- instance->GetIsolate());
- return info;
- }
- Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance);
- instance->set_debug_info(*new_info);
- return new_info;
+ WasmInstanceObject::cast(*instance)->compiled_module();
+ return handle(compiled_module->script());
}
// TODO(clemensh): origin can be inferred from asm_js_script; remove it.
MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
ModuleOrigin origin, Handle<Script> asm_js_script,
- const byte* asm_js_offset_tables_start,
- const byte* asm_js_offset_tables_end) {
+ Vector<const byte> asm_js_offset_table_bytes) {
MaybeHandle<WasmModuleObject> nothing;
ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
if (result.failed()) {
@@ -2024,61 +2063,14 @@ MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
// Compile the functions of the module, producing a compiled module.
MaybeHandle<WasmCompiledModule> maybe_compiled_module =
result.val->CompileFunctions(isolate, module_wrapper, thrower,
- ModuleWireBytes(start, end));
+ ModuleWireBytes(start, end), asm_js_script,
+ asm_js_offset_table_bytes);
if (maybe_compiled_module.is_null()) return nothing;
Handle<WasmCompiledModule> compiled_module =
maybe_compiled_module.ToHandleChecked();
- DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null());
- DCHECK(!compiled_module->has_script());
- DCHECK(!compiled_module->has_asm_js_offset_table());
- if (origin == kAsmJsOrigin) {
- // Set script for the asm.js source, and the offset table mapping wasm byte
- // offsets to source positions.
- compiled_module->set_script(asm_js_script);
- size_t offset_table_len =
- asm_js_offset_tables_end - asm_js_offset_tables_start;
- DCHECK_GE(kMaxInt, offset_table_len);
- Handle<ByteArray> offset_table =
- isolate->factory()->NewByteArray(static_cast<int>(offset_table_len));
- memcpy(offset_table->GetDataStartAddress(), asm_js_offset_tables_start,
- offset_table_len);
- compiled_module->set_asm_js_offset_table(offset_table);
- } else {
- // Create a new Script object representing this wasm module, store it in the
- // compiled wasm module, and register it at the debugger.
- Handle<Script> script =
- isolate->factory()->NewScript(isolate->factory()->empty_string());
- script->set_type(Script::TYPE_WASM);
-
- DCHECK_GE(kMaxInt, end - start);
- int hash = StringHasher::HashSequentialString(
- reinterpret_cast<const char*>(start), static_cast<int>(end - start),
- kZeroHashSeed);
-
- const int kBufferSize = 50;
- char buffer[kBufferSize];
- int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash);
- DCHECK(url_chars >= 0 && url_chars < kBufferSize);
- MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte(
- Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars),
- TENURED);
- script->set_source_url(*url_str.ToHandleChecked());
-
- int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash);
- DCHECK(name_chars >= 0 && name_chars < kBufferSize);
- MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte(
- Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars),
- TENURED);
- script->set_name(*name_str.ToHandleChecked());
-
- script->set_wasm_compiled_module(*compiled_module);
- compiled_module->set_script(script);
- isolate->debug()->OnAfterCompile(script);
- }
-
return WasmModuleObject::New(isolate, compiled_module);
}
@@ -2098,7 +2090,7 @@ MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
Isolate* isolate, Handle<WasmInstanceObject> object) {
auto instance = Handle<WasmInstanceObject>::cast(object);
if (instance->has_memory_buffer()) {
- return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate);
+ return Handle<JSArrayBuffer>(instance->memory_buffer(), isolate);
}
return MaybeHandle<JSArrayBuffer>();
}
@@ -2107,7 +2099,7 @@ void SetInstanceMemory(Handle<WasmInstanceObject> instance,
JSArrayBuffer* buffer) {
DisallowHeapAllocation no_gc;
instance->set_memory_buffer(buffer);
- instance->get_compiled_module()->set_ptr_to_memory(buffer);
+ instance->compiled_module()->set_ptr_to_memory(buffer);
}
int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
@@ -2126,14 +2118,12 @@ int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
uint32_t GetMaxInstanceMemorySize(Isolate* isolate,
Handle<WasmInstanceObject> instance) {
if (instance->has_memory_object()) {
- Handle<WasmMemoryObject> memory_object(instance->get_memory_object(),
- isolate);
+ Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate);
int maximum = memory_object->maximum_pages();
if (maximum > 0) return static_cast<uint32_t>(maximum);
}
- uint32_t compiled_max_pages =
- instance->get_compiled_module()->max_mem_pages();
+ uint32_t compiled_max_pages = instance->compiled_module()->max_mem_pages();
isolate->counters()->wasm_max_mem_pages_count()->AddSample(
compiled_max_pages);
if (compiled_max_pages != 0) return compiled_max_pages;
@@ -2186,12 +2176,12 @@ void UncheckedUpdateInstanceMemory(Isolate* isolate,
Handle<WasmInstanceObject> instance,
Address old_mem_start, uint32_t old_size) {
DCHECK(instance->has_memory_buffer());
- Handle<JSArrayBuffer> new_buffer(instance->get_memory_buffer());
+ Handle<JSArrayBuffer> new_buffer(instance->memory_buffer());
uint32_t new_size = new_buffer->byte_length()->Number();
DCHECK(new_size <= std::numeric_limits<uint32_t>::max());
Address new_mem_start = static_cast<Address>(new_buffer->backing_store());
DCHECK_NOT_NULL(new_mem_start);
- Handle<FixedArray> code_table = instance->get_compiled_module()->code_table();
+ Handle<FixedArray> code_table = instance->compiled_module()->code_table();
RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start,
old_size, new_size);
}
@@ -2201,8 +2191,7 @@ int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, Handle<Object> receiver,
DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver));
Handle<WasmMemoryObject> memory_object =
handle(WasmMemoryObject::cast(*receiver));
- Handle<WasmInstanceWrapper> instance_wrapper(
- memory_object->get_instances_link());
+ Handle<WasmInstanceWrapper> instance_wrapper(memory_object->instances_link());
DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
DCHECK(instance_wrapper->has_instance());
Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
@@ -2211,8 +2200,7 @@ int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, Handle<Object> receiver,
uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
// Grow memory object buffer and update instances associated with it.
- MaybeHandle<JSArrayBuffer> memory_buffer =
- handle(memory_object->get_buffer());
+ MaybeHandle<JSArrayBuffer> memory_buffer = handle(memory_object->buffer());
Handle<JSArrayBuffer> old_buffer;
uint32_t old_size = 0;
Address old_mem_start = nullptr;
@@ -2266,8 +2254,8 @@ int32_t wasm::GrowMemory(Isolate* isolate, Handle<WasmInstanceObject> instance,
DCHECK(old_size % WasmModule::kPageSize == 0);
return (old_size / WasmModule::kPageSize);
} else {
- return GrowWebAssemblyMemory(
- isolate, handle(instance_obj->get_memory_object()), pages);
+ return GrowWebAssemblyMemory(isolate, handle(instance_obj->memory_object()),
+ pages);
}
}
@@ -2276,7 +2264,7 @@ void testing::ValidateInstancesChain(Isolate* isolate,
int instance_count) {
CHECK_GE(instance_count, 0);
DisallowHeapAllocation no_gc;
- WasmCompiledModule* compiled_module = module_obj->get_compiled_module();
+ WasmCompiledModule* compiled_module = module_obj->compiled_module();
CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()),
*module_obj);
Object* prev = nullptr;
@@ -2300,7 +2288,7 @@ void testing::ValidateInstancesChain(Isolate* isolate,
void testing::ValidateModuleState(Isolate* isolate,
Handle<WasmModuleObject> module_obj) {
DisallowHeapAllocation no_gc;
- WasmCompiledModule* compiled_module = module_obj->get_compiled_module();
+ WasmCompiledModule* compiled_module = module_obj->compiled_module();
CHECK(compiled_module->has_weak_wasm_module());
CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *module_obj);
CHECK(!compiled_module->has_weak_prev_instance());
@@ -2311,7 +2299,7 @@ void testing::ValidateModuleState(Isolate* isolate,
void testing::ValidateOrphanedInstance(Isolate* isolate,
Handle<WasmInstanceObject> instance) {
DisallowHeapAllocation no_gc;
- WasmCompiledModule* compiled_module = instance->get_compiled_module();
+ WasmCompiledModule* compiled_module = instance->compiled_module();
CHECK(compiled_module->has_weak_wasm_module());
CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
}
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698