Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |