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

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2551053002: [wasm] Always provide a wasm instance object at runtime (Closed)
Patch Set: Rebase 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 unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/base/atomic-utils.h" 8 #include "src/base/atomic-utils.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compiler/wasm-compiler.h" 10 #include "src/compiler/wasm-compiler.h"
(...skipping 29 matching lines...) Expand all
40 40
41 namespace { 41 namespace {
42 42
43 static const int kInvalidSigIndex = -1; 43 static const int kInvalidSigIndex = -1;
44 static const int kPlaceholderMarker = 1000000000; 44 static const int kPlaceholderMarker = 1000000000;
45 45
46 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { 46 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) {
47 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; 47 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset;
48 } 48 }
49 49
50 MaybeHandle<String> ExtractStringFromModuleBytes(
51 Isolate* isolate, Handle<WasmCompiledModule> compiled_module,
52 uint32_t offset, uint32_t size) {
53 // TODO(wasm): cache strings from modules if it's a performance win.
54 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes();
55 DCHECK_GE(module_bytes->length(), offset);
56 DCHECK_GE(module_bytes->length() - offset, size);
57 Address raw = module_bytes->GetCharsAddress() + offset;
58 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size))
59 return {}; // UTF8 decoding error for name.
60 return isolate->factory()->NewStringFromUtf8SubString(
61 module_bytes, static_cast<int>(offset), static_cast<int>(size));
62 }
63
64 void ReplaceReferenceInCode(Handle<Code> code, Handle<Object> old_ref, 50 void ReplaceReferenceInCode(Handle<Code> code, Handle<Object> old_ref,
65 Handle<Object> new_ref) { 51 Handle<Object> new_ref) {
66 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); 52 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done();
67 it.next()) { 53 it.next()) {
68 if (it.rinfo()->target_object() == *old_ref) { 54 if (it.rinfo()->target_object() == *old_ref) {
69 it.rinfo()->set_target_object(*new_ref); 55 it.rinfo()->set_target_object(*new_ref);
70 } 56 }
71 } 57 }
72 } 58 }
73 59
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 return os; 781 return os;
796 } 782 }
797 783
798 WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) { 784 WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) {
799 DCHECK(code->kind() == Code::WASM_FUNCTION); 785 DCHECK(code->kind() == Code::WASM_FUNCTION);
800 DisallowHeapAllocation no_gc; 786 DisallowHeapAllocation no_gc;
801 FixedArray* deopt_data = code->deoptimization_data(); 787 FixedArray* deopt_data = code->deoptimization_data();
802 DCHECK_NOT_NULL(deopt_data); 788 DCHECK_NOT_NULL(deopt_data);
803 DCHECK(deopt_data->length() == 2); 789 DCHECK(deopt_data->length() == 2);
804 Object* weak_link = deopt_data->get(0); 790 Object* weak_link = deopt_data->get(0);
805 if (!weak_link->IsWeakCell()) return nullptr; 791 DCHECK(weak_link->IsWeakCell());
806 WeakCell* cell = WeakCell::cast(weak_link); 792 WeakCell* cell = WeakCell::cast(weak_link);
807 if (!cell->value()) return nullptr; 793 if (!cell->value()) return nullptr;
808 return WasmInstanceObject::cast(cell->value()); 794 return WasmInstanceObject::cast(cell->value());
809 } 795 }
810 796
811 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, 797 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
812 int func_index) { 798 int func_index) {
813 return GetFunctionOffsetAndLength(compiled_module, func_index).first; 799 return GetFunctionOffsetAndLength(compiled_module, func_index).first;
814 } 800 }
815 801
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 // functions. 1500 // functions.
1515 int ProcessImports(Handle<FixedArray> code_table, 1501 int ProcessImports(Handle<FixedArray> code_table,
1516 Handle<WasmInstanceObject> instance) { 1502 Handle<WasmInstanceObject> instance) {
1517 int num_imported_functions = 0; 1503 int num_imported_functions = 0;
1518 int num_imported_tables = 0; 1504 int num_imported_tables = 0;
1519 for (int index = 0; index < static_cast<int>(module_->import_table.size()); 1505 for (int index = 0; index < static_cast<int>(module_->import_table.size());
1520 ++index) { 1506 ++index) {
1521 WasmImport& import = module_->import_table[index]; 1507 WasmImport& import = module_->import_table[index];
1522 1508
1523 Handle<String> module_name; 1509 Handle<String> module_name;
1524 MaybeHandle<String> maybe_module_name = ExtractStringFromModuleBytes( 1510 MaybeHandle<String> maybe_module_name =
1525 isolate_, compiled_module_, import.module_name_offset, 1511 WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
1526 import.module_name_length); 1512 isolate_, compiled_module_, import.module_name_offset,
1513 import.module_name_length);
1527 if (!maybe_module_name.ToHandle(&module_name)) return -1; 1514 if (!maybe_module_name.ToHandle(&module_name)) return -1;
1528 1515
1529 Handle<String> import_name; 1516 Handle<String> import_name;
1530 MaybeHandle<String> maybe_import_name = ExtractStringFromModuleBytes( 1517 MaybeHandle<String> maybe_import_name =
1531 isolate_, compiled_module_, import.field_name_offset, 1518 WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
1532 import.field_name_length); 1519 isolate_, compiled_module_, import.field_name_offset,
1520 import.field_name_length);
1533 if (!maybe_import_name.ToHandle(&import_name)) return -1; 1521 if (!maybe_import_name.ToHandle(&import_name)) return -1;
1534 1522
1535 MaybeHandle<Object> result = 1523 MaybeHandle<Object> result =
1536 LookupImport(index, module_name, import_name); 1524 LookupImport(index, module_name, import_name);
1537 if (thrower_->error()) return -1; 1525 if (thrower_->error()) return -1;
1538 Handle<Object> value = result.ToHandleChecked(); 1526 Handle<Object> value = result.ToHandleChecked();
1539 1527
1540 switch (import.kind) { 1528 switch (import.kind) {
1541 case kExternalFunction: { 1529 case kExternalFunction: {
1542 // Function imports must be callable. 1530 // Function imports must be callable.
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 int export_index = 0; 1733 int export_index = 0;
1746 for (auto exp : module_->export_table) { 1734 for (auto exp : module_->export_table) {
1747 if (exp.kind == kExternalFunction) { 1735 if (exp.kind == kExternalFunction) {
1748 ++export_index; 1736 ++export_index;
1749 } 1737 }
1750 } 1738 }
1751 // Process each export in the export table (go in reverse so asm.js 1739 // Process each export in the export table (go in reverse so asm.js
1752 // can skip duplicates). 1740 // can skip duplicates).
1753 for (auto exp : base::Reversed(module_->export_table)) { 1741 for (auto exp : base::Reversed(module_->export_table)) {
1754 Handle<String> name = 1742 Handle<String> name =
1755 ExtractStringFromModuleBytes(isolate_, compiled_module_, 1743 WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
1756 exp.name_offset, exp.name_length) 1744 isolate_, compiled_module_, exp.name_offset, exp.name_length)
1757 .ToHandleChecked(); 1745 .ToHandleChecked();
1758 switch (exp.kind) { 1746 switch (exp.kind) {
1759 case kExternalFunction: { 1747 case kExternalFunction: {
1760 // Wrap and export the code as a JSFunction. 1748 // Wrap and export the code as a JSFunction.
1761 WasmFunction& function = module_->functions[exp.index]; 1749 WasmFunction& function = module_->functions[exp.index];
1762 int func_index = 1750 int func_index =
1763 static_cast<int>(module_->functions.size() + --export_index); 1751 static_cast<int>(module_->functions.size() + --export_index);
1764 Handle<JSFunction> js_function = js_wrappers_[exp.index]; 1752 Handle<JSFunction> js_function = js_wrappers_[exp.index];
1765 if (js_function.is_null()) { 1753 if (js_function.is_null()) {
1766 // Wrap the exported code as a JSFunction. 1754 // Wrap the exported code as a JSFunction.
1767 Handle<Code> export_code = 1755 Handle<Code> export_code =
1768 code_table->GetValueChecked<Code>(isolate_, func_index); 1756 code_table->GetValueChecked<Code>(isolate_, func_index);
1769 MaybeHandle<String> func_name; 1757 MaybeHandle<String> func_name;
1770 if (module_->origin == kAsmJsOrigin) { 1758 if (module_->origin == kAsmJsOrigin) {
1771 // For modules arising from asm.js, honor the names section. 1759 // For modules arising from asm.js, honor the names section.
1772 func_name = ExtractStringFromModuleBytes( 1760 func_name = WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
1773 isolate_, compiled_module_, function.name_offset, 1761 isolate_, compiled_module_, function.name_offset,
1774 function.name_length) 1762 function.name_length)
1775 .ToHandleChecked(); 1763 .ToHandleChecked();
1776 } 1764 }
1777 js_function = WasmExportedFunction::New( 1765 js_function = WasmExportedFunction::New(
1778 isolate_, instance, func_name, function.func_index, 1766 isolate_, instance, func_name, function.func_index,
1779 static_cast<int>(function.sig->parameter_count()), export_code); 1767 static_cast<int>(function.sig->parameter_count()), export_code);
1780 js_wrappers_[exp.index] = js_function; 1768 js_wrappers_[exp.index] = js_function;
1781 } 1769 }
1782 desc.set_value(js_function); 1770 desc.set_value(js_function);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 temp_instance.context = isolate_->native_context(); 1917 temp_instance.context = isolate_->native_context();
1930 temp_instance.mem_size = 0; 1918 temp_instance.mem_size = 0;
1931 temp_instance.mem_start = nullptr; 1919 temp_instance.mem_start = nullptr;
1932 temp_instance.globals_start = nullptr; 1920 temp_instance.globals_start = nullptr;
1933 1921
1934 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( 1922 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper(
1935 isolate_, module_, wasm_code, func_index); 1923 isolate_, module_, wasm_code, func_index);
1936 MaybeHandle<String> func_name; 1924 MaybeHandle<String> func_name;
1937 if (module_->origin == kAsmJsOrigin) { 1925 if (module_->origin == kAsmJsOrigin) {
1938 // For modules arising from asm.js, honor the names section. 1926 // For modules arising from asm.js, honor the names section.
1939 func_name = ExtractStringFromModuleBytes( 1927 func_name =
1940 isolate_, compiled_module_, 1928 WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
1941 function->name_offset, function->name_length) 1929 isolate_, compiled_module_, function->name_offset,
1942 .ToHandleChecked(); 1930 function->name_length)
1931 .ToHandleChecked();
1943 } 1932 }
1944 Handle<WasmExportedFunction> js_function = 1933 Handle<WasmExportedFunction> js_function =
1945 WasmExportedFunction::New( 1934 WasmExportedFunction::New(
1946 isolate_, instance, func_name, func_index, 1935 isolate_, instance, func_name, func_index,
1947 static_cast<int>(function->sig->parameter_count()), 1936 static_cast<int>(function->sig->parameter_count()),
1948 wrapper_code); 1937 wrapper_code);
1949 js_wrappers_[func_index] = js_function; 1938 js_wrappers_[func_index] = js_function;
1950 } 1939 }
1951 table_instance.js_wrappers->set(table_index, 1940 table_instance.js_wrappers->set(table_index,
1952 *js_wrappers_[func_index]); 1941 *js_wrappers_[func_index]);
(...skipping 30 matching lines...) Expand all
1983 1972
1984 // Instantiates a WASM module, creating a WebAssembly.Instance from a 1973 // Instantiates a WASM module, creating a WebAssembly.Instance from a
1985 // WebAssembly.Module. 1974 // WebAssembly.Module.
1986 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate( 1975 MaybeHandle<WasmInstanceObject> WasmModule::Instantiate(
1987 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module, 1976 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module,
1988 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) { 1977 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) {
1989 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); 1978 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
1990 return builder.Build(); 1979 return builder.Build();
1991 } 1980 }
1992 1981
1993 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate,
1994 Handle<Object> instance_or_undef,
1995 uint32_t func_index) {
1996 if (!instance_or_undef->IsUndefined(isolate)) {
1997 Handle<WasmCompiledModule> compiled_module(
1998 Handle<WasmInstanceObject>::cast(instance_or_undef)
1999 ->get_compiled_module());
2000 MaybeHandle<String> maybe_name =
2001 WasmCompiledModule::GetFunctionName(compiled_module, func_index);
2002 if (!maybe_name.is_null()) return maybe_name.ToHandleChecked();
2003 }
2004 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>");
2005 }
2006
2007 bool wasm::IsWasmInstance(Object* object) { 1982 bool wasm::IsWasmInstance(Object* object) {
2008 return WasmInstanceObject::IsWasmInstanceObject(object); 1983 return WasmInstanceObject::IsWasmInstanceObject(object);
2009 } 1984 }
2010 1985
2011 bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) {
2012 if (instance->IsUndefined(isolate)) return false;
2013 DCHECK(IsWasmInstance(instance));
2014 WasmCompiledModule* compiled_module =
2015 WasmInstanceObject::cast(instance)->get_compiled_module();
2016 DCHECK_EQ(compiled_module->has_asm_js_offset_table(),
2017 compiled_module->script()->type() == Script::TYPE_NORMAL);
2018 return compiled_module->has_asm_js_offset_table();
2019 }
2020
2021 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { 1986 Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
2022 WasmCompiledModule* compiled_module = 1987 WasmCompiledModule* compiled_module =
2023 WasmInstanceObject::cast(*instance)->get_compiled_module(); 1988 WasmInstanceObject::cast(*instance)->get_compiled_module();
2024 DCHECK(compiled_module->has_script()); 1989 DCHECK(compiled_module->has_script());
2025 return compiled_module->script(); 1990 return compiled_module->script();
2026 } 1991 }
2027 1992
2028 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) { 1993 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) {
2029 auto instance = Handle<WasmInstanceObject>::cast(object); 1994 auto instance = Handle<WasmInstanceObject>::cast(object);
2030 if (instance->has_debug_info()) { 1995 if (instance->has_debug_info()) {
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 CHECK(!compiled_module->has_weak_owning_instance()); 2308 CHECK(!compiled_module->has_weak_owning_instance());
2344 } 2309 }
2345 2310
2346 void testing::ValidateOrphanedInstance(Isolate* isolate, 2311 void testing::ValidateOrphanedInstance(Isolate* isolate,
2347 Handle<WasmInstanceObject> instance) { 2312 Handle<WasmInstanceObject> instance) {
2348 DisallowHeapAllocation no_gc; 2313 DisallowHeapAllocation no_gc;
2349 WasmCompiledModule* compiled_module = instance->get_compiled_module(); 2314 WasmCompiledModule* compiled_module = instance->get_compiled_module();
2350 CHECK(compiled_module->has_weak_wasm_module()); 2315 CHECK(compiled_module->has_weak_wasm_module());
2351 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); 2316 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
2352 } 2317 }
2353
2354 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate,
2355 Handle<FixedArray> array) {
2356 Handle<WasmCompiledModule> compiled_module(
2357 reinterpret_cast<WasmCompiledModule*>(*array), isolate);
2358
2359 WasmModule* module = nullptr;
2360 {
2361 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes();
2362 // We parse the module again directly from the module bytes, so
2363 // the underlying storage must not be moved meanwhile.
2364 DisallowHeapAllocation no_allocation;
2365 const byte* start =
2366 reinterpret_cast<const byte*>(module_bytes->GetCharsAddress());
2367 const byte* end = start + module_bytes->length();
2368 // TODO(titzer): remember the module origin in the compiled_module
2369 // For now, we assume serialized modules did not originate from asm.js.
2370 ModuleResult result =
2371 DecodeWasmModule(isolate, start, end, false, kWasmOrigin);
2372 CHECK(result.ok());
2373 CHECK_NOT_NULL(result.val);
2374 module = const_cast<WasmModule*>(result.val);
2375 }
2376
2377 Handle<WasmModuleWrapper> module_wrapper =
2378 WasmModuleWrapper::New(isolate, module);
2379
2380 compiled_module->set_module_wrapper(module_wrapper);
2381 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
2382 }
2383
2384 MaybeHandle<String> WasmCompiledModule::GetFunctionName(
2385 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) {
2386 DCHECK_LT(func_index, compiled_module->module()->functions.size());
2387 WasmFunction& function = compiled_module->module()->functions[func_index];
2388 Isolate* isolate = compiled_module->GetIsolate();
2389 MaybeHandle<String> string = ExtractStringFromModuleBytes(
2390 isolate, compiled_module, function.name_offset, function.name_length);
2391 if (!string.is_null()) return string.ToHandleChecked();
2392 return {};
2393 }
OLDNEW
« 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