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 |