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

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: 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"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 os << "+" << pair.function_->func_index; 109 os << "+" << pair.function_->func_index;
110 } 110 }
111 } else { 111 } else {
112 os << "?"; 112 os << "?";
113 } 113 }
114 return os; 114 return os;
115 } 115 }
116 116
117 Handle<JSFunction> WrapExportCodeAsJSFunction( 117 Handle<JSFunction> WrapExportCodeAsJSFunction(
118 Isolate* isolate, Handle<Code> export_code, Handle<String> name, int arity, 118 Isolate* isolate, Handle<Code> export_code, Handle<String> name, int arity,
119 Handle<JSObject> module_instance) { 119 Handle<ByteArray> signature, Handle<JSObject> module_instance) {
120 Handle<SharedFunctionInfo> shared = 120 Handle<SharedFunctionInfo> shared =
121 isolate->factory()->NewSharedFunctionInfo(name, export_code, false); 121 isolate->factory()->NewSharedFunctionInfo(name, export_code, false);
122 shared->set_length(arity); 122 shared->set_length(arity);
123 shared->set_internal_formal_parameter_count(arity); 123 shared->set_internal_formal_parameter_count(arity);
124 Handle<JSFunction> function = isolate->factory()->NewFunction( 124 Handle<JSFunction> function = isolate->factory()->NewFunction(
125 isolate->wasm_function_map(), name, export_code); 125 isolate->wasm_function_map(), name, export_code);
126 function->set_shared(*shared); 126 function->set_shared(*shared);
127 127
128 function->SetInternalField(0, *module_instance); 128 function->SetInternalField(0, *module_instance);
129 // add another Internal Field as the shared function
130 function->SetInternalField(1, *shared);
131 // add another Internal Field as the signature of the foreign function
132 function->SetInternalField(2, *signature);
Mircea Trofin 2016/08/01 23:38:32 This might fail, because we only specified a grand
129 return function; 133 return function;
130 } 134 }
131 135
132 namespace { 136 namespace {
133 // Internal constants for the layout of the module object. 137 // Internal constants for the layout of the module object.
134 const int kWasmModuleFunctionTable = 0; 138 const int kWasmModuleFunctionTable = 0;
135 const int kWasmModuleCodeTable = 1; 139 const int kWasmModuleCodeTable = 1;
136 const int kWasmMemArrayBuffer = 2; 140 const int kWasmMemArrayBuffer = 2;
137 const int kWasmGlobalsArrayBuffer = 3; 141 const int kWasmGlobalsArrayBuffer = 3;
138 // TODO(clemensh): Remove function name array, extract names from module bytes. 142 // 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 180 kOutputCount, // Smi. an uint32_t
177 kSignature, // ByteArray. A copy of the data in FunctionSig 181 kSignature, // ByteArray. A copy of the data in FunctionSig
178 kWasmImportDataTableSize // Sentinel value. 182 kWasmImportDataTableSize // Sentinel value.
179 }; 183 };
180 184
181 enum WasmExportMetadata { 185 enum WasmExportMetadata {
182 kExportCode, // Code 186 kExportCode, // Code
183 kExportName, // String 187 kExportName, // String
184 kExportArity, // Smi, an int 188 kExportArity, // Smi, an int
185 kExportedFunctionIndex, // Smi, an uint32_t 189 kExportedFunctionIndex, // Smi, an uint32_t
190 kExportedSignature, // ByteArray. A copy of the data in FunctionSig
186 kWasmExportMetadataTableSize // Sentinel value. 191 kWasmExportMetadataTableSize // Sentinel value.
187 }; 192 };
188 193
189 enum WasmSegmentInfo { 194 enum WasmSegmentInfo {
190 kDestAddr, // Smi. an uint32_t 195 kDestAddr, // Smi. an uint32_t
191 kSourceSize, // Smi. an uint32_t 196 kSourceSize, // Smi. an uint32_t
192 kWasmSegmentInfoSize // Sentinel value. 197 kWasmSegmentInfoSize // Sentinel value.
193 }; 198 };
194 199
195 uint32_t GetMinModuleMemSize(const WasmModule* module) { 200 uint32_t GetMinModuleMemSize(const WasmModule* module) {
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 CHECK(ret_count >= 0); 669 CHECK(ret_count >= 0);
665 Handle<ByteArray> sig_data = data->GetValueChecked<ByteArray>(kSignature); 670 Handle<ByteArray> sig_data = data->GetValueChecked<ByteArray>(kSignature);
666 int sig_data_size = sig_data->length(); 671 int sig_data_size = sig_data->length();
667 int param_count = sig_data_size - ret_count; 672 int param_count = sig_data_size - ret_count;
668 CHECK(param_count >= 0); 673 CHECK(param_count >= 0);
669 674
670 MaybeHandle<JSFunction> function = LookupFunction( 675 MaybeHandle<JSFunction> function = LookupFunction(
671 *thrower, isolate->factory(), ffi, index, module_name, function_name); 676 *thrower, isolate->factory(), ffi, index, module_name, function_name);
672 if (function.is_null()) return false; 677 if (function.is_null()) return false;
673 678
674 { 679 Handle<Code> code;
680 Handle<JSFunction> func = function.ToHandleChecked();
681 Handle<Code> export_wrapper_code = handle(func->code());
682 bool isMatch = true;
683 if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) {
684 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(
685 SharedFunctionInfo::cast(func->GetInternalField(1)));
686 int exported_param_count = shared->length();
687 // check whether two functions have same param count
Mircea Trofin 2016/08/01 23:38:32 You should get the parameter count from the wasm f
688 if (exported_param_count != param_count) isMatch = false;
689 Handle<ByteArray> exportedSig =
690 Handle<ByteArray>(ByteArray::cast(func->GetInternalField(2)));
Mircea Trofin 2016/08/01 23:38:32 why continue computing exportedSig if isMatch=fals
691 // check whether two functions have same signature
692 if (exportedSig->length() == sig_data->length()) {
693 for (int i = 0; i < exportedSig->length(); i++) {
694 if (exportedSig->get(i) != sig_data->get(i)) {
695 isMatch = false;
696 break;
697 }
698 }
699 } else {
700 isMatch = false;
701 }
702 if (isMatch) {
703 int wasm_count = 0;
704 int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
705 for (RelocIterator it(*export_wrapper_code, mask); !it.done();
706 it.next()) {
707 RelocInfo* rinfo = it.rinfo();
708 Address target_address = rinfo->target_address();
709 Code* target = Code::GetCodeFromTargetAddress(target_address);
710 if (target->kind() == Code::WASM_FUNCTION) {
711 wasm_count++;
Mircea Trofin 2016/08/01 23:38:32 ++wasm_count
712 code = handle(target);
713 }
714 }
715 CHECK(wasm_count == 1);
Mircea Trofin 2016/08/01 23:38:32 DCHECK
716 }
717 }
718 if (export_wrapper_code->kind() != Code::JS_TO_WASM_FUNCTION ||
719 !isMatch) {
675 // Copy the signature to avoid a raw pointer into a heap object when 720 // Copy the signature to avoid a raw pointer into a heap object when
676 // GC can happen. 721 // GC can happen.
677 Zone zone(isolate->allocator()); 722 Zone zone(isolate->allocator());
678 MachineRepresentation* reps = 723 MachineRepresentation* reps =
679 zone.NewArray<MachineRepresentation>(sig_data_size); 724 zone.NewArray<MachineRepresentation>(sig_data_size);
680 memcpy(reps, sig_data->data(), 725 memcpy(reps, sig_data->data(),
681 sizeof(MachineRepresentation) * sig_data_size); 726 sizeof(MachineRepresentation) * sig_data_size);
682 FunctionSig sig(ret_count, param_count, reps); 727 FunctionSig sig(ret_count, param_count, reps);
683 728
684 Handle<Code> code = compiler::CompileWasmToJSWrapper( 729 code = compiler::CompileWasmToJSWrapper(isolate, func, &sig, index,
685 isolate, function.ToHandleChecked(), &sig, index, module_name, 730 module_name, function_name);
686 function_name);
687
688 imports.push_back(code);
689 } 731 }
732 imports.push_back(code);
690 } 733 }
691 } 734 }
692 return true; 735 return true;
693 } 736 }
694 737
695 void InitializeParallelCompilation( 738 void InitializeParallelCompilation(
696 Isolate* isolate, const std::vector<WasmFunction>& functions, 739 Isolate* isolate, const std::vector<WasmFunction>& functions,
697 std::vector<compiler::WasmCompilationUnit*>& compilation_units, 740 std::vector<compiler::WasmCompilationUnit*>& compilation_units,
698 ModuleEnv& module_env, ErrorThrower& thrower) { 741 ModuleEnv& module_env, ErrorThrower& thrower) {
699 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { 742 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 for (int i = 0; i < exports_size; ++i) { 1026 for (int i = 0; i < exports_size; ++i) {
984 if (thrower->error()) return false; 1027 if (thrower->error()) return false;
985 Handle<FixedArray> export_metadata = 1028 Handle<FixedArray> export_metadata =
986 exports->GetValueChecked<FixedArray>(i); 1029 exports->GetValueChecked<FixedArray>(i);
987 Handle<Code> export_code = 1030 Handle<Code> export_code =
988 export_metadata->GetValueChecked<Code>(kExportCode); 1031 export_metadata->GetValueChecked<Code>(kExportCode);
989 RecordStats(isolate, *export_code); 1032 RecordStats(isolate, *export_code);
990 Handle<String> name = 1033 Handle<String> name =
991 export_metadata->GetValueChecked<String>(kExportName); 1034 export_metadata->GetValueChecked<String>(kExportName);
992 int arity = Smi::cast(export_metadata->get(kExportArity))->value(); 1035 int arity = Smi::cast(export_metadata->get(kExportArity))->value();
1036 Handle<ByteArray> signature =
1037 export_metadata->GetValueChecked<ByteArray>(kExportedSignature);
993 Handle<JSFunction> function = WrapExportCodeAsJSFunction( 1038 Handle<JSFunction> function = WrapExportCodeAsJSFunction(
994 isolate, export_code, name, arity, instance); 1039 isolate, export_code, name, arity, signature, instance);
995 desc.set_value(function); 1040 desc.set_value(function);
996 Maybe<bool> status = JSReceiver::DefineOwnProperty( 1041 Maybe<bool> status = JSReceiver::DefineOwnProperty(
997 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR); 1042 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR);
998 if (!status.IsJust()) { 1043 if (!status.IsJust()) {
999 thrower->Error("export of %.*s failed.", name->length(), 1044 thrower->Error("export of %.*s failed.", name->length(),
1000 name->ToCString().get()); 1045 name->ToCString().get());
1001 return false; 1046 return false;
1002 } 1047 }
1003 } 1048 }
1004 } 1049 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 1133
1089 // Compile export functions. 1134 // Compile export functions.
1090 int export_size = static_cast<int>(export_table.size()); 1135 int export_size = static_cast<int>(export_table.size());
1091 Handle<Code> startup_fct; 1136 Handle<Code> startup_fct;
1092 if (export_size > 0) { 1137 if (export_size > 0) {
1093 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); 1138 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED);
1094 for (int i = 0; i < export_size; ++i) { 1139 for (int i = 0; i < export_size; ++i) {
1095 Handle<FixedArray> export_metadata = 1140 Handle<FixedArray> export_metadata =
1096 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED); 1141 factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED);
1097 const WasmExport& exp = export_table[i]; 1142 const WasmExport& exp = export_table[i];
1143 FunctionSig* funcSig = functions[exp.func_index].sig;
1144 Handle<ByteArray> exportedSig =
1145 factory->NewByteArray(static_cast<int>(funcSig->parameter_count() +
1146 funcSig->return_count()),
1147 TENURED);
1148 exportedSig->copy_in(0,
1149 reinterpret_cast<const byte*>(funcSig->raw_data()),
1150 exportedSig->length());
1151 export_metadata->set(kExportedSignature, *exportedSig);
1098 WasmName str = GetName(exp.name_offset, exp.name_length); 1152 WasmName str = GetName(exp.name_offset, exp.name_length);
1099 Handle<String> name = factory->InternalizeUtf8String(str); 1153 Handle<String> name = factory->InternalizeUtf8String(str);
1100 Handle<Code> code = 1154 Handle<Code> code =
1101 temp_instance_for_compilation.function_code[exp.func_index]; 1155 temp_instance_for_compilation.function_code[exp.func_index];
1102 Handle<Code> export_code = compiler::CompileJSToWasmWrapper( 1156 Handle<Code> export_code = compiler::CompileJSToWasmWrapper(
1103 isolate, &module_env, code, exp.func_index); 1157 isolate, &module_env, code, exp.func_index);
1104 if (thrower->error()) return nothing; 1158 if (thrower->error()) return nothing;
1105 export_metadata->set(kExportCode, *export_code); 1159 export_metadata->set(kExportCode, *export_code);
1106 export_metadata->set(kExportName, *name); 1160 export_metadata->set(kExportName, *name);
1107 export_metadata->set( 1161 export_metadata->set(
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 } 1378 }
1325 1379
1326 // Run the start function if one was specified. 1380 // Run the start function if one was specified.
1327 MaybeHandle<FixedArray> maybe_startup_fct = 1381 MaybeHandle<FixedArray> maybe_startup_fct =
1328 compiled_module->GetValue<FixedArray>(kStartupFunction); 1382 compiled_module->GetValue<FixedArray>(kStartupFunction);
1329 Handle<FixedArray> metadata; 1383 Handle<FixedArray> metadata;
1330 if (maybe_startup_fct.ToHandle(&metadata)) { 1384 if (maybe_startup_fct.ToHandle(&metadata)) {
1331 HandleScope scope(isolate); 1385 HandleScope scope(isolate);
1332 Handle<Code> startup_code = metadata->GetValueChecked<Code>(kExportCode); 1386 Handle<Code> startup_code = metadata->GetValueChecked<Code>(kExportCode);
1333 int arity = Smi::cast(metadata->get(kExportArity))->value(); 1387 int arity = Smi::cast(metadata->get(kExportArity))->value();
1388 Handle<ByteArray> startup_signature =
1389 metadata->GetValueChecked<ByteArray>(kExportedSignature);
1334 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1390 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
1335 isolate, startup_code, factory->InternalizeUtf8String("start"), arity, 1391 isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
1336 js_object); 1392 startup_signature, js_object);
1337 RecordStats(isolate, *startup_code); 1393 RecordStats(isolate, *startup_code);
1338 // Call the JS function. 1394 // Call the JS function.
1339 Handle<Object> undefined = isolate->factory()->undefined_value(); 1395 Handle<Object> undefined = isolate->factory()->undefined_value();
1340 MaybeHandle<Object> retval = 1396 MaybeHandle<Object> retval =
1341 Execution::Call(isolate, startup_fct, undefined, 0, nullptr); 1397 Execution::Call(isolate, startup_fct, undefined, 0, nullptr);
1342 1398
1343 if (retval.is_null()) { 1399 if (retval.is_null()) {
1344 thrower.Error("WASM.instantiateModule(): start function failed"); 1400 thrower.Error("WASM.instantiateModule(): start function failed");
1345 return nothing; 1401 return nothing;
1346 } 1402 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 1606 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1551 } 1607 }
1552 thrower.Error("WASM.compileRun() failed: Return value should be number"); 1608 thrower.Error("WASM.compileRun() failed: Return value should be number");
1553 return -1; 1609 return -1;
1554 } 1610 }
1555 1611
1556 } // namespace testing 1612 } // namespace testing
1557 } // namespace wasm 1613 } // namespace wasm
1558 } // namespace internal 1614 } // namespace internal
1559 } // namespace v8 1615 } // 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