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

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

Issue 2403823002: [wasm] Base address for data segments can also be the value of a global variable. (Closed)
Patch Set: Created 4 years, 2 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
« no previous file with comments | « no previous file | test/mjsunit/wasm/data-segments.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/data-segments.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698