Chromium Code Reviews| 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 |