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 MAP_CLASS_ID | |
zra
2016/05/19 16:24:28
#undef DEFINE_CASTS ?
Vyacheslav Egorov (Google)
2016/05/20 12:11:47
Done.
| |
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); |
1413 | |
1414 // Check if single stepping. | |
Florian Schneider
2016/05/19 13:21:40
Optimized code can't be single stepped.
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
1355 if (thread->isolate()->single_step()) { | 1415 if (thread->isolate()->single_step()) { |
1356 Exit(thread, FP, SP + 1, pc); | 1416 Exit(thread, FP, SP + 1, pc); |
1357 NativeArguments args(thread, 0, NULL, NULL); | 1417 NativeArguments args(thread, 0, NULL, NULL); |
1358 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1418 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1359 } | 1419 } |
1360 | 1420 |
1361 { | 1421 { |
1362 const uint16_t argc = rA; | 1422 const uint16_t argc = rA; |
1363 const uint16_t kidx = rD; | 1423 const uint16_t kidx = rD; |
1364 | 1424 |
1365 RawObject** call_base = SP - argc + 1; | 1425 RawObject** call_base = SP - argc + 1; |
1366 RawObject** call_top = SP + 1; | 1426 RawObject** call_top = SP + 1; |
1367 InstanceCall3(thread, | 1427 |
1368 static_cast<RawICData*>(LOAD_CONSTANT(kidx)), | 1428 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1369 call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | 1429 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1430 InstanceCall1( | |
1431 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | |
1370 } | 1432 } |
1371 | 1433 |
1372 DISPATCH(); | 1434 DISPATCH(); |
1435 } | |
1436 | |
1437 { | |
1438 BYTECODE(InstanceCall2Opt, A_D); | |
1439 if (thread->isolate()->single_step()) { | |
Florian Schneider
2016/05/19 13:21:40
Optimized code can't be single-stepped.
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
1440 Exit(thread, FP, SP + 1, pc); | |
1441 NativeArguments args(thread, 0, NULL, NULL); | |
1442 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | |
1443 } | |
1444 | |
1445 { | |
1446 const uint16_t argc = rA; | |
1447 const uint16_t kidx = rD; | |
1448 | |
1449 RawObject** call_base = SP - argc + 1; | |
1450 RawObject** call_top = SP + 1; | |
1451 | |
1452 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | |
1453 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | |
1454 InstanceCall2( | |
1455 thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP); | |
1456 } | |
1457 | |
1458 DISPATCH(); | |
1373 } | 1459 } |
1374 | 1460 |
1375 { | 1461 { |
1376 BYTECODE(NativeBootstrapCall, 0); | 1462 BYTECODE(NativeBootstrapCall, 0); |
1377 RawFunction* function = FrameFunction(FP); | 1463 RawFunction* function = FrameFunction(FP); |
1378 RawObject** incoming_args = | 1464 RawObject** incoming_args = |
1379 (function->ptr()->num_optional_parameters_ == 0) | 1465 (function->ptr()->num_optional_parameters_ == 0) |
1380 ? FrameArguments(FP, function->ptr()->num_fixed_parameters_) | 1466 ? FrameArguments(FP, function->ptr()->num_fixed_parameters_) |
1381 : FP; | 1467 : FP; |
1382 | 1468 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 thread->set_vm_tag(vm_tag); | 1574 thread->set_vm_tag(vm_tag); |
1489 return result; | 1575 return result; |
1490 } | 1576 } |
1491 | 1577 |
1492 // Look at the caller to determine how many arguments to pop. | 1578 // Look at the caller to determine how many arguments to pop. |
1493 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); | 1579 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); |
1494 | 1580 |
1495 // Restore SP, FP and PP. Push result and dispatch. | 1581 // Restore SP, FP and PP. Push result and dispatch. |
1496 SP = FrameArguments(FP, argc); | 1582 SP = FrameArguments(FP, argc); |
1497 FP = SavedCallerFP(FP); | 1583 FP = SavedCallerFP(FP); |
1498 pp = FrameCode(FP)->ptr()->object_pool_->ptr(); | 1584 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
1499 *SP = result; | 1585 *SP = result; |
1500 DISPATCH(); | 1586 DISPATCH(); |
1501 } | 1587 } |
1502 | 1588 |
1503 { | 1589 { |
1504 BYTECODE(StoreStaticTOS, A_D); | 1590 BYTECODE(StoreStaticTOS, A_D); |
1505 RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD)); | 1591 RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD)); |
1506 RawInstance* value = static_cast<RawInstance*>(*SP--); | 1592 RawInstance* value = static_cast<RawInstance*>(*SP--); |
1507 field->StorePointer(&field->ptr()->value_.static_value_, value); | 1593 field->StorePointer(&field->ptr()->value_.static_value_, value); |
1508 DISPATCH(); | 1594 DISPATCH(); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1733 Exit(thread, FP, SP + 2, pc); | 1819 Exit(thread, FP, SP + 2, pc); |
1734 NativeArguments args(thread, 1, SP + 1, SP); | 1820 NativeArguments args(thread, 1, SP + 1, SP); |
1735 INVOKE_RUNTIME(DRT_NonBoolTypeError, args); | 1821 INVOKE_RUNTIME(DRT_NonBoolTypeError, args); |
1736 } | 1822 } |
1737 | 1823 |
1738 AssertBooleanOk: | 1824 AssertBooleanOk: |
1739 DISPATCH(); | 1825 DISPATCH(); |
1740 } | 1826 } |
1741 | 1827 |
1742 { | 1828 { |
1743 BYTECODE(IfEqStrictTOS, A_D); | 1829 BYTECODE(IfEqStrictTOS, 0); |
1744 SP -= 2; | 1830 SP -= 2; |
1745 if (SP[1] != SP[2]) { | 1831 if (SP[1] != SP[2]) { |
1746 pc++; | 1832 pc++; |
1747 } | 1833 } |
1748 DISPATCH(); | 1834 DISPATCH(); |
1749 } | 1835 } |
1750 | 1836 |
1751 { | 1837 { |
1752 BYTECODE(IfNeStrictTOS, A_D); | 1838 BYTECODE(IfNeStrictTOS, 0); |
1753 SP -= 2; | 1839 SP -= 2; |
1754 if (SP[1] == SP[2]) { | 1840 if (SP[1] == SP[2]) { |
1755 pc++; | 1841 pc++; |
1756 } | 1842 } |
1757 DISPATCH(); | 1843 DISPATCH(); |
1758 } | 1844 } |
1759 | 1845 |
1760 { | 1846 { |
1761 BYTECODE(IfEqStrictNumTOS, A_D); | 1847 BYTECODE(IfEqStrictNumTOS, 0); |
1762 if (thread->isolate()->single_step()) { | 1848 if (thread->isolate()->single_step()) { |
1763 Exit(thread, FP, SP + 1, pc); | 1849 Exit(thread, FP, SP + 1, pc); |
1764 NativeArguments args(thread, 0, NULL, NULL); | 1850 NativeArguments args(thread, 0, NULL, NULL); |
1765 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1851 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1766 } | 1852 } |
1767 | 1853 |
1768 SP -= 2; | 1854 SP -= 2; |
1769 if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { | 1855 if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { |
1770 pc++; | 1856 pc++; |
1771 } | 1857 } |
1772 DISPATCH(); | 1858 DISPATCH(); |
1773 } | 1859 } |
1774 | 1860 |
1775 { | 1861 { |
1776 BYTECODE(IfNeStrictNumTOS, A_D); | 1862 BYTECODE(IfNeStrictNumTOS, 0); |
1777 if (thread->isolate()->single_step()) { | 1863 if (thread->isolate()->single_step()) { |
1778 Exit(thread, FP, SP + 1, pc); | 1864 Exit(thread, FP, SP + 1, pc); |
1779 NativeArguments args(thread, 0, NULL, NULL); | 1865 NativeArguments args(thread, 0, NULL, NULL); |
1780 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1866 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1781 } | 1867 } |
1782 | 1868 |
1783 SP -= 2; | 1869 SP -= 2; |
1784 if (SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { | 1870 if (SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) { |
1785 pc++; | 1871 pc++; |
1786 } | 1872 } |
1787 DISPATCH(); | 1873 DISPATCH(); |
1788 } | 1874 } |
1789 | 1875 |
1790 { | 1876 { |
1877 BYTECODE(IfEqStrict, A_D); | |
1878 RawObject* lhs = FP[rA]; | |
1879 RawObject* rhs = FP[rD]; | |
1880 if (lhs != rhs) { | |
1881 pc++; | |
1882 } | |
1883 DISPATCH(); | |
1884 } | |
1885 | |
1886 { | |
1887 BYTECODE(IfNeStrict, A_D); | |
1888 RawObject* lhs = FP[rA]; | |
1889 RawObject* rhs = FP[rD]; | |
1890 if (lhs == rhs) { | |
1891 pc++; | |
1892 } | |
1893 DISPATCH(); | |
1894 } | |
1895 | |
1896 { | |
1897 BYTECODE(IfEqStrictNum, A_D); | |
1898 RawObject* lhs = FP[rA]; | |
1899 RawObject* rhs = FP[rD]; | |
1900 if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) { | |
1901 pc++; | |
1902 } | |
1903 DISPATCH(); | |
1904 } | |
1905 | |
1906 { | |
1907 BYTECODE(IfNeStrictNum, A_D); | |
1908 RawObject* lhs = FP[rA]; | |
1909 RawObject* rhs = FP[rD]; | |
1910 if (SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) { | |
1911 pc++; | |
1912 } | |
1913 DISPATCH(); | |
1914 } | |
1915 | |
1916 { | |
1791 BYTECODE(Jump, 0); | 1917 BYTECODE(Jump, 0); |
1792 const int32_t target = static_cast<int32_t>(op) >> 8; | 1918 const int32_t target = static_cast<int32_t>(op) >> 8; |
1793 pc += (target - 1); | 1919 pc += (target - 1); |
1794 DISPATCH(); | 1920 DISPATCH(); |
1795 } | 1921 } |
1796 | 1922 |
1797 { | 1923 { |
1798 BYTECODE(LoadClassId, A_D); | 1924 BYTECODE(LoadClassId, A_D); |
1799 const uint16_t object_reg = rD; | 1925 const uint16_t object_reg = rD; |
1800 RawObject* obj = static_cast<RawObject*>(FP[object_reg]); | 1926 RawObject* obj = static_cast<RawObject*>(FP[object_reg]); |
1801 FP[rA] = SimulatorHelpers::GetClassIdAsSmi(obj); | 1927 FP[rA] = SimulatorHelpers::GetClassIdAsSmi(obj); |
1802 DISPATCH(); | 1928 DISPATCH(); |
1803 } | 1929 } |
1804 | 1930 |
1805 { | 1931 { |
1806 BYTECODE(LoadClassIdTOS, 0); | 1932 BYTECODE(LoadClassIdTOS, 0); |
1807 RawObject* obj = static_cast<RawObject*>(SP[0]); | 1933 RawObject* obj = static_cast<RawObject*>(SP[0]); |
1808 SP[0] = SimulatorHelpers::GetClassIdAsSmi(obj); | 1934 SP[0] = SimulatorHelpers::GetClassIdAsSmi(obj); |
1809 DISPATCH(); | 1935 DISPATCH(); |
1810 } | 1936 } |
1811 | 1937 |
1812 { | 1938 { |
1813 BYTECODE(StoreIndexedTOS, 0); | 1939 BYTECODE(StoreIndexedTOS, 0); |
1814 SP -= 3; | 1940 SP -= 3; |
1815 RawArray* array = static_cast<RawArray*>(SP[1]); | 1941 RawArray* array = static_cast<RawArray*>(SP[1]); |
1816 RawSmi* index = static_cast<RawSmi*>(SP[2]); | 1942 RawSmi* index = static_cast<RawSmi*>(SP[2]); |
1817 RawObject* value = SP[3]; | 1943 RawObject* value = SP[3]; |
1818 ASSERT(array->GetClassId() == kArrayCid); | 1944 ASSERT(array->GetClassId() == kArrayCid); |
1819 ASSERT(!index->IsHeapObject()); | 1945 ASSERT(!index->IsHeapObject()); |
1946 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); | |
1820 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); | 1947 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); |
1821 DISPATCH(); | 1948 DISPATCH(); |
1822 } | 1949 } |
1823 | 1950 |
1824 { | 1951 { |
1952 BYTECODE(StoreIndexed, A_B_C); | |
1953 RawArray* array = static_cast<RawArray*>(FP[rA]); | |
1954 RawSmi* index = static_cast<RawSmi*>(FP[rB]); | |
1955 RawObject* value = FP[rC]; | |
1956 ASSERT(array->GetClassId() == kArrayCid); | |
1957 ASSERT(!index->IsHeapObject()); | |
1958 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); | |
1959 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); | |
1960 DISPATCH(); | |
1961 } | |
1962 | |
1963 { | |
1964 BYTECODE(Deopt, A_D); | |
1965 const uint16_t deopt_id = rD; | |
1966 if (deopt_id == 0) { // Lazy deoptimization. | |
1967 // Preserve result of the previous call. | |
1968 // TODO(vegorov) we could have actually included result into the | |
1969 // deoptimization environment because it is passed through the stack. | |
1970 // If we do then we could remove special result handling from this code. | |
1971 RawObject* result = SP[0]; | |
1972 | |
1973 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. | |
1974 // The code in this frame may not cause GC. | |
1975 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. | |
1976 EnterSyntheticFrame(&FP, &SP, pc - 1); | |
1977 const intptr_t frame_size_in_bytes = | |
1978 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), | |
1979 /*is_lazy_deopt=*/1); | |
1980 LeaveSyntheticFrame(&FP, &SP); | |
1981 | |
1982 SP = FP + (frame_size_in_bytes / kWordSize); | |
1983 EnterSyntheticFrame(&FP, &SP, pc - 1); | |
1984 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP)); | |
1985 | |
1986 // We are now inside a valid frame. | |
1987 { | |
1988 *++SP = result; // Preserve result (call below can cause GC). | |
1989 *++SP = 0; // Space for the result: number of materialization args. | |
1990 Exit(thread, FP, SP + 1, /*pc=*/0); | |
1991 NativeArguments native_args(thread, 0, SP, SP); | |
1992 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args); | |
1993 } | |
1994 const intptr_t materialization_arg_count = | |
1995 Smi::Value(RAW_CAST(Smi, *SP--)); | |
1996 result = *SP--; // Reload the result. It might have been relocated by GC. | |
1997 | |
1998 // Restore caller PC. | |
1999 pc = SavedCallerPC(FP); | |
2000 | |
2001 // Check if it is a fake PC marking the entry frame. | |
2002 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); | |
2003 | |
2004 // Restore SP, FP and PP. Push result and dispatch. | |
2005 // Note: unlike in a normal return sequence we don't need to drop | |
2006 // arguments - those are not part of the innermost deoptimization | |
2007 // environment they were dropped by FlowGraphCompiler::RecordAfterCall. | |
2008 SP = FrameArguments(FP, materialization_arg_count); | |
2009 FP = SavedCallerFP(FP); | |
2010 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); | |
2011 *SP = result; | |
2012 } else { | |
2013 UNIMPLEMENTED(); | |
2014 } | |
2015 DISPATCH(); | |
2016 } | |
2017 | |
2018 { | |
1825 BYTECODE(Trap, 0); | 2019 BYTECODE(Trap, 0); |
1826 UNIMPLEMENTED(); | 2020 UNIMPLEMENTED(); |
1827 DISPATCH(); | 2021 DISPATCH(); |
1828 } | 2022 } |
1829 | 2023 |
1830 // Helper used to handle noSuchMethod on closures. | 2024 // Helper used to handle noSuchMethod on closures. |
1831 { | 2025 { |
1832 ClosureNoSuchMethod: | 2026 ClosureNoSuchMethod: |
1833 #if defined(DEBUG) | 2027 #if defined(DEBUG) |
1834 function_h ^= FrameFunction(FP); | 2028 function_h ^= FrameFunction(FP); |
1835 ASSERT(function_h.IsClosureFunction()); | 2029 ASSERT(function_h.IsClosureFunction()); |
1836 #endif | 2030 #endif |
1837 | 2031 |
1838 // Restore caller context as we are going to throw NoSuchMethod. | 2032 // Restore caller context as we are going to throw NoSuchMethod. |
1839 pc = SavedCallerPC(FP); | 2033 pc = SavedCallerPC(FP); |
1840 | 2034 |
1841 const bool has_dart_caller = (reinterpret_cast<uword>(pc) & 2) == 0; | 2035 const bool has_dart_caller = (reinterpret_cast<uword>(pc) & 2) == 0; |
1842 const intptr_t argc = has_dart_caller | 2036 const intptr_t argc = has_dart_caller |
1843 ? Bytecode::DecodeArgc(pc[-1]) | 2037 ? Bytecode::DecodeArgc(pc[-1]) |
1844 : (reinterpret_cast<uword>(pc) >> 2); | 2038 : (reinterpret_cast<uword>(pc) >> 2); |
1845 | 2039 |
1846 SP = FrameArguments(FP, 0); | 2040 SP = FrameArguments(FP, 0); |
1847 RawObject** args = SP - argc; | 2041 RawObject** args = SP - argc; |
1848 FP = SavedCallerFP(FP); | 2042 FP = SavedCallerFP(FP); |
1849 if (has_dart_caller) { | 2043 if (has_dart_caller) { |
1850 pp = FrameCode(FP)->ptr()->object_pool_->ptr(); | 2044 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
1851 } | 2045 } |
1852 | 2046 |
1853 *++SP = null_value; | 2047 *++SP = null_value; |
1854 *++SP = args[0]; // Closure object. | 2048 *++SP = args[0]; // Closure object. |
1855 *++SP = argdesc; | 2049 *++SP = argdesc; |
1856 *++SP = null_value; // Array of arguments (will be filled). | 2050 *++SP = null_value; // Array of arguments (will be filled). |
1857 | 2051 |
1858 // Allocate array of arguments. | 2052 // Allocate array of arguments. |
1859 { | 2053 { |
1860 SP[1] = Smi::New(argc); // length | 2054 SP[1] = Smi::New(argc); // length |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1925 special_[kExceptionSpecialIndex] = raw_exception; | 2119 special_[kExceptionSpecialIndex] = raw_exception; |
1926 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 2120 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
1927 buf->Longjmp(); | 2121 buf->Longjmp(); |
1928 UNREACHABLE(); | 2122 UNREACHABLE(); |
1929 } | 2123 } |
1930 | 2124 |
1931 } // namespace dart | 2125 } // namespace dart |
1932 | 2126 |
1933 | 2127 |
1934 #endif // defined TARGET_ARCH_DBC | 2128 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |