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

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

Issue 2204703002: [wasm] Get rid of extra wrappers when import another wasm export (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make test case code more clean Created 4 years, 4 months 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') | test/cctest/wasm/wasm-run-utils.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/atomic-utils.h" 7 #include "src/base/atomic-utils.h"
8 #include "src/macro-assembler.h" 8 #include "src/macro-assembler.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/property-descriptor.h" 10 #include "src/property-descriptor.h"
11 #include "src/v8.h" 11 #include "src/v8.h"
12 12
13 #include "src/simulator.h" 13 #include "src/simulator.h"
14 14
15 #include "src/wasm/ast-decoder.h" 15 #include "src/wasm/ast-decoder.h"
16 #include "src/wasm/module-decoder.h" 16 #include "src/wasm/module-decoder.h"
17 #include "src/wasm/wasm-debug.h" 17 #include "src/wasm/wasm-debug.h"
18 #include "src/wasm/wasm-function-name-table.h" 18 #include "src/wasm/wasm-function-name-table.h"
19 #include "src/wasm/wasm-module.h" 19 #include "src/wasm/wasm-module.h"
20 #include "src/wasm/wasm-result.h" 20 #include "src/wasm/wasm-result.h"
21 21
22 #include "src/compiler/wasm-compiler.h" 22 #include "src/compiler/wasm-compiler.h"
23 23
24 namespace v8 { 24 namespace v8 {
25 namespace internal { 25 namespace internal {
26 namespace wasm { 26 namespace wasm {
27 27
28 enum JSFunctionExportInternalField {
29 kInternalModuleInstance,
30 kInternalArity,
31 kInternalSignature
32 };
33
28 static const int kPlaceholderMarker = 1000000000; 34 static const int kPlaceholderMarker = 1000000000;
29 35
30 static const char* wasmSections[] = { 36 static const char* wasmSections[] = {
31 #define F(enumerator, order, string) string, 37 #define F(enumerator, order, string) string,
32 FOR_EACH_WASM_SECTION_TYPE(F) 38 FOR_EACH_WASM_SECTION_TYPE(F)
33 #undef F 39 #undef F
34 "<unknown>" // entry for "Max" 40 "<unknown>" // entry for "Max"
35 }; 41 };
36 42
37 static uint8_t wasmSectionsLengths[]{ 43 static uint8_t wasmSectionsLengths[]{
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 os << "+" << pair.function_->func_index; 115 os << "+" << pair.function_->func_index;
110 } 116 }
111 } else { 117 } else {
112 os << "?"; 118 os << "?";
113 } 119 }
114 return os; 120 return os;
115 } 121 }
116 122
117 Handle<JSFunction> WrapExportCodeAsJSFunction( 123 Handle<JSFunction> WrapExportCodeAsJSFunction(
118 Isolate* isolate, Handle<Code> export_code, Handle<String> name, int arity, 124 Isolate* isolate, Handle<Code> export_code, Handle<String> name, int arity,
119 Handle<JSObject> module_instance) { 125 MaybeHandle<ByteArray> maybe_signature, Handle<JSObject> module_instance) {
120 Handle<SharedFunctionInfo> shared = 126 Handle<SharedFunctionInfo> shared =
121 isolate->factory()->NewSharedFunctionInfo(name, export_code, false); 127 isolate->factory()->NewSharedFunctionInfo(name, export_code, false);
122 shared->set_length(arity); 128 shared->set_length(arity);
123 shared->set_internal_formal_parameter_count(arity); 129 shared->set_internal_formal_parameter_count(arity);
124 Handle<JSFunction> function = isolate->factory()->NewFunction( 130 Handle<JSFunction> function = isolate->factory()->NewFunction(
125 isolate->wasm_function_map(), name, export_code); 131 isolate->wasm_function_map(), name, export_code);
126 function->set_shared(*shared); 132 function->set_shared(*shared);
127 133
128 function->SetInternalField(0, *module_instance); 134 function->SetInternalField(kInternalModuleInstance, *module_instance);
135 // add another Internal Field as the function arity
136 function->SetInternalField(kInternalArity, Smi::FromInt(arity));
137 // add another Internal Field as the signature of the foreign function
138 Handle<ByteArray> signature;
139 if (maybe_signature.ToHandle(&signature)) {
140 function->SetInternalField(kInternalSignature, *signature);
141 }
129 return function; 142 return function;
130 } 143 }
131 144
132 namespace { 145 namespace {
133 // Internal constants for the layout of the module object. 146 // Internal constants for the layout of the module object.
134 const int kWasmModuleFunctionTable = 0; 147 const int kWasmModuleFunctionTable = 0;
135 const int kWasmModuleCodeTable = 1; 148 const int kWasmModuleCodeTable = 1;
136 const int kWasmMemArrayBuffer = 2; 149 const int kWasmMemArrayBuffer = 2;
137 const int kWasmGlobalsArrayBuffer = 3; 150 const int kWasmGlobalsArrayBuffer = 3;
138 // TODO(clemensh): Remove function name array, extract names from module bytes. 151 // TODO(clemensh): Remove function name array, extract names from module bytes.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 kOutputCount, // Smi. an uint32_t 189 kOutputCount, // Smi. an uint32_t
177 kSignature, // ByteArray. A copy of the data in FunctionSig 190 kSignature, // ByteArray. A copy of the data in FunctionSig
178 kWasmImportDataTableSize // Sentinel value. 191 kWasmImportDataTableSize // Sentinel value.
179 }; 192 };
180 193
181 enum WasmExportMetadata { 194 enum WasmExportMetadata {
182 kExportCode, // Code 195 kExportCode, // Code
183 kExportName, // String 196 kExportName, // String
184 kExportArity, // Smi, an int 197 kExportArity, // Smi, an int
185 kExportedFunctionIndex, // Smi, an uint32_t 198 kExportedFunctionIndex, // Smi, an uint32_t
199 kExportedSignature, // ByteArray. A copy of the data in FunctionSig
186 kWasmExportMetadataTableSize // Sentinel value. 200 kWasmExportMetadataTableSize // Sentinel value.
187 }; 201 };
188 202
189 enum WasmSegmentInfo { 203 enum WasmSegmentInfo {
190 kDestAddr, // Smi. an uint32_t 204 kDestAddr, // Smi. an uint32_t
191 kSourceSize, // Smi. an uint32_t 205 kSourceSize, // Smi. an uint32_t
192 kWasmSegmentInfoSize // Sentinel value. 206 kWasmSegmentInfoSize // Sentinel value.
193 }; 207 };
194 208
195 enum WasmIndirectFunctionTableMetadata { 209 enum WasmIndirectFunctionTableMetadata {
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 CHECK(ret_count >= 0); 655 CHECK(ret_count >= 0);
642 Handle<ByteArray> sig_data = 656 Handle<ByteArray> sig_data =
643 data->GetValueChecked<ByteArray>(isolate, kSignature); 657 data->GetValueChecked<ByteArray>(isolate, kSignature);
644 int sig_data_size = sig_data->length(); 658 int sig_data_size = sig_data->length();
645 int param_count = sig_data_size - ret_count; 659 int param_count = sig_data_size - ret_count;
646 CHECK(param_count >= 0); 660 CHECK(param_count >= 0);
647 661
648 MaybeHandle<JSFunction> function = LookupFunction( 662 MaybeHandle<JSFunction> function = LookupFunction(
649 *thrower, isolate->factory(), ffi, index, module_name, function_name); 663 *thrower, isolate->factory(), ffi, index, module_name, function_name);
650 if (function.is_null()) return false; 664 if (function.is_null()) return false;
651 665 Handle<Code> code;
652 { 666 Handle<JSFunction> func = function.ToHandleChecked();
667 Handle<Code> export_wrapper_code = handle(func->code());
668 bool isMatch = false;
669 if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) {
670 int exported_param_count =
671 Smi::cast(func->GetInternalField(kInternalArity))->value();
672 Handle<ByteArray> exportedSig = Handle<ByteArray>(
673 ByteArray::cast(func->GetInternalField(kInternalSignature)));
674 if (exported_param_count == param_count &&
675 exportedSig->length() == sig_data->length() &&
676 memcmp(exportedSig->data(), sig_data->data(),
677 exportedSig->length()) == 0) {
678 isMatch = true;
679 }
680 }
681 if (isMatch) {
682 int wasm_count = 0;
683 int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
684 for (RelocIterator it(*export_wrapper_code, mask); !it.done();
685 it.next()) {
686 RelocInfo* rinfo = it.rinfo();
687 Address target_address = rinfo->target_address();
688 Code* target = Code::GetCodeFromTargetAddress(target_address);
689 if (target->kind() == Code::WASM_FUNCTION) {
690 ++wasm_count;
691 code = handle(target);
692 }
693 }
694 DCHECK(wasm_count == 1);
695 } else {
653 // Copy the signature to avoid a raw pointer into a heap object when 696 // Copy the signature to avoid a raw pointer into a heap object when
654 // GC can happen. 697 // GC can happen.
655 Zone zone(isolate->allocator()); 698 Zone zone(isolate->allocator());
656 MachineRepresentation* reps = 699 MachineRepresentation* reps =
657 zone.NewArray<MachineRepresentation>(sig_data_size); 700 zone.NewArray<MachineRepresentation>(sig_data_size);
658 memcpy(reps, sig_data->data(), 701 memcpy(reps, sig_data->data(),
659 sizeof(MachineRepresentation) * sig_data_size); 702 sizeof(MachineRepresentation) * sig_data_size);
660 FunctionSig sig(ret_count, param_count, reps); 703 FunctionSig sig(ret_count, param_count, reps);
661 704
662 Handle<Code> code = compiler::CompileWasmToJSWrapper( 705 code = compiler::CompileWasmToJSWrapper(isolate, func, &sig, index,
663 isolate, function.ToHandleChecked(), &sig, index, module_name, 706 module_name, function_name);
664 function_name);
665
666 imports.push_back(code);
667 } 707 }
708 imports.push_back(code);
668 } 709 }
669 } 710 }
670 return true; 711 return true;
671 } 712 }
672 713
673 void InitializeParallelCompilation( 714 void InitializeParallelCompilation(
674 Isolate* isolate, const std::vector<WasmFunction>& functions, 715 Isolate* isolate, const std::vector<WasmFunction>& functions,
675 std::vector<compiler::WasmCompilationUnit*>& compilation_units, 716 std::vector<compiler::WasmCompilationUnit*>& compilation_units,
676 ModuleEnv& module_env, ErrorThrower& thrower) { 717 ModuleEnv& module_env, ErrorThrower& thrower) {
677 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { 718 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) {
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 for (int i = 0; i < exports_size; ++i) { 1003 for (int i = 0; i < exports_size; ++i) {
963 if (thrower->error()) return false; 1004 if (thrower->error()) return false;
964 Handle<FixedArray> export_metadata = 1005 Handle<FixedArray> export_metadata =
965 exports->GetValueChecked<FixedArray>(isolate, i); 1006 exports->GetValueChecked<FixedArray>(isolate, i);
966 Handle<Code> export_code = 1007 Handle<Code> export_code =
967 export_metadata->GetValueChecked<Code>(isolate, kExportCode); 1008 export_metadata->GetValueChecked<Code>(isolate, kExportCode);
968 RecordStats(isolate, *export_code); 1009 RecordStats(isolate, *export_code);
969 Handle<String> name = 1010 Handle<String> name =
970 export_metadata->GetValueChecked<String>(isolate, kExportName); 1011 export_metadata->GetValueChecked<String>(isolate, kExportName);
971 int arity = Smi::cast(export_metadata->get(kExportArity))->value(); 1012 int arity = Smi::cast(export_metadata->get(kExportArity))->value();
1013 MaybeHandle<ByteArray> signature =
1014 export_metadata->GetValue<ByteArray>(isolate, kExportedSignature);
972 Handle<JSFunction> function = WrapExportCodeAsJSFunction( 1015 Handle<JSFunction> function = WrapExportCodeAsJSFunction(
973 isolate, export_code, name, arity, instance); 1016 isolate, export_code, name, arity, signature, instance);
974 desc.set_value(function); 1017 desc.set_value(function);
975 Maybe<bool> status = JSReceiver::DefineOwnProperty( 1018 Maybe<bool> status = JSReceiver::DefineOwnProperty(
976 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR); 1019 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR);
977 if (!status.IsJust()) { 1020 if (!status.IsJust()) {
978 thrower->Error("export of %.*s failed.", name->length(), 1021 thrower->Error("export of %.*s failed.", name->length(),
979 name->ToCString().get()); 1022 name->ToCString().get());
980 return false; 1023 return false;
981 } 1024 }
982 } 1025 }
983 } 1026 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 1117
1075 // Compile export functions. 1118 // Compile export functions.
1076 int export_size = static_cast<int>(export_table.size()); 1119 int export_size = static_cast<int>(export_table.size());
1077 Handle<Code> startup_fct; 1120 Handle<Code> startup_fct;
1078 if (export_size > 0) { 1121 if (export_size > 0) {
1079 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); 1122 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED);
1080 for (int i = 0; i < export_size; ++i) { 1123 for (int i = 0; i < export_size; ++i) {
1081 Handle<FixedArray> export_metadata = 1124 Handle<FixedArray> export_metadata =
1082 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED); 1125 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED);
1083 const WasmExport& exp = export_table[i]; 1126 const WasmExport& exp = export_table[i];
1127 FunctionSig* funcSig = functions[exp.func_index].sig;
1128 Handle<ByteArray> exportedSig =
1129 factory->NewByteArray(static_cast<int>(funcSig->parameter_count() +
1130 funcSig->return_count()),
1131 TENURED);
1132 exportedSig->copy_in(0,
1133 reinterpret_cast<const byte*>(funcSig->raw_data()),
1134 exportedSig->length());
1135 export_metadata->set(kExportedSignature, *exportedSig);
1084 WasmName str = GetName(exp.name_offset, exp.name_length); 1136 WasmName str = GetName(exp.name_offset, exp.name_length);
1085 Handle<String> name = factory->InternalizeUtf8String(str); 1137 Handle<String> name = factory->InternalizeUtf8String(str);
1086 Handle<Code> code = 1138 Handle<Code> code =
1087 temp_instance_for_compilation.function_code[exp.func_index]; 1139 temp_instance_for_compilation.function_code[exp.func_index];
1088 Handle<Code> export_code = compiler::CompileJSToWasmWrapper( 1140 Handle<Code> export_code = compiler::CompileJSToWasmWrapper(
1089 isolate, &module_env, code, exp.func_index); 1141 isolate, &module_env, code, exp.func_index);
1090 if (thrower->error()) return nothing; 1142 if (thrower->error()) return nothing;
1091 export_metadata->set(kExportCode, *export_code); 1143 export_metadata->set(kExportCode, *export_code);
1092 export_metadata->set(kExportName, *name); 1144 export_metadata->set(kExportName, *name);
1093 export_metadata->set( 1145 export_metadata->set(
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 1378
1327 // Run the start function if one was specified. 1379 // Run the start function if one was specified.
1328 MaybeHandle<FixedArray> maybe_startup_fct = 1380 MaybeHandle<FixedArray> maybe_startup_fct =
1329 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction); 1381 compiled_module->GetValue<FixedArray>(isolate, kStartupFunction);
1330 Handle<FixedArray> metadata; 1382 Handle<FixedArray> metadata;
1331 if (maybe_startup_fct.ToHandle(&metadata)) { 1383 if (maybe_startup_fct.ToHandle(&metadata)) {
1332 HandleScope scope(isolate); 1384 HandleScope scope(isolate);
1333 Handle<Code> startup_code = 1385 Handle<Code> startup_code =
1334 metadata->GetValueChecked<Code>(isolate, kExportCode); 1386 metadata->GetValueChecked<Code>(isolate, kExportCode);
1335 int arity = Smi::cast(metadata->get(kExportArity))->value(); 1387 int arity = Smi::cast(metadata->get(kExportArity))->value();
1388 MaybeHandle<ByteArray> startup_signature =
1389 metadata->GetValue<ByteArray>(isolate, kExportedSignature);
1336 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1390 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1337 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, 1391 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1338 js_object); 1392 startup_signature, js_object);
1339 RecordStats(isolate, *startup_code); 1393 RecordStats(isolate, *startup_code);
1340 // Call the JS function. 1394 // Call the JS function.
1341 Handle<Object> undefined = isolate->factory()->undefined_value(); 1395 Handle<Object> undefined = isolate->factory()->undefined_value();
1342 MaybeHandle<Object> retval = 1396 MaybeHandle<Object> retval =
1343 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1397 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1344 1398
1345 if (retval.is_null()) { 1399 if (retval.is_null()) {
1346 thrower.Error("WASM.instantiateModule(): start function failed"); 1400 thrower.Error("WASM.instantiateModule(): start function failed");
1347 return nothing; 1401 return nothing;
1348 } 1402 }
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 1640 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1587 } 1641 }
1588 thrower.Error("WASM.compileRun() failed: Return value should be number"); 1642 thrower.Error("WASM.compileRun() failed: Return value should be number");
1589 return -1; 1643 return -1;
1590 } 1644 }
1591 1645
1592 } // namespace testing 1646 } // namespace testing
1593 } // namespace wasm 1647 } // namespace wasm
1594 } // namespace internal 1648 } // namespace internal
1595 } // namespace v8 1649 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/wasm-run-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698