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 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 | 441 |
440 WasmFunction& function = module()->functions[func_index]; | 442 WasmFunction& function = module()->functions[func_index]; |
441 | 443 |
442 info->line = func_index; | 444 info->line = func_index; |
443 info->column = position - function.code_start_offset; | 445 info->column = position - function.code_start_offset; |
444 info->line_start = function.code_start_offset; | 446 info->line_start = function.code_start_offset; |
445 info->line_end = function.code_end_offset; | 447 info->line_end = function.code_end_offset; |
446 return true; | 448 return true; |
447 } | 449 } |
448 | 450 |
| 451 namespace { |
| 452 Handle<ByteArray> GetDecodedAsmJsOffsetTable( |
| 453 Handle<WasmCompiledModule> compiled_module, Isolate* isolate) { |
| 454 DCHECK(compiled_module->has_asm_js_offset_table()); |
| 455 Handle<ByteArray> offset_table = compiled_module->asm_js_offset_table(); |
| 456 |
| 457 // The last byte in the asm_js_offset_tables ByteArray tells whether it is |
| 458 // still encoded (0) or decoded (1). |
| 459 enum AsmJsTableType : int { Encoded = 0, Decoded = 1 }; |
| 460 int table_type = offset_table->get(offset_table->length() - 1); |
| 461 DCHECK(table_type == Encoded || table_type == Decoded); |
| 462 if (table_type == Decoded) return offset_table; |
| 463 |
| 464 AsmJsOffsetsResult asm_offsets; |
| 465 { |
| 466 DisallowHeapAllocation no_gc; |
| 467 const byte* bytes_start = offset_table->GetDataStartAddress(); |
| 468 const byte* bytes_end = bytes_start + offset_table->length() - 1; |
| 469 asm_offsets = wasm::DecodeAsmJsOffsets(bytes_start, bytes_end); |
| 470 } |
| 471 // Wasm bytes must be valid and must contain asm.js offset table. |
| 472 DCHECK(asm_offsets.ok()); |
| 473 DCHECK_GE(static_cast<size_t>(kMaxInt), asm_offsets.val.size()); |
| 474 int num_functions = static_cast<int>(asm_offsets.val.size()); |
| 475 int num_imported_functions = |
| 476 static_cast<int>(compiled_module->module()->num_imported_functions); |
| 477 DCHECK_EQ(compiled_module->module()->functions.size(), |
| 478 static_cast<size_t>(num_functions) + num_imported_functions); |
| 479 // One byte to encode that this is a decoded table. |
| 480 int total_size = 1; |
| 481 for (int func = 0; func < num_functions; ++func) { |
| 482 size_t new_size = asm_offsets.val[func].size() * 2 * kIntSize; |
| 483 DCHECK_LE(new_size, static_cast<size_t>(kMaxInt) - total_size); |
| 484 total_size += static_cast<int>(new_size); |
| 485 } |
| 486 Handle<ByteArray> decoded_table = |
| 487 isolate->factory()->NewByteArray(total_size, TENURED); |
| 488 decoded_table->set(total_size - 1, AsmJsTableType::Decoded); |
| 489 compiled_module->set_asm_js_offset_table(decoded_table); |
| 490 |
| 491 int idx = 0; |
| 492 std::vector<WasmFunction>& wasm_funs = compiled_module->module()->functions; |
| 493 for (int func = 0; func < num_functions; ++func) { |
| 494 std::vector<std::pair<int, int>>& func_asm_offsets = asm_offsets.val[func]; |
| 495 if (func_asm_offsets.empty()) continue; |
| 496 int func_offset = |
| 497 wasm_funs[num_imported_functions + func].code_start_offset; |
| 498 for (std::pair<int, int> p : func_asm_offsets) { |
| 499 // Byte offsets must be strictly monotonously increasing: |
| 500 DCHECK(idx == 0 || |
| 501 func_offset + p.first > decoded_table->get_int(idx - 2)); |
| 502 decoded_table->set_int(idx++, func_offset + p.first); |
| 503 decoded_table->set_int(idx++, p.second); |
| 504 } |
| 505 } |
| 506 DCHECK_EQ(total_size, idx * kIntSize + 1); |
| 507 return decoded_table; |
| 508 } |
| 509 } // namespace |
| 510 |
| 511 int WasmCompiledModule::GetAsmJsSourcePosition( |
| 512 Handle<WasmCompiledModule> compiled_module, uint32_t func_index, |
| 513 uint32_t byte_offset) { |
| 514 Isolate* isolate = compiled_module->GetIsolate(); |
| 515 Handle<ByteArray> offset_table = |
| 516 GetDecodedAsmJsOffsetTable(compiled_module, isolate); |
| 517 |
| 518 DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
| 519 uint32_t func_code_offset = |
| 520 compiled_module->module()->functions[func_index].code_start_offset; |
| 521 uint32_t total_offset = func_code_offset + byte_offset; |
| 522 |
| 523 // Binary search for the total byte offset. |
| 524 int left = 0; // inclusive |
| 525 int right = offset_table->length() / kIntSize / 2; // exclusive |
| 526 DCHECK_LT(left, right); |
| 527 while (right - left > 1) { |
| 528 int mid = left + (right - left) / 2; |
| 529 int mid_entry = offset_table->get_int(2 * mid); |
| 530 DCHECK_GE(kMaxInt, mid_entry); |
| 531 if (static_cast<uint32_t>(mid_entry) <= total_offset) { |
| 532 left = mid; |
| 533 } else { |
| 534 right = mid; |
| 535 } |
| 536 } |
| 537 // There should be an entry for each position that could show up on the stack |
| 538 // trace: |
| 539 DCHECK_EQ(total_offset, |
| 540 static_cast<uint32_t>(offset_table->get_int(2 * left))); |
| 541 return offset_table->get_int(2 * left + 1); |
| 542 } |
| 543 |
449 Handle<WasmInstanceWrapper> WasmInstanceWrapper::New( | 544 Handle<WasmInstanceWrapper> WasmInstanceWrapper::New( |
450 Isolate* isolate, Handle<WasmInstanceObject> instance) { | 545 Isolate* isolate, Handle<WasmInstanceObject> instance) { |
451 Handle<FixedArray> array = | 546 Handle<FixedArray> array = |
452 isolate->factory()->NewFixedArray(kWrapperPropertyCount, TENURED); | 547 isolate->factory()->NewFixedArray(kWrapperPropertyCount, TENURED); |
453 Handle<WasmInstanceWrapper> instance_wrapper( | 548 Handle<WasmInstanceWrapper> instance_wrapper( |
454 reinterpret_cast<WasmInstanceWrapper*>(*array), isolate); | 549 reinterpret_cast<WasmInstanceWrapper*>(*array), isolate); |
455 instance_wrapper->set_instance_object(instance, isolate); | 550 instance_wrapper->set_instance_object(instance, isolate); |
456 return instance_wrapper; | 551 return instance_wrapper; |
457 } | 552 } |
458 | 553 |
(...skipping 10 matching lines...) Expand all Loading... |
469 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) | 564 !array->get(kPreviousInstanceWrapper)->IsFixedArray()) |
470 return false; | 565 return false; |
471 return true; | 566 return true; |
472 } | 567 } |
473 | 568 |
474 void WasmInstanceWrapper::set_instance_object(Handle<JSObject> instance, | 569 void WasmInstanceWrapper::set_instance_object(Handle<JSObject> instance, |
475 Isolate* isolate) { | 570 Isolate* isolate) { |
476 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); | 571 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); |
477 set(kWrapperInstanceObject, *cell); | 572 set(kWrapperInstanceObject, *cell); |
478 } | 573 } |
OLD | NEW |