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

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

Issue 2269323002: [wasm] Remember import indices with the compiled module (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: git cl try Created 4 years, 3 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 | « no previous file | no next file » | 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/code-stubs.h" 8 #include "src/code-stubs.h"
9 9
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code. 159 // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code.
160 // For now, each field is expected to have the type commented by its side. 160 // For now, each field is expected to have the type commented by its side.
161 // The elements typed as "maybe" are optional. The others are mandatory. Since 161 // The elements typed as "maybe" are optional. The others are mandatory. Since
162 // the compiled module is either obtained from the current v8 instance, or from 162 // the compiled module is either obtained from the current v8 instance, or from
163 // a snapshot produced by a compatible (==identical) v8 instance, we simply 163 // a snapshot produced by a compatible (==identical) v8 instance, we simply
164 // fail at instantiation time, in the face of invalid data. 164 // fail at instantiation time, in the face of invalid data.
165 enum CompiledWasmObjectFields { 165 enum CompiledWasmObjectFields {
166 kFunctions, // FixedArray of Code 166 kFunctions, // FixedArray of Code
167 kImportData, // maybe FixedArray of FixedArray respecting the 167 kImportData, // maybe FixedArray of FixedArray respecting the
168 // WasmImportMetadata structure. 168 // WasmImportMetadata structure.
169 kImportMap, // FixedArray. The i-th element is the Code object used for
170 // import i
169 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata 171 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata
170 // structure 172 // structure
171 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure 173 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure
172 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of 174 kTableOfIndirectFunctionTables, // maybe FixedArray of FixedArray of
173 // WasmIndirectFunctionTableMetadata 175 // WasmIndirectFunctionTableMetadata
174 kModuleBytes, // maybe String 176 kModuleBytes, // maybe String
175 kFunctionNameTable, // maybe ByteArray 177 kFunctionNameTable, // maybe ByteArray
176 kMinRequiredMemory, // Smi. an uint32_t 178 kMinRequiredMemory, // Smi. an uint32_t
177 // The following 2 are either together present or absent: 179 // The following 2 are either together present or absent:
178 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the 180 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 } 419 }
418 420
419 void LinkModuleFunctions(Isolate* isolate, 421 void LinkModuleFunctions(Isolate* isolate,
420 std::vector<Handle<Code>>& functions) { 422 std::vector<Handle<Code>>& functions) {
421 for (size_t i = 0; i < functions.size(); ++i) { 423 for (size_t i = 0; i < functions.size(); ++i) {
422 Handle<Code> code = functions[i]; 424 Handle<Code> code = functions[i];
423 LinkFunction(code, functions, Code::WASM_FUNCTION); 425 LinkFunction(code, functions, Code::WASM_FUNCTION);
424 } 426 }
425 } 427 }
426 428
427 void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions,
428 const std::vector<Handle<Code>>& imports) {
429 for (uint32_t i = 0; i < functions.size(); ++i) {
430 Handle<Code> code = functions[i];
431 LinkFunction(code, imports, Code::WASM_TO_JS_FUNCTION);
432 }
433 }
434
435 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) { 429 void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) {
436 for (int i = 0; i < functions->length(); ++i) { 430 for (int i = 0; i < functions->length(); ++i) {
437 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); 431 Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
438 Assembler::FlushICache(isolate, code->instruction_start(), 432 Assembler::FlushICache(isolate, code->instruction_start(),
439 code->instruction_size()); 433 code->instruction_size());
440 } 434 }
441 } 435 }
442 436
443 } // namespace 437 } // namespace
444 438
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 Handle<FixedArray> import_data; 953 Handle<FixedArray> import_data;
960 if (maybe_import_data.ToHandle(&import_data)) { 954 if (maybe_import_data.ToHandle(&import_data)) {
961 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code, 955 if (!CompileWrappersToImportedFunctions(isolate, ffi, import_code,
962 import_data, thrower)) { 956 import_data, thrower)) {
963 return false; 957 return false;
964 } 958 }
965 } 959 }
966 960
967 RecordStats(isolate, import_code); 961 RecordStats(isolate, import_code);
968 962
969 Handle<FixedArray> code_table = Handle<FixedArray>( 963 if (import_code.empty()) return true;
970 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); 964
971 // TODO(mtrofin): get the code off std::vector and on FixedArray, for 965 {
972 // consistency. 966 DisallowHeapAllocation no_gc;
973 std::vector<Handle<Code>> function_code(code_table->length()); 967 std::map<Code*, int> import_to_index;
974 for (int i = 0; i < code_table->length(); ++i) { 968 Handle<FixedArray> mapping =
975 Handle<Code> code = Handle<Code>(Code::cast(code_table->get(i))); 969 compiled_module->GetValueChecked<FixedArray>(isolate, kImportMap);
976 function_code[i] = code; 970 for (int i = 0; i < mapping->length(); ++i) {
971 import_to_index.insert(std::make_pair(Code::cast(mapping->get(i)), i));
972 }
973
974 Handle<FixedArray> code_table = Handle<FixedArray>(
975 FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
976
977 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
978 AllowDeferredHandleDereference embedding_raw_address;
979 for (int i = 0; i < code_table->length(); ++i) {
980 Handle<Code> wasm_function =
981 code_table->GetValueChecked<Code>(isolate, i);
982 for (RelocIterator it(*wasm_function, mode_mask); !it.done(); it.next()) {
983 Code* target =
984 Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
985 if (target->kind() == Code::WASM_TO_JS_FUNCTION) {
986 auto found_index = import_to_index.find(target);
987 CHECK(found_index != import_to_index.end());
988 int index = found_index->second;
989 CHECK(index < static_cast<int>(import_code.size()));
990 Handle<Code> new_target = import_code[index];
991 it.rinfo()->set_target_address(new_target->instruction_start(),
992 UPDATE_WRITE_BARRIER,
993 SKIP_ICACHE_FLUSH);
994 }
995 }
996 }
977 } 997 }
998 Handle<FixedArray> new_mapping =
999 isolate->factory()->NewFixedArray(static_cast<int>(import_code.size()));
1000 for (int i = 0; i < new_mapping->length(); ++i) {
1001 new_mapping->set(i, *import_code[i]);
1002 }
1003 compiled_module->set(kImportMap, *new_mapping);
978 1004
979 LinkImports(isolate, function_code, import_code);
980 return true; 1005 return true;
981 } 1006 }
982 1007
983 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, 1008 bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate,
984 Handle<JSObject> instance, ErrorThrower* thrower) { 1009 Handle<JSObject> instance, ErrorThrower* thrower) {
985 Factory* factory = isolate->factory(); 1010 Factory* factory = isolate->factory();
986 bool mem_export = 1011 bool mem_export =
987 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value()); 1012 static_cast<bool>(Smi::cast(compiled_module->get(kExportMem))->value());
988 ModuleOrigin origin = static_cast<ModuleOrigin>( 1013 ModuleOrigin origin = static_cast<ModuleOrigin>(
989 Smi::cast(compiled_module->get(kOrigin))->value()); 1014 Smi::cast(compiled_module->get(kOrigin))->value());
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 1101
1077 ModuleEnv module_env; 1102 ModuleEnv module_env;
1078 module_env.module = this; 1103 module_env.module = this;
1079 module_env.instance = &temp_instance_for_compilation; 1104 module_env.instance = &temp_instance_for_compilation;
1080 module_env.origin = origin; 1105 module_env.origin = origin;
1081 InitializePlaceholders(factory, &module_env.placeholders, functions.size()); 1106 InitializePlaceholders(factory, &module_env.placeholders, functions.size());
1082 1107
1083 Handle<FixedArray> compiled_functions = 1108 Handle<FixedArray> compiled_functions =
1084 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); 1109 factory->NewFixedArray(static_cast<int>(functions.size()), TENURED);
1085 1110
1086 temp_instance_for_compilation.import_code.resize(import_table.size()); 1111 MaybeHandle<FixedArray> maybe_imports;
1087 for (uint32_t i = 0; i < import_table.size(); ++i) { 1112 if (import_table.size() > 0) {
1088 temp_instance_for_compilation.import_code[i] = 1113 temp_instance_for_compilation.import_code.resize(import_table.size());
1089 CreatePlaceholder(factory, i, Code::WASM_TO_JS_FUNCTION); 1114 Handle<FixedArray> imports =
1115 factory->NewFixedArray(static_cast<int>(import_table.size()));
1116 for (uint32_t i = 0; i < import_table.size(); ++i) {
1117 Handle<Code> placeholder =
1118 CreatePlaceholder(factory, i, Code::WASM_TO_JS_FUNCTION);
1119 temp_instance_for_compilation.import_code[i] = placeholder;
1120 imports->set(i, *placeholder);
1121 }
1122 maybe_imports = imports;
1090 } 1123 }
1091 isolate->counters()->wasm_functions_per_module()->AddSample( 1124 isolate->counters()->wasm_functions_per_module()->AddSample(
1092 static_cast<int>(functions.size())); 1125 static_cast<int>(functions.size()));
1093 if (FLAG_wasm_num_compilation_tasks != 0) { 1126 if (FLAG_wasm_num_compilation_tasks != 0) {
1094 CompileInParallel(isolate, this, 1127 CompileInParallel(isolate, this,
1095 temp_instance_for_compilation.function_code, thrower, 1128 temp_instance_for_compilation.function_code, thrower,
1096 &module_env); 1129 &module_env);
1097 } else { 1130 } else {
1098 CompileSequentially(isolate, this, 1131 CompileSequentially(isolate, this,
1099 temp_instance_for_compilation.function_code, thrower, 1132 temp_instance_for_compilation.function_code, thrower,
(...skipping 11 matching lines...) Expand all
1111 // Create the compiled module object, and populate with compiled functions 1144 // Create the compiled module object, and populate with compiled functions
1112 // and information needed at instantiation time. This object needs to be 1145 // and information needed at instantiation time. This object needs to be
1113 // serializable. Instantiation may occur off a deserialized version of this 1146 // serializable. Instantiation may occur off a deserialized version of this
1114 // object. 1147 // object.
1115 Handle<FixedArray> ret = 1148 Handle<FixedArray> ret =
1116 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); 1149 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED);
1117 ret->set(kFunctions, *compiled_functions); 1150 ret->set(kFunctions, *compiled_functions);
1118 if (!indirect_table.is_null()) { 1151 if (!indirect_table.is_null()) {
1119 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked()); 1152 ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked());
1120 } 1153 }
1154 if (!maybe_imports.is_null()) {
1155 ret->set(kImportMap, *maybe_imports.ToHandleChecked());
1156 }
1121 Handle<FixedArray> import_data = GetImportsMetadata(factory, this); 1157 Handle<FixedArray> import_data = GetImportsMetadata(factory, this);
1122 ret->set(kImportData, *import_data); 1158 ret->set(kImportData, *import_data);
1123 1159
1124 // Compile export functions. 1160 // Compile export functions.
1125 int export_size = static_cast<int>(export_table.size()); 1161 int export_size = static_cast<int>(export_table.size());
1126 Handle<Code> startup_fct; 1162 Handle<Code> startup_fct;
1127 if (export_size > 0) { 1163 if (export_size > 0) {
1128 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); 1164 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED);
1129 for (int i = 0; i < export_size; ++i) { 1165 for (int i = 0; i < export_size; ++i) {
1130 Handle<FixedArray> export_metadata = 1166 Handle<FixedArray> export_metadata =
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 1699 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1664 } 1700 }
1665 thrower->Error("WASM.compileRun() failed: Return value should be number"); 1701 thrower->Error("WASM.compileRun() failed: Return value should be number");
1666 return -1; 1702 return -1;
1667 } 1703 }
1668 1704
1669 } // namespace testing 1705 } // namespace testing
1670 } // namespace wasm 1706 } // namespace wasm
1671 } // namespace internal 1707 } // namespace internal
1672 } // namespace v8 1708 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698