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 DeoptUint32RegisterInstr: public DeoptInstr { |
| 894 public: |
| 895 explicit DeoptUint32RegisterInstr(intptr_t reg_as_int) |
| 896 : reg_(static_cast<Register>(reg_as_int)) {} |
| 897 |
| 898 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
| 899 virtual DeoptInstr::Kind kind() const { return kUint32Register; } |
| 900 |
| 901 virtual const char* ToCString() const { |
| 902 return Isolate::Current()->current_zone()->PrintToString( |
| 903 "uint32 %s", Assembler::RegisterName(reg_)); |
| 904 } |
| 905 |
| 906 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 907 uint32_t low = static_cast<uint32_t>(deopt_context->RegisterValue(reg_)); |
| 908 int64_t value = Utils::LowHighTo64Bits(low, 0); |
| 909 if (Smi::IsValid(value)) { |
| 910 *dest_addr = reinterpret_cast<intptr_t>( |
| 911 Smi::New(static_cast<intptr_t>(value))); |
| 912 } else { |
| 913 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
| 914 deopt_context->DeferMintMaterialization( |
| 915 value, reinterpret_cast<RawMint**>(dest_addr)); |
| 916 } |
| 917 } |
| 918 |
| 919 private: |
| 920 const Register reg_; |
| 921 |
| 922 DISALLOW_COPY_AND_ASSIGN(DeoptUint32RegisterInstr); |
| 923 }; |
| 924 |
| 925 |
| 926 class DeoptUint32StackSlotInstr : public DeoptInstr { |
| 927 public: |
| 928 explicit DeoptUint32StackSlotInstr(intptr_t source_index) |
| 929 : stack_slot_index_(source_index) { |
| 930 ASSERT(stack_slot_index_ >= 0); |
| 931 } |
| 932 |
| 933 virtual intptr_t source_index() const { return stack_slot_index_; } |
| 934 virtual DeoptInstr::Kind kind() const { return kUint32StackSlot; } |
| 935 |
| 936 virtual const char* ToCString() const { |
| 937 return Isolate::Current()->current_zone()->PrintToString( |
| 938 "uint32 s%" Pd "", stack_slot_index_); |
| 939 } |
| 940 |
| 941 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 942 intptr_t source_index = |
| 943 deopt_context->source_frame_size() - stack_slot_index_ - 1; |
| 944 uint32_t* source_addr = reinterpret_cast<uint32_t*>( |
| 945 deopt_context->GetSourceFrameAddressAt(source_index)); |
| 946 int64_t value = Utils::LowHighTo64Bits(*source_addr, 0); |
| 947 if (Smi::IsValid(value)) { |
| 948 *dest_addr = reinterpret_cast<intptr_t>( |
| 949 Smi::New(static_cast<intptr_t>(value))); |
| 950 } else { |
| 951 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
| 952 deopt_context->DeferMintMaterialization( |
| 953 value, reinterpret_cast<RawMint**>(dest_addr)); |
| 954 } |
| 955 } |
| 956 |
| 957 private: |
| 958 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| 959 |
| 960 DISALLOW_COPY_AND_ASSIGN(DeoptUint32StackSlotInstr); |
| 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 kUint32Register: |
| 1374 return new DeoptUint32RegisterInstr(source_index); |
| 1375 case kUint32StackSlot: |
| 1376 return new DeoptUint32StackSlotInstr(source_index); |
1302 case kFloat32x4FpuRegister: | 1377 case kFloat32x4FpuRegister: |
1303 return new DeoptFloat32x4FpuRegisterInstr(source_index); | 1378 return new DeoptFloat32x4FpuRegisterInstr(source_index); |
1304 case kFloat64x2FpuRegister: | 1379 case kFloat64x2FpuRegister: |
1305 return new DeoptFloat64x2FpuRegisterInstr(source_index); | 1380 return new DeoptFloat64x2FpuRegisterInstr(source_index); |
1306 case kInt32x4FpuRegister: | 1381 case kInt32x4FpuRegister: |
1307 return new DeoptInt32x4FpuRegisterInstr(source_index); | 1382 return new DeoptInt32x4FpuRegisterInstr(source_index); |
1308 case kPcMarker: return new DeoptPcMarkerInstr(source_index); | 1383 case kPcMarker: return new DeoptPcMarkerInstr(source_index); |
1309 case kPp: return new DeoptPpInstr(source_index); | 1384 case kPp: return new DeoptPpInstr(source_index); |
1310 case kCallerFp: return new DeoptCallerFpInstr(); | 1385 case kCallerFp: return new DeoptCallerFpInstr(); |
1311 case kCallerPp: return new DeoptCallerPpInstr(); | 1386 case kCallerPp: return new DeoptCallerPpInstr(); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 | 1495 |
1421 | 1496 |
1422 void DeoptInfoBuilder::AddCopy(Value* value, | 1497 void DeoptInfoBuilder::AddCopy(Value* value, |
1423 const Location& source_loc, | 1498 const Location& source_loc, |
1424 const intptr_t dest_index) { | 1499 const intptr_t dest_index) { |
1425 DeoptInstr* deopt_instr = NULL; | 1500 DeoptInstr* deopt_instr = NULL; |
1426 if (source_loc.IsConstant()) { | 1501 if (source_loc.IsConstant()) { |
1427 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); | 1502 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); |
1428 deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index); | 1503 deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index); |
1429 } else if (source_loc.IsRegister()) { | 1504 } else if (source_loc.IsRegister()) { |
1430 ASSERT(value->definition()->representation() == kTagged); | 1505 if (value->definition()->representation() == kUnboxedUint32) { |
1431 deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg()); | 1506 deopt_instr = new(isolate()) DeoptUint32RegisterInstr(source_loc.reg()); |
| 1507 } else { |
| 1508 ASSERT(value->definition()->representation() == kTagged); |
| 1509 deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg()); |
| 1510 } |
1432 } else if (source_loc.IsFpuRegister()) { | 1511 } else if (source_loc.IsFpuRegister()) { |
1433 if (value->definition()->representation() == kUnboxedDouble) { | 1512 if (value->definition()->representation() == kUnboxedDouble) { |
1434 deopt_instr = new(isolate()) DeoptFpuRegisterInstr(source_loc.fpu_reg()); | 1513 deopt_instr = new(isolate()) DeoptFpuRegisterInstr(source_loc.fpu_reg()); |
1435 } else if (value->definition()->representation() == kUnboxedFloat32x4) { | 1514 } else if (value->definition()->representation() == kUnboxedFloat32x4) { |
1436 deopt_instr = | 1515 deopt_instr = |
1437 new(isolate()) DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1516 new(isolate()) DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1438 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1517 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1439 deopt_instr = | 1518 deopt_instr = |
1440 new(isolate()) DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); | 1519 new(isolate()) DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg()); |
1441 } else { | 1520 } else { |
1442 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); | 1521 ASSERT(value->definition()->representation() == kUnboxedFloat64x2); |
1443 deopt_instr = | 1522 deopt_instr = |
1444 new(isolate()) DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); | 1523 new(isolate()) DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); |
1445 } | 1524 } |
1446 } else if (source_loc.IsStackSlot()) { | 1525 } else if (source_loc.IsStackSlot()) { |
1447 ASSERT(value->definition()->representation() == kTagged); | 1526 if (value->definition()->representation() == kUnboxedUint32) { |
1448 intptr_t source_index = CalculateStackIndex(source_loc); | 1527 intptr_t source_index = CalculateStackIndex(source_loc); |
1449 deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index); | 1528 deopt_instr = new(isolate()) DeoptUint32StackSlotInstr(source_index); |
| 1529 } else { |
| 1530 ASSERT(value->definition()->representation() == kTagged); |
| 1531 intptr_t source_index = CalculateStackIndex(source_loc); |
| 1532 deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index); |
| 1533 } |
1450 } else if (source_loc.IsDoubleStackSlot()) { | 1534 } else if (source_loc.IsDoubleStackSlot()) { |
1451 ASSERT(value->definition()->representation() == kUnboxedDouble); | 1535 ASSERT(value->definition()->representation() == kUnboxedDouble); |
1452 intptr_t source_index = CalculateStackIndex(source_loc); | 1536 intptr_t source_index = CalculateStackIndex(source_loc); |
1453 deopt_instr = new(isolate()) DeoptDoubleStackSlotInstr(source_index); | 1537 deopt_instr = new(isolate()) DeoptDoubleStackSlotInstr(source_index); |
1454 } else if (source_loc.IsQuadStackSlot()) { | 1538 } else if (source_loc.IsQuadStackSlot()) { |
1455 intptr_t source_index = CalculateStackIndex(source_loc); | 1539 intptr_t source_index = CalculateStackIndex(source_loc); |
1456 if (value->definition()->representation() == kUnboxedFloat32x4) { | 1540 if (value->definition()->representation() == kUnboxedFloat32x4) { |
1457 deopt_instr = new(isolate()) DeoptFloat32x4StackSlotInstr(source_index); | 1541 deopt_instr = new(isolate()) DeoptFloat32x4StackSlotInstr(source_index); |
1458 } else if (value->definition()->representation() == kUnboxedInt32x4) { | 1542 } else if (value->definition()->representation() == kUnboxedInt32x4) { |
1459 deopt_instr = new(isolate()) DeoptInt32x4StackSlotInstr(source_index); | 1543 deopt_instr = new(isolate()) DeoptInt32x4StackSlotInstr(source_index); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 Smi* offset, | 1751 Smi* offset, |
1668 DeoptInfo* info, | 1752 DeoptInfo* info, |
1669 Smi* reason) { | 1753 Smi* reason) { |
1670 intptr_t i = index * kEntrySize; | 1754 intptr_t i = index * kEntrySize; |
1671 *offset ^= table.At(i); | 1755 *offset ^= table.At(i); |
1672 *info ^= table.At(i + 1); | 1756 *info ^= table.At(i + 1); |
1673 *reason ^= table.At(i + 2); | 1757 *reason ^= table.At(i + 2); |
1674 } | 1758 } |
1675 | 1759 |
1676 } // namespace dart | 1760 } // namespace dart |
OLD | NEW |