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/wasm/wasm-objects.h" | 5 #include "src/wasm/wasm-objects.h" |
| 6 | |
| 7 #include "src/wasm/module-decoder.h" | |
| 6 #include "src/wasm/wasm-module.h" | 8 #include "src/wasm/wasm-module.h" |
| 7 | 9 |
| 8 #define TRACE(...) \ | 10 #define TRACE(...) \ |
| 9 do { \ | 11 do { \ |
| 10 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ | 12 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ |
| 11 } while (false) | 13 } while (false) |
| 12 | 14 |
| 13 #define TRACE_CHAIN(instance) \ | 15 #define TRACE_CHAIN(instance) \ |
| 14 do { \ | 16 do { \ |
| 15 instance->PrintInstancesChain(); \ | 17 instance->PrintInstancesChain(); \ |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 if (func_index < 0) return false; | 419 if (func_index < 0) return false; |
| 418 | 420 |
| 419 WasmFunction& function = module()->functions[func_index]; | 421 WasmFunction& function = module()->functions[func_index]; |
| 420 | 422 |
| 421 info->line = func_index; | 423 info->line = func_index; |
| 422 info->column = position - function.code_start_offset; | 424 info->column = position - function.code_start_offset; |
| 423 info->line_start = function.code_start_offset; | 425 info->line_start = function.code_start_offset; |
| 424 info->line_end = function.code_end_offset; | 426 info->line_end = function.code_end_offset; |
| 425 return true; | 427 return true; |
| 426 } | 428 } |
| 429 | |
| 430 namespace { | |
| 431 Handle<ByteArray> GetDecodedAsmJsOffsetTable( | |
| 432 Handle<WasmCompiledModule> compiled_module, Isolate* isolate) { | |
| 433 DCHECK(compiled_module->has_asm_js_offset_table()); | |
| 434 Handle<ByteArray> offset_table = compiled_module->asm_js_offset_table(); | |
| 435 | |
| 436 // The last byte in the asm_js_offset_tables ByteArray tells whether it is | |
| 437 // still encoded (0) or decoded (1). | |
| 438 int is_decoded = offset_table->get(offset_table->length() - 1); | |
| 439 DCHECK(is_decoded == 0 || is_decoded == 1); | |
| 440 if (is_decoded) return offset_table; | |
| 441 | |
| 442 AsmJsOffsetsResult asm_offsets; | |
| 443 { | |
| 444 DisallowHeapAllocation no_gc; | |
| 445 const byte* bytes_start = offset_table->GetDataStartAddress(); | |
| 446 const byte* bytes_end = bytes_start + offset_table->length() - 1; | |
| 447 asm_offsets = wasm::DecodeAsmJsOffsets(bytes_start, bytes_end); | |
| 448 } | |
| 449 // Wasm bytes must be valid and must contain asm.js offset table. | |
| 450 DCHECK(asm_offsets.ok()); | |
| 451 DCHECK_GE(static_cast<size_t>(kMaxInt), asm_offsets.val.size()); | |
| 452 int num_functions = static_cast<int>(asm_offsets.val.size()); | |
| 453 int num_imported_functions = | |
| 454 static_cast<int>(compiled_module->module()->num_imported_functions); | |
| 455 DCHECK_EQ(compiled_module->module()->functions.size(), | |
| 456 static_cast<size_t>(num_functions) + num_imported_functions); | |
| 457 // One byte to encode that this is a decoded table. | |
| 458 int total_size = 1; | |
| 459 for (int func = 0; func < num_functions; ++func) { | |
| 460 size_t new_size = asm_offsets.val[func].size() * 2 * kIntSize; | |
| 461 DCHECK_LE(new_size, static_cast<size_t>(kMaxInt) - total_size); | |
| 462 total_size += static_cast<int>(new_size); | |
| 463 } | |
| 464 Handle<ByteArray> decoded_table = | |
| 465 isolate->factory()->NewByteArray(total_size, TENURED); | |
| 466 decoded_table->set(total_size - 1, 1); | |
|
ahaas
2016/11/23 10:08:54
same here.
Clemens Hammacher
2016/11/23 12:24:36
Added a function-local enum to make clear the mean
| |
| 467 compiled_module->set_asm_js_offset_table(decoded_table); | |
| 468 | |
| 469 int idx = 0; | |
| 470 std::vector<WasmFunction>& wasm_funs = compiled_module->module()->functions; | |
| 471 for (int func = 0; func < num_functions; ++func) { | |
| 472 std::vector<std::pair<int, int>>& func_asm_offsets = asm_offsets.val[func]; | |
| 473 if (func_asm_offsets.empty()) continue; | |
| 474 int func_offset = | |
| 475 wasm_funs[num_imported_functions + func].code_start_offset; | |
| 476 for (std::pair<int, int> p : func_asm_offsets) { | |
| 477 // Byte offsets must be strictly monotonously increasing: | |
| 478 DCHECK(idx == 0 || | |
| 479 func_offset + p.first > decoded_table->get_int(idx - 2)); | |
| 480 decoded_table->set_int(idx++, func_offset + p.first); | |
| 481 decoded_table->set_int(idx++, p.second); | |
| 482 } | |
| 483 } | |
| 484 DCHECK_EQ(total_size, idx * kIntSize + 1); | |
| 485 return decoded_table; | |
| 486 } | |
| 487 } // namespace | |
| 488 | |
| 489 int WasmCompiledModule::GetAsmJsSourcePosition( | |
| 490 Handle<WasmCompiledModule> compiled_module, uint32_t func_index, | |
| 491 uint32_t byte_offset) { | |
| 492 Isolate* isolate = compiled_module->GetIsolate(); | |
| 493 Handle<ByteArray> offset_table = | |
| 494 GetDecodedAsmJsOffsetTable(compiled_module, isolate); | |
| 495 | |
| 496 DCHECK_LT(func_index, compiled_module->module()->functions.size()); | |
| 497 uint32_t func_code_offset = | |
| 498 compiled_module->module()->functions[func_index].code_start_offset; | |
| 499 uint32_t total_offset = func_code_offset + byte_offset; | |
| 500 | |
| 501 // Binary search for the total byte offset. | |
| 502 int left = 0; // inclusive | |
| 503 int right = offset_table->length() / kIntSize / 2; // exclusive | |
| 504 DCHECK_LT(left, right); | |
| 505 while (right - left > 1) { | |
| 506 int mid = left + (right - left) / 2; | |
| 507 int mid_entry = offset_table->get_int(2 * mid); | |
| 508 DCHECK_GE(kMaxInt, mid_entry); | |
| 509 if (static_cast<uint32_t>(mid_entry) <= total_offset) { | |
| 510 left = mid; | |
| 511 } else { | |
| 512 right = mid; | |
| 513 } | |
| 514 } | |
| 515 // There should be an entry for each position that could show up on the stack | |
| 516 // trace: | |
| 517 DCHECK_EQ(total_offset, | |
| 518 static_cast<uint32_t>(offset_table->get_int(2 * left))); | |
| 519 return offset_table->get_int(2 * left + 1); | |
| 520 } | |
| OLD | NEW |