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 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 } | 883 } |
884 | 884 |
885 private: | 885 private: |
886 const intptr_t slot_; | 886 const intptr_t slot_; |
887 const Register reg_; | 887 const Register reg_; |
888 const bool flip_; | 888 const bool flip_; |
889 DISALLOW_COPY_AND_ASSIGN(DeoptMintStackSlotRegisterInstr); | 889 DISALLOW_COPY_AND_ASSIGN(DeoptMintStackSlotRegisterInstr); |
890 }; | 890 }; |
891 | 891 |
892 | 892 |
| 893 class DeoptMint32StackSlotInstr : public DeoptInstr { |
| 894 public: |
| 895 explicit DeoptMint32StackSlotInstr(intptr_t source_index) |
| 896 : stack_slot_index_(source_index) { |
| 897 ASSERT(stack_slot_index_ >= 0); |
| 898 } |
| 899 |
| 900 virtual intptr_t source_index() const { return stack_slot_index_; } |
| 901 virtual DeoptInstr::Kind kind() const { return kMint32StackSlot; } |
| 902 |
| 903 virtual const char* ToCString() const { |
| 904 return Isolate::Current()->current_zone()->PrintToString( |
| 905 "(32-bit) int64 s%" Pd "", stack_slot_index_); |
| 906 } |
| 907 |
| 908 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 909 intptr_t source_index = |
| 910 deopt_context->source_frame_size() - stack_slot_index_ - 1; |
| 911 intptr_t* source_addr = |
| 912 deopt_context->GetSourceFrameAddressAt(source_index); |
| 913 int64_t value = Utils::LowHighTo64Bits(*source_addr, 0); |
| 914 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
| 915 if (Smi::IsValid64(value)) { |
| 916 *dest_addr = reinterpret_cast<intptr_t>( |
| 917 Smi::New(static_cast<intptr_t>(value))); |
| 918 } else { |
| 919 deopt_context->DeferMintMaterialization( |
| 920 value, reinterpret_cast<RawMint**>(dest_addr)); |
| 921 } |
| 922 } |
| 923 |
| 924 private: |
| 925 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 926 |
| 927 DISALLOW_COPY_AND_ASSIGN(DeoptMint32StackSlotInstr); |
| 928 }; |
| 929 |
| 930 |
| 931 class DeoptMint32RegisterInstr: public DeoptInstr { |
| 932 public: |
| 933 explicit DeoptMint32RegisterInstr(intptr_t reg_as_int) |
| 934 : reg_(static_cast<Register>(reg_as_int)) {} |
| 935 |
| 936 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
| 937 virtual DeoptInstr::Kind kind() const { return kMint32Register; } |
| 938 |
| 939 virtual const char* ToCString() const { |
| 940 return Isolate::Current()->current_zone()->PrintToString( |
| 941 "(32-bit) int64 register %s", Assembler::RegisterName(reg_)); |
| 942 } |
| 943 |
| 944 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 945 int32_t lo = deopt_context->RegisterValue(reg_); |
| 946 int64_t value = Utils::LowHighTo64Bits(lo, 0); |
| 947 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
| 948 if (Smi::IsValid64(value)) { |
| 949 *dest_addr = reinterpret_cast<intptr_t>( |
| 950 Smi::New(static_cast<intptr_t>(value))); |
| 951 } else { |
| 952 deopt_context->DeferMintMaterialization( |
| 953 value, reinterpret_cast<RawMint**>(dest_addr)); |
| 954 } |
| 955 } |
| 956 |
| 957 private: |
| 958 const Register reg_; |
| 959 |
| 960 DISALLOW_COPY_AND_ASSIGN(DeoptMint32RegisterInstr); |
| 961 }; |
| 962 |
| 963 |
893 // Deoptimization instruction moving an XMM register. | 964 // Deoptimization instruction moving an XMM register. |
894 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { | 965 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
895 public: | 966 public: |
896 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) | 967 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) |
897 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 968 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
898 | 969 |
899 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } | 970 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
900 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } | 971 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
901 | 972 |
902 virtual const char* ToCString() const { | 973 virtual const char* ToCString() const { |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1292 return new DeoptMintStackSlotPairInstr(lo_slot, hi_slot); | 1363 return new DeoptMintStackSlotPairInstr(lo_slot, hi_slot); |
1293 } | 1364 } |
1294 case kMintStackSlotRegister: { | 1365 case kMintStackSlotRegister: { |
1295 intptr_t slot = | 1366 intptr_t slot = |
1296 DeoptMintStackSlotRegisterInstr::Slot::decode(source_index); | 1367 DeoptMintStackSlotRegisterInstr::Slot::decode(source_index); |
1297 intptr_t reg_as_int = | 1368 intptr_t reg_as_int = |
1298 DeoptMintStackSlotRegisterInstr::Reg::decode(source_index); | 1369 DeoptMintStackSlotRegisterInstr::Reg::decode(source_index); |
1299 bool flip = DeoptMintStackSlotRegisterInstr::Flip::decode(source_index); | 1370 bool flip = DeoptMintStackSlotRegisterInstr::Flip::decode(source_index); |
1300 return new DeoptMintStackSlotRegisterInstr(slot, reg_as_int, flip); | 1371 return new DeoptMintStackSlotRegisterInstr(slot, reg_as_int, flip); |
1301 } | 1372 } |
| 1373 case kMint32Register: { |
| 1374 return new DeoptMint32RegisterInstr(source_index); |
| 1375 } |
| 1376 case kMint32StackSlot: { |
| 1377 return new DeoptMint32StackSlotInstr(source_index); |
| 1378 } |
1302 case kFloat32x4FpuRegister: | 1379 case kFloat32x4FpuRegister: |
1303 return new DeoptFloat32x4FpuRegisterInstr(source_index); | 1380 return new DeoptFloat32x4FpuRegisterInstr(source_index); |
1304 case kFloat64x2FpuRegister: | 1381 case kFloat64x2FpuRegister: |
1305 return new DeoptFloat64x2FpuRegisterInstr(source_index); | 1382 return new DeoptFloat64x2FpuRegisterInstr(source_index); |
1306 case kInt32x4FpuRegister: | 1383 case kInt32x4FpuRegister: |
1307 return new DeoptInt32x4FpuRegisterInstr(source_index); | 1384 return new DeoptInt32x4FpuRegisterInstr(source_index); |
1308 case kPcMarker: return new DeoptPcMarkerInstr(source_index); | 1385 case kPcMarker: return new DeoptPcMarkerInstr(source_index); |
1309 case kPp: return new DeoptPpInstr(source_index); | 1386 case kPp: return new DeoptPpInstr(source_index); |
1310 case kCallerFp: return new DeoptCallerFpInstr(); | 1387 case kCallerFp: return new DeoptCallerFpInstr(); |
1311 case kCallerPp: return new DeoptCallerPpInstr(); | 1388 case kCallerPp: return new DeoptCallerPpInstr(); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 | 1497 |
1421 | 1498 |
1422 void DeoptInfoBuilder::AddCopy(Value* value, | 1499 void DeoptInfoBuilder::AddCopy(Value* value, |
1423 const Location& source_loc, | 1500 const Location& source_loc, |
1424 const intptr_t dest_index) { | 1501 const intptr_t dest_index) { |
1425 DeoptInstr* deopt_instr = NULL; | 1502 DeoptInstr* deopt_instr = NULL; |
1426 if (source_loc.IsConstant()) { | 1503 if (source_loc.IsConstant()) { |
1427 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); | 1504 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); |
1428 deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index); | 1505 deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index); |
1429 } else if (source_loc.IsRegister()) { | 1506 } else if (source_loc.IsRegister()) { |
1430 ASSERT(value->definition()->representation() == kTagged); | 1507 if (value->definition()->representation() == kTagged) { |
1431 deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg()); | 1508 deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg()); |
| 1509 } else { |
| 1510 // TODO(johnmccutchan): Add a DeoptInt32RegisterInstr. |
| 1511 ASSERT(value->definition()->representation() == kUnboxedMint32); |
| 1512 deopt_instr = new(isolate()) DeoptMint32RegisterInstr(source_loc.reg()); |
| 1513 } |
1432 } else if (source_loc.IsFpuRegister()) { | 1514 } else if (source_loc.IsFpuRegister()) { |
1433 if (value->definition()->representation() == kUnboxedDouble) { | 1515 if (value->definition()->representation() == kUnboxedDouble) { |
1434 deopt_instr = new(isolate()) DeoptFpuRegisterInstr(source_loc.fpu_reg()); | 1516 deopt_instr = new(isolate()) DeoptFpuRegisterInstr(source_loc.fpu_reg()); |
1435 } else if (value->definition()->representation() == kUnboxedFloat32x4) { | 1517 } else if (value->definition()->representation() == kUnboxedFloat32x4) { |
1436 deopt_instr = | 1518 deopt_instr = |
1437 new(isolate()) DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1519 new(isolate()) DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1438 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1520 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1439 deopt_instr = | 1521 deopt_instr = |
1440 new(isolate()) DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1522 new(isolate()) DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1441 } else { | 1523 } else { |
1442 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); | 1524 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); |
1443 deopt_instr = | 1525 deopt_instr = |
1444 new(isolate()) DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); | 1526 new(isolate()) DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); |
1445 } | 1527 } |
1446 } else if (source_loc.IsStackSlot()) { | 1528 } else if (source_loc.IsStackSlot()) { |
1447 ASSERT(value->definition()->representation() == kTagged); | 1529 // TODO(johnmccutchan): Add a DeoptInt32RegisterInstr. |
1448 intptr_t source_index = CalculateStackIndex(source_loc); | 1530 if (value->definition()->representation() == kTagged) { |
1449 deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index); | 1531 intptr_t source_index = CalculateStackIndex(source_loc); |
| 1532 deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index); |
| 1533 } else { |
| 1534 ASSERT(value->definition()->representation() == kUnboxedMint32); |
| 1535 intptr_t source_index = CalculateStackIndex(source_loc); |
| 1536 deopt_instr = new(isolate()) DeoptMint32StackSlotInstr(source_index); |
| 1537 } |
1450 } else if (source_loc.IsDoubleStackSlot()) { | 1538 } else if (source_loc.IsDoubleStackSlot()) { |
1451 ASSERT(value->definition()->representation() == kUnboxedDouble); | 1539 ASSERT(value->definition()->representation() == kUnboxedDouble); |
1452 intptr_t source_index = CalculateStackIndex(source_loc); | 1540 intptr_t source_index = CalculateStackIndex(source_loc); |
1453 deopt_instr = new(isolate()) DeoptDoubleStackSlotInstr(source_index); | 1541 deopt_instr = new(isolate()) DeoptDoubleStackSlotInstr(source_index); |
1454 } else if (source_loc.IsQuadStackSlot()) { | 1542 } else if (source_loc.IsQuadStackSlot()) { |
1455 intptr_t source_index = CalculateStackIndex(source_loc); | 1543 intptr_t source_index = CalculateStackIndex(source_loc); |
1456 if (value->definition()->representation() == kUnboxedFloat32x4) { | 1544 if (value->definition()->representation() == kUnboxedFloat32x4) { |
1457 deopt_instr = new(isolate()) DeoptFloat32x4StackSlotInstr(source_index); | 1545 deopt_instr = new(isolate()) DeoptFloat32x4StackSlotInstr(source_index); |
1458 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1546 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1459 deopt_instr = new(isolate()) DeoptInt32x4StackSlotInstr(source_index); | 1547 deopt_instr = new(isolate()) DeoptInt32x4StackSlotInstr(source_index); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 Smi* offset, | 1755 Smi* offset, |
1668 DeoptInfo* info, | 1756 DeoptInfo* info, |
1669 Smi* reason) { | 1757 Smi* reason) { |
1670 intptr_t i = index * kEntrySize; | 1758 intptr_t i = index * kEntrySize; |
1671 *offset ^= table.At(i); | 1759 *offset ^= table.At(i); |
1672 *info ^= table.At(i + 1); | 1760 *info ^= table.At(i + 1); |
1673 *reason ^= table.At(i + 2); | 1761 *reason ^= table.At(i + 2); |
1674 } | 1762 } |
1675 | 1763 |
1676 } // namespace dart | 1764 } // namespace dart |
OLD | NEW |