| 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 <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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 83 |
| 84 enum WasmGlobalInitData { | 84 enum WasmGlobalInitData { |
| 85 kGlobalInitKind, // 0 = constant, 1 = global index | 85 kGlobalInitKind, // 0 = constant, 1 = global index |
| 86 kGlobalInitType, // Smi. Type for globals. | 86 kGlobalInitType, // Smi. Type for globals. |
| 87 kGlobalInitIndex, // Smi, an uint32_t | 87 kGlobalInitIndex, // Smi, an uint32_t |
| 88 kGlobalInitValue, // Number. | 88 kGlobalInitValue, // Number. |
| 89 kWasmGlobalInitDataSize | 89 kWasmGlobalInitDataSize |
| 90 }; | 90 }; |
| 91 | 91 |
| 92 enum WasmSegmentInfo { | 92 enum WasmSegmentInfo { |
| 93 kDestInitKind, // 0 = constant, 1 = global index | 93 kDestAddrKind, // 0 = constant, 1 = global index |
| 94 kDestAddrValue, // Smi. an uint32_t | 94 kDestAddrValue, // Smi. an uint32_t |
| 95 kSourceSize, // Smi. an uint32_t | 95 kSourceSize, // Smi. an uint32_t |
| 96 kWasmSegmentInfoSize // Sentinel value. | 96 kWasmSegmentInfoSize // Sentinel value. |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 enum WasmIndirectFunctionTableData { | 99 enum WasmIndirectFunctionTableData { |
| 100 kSize, // Smi. an uint32_t | 100 kSize, // Smi. an uint32_t |
| 101 kTable, // FixedArray of indirect function table | 101 kTable, // FixedArray of indirect function table |
| 102 kWasmIndirectFunctionTableDataSize // Sentinel value. | 102 kWasmIndirectFunctionTableDataSize // Sentinel value. |
| 103 }; | 103 }; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 120 data_size += segment.source_size; | 120 data_size += segment.source_size; |
| 121 } | 121 } |
| 122 Handle<ByteArray> data = factory->NewByteArray(data_size, TENURED); | 122 Handle<ByteArray> data = factory->NewByteArray(data_size, TENURED); |
| 123 | 123 |
| 124 uint32_t last_insertion_pos = 0; | 124 uint32_t last_insertion_pos = 0; |
| 125 for (uint32_t i = 0; i < module->data_segments.size(); ++i) { | 125 for (uint32_t i = 0; i < module->data_segments.size(); ++i) { |
| 126 const WasmDataSegment& segment = module->data_segments[i]; | 126 const WasmDataSegment& segment = module->data_segments[i]; |
| 127 if (segment.source_size == 0) continue; | 127 if (segment.source_size == 0) continue; |
| 128 Handle<ByteArray> js_segment = | 128 Handle<ByteArray> js_segment = |
| 129 factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED); | 129 factory->NewByteArray(kWasmSegmentInfoSize * sizeof(uint32_t), TENURED); |
| 130 // TODO(titzer): add support for global offsets for dest_addr | 130 if (segment.dest_addr.kind == WasmInitExpr::kGlobalIndex) { |
| 131 CHECK_EQ(WasmInitExpr::kI32Const, segment.dest_addr.kind); | 131 // The destination address is the value of a global variable. |
| 132 js_segment->set_int(kDestAddrValue, segment.dest_addr.val.i32_const); | 132 js_segment->set_int(kDestAddrKind, 1); |
| 133 uint32_t offset = |
| 134 module->globals[segment.dest_addr.val.global_index].offset; |
| 135 js_segment->set_int(kDestAddrValue, static_cast<int>(offset)); |
| 136 } else { |
| 137 // The destination address is a constant. |
| 138 CHECK_EQ(WasmInitExpr::kI32Const, segment.dest_addr.kind); |
| 139 js_segment->set_int(kDestAddrKind, 0); |
| 140 js_segment->set_int(kDestAddrValue, segment.dest_addr.val.i32_const); |
| 141 } |
| 133 js_segment->set_int(kSourceSize, segment.source_size); | 142 js_segment->set_int(kSourceSize, segment.source_size); |
| 134 segments->set(i, *js_segment); | 143 segments->set(i, *js_segment); |
| 135 data->copy_in(last_insertion_pos, | 144 data->copy_in(last_insertion_pos, |
| 136 module->module_start + segment.source_offset, | 145 module->module_start + segment.source_offset, |
| 137 segment.source_size); | 146 segment.source_size); |
| 138 last_insertion_pos += segment.source_size; | 147 last_insertion_pos += segment.source_size; |
| 139 } | 148 } |
| 140 compiled_module->set_data_segments_info(segments); | 149 compiled_module->set_data_segments_info(segments); |
| 141 compiled_module->set_data_segments(data); | 150 compiled_module->set_data_segments(data); |
| 142 } | 151 } |
| (...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); | 1278 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); |
| 1270 } | 1279 } |
| 1271 | 1280 |
| 1272 //-------------------------------------------------------------------------- | 1281 //-------------------------------------------------------------------------- |
| 1273 // Process the imports for the module. | 1282 // Process the imports for the module. |
| 1274 //-------------------------------------------------------------------------- | 1283 //-------------------------------------------------------------------------- |
| 1275 int num_imported_functions = ProcessImports(globals, code_table, instance); | 1284 int num_imported_functions = ProcessImports(globals, code_table, instance); |
| 1276 if (num_imported_functions < 0) return nothing; | 1285 if (num_imported_functions < 0) return nothing; |
| 1277 | 1286 |
| 1278 //-------------------------------------------------------------------------- | 1287 //-------------------------------------------------------------------------- |
| 1288 // Process the initialization for the module's globals. |
| 1289 //-------------------------------------------------------------------------- |
| 1290 ProcessInits(globals); |
| 1291 |
| 1292 //-------------------------------------------------------------------------- |
| 1279 // Set up the memory for the new instance. | 1293 // Set up the memory for the new instance. |
| 1280 //-------------------------------------------------------------------------- | 1294 //-------------------------------------------------------------------------- |
| 1281 MaybeHandle<JSArrayBuffer> old_memory; | 1295 MaybeHandle<JSArrayBuffer> old_memory; |
| 1282 // TODO(titzer): handle imported memory properly. | 1296 // TODO(titzer): handle imported memory properly. |
| 1283 | 1297 |
| 1284 uint32_t min_mem_pages = compiled_module_->min_memory_pages(); | 1298 uint32_t min_mem_pages = compiled_module_->min_memory_pages(); |
| 1285 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); | 1299 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); |
| 1286 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. | 1300 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. |
| 1287 | 1301 |
| 1288 if (memory_.is_null() && min_mem_pages > 0) { | 1302 if (memory_.is_null() && min_mem_pages > 0) { |
| 1289 memory_ = AllocateMemory(min_mem_pages); | 1303 memory_ = AllocateMemory(min_mem_pages); |
| 1290 if (memory_.is_null()) return nothing; // failed to allocate memory | 1304 if (memory_.is_null()) return nothing; // failed to allocate memory |
| 1291 } | 1305 } |
| 1292 | 1306 |
| 1293 if (!memory_.is_null()) { | 1307 if (!memory_.is_null()) { |
| 1294 instance->SetInternalField(kWasmMemArrayBuffer, *memory_); | 1308 instance->SetInternalField(kWasmMemArrayBuffer, *memory_); |
| 1295 Address mem_start = static_cast<Address>(memory_->backing_store()); | 1309 Address mem_start = static_cast<Address>(memory_->backing_store()); |
| 1296 uint32_t mem_size = | 1310 uint32_t mem_size = |
| 1297 static_cast<uint32_t>(memory_->byte_length()->Number()); | 1311 static_cast<uint32_t>(memory_->byte_length()->Number()); |
| 1298 LoadDataSegments(mem_start, mem_size); | 1312 LoadDataSegments(globals, mem_start, mem_size); |
| 1299 | 1313 |
| 1300 uint32_t old_mem_size = compiled_module_->has_heap() | 1314 uint32_t old_mem_size = compiled_module_->has_heap() |
| 1301 ? compiled_module_->mem_size() | 1315 ? compiled_module_->mem_size() |
| 1302 : compiled_module_->default_mem_size(); | 1316 : compiled_module_->default_mem_size(); |
| 1303 Address old_mem_start = | 1317 Address old_mem_start = |
| 1304 compiled_module_->has_heap() | 1318 compiled_module_->has_heap() |
| 1305 ? static_cast<Address>(compiled_module_->heap()->backing_store()) | 1319 ? static_cast<Address>(compiled_module_->heap()->backing_store()) |
| 1306 : nullptr; | 1320 : nullptr; |
| 1307 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, | 1321 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, |
| 1308 mem_size); | 1322 mem_size); |
| 1309 compiled_module_->set_heap(memory_); | 1323 compiled_module_->set_heap(memory_); |
| 1310 } | 1324 } |
| 1311 | 1325 |
| 1312 //-------------------------------------------------------------------------- | 1326 //-------------------------------------------------------------------------- |
| 1313 // Process the initialization for the module's globals. | |
| 1314 //-------------------------------------------------------------------------- | |
| 1315 ProcessInits(globals); | |
| 1316 | |
| 1317 //-------------------------------------------------------------------------- | |
| 1318 // Set up the runtime support for the new instance. | 1327 // Set up the runtime support for the new instance. |
| 1319 //-------------------------------------------------------------------------- | 1328 //-------------------------------------------------------------------------- |
| 1320 Handle<WeakCell> weak_link = factory->NewWeakCell(instance); | 1329 Handle<WeakCell> weak_link = factory->NewWeakCell(instance); |
| 1321 | 1330 |
| 1322 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs; | 1331 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs; |
| 1323 i < code_table->length(); ++i) { | 1332 i < code_table->length(); ++i) { |
| 1324 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); | 1333 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); |
| 1325 if (code->kind() == Code::WASM_FUNCTION) { | 1334 if (code->kind() == Code::WASM_FUNCTION) { |
| 1326 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); | 1335 Handle<FixedArray> deopt_data = factory->NewFixedArray(2, TENURED); |
| 1327 deopt_data->set(0, *weak_link); | 1336 deopt_data->set(0, *weak_link); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 } | 1504 } |
| 1496 } else { | 1505 } else { |
| 1497 // No function specified. Use the "default export". | 1506 // No function specified. Use the "default export". |
| 1498 result = module; | 1507 result = module; |
| 1499 } | 1508 } |
| 1500 | 1509 |
| 1501 return result; | 1510 return result; |
| 1502 } | 1511 } |
| 1503 | 1512 |
| 1504 // Load data segments into the memory. | 1513 // Load data segments into the memory. |
| 1505 void LoadDataSegments(Address mem_addr, size_t mem_size) { | 1514 void LoadDataSegments(MaybeHandle<JSArrayBuffer> globals, Address mem_addr, |
| 1515 size_t mem_size) { |
| 1506 CHECK(compiled_module_->has_data_segments() == | 1516 CHECK(compiled_module_->has_data_segments() == |
| 1507 compiled_module_->has_data_segments_info()); | 1517 compiled_module_->has_data_segments_info()); |
| 1508 | 1518 |
| 1509 // If we have neither, we're done. | 1519 // If we have neither, we're done. |
| 1510 if (!compiled_module_->has_data_segments()) return; | 1520 if (!compiled_module_->has_data_segments()) return; |
| 1511 | 1521 |
| 1512 Handle<ByteArray> data = compiled_module_->data_segments(); | 1522 Handle<ByteArray> data = compiled_module_->data_segments(); |
| 1513 Handle<FixedArray> segments = compiled_module_->data_segments_info(); | 1523 Handle<FixedArray> segments = compiled_module_->data_segments_info(); |
| 1514 | 1524 |
| 1515 uint32_t last_extraction_pos = 0; | 1525 uint32_t last_extraction_pos = 0; |
| 1516 for (int i = 0; i < segments->length(); ++i) { | 1526 for (int i = 0; i < segments->length(); ++i) { |
| 1517 Handle<ByteArray> segment = | 1527 Handle<ByteArray> segment = |
| 1518 Handle<ByteArray>(ByteArray::cast(segments->get(i))); | 1528 Handle<ByteArray>(ByteArray::cast(segments->get(i))); |
| 1519 uint32_t dest_addr = | 1529 uint32_t dest_addr = |
| 1520 static_cast<uint32_t>(segment->get_int(kDestAddrValue)); | 1530 static_cast<uint32_t>(segment->get_int(kDestAddrValue)); |
| 1531 if (segment->get_int(kDestAddrKind) == 1) { |
| 1532 // The destination address is the value of a global variable. |
| 1533 dest_addr = |
| 1534 *reinterpret_cast<uint32_t*>(raw_buffer_ptr(globals, dest_addr)); |
| 1535 } |
| 1536 |
| 1521 uint32_t source_size = | 1537 uint32_t source_size = |
| 1522 static_cast<uint32_t>(segment->get_int(kSourceSize)); | 1538 static_cast<uint32_t>(segment->get_int(kSourceSize)); |
| 1523 CHECK_LT(dest_addr, mem_size); | 1539 CHECK_LT(dest_addr, mem_size); |
| 1524 CHECK_LE(source_size, mem_size); | 1540 CHECK_LE(source_size, mem_size); |
| 1525 CHECK_LE(dest_addr, mem_size - source_size); | 1541 CHECK_LE(dest_addr, mem_size - source_size); |
| 1526 byte* addr = mem_addr + dest_addr; | 1542 byte* addr = mem_addr + dest_addr; |
| 1527 data->copy_out(last_extraction_pos, addr, source_size); | 1543 data->copy_out(last_extraction_pos, addr, source_size); |
| 1528 last_extraction_pos += source_size; | 1544 last_extraction_pos += source_size; |
| 1529 } | 1545 } |
| 1530 } | 1546 } |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2251 WasmCompiledModule* compiled_module = | 2267 WasmCompiledModule* compiled_module = |
| 2252 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); | 2268 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); |
| 2253 CHECK(compiled_module->has_weak_module_object()); | 2269 CHECK(compiled_module->has_weak_module_object()); |
| 2254 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); | 2270 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
| 2255 } | 2271 } |
| 2256 | 2272 |
| 2257 } // namespace testing | 2273 } // namespace testing |
| 2258 } // namespace wasm | 2274 } // namespace wasm |
| 2259 } // namespace internal | 2275 } // namespace internal |
| 2260 } // namespace v8 | 2276 } // namespace v8 |
| OLD | NEW |