| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
| 10 | 10 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 RawObject** fp_; | 79 RawObject** fp_; |
| 80 Simulator* simulator_; | 80 Simulator* simulator_; |
| 81 SimulatorSetjmpBuffer* link_; | 81 SimulatorSetjmpBuffer* link_; |
| 82 | 82 |
| 83 friend class Simulator; | 83 friend class Simulator; |
| 84 | 84 |
| 85 DISALLOW_ALLOCATION(); | 85 DISALLOW_ALLOCATION(); |
| 86 DISALLOW_COPY_AND_ASSIGN(SimulatorSetjmpBuffer); | 86 DISALLOW_COPY_AND_ASSIGN(SimulatorSetjmpBuffer); |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 | |
| 90 DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) { | 89 DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) { |
| 91 return reinterpret_cast<RawObject**>(FP[kSavedCallerFpSlotFromFp]); | 90 return reinterpret_cast<RawObject**>(FP[kSavedCallerFpSlotFromFp]); |
| 92 } | 91 } |
| 93 | 92 |
| 94 | |
| 95 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP, | 93 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP, |
| 96 intptr_t argc) { | 94 intptr_t argc) { |
| 97 return FP - (kDartFrameFixedSize + argc); | 95 return FP - (kDartFrameFixedSize + argc); |
| 98 } | 96 } |
| 99 | 97 |
| 100 | |
| 101 #define RAW_CAST(Type, val) (SimulatorHelpers::CastTo##Type(val)) | 98 #define RAW_CAST(Type, val) (SimulatorHelpers::CastTo##Type(val)) |
| 102 | 99 |
| 103 | |
| 104 class SimulatorHelpers { | 100 class SimulatorHelpers { |
| 105 public: | 101 public: |
| 106 #define DEFINE_CASTS(Type) \ | 102 #define DEFINE_CASTS(Type) \ |
| 107 DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \ | 103 DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \ |
| 108 ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject() \ | 104 ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject() \ |
| 109 : obj->Is##Type()); \ | 105 : obj->Is##Type()); \ |
| 110 return reinterpret_cast<Raw##Type*>(obj); \ | 106 return reinterpret_cast<Raw##Type*>(obj); \ |
| 111 } | 107 } |
| 112 CLASS_LIST(DEFINE_CASTS) | 108 CLASS_LIST(DEFINE_CASTS) |
| 113 #undef DEFINE_CASTS | 109 #undef DEFINE_CASTS |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 reinterpret_cast<RawStackTrace*>(args[0])); | 447 reinterpret_cast<RawStackTrace*>(args[0])); |
| 452 *result = Object::null(); | 448 *result = Object::null(); |
| 453 return true; | 449 return true; |
| 454 } | 450 } |
| 455 | 451 |
| 456 DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) { | 452 DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) { |
| 457 ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid); | 453 ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid); |
| 458 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); | 454 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); |
| 459 } | 455 } |
| 460 | 456 |
| 461 | |
| 462 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { | 457 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { |
| 463 ASSERT(GetClassId(code) == kCodeCid); | 458 ASSERT(GetClassId(code) == kCodeCid); |
| 464 FP[kPcMarkerSlotFromFp] = code; | 459 FP[kPcMarkerSlotFromFp] = code; |
| 465 } | 460 } |
| 466 | 461 |
| 467 DART_FORCE_INLINE static uint8_t* GetTypedData(RawObject* obj, | 462 DART_FORCE_INLINE static uint8_t* GetTypedData(RawObject* obj, |
| 468 RawObject* index) { | 463 RawObject* index) { |
| 469 ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId())); | 464 ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId())); |
| 470 RawTypedData* array = reinterpret_cast<RawTypedData*>(obj); | 465 RawTypedData* array = reinterpret_cast<RawTypedData*>(obj); |
| 471 const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index)); | 466 const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index)); |
| 472 ASSERT(byte_offset >= 0); | 467 ASSERT(byte_offset >= 0); |
| 473 return array->ptr()->data() + byte_offset; | 468 return array->ptr()->data() + byte_offset; |
| 474 } | 469 } |
| 475 }; | 470 }; |
| 476 | 471 |
| 477 | |
| 478 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { | 472 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { |
| 479 return reinterpret_cast<uint32_t*>(FP[kSavedCallerPcSlotFromFp]); | 473 return reinterpret_cast<uint32_t*>(FP[kSavedCallerPcSlotFromFp]); |
| 480 } | 474 } |
| 481 | 475 |
| 482 | |
| 483 DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) { | 476 DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) { |
| 484 RawFunction* function = static_cast<RawFunction*>(FP[kFunctionSlotFromFp]); | 477 RawFunction* function = static_cast<RawFunction*>(FP[kFunctionSlotFromFp]); |
| 485 ASSERT(SimulatorHelpers::GetClassId(function) == kFunctionCid); | 478 ASSERT(SimulatorHelpers::GetClassId(function) == kFunctionCid); |
| 486 return function; | 479 return function; |
| 487 } | 480 } |
| 488 | 481 |
| 489 | |
| 490 IntrinsicHandler Simulator::intrinsics_[Simulator::kIntrinsicCount]; | 482 IntrinsicHandler Simulator::intrinsics_[Simulator::kIntrinsicCount]; |
| 491 | 483 |
| 492 | |
| 493 // Synchronization primitives support. | 484 // Synchronization primitives support. |
| 494 void Simulator::InitOnce() { | 485 void Simulator::InitOnce() { |
| 495 for (intptr_t i = 0; i < kIntrinsicCount; i++) { | 486 for (intptr_t i = 0; i < kIntrinsicCount; i++) { |
| 496 intrinsics_[i] = 0; | 487 intrinsics_[i] = 0; |
| 497 } | 488 } |
| 498 | 489 |
| 499 intrinsics_[kObjectArraySetIndexedIntrinsic] = | 490 intrinsics_[kObjectArraySetIndexedIntrinsic] = |
| 500 SimulatorHelpers::ObjectArraySetIndexed; | 491 SimulatorHelpers::ObjectArraySetIndexed; |
| 501 intrinsics_[kObjectArrayGetIndexedIntrinsic] = | 492 intrinsics_[kObjectArrayGetIndexedIntrinsic] = |
| 502 SimulatorHelpers::ObjectArrayGetIndexed; | 493 SimulatorHelpers::ObjectArrayGetIndexed; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 522 intrinsics_[kDouble_lessThanIntrinsic] = SimulatorHelpers::Double_lessThan; | 513 intrinsics_[kDouble_lessThanIntrinsic] = SimulatorHelpers::Double_lessThan; |
| 523 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; | 514 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; |
| 524 intrinsics_[kDouble_lessEqualThanIntrinsic] = | 515 intrinsics_[kDouble_lessEqualThanIntrinsic] = |
| 525 SimulatorHelpers::Double_lessEqualThan; | 516 SimulatorHelpers::Double_lessEqualThan; |
| 526 intrinsics_[kClearAsyncThreadStackTraceIntrinsic] = | 517 intrinsics_[kClearAsyncThreadStackTraceIntrinsic] = |
| 527 SimulatorHelpers::ClearAsyncThreadStack; | 518 SimulatorHelpers::ClearAsyncThreadStack; |
| 528 intrinsics_[kSetAsyncThreadStackTraceIntrinsic] = | 519 intrinsics_[kSetAsyncThreadStackTraceIntrinsic] = |
| 529 SimulatorHelpers::SetAsyncThreadStackTrace; | 520 SimulatorHelpers::SetAsyncThreadStackTrace; |
| 530 } | 521 } |
| 531 | 522 |
| 532 | |
| 533 Simulator::Simulator() : stack_(NULL), fp_(NULL) { | 523 Simulator::Simulator() : stack_(NULL), fp_(NULL) { |
| 534 // Setup simulator support first. Some of this information is needed to | 524 // Setup simulator support first. Some of this information is needed to |
| 535 // setup the architecture state. | 525 // setup the architecture state. |
| 536 // We allocate the stack here, the size is computed as the sum of | 526 // We allocate the stack here, the size is computed as the sum of |
| 537 // the size specified by the user and the buffer space needed for | 527 // the size specified by the user and the buffer space needed for |
| 538 // handling stack overflow exceptions. To be safe in potential | 528 // handling stack overflow exceptions. To be safe in potential |
| 539 // stack underflows we also add some underflow buffer space. | 529 // stack underflows we also add some underflow buffer space. |
| 540 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + | 530 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + |
| 541 OSThread::kStackSizeBuffer + | 531 OSThread::kStackSizeBuffer + |
| 542 kSimulatorStackUnderflowSize) / | 532 kSimulatorStackUnderflowSize) / |
| 543 sizeof(uintptr_t)]; | 533 sizeof(uintptr_t)]; |
| 544 last_setjmp_buffer_ = NULL; | 534 last_setjmp_buffer_ = NULL; |
| 545 top_exit_frame_info_ = 0; | 535 top_exit_frame_info_ = 0; |
| 546 | 536 |
| 547 NOT_IN_PRODUCT(icount_ = 0;) | 537 NOT_IN_PRODUCT(icount_ = 0;) |
| 548 } | 538 } |
| 549 | 539 |
| 550 | |
| 551 Simulator::~Simulator() { | 540 Simulator::~Simulator() { |
| 552 delete[] stack_; | 541 delete[] stack_; |
| 553 Isolate* isolate = Isolate::Current(); | 542 Isolate* isolate = Isolate::Current(); |
| 554 if (isolate != NULL) { | 543 if (isolate != NULL) { |
| 555 isolate->set_simulator(NULL); | 544 isolate->set_simulator(NULL); |
| 556 } | 545 } |
| 557 } | 546 } |
| 558 | 547 |
| 559 | |
| 560 // Get the active Simulator for the current isolate. | 548 // Get the active Simulator for the current isolate. |
| 561 Simulator* Simulator::Current() { | 549 Simulator* Simulator::Current() { |
| 562 Simulator* simulator = Isolate::Current()->simulator(); | 550 Simulator* simulator = Isolate::Current()->simulator(); |
| 563 if (simulator == NULL) { | 551 if (simulator == NULL) { |
| 564 simulator = new Simulator(); | 552 simulator = new Simulator(); |
| 565 Isolate::Current()->set_simulator(simulator); | 553 Isolate::Current()->set_simulator(simulator); |
| 566 } | 554 } |
| 567 return simulator; | 555 return simulator; |
| 568 } | 556 } |
| 569 | 557 |
| 570 | |
| 571 // Returns the top of the stack area to enable checking for stack pointer | 558 // Returns the top of the stack area to enable checking for stack pointer |
| 572 // validity. | 559 // validity. |
| 573 uword Simulator::StackTop() const { | 560 uword Simulator::StackTop() const { |
| 574 // To be safe in potential stack underflows we leave some buffer above and | 561 // To be safe in potential stack underflows we leave some buffer above and |
| 575 // set the stack top. | 562 // set the stack top. |
| 576 return StackBase() + | 563 return StackBase() + |
| 577 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); | 564 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); |
| 578 } | 565 } |
| 579 | 566 |
| 580 | |
| 581 #if !defined(PRODUCT) | 567 #if !defined(PRODUCT) |
| 582 // Returns true if tracing of executed instructions is enabled. | 568 // Returns true if tracing of executed instructions is enabled. |
| 583 DART_FORCE_INLINE bool Simulator::IsTracingExecution() const { | 569 DART_FORCE_INLINE bool Simulator::IsTracingExecution() const { |
| 584 return icount_ > FLAG_trace_sim_after; | 570 return icount_ > FLAG_trace_sim_after; |
| 585 } | 571 } |
| 586 | 572 |
| 587 | |
| 588 // Prints bytecode instruction at given pc for instruction tracing. | 573 // Prints bytecode instruction at given pc for instruction tracing. |
| 589 DART_NOINLINE void Simulator::TraceInstruction(uint32_t* pc) const { | 574 DART_NOINLINE void Simulator::TraceInstruction(uint32_t* pc) const { |
| 590 THR_Print("%" Pu64 " ", icount_); | 575 THR_Print("%" Pu64 " ", icount_); |
| 591 if (FLAG_support_disassembler) { | 576 if (FLAG_support_disassembler) { |
| 592 Disassembler::Disassemble(reinterpret_cast<uword>(pc), | 577 Disassembler::Disassemble(reinterpret_cast<uword>(pc), |
| 593 reinterpret_cast<uword>(pc + 1)); | 578 reinterpret_cast<uword>(pc + 1)); |
| 594 } else { | 579 } else { |
| 595 THR_Print("Disassembler not supported in this mode.\n"); | 580 THR_Print("Disassembler not supported in this mode.\n"); |
| 596 } | 581 } |
| 597 } | 582 } |
| 598 #endif // !defined(PRODUCT) | 583 #endif // !defined(PRODUCT) |
| 599 | 584 |
| 600 | |
| 601 // Calls into the Dart runtime are based on this interface. | 585 // Calls into the Dart runtime are based on this interface. |
| 602 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); | 586 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); |
| 603 | 587 |
| 604 // Calls to leaf Dart runtime functions are based on this interface. | 588 // Calls to leaf Dart runtime functions are based on this interface. |
| 605 typedef intptr_t (*SimulatorLeafRuntimeCall)(intptr_t r0, | 589 typedef intptr_t (*SimulatorLeafRuntimeCall)(intptr_t r0, |
| 606 intptr_t r1, | 590 intptr_t r1, |
| 607 intptr_t r2, | 591 intptr_t r2, |
| 608 intptr_t r3); | 592 intptr_t r3); |
| 609 | 593 |
| 610 // Calls to leaf float Dart runtime functions are based on this interface. | 594 // Calls to leaf float Dart runtime functions are based on this interface. |
| 611 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); | 595 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); |
| 612 | 596 |
| 613 // Calls to native Dart functions are based on this interface. | 597 // Calls to native Dart functions are based on this interface. |
| 614 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments); | 598 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments); |
| 615 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target); | 599 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target); |
| 616 | 600 |
| 617 | |
| 618 void Simulator::Exit(Thread* thread, | 601 void Simulator::Exit(Thread* thread, |
| 619 RawObject** base, | 602 RawObject** base, |
| 620 RawObject** frame, | 603 RawObject** frame, |
| 621 uint32_t* pc) { | 604 uint32_t* pc) { |
| 622 frame[0] = Function::null(); | 605 frame[0] = Function::null(); |
| 623 frame[1] = Code::null(); | 606 frame[1] = Code::null(); |
| 624 frame[2] = reinterpret_cast<RawObject*>(pc); | 607 frame[2] = reinterpret_cast<RawObject*>(pc); |
| 625 frame[3] = reinterpret_cast<RawObject*>(base); | 608 frame[3] = reinterpret_cast<RawObject*>(base); |
| 626 fp_ = frame + kDartFrameFixedSize; | 609 fp_ = frame + kDartFrameFixedSize; |
| 627 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); | 610 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 654 "1:" | 637 "1:" |
| 655 : "+r"(res), "+r"(lhs) | 638 : "+r"(res), "+r"(lhs) |
| 656 : "r"(rhs), "r"(out) | 639 : "r"(rhs), "r"(out) |
| 657 : "cc"); | 640 : "cc"); |
| 658 #else | 641 #else |
| 659 #error "Unsupported platform" | 642 #error "Unsupported platform" |
| 660 #endif | 643 #endif |
| 661 return (res != 0); | 644 return (res != 0); |
| 662 } | 645 } |
| 663 | 646 |
| 664 | |
| 665 DART_FORCE_INLINE static bool SignedSubWithOverflow(intptr_t lhs, | 647 DART_FORCE_INLINE static bool SignedSubWithOverflow(intptr_t lhs, |
| 666 intptr_t rhs, | 648 intptr_t rhs, |
| 667 intptr_t* out) { | 649 intptr_t* out) { |
| 668 intptr_t res = 1; | 650 intptr_t res = 1; |
| 669 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) | 651 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) |
| 670 asm volatile( | 652 asm volatile( |
| 671 "sub %2, %1\n" | 653 "sub %2, %1\n" |
| 672 "jo 1f;\n" | 654 "jo 1f;\n" |
| 673 "xor %0, %0\n" | 655 "xor %0, %0\n" |
| 674 "mov %1, 0(%3)\n" | 656 "mov %1, 0(%3)\n" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 685 "1:" | 667 "1:" |
| 686 : "+r"(res), "+r"(lhs) | 668 : "+r"(res), "+r"(lhs) |
| 687 : "r"(rhs), "r"(out) | 669 : "r"(rhs), "r"(out) |
| 688 : "cc"); | 670 : "cc"); |
| 689 #else | 671 #else |
| 690 #error "Unsupported platform" | 672 #error "Unsupported platform" |
| 691 #endif | 673 #endif |
| 692 return (res != 0); | 674 return (res != 0); |
| 693 } | 675 } |
| 694 | 676 |
| 695 | |
| 696 DART_FORCE_INLINE static bool SignedMulWithOverflow(intptr_t lhs, | 677 DART_FORCE_INLINE static bool SignedMulWithOverflow(intptr_t lhs, |
| 697 intptr_t rhs, | 678 intptr_t rhs, |
| 698 intptr_t* out) { | 679 intptr_t* out) { |
| 699 intptr_t res = 1; | 680 intptr_t res = 1; |
| 700 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) | 681 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) |
| 701 asm volatile( | 682 asm volatile( |
| 702 "imul %2, %1\n" | 683 "imul %2, %1\n" |
| 703 "jo 1f;\n" | 684 "jo 1f;\n" |
| 704 "xor %0, %0\n" | 685 "xor %0, %0\n" |
| 705 "mov %1, 0(%3)\n" | 686 "mov %1, 0(%3)\n" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 730 "1:" | 711 "1:" |
| 731 : "=r"(res), "+r"(prod_lo), "+r"(lhs) | 712 : "=r"(res), "+r"(prod_lo), "+r"(lhs) |
| 732 : "r"(rhs), "r"(out) | 713 : "r"(rhs), "r"(out) |
| 733 : "cc"); | 714 : "cc"); |
| 734 #else | 715 #else |
| 735 #error "Unsupported platform" | 716 #error "Unsupported platform" |
| 736 #endif | 717 #endif |
| 737 return (res != 0); | 718 return (res != 0); |
| 738 } | 719 } |
| 739 | 720 |
| 740 | |
| 741 DART_FORCE_INLINE static bool AreBothSmis(intptr_t a, intptr_t b) { | 721 DART_FORCE_INLINE static bool AreBothSmis(intptr_t a, intptr_t b) { |
| 742 return ((a | b) & kHeapObjectTag) == 0; | 722 return ((a | b) & kHeapObjectTag) == 0; |
| 743 } | 723 } |
| 744 | 724 |
| 745 | |
| 746 #define SMI_MUL(lhs, rhs, pres) SignedMulWithOverflow((lhs), (rhs) >> 1, pres) | 725 #define SMI_MUL(lhs, rhs, pres) SignedMulWithOverflow((lhs), (rhs) >> 1, pres) |
| 747 #define SMI_COND(cond, lhs, rhs, pres) \ | 726 #define SMI_COND(cond, lhs, rhs, pres) \ |
| 748 ((*(pres) = ((lhs cond rhs) ? true_value : false_value)), false) | 727 ((*(pres) = ((lhs cond rhs) ? true_value : false_value)), false) |
| 749 #define SMI_EQ(lhs, rhs, pres) SMI_COND(==, lhs, rhs, pres) | 728 #define SMI_EQ(lhs, rhs, pres) SMI_COND(==, lhs, rhs, pres) |
| 750 #define SMI_LT(lhs, rhs, pres) SMI_COND(<, lhs, rhs, pres) | 729 #define SMI_LT(lhs, rhs, pres) SMI_COND(<, lhs, rhs, pres) |
| 751 #define SMI_GT(lhs, rhs, pres) SMI_COND(>, lhs, rhs, pres) | 730 #define SMI_GT(lhs, rhs, pres) SMI_COND(>, lhs, rhs, pres) |
| 752 #define SMI_BITOR(lhs, rhs, pres) ((*(pres) = (lhs | rhs)), false) | 731 #define SMI_BITOR(lhs, rhs, pres) ((*(pres) = (lhs | rhs)), false) |
| 753 #define SMI_BITAND(lhs, rhs, pres) ((*(pres) = ((lhs) & (rhs))), false) | 732 #define SMI_BITAND(lhs, rhs, pres) ((*(pres) = ((lhs) & (rhs))), false) |
| 754 #define SMI_BITXOR(lhs, rhs, pres) ((*(pres) = ((lhs) ^ (rhs))), false) | 733 #define SMI_BITXOR(lhs, rhs, pres) ((*(pres) = ((lhs) ^ (rhs))), false) |
| 755 | 734 |
| 756 | |
| 757 void Simulator::CallRuntime(Thread* thread, | 735 void Simulator::CallRuntime(Thread* thread, |
| 758 RawObject** base, | 736 RawObject** base, |
| 759 RawObject** exit_frame, | 737 RawObject** exit_frame, |
| 760 uint32_t* pc, | 738 uint32_t* pc, |
| 761 intptr_t argc_tag, | 739 intptr_t argc_tag, |
| 762 RawObject** args, | 740 RawObject** args, |
| 763 RawObject** result, | 741 RawObject** result, |
| 764 uword target) { | 742 uword target) { |
| 765 Exit(thread, base, exit_frame, pc); | 743 Exit(thread, base, exit_frame, pc); |
| 766 NativeArguments native_args(thread, argc_tag, args, result); | 744 NativeArguments native_args(thread, argc_tag, args, result); |
| 767 reinterpret_cast<RuntimeFunction>(target)(native_args); | 745 reinterpret_cast<RuntimeFunction>(target)(native_args); |
| 768 } | 746 } |
| 769 | 747 |
| 770 | |
| 771 DART_FORCE_INLINE static void EnterSyntheticFrame(RawObject*** FP, | 748 DART_FORCE_INLINE static void EnterSyntheticFrame(RawObject*** FP, |
| 772 RawObject*** SP, | 749 RawObject*** SP, |
| 773 uint32_t* pc) { | 750 uint32_t* pc) { |
| 774 RawObject** fp = *SP + kDartFrameFixedSize; | 751 RawObject** fp = *SP + kDartFrameFixedSize; |
| 775 fp[kPcMarkerSlotFromFp] = 0; | 752 fp[kPcMarkerSlotFromFp] = 0; |
| 776 fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(pc); | 753 fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(pc); |
| 777 fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); | 754 fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); |
| 778 *FP = fp; | 755 *FP = fp; |
| 779 *SP = fp - 1; | 756 *SP = fp - 1; |
| 780 } | 757 } |
| 781 | 758 |
| 782 | |
| 783 DART_FORCE_INLINE static void LeaveSyntheticFrame(RawObject*** FP, | 759 DART_FORCE_INLINE static void LeaveSyntheticFrame(RawObject*** FP, |
| 784 RawObject*** SP) { | 760 RawObject*** SP) { |
| 785 RawObject** fp = *FP; | 761 RawObject** fp = *FP; |
| 786 *FP = reinterpret_cast<RawObject**>(fp[kSavedCallerFpSlotFromFp]); | 762 *FP = reinterpret_cast<RawObject**>(fp[kSavedCallerFpSlotFromFp]); |
| 787 *SP = fp - kDartFrameFixedSize; | 763 *SP = fp - kDartFrameFixedSize; |
| 788 } | 764 } |
| 789 | 765 |
| 790 | |
| 791 DART_FORCE_INLINE void Simulator::Invoke(Thread* thread, | 766 DART_FORCE_INLINE void Simulator::Invoke(Thread* thread, |
| 792 RawObject** call_base, | 767 RawObject** call_base, |
| 793 RawObject** call_top, | 768 RawObject** call_top, |
| 794 RawObjectPool** pp, | 769 RawObjectPool** pp, |
| 795 uint32_t** pc, | 770 uint32_t** pc, |
| 796 RawObject*** FP, | 771 RawObject*** FP, |
| 797 RawObject*** SP) { | 772 RawObject*** SP) { |
| 798 RawObject** callee_fp = call_top + kDartFrameFixedSize; | 773 RawObject** callee_fp = call_top + kDartFrameFixedSize; |
| 799 | 774 |
| 800 RawFunction* function = FrameFunction(callee_fp); | 775 RawFunction* function = FrameFunction(callee_fp); |
| 801 RawCode* code = function->ptr()->code_; | 776 RawCode* code = function->ptr()->code_; |
| 802 callee_fp[kPcMarkerSlotFromFp] = code; | 777 callee_fp[kPcMarkerSlotFromFp] = code; |
| 803 callee_fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc); | 778 callee_fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc); |
| 804 callee_fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); | 779 callee_fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); |
| 805 *pp = code->ptr()->object_pool_->ptr(); | 780 *pp = code->ptr()->object_pool_->ptr(); |
| 806 *pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); | 781 *pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
| 807 pc_ = reinterpret_cast<uword>(*pc); // For the profiler. | 782 pc_ = reinterpret_cast<uword>(*pc); // For the profiler. |
| 808 *FP = callee_fp; | 783 *FP = callee_fp; |
| 809 *SP = *FP - 1; | 784 *SP = *FP - 1; |
| 810 } | 785 } |
| 811 | 786 |
| 812 | |
| 813 void Simulator::InlineCacheMiss(int checked_args, | 787 void Simulator::InlineCacheMiss(int checked_args, |
| 814 Thread* thread, | 788 Thread* thread, |
| 815 RawICData* icdata, | 789 RawICData* icdata, |
| 816 RawObject** args, | 790 RawObject** args, |
| 817 RawObject** top, | 791 RawObject** top, |
| 818 uint32_t* pc, | 792 uint32_t* pc, |
| 819 RawObject** FP, | 793 RawObject** FP, |
| 820 RawObject** SP) { | 794 RawObject** SP) { |
| 821 RawObject** result = top; | 795 RawObject** result = top; |
| 822 RawObject** miss_handler_args = top + 1; | 796 RawObject** miss_handler_args = top + 1; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 837 break; | 811 break; |
| 838 } | 812 } |
| 839 | 813 |
| 840 // Handler arguments: arguments to check and an ICData object. | 814 // Handler arguments: arguments to check and an ICData object. |
| 841 const intptr_t miss_handler_argc = checked_args + 1; | 815 const intptr_t miss_handler_argc = checked_args + 1; |
| 842 RawObject** exit_frame = miss_handler_args + miss_handler_argc; | 816 RawObject** exit_frame = miss_handler_args + miss_handler_argc; |
| 843 CallRuntime(thread, FP, exit_frame, pc, miss_handler_argc, miss_handler_args, | 817 CallRuntime(thread, FP, exit_frame, pc, miss_handler_argc, miss_handler_args, |
| 844 result, reinterpret_cast<uword>(handler)); | 818 result, reinterpret_cast<uword>(handler)); |
| 845 } | 819 } |
| 846 | 820 |
| 847 | |
| 848 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, | 821 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, |
| 849 RawICData* icdata, | 822 RawICData* icdata, |
| 850 RawObject** call_base, | 823 RawObject** call_base, |
| 851 RawObject** top, | 824 RawObject** top, |
| 852 RawArray** argdesc, | 825 RawArray** argdesc, |
| 853 RawObjectPool** pp, | 826 RawObjectPool** pp, |
| 854 uint32_t** pc, | 827 uint32_t** pc, |
| 855 RawObject*** FP, | 828 RawObject*** FP, |
| 856 RawObject*** SP, | 829 RawObject*** SP, |
| 857 bool optimized) { | 830 bool optimized) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 880 } | 853 } |
| 881 } else { | 854 } else { |
| 882 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, | 855 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, |
| 883 *SP); | 856 *SP); |
| 884 } | 857 } |
| 885 | 858 |
| 886 *argdesc = icdata->ptr()->args_descriptor_; | 859 *argdesc = icdata->ptr()->args_descriptor_; |
| 887 Invoke(thread, call_base, top, pp, pc, FP, SP); | 860 Invoke(thread, call_base, top, pp, pc, FP, SP); |
| 888 } | 861 } |
| 889 | 862 |
| 890 | |
| 891 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 863 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
| 892 RawICData* icdata, | 864 RawICData* icdata, |
| 893 RawObject** call_base, | 865 RawObject** call_base, |
| 894 RawObject** top, | 866 RawObject** top, |
| 895 RawArray** argdesc, | 867 RawArray** argdesc, |
| 896 RawObjectPool** pp, | 868 RawObjectPool** pp, |
| 897 uint32_t** pc, | 869 uint32_t** pc, |
| 898 RawObject*** FP, | 870 RawObject*** FP, |
| 899 RawObject*** SP, | 871 RawObject*** SP, |
| 900 bool optimized) { | 872 bool optimized) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 925 } | 897 } |
| 926 } else { | 898 } else { |
| 927 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, | 899 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, |
| 928 *SP); | 900 *SP); |
| 929 } | 901 } |
| 930 | 902 |
| 931 *argdesc = icdata->ptr()->args_descriptor_; | 903 *argdesc = icdata->ptr()->args_descriptor_; |
| 932 Invoke(thread, call_base, top, pp, pc, FP, SP); | 904 Invoke(thread, call_base, top, pp, pc, FP, SP); |
| 933 } | 905 } |
| 934 | 906 |
| 935 | |
| 936 // Note: functions below are marked DART_NOINLINE to recover performance on | 907 // Note: functions below are marked DART_NOINLINE to recover performance on |
| 937 // ARM where inlining these functions into the interpreter loop seemed to cause | 908 // ARM where inlining these functions into the interpreter loop seemed to cause |
| 938 // some code quality issues. | 909 // some code quality issues. |
| 939 static DART_NOINLINE bool InvokeRuntime(Thread* thread, | 910 static DART_NOINLINE bool InvokeRuntime(Thread* thread, |
| 940 Simulator* sim, | 911 Simulator* sim, |
| 941 RuntimeFunction drt, | 912 RuntimeFunction drt, |
| 942 const NativeArguments& args) { | 913 const NativeArguments& args) { |
| 943 SimulatorSetjmpBuffer buffer(sim); | 914 SimulatorSetjmpBuffer buffer(sim); |
| 944 if (!setjmp(buffer.buffer_)) { | 915 if (!setjmp(buffer.buffer_)) { |
| 945 thread->set_vm_tag(reinterpret_cast<uword>(drt)); | 916 thread->set_vm_tag(reinterpret_cast<uword>(drt)); |
| 946 drt(args); | 917 drt(args); |
| 947 thread->set_vm_tag(VMTag::kDartTagId); | 918 thread->set_vm_tag(VMTag::kDartTagId); |
| 948 thread->set_top_exit_frame_info(0); | 919 thread->set_top_exit_frame_info(0); |
| 949 return true; | 920 return true; |
| 950 } else { | 921 } else { |
| 951 return false; | 922 return false; |
| 952 } | 923 } |
| 953 } | 924 } |
| 954 | 925 |
| 955 | |
| 956 static DART_NOINLINE bool InvokeBootstrapNative(Thread* thread, | 926 static DART_NOINLINE bool InvokeBootstrapNative(Thread* thread, |
| 957 Simulator* sim, | 927 Simulator* sim, |
| 958 SimulatorBootstrapNativeCall f, | 928 SimulatorBootstrapNativeCall f, |
| 959 NativeArguments* args) { | 929 NativeArguments* args) { |
| 960 SimulatorSetjmpBuffer buffer(sim); | 930 SimulatorSetjmpBuffer buffer(sim); |
| 961 if (!setjmp(buffer.buffer_)) { | 931 if (!setjmp(buffer.buffer_)) { |
| 962 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 932 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
| 963 f(args); | 933 f(args); |
| 964 thread->set_vm_tag(VMTag::kDartTagId); | 934 thread->set_vm_tag(VMTag::kDartTagId); |
| 965 thread->set_top_exit_frame_info(0); | 935 thread->set_top_exit_frame_info(0); |
| 966 return true; | 936 return true; |
| 967 } else { | 937 } else { |
| 968 return false; | 938 return false; |
| 969 } | 939 } |
| 970 } | 940 } |
| 971 | 941 |
| 972 | |
| 973 static DART_NOINLINE bool InvokeNativeNoScopeWrapper(Thread* thread, | 942 static DART_NOINLINE bool InvokeNativeNoScopeWrapper(Thread* thread, |
| 974 Simulator* sim, | 943 Simulator* sim, |
| 975 Dart_NativeFunction f, | 944 Dart_NativeFunction f, |
| 976 NativeArguments* args) { | 945 NativeArguments* args) { |
| 977 SimulatorSetjmpBuffer buffer(sim); | 946 SimulatorSetjmpBuffer buffer(sim); |
| 978 if (!setjmp(buffer.buffer_)) { | 947 if (!setjmp(buffer.buffer_)) { |
| 979 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 948 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
| 980 NativeEntry::NoScopeNativeCallWrapper( | 949 NativeEntry::NoScopeNativeCallWrapper( |
| 981 reinterpret_cast<Dart_NativeArguments>(args), f); | 950 reinterpret_cast<Dart_NativeArguments>(args), f); |
| 982 thread->set_vm_tag(VMTag::kDartTagId); | 951 thread->set_vm_tag(VMTag::kDartTagId); |
| 983 thread->set_top_exit_frame_info(0); | 952 thread->set_top_exit_frame_info(0); |
| 984 return true; | 953 return true; |
| 985 } else { | 954 } else { |
| 986 return false; | 955 return false; |
| 987 } | 956 } |
| 988 } | 957 } |
| 989 | 958 |
| 990 | |
| 991 static DART_NOINLINE bool InvokeNativeAutoScopeWrapper(Thread* thread, | 959 static DART_NOINLINE bool InvokeNativeAutoScopeWrapper(Thread* thread, |
| 992 Simulator* sim, | 960 Simulator* sim, |
| 993 Dart_NativeFunction f, | 961 Dart_NativeFunction f, |
| 994 NativeArguments* args) { | 962 NativeArguments* args) { |
| 995 SimulatorSetjmpBuffer buffer(sim); | 963 SimulatorSetjmpBuffer buffer(sim); |
| 996 if (!setjmp(buffer.buffer_)) { | 964 if (!setjmp(buffer.buffer_)) { |
| 997 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 965 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
| 998 NativeEntry::AutoScopeNativeCallWrapper( | 966 NativeEntry::AutoScopeNativeCallWrapper( |
| 999 reinterpret_cast<Dart_NativeArguments>(args), f); | 967 reinterpret_cast<Dart_NativeArguments>(args), f); |
| 1000 thread->set_vm_tag(VMTag::kDartTagId); | 968 thread->set_vm_tag(VMTag::kDartTagId); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 #define DECODE___D rD = (op >> Bytecode::kDShift); | 1029 #define DECODE___D rD = (op >> Bytecode::kDShift); |
| 1062 | 1030 |
| 1063 #define DECLARE_A_D DECLARE___D | 1031 #define DECLARE_A_D DECLARE___D |
| 1064 #define DECODE_A_D DECODE___D | 1032 #define DECODE_A_D DECODE___D |
| 1065 | 1033 |
| 1066 #define DECLARE_A_X \ | 1034 #define DECLARE_A_X \ |
| 1067 int32_t rD; \ | 1035 int32_t rD; \ |
| 1068 USE(rD) | 1036 USE(rD) |
| 1069 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); | 1037 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); |
| 1070 | 1038 |
| 1071 | |
| 1072 #define SMI_FASTPATH_ICDATA_INC \ | 1039 #define SMI_FASTPATH_ICDATA_INC \ |
| 1073 do { \ | 1040 do { \ |
| 1074 ASSERT(Bytecode::IsCallOpcode(*pc)); \ | 1041 ASSERT(Bytecode::IsCallOpcode(*pc)); \ |
| 1075 const uint16_t kidx = Bytecode::DecodeD(*pc); \ | 1042 const uint16_t kidx = Bytecode::DecodeD(*pc); \ |
| 1076 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ | 1043 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ |
| 1077 RawObject** entries = icdata->ptr()->ic_data_->ptr()->data(); \ | 1044 RawObject** entries = icdata->ptr()->ic_data_->ptr()->data(); \ |
| 1078 SimulatorHelpers::IncrementICUsageCount(entries, 0, 2); \ | 1045 SimulatorHelpers::IncrementICUsageCount(entries, 0, 2); \ |
| 1079 } while (0); | 1046 } while (0); |
| 1080 | 1047 |
| 1081 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the | 1048 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1111 | 1078 |
| 1112 // Do not check for overflow. | 1079 // Do not check for overflow. |
| 1113 #define SMI_OP_NOCHECK(ResultT, Func) \ | 1080 #define SMI_OP_NOCHECK(ResultT, Func) \ |
| 1114 { \ | 1081 { \ |
| 1115 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); \ | 1082 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); \ |
| 1116 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); \ | 1083 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); \ |
| 1117 ResultT* slot = reinterpret_cast<ResultT*>(&FP[rA]); \ | 1084 ResultT* slot = reinterpret_cast<ResultT*>(&FP[rA]); \ |
| 1118 Func(lhs, rhs, slot); \ | 1085 Func(lhs, rhs, slot); \ |
| 1119 } | 1086 } |
| 1120 | 1087 |
| 1121 | |
| 1122 // Exception handling helper. Gets handler FP and PC from the Simulator where | 1088 // Exception handling helper. Gets handler FP and PC from the Simulator where |
| 1123 // they were stored by Simulator::Longjmp and proceeds to execute the handler. | 1089 // they were stored by Simulator::Longjmp and proceeds to execute the handler. |
| 1124 // Corner case: handler PC can be a fake marker that marks entry frame, which | 1090 // Corner case: handler PC can be a fake marker that marks entry frame, which |
| 1125 // means exception was not handled in the Dart code. In this case we return | 1091 // means exception was not handled in the Dart code. In this case we return |
| 1126 // caught exception from Simulator::Call. | 1092 // caught exception from Simulator::Call. |
| 1127 #define HANDLE_EXCEPTION \ | 1093 #define HANDLE_EXCEPTION \ |
| 1128 do { \ | 1094 do { \ |
| 1129 FP = reinterpret_cast<RawObject**>(fp_); \ | 1095 FP = reinterpret_cast<RawObject**>(fp_); \ |
| 1130 pc = reinterpret_cast<uint32_t*>(pc_); \ | 1096 pc = reinterpret_cast<uint32_t*>(pc_); \ |
| 1131 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ | 1097 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1155 HANDLE_EXCEPTION; \ | 1121 HANDLE_EXCEPTION; \ |
| 1156 } | 1122 } |
| 1157 | 1123 |
| 1158 #define INVOKE_NATIVE_AUTO_SCOPE(Func, Args) \ | 1124 #define INVOKE_NATIVE_AUTO_SCOPE(Func, Args) \ |
| 1159 if (!InvokeNativeAutoScopeWrapper(thread, this, Func, &Args)) { \ | 1125 if (!InvokeNativeAutoScopeWrapper(thread, this, Func, &Args)) { \ |
| 1160 HANDLE_EXCEPTION; \ | 1126 HANDLE_EXCEPTION; \ |
| 1161 } | 1127 } |
| 1162 | 1128 |
| 1163 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) | 1129 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) |
| 1164 | 1130 |
| 1165 | |
| 1166 // Returns true if deoptimization succeeds. | 1131 // Returns true if deoptimization succeeds. |
| 1167 DART_FORCE_INLINE bool Simulator::Deoptimize(Thread* thread, | 1132 DART_FORCE_INLINE bool Simulator::Deoptimize(Thread* thread, |
| 1168 RawObjectPool** pp, | 1133 RawObjectPool** pp, |
| 1169 uint32_t** pc, | 1134 uint32_t** pc, |
| 1170 RawObject*** FP, | 1135 RawObject*** FP, |
| 1171 RawObject*** SP, | 1136 RawObject*** SP, |
| 1172 bool is_lazy) { | 1137 bool is_lazy) { |
| 1173 // Note: frame translation will take care of preserving result at the | 1138 // Note: frame translation will take care of preserving result at the |
| 1174 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo. | 1139 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo. |
| 1175 | 1140 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 // FrameArguments(...) returns a pointer to the first argument. | 1177 // FrameArguments(...) returns a pointer to the first argument. |
| 1213 *SP = FrameArguments(*FP, materialization_arg_count) - 1; | 1178 *SP = FrameArguments(*FP, materialization_arg_count) - 1; |
| 1214 *FP = SavedCallerFP(*FP); | 1179 *FP = SavedCallerFP(*FP); |
| 1215 | 1180 |
| 1216 // Restore pp. | 1181 // Restore pp. |
| 1217 *pp = SimulatorHelpers::FrameCode(*FP)->ptr()->object_pool_->ptr(); | 1182 *pp = SimulatorHelpers::FrameCode(*FP)->ptr()->object_pool_->ptr(); |
| 1218 | 1183 |
| 1219 return true; | 1184 return true; |
| 1220 } | 1185 } |
| 1221 | 1186 |
| 1222 | |
| 1223 RawObject* Simulator::Call(const Code& code, | 1187 RawObject* Simulator::Call(const Code& code, |
| 1224 const Array& arguments_descriptor, | 1188 const Array& arguments_descriptor, |
| 1225 const Array& arguments, | 1189 const Array& arguments, |
| 1226 Thread* thread) { | 1190 Thread* thread) { |
| 1227 // Dispatch used to interpret bytecode. Contains addresses of | 1191 // Dispatch used to interpret bytecode. Contains addresses of |
| 1228 // labels of bytecode handlers. Handlers themselves are defined below. | 1192 // labels of bytecode handlers. Handlers themselves are defined below. |
| 1229 static const void* dispatch[] = { | 1193 static const void* dispatch[] = { |
| 1230 #define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name, | 1194 #define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name, |
| 1231 BYTECODES_LIST(TARGET) | 1195 BYTECODES_LIST(TARGET) |
| 1232 #undef TARGET | 1196 #undef TARGET |
| (...skipping 2664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3897 // Single dispatch point used by exception handling macros. | 3861 // Single dispatch point used by exception handling macros. |
| 3898 { | 3862 { |
| 3899 DispatchAfterException: | 3863 DispatchAfterException: |
| 3900 DISPATCH(); | 3864 DISPATCH(); |
| 3901 } | 3865 } |
| 3902 | 3866 |
| 3903 UNREACHABLE(); | 3867 UNREACHABLE(); |
| 3904 return 0; | 3868 return 0; |
| 3905 } | 3869 } |
| 3906 | 3870 |
| 3907 | |
| 3908 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { | 3871 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { |
| 3909 // Walk over all setjmp buffers (simulated --> C++ transitions) | 3872 // Walk over all setjmp buffers (simulated --> C++ transitions) |
| 3910 // and try to find the setjmp associated with the simulated frame pointer. | 3873 // and try to find the setjmp associated with the simulated frame pointer. |
| 3911 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); | 3874 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); |
| 3912 while ((buf->link() != NULL) && (buf->link()->fp() > fp)) { | 3875 while ((buf->link() != NULL) && (buf->link()->fp() > fp)) { |
| 3913 buf = buf->link(); | 3876 buf = buf->link(); |
| 3914 } | 3877 } |
| 3915 ASSERT(buf != NULL); | 3878 ASSERT(buf != NULL); |
| 3916 ASSERT(last_setjmp_buffer() == buf); | 3879 ASSERT(last_setjmp_buffer() == buf); |
| 3917 | 3880 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3940 pc_ = pc; | 3903 pc_ = pc; |
| 3941 } | 3904 } |
| 3942 | 3905 |
| 3943 buf->Longjmp(); | 3906 buf->Longjmp(); |
| 3944 UNREACHABLE(); | 3907 UNREACHABLE(); |
| 3945 } | 3908 } |
| 3946 | 3909 |
| 3947 } // namespace dart | 3910 } // namespace dart |
| 3948 | 3911 |
| 3949 #endif // defined TARGET_ARCH_DBC | 3912 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |