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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 DISALLOW_ALLOCATION(); | 80 DISALLOW_ALLOCATION(); |
81 DISALLOW_COPY_AND_ASSIGN(SimulatorSetjmpBuffer); | 81 DISALLOW_COPY_AND_ASSIGN(SimulatorSetjmpBuffer); |
82 }; | 82 }; |
83 | 83 |
84 | 84 |
85 DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) { | 85 DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) { |
86 return reinterpret_cast<RawObject**>(FP[kSavedCallerFpSlotFromFp]); | 86 return reinterpret_cast<RawObject**>(FP[kSavedCallerFpSlotFromFp]); |
87 } | 87 } |
88 | 88 |
89 | 89 |
90 DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) { | |
91 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); | |
92 } | |
93 | |
94 | |
95 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { | |
96 FP[kPcMarkerSlotFromFp] = code; | |
97 } | |
98 | |
99 | |
100 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP, | 90 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP, |
101 intptr_t argc) { | 91 intptr_t argc) { |
102 return FP - (kDartFrameFixedSize + argc); | 92 return FP - (kDartFrameFixedSize + argc); |
103 } | 93 } |
104 | 94 |
105 | 95 |
| 96 #define RAW_CAST(Type, val) (SimulatorHelpers::CastTo##Type(val)) |
| 97 |
| 98 |
106 class SimulatorHelpers { | 99 class SimulatorHelpers { |
107 public: | 100 public: |
| 101 #define DEFINE_CASTS(Type) \ |
| 102 DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \ |
| 103 ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject() \ |
| 104 : obj->Is##Type()); \ |
| 105 return reinterpret_cast<Raw##Type*>(obj); \ |
| 106 } |
| 107 CLASS_LIST(DEFINE_CASTS) |
| 108 #undef DEFINE_CASTS |
| 109 |
108 DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) { | 110 DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) { |
109 return Smi::New(obj->IsHeapObject() ? obj->GetClassId() | 111 return Smi::New(obj->IsHeapObject() ? obj->GetClassId() |
110 : static_cast<intptr_t>(kSmiCid)); | 112 : static_cast<intptr_t>(kSmiCid)); |
111 } | 113 } |
112 | 114 |
113 DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) { | 115 DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) { |
114 return obj->IsHeapObject() ? obj->GetClassId() | 116 return obj->IsHeapObject() ? obj->GetClassId() |
115 : static_cast<intptr_t>(kSmiCid); | 117 : static_cast<intptr_t>(kSmiCid); |
116 } | 118 } |
117 | 119 |
118 DART_FORCE_INLINE static void IncrementUsageCounter(RawICData* icdata) { | 120 DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) { |
119 reinterpret_cast<RawFunction*>(icdata->ptr()->owner_) | 121 f->ptr()->usage_counter_++; |
120 ->ptr() | |
121 ->usage_counter_++; | |
122 } | 122 } |
123 | 123 |
124 DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs, | 124 DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs, |
125 RawObject* rhs) { | 125 RawObject* rhs) { |
126 if (lhs == rhs) { | 126 if (lhs == rhs) { |
127 return true; | 127 return true; |
128 } | 128 } |
129 | 129 |
130 if (lhs->IsHeapObject() && rhs->IsHeapObject()) { | 130 if (lhs->IsHeapObject() && rhs->IsHeapObject()) { |
131 const intptr_t lhs_cid = lhs->GetClassId(); | 131 const intptr_t lhs_cid = lhs->GetClassId(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 RawObject** args = FrameArguments(FP, 2); | 219 RawObject** args = FrameArguments(FP, 2); |
220 RawSmi* index = static_cast<RawSmi*>(args[1]); | 220 RawSmi* index = static_cast<RawSmi*>(args[1]); |
221 RawGrowableObjectArray* array = | 221 RawGrowableObjectArray* array = |
222 static_cast<RawGrowableObjectArray*>(args[0]); | 222 static_cast<RawGrowableObjectArray*>(args[0]); |
223 if (CheckIndex(index, array->ptr()->length_)) { | 223 if (CheckIndex(index, array->ptr()->length_)) { |
224 *result = array->ptr()->data_->ptr()->data()[Smi::Value(index)]; | 224 *result = array->ptr()->data_->ptr()->data()[Smi::Value(index)]; |
225 return true; | 225 return true; |
226 } | 226 } |
227 return false; | 227 return false; |
228 } | 228 } |
| 229 |
| 230 DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) { |
| 231 ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid); |
| 232 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); |
| 233 } |
| 234 |
| 235 |
| 236 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { |
| 237 ASSERT(GetClassId(code) == kCodeCid); |
| 238 FP[kPcMarkerSlotFromFp] = code; |
| 239 } |
229 }; | 240 }; |
230 | 241 |
231 | 242 |
232 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { | 243 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { |
233 return reinterpret_cast<uint32_t*>(FP[kSavedCallerPcSlotFromFp]); | 244 return reinterpret_cast<uint32_t*>(FP[kSavedCallerPcSlotFromFp]); |
234 } | 245 } |
235 | 246 |
236 | 247 |
237 DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) { | 248 DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) { |
238 RawFunction* function = static_cast<RawFunction*>(FP[kFunctionSlotFromFp]); | 249 RawFunction* function = static_cast<RawFunction*>(FP[kFunctionSlotFromFp]); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 intptr_t argc_tag, | 486 intptr_t argc_tag, |
476 RawObject** args, | 487 RawObject** args, |
477 RawObject** result, | 488 RawObject** result, |
478 uword target) { | 489 uword target) { |
479 Exit(thread, base, exit_frame, pc); | 490 Exit(thread, base, exit_frame, pc); |
480 NativeArguments native_args(thread, argc_tag, args, result); | 491 NativeArguments native_args(thread, argc_tag, args, result); |
481 reinterpret_cast<RuntimeFunction>(target)(native_args); | 492 reinterpret_cast<RuntimeFunction>(target)(native_args); |
482 } | 493 } |
483 | 494 |
484 | 495 |
| 496 DART_FORCE_INLINE static void EnterSyntheticFrame(RawObject*** FP, |
| 497 RawObject*** SP, |
| 498 uint32_t* pc) { |
| 499 RawObject** fp = *SP + kDartFrameFixedSize; |
| 500 fp[kPcMarkerSlotFromFp] = 0; |
| 501 fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(pc); |
| 502 fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); |
| 503 *FP = fp; |
| 504 *SP = fp - 1; |
| 505 } |
| 506 |
| 507 |
| 508 DART_FORCE_INLINE static void LeaveSyntheticFrame(RawObject*** FP, |
| 509 RawObject*** SP) { |
| 510 RawObject** fp = *FP; |
| 511 *FP = reinterpret_cast<RawObject**>(fp[kSavedCallerFpSlotFromFp]); |
| 512 *SP = fp - kDartFrameFixedSize; |
| 513 } |
| 514 |
| 515 |
485 DART_FORCE_INLINE void Simulator::Invoke(Thread* thread, | 516 DART_FORCE_INLINE void Simulator::Invoke(Thread* thread, |
486 RawObject** call_base, | 517 RawObject** call_base, |
487 RawObject** call_top, | 518 RawObject** call_top, |
488 RawObjectPool** pp, | 519 RawObjectPool** pp, |
489 uint32_t** pc, | 520 uint32_t** pc, |
490 RawObject*** FP, | 521 RawObject*** FP, |
491 RawObject*** SP) { | 522 RawObject*** SP) { |
492 RawObject** callee_fp = call_top + kDartFrameFixedSize; | 523 RawObject** callee_fp = call_top + kDartFrameFixedSize; |
493 | 524 |
494 RawFunction* function = FrameFunction(callee_fp); | 525 RawFunction* function = FrameFunction(callee_fp); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, | 581 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, |
551 RawICData* icdata, | 582 RawICData* icdata, |
552 RawObject** call_base, | 583 RawObject** call_base, |
553 RawObject** top, | 584 RawObject** top, |
554 RawArray** argdesc, | 585 RawArray** argdesc, |
555 RawObjectPool** pp, | 586 RawObjectPool** pp, |
556 uint32_t** pc, | 587 uint32_t** pc, |
557 RawObject*** FP, | 588 RawObject*** FP, |
558 RawObject*** SP) { | 589 RawObject*** SP) { |
559 ASSERT(icdata->GetClassId() == kICDataCid); | 590 ASSERT(icdata->GetClassId() == kICDataCid); |
560 SimulatorHelpers::IncrementUsageCounter(icdata); | |
561 | 591 |
562 const intptr_t kCheckedArgs = 1; | 592 const intptr_t kCheckedArgs = 1; |
563 RawObject** args = call_base; | 593 RawObject** args = call_base; |
564 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 594 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
565 | 595 |
566 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 596 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
567 | 597 |
568 bool found = false; | 598 bool found = false; |
569 const intptr_t length = Smi::Value(cache->length_); | 599 const intptr_t length = Smi::Value(cache->length_); |
570 for (intptr_t i = 0; | 600 for (intptr_t i = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
589 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 619 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
590 RawICData* icdata, | 620 RawICData* icdata, |
591 RawObject** call_base, | 621 RawObject** call_base, |
592 RawObject** top, | 622 RawObject** top, |
593 RawArray** argdesc, | 623 RawArray** argdesc, |
594 RawObjectPool** pp, | 624 RawObjectPool** pp, |
595 uint32_t** pc, | 625 uint32_t** pc, |
596 RawObject*** FP, | 626 RawObject*** FP, |
597 RawObject*** SP) { | 627 RawObject*** SP) { |
598 ASSERT(icdata->GetClassId() == kICDataCid); | 628 ASSERT(icdata->GetClassId() == kICDataCid); |
599 SimulatorHelpers::IncrementUsageCounter(icdata); | |
600 | 629 |
601 const intptr_t kCheckedArgs = 2; | 630 const intptr_t kCheckedArgs = 2; |
602 RawObject** args = call_base; | 631 RawObject** args = call_base; |
603 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 632 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
604 | 633 |
605 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 634 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
606 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | 635 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); |
607 | 636 |
608 bool found = false; | 637 bool found = false; |
609 const intptr_t length = Smi::Value(cache->length_); | 638 const intptr_t length = Smi::Value(cache->length_); |
(...skipping 10 matching lines...) Expand all Loading... |
620 if (!found) { | 649 if (!found) { |
621 InlineCacheMiss( | 650 InlineCacheMiss( |
622 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 651 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); |
623 } | 652 } |
624 | 653 |
625 *argdesc = icdata->ptr()->args_descriptor_; | 654 *argdesc = icdata->ptr()->args_descriptor_; |
626 Invoke(thread, call_base, top, pp, pc, FP, SP); | 655 Invoke(thread, call_base, top, pp, pc, FP, SP); |
627 } | 656 } |
628 | 657 |
629 | 658 |
630 DART_FORCE_INLINE void Simulator::InstanceCall3(Thread* thread, | |
631 RawICData* icdata, | |
632 RawObject** call_base, | |
633 RawObject** top, | |
634 RawArray** argdesc, | |
635 RawObjectPool** pp, | |
636 uint32_t** pc, | |
637 RawObject*** FP, | |
638 RawObject*** SP) { | |
639 ASSERT(icdata->GetClassId() == kICDataCid); | |
640 SimulatorHelpers::IncrementUsageCounter(icdata); | |
641 | |
642 const intptr_t kCheckedArgs = 3; | |
643 RawObject** args = call_base; | |
644 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | |
645 | |
646 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | |
647 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | |
648 RawSmi* arg1_cid = SimulatorHelpers::GetClassIdAsSmi(args[2]); | |
649 | |
650 bool found = false; | |
651 const intptr_t length = Smi::Value(cache->length_); | |
652 for (intptr_t i = 0; | |
653 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | |
654 if ((cache->data()[i + 0] == receiver_cid) && | |
655 (cache->data()[i + 1] == arg0_cid) && | |
656 (cache->data()[i + 2] == arg1_cid)) { | |
657 top[0] = cache->data()[i + kCheckedArgs]; | |
658 found = true; | |
659 break; | |
660 } | |
661 } | |
662 | |
663 if (!found) { | |
664 InlineCacheMiss( | |
665 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | |
666 } | |
667 | |
668 *argdesc = icdata->ptr()->args_descriptor_; | |
669 Invoke(thread, call_base, top, pp, pc, FP, SP); | |
670 } | |
671 | |
672 | |
673 // Note: functions below are marked DART_NOINLINE to recover performance on | 659 // Note: functions below are marked DART_NOINLINE to recover performance on |
674 // ARM where inlining these functions into the interpreter loop seemed to cause | 660 // ARM where inlining these functions into the interpreter loop seemed to cause |
675 // some code quality issues. | 661 // some code quality issues. |
676 static DART_NOINLINE bool InvokeRuntime( | 662 static DART_NOINLINE bool InvokeRuntime( |
677 Thread* thread, | 663 Thread* thread, |
678 Simulator* sim, | 664 Simulator* sim, |
679 RuntimeFunction drt, | 665 RuntimeFunction drt, |
680 const NativeArguments& args) { | 666 const NativeArguments& args) { |
681 SimulatorSetjmpBuffer buffer(sim); | 667 SimulatorSetjmpBuffer buffer(sim); |
682 if (!setjmp(buffer.buffer_)) { | 668 if (!setjmp(buffer.buffer_)) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 do { \ | 780 do { \ |
795 FP = reinterpret_cast<RawObject**>(fp_); \ | 781 FP = reinterpret_cast<RawObject**>(fp_); \ |
796 pc = reinterpret_cast<uint32_t*>(pc_); \ | 782 pc = reinterpret_cast<uint32_t*>(pc_); \ |
797 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ | 783 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ |
798 fp_ = sp_ = reinterpret_cast<RawObject**>(fp_[0]); \ | 784 fp_ = sp_ = reinterpret_cast<RawObject**>(fp_[0]); \ |
799 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); \ | 785 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); \ |
800 thread->set_top_resource(top_resource); \ | 786 thread->set_top_resource(top_resource); \ |
801 thread->set_vm_tag(vm_tag); \ | 787 thread->set_vm_tag(vm_tag); \ |
802 return special_[kExceptionSpecialIndex]; \ | 788 return special_[kExceptionSpecialIndex]; \ |
803 } \ | 789 } \ |
804 pp = FrameCode(FP)->ptr()->object_pool_->ptr(); \ | 790 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ |
805 goto DispatchAfterException; \ | 791 goto DispatchAfterException; \ |
806 } while (0) \ | 792 } while (0) \ |
807 | 793 |
808 // Runtime call helpers: handle invocation and potential exception after return. | 794 // Runtime call helpers: handle invocation and potential exception after return. |
809 #define INVOKE_RUNTIME(Func, Args) \ | 795 #define INVOKE_RUNTIME(Func, Args) \ |
810 if (!InvokeRuntime(thread, this, Func, Args)) { \ | 796 if (!InvokeRuntime(thread, this, Func, Args)) { \ |
811 HANDLE_EXCEPTION; \ | 797 HANDLE_EXCEPTION; \ |
812 } \ | 798 } \ |
813 | 799 |
814 #define INVOKE_NATIVE(Func, Args) \ | 800 #define INVOKE_NATIVE(Func, Args) \ |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 L[i] = null_value; | 929 L[i] = null_value; |
944 } | 930 } |
945 L[context_reg] = empty_context; | 931 L[context_reg] = empty_context; |
946 SP = FP + num_locals - 1; | 932 SP = FP + num_locals - 1; |
947 } | 933 } |
948 | 934 |
949 DISPATCH(); | 935 DISPATCH(); |
950 } | 936 } |
951 | 937 |
952 { | 938 { |
953 BYTECODE(EntryOpt, A_B_C); | 939 BYTECODE(EntryOptimized, A_D); |
| 940 const uint8_t num_fixed_params = rA; |
| 941 const uint16_t num_registers = rD; |
| 942 |
| 943 // Decode arguments descriptor. |
| 944 const intptr_t pos_count = Smi::Value(*reinterpret_cast<RawSmi**>( |
| 945 reinterpret_cast<uword>(argdesc->ptr()) + |
| 946 Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex))); |
| 947 |
| 948 // Check that we got the right number of positional parameters. |
| 949 if (pos_count != num_fixed_params) { |
| 950 // Mismatch can only occur if current function is a closure. |
| 951 goto ClosureNoSuchMethod; |
| 952 } |
| 953 |
| 954 // Reserve space for registers used by the optimized code. |
| 955 SP = FP + num_registers - 1; |
| 956 |
| 957 DISPATCH(); |
| 958 } |
| 959 |
| 960 { |
| 961 BYTECODE(EntryOptional, A_B_C); |
954 const uint16_t num_fixed_params = rA; | 962 const uint16_t num_fixed_params = rA; |
955 const uint16_t num_opt_pos_params = rB; | 963 const uint16_t num_opt_pos_params = rB; |
956 const uint16_t num_opt_named_params = rC; | 964 const uint16_t num_opt_named_params = rC; |
957 const intptr_t min_num_pos_args = num_fixed_params; | 965 const intptr_t min_num_pos_args = num_fixed_params; |
958 const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params; | 966 const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params; |
959 | 967 |
960 // Decode arguments descriptor. | 968 // Decode arguments descriptor. |
961 const intptr_t arg_count = Smi::Value(*reinterpret_cast<RawSmi**>( | 969 const intptr_t arg_count = Smi::Value(*reinterpret_cast<RawSmi**>( |
962 reinterpret_cast<uword>(argdesc->ptr()) + | 970 reinterpret_cast<uword>(argdesc->ptr()) + |
963 Array::element_offset(ArgumentsDescriptor::kCountIndex))); | 971 Array::element_offset(ArgumentsDescriptor::kCountIndex))); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 { | 1099 { |
1092 BYTECODE(Compile, 0); | 1100 BYTECODE(Compile, 0); |
1093 FP[0] = FrameFunction(FP); | 1101 FP[0] = FrameFunction(FP); |
1094 FP[1] = 0; | 1102 FP[1] = 0; |
1095 Exit(thread, FP, FP + 2, pc); | 1103 Exit(thread, FP, FP + 2, pc); |
1096 NativeArguments args(thread, 1, FP, FP + 1); | 1104 NativeArguments args(thread, 1, FP, FP + 1); |
1097 INVOKE_RUNTIME(DRT_CompileFunction, args); | 1105 INVOKE_RUNTIME(DRT_CompileFunction, args); |
1098 { | 1106 { |
1099 // Function should be compiled now, dispatch to its entry point. | 1107 // Function should be compiled now, dispatch to its entry point. |
1100 RawCode* code = FrameFunction(FP)->ptr()->code_; | 1108 RawCode* code = FrameFunction(FP)->ptr()->code_; |
1101 SetFrameCode(FP, code); | 1109 SimulatorHelpers::SetFrameCode(FP, code); |
1102 pp = code->ptr()->object_pool_->ptr(); | 1110 pp = code->ptr()->object_pool_->ptr(); |
1103 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); | 1111 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
1104 } | 1112 } |
1105 DISPATCH(); | 1113 DISPATCH(); |
1106 } | 1114 } |
1107 | 1115 |
1108 { | 1116 { |
| 1117 BYTECODE(HotCheck, A_D); |
| 1118 const uint8_t increment = rA; |
| 1119 const uint16_t threshold = rD; |
| 1120 RawFunction* f = FrameFunction(FP); |
| 1121 int32_t counter = f->ptr()->usage_counter_; |
| 1122 // Note: we don't increment usage counter in the prologue of optimized |
| 1123 // functions. |
| 1124 if (increment) { |
| 1125 counter += increment; |
| 1126 f->ptr()->usage_counter_ = counter; |
| 1127 } |
| 1128 if (counter >= threshold) { |
| 1129 FP[0] = f; |
| 1130 FP[1] = 0; |
| 1131 Exit(thread, FP, FP + 2, pc); |
| 1132 NativeArguments args(thread, 1, FP, FP + 1); |
| 1133 INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args); |
| 1134 { |
| 1135 // DRT_OptimizeInvokedFunction returns the code object to execute. |
| 1136 ASSERT(FP[1]->GetClassId() == kCodeCid); |
| 1137 RawCode* code = static_cast<RawCode*>(FP[1]); |
| 1138 SimulatorHelpers::SetFrameCode(FP, code); |
| 1139 pp = code->ptr()->object_pool_->ptr(); |
| 1140 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
| 1141 } |
| 1142 } |
| 1143 DISPATCH(); |
| 1144 } |
| 1145 |
| 1146 { |
1109 BYTECODE(CheckStack, A); | 1147 BYTECODE(CheckStack, A); |
1110 { | 1148 { |
1111 if (reinterpret_cast<uword>(SP) >= thread->stack_limit()) { | 1149 if (reinterpret_cast<uword>(SP) >= thread->stack_limit()) { |
1112 Exit(thread, FP, SP + 1, pc); | 1150 Exit(thread, FP, SP + 1, pc); |
1113 NativeArguments args(thread, 0, NULL, NULL); | 1151 NativeArguments args(thread, 0, NULL, NULL); |
1114 INVOKE_RUNTIME(DRT_StackOverflow, args); | 1152 INVOKE_RUNTIME(DRT_StackOverflow, args); |
1115 } | 1153 } |
1116 } | 1154 } |
1117 DISPATCH(); | 1155 DISPATCH(); |
1118 } | 1156 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 DISPATCH(); | 1290 DISPATCH(); |
1253 } | 1291 } |
1254 | 1292 |
1255 { | 1293 { |
1256 BYTECODE(Move, A_X); | 1294 BYTECODE(Move, A_X); |
1257 FP[rA] = FP[rD]; | 1295 FP[rA] = FP[rD]; |
1258 DISPATCH(); | 1296 DISPATCH(); |
1259 } | 1297 } |
1260 | 1298 |
1261 { | 1299 { |
| 1300 BYTECODE(Swap, A_X); |
| 1301 RawObject* tmp = FP[rD]; |
| 1302 FP[rD] = FP[rA]; |
| 1303 FP[rA] = tmp; |
| 1304 DISPATCH(); |
| 1305 } |
| 1306 |
| 1307 { |
1262 BYTECODE(StoreLocal, A_X); | 1308 BYTECODE(StoreLocal, A_X); |
1263 FP[rD] = *SP; | 1309 FP[rD] = *SP; |
1264 DISPATCH(); | 1310 DISPATCH(); |
1265 } | 1311 } |
1266 | 1312 |
1267 { | 1313 { |
1268 BYTECODE(PopLocal, A_X); | 1314 BYTECODE(PopLocal, A_X); |
1269 FP[rD] = *SP--; | 1315 FP[rD] = *SP--; |
1270 DISPATCH(); | 1316 DISPATCH(); |
1271 } | 1317 } |
1272 | 1318 |
1273 { | 1319 { |
1274 BYTECODE(MoveSpecial, A_D); | 1320 BYTECODE(MoveSpecial, A_D); |
1275 FP[rA] = special_[rD]; | 1321 FP[rA] = special_[rD]; |
1276 DISPATCH(); | 1322 DISPATCH(); |
1277 } | 1323 } |
1278 | 1324 |
1279 { | 1325 { |
1280 BYTECODE(BooleanNegateTOS, 0); | 1326 BYTECODE(BooleanNegateTOS, 0); |
1281 SP[0] = (SP[0] == true_value) ? false_value : true_value; | 1327 SP[0] = (SP[0] == true_value) ? false_value : true_value; |
1282 DISPATCH(); | 1328 DISPATCH(); |
1283 } | 1329 } |
1284 | 1330 |
1285 { | 1331 { |
| 1332 BYTECODE(BooleanNegate, A_D); |
| 1333 FP[rA] = (FP[rD] == true_value) ? false_value : true_value; |
| 1334 DISPATCH(); |
| 1335 } |
| 1336 |
| 1337 { |
1286 BYTECODE(StaticCall, A_D); | 1338 BYTECODE(StaticCall, A_D); |
1287 | 1339 |
1288 // Check if single stepping. | 1340 // Check if single stepping. |
1289 if (thread->isolate()->single_step()) { | 1341 if (thread->isolate()->single_step()) { |
1290 Exit(thread, FP, SP + 1, pc); | 1342 Exit(thread, FP, SP + 1, pc); |
1291 NativeArguments args(thread, 0, NULL, NULL); | 1343 NativeArguments args(thread, 0, NULL, NULL); |
1292 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1344 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1293 } | 1345 } |
1294 | 1346 |
1295 // Invoke target function. | 1347 // Invoke target function. |
1296 { | 1348 { |
1297 const uint16_t argc = rA; | 1349 const uint16_t argc = rA; |
1298 RawObject** call_base = SP - argc; | 1350 RawObject** call_base = SP - argc; |
1299 RawObject** call_top = SP; // *SP contains function | 1351 RawObject** call_top = SP; // *SP contains function |
1300 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); | 1352 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); |
1301 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); | 1353 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); |
1302 } | 1354 } |
1303 | 1355 |
1304 DISPATCH(); | 1356 DISPATCH(); |
1305 } | 1357 } |
1306 | 1358 |
1307 { | 1359 { |
1308 BYTECODE(InstanceCall, A_D); | 1360 BYTECODE(InstanceCall1, A_D); |
1309 | 1361 |
1310 // Check if single stepping. | 1362 // Check if single stepping. |
1311 if (thread->isolate()->single_step()) { | 1363 if (thread->isolate()->single_step()) { |
1312 Exit(thread, FP, SP + 1, pc); | 1364 Exit(thread, FP, SP + 1, pc); |
1313 NativeArguments args(thread, 0, NULL, NULL); | 1365 NativeArguments args(thread, 0, NULL, NULL); |
1314 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1366 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1315 } | 1367 } |
1316 | 1368 |
1317 { | 1369 { |
1318 const uint16_t argc = rA; | 1370 const uint16_t argc = rA; |
1319 const uint16_t kidx = rD; | 1371 const uint16_t kidx = rD; |
1320 | 1372 |
1321 RawObject** call_base = SP - argc + 1; | 1373 RawObject** call_base = SP - argc + 1; |
1322 RawObject** call_top = SP + 1; | 1374 RawObject** call_top = SP + 1; |
1323 InstanceCall1(thread, | 1375 |
1324 static_cast<RawICData*>(LOAD_CONSTANT(kidx)), | 1376 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1325 call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1377 SimulatorHelpers::IncrementUsageCounter( |
| 1378 RAW_CAST(Function, icdata->ptr()->owner_)); |
| 1379 InstanceCall1( |
| 1380 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); |
1326 } | 1381 } |
1327 | 1382 |
1328 DISPATCH(); | 1383 DISPATCH(); |
1329 } | 1384 } |
1330 | 1385 |
1331 { | 1386 { |
1332 BYTECODE(InstanceCall2, A_D); | 1387 BYTECODE(InstanceCall2, A_D); |
1333 if (thread->isolate()->single_step()) { | 1388 if (thread->isolate()->single_step()) { |
1334 Exit(thread, FP, SP + 1, pc); | 1389 Exit(thread, FP, SP + 1, pc); |
1335 NativeArguments args(thread, 0, NULL, NULL); | 1390 NativeArguments args(thread, 0, NULL, NULL); |
1336 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1391 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1337 } | 1392 } |
1338 | 1393 |
1339 { | 1394 { |
1340 const uint16_t argc = rA; | 1395 const uint16_t argc = rA; |
1341 const uint16_t kidx = rD; | 1396 const uint16_t kidx = rD; |
1342 | 1397 |
1343 RawObject** call_base = SP - argc + 1; | 1398 RawObject** call_base = SP - argc + 1; |
1344 RawObject** call_top = SP + 1; | 1399 RawObject** call_top = SP + 1; |
1345 InstanceCall2(thread, | 1400 |
1346 static_cast<RawICData*>(LOAD_CONSTANT(kidx)), | 1401 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1347 call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1402 SimulatorHelpers::IncrementUsageCounter( |
| 1403 RAW_CAST(Function, icdata->ptr()->owner_)); |
| 1404 InstanceCall2( |
| 1405 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); |
1348 } | 1406 } |
1349 | 1407 |
1350 DISPATCH(); | 1408 DISPATCH(); |
1351 } | 1409 } |
1352 | 1410 |
1353 { | 1411 { |
1354 BYTECODE(InstanceCall3, A_D); | 1412 BYTECODE(InstanceCall1Opt, A_D); |
1355 if (thread->isolate()->single_step()) { | |
1356 Exit(thread, FP, SP + 1, pc); | |
1357 NativeArguments args(thread, 0, NULL, NULL); | |
1358 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | |
1359 } | |
1360 | 1413 |
1361 { | 1414 { |
1362 const uint16_t argc = rA; | 1415 const uint16_t argc = rA; |
1363 const uint16_t kidx = rD; | 1416 const uint16_t kidx = rD; |
1364 | 1417 |
1365 RawObject** call_base = SP - argc + 1; | 1418 RawObject** call_base = SP - argc + 1; |
1366 RawObject** call_top = SP + 1; | 1419 RawObject** call_top = SP + 1; |
1367 InstanceCall3(thread, | 1420 |
1368 static_cast<RawICData*>(LOAD_CONSTANT(kidx)), | 1421 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1369 call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1422 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
| 1423 InstanceCall1( |
| 1424 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); |
1370 } | 1425 } |
1371 | 1426 |
1372 DISPATCH(); | 1427 DISPATCH(); |
| 1428 } |
| 1429 |
| 1430 { |
| 1431 BYTECODE(InstanceCall2Opt, A_D); |
| 1432 |
| 1433 { |
| 1434 const uint16_t argc = rA; |
| 1435 const uint16_t kidx = rD; |
| 1436 |
| 1437 RawObject** call_base = SP - argc + 1; |
| 1438 RawObject** call_top = SP + 1; |
| 1439 |
| 1440 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
| 1441 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
| 1442 InstanceCall2( |
| 1443 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); |
| 1444 } |
| 1445 |
| 1446 DISPATCH(); |
1373 } | 1447 } |
1374 | 1448 |
1375 { | 1449 { |
1376 BYTECODE(NativeBootstrapCall, 0); | 1450 BYTECODE(NativeBootstrapCall, 0); |
1377 RawFunction* function = FrameFunction(FP); | 1451 RawFunction* function = FrameFunction(FP); |
1378 RawObject** incoming_args = | 1452 RawObject** incoming_args = |
1379 (function->ptr()->num_optional_parameters_ == 0) | 1453 (function->ptr()->num_optional_parameters_ == 0) |
1380 ? FrameArguments(FP, function->ptr()->num_fixed_parameters_) | 1454 ? FrameArguments(FP, function->ptr()->num_fixed_parameters_) |
1381 : FP; | 1455 : FP; |
1382 | 1456 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 thread->set_vm_tag(vm_tag); | 1562 thread->set_vm_tag(vm_tag); |
1489 return result; | 1563 return result; |
1490 } | 1564 } |
1491 | 1565 |
1492 // Look at the caller to determine how many arguments to pop. | 1566 // Look at the caller to determine how many arguments to pop. |
1493 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); | 1567 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); |
1494 | 1568 |
1495 // Restore SP, FP and PP. Push result and dispatch. | 1569 // Restore SP, FP and PP. Push result and dispatch. |
1496 SP = FrameArguments(FP, argc); | 1570 SP = FrameArguments(FP, argc); |
1497 FP = SavedCallerFP(FP); | 1571 FP = SavedCallerFP(FP); |
1498 pp = FrameCode(FP)->ptr()->object_pool_->ptr(); | 1572 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
1499 *SP = result; | 1573 *SP = result; |
1500 DISPATCH(); | 1574 DISPATCH(); |
1501 } | 1575 } |
1502 | 1576 |
1503 { | 1577 { |
1504 BYTECODE(StoreStaticTOS, A_D); | 1578 BYTECODE(StoreStaticTOS, A_D); |
1505 RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD)); | 1579 RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD)); |
1506 RawInstance* value = static_cast<RawInstance*>(*SP--); | 1580 RawInstance* value = static_cast<RawInstance*>(*SP--); |
1507 field->StorePointer(&field->ptr()->value_.static_value_, value); | 1581 field->StorePointer(&field->ptr()->value_.static_value_, value); |
1508 DISPATCH(); | 1582 DISPATCH(); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 Exit(thread, FP, SP + 2, pc); | 1807 Exit(thread, FP, SP + 2, pc); |
1734 NativeArguments args(thread, 1, SP + 1, SP); | 1808 NativeArguments args(thread, 1, SP + 1, SP); |
1735 INVOKE_RUNTIME(DRT_NonBoolTypeError, args); | 1809 INVOKE_RUNTIME(DRT_NonBoolTypeError, args); |
1736 } | 1810 } |
1737 | 1811 |
1738 AssertBooleanOk: | 1812 AssertBooleanOk: |
1739 DISPATCH(); | 1813 DISPATCH(); |
1740 } | 1814 } |
1741 | 1815 |
1742 { | 1816 { |
1743 BYTECODE(IfEqStrictTOS, A_D); | 1817 BYTECODE(IfEqStrictTOS, 0); |
1744 SP -= 2; | 1818 SP -= 2; |
1745 if (SP[1] != SP[2]) { | 1819 if (SP[1] != SP[2]) { |
1746 pc++; | 1820 pc++; |
1747 } | 1821 } |
1748 DISPATCH(); | 1822 DISPATCH(); |
1749 } | 1823 } |
1750 | 1824 |
1751 { | 1825 { |
1752 BYTECODE(IfNeStrictTOS, A_D); | 1826 BYTECODE(IfNeStrictTOS, 0); |
1753 SP -= 2; | 1827 SP -= 2; |
1754 if (SP[1] == SP[2]) { | 1828 if (SP[1] == SP[2]) { |
1755 pc++; | 1829 pc++; |
1756 } | 1830 } |
1757 DISPATCH(); | 1831 DISPATCH(); |
1758 } | 1832 } |
1759 | 1833 |
1760 { | 1834 { |
1761 BYTECODE(IfEqStrictNumTOS, A_D); | 1835 BYTECODE(IfEqStrictNumTOS, 0); |
1762 if (thread->isolate()->single_step()) { | 1836 if (thread->isolate()->single_step()) { |
1763 Exit(thread, FP, SP + 1, pc); | 1837 Exit(thread, FP, SP + 1, pc); |
1764 NativeArguments args(thread, 0, NULL, NULL); | 1838 NativeArguments args(thread, 0, NULL, NULL); |
1765 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1839 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1766 } | 1840 } |
1767 | 1841 |
1768 SP -= 2; | 1842 SP -= 2; |
1769 if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { | 1843 if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { |
1770 pc++; | 1844 pc++; |
1771 } | 1845 } |
1772 DISPATCH(); | 1846 DISPATCH(); |
1773 } | 1847 } |
1774 | 1848 |
1775 { | 1849 { |
1776 BYTECODE(IfNeStrictNumTOS, A_D); | 1850 BYTECODE(IfNeStrictNumTOS, 0); |
1777 if (thread->isolate()->single_step()) { | 1851 if (thread->isolate()->single_step()) { |
1778 Exit(thread, FP, SP + 1, pc); | 1852 Exit(thread, FP, SP + 1, pc); |
1779 NativeArguments args(thread, 0, NULL, NULL); | 1853 NativeArguments args(thread, 0, NULL, NULL); |
1780 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1854 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1781 } | 1855 } |
1782 | 1856 |
1783 SP -= 2; | 1857 SP -= 2; |
1784 if (SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { | 1858 if (SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { |
1785 pc++; | 1859 pc++; |
1786 } | 1860 } |
1787 DISPATCH(); | 1861 DISPATCH(); |
1788 } | 1862 } |
1789 | 1863 |
1790 { | 1864 { |
| 1865 BYTECODE(IfEqStrict, A_D); |
| 1866 RawObject* lhs = FP[rA]; |
| 1867 RawObject* rhs = FP[rD]; |
| 1868 if (lhs != rhs) { |
| 1869 pc++; |
| 1870 } |
| 1871 DISPATCH(); |
| 1872 } |
| 1873 |
| 1874 { |
| 1875 BYTECODE(IfNeStrict, A_D); |
| 1876 RawObject* lhs = FP[rA]; |
| 1877 RawObject* rhs = FP[rD]; |
| 1878 if (lhs == rhs) { |
| 1879 pc++; |
| 1880 } |
| 1881 DISPATCH(); |
| 1882 } |
| 1883 |
| 1884 { |
| 1885 BYTECODE(IfEqStrictNum, A_D); |
| 1886 RawObject* lhs = FP[rA]; |
| 1887 RawObject* rhs = FP[rD]; |
| 1888 if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) { |
| 1889 pc++; |
| 1890 } |
| 1891 DISPATCH(); |
| 1892 } |
| 1893 |
| 1894 { |
| 1895 BYTECODE(IfNeStrictNum, A_D); |
| 1896 RawObject* lhs = FP[rA]; |
| 1897 RawObject* rhs = FP[rD]; |
| 1898 if (SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) { |
| 1899 pc++; |
| 1900 } |
| 1901 DISPATCH(); |
| 1902 } |
| 1903 |
| 1904 { |
1791 BYTECODE(Jump, 0); | 1905 BYTECODE(Jump, 0); |
1792 const int32_t target = static_cast<int32_t>(op) >> 8; | 1906 const int32_t target = static_cast<int32_t>(op) >> 8; |
1793 pc += (target - 1); | 1907 pc += (target - 1); |
1794 DISPATCH(); | 1908 DISPATCH(); |
1795 } | 1909 } |
1796 | 1910 |
1797 { | 1911 { |
1798 BYTECODE(LoadClassId, A_D); | 1912 BYTECODE(LoadClassId, A_D); |
1799 const uint16_t object_reg = rD; | 1913 const uint16_t object_reg = rD; |
1800 RawObject* obj = static_cast<RawObject*>(FP[object_reg]); | 1914 RawObject* obj = static_cast<RawObject*>(FP[object_reg]); |
1801 FP[rA] = SimulatorHelpers::GetClassIdAsSmi(obj); | 1915 FP[rA] = SimulatorHelpers::GetClassIdAsSmi(obj); |
1802 DISPATCH(); | 1916 DISPATCH(); |
1803 } | 1917 } |
1804 | 1918 |
1805 { | 1919 { |
1806 BYTECODE(LoadClassIdTOS, 0); | 1920 BYTECODE(LoadClassIdTOS, 0); |
1807 RawObject* obj = static_cast<RawObject*>(SP[0]); | 1921 RawObject* obj = static_cast<RawObject*>(SP[0]); |
1808 SP[0] = SimulatorHelpers::GetClassIdAsSmi(obj); | 1922 SP[0] = SimulatorHelpers::GetClassIdAsSmi(obj); |
1809 DISPATCH(); | 1923 DISPATCH(); |
1810 } | 1924 } |
1811 | 1925 |
1812 { | 1926 { |
1813 BYTECODE(StoreIndexedTOS, 0); | 1927 BYTECODE(StoreIndexedTOS, 0); |
1814 SP -= 3; | 1928 SP -= 3; |
1815 RawArray* array = static_cast<RawArray*>(SP[1]); | 1929 RawArray* array = static_cast<RawArray*>(SP[1]); |
1816 RawSmi* index = static_cast<RawSmi*>(SP[2]); | 1930 RawSmi* index = static_cast<RawSmi*>(SP[2]); |
1817 RawObject* value = SP[3]; | 1931 RawObject* value = SP[3]; |
1818 ASSERT(array->GetClassId() == kArrayCid); | 1932 ASSERT(array->GetClassId() == kArrayCid); |
1819 ASSERT(!index->IsHeapObject()); | 1933 ASSERT(!index->IsHeapObject()); |
| 1934 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); |
1820 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); | 1935 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); |
1821 DISPATCH(); | 1936 DISPATCH(); |
1822 } | 1937 } |
1823 | 1938 |
1824 { | 1939 { |
| 1940 BYTECODE(StoreIndexed, A_B_C); |
| 1941 RawArray* array = static_cast<RawArray*>(FP[rA]); |
| 1942 RawSmi* index = static_cast<RawSmi*>(FP[rB]); |
| 1943 RawObject* value = FP[rC]; |
| 1944 ASSERT(array->GetClassId() == kArrayCid); |
| 1945 ASSERT(!index->IsHeapObject()); |
| 1946 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); |
| 1947 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); |
| 1948 DISPATCH(); |
| 1949 } |
| 1950 |
| 1951 { |
| 1952 BYTECODE(Deopt, A_D); |
| 1953 const uint16_t deopt_id = rD; |
| 1954 if (deopt_id == 0) { // Lazy deoptimization. |
| 1955 // Preserve result of the previous call. |
| 1956 // TODO(vegorov) we could have actually included result into the |
| 1957 // deoptimization environment because it is passed through the stack. |
| 1958 // If we do then we could remove special result handling from this code. |
| 1959 RawObject* result = SP[0]; |
| 1960 |
| 1961 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. |
| 1962 // The code in this frame may not cause GC. |
| 1963 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. |
| 1964 EnterSyntheticFrame(&FP, &SP, pc - 1); |
| 1965 const intptr_t frame_size_in_bytes = |
| 1966 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), |
| 1967 /*is_lazy_deopt=*/1); |
| 1968 LeaveSyntheticFrame(&FP, &SP); |
| 1969 |
| 1970 SP = FP + (frame_size_in_bytes / kWordSize); |
| 1971 EnterSyntheticFrame(&FP, &SP, pc - 1); |
| 1972 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP)); |
| 1973 |
| 1974 // We are now inside a valid frame. |
| 1975 { |
| 1976 *++SP = result; // Preserve result (call below can cause GC). |
| 1977 *++SP = 0; // Space for the result: number of materialization args. |
| 1978 Exit(thread, FP, SP + 1, /*pc=*/0); |
| 1979 NativeArguments native_args(thread, 0, SP, SP); |
| 1980 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args); |
| 1981 } |
| 1982 const intptr_t materialization_arg_count = |
| 1983 Smi::Value(RAW_CAST(Smi, *SP--)); |
| 1984 result = *SP--; // Reload the result. It might have been relocated by GC. |
| 1985 |
| 1986 // Restore caller PC. |
| 1987 pc = SavedCallerPC(FP); |
| 1988 |
| 1989 // Check if it is a fake PC marking the entry frame. |
| 1990 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); |
| 1991 |
| 1992 // Restore SP, FP and PP. Push result and dispatch. |
| 1993 // Note: unlike in a normal return sequence we don't need to drop |
| 1994 // arguments - those are not part of the innermost deoptimization |
| 1995 // environment they were dropped by FlowGraphCompiler::RecordAfterCall. |
| 1996 SP = FrameArguments(FP, materialization_arg_count); |
| 1997 FP = SavedCallerFP(FP); |
| 1998 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
| 1999 *SP = result; |
| 2000 } else { |
| 2001 UNIMPLEMENTED(); |
| 2002 } |
| 2003 DISPATCH(); |
| 2004 } |
| 2005 |
| 2006 { |
1825 BYTECODE(Trap, 0); | 2007 BYTECODE(Trap, 0); |
1826 UNIMPLEMENTED(); | 2008 UNIMPLEMENTED(); |
1827 DISPATCH(); | 2009 DISPATCH(); |
1828 } | 2010 } |
1829 | 2011 |
1830 // Helper used to handle noSuchMethod on closures. | 2012 // Helper used to handle noSuchMethod on closures. |
1831 { | 2013 { |
1832 ClosureNoSuchMethod: | 2014 ClosureNoSuchMethod: |
1833 #if defined(DEBUG) | 2015 #if defined(DEBUG) |
1834 function_h ^= FrameFunction(FP); | 2016 function_h ^= FrameFunction(FP); |
1835 ASSERT(function_h.IsClosureFunction()); | 2017 ASSERT(function_h.IsClosureFunction()); |
1836 #endif | 2018 #endif |
1837 | 2019 |
1838 // Restore caller context as we are going to throw NoSuchMethod. | 2020 // Restore caller context as we are going to throw NoSuchMethod. |
1839 pc = SavedCallerPC(FP); | 2021 pc = SavedCallerPC(FP); |
1840 | 2022 |
1841 const bool has_dart_caller = (reinterpret_cast<uword>(pc) & 2) == 0; | 2023 const bool has_dart_caller = (reinterpret_cast<uword>(pc) & 2) == 0; |
1842 const intptr_t argc = has_dart_caller | 2024 const intptr_t argc = has_dart_caller |
1843 ? Bytecode::DecodeArgc(pc[-1]) | 2025 ? Bytecode::DecodeArgc(pc[-1]) |
1844 : (reinterpret_cast<uword>(pc) >> 2); | 2026 : (reinterpret_cast<uword>(pc) >> 2); |
1845 | 2027 |
1846 SP = FrameArguments(FP, 0); | 2028 SP = FrameArguments(FP, 0); |
1847 RawObject** args = SP - argc; | 2029 RawObject** args = SP - argc; |
1848 FP = SavedCallerFP(FP); | 2030 FP = SavedCallerFP(FP); |
1849 if (has_dart_caller) { | 2031 if (has_dart_caller) { |
1850 pp = FrameCode(FP)->ptr()->object_pool_->ptr(); | 2032 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
1851 } | 2033 } |
1852 | 2034 |
1853 *++SP = null_value; | 2035 *++SP = null_value; |
1854 *++SP = args[0]; // Closure object. | 2036 *++SP = args[0]; // Closure object. |
1855 *++SP = argdesc; | 2037 *++SP = argdesc; |
1856 *++SP = null_value; // Array of arguments (will be filled). | 2038 *++SP = null_value; // Array of arguments (will be filled). |
1857 | 2039 |
1858 // Allocate array of arguments. | 2040 // Allocate array of arguments. |
1859 { | 2041 { |
1860 SP[1] = Smi::New(argc); // length | 2042 SP[1] = Smi::New(argc); // length |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1925 special_[kExceptionSpecialIndex] = raw_exception; | 2107 special_[kExceptionSpecialIndex] = raw_exception; |
1926 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 2108 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
1927 buf->Longjmp(); | 2109 buf->Longjmp(); |
1928 UNREACHABLE(); | 2110 UNREACHABLE(); |
1929 } | 2111 } |
1930 | 2112 |
1931 } // namespace dart | 2113 } // namespace dart |
1932 | 2114 |
1933 | 2115 |
1934 #endif // defined TARGET_ARCH_DBC | 2116 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |