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 #include "src/utils.h" | 6 #include "src/utils.h" |
7 | 7 |
8 #include "src/wasm/module-decoder.h" | 8 #include "src/wasm/module-decoder.h" |
9 #include "src/wasm/wasm-module.h" | 9 #include "src/wasm/wasm-module.h" |
10 #include "src/wasm/wasm-text.h" | 10 #include "src/wasm/wasm-text.h" |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 WasmFunction& function = module()->functions[func_index]; | 454 WasmFunction& function = module()->functions[func_index]; |
455 | 455 |
456 info->line = func_index; | 456 info->line = func_index; |
457 info->column = position - function.code_start_offset; | 457 info->column = position - function.code_start_offset; |
458 info->line_start = function.code_start_offset; | 458 info->line_start = function.code_start_offset; |
459 info->line_end = function.code_end_offset; | 459 info->line_end = function.code_end_offset; |
460 return true; | 460 return true; |
461 } | 461 } |
462 | 462 |
463 namespace { | 463 namespace { |
| 464 |
| 465 enum AsmJsOffsetTableEntryLayout { |
| 466 kOTEByteOffset, |
| 467 kOTECallPosition, |
| 468 kOTENumberConvPosition, |
| 469 kOTESize |
| 470 }; |
| 471 |
464 Handle<ByteArray> GetDecodedAsmJsOffsetTable( | 472 Handle<ByteArray> GetDecodedAsmJsOffsetTable( |
465 Handle<WasmCompiledModule> compiled_module, Isolate* isolate) { | 473 Handle<WasmCompiledModule> compiled_module, Isolate* isolate) { |
466 DCHECK(compiled_module->has_asm_js_offset_table()); | 474 DCHECK(compiled_module->has_asm_js_offset_table()); |
467 Handle<ByteArray> offset_table = compiled_module->asm_js_offset_table(); | 475 Handle<ByteArray> offset_table = compiled_module->asm_js_offset_table(); |
468 | 476 |
469 // The last byte in the asm_js_offset_tables ByteArray tells whether it is | 477 // The last byte in the asm_js_offset_tables ByteArray tells whether it is |
470 // still encoded (0) or decoded (1). | 478 // still encoded (0) or decoded (1). |
471 enum AsmJsTableType : int { Encoded = 0, Decoded = 1 }; | 479 enum AsmJsTableType : int { Encoded = 0, Decoded = 1 }; |
472 int table_type = offset_table->get(offset_table->length() - 1); | 480 int table_type = offset_table->get(offset_table->length() - 1); |
473 DCHECK(table_type == Encoded || table_type == Decoded); | 481 DCHECK(table_type == Encoded || table_type == Decoded); |
474 if (table_type == Decoded) return offset_table; | 482 if (table_type == Decoded) return offset_table; |
475 | 483 |
476 AsmJsOffsetsResult asm_offsets; | 484 AsmJsOffsetsResult asm_offsets; |
477 { | 485 { |
478 DisallowHeapAllocation no_gc; | 486 DisallowHeapAllocation no_gc; |
479 const byte* bytes_start = offset_table->GetDataStartAddress(); | 487 const byte* bytes_start = offset_table->GetDataStartAddress(); |
480 const byte* bytes_end = bytes_start + offset_table->length() - 1; | 488 const byte* bytes_end = bytes_start + offset_table->length() - 1; |
481 asm_offsets = wasm::DecodeAsmJsOffsets(bytes_start, bytes_end); | 489 asm_offsets = wasm::DecodeAsmJsOffsets(bytes_start, bytes_end); |
482 } | 490 } |
483 // Wasm bytes must be valid and must contain asm.js offset table. | 491 // Wasm bytes must be valid and must contain asm.js offset table. |
484 DCHECK(asm_offsets.ok()); | 492 DCHECK(asm_offsets.ok()); |
485 DCHECK_GE(kMaxInt, asm_offsets.val.size()); | 493 DCHECK_GE(kMaxInt, asm_offsets.val.size()); |
486 int num_functions = static_cast<int>(asm_offsets.val.size()); | 494 int num_functions = static_cast<int>(asm_offsets.val.size()); |
487 int num_imported_functions = | 495 int num_imported_functions = |
488 static_cast<int>(compiled_module->module()->num_imported_functions); | 496 static_cast<int>(compiled_module->module()->num_imported_functions); |
489 DCHECK_EQ(compiled_module->module()->functions.size(), | 497 DCHECK_EQ(compiled_module->module()->functions.size(), |
490 static_cast<size_t>(num_functions) + num_imported_functions); | 498 static_cast<size_t>(num_functions) + num_imported_functions); |
| 499 int num_entries = 0; |
| 500 for (int func = 0; func < num_functions; ++func) { |
| 501 size_t new_size = asm_offsets.val[func].size(); |
| 502 DCHECK_LE(new_size, static_cast<size_t>(kMaxInt) - num_entries); |
| 503 num_entries += static_cast<int>(new_size); |
| 504 } |
491 // One byte to encode that this is a decoded table. | 505 // One byte to encode that this is a decoded table. |
492 int total_size = 1; | 506 DCHECK_GE(kMaxInt, |
493 for (int func = 0; func < num_functions; ++func) { | 507 1 + static_cast<uint64_t>(num_entries) * kOTESize * kIntSize); |
494 size_t new_size = asm_offsets.val[func].size() * 2 * kIntSize; | 508 int total_size = 1 + num_entries * kOTESize * kIntSize; |
495 DCHECK_LE(new_size, static_cast<size_t>(kMaxInt) - total_size); | |
496 total_size += static_cast<int>(new_size); | |
497 } | |
498 Handle<ByteArray> decoded_table = | 509 Handle<ByteArray> decoded_table = |
499 isolate->factory()->NewByteArray(total_size, TENURED); | 510 isolate->factory()->NewByteArray(total_size, TENURED); |
500 decoded_table->set(total_size - 1, AsmJsTableType::Decoded); | 511 decoded_table->set(total_size - 1, AsmJsTableType::Decoded); |
501 compiled_module->set_asm_js_offset_table(decoded_table); | 512 compiled_module->set_asm_js_offset_table(decoded_table); |
502 | 513 |
503 int idx = 0; | 514 int idx = 0; |
504 std::vector<WasmFunction>& wasm_funs = compiled_module->module()->functions; | 515 std::vector<WasmFunction>& wasm_funs = compiled_module->module()->functions; |
505 for (int func = 0; func < num_functions; ++func) { | 516 for (int func = 0; func < num_functions; ++func) { |
506 std::vector<std::pair<int, int>>& func_asm_offsets = asm_offsets.val[func]; | 517 std::vector<AsmJsOffsetEntry>& func_asm_offsets = asm_offsets.val[func]; |
507 if (func_asm_offsets.empty()) continue; | 518 if (func_asm_offsets.empty()) continue; |
508 int func_offset = | 519 int func_offset = |
509 wasm_funs[num_imported_functions + func].code_start_offset; | 520 wasm_funs[num_imported_functions + func].code_start_offset; |
510 for (std::pair<int, int> p : func_asm_offsets) { | 521 for (AsmJsOffsetEntry& e : func_asm_offsets) { |
511 // Byte offsets must be strictly monotonously increasing: | 522 // Byte offsets must be strictly monotonously increasing: |
512 DCHECK(idx == 0 || | 523 DCHECK_IMPLIES(idx > 0, func_offset + e.byte_offset > |
513 func_offset + p.first > decoded_table->get_int(idx - 2)); | 524 decoded_table->get_int(idx - kOTESize)); |
514 decoded_table->set_int(idx++, func_offset + p.first); | 525 decoded_table->set_int(idx + kOTEByteOffset, func_offset + e.byte_offset); |
515 decoded_table->set_int(idx++, p.second); | 526 decoded_table->set_int(idx + kOTECallPosition, e.source_position_call); |
| 527 decoded_table->set_int(idx + kOTENumberConvPosition, |
| 528 e.source_position_number_conversion); |
| 529 idx += kOTESize; |
516 } | 530 } |
517 } | 531 } |
518 DCHECK_EQ(total_size, idx * kIntSize + 1); | 532 DCHECK_EQ(total_size, idx * kIntSize + 1); |
519 return decoded_table; | 533 return decoded_table; |
520 } | 534 } |
521 } // namespace | 535 } // namespace |
522 | 536 |
523 int WasmCompiledModule::GetAsmJsSourcePosition( | 537 int WasmCompiledModule::GetAsmJsSourcePosition( |
524 Handle<WasmCompiledModule> compiled_module, uint32_t func_index, | 538 Handle<WasmCompiledModule> compiled_module, uint32_t func_index, |
525 uint32_t byte_offset) { | 539 uint32_t byte_offset, bool is_at_number_conversion) { |
526 Isolate* isolate = compiled_module->GetIsolate(); | 540 Isolate* isolate = compiled_module->GetIsolate(); |
527 Handle<ByteArray> offset_table = | 541 Handle<ByteArray> offset_table = |
528 GetDecodedAsmJsOffsetTable(compiled_module, isolate); | 542 GetDecodedAsmJsOffsetTable(compiled_module, isolate); |
529 | 543 |
530 DCHECK_LT(func_index, compiled_module->module()->functions.size()); | 544 DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
531 uint32_t func_code_offset = | 545 uint32_t func_code_offset = |
532 compiled_module->module()->functions[func_index].code_start_offset; | 546 compiled_module->module()->functions[func_index].code_start_offset; |
533 uint32_t total_offset = func_code_offset + byte_offset; | 547 uint32_t total_offset = func_code_offset + byte_offset; |
534 | 548 |
535 // Binary search for the total byte offset. | 549 // Binary search for the total byte offset. |
536 int left = 0; // inclusive | 550 int left = 0; // inclusive |
537 int right = offset_table->length() / kIntSize / 2; // exclusive | 551 int right = offset_table->length() / kIntSize / kOTESize; // exclusive |
538 DCHECK_LT(left, right); | 552 DCHECK_LT(left, right); |
539 while (right - left > 1) { | 553 while (right - left > 1) { |
540 int mid = left + (right - left) / 2; | 554 int mid = left + (right - left) / 2; |
541 int mid_entry = offset_table->get_int(2 * mid); | 555 int mid_entry = offset_table->get_int(kOTESize * mid); |
542 DCHECK_GE(kMaxInt, mid_entry); | 556 DCHECK_GE(kMaxInt, mid_entry); |
543 if (static_cast<uint32_t>(mid_entry) <= total_offset) { | 557 if (static_cast<uint32_t>(mid_entry) <= total_offset) { |
544 left = mid; | 558 left = mid; |
545 } else { | 559 } else { |
546 right = mid; | 560 right = mid; |
547 } | 561 } |
548 } | 562 } |
549 // There should be an entry for each position that could show up on the stack | 563 // There should be an entry for each position that could show up on the stack |
550 // trace: | 564 // trace: |
551 DCHECK_EQ(total_offset, | 565 DCHECK_EQ(total_offset, offset_table->get_int(kOTESize * left)); |
552 static_cast<uint32_t>(offset_table->get_int(2 * left))); | 566 int idx = is_at_number_conversion ? kOTENumberConvPosition : kOTECallPosition; |
553 return offset_table->get_int(2 * left + 1); | 567 return offset_table->get_int(kOTESize * left + idx); |
554 } | 568 } |
555 | 569 |
556 v8::debug::WasmDisassembly WasmCompiledModule::DisassembleFunction( | 570 v8::debug::WasmDisassembly WasmCompiledModule::DisassembleFunction( |
557 int func_index) { | 571 int func_index) { |
558 DisallowHeapAllocation no_gc; | 572 DisallowHeapAllocation no_gc; |
559 | 573 |
560 if (func_index < 0 || | 574 if (func_index < 0 || |
561 static_cast<uint32_t>(func_index) >= module()->functions.size()) | 575 static_cast<uint32_t>(func_index) >= module()->functions.size()) |
562 return {}; | 576 return {}; |
563 | 577 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) | 611 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) |
598 return false; | 612 return false; |
599 return true; | 613 return true; |
600 } | 614 } |
601 | 615 |
602 void WasmInstanceWrapper::set_instance_object(Handle<JSObject> instance, | 616 void WasmInstanceWrapper::set_instance_object(Handle<JSObject> instance, |
603 Isolate* isolate) { | 617 Isolate* isolate) { |
604 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); | 618 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); |
605 set(kWrapperInstanceObject, *cell); | 619 set(kWrapperInstanceObject, *cell); |
606 } | 620 } |
OLD | NEW |