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