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. | |
Florian Schneider
2016/05/19 13:21:39
In generate it would be nice to encapsulate more o
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
I will keep this code without a helper for now.
| |
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. |
80 #if !defined(TARGET_ARCH_DBC) | |
75 source_frame_ = reinterpret_cast<intptr_t*>( | 81 source_frame_ = reinterpret_cast<intptr_t*>( |
76 frame->sp() - (kDartFrameFixedSize * kWordSize)); | 82 frame->sp() - (kDartFrameFixedSize * kWordSize)); |
83 #else | |
Florian Schneider
2016/05/19 13:21:39
A helper FrameStart(frame)?
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
84 source_frame_ = reinterpret_cast<intptr_t*>( | |
85 frame->fp() - (kDartFrameFixedSize + num_args_) * kWordSize); | |
86 #endif // !defined(TARGET_ARCH_DBC) | |
77 | 87 |
78 if (dest_options == kDestIsOriginalFrame) { | 88 if (dest_options == kDestIsOriginalFrame) { |
79 // Work from a copy of the source frame. | 89 // Work from a copy of the source frame. |
80 intptr_t* original_frame = source_frame_; | 90 intptr_t* original_frame = source_frame_; |
81 source_frame_ = new intptr_t[source_frame_size_]; | 91 source_frame_ = new intptr_t[source_frame_size_]; |
82 ASSERT(source_frame_ != NULL); | 92 ASSERT(source_frame_ != NULL); |
83 for (intptr_t i = 0; i < source_frame_size_; i++) { | 93 for (intptr_t i = 0; i < source_frame_size_; i++) { |
84 source_frame_[i] = original_frame[i]; | 94 source_frame_[i] = original_frame[i]; |
85 } | 95 } |
86 source_frame_is_allocated_ = true; | 96 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++) { | 185 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
176 if (dest_frame_[i] != 0) { | 186 if (dest_frame_[i] != 0) { |
177 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i])); | 187 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i])); |
178 } | 188 } |
179 } | 189 } |
180 } | 190 } |
181 } | 191 } |
182 | 192 |
183 | 193 |
184 intptr_t DeoptContext::DestStackAdjustment() const { | 194 intptr_t DeoptContext::DestStackAdjustment() const { |
185 return (dest_frame_size_ | 195 return dest_frame_size_ |
186 - kDartFrameFixedSize | 196 - kDartFrameFixedSize |
187 - num_args_ | 197 - num_args_ |
188 - kParamEndSlotFromFp | 198 #if !defined(TARGET_ARCH_DBC) |
189 - 1); // For fp. | 199 - 1 // For fp. |
200 #endif | |
201 - kParamEndSlotFromFp; | |
190 } | 202 } |
191 | 203 |
192 | 204 |
193 intptr_t DeoptContext::GetSourceFp() const { | 205 intptr_t DeoptContext::GetSourceFp() const { |
206 #if !defined(TARGET_ARCH_DBC) | |
194 return source_frame_[source_frame_size_ - 1 - num_args_ - | 207 return source_frame_[source_frame_size_ - 1 - num_args_ - |
195 kParamEndSlotFromFp]; | 208 kParamEndSlotFromFp]; |
209 #else | |
210 return source_frame_[num_args_ + kDartFrameFixedSize + | |
211 kSavedCallerFpSlotFromFp]; | |
212 #endif | |
196 } | 213 } |
197 | 214 |
198 | 215 |
199 intptr_t DeoptContext::GetSourcePp() const { | 216 intptr_t DeoptContext::GetSourcePp() const { |
217 #if !defined(TARGET_ARCH_DBC) | |
200 return source_frame_[source_frame_size_ - 1 - num_args_ - | 218 return source_frame_[source_frame_size_ - 1 - num_args_ - |
201 kParamEndSlotFromFp + | 219 kParamEndSlotFromFp + |
202 StackFrame::SavedCallerPpSlotFromFp()]; | 220 StackFrame::SavedCallerPpSlotFromFp()]; |
221 #else | |
222 UNREACHABLE(); | |
223 return 0; | |
224 #endif | |
203 } | 225 } |
204 | 226 |
205 | 227 |
206 intptr_t DeoptContext::GetSourcePc() const { | 228 intptr_t DeoptContext::GetSourcePc() const { |
229 #if !defined(TARGET_ARCH_DBC) | |
207 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp]; | 230 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp]; |
231 #else | |
232 return source_frame_[num_args_ + kDartFrameFixedSize + | |
233 kSavedCallerPcSlotFromFp]; | |
234 #endif | |
208 } | 235 } |
209 | 236 |
210 | 237 |
211 intptr_t DeoptContext::GetCallerFp() const { | 238 intptr_t DeoptContext::GetCallerFp() const { |
212 return caller_fp_; | 239 return caller_fp_; |
213 } | 240 } |
214 | 241 |
215 | 242 |
216 void DeoptContext::SetCallerFp(intptr_t caller_fp) { | 243 void DeoptContext::SetCallerFp(intptr_t caller_fp) { |
217 caller_fp_ = caller_fp; | 244 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); | 325 intptr_t* to_addr = GetDestFrameAddressAt(to_index); |
299 DeoptInstr* instr = deopt_instructions[from_index]; | 326 DeoptInstr* instr = deopt_instructions[from_index]; |
300 if (!objects_only || IsObjectInstruction(instr->kind())) { | 327 if (!objects_only || IsObjectInstruction(instr->kind())) { |
301 instr->Execute(this, to_addr); | 328 instr->Execute(this, to_addr); |
302 } else { | 329 } else { |
303 *reinterpret_cast<RawObject**>(to_addr) = Object::null(); | 330 *reinterpret_cast<RawObject**>(to_addr) = Object::null(); |
304 } | 331 } |
305 } | 332 } |
306 | 333 |
307 if (FLAG_trace_deoptimization_verbose) { | 334 if (FLAG_trace_deoptimization_verbose) { |
308 intptr_t* start = dest_frame_; | |
309 for (intptr_t i = 0; i < frame_size; i++) { | 335 for (intptr_t i = 0; i < frame_size; i++) { |
310 OS::PrintErr("*%" Pd ". [0x%" Px "] 0x%" Px " [%s]\n", | 336 intptr_t* to_addr = GetDestFrameAddressAt(i); |
337 OS::PrintErr("*%" Pd ". [%p] 0x%" Px " [%s]\n", | |
311 i, | 338 i, |
312 reinterpret_cast<uword>(&start[i]), | 339 to_addr, |
313 start[i], | 340 *to_addr, |
314 deopt_instructions[i + (len - frame_size)]->ToCString()); | 341 deopt_instructions[i + (len - frame_size)]->ToCString()); |
315 } | 342 } |
316 } | 343 } |
317 } | 344 } |
318 | 345 |
319 | 346 |
320 static void FillDeferredSlots(DeoptContext* deopt_context, | 347 static void FillDeferredSlots(DeoptContext* deopt_context, |
321 DeferredSlot** slot_list) { | 348 DeferredSlot** slot_list) { |
322 DeferredSlot* slot = *slot_list; | 349 DeferredSlot* slot = *slot_list; |
323 *slot_list = NULL; | 350 *slot_list = NULL; |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
653 | 680 |
654 virtual const char* ArgumentsToCString() const { | 681 virtual const char* ArgumentsToCString() const { |
655 return Thread::Current()->zone()->PrintToString( | 682 return Thread::Current()->zone()->PrintToString( |
656 "%" Pd "", object_table_index_); | 683 "%" Pd "", object_table_index_); |
657 } | 684 } |
658 | 685 |
659 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 686 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
660 Function& function = Function::Handle(deopt_context->zone()); | 687 Function& function = Function::Handle(deopt_context->zone()); |
661 function ^= deopt_context->ObjectAt(object_table_index_); | 688 function ^= deopt_context->ObjectAt(object_table_index_); |
662 if (function.IsNull()) { | 689 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() | 690 *reinterpret_cast<RawObject**>(dest_addr) = deopt_context->is_lazy_deopt() |
666 ? StubCode::DeoptimizeLazy_entry()->code() | 691 ? StubCode::DeoptimizeLazy_entry()->code() |
667 : StubCode::Deoptimize_entry()->code(); | 692 : StubCode::Deoptimize_entry()->code(); |
668 #endif | |
669 return; | 693 return; |
670 } | 694 } |
671 | 695 |
672 #if !defined(TARGET_ARCH_DBC) | 696 #if !defined(TARGET_ARCH_DBC) |
673 // We don't always have the Code object for the frame's corresponding | 697 // 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 | 698 // 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 | 699 // marker until we can recreate that Code object during deferred |
676 // materialization to maintain the invariant that Dart frames always have | 700 // materialization to maintain the invariant that Dart frames always have |
677 // a pc marker. | 701 // a pc marker. |
678 *reinterpret_cast<RawObject**>(dest_addr) = | 702 *reinterpret_cast<RawObject**>(dest_addr) = |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
722 class DeoptCallerFpInstr : public DeoptInstr { | 746 class DeoptCallerFpInstr : public DeoptInstr { |
723 public: | 747 public: |
724 DeoptCallerFpInstr() {} | 748 DeoptCallerFpInstr() {} |
725 | 749 |
726 virtual intptr_t source_index() const { return 0; } | 750 virtual intptr_t source_index() const { return 0; } |
727 virtual DeoptInstr::Kind kind() const { return kCallerFp; } | 751 virtual DeoptInstr::Kind kind() const { return kCallerFp; } |
728 | 752 |
729 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 753 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
730 *dest_addr = deopt_context->GetCallerFp(); | 754 *dest_addr = deopt_context->GetCallerFp(); |
731 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( | 755 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( |
732 dest_addr - (kSavedCallerFpSlotFromFp * kWordSize))); | 756 dest_addr - kSavedCallerFpSlotFromFp)); |
zra
2016/05/19 16:24:27
Oof. How was this working?
Vyacheslav Egorov (Google)
2016/05/20 12:11:47
kSavedCallerFpSlotFromFp is 0 on all architectures
| |
733 } | 757 } |
734 | 758 |
735 private: | 759 private: |
736 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); | 760 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); |
737 }; | 761 }; |
738 | 762 |
739 | 763 |
740 // Deoptimization instruction copying the caller saved PP from optimized frame. | 764 // Deoptimization instruction copying the caller saved PP from optimized frame. |
741 class DeoptCallerPpInstr : public DeoptInstr { | 765 class DeoptCallerPpInstr : public DeoptInstr { |
742 public: | 766 public: |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1319 Smi* offset, | 1343 Smi* offset, |
1320 TypedData* info, | 1344 TypedData* info, |
1321 Smi* reason) { | 1345 Smi* reason) { |
1322 intptr_t i = index * kEntrySize; | 1346 intptr_t i = index * kEntrySize; |
1323 *offset ^= table.At(i); | 1347 *offset ^= table.At(i); |
1324 *info ^= table.At(i + 1); | 1348 *info ^= table.At(i + 1); |
1325 *reason ^= table.At(i + 2); | 1349 *reason ^= table.At(i + 2); |
1326 } | 1350 } |
1327 | 1351 |
1328 } // namespace dart | 1352 } // namespace dart |
OLD | NEW |