| 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 |