OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/deopt_instructions.h" | 5 #include "vm/deopt_instructions.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 | 59 |
60 // Do not include incoming arguments if there are optional arguments | 60 // Do not include incoming arguments if there are optional arguments |
61 // (they are copied into local space at method entry). | 61 // (they are copied into local space at method entry). |
62 num_args_ = | 62 num_args_ = |
63 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 63 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
64 | 64 |
65 // The fixed size section of the (fake) Dart frame called via a stub by the | 65 // The fixed size section of the (fake) Dart frame called via a stub by the |
66 // optimized function contains FP, PP (ARM and MIPS only), PC-marker and | 66 // optimized function contains FP, PP (ARM and MIPS only), PC-marker and |
67 // return-address. This section is copied as well, so that its contained | 67 // return-address. This section is copied as well, so that its contained |
68 // values can be updated before returning to the deoptimized function. | 68 // values can be updated before returning to the deoptimized function. |
| 69 // Note: on DBC stack grows upwards unlike on all other architectures. |
69 source_frame_size_ = | 70 source_frame_size_ = |
70 + kDartFrameFixedSize // For saved values below sp. | 71 + kDartFrameFixedSize // For saved values below sp. |
| 72 #if !defined(TARGET_ARCH_DBC) |
71 + ((frame->fp() - frame->sp()) / kWordSize) // For frame size incl. sp. | 73 + ((frame->fp() - frame->sp()) / kWordSize) // For frame size incl. sp. |
| 74 #else |
| 75 + ((frame->sp() - frame->fp()) / kWordSize) // For frame size incl. sp. |
| 76 #endif // !defined(TARGET_ARCH_DBC) |
72 + 1 // For fp. | 77 + 1 // For fp. |
73 + kParamEndSlotFromFp // For saved values above fp. | 78 + kParamEndSlotFromFp // For saved values above fp. |
74 + num_args_; // For arguments. | 79 + num_args_; // For arguments. |
75 source_frame_ = reinterpret_cast<intptr_t*>( | 80 |
76 frame->sp() - (kDartFrameFixedSize * kWordSize)); | 81 source_frame_ = FrameBase(frame); |
77 | 82 |
78 if (dest_options == kDestIsOriginalFrame) { | 83 if (dest_options == kDestIsOriginalFrame) { |
79 // Work from a copy of the source frame. | 84 // Work from a copy of the source frame. |
80 intptr_t* original_frame = source_frame_; | 85 intptr_t* original_frame = source_frame_; |
81 source_frame_ = new intptr_t[source_frame_size_]; | 86 source_frame_ = new intptr_t[source_frame_size_]; |
82 ASSERT(source_frame_ != NULL); | 87 ASSERT(source_frame_ != NULL); |
83 for (intptr_t i = 0; i < source_frame_size_; i++) { | 88 for (intptr_t i = 0; i < source_frame_size_; i++) { |
84 source_frame_[i] = original_frame[i]; | 89 source_frame_[i] = original_frame[i]; |
85 } | 90 } |
86 source_frame_is_allocated_ = true; | 91 source_frame_is_allocated_ = true; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 180 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
176 if (dest_frame_[i] != 0) { | 181 if (dest_frame_[i] != 0) { |
177 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i])); | 182 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i])); |
178 } | 183 } |
179 } | 184 } |
180 } | 185 } |
181 } | 186 } |
182 | 187 |
183 | 188 |
184 intptr_t DeoptContext::DestStackAdjustment() const { | 189 intptr_t DeoptContext::DestStackAdjustment() const { |
185 return (dest_frame_size_ | 190 return dest_frame_size_ |
186 - kDartFrameFixedSize | 191 - kDartFrameFixedSize |
187 - num_args_ | 192 - num_args_ |
188 - kParamEndSlotFromFp | 193 #if !defined(TARGET_ARCH_DBC) |
189 - 1); // For fp. | 194 - 1 // For fp. |
| 195 #endif |
| 196 - kParamEndSlotFromFp; |
190 } | 197 } |
191 | 198 |
192 | 199 |
193 intptr_t DeoptContext::GetSourceFp() const { | 200 intptr_t DeoptContext::GetSourceFp() const { |
| 201 #if !defined(TARGET_ARCH_DBC) |
194 return source_frame_[source_frame_size_ - 1 - num_args_ - | 202 return source_frame_[source_frame_size_ - 1 - num_args_ - |
195 kParamEndSlotFromFp]; | 203 kParamEndSlotFromFp]; |
| 204 #else |
| 205 return source_frame_[num_args_ + kDartFrameFixedSize + |
| 206 kSavedCallerFpSlotFromFp]; |
| 207 #endif |
196 } | 208 } |
197 | 209 |
198 | 210 |
199 intptr_t DeoptContext::GetSourcePp() const { | 211 intptr_t DeoptContext::GetSourcePp() const { |
| 212 #if !defined(TARGET_ARCH_DBC) |
200 return source_frame_[source_frame_size_ - 1 - num_args_ - | 213 return source_frame_[source_frame_size_ - 1 - num_args_ - |
201 kParamEndSlotFromFp + | 214 kParamEndSlotFromFp + |
202 StackFrame::SavedCallerPpSlotFromFp()]; | 215 StackFrame::SavedCallerPpSlotFromFp()]; |
| 216 #else |
| 217 UNREACHABLE(); |
| 218 return 0; |
| 219 #endif |
203 } | 220 } |
204 | 221 |
205 | 222 |
206 intptr_t DeoptContext::GetSourcePc() const { | 223 intptr_t DeoptContext::GetSourcePc() const { |
| 224 #if !defined(TARGET_ARCH_DBC) |
207 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp]; | 225 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp]; |
| 226 #else |
| 227 return source_frame_[num_args_ + kDartFrameFixedSize + |
| 228 kSavedCallerPcSlotFromFp]; |
| 229 #endif |
208 } | 230 } |
209 | 231 |
210 | 232 |
211 intptr_t DeoptContext::GetCallerFp() const { | 233 intptr_t DeoptContext::GetCallerFp() const { |
212 return caller_fp_; | 234 return caller_fp_; |
213 } | 235 } |
214 | 236 |
215 | 237 |
216 void DeoptContext::SetCallerFp(intptr_t caller_fp) { | 238 void DeoptContext::SetCallerFp(intptr_t caller_fp) { |
217 caller_fp_ = caller_fp; | 239 caller_fp_ = caller_fp; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 intptr_t* to_addr = GetDestFrameAddressAt(to_index); | 320 intptr_t* to_addr = GetDestFrameAddressAt(to_index); |
299 DeoptInstr* instr = deopt_instructions[from_index]; | 321 DeoptInstr* instr = deopt_instructions[from_index]; |
300 if (!objects_only || IsObjectInstruction(instr->kind())) { | 322 if (!objects_only || IsObjectInstruction(instr->kind())) { |
301 instr->Execute(this, to_addr); | 323 instr->Execute(this, to_addr); |
302 } else { | 324 } else { |
303 *reinterpret_cast<RawObject**>(to_addr) = Object::null(); | 325 *reinterpret_cast<RawObject**>(to_addr) = Object::null(); |
304 } | 326 } |
305 } | 327 } |
306 | 328 |
307 if (FLAG_trace_deoptimization_verbose) { | 329 if (FLAG_trace_deoptimization_verbose) { |
308 intptr_t* start = dest_frame_; | |
309 for (intptr_t i = 0; i < frame_size; i++) { | 330 for (intptr_t i = 0; i < frame_size; i++) { |
310 OS::PrintErr("*%" Pd ". [0x%" Px "] 0x%" Px " [%s]\n", | 331 intptr_t* to_addr = GetDestFrameAddressAt(i); |
| 332 OS::PrintErr("*%" Pd ". [%p] 0x%" Px " [%s]\n", |
311 i, | 333 i, |
312 reinterpret_cast<uword>(&start[i]), | 334 to_addr, |
313 start[i], | 335 *to_addr, |
314 deopt_instructions[i + (len - frame_size)]->ToCString()); | 336 deopt_instructions[i + (len - frame_size)]->ToCString()); |
315 } | 337 } |
316 } | 338 } |
317 } | 339 } |
318 | 340 |
319 | 341 |
320 static void FillDeferredSlots(DeoptContext* deopt_context, | 342 static void FillDeferredSlots(DeoptContext* deopt_context, |
321 DeferredSlot** slot_list) { | 343 DeferredSlot** slot_list) { |
322 DeferredSlot* slot = *slot_list; | 344 DeferredSlot* slot = *slot_list; |
323 *slot_list = NULL; | 345 *slot_list = NULL; |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 | 675 |
654 virtual const char* ArgumentsToCString() const { | 676 virtual const char* ArgumentsToCString() const { |
655 return Thread::Current()->zone()->PrintToString( | 677 return Thread::Current()->zone()->PrintToString( |
656 "%" Pd "", object_table_index_); | 678 "%" Pd "", object_table_index_); |
657 } | 679 } |
658 | 680 |
659 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 681 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
660 Function& function = Function::Handle(deopt_context->zone()); | 682 Function& function = Function::Handle(deopt_context->zone()); |
661 function ^= deopt_context->ObjectAt(object_table_index_); | 683 function ^= deopt_context->ObjectAt(object_table_index_); |
662 if (function.IsNull()) { | 684 if (function.IsNull()) { |
663 // There are no deoptimization stubs on DBC. | |
664 #if !defined(TARGET_ARCH_DBC) | |
665 *reinterpret_cast<RawObject**>(dest_addr) = deopt_context->is_lazy_deopt() | 685 *reinterpret_cast<RawObject**>(dest_addr) = deopt_context->is_lazy_deopt() |
666 ? StubCode::DeoptimizeLazy_entry()->code() | 686 ? StubCode::DeoptimizeLazy_entry()->code() |
667 : StubCode::Deoptimize_entry()->code(); | 687 : StubCode::Deoptimize_entry()->code(); |
668 #endif | |
669 return; | 688 return; |
670 } | 689 } |
671 | 690 |
672 #if !defined(TARGET_ARCH_DBC) | 691 #if !defined(TARGET_ARCH_DBC) |
673 // We don't always have the Code object for the frame's corresponding | 692 // We don't always have the Code object for the frame's corresponding |
674 // unoptimized code as it may have been collected. Use a stub as the pc | 693 // unoptimized code as it may have been collected. Use a stub as the pc |
675 // marker until we can recreate that Code object during deferred | 694 // marker until we can recreate that Code object during deferred |
676 // materialization to maintain the invariant that Dart frames always have | 695 // materialization to maintain the invariant that Dart frames always have |
677 // a pc marker. | 696 // a pc marker. |
678 *reinterpret_cast<RawObject**>(dest_addr) = | 697 *reinterpret_cast<RawObject**>(dest_addr) = |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 class DeoptCallerFpInstr : public DeoptInstr { | 741 class DeoptCallerFpInstr : public DeoptInstr { |
723 public: | 742 public: |
724 DeoptCallerFpInstr() {} | 743 DeoptCallerFpInstr() {} |
725 | 744 |
726 virtual intptr_t source_index() const { return 0; } | 745 virtual intptr_t source_index() const { return 0; } |
727 virtual DeoptInstr::Kind kind() const { return kCallerFp; } | 746 virtual DeoptInstr::Kind kind() const { return kCallerFp; } |
728 | 747 |
729 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 748 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
730 *dest_addr = deopt_context->GetCallerFp(); | 749 *dest_addr = deopt_context->GetCallerFp(); |
731 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( | 750 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( |
732 dest_addr - (kSavedCallerFpSlotFromFp * kWordSize))); | 751 dest_addr - kSavedCallerFpSlotFromFp)); |
733 } | 752 } |
734 | 753 |
735 private: | 754 private: |
736 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); | 755 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); |
737 }; | 756 }; |
738 | 757 |
739 | 758 |
740 // Deoptimization instruction copying the caller saved PP from optimized frame. | 759 // Deoptimization instruction copying the caller saved PP from optimized frame. |
741 class DeoptCallerPpInstr : public DeoptInstr { | 760 class DeoptCallerPpInstr : public DeoptInstr { |
742 public: | 761 public: |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 Smi* offset, | 1338 Smi* offset, |
1320 TypedData* info, | 1339 TypedData* info, |
1321 Smi* reason) { | 1340 Smi* reason) { |
1322 intptr_t i = index * kEntrySize; | 1341 intptr_t i = index * kEntrySize; |
1323 *offset ^= table.At(i); | 1342 *offset ^= table.At(i); |
1324 *info ^= table.At(i + 1); | 1343 *info ^= table.At(i + 1); |
1325 *reason ^= table.At(i + 2); | 1344 *reason ^= table.At(i + 2); |
1326 } | 1345 } |
1327 | 1346 |
1328 } // namespace dart | 1347 } // namespace dart |
OLD | NEW |