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 |