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

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

Issue 2174123002: [wasm] Add support for multiple indirect function tables (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix loop bug, cleanups, style Created 4 years, 5 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
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 "src/base/atomic-utils.h" 5 #include "src/base/atomic-utils.h"
6 #include "src/macro-assembler.h" 6 #include "src/macro-assembler.h"
7 #include "src/objects.h" 7 #include "src/objects.h"
8 #include "src/property-descriptor.h" 8 #include "src/property-descriptor.h"
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // the compiled module is either obtained from the current v8 instance, or from 145 // the compiled module is either obtained from the current v8 instance, or from
146 // a snapshot produced by a compatible (==identical) v8 instance, we simply 146 // a snapshot produced by a compatible (==identical) v8 instance, we simply
147 // fail at instantiation time, in the face of invalid data. 147 // fail at instantiation time, in the face of invalid data.
148 enum CompiledWasmObjectFields { 148 enum CompiledWasmObjectFields {
149 kFunctions, // FixedArray of Code 149 kFunctions, // FixedArray of Code
150 kImportData, // maybe FixedArray of FixedArray respecting the 150 kImportData, // maybe FixedArray of FixedArray respecting the
151 // WasmImportMetadata structure. 151 // WasmImportMetadata structure.
152 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata 152 kExports, // maybe FixedArray of FixedArray of WasmExportMetadata
153 // structure 153 // structure
154 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure 154 kStartupFunction, // maybe FixedArray of WasmExportMetadata structure
155 kIndirectFunctionTableSize, // Smi. Size of indirect function table. 155 kIndirectFunctionTable, // maybe FixedArray of FixedArray of
Mircea Trofin 2016/07/26 03:37:27 is this one or more tables? kIndirectFunctionTabl
ddchen 2016/07/26 05:44:44 One table that contains all of the other tables.
Mircea Trofin 2016/07/26 05:52:47 OK, but the name may cause confusion. How about kT
ddchen 2016/07/26 16:11:44 Done.
156 kIndirectFunctionTablePrototype, // maybe FixedArray 156 // WasmTableMetadata
157 kModuleBytes, // maybe String 157 kModuleBytes, // maybe String
158 kFunctionNameTable, // maybe ByteArray 158 kFunctionNameTable, // maybe ByteArray
159 kMinRequiredMemory, // Smi. an uint32_t 159 kMinRequiredMemory, // Smi. an uint32_t
160 // The following 2 are either together present or absent: 160 // The following 2 are either together present or absent:
161 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the 161 kDataSegmentsInfo, // maybe FixedArray of FixedArray respecting the
162 // WasmSegmentInfo structure 162 // WasmSegmentInfo structure
163 kDataSegments, // maybe ByteArray. 163 kDataSegments, // maybe ByteArray.
164 164
165 kGlobalsSize, // Smi. an uint32_t 165 kGlobalsSize, // Smi. an uint32_t
166 kExportMem, // Smi. bool 166 kExportMem, // Smi. bool
167 kOrigin, // Smi. ModuleOrigin 167 kOrigin, // Smi. ModuleOrigin
168 kCompiledWasmObjectTableSize // Sentinel value. 168 kCompiledWasmObjectTableSize // Sentinel value.
169 }; 169 };
(...skipping 13 matching lines...) Expand all
183 kExportedFunctionIndex, // Smi, an uint32_t 183 kExportedFunctionIndex, // Smi, an uint32_t
184 kWasmExportMetadataTableSize // Sentinel value. 184 kWasmExportMetadataTableSize // Sentinel value.
185 }; 185 };
186 186
187 enum WasmSegmentInfo { 187 enum WasmSegmentInfo {
188 kDestAddr, // Smi. an uint32_t 188 kDestAddr, // Smi. an uint32_t
189 kSourceSize, // Smi. an uint32_t 189 kSourceSize, // Smi. an uint32_t
190 kWasmSegmentInfoSize // Sentinel value. 190 kWasmSegmentInfoSize // Sentinel value.
191 }; 191 };
192 192
193 enum WasmTableMetadata {
Mircea Trofin 2016/07/26 03:37:27 WasmIndirectFunctionTableMetadata long name, but
ddchen 2016/07/26 05:44:44 Done.
194 kSize, // Smi. an uint32_t
195 kTable, // FixedArray of indirect function table
196 kWasmTableMetadataSize // Sentinel value.
197 };
198
193 uint32_t GetMinModuleMemSize(const WasmModule* module) { 199 uint32_t GetMinModuleMemSize(const WasmModule* module) {
194 return WasmModule::kPageSize * module->min_mem_pages; 200 return WasmModule::kPageSize * module->min_mem_pages;
195 } 201 }
196 202
197 void LoadDataSegments(Handle<FixedArray> compiled_module, Address mem_addr, 203 void LoadDataSegments(Handle<FixedArray> compiled_module, Address mem_addr,
198 size_t mem_size) { 204 size_t mem_size) {
199 MaybeHandle<ByteArray> maybe_data = 205 MaybeHandle<ByteArray> maybe_data =
200 compiled_module->GetValue<ByteArray>(kDataSegments); 206 compiled_module->GetValue<ByteArray>(kDataSegments);
201 MaybeHandle<FixedArray> maybe_segments = 207 MaybeHandle<FixedArray> maybe_segments =
202 compiled_module->GetValue<FixedArray>(kDataSegmentsInfo); 208 compiled_module->GetValue<FixedArray>(kDataSegmentsInfo);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 segments->set(i, *js_segment); 254 segments->set(i, *js_segment);
249 data->copy_in(last_insertion_pos, 255 data->copy_in(last_insertion_pos,
250 module->module_start + segment.source_offset, 256 module->module_start + segment.source_offset,
251 segment.source_size); 257 segment.source_size);
252 last_insertion_pos += segment.source_size; 258 last_insertion_pos += segment.source_size;
253 } 259 }
254 compiled_module->set(kDataSegmentsInfo, *segments); 260 compiled_module->set(kDataSegmentsInfo, *segments);
255 compiled_module->set(kDataSegments, *data); 261 compiled_module->set(kDataSegments, *data);
256 } 262 }
257 263
258 MaybeHandle<FixedArray> BuildFunctionTable(Isolate* isolate,
Mircea Trofin 2016/07/26 03:37:27 why did this move?
ddchen 2016/07/26 05:44:44 In order to expose this function and eliminate the
259 const WasmModule* module) {
260 // Compute the size of the indirect function table
261 uint32_t table_size = module->FunctionTableSize();
262 if (table_size == 0) {
263 return MaybeHandle<FixedArray>();
264 }
265
266 DCHECK_GE(table_size, module->function_table.size());
267
268 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size);
269 for (uint32_t i = 0; i < module->function_table.size(); ++i) {
270 const WasmFunction* function =
271 &module->functions[module->function_table[i]];
272 int fixed_array_index = static_cast<int>(i);
273 fixed->set(fixed_array_index, Smi::FromInt(function->sig_index));
274 fixed->set(fixed_array_index + table_size,
275 Smi::FromInt(module->function_table[fixed_array_index]));
276 }
277
278 // Set the remaining elements to -1 (instead of "undefined"). These
279 // elements are accessed directly as SMIs (without a check). On 64-bit
280 // platforms, it is possible to have the top bits of "undefined" take
281 // small integer values (or zero), which are more likely to be equal to
282 // the signature index we check against.
283 for (uint32_t i = static_cast<uint32_t>(module->function_table.size());
284 i < table_size;
285 ++i) {
286 fixed->set(i, Smi::FromInt(-1));
287 }
288 return fixed;
289 }
290
291 void PatchFunctionTable(Handle<Code> code, 264 void PatchFunctionTable(Handle<Code> code,
292 Handle<FixedArray> old_indirect_table, 265 Handle<FixedArray> old_indirect_table,
293 Handle<FixedArray> new_indirect_table) { 266 Handle<FixedArray> new_indirect_table) {
294 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done(); 267 for (RelocIterator it(*code, 1 << RelocInfo::EMBEDDED_OBJECT); !it.done();
295 it.next()) { 268 it.next()) {
296 if (it.rinfo()->target_object() == *old_indirect_table) { 269 if (it.rinfo()->target_object() == *old_indirect_table) {
297 it.rinfo()->set_target_object(*new_indirect_table); 270 it.rinfo()->set_target_object(*new_indirect_table);
298 } 271 }
299 } 272 }
300 } 273 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 WasmModule::WasmModule(byte* module_start) 425 WasmModule::WasmModule(byte* module_start)
453 : module_start(module_start), 426 : module_start(module_start),
454 module_end(nullptr), 427 module_end(nullptr),
455 min_mem_pages(0), 428 min_mem_pages(0),
456 max_mem_pages(0), 429 max_mem_pages(0),
457 mem_export(false), 430 mem_export(false),
458 mem_external(false), 431 mem_external(false),
459 start_function_index(-1), 432 start_function_index(-1),
460 origin(kWasmOrigin), 433 origin(kWasmOrigin),
461 globals_size(0), 434 globals_size(0),
462 indirect_table_size(0),
463 pending_tasks(new base::Semaphore(0)) {} 435 pending_tasks(new base::Semaphore(0)) {}
464 436
465 static MaybeHandle<JSFunction> ReportFFIError( 437 static MaybeHandle<JSFunction> ReportFFIError(
466 ErrorThrower& thrower, const char* error, uint32_t index, 438 ErrorThrower& thrower, const char* error, uint32_t index,
467 Handle<String> module_name, MaybeHandle<String> function_name) { 439 Handle<String> module_name, MaybeHandle<String> function_name) {
468 Handle<String> function_name_handle; 440 Handle<String> function_name_handle;
469 if (function_name.ToHandle(&function_name_handle)) { 441 if (function_name.ToHandle(&function_name_handle)) {
470 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", 442 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s",
471 index, module_name->length(), module_name->ToCString().get(), 443 index, module_name->length(), module_name->ToCString().get(),
472 function_name_handle->length(), 444 function_name_handle->length(),
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 Factory* factory = isolate->factory(); 990 Factory* factory = isolate->factory();
1019 991
1020 MaybeHandle<FixedArray> nothing; 992 MaybeHandle<FixedArray> nothing;
1021 993
1022 WasmModuleInstance temp_instance_for_compilation(this); 994 WasmModuleInstance temp_instance_for_compilation(this);
1023 temp_instance_for_compilation.context = isolate->native_context(); 995 temp_instance_for_compilation.context = isolate->native_context();
1024 temp_instance_for_compilation.mem_size = GetMinModuleMemSize(this); 996 temp_instance_for_compilation.mem_size = GetMinModuleMemSize(this);
1025 temp_instance_for_compilation.mem_start = nullptr; 997 temp_instance_for_compilation.mem_start = nullptr;
1026 temp_instance_for_compilation.globals_start = nullptr; 998 temp_instance_for_compilation.globals_start = nullptr;
1027 999
1028 MaybeHandle<FixedArray> indirect_table = BuildFunctionTable(isolate, this); 1000 MaybeHandle<FixedArray> indirect_table =
1029 if (!indirect_table.is_null()) { 1001 function_tables.size()
1030 temp_instance_for_compilation.function_table = 1002 ? factory->NewFixedArray(static_cast<int>(function_tables.size()))
1031 indirect_table.ToHandleChecked(); 1003 : MaybeHandle<FixedArray>();
1004 for (uint32_t i = 0; i < function_tables.size(); i++) {
Mircea Trofin 2016/07/26 03:37:27 ++i
ddchen 2016/07/26 05:44:44 Done.
1005 Handle<FixedArray> values = wasm::BuildFunctionTable(isolate, i, this);
1006 temp_instance_for_compilation.function_tables[i] = values;
1007
1008 Handle<FixedArray> metadata =
1009 isolate->factory()->NewFixedArray(kWasmTableMetadataSize);
1010 metadata->set(kSize, Smi::FromInt(function_tables[i].size));
1011 metadata->set(kTable, *values);
1012 indirect_table.ToHandleChecked()->set(i, *metadata);
1032 } 1013 }
1033 1014
1034 HistogramTimerScope wasm_compile_module_time_scope( 1015 HistogramTimerScope wasm_compile_module_time_scope(
1035 isolate->counters()->wasm_compile_module_time()); 1016 isolate->counters()->wasm_compile_module_time());
1036 1017
1037 ModuleEnv module_env; 1018 ModuleEnv module_env;
1038 module_env.module = this; 1019 module_env.module = this;
1039 module_env.instance = &temp_instance_for_compilation; 1020 module_env.instance = &temp_instance_for_compilation;
1040 module_env.origin = origin; 1021 module_env.origin = origin;
1041 InitializePlaceholders(factory, &module_env.placeholders, functions.size()); 1022 InitializePlaceholders(factory, &module_env.placeholders, functions.size());
(...skipping 26 matching lines...) Expand all
1068 compiled_functions->set(static_cast<int>(i), code); 1049 compiled_functions->set(static_cast<int>(i), code);
1069 } 1050 }
1070 1051
1071 // Create the compiled module object, and populate with compiled functions 1052 // Create the compiled module object, and populate with compiled functions
1072 // and information needed at instantiation time. This object needs to be 1053 // and information needed at instantiation time. This object needs to be
1073 // serializable. Instantiation may occur off a deserialized version of this 1054 // serializable. Instantiation may occur off a deserialized version of this
1074 // object. 1055 // object.
1075 Handle<FixedArray> ret = 1056 Handle<FixedArray> ret =
1076 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED); 1057 factory->NewFixedArray(kCompiledWasmObjectTableSize, TENURED);
1077 ret->set(kFunctions, *compiled_functions); 1058 ret->set(kFunctions, *compiled_functions);
1078 ret->set(kIndirectFunctionTableSize,
1079 Smi::FromInt(static_cast<int>(function_table.size())));
1080 if (!indirect_table.is_null()) { 1059 if (!indirect_table.is_null()) {
1081 ret->set(kIndirectFunctionTablePrototype, 1060 ret->set(kIndirectFunctionTable, *indirect_table.ToHandleChecked());
1082 *indirect_table.ToHandleChecked());
1083 } 1061 }
1084 Handle<FixedArray> import_data = GetImportsMetadata(factory, this); 1062 Handle<FixedArray> import_data = GetImportsMetadata(factory, this);
1085 ret->set(kImportData, *import_data); 1063 ret->set(kImportData, *import_data);
1086 1064
1087 // Compile export functions. 1065 // Compile export functions.
1088 int export_size = static_cast<int>(export_table.size()); 1066 int export_size = static_cast<int>(export_table.size());
1089 Handle<Code> startup_fct; 1067 Handle<Code> startup_fct;
1090 if (export_size > 0) { 1068 if (export_size > 0) {
1091 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED); 1069 Handle<FixedArray> exports = factory->NewFixedArray(export_size, TENURED);
1092 for (int i = 0; i < export_size; ++i) { 1070 for (int i = 0; i < export_size; ++i) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate, 1157 Handle<FixedArray> CloneModuleForInstance(Isolate* isolate,
1180 Handle<FixedArray> original) { 1158 Handle<FixedArray> original) {
1181 Factory* factory = isolate->factory(); 1159 Factory* factory = isolate->factory();
1182 Handle<FixedArray> clone = factory->CopyFixedArray(original); 1160 Handle<FixedArray> clone = factory->CopyFixedArray(original);
1183 1161
1184 Handle<FixedArray> orig_wasm_functions = 1162 Handle<FixedArray> orig_wasm_functions =
1185 original->GetValueChecked<FixedArray>(kFunctions); 1163 original->GetValueChecked<FixedArray>(kFunctions);
1186 Handle<FixedArray> clone_wasm_functions = 1164 Handle<FixedArray> clone_wasm_functions =
1187 factory->CopyFixedArray(orig_wasm_functions); 1165 factory->CopyFixedArray(orig_wasm_functions);
1188 clone->set(kFunctions, *clone_wasm_functions); 1166 clone->set(kFunctions, *clone_wasm_functions);
1189
1190 MaybeHandle<FixedArray> maybe_indirect_table =
1191 original->GetValue<FixedArray>(kIndirectFunctionTablePrototype);
1192
1193 Handle<FixedArray> indirect_table;
1194 Handle<FixedArray> old_table;
1195 if (maybe_indirect_table.ToHandle(&old_table)) {
1196 indirect_table = factory->CopyFixedArray(old_table);
1197 clone->set(kIndirectFunctionTablePrototype, *indirect_table);
1198 }
1199
1200 for (int i = 0; i < orig_wasm_functions->length(); ++i) { 1167 for (int i = 0; i < orig_wasm_functions->length(); ++i) {
1201 Handle<Code> orig_code = orig_wasm_functions->GetValueChecked<Code>(i); 1168 Handle<Code> orig_code = orig_wasm_functions->GetValueChecked<Code>(i);
1202 Handle<Code> cloned_code = factory->CopyCode(orig_code); 1169 Handle<Code> cloned_code = factory->CopyCode(orig_code);
1203 clone_wasm_functions->set(i, *cloned_code); 1170 clone_wasm_functions->set(i, *cloned_code);
1204 if (!maybe_indirect_table.is_null()) { 1171 }
1205 PatchFunctionTable(cloned_code, old_table, indirect_table); 1172
1173 MaybeHandle<FixedArray> maybe_indirect_table =
Mircea Trofin 2016/07/26 03:37:27 _tables (plural)
ddchen 2016/07/26 05:44:44 Done.
1174 original->GetValue<FixedArray>(kIndirectFunctionTable);
1175 Handle<FixedArray> indirect_table;
Mircea Trofin 2016/07/26 03:37:27 _tables
ddchen 2016/07/26 05:44:44 Done.
1176 if (maybe_indirect_table.ToHandle(&indirect_table)) {
1177 Handle<FixedArray> clone_indirect_table =
Mircea Trofin 2016/07/26 03:37:27 plural here, too
ddchen 2016/07/26 05:44:44 Done.
1178 factory->CopyFixedArray(indirect_table);
1179 clone->set(kIndirectFunctionTable, *clone_indirect_table);
1180 for (int i = 0; i < clone_indirect_table->length(); ++i) {
1181 Handle<FixedArray> orig_metadata =
1182 clone_indirect_table->GetValueChecked<FixedArray>(i);
1183 Handle<FixedArray> clone_metadata =
1184 factory->CopyFixedArray(orig_metadata);
1185 clone_indirect_table->set(i, *clone_metadata);
1186 Handle<FixedArray> orig_table =
1187 clone_metadata->GetValueChecked<FixedArray>(kTable);
1188 Handle<FixedArray> clone_table = factory->CopyFixedArray(orig_table);
1189 clone_metadata->set(kTable, *clone_table);
1190 // Update all the functions in each table
1191 for (int i = 0; i < clone_wasm_functions->length(); ++i) {
1192 Handle<Code> code = clone_wasm_functions->GetValueChecked<Code>(i);
1193 PatchFunctionTable(code, orig_table, clone_table);
1194 }
1206 } 1195 }
1207 } 1196 }
1208 1197
1209 MaybeHandle<FixedArray> maybe_orig_exports = 1198 MaybeHandle<FixedArray> maybe_orig_exports =
1210 original->GetValue<FixedArray>(kExports); 1199 original->GetValue<FixedArray>(kExports);
1211 Handle<FixedArray> orig_exports; 1200 Handle<FixedArray> orig_exports;
1212 if (maybe_orig_exports.ToHandle(&orig_exports)) { 1201 if (maybe_orig_exports.ToHandle(&orig_exports)) {
1213 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports); 1202 Handle<FixedArray> cloned_exports = factory->CopyFixedArray(orig_exports);
1214 clone->set(kExports, *cloned_exports); 1203 clone->set(kExports, *cloned_exports);
1215 for (int i = 0; i < orig_exports->length(); ++i) { 1204 for (int i = 0; i < orig_exports->length(); ++i) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 isolate->counters()->wasm_instantiate_module_time()); 1256 isolate->counters()->wasm_instantiate_module_time());
1268 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 1257 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
1269 Factory* factory = isolate->factory(); 1258 Factory* factory = isolate->factory();
1270 1259
1271 compiled_module = CloneModuleForInstance(isolate, compiled_module); 1260 compiled_module = CloneModuleForInstance(isolate, compiled_module);
1272 1261
1273 // These fields are compulsory. 1262 // These fields are compulsory.
1274 Handle<FixedArray> code_table = 1263 Handle<FixedArray> code_table =
1275 compiled_module->GetValueChecked<FixedArray>(kFunctions); 1264 compiled_module->GetValueChecked<FixedArray>(kFunctions);
1276 1265
1277 { 1266 std::vector<Handle<Code>> functions(
1278 std::vector<Handle<Code>> functions( 1267 static_cast<size_t>(code_table->length()));
1279 static_cast<size_t>(code_table->length())); 1268 for (int i = 0; i < code_table->length(); ++i) {
1280 for (int i = 0; i < code_table->length(); ++i) { 1269 functions[static_cast<size_t>(i)] = code_table->GetValueChecked<Code>(i);
1281 functions[static_cast<size_t>(i)] = code_table->GetValueChecked<Code>(i);
1282 }
1283 LinkModuleFunctions(isolate, functions);
1284 } 1270 }
1271 LinkModuleFunctions(isolate, functions);
1285 1272
1286 RecordStats(isolate, code_table); 1273 RecordStats(isolate, code_table);
1287 1274
1288 MaybeHandle<JSObject> nothing; 1275 MaybeHandle<JSObject> nothing;
1289 1276
1290 Handle<Map> map = factory->NewMap( 1277 Handle<Map> map = factory->NewMap(
1291 JS_OBJECT_TYPE, 1278 JS_OBJECT_TYPE,
1292 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1279 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1293 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED); 1280 Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED);
1294 js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 1281 js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
1295 1282
1296 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory, 1283 if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory,
1297 &thrower) && 1284 &thrower) &&
1298 SetupGlobals(isolate, compiled_module, js_object, &thrower) && 1285 SetupGlobals(isolate, compiled_module, js_object, &thrower) &&
1299 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) && 1286 SetupImports(isolate, compiled_module, js_object, &thrower, ffi) &&
1300 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) { 1287 SetupExportsObject(compiled_module, isolate, js_object, &thrower))) {
1301 return nothing; 1288 return nothing;
1302 } 1289 }
1303 1290
1304 SetDebugSupport(factory, compiled_module, js_object); 1291 SetDebugSupport(factory, compiled_module, js_object);
1305 1292
1306 FlushAssemblyCache(isolate, code_table); 1293 FlushAssemblyCache(isolate, code_table);
1307 1294
1308 MaybeHandle<FixedArray> maybe_indirect_table = 1295 MaybeHandle<FixedArray> maybe_indirect_table =
1309 compiled_module->GetValue<FixedArray>(kIndirectFunctionTablePrototype); 1296 compiled_module->GetValue<FixedArray>(kIndirectFunctionTable);
1310 Handle<FixedArray> indirect_table; 1297 Handle<FixedArray> indirect_table;
Mircea Trofin 2016/07/26 03:37:27 tables
ddchen 2016/07/26 05:44:44 Done.
1311 if (maybe_indirect_table.ToHandle(&indirect_table)) { 1298 if (maybe_indirect_table.ToHandle(&indirect_table)) {
1312 int table_size = 1299 for (int i = 0; i < indirect_table->length(); ++i) {
1313 Smi::cast(compiled_module->get(kIndirectFunctionTableSize))->value(); 1300 Handle<FixedArray> metadata =
1314 int half_point = indirect_table->length() / 2; 1301 indirect_table->GetValueChecked<FixedArray>(i);
1315 for (int i = half_point; i < half_point + table_size; ++i) { 1302 uint32_t size = Smi::cast(metadata->get(kSize))->value();
1316 int index = Smi::cast(indirect_table->get(i))->value(); 1303 Handle<FixedArray> table = metadata->GetValueChecked<FixedArray>(kTable);
1317 DCHECK_GE(index, 0); 1304 wasm::PopulateFunctionTable(table, size, &functions);
1318 DCHECK_LT(index, code_table->length());
1319 indirect_table->set(i, code_table->get(index));
1320 } 1305 }
1321 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_table); 1306 js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_table);
1322 } 1307 }
1323 1308
1324 // Run the start function if one was specified. 1309 // Run the start function if one was specified.
1325 MaybeHandle<FixedArray> maybe_startup_fct = 1310 MaybeHandle<FixedArray> maybe_startup_fct =
1326 compiled_module->GetValue<FixedArray>(kStartupFunction); 1311 compiled_module->GetValue<FixedArray>(kStartupFunction);
1327 Handle<FixedArray> metadata; 1312 Handle<FixedArray> metadata;
1328 if (maybe_startup_fct.ToHandle(&metadata)) { 1313 if (maybe_startup_fct.ToHandle(&metadata)) {
1329 HandleScope scope(isolate); 1314 HandleScope scope(isolate);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 if (RelocInfo::IsWasmMemoryReference(mode) || 1451 if (RelocInfo::IsWasmMemoryReference(mode) ||
1467 RelocInfo::IsWasmMemorySizeReference(mode)) { 1452 RelocInfo::IsWasmMemorySizeReference(mode)) {
1468 it.rinfo()->update_wasm_memory_reference(old_start, new_start, old_size, 1453 it.rinfo()->update_wasm_memory_reference(old_start, new_start, old_size,
1469 new_size); 1454 new_size);
1470 } 1455 }
1471 } 1456 }
1472 } 1457 }
1473 return true; 1458 return true;
1474 } 1459 }
1475 1460
1461 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, uint32_t index,
1462 const WasmModule* module) {
1463 const WasmTable* table = &module->function_tables[index];
1464 DCHECK_EQ(table->size, table->values.size());
1465 DCHECK_GE(table->max_size, table->size);
1466 Handle<FixedArray> values =
1467 isolate->factory()->NewFixedArray(2 * table->max_size);
1468 for (uint32_t i = 0; i < table->size; ++i) {
1469 const WasmFunction* function = &module->functions[table->values[i]];
1470 values->set(i, Smi::FromInt(function->sig_index));
1471 values->set(i + table->max_size, Smi::FromInt(table->values[i]));
1472 }
1473 // Set the remaining elements to -1 (instead of "undefined"). These
1474 // elements are accessed directly as SMIs (without a check). On 64-bit
1475 // platforms, it is possible to have the top bits of "undefined" take
1476 // small integer values (or zero), which are more likely to be equal to
1477 // the signature index we check against.
1478 for (uint32_t i = table->size; i < table->max_size; i++) {
1479 values->set(i, Smi::FromInt(-1));
1480 }
1481 return values;
1482 }
1483
1484 void PopulateFunctionTable(Handle<FixedArray> table, uint32_t table_size,
1485 const std::vector<Handle<Code>>* code_table) {
1486 int max_size = table->length() / 2;
1487 for (int i = max_size; i < max_size + table_size; ++i) {
1488 int index = Smi::cast(table->get(i))->value();
1489 DCHECK_GE(index, 0);
1490 DCHECK_LT(index, code_table->size());
1491 table->set(i, *(*code_table)[index]);
1492 }
1493 }
1494
1476 int GetNumberOfFunctions(JSObject* wasm) { 1495 int GetNumberOfFunctions(JSObject* wasm) {
1477 Object* func_names_obj = wasm->GetInternalField(kWasmFunctionNamesArray); 1496 Object* func_names_obj = wasm->GetInternalField(kWasmFunctionNamesArray);
1478 // TODO(clemensh): this looks inside an array constructed elsewhere. Refactor. 1497 // TODO(clemensh): this looks inside an array constructed elsewhere. Refactor.
1479 return ByteArray::cast(func_names_obj)->get_int(0); 1498 return ByteArray::cast(func_names_obj)->get_int(0);
1480 } 1499 }
1481 1500
1482 namespace testing { 1501 namespace testing {
1483 1502
1484 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, 1503 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
1485 const byte* module_end, bool asm_js) { 1504 const byte* module_end, bool asm_js) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 1567 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1549 } 1568 }
1550 thrower.Error("WASM.compileRun() failed: Return value should be number"); 1569 thrower.Error("WASM.compileRun() failed: Return value should be number");
1551 return -1; 1570 return -1;
1552 } 1571 }
1553 1572
1554 } // namespace testing 1573 } // namespace testing
1555 } // namespace wasm 1574 } // namespace wasm
1556 } // namespace internal 1575 } // namespace internal
1557 } // namespace v8 1576 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698