Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 462 Isolate* isolate = Isolate::Current(); | 462 Isolate* isolate = Isolate::Current(); |
| 463 next_ = isolate->simulator_redirection(); | 463 next_ = isolate->simulator_redirection(); |
| 464 // TODO(all): Simulator flush I cache | 464 // TODO(all): Simulator flush I cache |
| 465 isolate->set_simulator_redirection(this); | 465 isolate->set_simulator_redirection(this); |
| 466 } | 466 } |
| 467 | 467 |
| 468 void* address_of_redirect_call() { | 468 void* address_of_redirect_call() { |
| 469 return reinterpret_cast<void*>(&redirect_call_); | 469 return reinterpret_cast<void*>(&redirect_call_); |
| 470 } | 470 } |
| 471 | 471 |
| 472 void* external_function() { return external_function_; } | 472 template <typename T> |
| 473 T external_function() { return reinterpret_cast<T>(external_function_); } | |
|
ulan
2014/03/19 08:53:19
Indentation is off
Alexandre Rames
2014/03/20 09:49:33
Fixing before landing.
| |
| 473 ExternalReference::Type type() { return type_; } | 474 ExternalReference::Type type() { return type_; } |
| 474 | 475 |
| 475 static Redirection* Get(void* external_function, | 476 static Redirection* Get(void* external_function, |
| 476 ExternalReference::Type type) { | 477 ExternalReference::Type type) { |
| 477 Isolate* isolate = Isolate::Current(); | 478 Isolate* isolate = Isolate::Current(); |
| 478 Redirection* current = isolate->simulator_redirection(); | 479 Redirection* current = isolate->simulator_redirection(); |
| 479 for (; current != NULL; current = current->next_) { | 480 for (; current != NULL; current = current->next_) { |
| 480 if (current->external_function_ == external_function) { | 481 if (current->external_function_ == external_function) { |
| 481 ASSERT_EQ(current->type(), type); | 482 ASSERT_EQ(current->type(), type); |
| 482 return current; | 483 return current; |
| 483 } | 484 } |
| 484 } | 485 } |
| 485 return new Redirection(external_function, type); | 486 return new Redirection(external_function, type); |
| 486 } | 487 } |
| 487 | 488 |
| 488 static Redirection* FromHltInstruction(Instruction* redirect_call) { | 489 static Redirection* FromHltInstruction(Instruction* redirect_call) { |
| 489 char* addr_of_hlt = reinterpret_cast<char*>(redirect_call); | 490 char* addr_of_hlt = reinterpret_cast<char*>(redirect_call); |
| 490 char* addr_of_redirection = | 491 char* addr_of_redirection = |
| 491 addr_of_hlt - OFFSET_OF(Redirection, redirect_call_); | 492 addr_of_hlt - OFFSET_OF(Redirection, redirect_call_); |
| 492 return reinterpret_cast<Redirection*>(addr_of_redirection); | 493 return reinterpret_cast<Redirection*>(addr_of_redirection); |
| 493 } | 494 } |
| 494 | 495 |
| 495 static void* ReverseRedirection(int64_t reg) { | 496 static void* ReverseRedirection(int64_t reg) { |
| 496 Redirection* redirection = | 497 Redirection* redirection = |
| 497 FromHltInstruction(reinterpret_cast<Instruction*>(reg)); | 498 FromHltInstruction(reinterpret_cast<Instruction*>(reg)); |
| 498 return redirection->external_function(); | 499 return redirection->external_function<void*>(); |
| 499 } | 500 } |
| 500 | 501 |
| 501 private: | 502 private: |
| 502 void* external_function_; | 503 void* external_function_; |
| 503 Instruction redirect_call_; | 504 Instruction redirect_call_; |
| 504 ExternalReference::Type type_; | 505 ExternalReference::Type type_; |
| 505 Redirection* next_; | 506 Redirection* next_; |
| 506 }; | 507 }; |
| 507 | 508 |
| 508 | 509 |
| 510 // Calls into the V8 runtime are based on this very simple interface. | |
| 511 // Note: To be able to return two values from some calls the code in runtime.cc | |
| 512 // uses the ObjectPair structure. | |
| 513 // The simulator assumes all runtime calls return two 64-bits values. If they | |
| 514 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. | |
| 515 struct ObjectPair { | |
| 516 int64_t res0; | |
| 517 int64_t res1; | |
| 518 }; | |
| 519 | |
| 520 | |
| 521 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, | |
| 522 int64_t arg1, | |
| 523 int64_t arg2, | |
| 524 int64_t arg3, | |
| 525 int64_t arg4, | |
| 526 int64_t arg5, | |
| 527 int64_t arg6, | |
| 528 int64_t arg7); | |
| 529 | |
| 530 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); | |
| 531 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); | |
| 532 typedef double (*SimulatorRuntimeFPCall)(double arg1); | |
| 533 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); | |
| 534 | |
| 535 // This signature supports direct call in to API function native callback | |
| 536 // (refer to InvocationCallback in v8.h). | |
| 537 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0); | |
| 538 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1); | |
| 539 | |
| 540 // This signature supports direct call to accessor getter callback. | |
| 541 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1); | |
| 542 typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1, | |
| 543 void* arg2); | |
| 544 | |
| 545 void Simulator::DoRuntimeCall(Instruction* instr) { | |
| 546 Redirection* redirection = Redirection::FromHltInstruction(instr); | |
| 547 | |
| 548 // The called C code might itself call simulated code, so any | |
| 549 // caller-saved registers (including lr) could still be clobbered by a | |
| 550 // redirected call. | |
| 551 Instruction* return_address = lr(); | |
| 552 | |
| 553 int64_t external = redirection->external_function<int64_t>(); | |
| 554 | |
| 555 TraceSim("Call to host function at %p\n", | |
| 556 redirection->external_function<void*>()); | |
| 557 | |
| 558 // SP must be 16-byte-aligned at the call interface. | |
| 559 bool stack_alignment_exception = ((sp() & 0xf) != 0); | |
| 560 if (stack_alignment_exception) { | |
| 561 TraceSim(" with unaligned stack 0x%016" PRIx64 ".\n", sp()); | |
| 562 FATAL("ALIGNMENT EXCEPTION"); | |
| 563 } | |
| 564 | |
| 565 switch (redirection->type()) { | |
| 566 default: | |
| 567 TraceSim("Type: Unknown.\n"); | |
| 568 UNREACHABLE(); | |
| 569 break; | |
| 570 | |
| 571 case ExternalReference::BUILTIN_CALL: { | |
| 572 // MaybeObject* f(v8::internal::Arguments). | |
| 573 TraceSim("Type: BUILTIN_CALL\n"); | |
| 574 SimulatorRuntimeCall target = | |
| 575 reinterpret_cast<SimulatorRuntimeCall>(external); | |
| 576 | |
| 577 // We don't know how many arguments are being passed, but we can | |
| 578 // pass 8 without touching the stack. They will be ignored by the | |
| 579 // host function if they aren't used. | |
| 580 TraceSim("Arguments: " | |
| 581 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | |
| 582 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | |
| 583 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | |
| 584 "0x%016" PRIx64 ", 0x%016" PRIx64, | |
| 585 xreg(0), xreg(1), xreg(2), xreg(3), | |
| 586 xreg(4), xreg(5), xreg(6), xreg(7)); | |
| 587 ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3), | |
| 588 xreg(4), xreg(5), xreg(6), xreg(7)); | |
| 589 TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64 "}\n", | |
| 590 result.res0, result.res1); | |
| 591 #ifdef DEBUG | |
| 592 CorruptAllCallerSavedCPURegisters(); | |
| 593 #endif | |
| 594 set_xreg(0, result.res0); | |
| 595 set_xreg(1, result.res1); | |
| 596 break; | |
| 597 } | |
| 598 | |
| 599 case ExternalReference::DIRECT_API_CALL: { | |
| 600 // void f(v8::FunctionCallbackInfo&) | |
| 601 TraceSim("Type: DIRECT_API_CALL\n"); | |
| 602 SimulatorRuntimeDirectApiCall target = | |
| 603 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); | |
| 604 TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0)); | |
| 605 target(xreg(0)); | |
| 606 TraceSim("No return value."); | |
| 607 #ifdef DEBUG | |
| 608 CorruptAllCallerSavedCPURegisters(); | |
| 609 #endif | |
| 610 break; | |
| 611 } | |
| 612 | |
| 613 case ExternalReference::BUILTIN_COMPARE_CALL: { | |
| 614 // int f(double, double) | |
| 615 TraceSim("Type: BUILTIN_COMPARE_CALL\n"); | |
| 616 SimulatorRuntimeCompareCall target = | |
| 617 reinterpret_cast<SimulatorRuntimeCompareCall>(external); | |
| 618 TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1)); | |
| 619 int64_t result = target(dreg(0), dreg(1)); | |
| 620 TraceSim("Returned: %" PRId64 "\n", result); | |
| 621 #ifdef DEBUG | |
| 622 CorruptAllCallerSavedCPURegisters(); | |
| 623 #endif | |
| 624 set_xreg(0, result); | |
| 625 break; | |
| 626 } | |
| 627 | |
| 628 case ExternalReference::BUILTIN_FP_CALL: { | |
| 629 // double f(double) | |
| 630 TraceSim("Type: BUILTIN_FP_CALL\n"); | |
| 631 SimulatorRuntimeFPCall target = | |
| 632 reinterpret_cast<SimulatorRuntimeFPCall>(external); | |
| 633 TraceSim("Argument: %f\n", dreg(0)); | |
| 634 double result = target(dreg(0)); | |
| 635 TraceSim("Returned: %f\n", result); | |
| 636 #ifdef DEBUG | |
| 637 CorruptAllCallerSavedCPURegisters(); | |
| 638 #endif | |
| 639 set_dreg(0, result); | |
| 640 break; | |
| 641 } | |
| 642 | |
| 643 case ExternalReference::BUILTIN_FP_FP_CALL: { | |
| 644 // double f(double, double) | |
| 645 TraceSim("Type: BUILTIN_FP_FP_CALL\n"); | |
| 646 SimulatorRuntimeFPFPCall target = | |
| 647 reinterpret_cast<SimulatorRuntimeFPFPCall>(external); | |
| 648 TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1)); | |
| 649 double result = target(dreg(0), dreg(1)); | |
| 650 TraceSim("Returned: %f\n", result); | |
| 651 #ifdef DEBUG | |
| 652 CorruptAllCallerSavedCPURegisters(); | |
| 653 #endif | |
| 654 set_dreg(0, result); | |
| 655 break; | |
| 656 } | |
| 657 | |
| 658 case ExternalReference::BUILTIN_FP_INT_CALL: { | |
| 659 // double f(double, int) | |
| 660 TraceSim("Type: BUILTIN_FP_INT_CALL\n"); | |
| 661 SimulatorRuntimeFPIntCall target = | |
| 662 reinterpret_cast<SimulatorRuntimeFPIntCall>(external); | |
| 663 TraceSim("Arguments: %f, %d\n", dreg(0), wreg(0)); | |
| 664 double result = target(dreg(0), wreg(0)); | |
| 665 TraceSim("Returned: %f\n", result); | |
| 666 #ifdef DEBUG | |
| 667 CorruptAllCallerSavedCPURegisters(); | |
| 668 #endif | |
| 669 set_dreg(0, result); | |
| 670 break; | |
| 671 } | |
| 672 | |
| 673 case ExternalReference::DIRECT_GETTER_CALL: { | |
| 674 // void f(Local<String> property, PropertyCallbackInfo& info) | |
| 675 TraceSim("Type: DIRECT_GETTER_CALL\n"); | |
| 676 SimulatorRuntimeDirectGetterCall target = | |
| 677 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); | |
| 678 TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n", | |
| 679 xreg(0), xreg(1)); | |
| 680 target(xreg(0), xreg(1)); | |
| 681 TraceSim("No return value."); | |
| 682 #ifdef DEBUG | |
| 683 CorruptAllCallerSavedCPURegisters(); | |
| 684 #endif | |
| 685 break; | |
| 686 } | |
| 687 | |
| 688 case ExternalReference::PROFILING_API_CALL: { | |
| 689 // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback) | |
| 690 TraceSim("Type: PROFILING_API_CALL\n"); | |
| 691 SimulatorRuntimeProfilingApiCall target = | |
| 692 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); | |
| 693 void* arg1 = Redirection::ReverseRedirection(xreg(1)); | |
| 694 TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1); | |
| 695 target(xreg(0), arg1); | |
| 696 TraceSim("No return value."); | |
| 697 #ifdef DEBUG | |
| 698 CorruptAllCallerSavedCPURegisters(); | |
| 699 #endif | |
| 700 break; | |
| 701 } | |
| 702 | |
| 703 case ExternalReference::PROFILING_GETTER_CALL: { | |
| 704 // void f(Local<String> property, PropertyCallbackInfo& info, | |
| 705 // AccessorGetterCallback callback) | |
| 706 TraceSim("Type: PROFILING_GETTER_CALL\n"); | |
| 707 SimulatorRuntimeProfilingGetterCall target = | |
| 708 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>( | |
| 709 external); | |
| 710 void* arg2 = Redirection::ReverseRedirection(xreg(2)); | |
| 711 TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n", | |
| 712 xreg(0), xreg(1), arg2); | |
| 713 target(xreg(0), xreg(1), arg2); | |
| 714 TraceSim("No return value."); | |
| 715 #ifdef DEBUG | |
| 716 CorruptAllCallerSavedCPURegisters(); | |
| 717 #endif | |
| 718 break; | |
| 719 } | |
| 720 } | |
| 721 | |
| 722 set_lr(return_address); | |
| 723 set_pc(return_address); | |
| 724 } | |
| 725 | |
| 726 | |
| 509 void* Simulator::RedirectExternalReference(void* external_function, | 727 void* Simulator::RedirectExternalReference(void* external_function, |
| 510 ExternalReference::Type type) { | 728 ExternalReference::Type type) { |
| 511 Redirection* redirection = Redirection::Get(external_function, type); | 729 Redirection* redirection = Redirection::Get(external_function, type); |
| 512 return redirection->address_of_redirect_call(); | 730 return redirection->address_of_redirect_call(); |
| 513 } | 731 } |
| 514 | 732 |
| 515 | 733 |
| 516 const char* Simulator::xreg_names[] = { | 734 const char* Simulator::xreg_names[] = { |
| 517 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", | 735 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", |
| 518 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", | 736 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", |
| (...skipping 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3292 PrintF("Use 'help' for more information.\n"); | 3510 PrintF("Use 'help' for more information.\n"); |
| 3293 } | 3511 } |
| 3294 } | 3512 } |
| 3295 if (cleared_log_disasm_bit == true) { | 3513 if (cleared_log_disasm_bit == true) { |
| 3296 set_log_parameters(log_parameters_ | LOG_DISASM); | 3514 set_log_parameters(log_parameters_ | LOG_DISASM); |
| 3297 } | 3515 } |
| 3298 } | 3516 } |
| 3299 } | 3517 } |
| 3300 | 3518 |
| 3301 | 3519 |
| 3302 // Calls into the V8 runtime are based on this very simple interface. | |
| 3303 // Note: To be able to return two values from some calls the code in runtime.cc | |
| 3304 // uses the ObjectPair structure. | |
| 3305 // The simulator assumes all runtime calls return two 64-bits values. If they | |
| 3306 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. | |
| 3307 struct ObjectPair { | |
| 3308 int64_t res0; | |
| 3309 int64_t res1; | |
| 3310 }; | |
| 3311 | |
| 3312 | |
| 3313 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, | |
| 3314 int64_t arg1, | |
| 3315 int64_t arg2, | |
| 3316 int64_t arg3, | |
| 3317 int64_t arg4, | |
| 3318 int64_t arg5, | |
| 3319 int64_t arg6, | |
| 3320 int64_t arg7); | |
| 3321 | |
| 3322 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); | |
| 3323 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); | |
| 3324 typedef double (*SimulatorRuntimeFPCall)(double arg1); | |
| 3325 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); | |
| 3326 | |
| 3327 // This signature supports direct call in to API function native callback | |
| 3328 // (refer to InvocationCallback in v8.h). | |
| 3329 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0); | |
| 3330 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1); | |
| 3331 | |
| 3332 // This signature supports direct call to accessor getter callback. | |
| 3333 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1); | |
| 3334 typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1, | |
| 3335 void* arg2); | |
| 3336 | |
| 3337 void Simulator::VisitException(Instruction* instr) { | 3520 void Simulator::VisitException(Instruction* instr) { |
| 3338 // Define some colour codes to use for log messages. | 3521 // Define some colour codes to use for log messages. |
| 3339 // TODO(jbramley): Find a more elegant way of defining these. | 3522 // TODO(jbramley): Find a more elegant way of defining these. |
| 3340 char const* const clr_normal = (FLAG_log_colour) ? ("\033[m") | 3523 char const* const clr_normal = (FLAG_log_colour) ? ("\033[m") |
| 3341 : (""); | 3524 : (""); |
| 3342 char const* const clr_debug_number = (FLAG_log_colour) ? ("\033[1;33m") | 3525 char const* const clr_debug_number = (FLAG_log_colour) ? ("\033[1;33m") |
| 3343 : (""); | 3526 : (""); |
| 3344 char const* const clr_debug_message = (FLAG_log_colour) ? ("\033[0;33m") | 3527 char const* const clr_debug_message = (FLAG_log_colour) ? ("\033[0;33m") |
| 3345 : (""); | 3528 : (""); |
| 3346 char const* const clr_printf = (FLAG_log_colour) ? ("\033[0;32m") | 3529 char const* const clr_printf = (FLAG_log_colour) ? ("\033[0;32m") |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3414 // - Verify that the unreachable marker is present. | 3597 // - Verify that the unreachable marker is present. |
| 3415 ASSERT(pc_->Mask(ExceptionMask) == HLT); | 3598 ASSERT(pc_->Mask(ExceptionMask) == HLT); |
| 3416 ASSERT(pc_->ImmException() == kImmExceptionIsUnreachable); | 3599 ASSERT(pc_->ImmException() == kImmExceptionIsUnreachable); |
| 3417 // - Skip past the unreachable marker. | 3600 // - Skip past the unreachable marker. |
| 3418 set_pc(pc_->following()); | 3601 set_pc(pc_->following()); |
| 3419 | 3602 |
| 3420 // Check if the debugger should break. | 3603 // Check if the debugger should break. |
| 3421 if (parameters & BREAK) Debug(); | 3604 if (parameters & BREAK) Debug(); |
| 3422 | 3605 |
| 3423 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) { | 3606 } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) { |
| 3424 // TODO(all): Extract the call redirection code into a separate | 3607 DoRuntimeCall(instr); |
| 3425 // function. | |
| 3426 | |
| 3427 Redirection* redirection = Redirection::FromHltInstruction(instr); | |
| 3428 | |
| 3429 // The called C code might itself call simulated code, so any | |
| 3430 // caller-saved registers (including lr) could still be clobbered by a | |
| 3431 // redirected call. | |
| 3432 Instruction* return_address = lr(); | |
| 3433 | |
| 3434 // TODO(jbramley): Make external_function() a template so that we don't | |
| 3435 // have to explicitly cast the result for each redirection type. | |
| 3436 int64_t external = | |
| 3437 reinterpret_cast<int64_t>(redirection->external_function()); | |
| 3438 | |
| 3439 TraceSim("Call to host function at %p\n", | |
| 3440 reinterpret_cast<void*>(redirection->external_function())); | |
| 3441 | |
| 3442 // SP must be 16 bytes aligned at the call interface. | |
| 3443 bool stack_alignment_exception = ((sp() & 0xf) != 0); | |
| 3444 if (stack_alignment_exception) { | |
| 3445 TraceSim(" with unaligned stack 0x%016" PRIx64 ".\n", sp()); | |
| 3446 FATAL("ALIGNMENT EXCEPTION"); | |
| 3447 } | |
| 3448 | |
| 3449 switch (redirection->type()) { | |
| 3450 default: | |
| 3451 TraceSim("Type: Unknown.\n"); | |
| 3452 UNREACHABLE(); | |
| 3453 break; | |
| 3454 | |
| 3455 case ExternalReference::BUILTIN_CALL: { | |
| 3456 // MaybeObject* f(v8::internal::Arguments). | |
| 3457 TraceSim("Type: BUILTIN_CALL\n"); | |
| 3458 SimulatorRuntimeCall target = | |
| 3459 reinterpret_cast<SimulatorRuntimeCall>(external); | |
| 3460 | |
| 3461 // We don't know how many arguments are being passed, but we can | |
| 3462 // pass 8 without touching the stack. They will be ignored by the | |
| 3463 // host function if they aren't used. | |
| 3464 TraceSim("Arguments: " | |
| 3465 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | |
| 3466 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | |
| 3467 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | |
| 3468 "0x%016" PRIx64 ", 0x%016" PRIx64, | |
| 3469 xreg(0), xreg(1), xreg(2), xreg(3), | |
| 3470 xreg(4), xreg(5), xreg(6), xreg(7)); | |
| 3471 ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3), | |
| 3472 xreg(4), xreg(5), xreg(6), xreg(7)); | |
| 3473 TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64"}\n", | |
| 3474 result.res0, result.res1); | |
| 3475 #ifdef DEBUG | |
| 3476 CorruptAllCallerSavedCPURegisters(); | |
| 3477 #endif | |
| 3478 set_xreg(0, result.res0); | |
| 3479 set_xreg(1, result.res1); | |
| 3480 break; | |
| 3481 } | |
| 3482 | |
| 3483 case ExternalReference::DIRECT_API_CALL: { | |
| 3484 // void f(v8::FunctionCallbackInfo&) | |
| 3485 TraceSim("Type: DIRECT_API_CALL\n"); | |
| 3486 SimulatorRuntimeDirectApiCall target = | |
| 3487 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); | |
| 3488 TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0)); | |
| 3489 target(xreg(0)); | |
| 3490 TraceSim("No return value."); | |
| 3491 #ifdef DEBUG | |
| 3492 CorruptAllCallerSavedCPURegisters(); | |
| 3493 #endif | |
| 3494 break; | |
| 3495 } | |
| 3496 | |
| 3497 case ExternalReference::BUILTIN_COMPARE_CALL: { | |
| 3498 // int f(double, double) | |
| 3499 TraceSim("Type: BUILTIN_COMPARE_CALL\n"); | |
| 3500 SimulatorRuntimeCompareCall target = | |
| 3501 reinterpret_cast<SimulatorRuntimeCompareCall>(external); | |
| 3502 TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1)); | |
| 3503 int64_t result = target(dreg(0), dreg(1)); | |
| 3504 TraceSim("Returned: %" PRId64 "\n", result); | |
| 3505 #ifdef DEBUG | |
| 3506 CorruptAllCallerSavedCPURegisters(); | |
| 3507 #endif | |
| 3508 set_xreg(0, result); | |
| 3509 break; | |
| 3510 } | |
| 3511 | |
| 3512 case ExternalReference::BUILTIN_FP_CALL: { | |
| 3513 // double f(double) | |
| 3514 TraceSim("Type: BUILTIN_FP_CALL\n"); | |
| 3515 SimulatorRuntimeFPCall target = | |
| 3516 reinterpret_cast<SimulatorRuntimeFPCall>(external); | |
| 3517 TraceSim("Argument: %f\n", dreg(0)); | |
| 3518 double result = target(dreg(0)); | |
| 3519 TraceSim("Returned: %f\n", result); | |
| 3520 #ifdef DEBUG | |
| 3521 CorruptAllCallerSavedCPURegisters(); | |
| 3522 #endif | |
| 3523 set_dreg(0, result); | |
| 3524 break; | |
| 3525 } | |
| 3526 | |
| 3527 case ExternalReference::BUILTIN_FP_FP_CALL: { | |
| 3528 // double f(double, double) | |
| 3529 TraceSim("Type: BUILTIN_FP_FP_CALL\n"); | |
| 3530 SimulatorRuntimeFPFPCall target = | |
| 3531 reinterpret_cast<SimulatorRuntimeFPFPCall>(external); | |
| 3532 TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1)); | |
| 3533 double result = target(dreg(0), dreg(1)); | |
| 3534 TraceSim("Returned: %f\n", result); | |
| 3535 #ifdef DEBUG | |
| 3536 CorruptAllCallerSavedCPURegisters(); | |
| 3537 #endif | |
| 3538 set_dreg(0, result); | |
| 3539 break; | |
| 3540 } | |
| 3541 | |
| 3542 case ExternalReference::BUILTIN_FP_INT_CALL: { | |
| 3543 // double f(double, int) | |
| 3544 TraceSim("Type: BUILTIN_FP_INT_CALL\n"); | |
| 3545 SimulatorRuntimeFPIntCall target = | |
| 3546 reinterpret_cast<SimulatorRuntimeFPIntCall>(external); | |
| 3547 TraceSim("Arguments: %f, %d\n", dreg(0), wreg(0)); | |
| 3548 double result = target(dreg(0), wreg(0)); | |
| 3549 TraceSim("Returned: %f\n", result); | |
| 3550 #ifdef DEBUG | |
| 3551 CorruptAllCallerSavedCPURegisters(); | |
| 3552 #endif | |
| 3553 set_dreg(0, result); | |
| 3554 break; | |
| 3555 } | |
| 3556 | |
| 3557 case ExternalReference::DIRECT_GETTER_CALL: { | |
| 3558 // void f(Local<String> property, PropertyCallbackInfo& info) | |
| 3559 TraceSim("Type: DIRECT_GETTER_CALL\n"); | |
| 3560 SimulatorRuntimeDirectGetterCall target = | |
| 3561 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); | |
| 3562 TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n", | |
| 3563 xreg(0), xreg(1)); | |
| 3564 target(xreg(0), xreg(1)); | |
| 3565 TraceSim("No return value."); | |
| 3566 #ifdef DEBUG | |
| 3567 CorruptAllCallerSavedCPURegisters(); | |
| 3568 #endif | |
| 3569 break; | |
| 3570 } | |
| 3571 | |
| 3572 case ExternalReference::PROFILING_API_CALL: { | |
| 3573 // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback) | |
| 3574 TraceSim("Type: PROFILING_API_CALL\n"); | |
| 3575 SimulatorRuntimeProfilingApiCall target = | |
| 3576 reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); | |
| 3577 void* arg1 = Redirection::ReverseRedirection(xreg(1)); | |
| 3578 TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1); | |
| 3579 target(xreg(0), arg1); | |
| 3580 TraceSim("No return value."); | |
| 3581 #ifdef DEBUG | |
| 3582 CorruptAllCallerSavedCPURegisters(); | |
| 3583 #endif | |
| 3584 break; | |
| 3585 } | |
| 3586 | |
| 3587 case ExternalReference::PROFILING_GETTER_CALL: { | |
| 3588 // void f(Local<String> property, PropertyCallbackInfo& info, | |
| 3589 // AccessorGetterCallback callback) | |
| 3590 TraceSim("Type: PROFILING_GETTER_CALL\n"); | |
| 3591 SimulatorRuntimeProfilingGetterCall target = | |
| 3592 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>( | |
| 3593 external); | |
| 3594 void* arg2 = Redirection::ReverseRedirection(xreg(2)); | |
| 3595 TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n", | |
| 3596 xreg(0), xreg(1), arg2); | |
| 3597 target(xreg(0), xreg(1), arg2); | |
| 3598 TraceSim("No return value."); | |
| 3599 #ifdef DEBUG | |
| 3600 CorruptAllCallerSavedCPURegisters(); | |
| 3601 #endif | |
| 3602 break; | |
| 3603 } | |
| 3604 } | |
| 3605 | |
| 3606 set_lr(return_address); | |
| 3607 set_pc(return_address); | |
| 3608 } else if (instr->ImmException() == kImmExceptionIsPrintf) { | 3608 } else if (instr->ImmException() == kImmExceptionIsPrintf) { |
| 3609 // Read the argument encoded inline in the instruction stream. | 3609 // Read the argument encoded inline in the instruction stream. |
| 3610 uint32_t type; | 3610 uint32_t type; |
| 3611 memcpy(&type, | 3611 memcpy(&type, |
| 3612 pc_->InstructionAtOffset(kPrintfTypeOffset), | 3612 pc_->InstructionAtOffset(kPrintfTypeOffset), |
| 3613 sizeof(type)); | 3613 sizeof(type)); |
| 3614 | 3614 |
| 3615 const char* format = reg<const char*>(0); | 3615 const char* format = reg<const char*>(0); |
| 3616 | 3616 |
| 3617 // Pass all of the relevant PCS registers onto printf. It doesn't | 3617 // Pass all of the relevant PCS registers onto printf. It doesn't |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3655 default: | 3655 default: |
| 3656 UNIMPLEMENTED(); | 3656 UNIMPLEMENTED(); |
| 3657 } | 3657 } |
| 3658 } | 3658 } |
| 3659 | 3659 |
| 3660 #endif // USE_SIMULATOR | 3660 #endif // USE_SIMULATOR |
| 3661 | 3661 |
| 3662 } } // namespace v8::internal | 3662 } } // namespace v8::internal |
| 3663 | 3663 |
| 3664 #endif // V8_TARGET_ARCH_A64 | 3664 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |