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 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 RawObject*** SP) { | 546 RawObject*** SP) { |
547 RawObject** callee_fp = call_top + kDartFrameFixedSize; | 547 RawObject** callee_fp = call_top + kDartFrameFixedSize; |
548 | 548 |
549 RawFunction* function = FrameFunction(callee_fp); | 549 RawFunction* function = FrameFunction(callee_fp); |
550 RawCode* code = function->ptr()->code_; | 550 RawCode* code = function->ptr()->code_; |
551 callee_fp[kPcMarkerSlotFromFp] = code; | 551 callee_fp[kPcMarkerSlotFromFp] = code; |
552 callee_fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc); | 552 callee_fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc); |
553 callee_fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); | 553 callee_fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); |
554 *pp = code->ptr()->object_pool_->ptr(); | 554 *pp = code->ptr()->object_pool_->ptr(); |
555 *pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); | 555 *pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
| 556 pc_ = reinterpret_cast<uword>(*pc); // For the profiler. |
556 *FP = callee_fp; | 557 *FP = callee_fp; |
557 *SP = *FP - 1; | 558 *SP = *FP - 1; |
558 } | 559 } |
559 | 560 |
560 | 561 |
561 void Simulator::InlineCacheMiss(int checked_args, | 562 void Simulator::InlineCacheMiss(int checked_args, |
562 Thread* thread, | 563 Thread* thread, |
563 RawICData* icdata, | 564 RawICData* icdata, |
564 RawObject** args, | 565 RawObject** args, |
565 RawObject** top, | 566 RawObject** top, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 static DART_NOINLINE bool InvokeRuntime( | 699 static DART_NOINLINE bool InvokeRuntime( |
699 Thread* thread, | 700 Thread* thread, |
700 Simulator* sim, | 701 Simulator* sim, |
701 RuntimeFunction drt, | 702 RuntimeFunction drt, |
702 const NativeArguments& args) { | 703 const NativeArguments& args) { |
703 SimulatorSetjmpBuffer buffer(sim); | 704 SimulatorSetjmpBuffer buffer(sim); |
704 if (!setjmp(buffer.buffer_)) { | 705 if (!setjmp(buffer.buffer_)) { |
705 thread->set_vm_tag(reinterpret_cast<uword>(drt)); | 706 thread->set_vm_tag(reinterpret_cast<uword>(drt)); |
706 drt(args); | 707 drt(args); |
707 thread->set_vm_tag(VMTag::kDartTagId); | 708 thread->set_vm_tag(VMTag::kDartTagId); |
| 709 thread->set_top_exit_frame_info(0); |
708 return true; | 710 return true; |
709 } else { | 711 } else { |
710 return false; | 712 return false; |
711 } | 713 } |
712 } | 714 } |
713 | 715 |
714 | 716 |
715 static DART_NOINLINE bool InvokeNative( | 717 static DART_NOINLINE bool InvokeNative( |
716 Thread* thread, | 718 Thread* thread, |
717 Simulator* sim, | 719 Simulator* sim, |
718 SimulatorBootstrapNativeCall f, | 720 SimulatorBootstrapNativeCall f, |
719 NativeArguments* args) { | 721 NativeArguments* args) { |
720 SimulatorSetjmpBuffer buffer(sim); | 722 SimulatorSetjmpBuffer buffer(sim); |
721 if (!setjmp(buffer.buffer_)) { | 723 if (!setjmp(buffer.buffer_)) { |
722 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 724 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
723 f(args); | 725 f(args); |
724 thread->set_vm_tag(VMTag::kDartTagId); | 726 thread->set_vm_tag(VMTag::kDartTagId); |
| 727 thread->set_top_exit_frame_info(0); |
725 return true; | 728 return true; |
726 } else { | 729 } else { |
727 return false; | 730 return false; |
728 } | 731 } |
729 } | 732 } |
730 | 733 |
731 | 734 |
732 static DART_NOINLINE bool InvokeNativeWrapper( | 735 static DART_NOINLINE bool InvokeNativeWrapper( |
733 Thread* thread, | 736 Thread* thread, |
734 Simulator* sim, | 737 Simulator* sim, |
735 Dart_NativeFunction f, | 738 Dart_NativeFunction f, |
736 NativeArguments* args) { | 739 NativeArguments* args) { |
737 SimulatorSetjmpBuffer buffer(sim); | 740 SimulatorSetjmpBuffer buffer(sim); |
738 if (!setjmp(buffer.buffer_)) { | 741 if (!setjmp(buffer.buffer_)) { |
739 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 742 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
740 NativeEntry::NativeCallWrapper(reinterpret_cast<Dart_NativeArguments>(args), | 743 NativeEntry::NativeCallWrapper(reinterpret_cast<Dart_NativeArguments>(args), |
741 f); | 744 f); |
742 thread->set_vm_tag(VMTag::kDartTagId); | 745 thread->set_vm_tag(VMTag::kDartTagId); |
| 746 thread->set_top_exit_frame_info(0); |
743 return true; | 747 return true; |
744 } else { | 748 } else { |
745 return false; | 749 return false; |
746 } | 750 } |
747 } | 751 } |
748 | 752 |
749 // Note: all macro helpers are intended to be used only inside Simulator::Call. | 753 // Note: all macro helpers are intended to be used only inside Simulator::Call. |
750 | 754 |
751 // Decode opcode and A part of the given value and dispatch to the | 755 // Decode opcode and A part of the given value and dispatch to the |
752 // corresponding bytecode handler. | 756 // corresponding bytecode handler. |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 // SP > | fp_ | | | 938 // SP > | fp_ | | |
935 // FP > | ........... | > normal Dart frame (see stack_frame_dbc.h) | 939 // FP > | ........... | > normal Dart frame (see stack_frame_dbc.h) |
936 // | | 940 // | |
937 // v | 941 // v |
938 // | 942 // |
939 FP = fp_ + 1 + arguments.Length() + kDartFrameFixedSize; | 943 FP = fp_ + 1 + arguments.Length() + kDartFrameFixedSize; |
940 SP = FP - 1; | 944 SP = FP - 1; |
941 | 945 |
942 // Save outer top_exit_frame_info. | 946 // Save outer top_exit_frame_info. |
943 fp_[0] = reinterpret_cast<RawObject*>(thread->top_exit_frame_info()); | 947 fp_[0] = reinterpret_cast<RawObject*>(thread->top_exit_frame_info()); |
| 948 thread->set_top_exit_frame_info(0); |
944 | 949 |
945 // Copy arguments and setup the Dart frame. | 950 // Copy arguments and setup the Dart frame. |
946 const intptr_t argc = arguments.Length(); | 951 const intptr_t argc = arguments.Length(); |
947 for (intptr_t i = 0; i < argc; i++) { | 952 for (intptr_t i = 0; i < argc; i++) { |
948 fp_[1 + i] = arguments.At(i); | 953 fp_[1 + i] = arguments.At(i); |
949 } | 954 } |
950 | 955 |
951 FP[kFunctionSlotFromFp] = code.function(); | 956 FP[kFunctionSlotFromFp] = code.function(); |
952 FP[kPcMarkerSlotFromFp] = code.raw(); | 957 FP[kPcMarkerSlotFromFp] = code.raw(); |
953 FP[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>((argc << 2) | 2); | 958 FP[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>((argc << 2) | 2); |
954 FP[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_); | 959 FP[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_); |
955 | 960 |
956 // Load argument descriptor. | 961 // Load argument descriptor. |
957 argdesc = arguments_descriptor.raw(); | 962 argdesc = arguments_descriptor.raw(); |
958 | 963 |
959 // Ready to start executing bytecode. Load entry point and corresponding | 964 // Ready to start executing bytecode. Load entry point and corresponding |
960 // object pool. | 965 // object pool. |
961 pc = reinterpret_cast<uint32_t*>(code.raw()->ptr()->entry_point_); | 966 pc = reinterpret_cast<uint32_t*>(code.raw()->ptr()->entry_point_); |
| 967 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
962 pp = code.object_pool()->ptr(); | 968 pp = code.object_pool()->ptr(); |
963 | 969 |
964 // Cache some frequently used values in the frame. | 970 // Cache some frequently used values in the frame. |
965 RawBool* true_value = Bool::True().raw(); | 971 RawBool* true_value = Bool::True().raw(); |
966 RawBool* false_value = Bool::False().raw(); | 972 RawBool* false_value = Bool::False().raw(); |
967 RawObject* null_value = Object::null(); | 973 RawObject* null_value = Object::null(); |
968 RawObject* empty_context = thread->isolate()->object_store()->empty_context(); | 974 RawObject* empty_context = thread->isolate()->object_store()->empty_context(); |
969 | 975 |
970 #if defined(DEBUG) | 976 #if defined(DEBUG) |
971 Function& function_h = Function::Handle(); | 977 Function& function_h = Function::Handle(); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 FP[1] = 0; | 1179 FP[1] = 0; |
1174 Exit(thread, FP, FP + 2, pc); | 1180 Exit(thread, FP, FP + 2, pc); |
1175 NativeArguments args(thread, 1, FP, FP + 1); | 1181 NativeArguments args(thread, 1, FP, FP + 1); |
1176 INVOKE_RUNTIME(DRT_CompileFunction, args); | 1182 INVOKE_RUNTIME(DRT_CompileFunction, args); |
1177 { | 1183 { |
1178 // Function should be compiled now, dispatch to its entry point. | 1184 // Function should be compiled now, dispatch to its entry point. |
1179 RawCode* code = FrameFunction(FP)->ptr()->code_; | 1185 RawCode* code = FrameFunction(FP)->ptr()->code_; |
1180 SimulatorHelpers::SetFrameCode(FP, code); | 1186 SimulatorHelpers::SetFrameCode(FP, code); |
1181 pp = code->ptr()->object_pool_->ptr(); | 1187 pp = code->ptr()->object_pool_->ptr(); |
1182 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); | 1188 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
| 1189 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
1183 } | 1190 } |
1184 DISPATCH(); | 1191 DISPATCH(); |
1185 } | 1192 } |
1186 | 1193 |
1187 { | 1194 { |
1188 BYTECODE(HotCheck, A_D); | 1195 BYTECODE(HotCheck, A_D); |
1189 const uint8_t increment = rA; | 1196 const uint8_t increment = rA; |
1190 const uint16_t threshold = rD; | 1197 const uint16_t threshold = rD; |
1191 RawFunction* f = FrameFunction(FP); | 1198 RawFunction* f = FrameFunction(FP); |
1192 int32_t counter = f->ptr()->usage_counter_; | 1199 int32_t counter = f->ptr()->usage_counter_; |
1193 // Note: we don't increment usage counter in the prologue of optimized | 1200 // Note: we don't increment usage counter in the prologue of optimized |
1194 // functions. | 1201 // functions. |
1195 if (increment) { | 1202 if (increment) { |
1196 counter += increment; | 1203 counter += increment; |
1197 f->ptr()->usage_counter_ = counter; | 1204 f->ptr()->usage_counter_ = counter; |
1198 } | 1205 } |
1199 if (counter >= threshold) { | 1206 if (counter >= threshold) { |
1200 FP[0] = f; | 1207 FP[0] = f; |
1201 FP[1] = 0; | 1208 FP[1] = 0; |
1202 Exit(thread, FP, FP + 2, pc); | 1209 Exit(thread, FP, FP + 2, pc); |
1203 NativeArguments args(thread, 1, FP, FP + 1); | 1210 NativeArguments args(thread, 1, FP, FP + 1); |
1204 INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args); | 1211 INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args); |
1205 { | 1212 { |
1206 // DRT_OptimizeInvokedFunction returns the code object to execute. | 1213 // DRT_OptimizeInvokedFunction returns the code object to execute. |
1207 ASSERT(FP[1]->GetClassId() == kCodeCid); | 1214 ASSERT(FP[1]->GetClassId() == kCodeCid); |
1208 RawCode* code = static_cast<RawCode*>(FP[1]); | 1215 RawCode* code = static_cast<RawCode*>(FP[1]); |
1209 SimulatorHelpers::SetFrameCode(FP, code); | 1216 SimulatorHelpers::SetFrameCode(FP, code); |
1210 pp = code->ptr()->object_pool_->ptr(); | 1217 pp = code->ptr()->object_pool_->ptr(); |
1211 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); | 1218 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
| 1219 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
1212 } | 1220 } |
1213 } | 1221 } |
1214 DISPATCH(); | 1222 DISPATCH(); |
1215 } | 1223 } |
1216 | 1224 |
1217 { | 1225 { |
1218 BYTECODE(CheckStack, A); | 1226 BYTECODE(CheckStack, A); |
1219 { | 1227 { |
1220 if (reinterpret_cast<uword>(SP) >= thread->stack_limit()) { | 1228 if (reinterpret_cast<uword>(SP) >= thread->stack_limit()) { |
1221 Exit(thread, FP, SP + 1, pc); | 1229 Exit(thread, FP, SP + 1, pc); |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2139 result = FP[rA]; | 2147 result = FP[rA]; |
2140 goto ReturnImpl; | 2148 goto ReturnImpl; |
2141 | 2149 |
2142 BYTECODE(ReturnTOS, 0); | 2150 BYTECODE(ReturnTOS, 0); |
2143 result = *SP; | 2151 result = *SP; |
2144 // Fall through to the ReturnImpl. | 2152 // Fall through to the ReturnImpl. |
2145 | 2153 |
2146 ReturnImpl: | 2154 ReturnImpl: |
2147 // Restore caller PC. | 2155 // Restore caller PC. |
2148 pc = SavedCallerPC(FP); | 2156 pc = SavedCallerPC(FP); |
| 2157 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
2149 | 2158 |
2150 // Check if it is a fake PC marking the entry frame. | 2159 // Check if it is a fake PC marking the entry frame. |
2151 if ((reinterpret_cast<uword>(pc) & 2) != 0) { | 2160 if ((reinterpret_cast<uword>(pc) & 2) != 0) { |
2152 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; | 2161 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; |
2153 fp_ = sp_ = | 2162 fp_ = sp_ = |
2154 reinterpret_cast<RawObject**>(FrameArguments(FP, argc + 1)[0]); | 2163 reinterpret_cast<RawObject**>(FrameArguments(FP, argc + 1)[0]); |
2155 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); | 2164 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); |
2156 thread->set_top_resource(top_resource); | 2165 thread->set_top_resource(top_resource); |
2157 thread->set_vm_tag(vm_tag); | 2166 thread->set_vm_tag(vm_tag); |
2158 return result; | 2167 return result; |
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 } | 3052 } |
3044 const intptr_t materialization_arg_count = | 3053 const intptr_t materialization_arg_count = |
3045 Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize; | 3054 Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize; |
3046 if (is_lazy) { | 3055 if (is_lazy) { |
3047 // Reload the result. It might have been relocated by GC. | 3056 // Reload the result. It might have been relocated by GC. |
3048 result = *SP--; | 3057 result = *SP--; |
3049 } | 3058 } |
3050 | 3059 |
3051 // Restore caller PC. | 3060 // Restore caller PC. |
3052 pc = SavedCallerPC(FP); | 3061 pc = SavedCallerPC(FP); |
| 3062 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
3053 | 3063 |
3054 // Check if it is a fake PC marking the entry frame. | 3064 // Check if it is a fake PC marking the entry frame. |
3055 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); | 3065 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); |
3056 | 3066 |
3057 // Restore SP, FP and PP. Push result and dispatch. | 3067 // Restore SP, FP and PP. Push result and dispatch. |
3058 // Note: unlike in a normal return sequence we don't need to drop | 3068 // Note: unlike in a normal return sequence we don't need to drop |
3059 // arguments - those are not part of the innermost deoptimization | 3069 // arguments - those are not part of the innermost deoptimization |
3060 // environment they were dropped by FlowGraphCompiler::RecordAfterCall. | 3070 // environment they were dropped by FlowGraphCompiler::RecordAfterCall. |
3061 | 3071 |
3062 // If the result is not preserved, the unoptimized frame ends at the | 3072 // If the result is not preserved, the unoptimized frame ends at the |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3181 pc_ = pc; | 3191 pc_ = pc; |
3182 special_[kExceptionSpecialIndex] = raw_exception; | 3192 special_[kExceptionSpecialIndex] = raw_exception; |
3183 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 3193 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
3184 buf->Longjmp(); | 3194 buf->Longjmp(); |
3185 UNREACHABLE(); | 3195 UNREACHABLE(); |
3186 } | 3196 } |
3187 | 3197 |
3188 } // namespace dart | 3198 } // namespace dart |
3189 | 3199 |
3190 #endif // defined TARGET_ARCH_DBC | 3200 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |