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/disassembler.h" | 10 #include "vm/disassembler.h" |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 intptr_t index, | 1372 intptr_t index, |
1373 Smi* offset, | 1373 Smi* offset, |
1374 TypedData* info, | 1374 TypedData* info, |
1375 Smi* reason) { | 1375 Smi* reason) { |
1376 intptr_t i = index * kEntrySize; | 1376 intptr_t i = index * kEntrySize; |
1377 *offset ^= table.At(i); | 1377 *offset ^= table.At(i); |
1378 *info ^= table.At(i + 1); | 1378 *info ^= table.At(i + 1); |
1379 *reason ^= table.At(i + 2); | 1379 *reason ^= table.At(i + 2); |
1380 } | 1380 } |
1381 | 1381 |
| 1382 |
| 1383 intptr_t DeoptInfo::FrameSize(const TypedData& packed) { |
| 1384 NoSafepointScope no_safepoint; |
| 1385 typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader; |
| 1386 ReadStream read_stream(reinterpret_cast<uint8_t*>(packed.DataAddr(0)), |
| 1387 packed.LengthInBytes()); |
| 1388 return Reader::Read(&read_stream); |
| 1389 } |
| 1390 |
| 1391 |
| 1392 intptr_t DeoptInfo::NumMaterializations( |
| 1393 const GrowableArray<DeoptInstr*>& unpacked) { |
| 1394 intptr_t num = 0; |
| 1395 while (unpacked[num]->kind() == DeoptInstr::kMaterializeObject) { |
| 1396 num++; |
| 1397 } |
| 1398 return num; |
| 1399 } |
| 1400 |
| 1401 |
| 1402 void DeoptInfo::UnpackInto(const Array& table, |
| 1403 const TypedData& packed, |
| 1404 GrowableArray<DeoptInstr*>* unpacked, |
| 1405 intptr_t length) { |
| 1406 NoSafepointScope no_safepoint; |
| 1407 typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader; |
| 1408 ReadStream read_stream(reinterpret_cast<uint8_t*>(packed.DataAddr(0)), |
| 1409 packed.LengthInBytes()); |
| 1410 const intptr_t frame_size = Reader::Read(&read_stream); // Skip frame size. |
| 1411 USE(frame_size); |
| 1412 |
| 1413 const intptr_t suffix_length = Reader::Read(&read_stream); |
| 1414 if (suffix_length != 0) { |
| 1415 ASSERT(suffix_length > 1); |
| 1416 const intptr_t info_number = Reader::Read(&read_stream); |
| 1417 |
| 1418 TypedData& suffix = TypedData::Handle(); |
| 1419 Smi& offset = Smi::Handle(); |
| 1420 Smi& reason_and_flags = Smi::Handle(); |
| 1421 DeoptTable::GetEntry(table, info_number, &offset, &suffix, |
| 1422 &reason_and_flags); |
| 1423 UnpackInto(table, suffix, unpacked, suffix_length); |
| 1424 } |
| 1425 |
| 1426 while ((read_stream.PendingBytes() > 0) && (unpacked->length() < length)) { |
| 1427 const intptr_t instruction = Reader::Read(&read_stream); |
| 1428 const intptr_t from_index = Reader::Read(&read_stream); |
| 1429 unpacked->Add(DeoptInstr::Create(instruction, from_index)); |
| 1430 } |
| 1431 } |
| 1432 |
| 1433 |
| 1434 void DeoptInfo::Unpack(const Array& table, |
| 1435 const TypedData& packed, |
| 1436 GrowableArray<DeoptInstr*>* unpacked) { |
| 1437 ASSERT(unpacked->is_empty()); |
| 1438 |
| 1439 // Pass kMaxInt32 as the length to unpack all instructions from the |
| 1440 // packed stream. |
| 1441 UnpackInto(table, packed, unpacked, kMaxInt32); |
| 1442 |
| 1443 unpacked->Reverse(); |
| 1444 } |
| 1445 |
| 1446 |
| 1447 const char* DeoptInfo::ToCString(const Array& deopt_table, |
| 1448 const TypedData& packed) { |
| 1449 #define FORMAT "[%s]" |
| 1450 GrowableArray<DeoptInstr*> deopt_instrs; |
| 1451 Unpack(deopt_table, packed, &deopt_instrs); |
| 1452 |
| 1453 // Compute the buffer size required. |
| 1454 intptr_t len = 1; // Trailing '\0'. |
| 1455 for (intptr_t i = 0; i < deopt_instrs.length(); i++) { |
| 1456 len += OS::SNPrint(NULL, 0, FORMAT, deopt_instrs[i]->ToCString()); |
| 1457 } |
| 1458 |
| 1459 // Allocate the buffer. |
| 1460 char* buffer = Thread::Current()->zone()->Alloc<char>(len); |
| 1461 |
| 1462 // Layout the fields in the buffer. |
| 1463 intptr_t index = 0; |
| 1464 for (intptr_t i = 0; i < deopt_instrs.length(); i++) { |
| 1465 index += OS::SNPrint((buffer + index), (len - index), FORMAT, |
| 1466 deopt_instrs[i]->ToCString()); |
| 1467 } |
| 1468 |
| 1469 return buffer; |
| 1470 #undef FORMAT |
| 1471 } |
| 1472 |
| 1473 |
| 1474 // Returns a bool so it can be asserted. |
| 1475 bool DeoptInfo::VerifyDecompression(const GrowableArray<DeoptInstr*>& original, |
| 1476 const Array& deopt_table, |
| 1477 const TypedData& packed) { |
| 1478 GrowableArray<DeoptInstr*> unpacked; |
| 1479 Unpack(deopt_table, packed, &unpacked); |
| 1480 ASSERT(unpacked.length() == original.length()); |
| 1481 for (intptr_t i = 0; i < unpacked.length(); ++i) { |
| 1482 ASSERT(unpacked[i]->Equals(*original[i])); |
| 1483 } |
| 1484 return true; |
| 1485 } |
| 1486 |
1382 } // namespace dart | 1487 } // namespace dart |
OLD | NEW |