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/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 private: | 166 private: |
167 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 167 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
168 | 168 |
169 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); | 169 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); |
170 }; | 170 }; |
171 | 171 |
172 | 172 |
| 173 class DeoptFloat32x4StackSlotInstr : public DeoptInstr { |
| 174 public: |
| 175 explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index) |
| 176 : stack_slot_index_(from_index) { |
| 177 ASSERT(stack_slot_index_ >= 0); |
| 178 } |
| 179 |
| 180 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 181 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; } |
| 182 |
| 183 virtual const char* ToCString() const { |
| 184 const char* format = "f32x4s%"Pd""; |
| 185 intptr_t len = OS::SNPrint(NULL, 0, format, stack_slot_index_); |
| 186 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 187 OS::SNPrint(chars, len + 1, format, stack_slot_index_); |
| 188 return chars; |
| 189 } |
| 190 |
| 191 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 192 intptr_t from_index = |
| 193 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 194 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( |
| 195 deopt_context->GetFromFrameAddressAt(from_index)); |
| 196 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 197 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 198 Isolate::Current()->DeferFloat32x4Materialization( |
| 199 *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr)); |
| 200 } |
| 201 |
| 202 private: |
| 203 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 204 |
| 205 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); |
| 206 }; |
| 207 |
| 208 |
| 209 class DeoptUint32x4StackSlotInstr : public DeoptInstr { |
| 210 public: |
| 211 explicit DeoptUint32x4StackSlotInstr(intptr_t from_index) |
| 212 : stack_slot_index_(from_index) { |
| 213 ASSERT(stack_slot_index_ >= 0); |
| 214 } |
| 215 |
| 216 virtual intptr_t from_index() const { return stack_slot_index_; } |
| 217 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } |
| 218 |
| 219 virtual const char* ToCString() const { |
| 220 const char* format = "ui32x4s%"Pd""; |
| 221 intptr_t len = OS::SNPrint(NULL, 0, format, stack_slot_index_); |
| 222 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 223 OS::SNPrint(chars, len + 1, format, stack_slot_index_); |
| 224 return chars; |
| 225 } |
| 226 |
| 227 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 228 intptr_t from_index = |
| 229 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| 230 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( |
| 231 deopt_context->GetFromFrameAddressAt(from_index)); |
| 232 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 233 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 234 Isolate::Current()->DeferUint32x4Materialization( |
| 235 *from_addr, reinterpret_cast<RawUint32x4**>(to_addr)); |
| 236 } |
| 237 |
| 238 private: |
| 239 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 240 |
| 241 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); |
| 242 }; |
| 243 |
| 244 |
173 // Deoptimization instruction creating return address using function and | 245 // Deoptimization instruction creating return address using function and |
174 // deopt-id stored at 'object_table_index'. Uses the deopt-after | 246 // deopt-id stored at 'object_table_index'. Uses the deopt-after |
175 // continuation point. | 247 // continuation point. |
176 class DeoptRetAfterAddressInstr : public DeoptInstr { | 248 class DeoptRetAfterAddressInstr : public DeoptInstr { |
177 public: | 249 public: |
178 DeoptRetAfterAddressInstr(intptr_t object_table_index, intptr_t deopt_id) | 250 DeoptRetAfterAddressInstr(intptr_t object_table_index, intptr_t deopt_id) |
179 : object_table_index_(object_table_index), deopt_id_(deopt_id) { | 251 : object_table_index_(object_table_index), deopt_id_(deopt_id) { |
180 ASSERT(object_table_index >= 0); | 252 ASSERT(object_table_index >= 0); |
181 ASSERT(deopt_id >= 0); | 253 ASSERT(deopt_id >= 0); |
182 } | 254 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } | 478 } |
407 } | 479 } |
408 | 480 |
409 private: | 481 private: |
410 const FpuRegister reg_; | 482 const FpuRegister reg_; |
411 | 483 |
412 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); | 484 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); |
413 }; | 485 }; |
414 | 486 |
415 | 487 |
| 488 // Deoptimization instruction moving an XMM register. |
| 489 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
| 490 public: |
| 491 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) |
| 492 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
| 493 |
| 494 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 495 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
| 496 |
| 497 virtual const char* ToCString() const { |
| 498 const char* format = "%s(f32x4)"; |
| 499 intptr_t len = |
| 500 OS::SNPrint(NULL, 0, format, Assembler::FpuRegisterName(reg_)); |
| 501 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 502 OS::SNPrint(chars, len + 1, format, Assembler::FpuRegisterName(reg_)); |
| 503 return chars; |
| 504 } |
| 505 |
| 506 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 507 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
| 508 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 509 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 510 Isolate::Current()->DeferFloat32x4Materialization( |
| 511 value, reinterpret_cast<RawFloat32x4**>(to_addr)); |
| 512 } |
| 513 |
| 514 private: |
| 515 const FpuRegister reg_; |
| 516 |
| 517 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); |
| 518 }; |
| 519 |
| 520 |
| 521 // Deoptimization instruction moving an XMM register. |
| 522 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { |
| 523 public: |
| 524 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) |
| 525 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
| 526 |
| 527 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| 528 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
| 529 |
| 530 virtual const char* ToCString() const { |
| 531 const char* format = "%s(f32x4)"; |
| 532 intptr_t len = |
| 533 OS::SNPrint(NULL, 0, format, Assembler::FpuRegisterName(reg_)); |
| 534 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 535 OS::SNPrint(chars, len + 1, format, Assembler::FpuRegisterName(reg_)); |
| 536 return chars; |
| 537 } |
| 538 |
| 539 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 540 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
| 541 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 542 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| 543 Isolate::Current()->DeferUint32x4Materialization( |
| 544 value, reinterpret_cast<RawUint32x4**>(to_addr)); |
| 545 } |
| 546 |
| 547 private: |
| 548 const FpuRegister reg_; |
| 549 |
| 550 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); |
| 551 }; |
| 552 |
| 553 |
416 // Deoptimization instruction creating a PC marker for the code of | 554 // Deoptimization instruction creating a PC marker for the code of |
417 // function at 'object_table_index'. | 555 // function at 'object_table_index'. |
418 class DeoptPcMarkerInstr : public DeoptInstr { | 556 class DeoptPcMarkerInstr : public DeoptInstr { |
419 public: | 557 public: |
420 explicit DeoptPcMarkerInstr(intptr_t object_table_index) | 558 explicit DeoptPcMarkerInstr(intptr_t object_table_index) |
421 : object_table_index_(object_table_index) { | 559 : object_table_index_(object_table_index) { |
422 ASSERT(object_table_index >= 0); | 560 ASSERT(object_table_index >= 0); |
423 } | 561 } |
424 | 562 |
425 virtual intptr_t from_index() const { return object_table_index_; } | 563 virtual intptr_t from_index() const { return object_table_index_; } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 return code.GetDeoptAfterPcAtDeoptId(ret_after_instr->deopt_id()); | 722 return code.GetDeoptAfterPcAtDeoptId(ret_after_instr->deopt_id()); |
585 } | 723 } |
586 | 724 |
587 | 725 |
588 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { | 726 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { |
589 Kind kind = static_cast<Kind>(kind_as_int); | 727 Kind kind = static_cast<Kind>(kind_as_int); |
590 switch (kind) { | 728 switch (kind) { |
591 case kStackSlot: return new DeoptStackSlotInstr(from_index); | 729 case kStackSlot: return new DeoptStackSlotInstr(from_index); |
592 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); | 730 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); |
593 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); | 731 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); |
| 732 case kFloat32x4StackSlot: |
| 733 return new DeoptFloat32x4StackSlotInstr(from_index); |
| 734 case kUint32x4StackSlot: |
| 735 return new DeoptUint32x4StackSlotInstr(from_index); |
594 case kRetAfterAddress: return new DeoptRetAfterAddressInstr(from_index); | 736 case kRetAfterAddress: return new DeoptRetAfterAddressInstr(from_index); |
595 case kRetBeforeAddress: return new DeoptRetBeforeAddressInstr(from_index); | 737 case kRetBeforeAddress: return new DeoptRetBeforeAddressInstr(from_index); |
596 case kConstant: return new DeoptConstantInstr(from_index); | 738 case kConstant: return new DeoptConstantInstr(from_index); |
597 case kRegister: return new DeoptRegisterInstr(from_index); | 739 case kRegister: return new DeoptRegisterInstr(from_index); |
598 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index); | 740 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index); |
599 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index); | 741 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index); |
| 742 case kFloat32x4FpuRegister: |
| 743 return new DeoptFloat32x4FpuRegisterInstr(from_index); |
| 744 case kUint32x4FpuRegister: |
| 745 return new DeoptUint32x4FpuRegisterInstr(from_index); |
600 case kPcMarker: return new DeoptPcMarkerInstr(from_index); | 746 case kPcMarker: return new DeoptPcMarkerInstr(from_index); |
601 case kCallerFp: return new DeoptCallerFpInstr(); | 747 case kCallerFp: return new DeoptCallerFpInstr(); |
602 case kCallerPc: return new DeoptCallerPcInstr(); | 748 case kCallerPc: return new DeoptCallerPcInstr(); |
603 case kSuffix: return new DeoptSuffixInstr(from_index); | 749 case kSuffix: return new DeoptSuffixInstr(from_index); |
604 } | 750 } |
605 UNREACHABLE(); | 751 UNREACHABLE(); |
606 return NULL; | 752 return NULL; |
607 } | 753 } |
608 | 754 |
609 | 755 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 if (from_loc.representation() == kUnboxedDouble) { | 865 if (from_loc.representation() == kUnboxedDouble) { |
720 deopt_instr = new DeoptDoubleStackSlotInstr(from_index); | 866 deopt_instr = new DeoptDoubleStackSlotInstr(from_index); |
721 } else { | 867 } else { |
722 ASSERT(from_loc.representation() == kUnboxedMint); | 868 ASSERT(from_loc.representation() == kUnboxedMint); |
723 deopt_instr = new DeoptInt64StackSlotInstr(from_index); | 869 deopt_instr = new DeoptInt64StackSlotInstr(from_index); |
724 } | 870 } |
725 } else { | 871 } else { |
726 UNREACHABLE(); | 872 UNREACHABLE(); |
727 } | 873 } |
728 ASSERT(to_index == instructions_.length()); | 874 ASSERT(to_index == instructions_.length()); |
| 875 ASSERT(deopt_instr != NULL); |
729 instructions_.Add(deopt_instr); | 876 instructions_.Add(deopt_instr); |
730 } | 877 } |
731 | 878 |
732 | 879 |
733 void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) { | 880 void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) { |
734 ASSERT(to_index == instructions_.length()); | 881 ASSERT(to_index == instructions_.length()); |
735 instructions_.Add(new DeoptCallerFpInstr()); | 882 instructions_.Add(new DeoptCallerFpInstr()); |
736 } | 883 } |
737 | 884 |
738 | 885 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 Smi* offset, | 962 Smi* offset, |
816 DeoptInfo* info, | 963 DeoptInfo* info, |
817 Smi* reason) { | 964 Smi* reason) { |
818 intptr_t i = index * kEntrySize; | 965 intptr_t i = index * kEntrySize; |
819 *offset ^= table.At(i); | 966 *offset ^= table.At(i); |
820 *info ^= table.At(i + 1); | 967 *info ^= table.At(i + 1); |
821 *reason ^= table.At(i + 2); | 968 *reason ^= table.At(i + 2); |
822 } | 969 } |
823 | 970 |
824 } // namespace dart | 971 } // namespace dart |
OLD | NEW |