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