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