OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/native_entry.h" | 5 #include "vm/native_entry.h" |
6 #include "vm/object.h" | 6 #include "vm/object.h" |
7 #include "vm/object_store.h" | 7 #include "vm/object_store.h" |
8 #include "vm/snapshot.h" | 8 #include "vm/snapshot.h" |
9 #include "vm/stub_code.h" | 9 #include "vm/stub_code.h" |
10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 // Write out the class and tags information. | 1367 // Write out the class and tags information. |
1368 writer->WriteVMIsolateObject(kNamespaceCid); | 1368 writer->WriteVMIsolateObject(kNamespaceCid); |
1369 writer->WriteTags(writer->GetObjectTags(this)); | 1369 writer->WriteTags(writer->GetObjectTags(this)); |
1370 | 1370 |
1371 // Write out all the object pointer fields. | 1371 // Write out all the object pointer fields. |
1372 SnapshotWriterVisitor visitor(writer, kAsReference); | 1372 SnapshotWriterVisitor visitor(writer, kAsReference); |
1373 visitor.VisitPointers(from(), to()); | 1373 visitor.VisitPointers(from(), to()); |
1374 } | 1374 } |
1375 | 1375 |
1376 | 1376 |
1377 #if defined(DEBUG) | |
1378 static uword Checksum(uword entry, intptr_t size) { | |
1379 uword sum = 0; | |
1380 uword* start = reinterpret_cast<uword*>(entry); | |
1381 uword* end = reinterpret_cast<uword*>(entry + size); | |
1382 for (uword* cursor = start; cursor < end; cursor++) { | |
1383 sum ^= *cursor; | |
1384 } | |
1385 return sum; | |
1386 } | |
1387 #endif | |
1388 | |
1389 | |
1390 RawCode* Code::ReadFrom(SnapshotReader* reader, | 1377 RawCode* Code::ReadFrom(SnapshotReader* reader, |
1391 intptr_t object_id, | 1378 intptr_t object_id, |
1392 intptr_t tags, | 1379 intptr_t tags, |
1393 Snapshot::Kind kind, | 1380 Snapshot::Kind kind, |
1394 bool as_reference) { | 1381 bool as_reference) { |
1395 ASSERT(Snapshot::IncludesCode(kind)); | 1382 UNREACHABLE(); |
1396 ASSERT(Snapshot::IsFull(kind)); | 1383 return Code::null(); |
1397 | |
1398 Code& result = Code::ZoneHandle(reader->zone(), NEW_OBJECT_WITH_LEN(Code, 0)); | |
1399 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
1400 | |
1401 result.set_compile_timestamp(0); | |
1402 result.set_state_bits(reader->Read<int32_t>()); | |
1403 result.set_lazy_deopt_pc_offset(-1); | |
1404 | |
1405 int32_t text_offset = reader->Read<int32_t>(); | |
1406 RawInstructions* instr = reinterpret_cast<RawInstructions*>( | |
1407 reader->GetInstructionsAt(text_offset) + kHeapObjectTag); | |
1408 uword entry_point = Instructions::EntryPoint(instr); | |
1409 | |
1410 #if defined(DEBUG) | |
1411 ASSERT(instr->IsMarked()); | |
1412 ASSERT(instr->IsVMHeapObject()); | |
1413 uword expected_check = reader->Read<uword>(); | |
1414 intptr_t instructions_size = Utils::RoundUp(instr->size_, | |
1415 OS::PreferredCodeAlignment()); | |
1416 uword actual_check = Checksum(entry_point, instructions_size); | |
1417 ASSERT(expected_check == actual_check); | |
1418 #endif | |
1419 | |
1420 result.StoreNonPointer(&result.raw_ptr()->entry_point_, entry_point); | |
1421 | |
1422 result.StorePointer(&result.raw_ptr()->active_instructions_, instr); | |
1423 result.StorePointer(&result.raw_ptr()->instructions_, instr); | |
1424 | |
1425 (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
1426 result.StorePointer(reinterpret_cast<RawObject*const*>( | |
1427 &result.raw_ptr()->object_pool_), | |
1428 reader->PassiveObjectHandle()->raw()); | |
1429 | |
1430 (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
1431 result.StorePointer(&result.raw_ptr()->owner_, | |
1432 reader->PassiveObjectHandle()->raw()); | |
1433 | |
1434 (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
1435 result.StorePointer(reinterpret_cast<RawObject*const*>( | |
1436 &result.raw_ptr()->exception_handlers_), | |
1437 reader->PassiveObjectHandle()->raw()); | |
1438 | |
1439 (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
1440 result.StorePointer(reinterpret_cast<RawObject*const*>( | |
1441 &result.raw_ptr()->pc_descriptors_), | |
1442 reader->PassiveObjectHandle()->raw()); | |
1443 | |
1444 (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
1445 result.StorePointer(reinterpret_cast<RawObject*const*>( | |
1446 &result.raw_ptr()->stackmaps_), | |
1447 reader->PassiveObjectHandle()->raw()); | |
1448 | |
1449 result.StorePointer(&result.raw_ptr()->deopt_info_array_, | |
1450 Array::null()); | |
1451 result.StorePointer(&result.raw_ptr()->static_calls_target_table_, | |
1452 Array::null()); | |
1453 result.StorePointer(&result.raw_ptr()->var_descriptors_, | |
1454 LocalVarDescriptors::null()); | |
1455 result.StorePointer(&result.raw_ptr()->inlined_metadata_, | |
1456 Array::null()); | |
1457 result.StorePointer(&result.raw_ptr()->code_source_map_, | |
1458 CodeSourceMap::null()); | |
1459 result.StorePointer(&result.raw_ptr()->comments_, | |
1460 Array::null()); | |
1461 result.StorePointer(&result.raw_ptr()->return_address_metadata_, | |
1462 Object::null()); | |
1463 | |
1464 return result.raw(); | |
1465 } | 1384 } |
1466 | 1385 |
1467 | 1386 |
1468 void RawCode::WriteTo(SnapshotWriter* writer, | 1387 void RawCode::WriteTo(SnapshotWriter* writer, |
1469 intptr_t object_id, | 1388 intptr_t object_id, |
1470 Snapshot::Kind kind, | 1389 Snapshot::Kind kind, |
1471 bool as_reference) { | 1390 bool as_reference) { |
1472 ASSERT(Snapshot::IncludesCode(kind)); | 1391 UNREACHABLE(); |
1473 ASSERT(Snapshot::IsFull(kind)); | |
1474 | |
1475 intptr_t pointer_offsets_length = | |
1476 Code::PtrOffBits::decode(ptr()->state_bits_); | |
1477 if (pointer_offsets_length != 0) { | |
1478 FATAL("Cannot serialize code with embedded pointers"); | |
1479 } | |
1480 if (kind == Snapshot::kAppNoJIT) { | |
1481 // No disabled code in precompilation. | |
1482 ASSERT(ptr()->instructions_ == ptr()->active_instructions_); | |
1483 } else { | |
1484 ASSERT(kind == Snapshot::kAppWithJIT); | |
1485 // We never include optimized code in JIT precompilation. Deoptimization | |
1486 // requires code patching and we cannot patch code that is shared between | |
1487 // isolates and should not mutate memory allocated by the embedder. | |
1488 bool is_optimized = Code::PtrOffBits::decode(ptr()->state_bits_); | |
1489 if (is_optimized) { | |
1490 FATAL("Cannot include optimized code in a JIT snapshot"); | |
1491 } | |
1492 } | |
1493 | |
1494 // Write out the serialization header value for this object. | |
1495 writer->WriteInlinedObjectHeader(object_id); | |
1496 | |
1497 // Write out the class and tags information. | |
1498 writer->WriteVMIsolateObject(kCodeCid); | |
1499 writer->WriteTags(writer->GetObjectTags(this)); | |
1500 | |
1501 // Write out all the non object fields. | |
1502 writer->Write<int32_t>(ptr()->state_bits_); | |
1503 | |
1504 RawInstructions* instr = ptr()->instructions_; | |
1505 int32_t text_offset = writer->GetInstructionsId(instr, this); | |
1506 writer->Write<int32_t>(text_offset); | |
1507 | |
1508 #if defined(DEBUG) | |
1509 uword entry = ptr()->entry_point_; | |
1510 intptr_t instructions_size = Utils::RoundUp(instr->size_, | |
1511 OS::PreferredCodeAlignment()); | |
1512 uword check = Checksum(entry, instructions_size); | |
1513 writer->Write<uword>(check); | |
1514 #endif | |
1515 | |
1516 writer->WriteObjectImpl(ptr()->object_pool_, kAsReference); | |
1517 writer->WriteObjectImpl(ptr()->owner_, kAsReference); | |
1518 writer->WriteObjectImpl(ptr()->exception_handlers_, kAsReference); | |
1519 writer->WriteObjectImpl(ptr()->pc_descriptors_, kAsReference); | |
1520 writer->WriteObjectImpl(ptr()->stackmaps_, kAsReference); | |
1521 } | 1392 } |
1522 | 1393 |
1523 | 1394 |
1524 RawInstructions* Instructions::ReadFrom(SnapshotReader* reader, | 1395 RawInstructions* Instructions::ReadFrom(SnapshotReader* reader, |
1525 intptr_t object_id, | 1396 intptr_t object_id, |
1526 intptr_t tags, | 1397 intptr_t tags, |
1527 Snapshot::Kind kind, | 1398 Snapshot::Kind kind, |
1528 bool as_reference) { | 1399 bool as_reference) { |
1529 UNREACHABLE(); | 1400 UNREACHABLE(); |
1530 return Instructions::null(); | 1401 return Instructions::null(); |
1531 } | 1402 } |
1532 | 1403 |
1533 | 1404 |
1534 void RawInstructions::WriteTo(SnapshotWriter* writer, | 1405 void RawInstructions::WriteTo(SnapshotWriter* writer, |
1535 intptr_t object_id, | 1406 intptr_t object_id, |
1536 Snapshot::Kind kind, | 1407 Snapshot::Kind kind, |
1537 bool as_reference) { | 1408 bool as_reference) { |
1538 UNREACHABLE(); | 1409 UNREACHABLE(); |
1539 } | 1410 } |
1540 | 1411 |
1541 | 1412 |
1542 RawObjectPool* ObjectPool::ReadFrom(SnapshotReader* reader, | 1413 RawObjectPool* ObjectPool::ReadFrom(SnapshotReader* reader, |
1543 intptr_t object_id, | 1414 intptr_t object_id, |
1544 intptr_t tags, | 1415 intptr_t tags, |
1545 Snapshot::Kind kind, | 1416 Snapshot::Kind kind, |
1546 bool as_reference) { | 1417 bool as_reference) { |
1547 ASSERT(Snapshot::IncludesCode(kind)); | 1418 UNREACHABLE(); |
1548 ASSERT(Snapshot::IsFull(kind)); | 1419 return ObjectPool::null(); |
1549 | |
1550 intptr_t len = reader->Read<intptr_t>(); | |
1551 ObjectPool* result = NULL; | |
1552 DeserializeState state; | |
1553 if (!as_reference) { | |
1554 result = reinterpret_cast<ObjectPool*>(reader->GetBackRef(object_id)); | |
1555 state = kIsDeserialized; | |
1556 } else { | |
1557 state = kIsNotDeserialized; | |
1558 } | |
1559 if (result == NULL) { | |
1560 result = &(ObjectPool::ZoneHandle( | |
1561 reader->zone(), NEW_OBJECT_WITH_LEN(ObjectPool, len))); | |
1562 reader->AddBackRef(object_id, result, state); | |
1563 } | |
1564 if (!as_reference) { | |
1565 // Read all the individual elements for inlined objects. | |
1566 const TypedData& info_array = | |
1567 TypedData::Handle(reader->NewTypedData(kTypedDataInt8ArrayCid, len)); | |
1568 result->set_info_array(info_array); | |
1569 | |
1570 NoSafepointScope no_safepoint; | |
1571 for (intptr_t i = 0; i < len; i++) { | |
1572 ObjectPool::EntryType entry_type = | |
1573 static_cast<ObjectPool::EntryType>(reader->Read<int8_t>()); | |
1574 *reinterpret_cast<int8_t*>(info_array.DataAddr(i)) = entry_type; | |
1575 switch (entry_type) { | |
1576 case ObjectPool::kTaggedObject: { | |
1577 (*reader->PassiveObjectHandle()) = | |
1578 reader->ReadObjectImpl(kAsReference); | |
1579 result->SetObjectAt(i, *(reader->PassiveObjectHandle())); | |
1580 break; | |
1581 } | |
1582 case ObjectPool::kImmediate: { | |
1583 intptr_t raw_value = reader->Read<intptr_t>(); | |
1584 result->SetRawValueAt(i, raw_value); | |
1585 break; | |
1586 } | |
1587 case ObjectPool::kNativeEntry: { | |
1588 #if !defined(TARGET_ARCH_DBC) | |
1589 // Read nothing. Initialize with the lazy link entry. | |
1590 uword new_entry = NativeEntry::LinkNativeCallEntry(); | |
1591 result->SetRawValueAt(i, static_cast<intptr_t>(new_entry)); | |
1592 #else | |
1593 UNREACHABLE(); // DBC does not support lazy native call linking. | |
1594 #endif | |
1595 break; | |
1596 } | |
1597 default: | |
1598 UNREACHABLE(); | |
1599 } | |
1600 } | |
1601 } | |
1602 return result->raw(); | |
1603 } | 1420 } |
1604 | 1421 |
1605 | 1422 |
1606 void RawObjectPool::WriteTo(SnapshotWriter* writer, | 1423 void RawObjectPool::WriteTo(SnapshotWriter* writer, |
1607 intptr_t object_id, | 1424 intptr_t object_id, |
1608 Snapshot::Kind kind, | 1425 Snapshot::Kind kind, |
1609 bool as_reference) { | 1426 bool as_reference) { |
1610 ASSERT(Snapshot::IncludesCode(kind)); | 1427 UNREACHABLE(); |
1611 ASSERT(Snapshot::IsFull(kind)); | |
1612 intptr_t tags = writer->GetObjectTags(this); | |
1613 intptr_t length = ptr()->length_; | |
1614 | |
1615 if (as_reference) { | |
1616 // Write out the serialization header value for this object. | |
1617 writer->WriteInlinedObjectHeader(kOmittedObjectId); | |
1618 | |
1619 // Write out the class information. | |
1620 writer->WriteVMIsolateObject(kObjectPoolCid); | |
1621 writer->WriteTags(tags); | |
1622 | |
1623 // Write out the length field. | |
1624 writer->Write<intptr_t>(length); | |
1625 } else { | |
1626 // Write out the serialization header value for this object. | |
1627 writer->WriteInlinedObjectHeader(object_id); | |
1628 | |
1629 // Write out the class and tags information. | |
1630 writer->WriteVMIsolateObject(kObjectPoolCid); | |
1631 writer->WriteTags(tags); | |
1632 | |
1633 RawTypedData* info_array = ptr()->info_array_->ptr(); | |
1634 ASSERT(info_array != TypedData::null()); | |
1635 | |
1636 writer->Write<intptr_t>(length); | |
1637 for (intptr_t i = 0; i < length; i++) { | |
1638 ObjectPool::EntryType entry_type = | |
1639 static_cast<ObjectPool::EntryType>(info_array->data()[i]); | |
1640 writer->Write<int8_t>(entry_type); | |
1641 Entry& entry = ptr()->data()[i]; | |
1642 switch (entry_type) { | |
1643 case ObjectPool::kTaggedObject: { | |
1644 #if !defined(TARGET_ARCH_DBC) | |
1645 if (entry.raw_obj_ == StubCode::CallNativeCFunction_entry()->code()) { | |
1646 // Natives can run while precompiling, becoming linked and switching | |
1647 // their stub. Reset to the initial stub used for lazy-linking. | |
1648 writer->WriteObjectImpl( | |
1649 StubCode::CallBootstrapCFunction_entry()->code(), kAsReference); | |
1650 break; | |
1651 } | |
1652 #endif | |
1653 writer->WriteObjectImpl(entry.raw_obj_, kAsReference); | |
1654 break; | |
1655 } | |
1656 case ObjectPool::kImmediate: { | |
1657 writer->Write<intptr_t>(entry.raw_value_); | |
1658 break; | |
1659 } | |
1660 case ObjectPool::kNativeEntry: { | |
1661 // Write nothing. Will initialize with the lazy link entry. | |
1662 #if defined(TARGET_ARCH_DBC) | |
1663 UNREACHABLE(); // DBC does not support lazy native call linking. | |
1664 #endif | |
1665 break; | |
1666 } | |
1667 default: | |
1668 UNREACHABLE(); | |
1669 } | |
1670 } | |
1671 } | |
1672 } | 1428 } |
1673 | 1429 |
1674 | 1430 |
1675 RawPcDescriptors* PcDescriptors::ReadFrom(SnapshotReader* reader, | 1431 RawPcDescriptors* PcDescriptors::ReadFrom(SnapshotReader* reader, |
1676 intptr_t object_id, | 1432 intptr_t object_id, |
1677 intptr_t tags, | 1433 intptr_t tags, |
1678 Snapshot::Kind kind, | 1434 Snapshot::Kind kind, |
1679 bool as_reference) { | 1435 bool as_reference) { |
1680 ASSERT(Snapshot::IncludesCode(kind)); | 1436 UNREACHABLE(); |
1681 ASSERT(Snapshot::IsFull(kind)); | 1437 return PcDescriptors::null(); |
1682 | |
1683 intptr_t offset = reader->Read<int32_t>(); | |
1684 PcDescriptors& result = PcDescriptors::ZoneHandle(reader->zone()); | |
1685 result ^= reader->GetObjectAt(offset); | |
1686 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
1687 | |
1688 return result.raw(); | |
1689 } | 1438 } |
1690 | 1439 |
1691 | 1440 |
1692 void RawPcDescriptors::WriteTo(SnapshotWriter* writer, | 1441 void RawPcDescriptors::WriteTo(SnapshotWriter* writer, |
1693 intptr_t object_id, | 1442 intptr_t object_id, |
1694 Snapshot::Kind kind, | 1443 Snapshot::Kind kind, |
1695 bool as_reference) { | 1444 bool as_reference) { |
1696 ASSERT(Snapshot::IncludesCode(kind)); | 1445 UNREACHABLE(); |
1697 ASSERT(Snapshot::IsFull(kind)); | |
1698 | |
1699 // Write out the serialization header value for this object. | |
1700 writer->WriteInlinedObjectHeader(object_id); | |
1701 writer->WriteIndexedObject(kPcDescriptorsCid); | |
1702 writer->WriteTags(writer->GetObjectTags(this)); | |
1703 | |
1704 writer->Write<int32_t>(writer->GetObjectId(this)); | |
1705 } | 1446 } |
1706 | 1447 |
1707 | 1448 |
1708 RawCodeSourceMap* CodeSourceMap::ReadFrom(SnapshotReader* reader, | 1449 RawCodeSourceMap* CodeSourceMap::ReadFrom(SnapshotReader* reader, |
1709 intptr_t object_id, | 1450 intptr_t object_id, |
1710 intptr_t tags, | 1451 intptr_t tags, |
1711 Snapshot::Kind kind, | 1452 Snapshot::Kind kind, |
1712 bool as_reference) { | 1453 bool as_reference) { |
1713 ASSERT(Snapshot::IncludesCode(kind)); | 1454 UNREACHABLE(); |
1714 ASSERT(Snapshot::IsFull(kind)); | 1455 return CodeSourceMap::null(); |
1715 | |
1716 const int32_t length = reader->Read<int32_t>(); | |
1717 CodeSourceMap& result = | |
1718 CodeSourceMap::ZoneHandle(reader->zone(), | |
1719 NEW_OBJECT_WITH_LEN(CodeSourceMap, length)); | |
1720 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
1721 | |
1722 if (result.Length() > 0) { | |
1723 NoSafepointScope no_safepoint; | |
1724 intptr_t len = result.Length(); | |
1725 uint8_t* data = result.UnsafeMutableNonPointer(result.raw_ptr()->data()); | |
1726 reader->ReadBytes(data, len); | |
1727 } | |
1728 | |
1729 return result.raw(); | |
1730 } | 1456 } |
1731 | 1457 |
1732 | 1458 |
1733 void RawCodeSourceMap::WriteTo(SnapshotWriter* writer, | 1459 void RawCodeSourceMap::WriteTo(SnapshotWriter* writer, |
1734 intptr_t object_id, | 1460 intptr_t object_id, |
1735 Snapshot::Kind kind, | 1461 Snapshot::Kind kind, |
1736 bool as_reference) { | 1462 bool as_reference) { |
1737 ASSERT(Snapshot::IncludesCode(kind)); | 1463 UNREACHABLE(); |
1738 ASSERT(Snapshot::IsFull(kind)); | |
1739 | |
1740 // Write out the serialization header value for this object. | |
1741 writer->WriteInlinedObjectHeader(object_id); | |
1742 writer->WriteIndexedObject(kCodeSourceMapCid); | |
1743 writer->WriteTags(writer->GetObjectTags(this)); | |
1744 writer->Write<int32_t>(ptr()->length_); | |
1745 if (ptr()->length_ > 0) { | |
1746 intptr_t len = ptr()->length_; | |
1747 uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data()); | |
1748 writer->WriteBytes(data, len); | |
1749 } | |
1750 } | 1464 } |
1751 | 1465 |
1752 | 1466 |
1753 RawStackmap* Stackmap::ReadFrom(SnapshotReader* reader, | 1467 RawStackmap* Stackmap::ReadFrom(SnapshotReader* reader, |
1754 intptr_t object_id, | 1468 intptr_t object_id, |
1755 intptr_t tags, | 1469 intptr_t tags, |
1756 Snapshot::Kind kind, | 1470 Snapshot::Kind kind, |
1757 bool as_reference) { | 1471 bool as_reference) { |
1758 ASSERT(Snapshot::IncludesCode(kind)); | 1472 UNREACHABLE(); |
1759 ASSERT(Snapshot::IsFull(kind)); | 1473 return Stackmap::null(); |
1760 | |
1761 intptr_t offset = reader->Read<int32_t>(); | |
1762 Stackmap& result = Stackmap::ZoneHandle(reader->zone()); | |
1763 result ^= reader->GetObjectAt(offset); | |
1764 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
1765 | |
1766 return result.raw(); | |
1767 } | 1474 } |
1768 | 1475 |
1769 | 1476 |
1770 void RawStackmap::WriteTo(SnapshotWriter* writer, | 1477 void RawStackmap::WriteTo(SnapshotWriter* writer, |
1771 intptr_t object_id, | 1478 intptr_t object_id, |
1772 Snapshot::Kind kind, | 1479 Snapshot::Kind kind, |
1773 bool as_reference) { | 1480 bool as_reference) { |
1774 ASSERT(Snapshot::IncludesCode(kind)); | 1481 UNREACHABLE(); |
1775 ASSERT(Snapshot::IsFull(kind)); | |
1776 | |
1777 // Write out the serialization header value for this object. | |
1778 writer->WriteInlinedObjectHeader(object_id); | |
1779 writer->WriteIndexedObject(kStackmapCid); | |
1780 writer->WriteTags(writer->GetObjectTags(this)); | |
1781 | |
1782 writer->Write<int32_t>(writer->GetObjectId(this)); | |
1783 } | 1482 } |
1784 | 1483 |
1785 | 1484 |
1786 RawLocalVarDescriptors* LocalVarDescriptors::ReadFrom(SnapshotReader* reader, | 1485 RawLocalVarDescriptors* LocalVarDescriptors::ReadFrom(SnapshotReader* reader, |
1787 intptr_t object_id, | 1486 intptr_t object_id, |
1788 intptr_t tags, | 1487 intptr_t tags, |
1789 Snapshot::Kind kind, | 1488 Snapshot::Kind kind, |
1790 bool as_reference) { | 1489 bool as_reference) { |
1791 ASSERT(Snapshot::IncludesCode(kind)); | 1490 UNREACHABLE(); |
1792 ASSERT(Snapshot::IsFull(kind)); | 1491 return LocalVarDescriptors::null(); |
1793 | |
1794 const int32_t num_entries = reader->Read<int32_t>(); | |
1795 | |
1796 LocalVarDescriptors& result = | |
1797 LocalVarDescriptors::ZoneHandle(reader->zone(), | |
1798 NEW_OBJECT_WITH_LEN(LocalVarDescriptors, | |
1799 num_entries)); | |
1800 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
1801 | |
1802 for (intptr_t i = 0; i < num_entries; i++) { | |
1803 (*reader->StringHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
1804 result.StorePointer(result.raw()->nameAddrAt(i), | |
1805 reader->StringHandle()->raw()); | |
1806 } | |
1807 | |
1808 if (num_entries > 0) { | |
1809 NoSafepointScope no_safepoint; | |
1810 intptr_t len = num_entries * sizeof(RawLocalVarDescriptors::VarInfo); | |
1811 uint8_t* data = result.UnsafeMutableNonPointer( | |
1812 reinterpret_cast<const uint8_t*>(result.raw()->data())); | |
1813 reader->ReadBytes(data, len); | |
1814 } | |
1815 | |
1816 return result.raw(); | |
1817 } | 1492 } |
1818 | 1493 |
1819 | 1494 |
1820 void RawLocalVarDescriptors::WriteTo(SnapshotWriter* writer, | 1495 void RawLocalVarDescriptors::WriteTo(SnapshotWriter* writer, |
1821 intptr_t object_id, | 1496 intptr_t object_id, |
1822 Snapshot::Kind kind, | 1497 Snapshot::Kind kind, |
1823 bool as_reference) { | 1498 bool as_reference) { |
1824 ASSERT(Snapshot::IncludesCode(kind)); | 1499 UNREACHABLE(); |
1825 ASSERT(Snapshot::IsFull(kind)); | |
1826 | |
1827 // Write out the serialization header value for this object. | |
1828 writer->WriteInlinedObjectHeader(object_id); | |
1829 writer->WriteIndexedObject(kLocalVarDescriptorsCid); | |
1830 writer->WriteTags(writer->GetObjectTags(this)); | |
1831 writer->Write<int32_t>(ptr()->num_entries_); | |
1832 for (intptr_t i = 0; i < ptr()->num_entries_; i++) { | |
1833 writer->WriteObjectImpl(ptr()->names()[i], kAsReference); | |
1834 } | |
1835 if (ptr()->num_entries_ > 0) { | |
1836 intptr_t len = ptr()->num_entries_ * sizeof(VarInfo); | |
1837 uint8_t* data = reinterpret_cast<uint8_t*>(this->data()); | |
1838 writer->WriteBytes(data, len); | |
1839 } | |
1840 } | 1500 } |
1841 | 1501 |
1842 | 1502 |
1843 RawExceptionHandlers* ExceptionHandlers::ReadFrom(SnapshotReader* reader, | 1503 RawExceptionHandlers* ExceptionHandlers::ReadFrom(SnapshotReader* reader, |
1844 intptr_t object_id, | 1504 intptr_t object_id, |
1845 intptr_t tags, | 1505 intptr_t tags, |
1846 Snapshot::Kind kind, | 1506 Snapshot::Kind kind, |
1847 bool as_reference) { | 1507 bool as_reference) { |
1848 ASSERT(Snapshot::IncludesCode(kind)); | 1508 UNREACHABLE(); |
1849 ASSERT(Snapshot::IsFull(kind)); | 1509 return ExceptionHandlers::null(); |
1850 | |
1851 const int32_t num_entries = reader->Read<int32_t>(); | |
1852 ExceptionHandlers& result = | |
1853 ExceptionHandlers::ZoneHandle(reader->zone(), | |
1854 NEW_OBJECT_WITH_LEN(ExceptionHandlers, | |
1855 num_entries)); | |
1856 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
1857 | |
1858 if (result.num_entries() > 0) { | |
1859 NoSafepointScope no_safepoint; | |
1860 const intptr_t len = | |
1861 result.num_entries() * sizeof(RawExceptionHandlers::HandlerInfo); | |
1862 uint8_t* data = result.UnsafeMutableNonPointer( | |
1863 reinterpret_cast<const uint8_t*>(result.raw_ptr()->data())); | |
1864 reader->ReadBytes(data, len); | |
1865 } | |
1866 | |
1867 *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject); | |
1868 result.StorePointer(&result.raw_ptr()->handled_types_data_, | |
1869 reader->ArrayHandle()->raw()); | |
1870 | |
1871 return result.raw(); | |
1872 } | 1510 } |
1873 | 1511 |
1874 | 1512 |
1875 void RawExceptionHandlers::WriteTo(SnapshotWriter* writer, | 1513 void RawExceptionHandlers::WriteTo(SnapshotWriter* writer, |
1876 intptr_t object_id, | 1514 intptr_t object_id, |
1877 Snapshot::Kind kind, | 1515 Snapshot::Kind kind, |
1878 bool as_reference) { | 1516 bool as_reference) { |
1879 ASSERT(Snapshot::IncludesCode(kind)); | 1517 UNREACHABLE(); |
1880 ASSERT(Snapshot::IsFull(kind)); | |
1881 | |
1882 // Write out the serialization header value for this object. | |
1883 writer->WriteInlinedObjectHeader(object_id); | |
1884 writer->WriteIndexedObject(kExceptionHandlersCid); | |
1885 writer->WriteTags(writer->GetObjectTags(this)); | |
1886 writer->Write<int32_t>(ptr()->num_entries_); | |
1887 | |
1888 if (ptr()->num_entries_ > 0) { | |
1889 intptr_t len = ptr()->num_entries_ * sizeof(HandlerInfo); | |
1890 uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data()); | |
1891 writer->WriteBytes(data, len); | |
1892 } | |
1893 | |
1894 writer->WriteObjectImpl(ptr()->handled_types_data_, kAsInlinedObject); | |
1895 } | 1518 } |
1896 | 1519 |
1897 | 1520 |
1898 RawContext* Context::ReadFrom(SnapshotReader* reader, | 1521 RawContext* Context::ReadFrom(SnapshotReader* reader, |
1899 intptr_t object_id, | 1522 intptr_t object_id, |
1900 intptr_t tags, | 1523 intptr_t tags, |
1901 Snapshot::Kind kind, | 1524 Snapshot::Kind kind, |
1902 bool as_reference) { | 1525 bool as_reference) { |
1903 ASSERT(reader != NULL); | 1526 ASSERT(reader != NULL); |
1904 | 1527 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 SnapshotWriterVisitor visitor(writer, kAsReference); | 1722 SnapshotWriterVisitor visitor(writer, kAsReference); |
2100 visitor.VisitPointers(from(), to_snapshot(kind)); | 1723 visitor.VisitPointers(from(), to_snapshot(kind)); |
2101 } | 1724 } |
2102 | 1725 |
2103 | 1726 |
2104 RawMegamorphicCache* MegamorphicCache::ReadFrom(SnapshotReader* reader, | 1727 RawMegamorphicCache* MegamorphicCache::ReadFrom(SnapshotReader* reader, |
2105 intptr_t object_id, | 1728 intptr_t object_id, |
2106 intptr_t tags, | 1729 intptr_t tags, |
2107 Snapshot::Kind kind, | 1730 Snapshot::Kind kind, |
2108 bool as_reference) { | 1731 bool as_reference) { |
2109 ASSERT(Snapshot::IncludesCode(kind)); | 1732 UNREACHABLE(); |
2110 ASSERT(Snapshot::IsFull(kind)); | 1733 return MegamorphicCache::null(); |
2111 | |
2112 MegamorphicCache& result = | |
2113 MegamorphicCache::ZoneHandle(reader->zone(), | |
2114 NEW_OBJECT(MegamorphicCache)); | |
2115 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
2116 | |
2117 result.set_filled_entry_count(reader->Read<int32_t>()); | |
2118 | |
2119 // Set all the object fields. | |
2120 READ_OBJECT_FIELDS(result, | |
2121 result.raw()->from(), result.raw()->to(), | |
2122 kAsReference); | |
2123 | |
2124 return result.raw(); | |
2125 } | 1734 } |
2126 | 1735 |
2127 | 1736 |
2128 void RawMegamorphicCache::WriteTo(SnapshotWriter* writer, | 1737 void RawMegamorphicCache::WriteTo(SnapshotWriter* writer, |
2129 intptr_t object_id, | 1738 intptr_t object_id, |
2130 Snapshot::Kind kind, | 1739 Snapshot::Kind kind, |
2131 bool as_reference) { | 1740 bool as_reference) { |
2132 ASSERT(Snapshot::IncludesCode(kind)); | 1741 UNREACHABLE(); |
2133 ASSERT(Snapshot::IsFull(kind)); | |
2134 | |
2135 // Write out the serialization header value for this object. | |
2136 writer->WriteInlinedObjectHeader(object_id); | |
2137 | |
2138 // Write out the class and tags information. | |
2139 writer->WriteVMIsolateObject(kMegamorphicCacheCid); | |
2140 writer->WriteTags(writer->GetObjectTags(this)); | |
2141 | |
2142 // Write out all the non object fields. | |
2143 writer->Write<int32_t>(ptr()->filled_entry_count_); | |
2144 | |
2145 // Write out all the object pointer fields. | |
2146 SnapshotWriterVisitor visitor(writer, kAsReference); | |
2147 visitor.VisitPointers(from(), to()); | |
2148 } | 1742 } |
2149 | 1743 |
2150 | 1744 |
2151 RawSubtypeTestCache* SubtypeTestCache::ReadFrom(SnapshotReader* reader, | 1745 RawSubtypeTestCache* SubtypeTestCache::ReadFrom(SnapshotReader* reader, |
2152 intptr_t object_id, | 1746 intptr_t object_id, |
2153 intptr_t tags, | 1747 intptr_t tags, |
2154 Snapshot::Kind kind, | 1748 Snapshot::Kind kind, |
2155 bool as_reference) { | 1749 bool as_reference) { |
2156 ASSERT(Snapshot::IncludesCode(kind)); | 1750 UNREACHABLE(); |
2157 ASSERT(Snapshot::IsFull(kind)); | 1751 return SubtypeTestCache::null(); |
2158 | |
2159 SubtypeTestCache& result = | |
2160 SubtypeTestCache::ZoneHandle(reader->zone(), | |
2161 NEW_OBJECT(SubtypeTestCache)); | |
2162 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
2163 | |
2164 // Set all the object fields. | |
2165 // TODO(5411462): Need to assert No GC can happen here, even though | |
2166 // allocations may happen. | |
2167 (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference); | |
2168 result.StorePointer(&result.raw_ptr()->cache_, | |
2169 reader->ArrayHandle()->raw()); | |
2170 | |
2171 return result.raw(); | |
2172 } | 1752 } |
2173 | 1753 |
2174 | 1754 |
2175 void RawSubtypeTestCache::WriteTo(SnapshotWriter* writer, | 1755 void RawSubtypeTestCache::WriteTo(SnapshotWriter* writer, |
2176 intptr_t object_id, | 1756 intptr_t object_id, |
2177 Snapshot::Kind kind, | 1757 Snapshot::Kind kind, |
2178 bool as_reference) { | 1758 bool as_reference) { |
2179 ASSERT(Snapshot::IncludesCode(kind)); | 1759 UNREACHABLE(); |
2180 ASSERT(Snapshot::IsFull(kind)); | |
2181 | |
2182 // Write out the serialization header value for this object. | |
2183 writer->WriteInlinedObjectHeader(object_id); | |
2184 | |
2185 // Write out the class and tags information. | |
2186 writer->WriteVMIsolateObject(kSubtypeTestCacheCid); | |
2187 writer->WriteTags(writer->GetObjectTags(this)); | |
2188 | |
2189 // Write out all the object pointer fields. | |
2190 writer->WriteObjectImpl(ptr()->cache_, kAsReference); | |
2191 } | 1760 } |
2192 | 1761 |
2193 | 1762 |
2194 RawError* Error::ReadFrom(SnapshotReader* reader, | 1763 RawError* Error::ReadFrom(SnapshotReader* reader, |
2195 intptr_t object_id, | 1764 intptr_t object_id, |
2196 intptr_t tags, | 1765 intptr_t tags, |
2197 Snapshot::Kind kind, | 1766 Snapshot::Kind kind, |
2198 bool as_referenec) { | 1767 bool as_referenec) { |
2199 UNREACHABLE(); | 1768 UNREACHABLE(); |
2200 return Error::null(); // Error is an abstract class. | 1769 return Error::null(); // Error is an abstract class. |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2614 } | 2183 } |
2615 } | 2184 } |
2616 } | 2185 } |
2617 | 2186 |
2618 | 2187 |
2619 RawOneByteString* OneByteString::ReadFrom(SnapshotReader* reader, | 2188 RawOneByteString* OneByteString::ReadFrom(SnapshotReader* reader, |
2620 intptr_t object_id, | 2189 intptr_t object_id, |
2621 intptr_t tags, | 2190 intptr_t tags, |
2622 Snapshot::Kind kind, | 2191 Snapshot::Kind kind, |
2623 bool as_reference) { | 2192 bool as_reference) { |
2624 if (Snapshot::IncludesCode(kind)) { | |
2625 ASSERT(Snapshot::IsFull(kind)); | |
2626 intptr_t offset = reader->Read<int32_t>(); | |
2627 String& result = String::ZoneHandle(reader->zone()); | |
2628 result ^= reader->GetObjectAt(offset); | |
2629 reader->AddBackRef(object_id, &result, kIsDeserialized); | |
2630 return raw(result); | |
2631 } | |
2632 // Read the length so that we can determine instance size to allocate. | 2193 // Read the length so that we can determine instance size to allocate. |
2633 ASSERT(reader != NULL); | 2194 ASSERT(reader != NULL); |
2634 intptr_t len = reader->ReadSmiValue(); | 2195 intptr_t len = reader->ReadSmiValue(); |
2635 intptr_t hash = reader->ReadSmiValue(); | 2196 intptr_t hash = reader->ReadSmiValue(); |
2636 String& str_obj = String::ZoneHandle(reader->zone(), String::null()); | 2197 String& str_obj = String::ZoneHandle(reader->zone(), String::null()); |
2637 | 2198 |
2638 if (Snapshot::IsFull(kind)) { | 2199 if (Snapshot::IsFull(kind)) { |
2639 // We currently only expect the Dart mutator to read snapshots. | 2200 // We currently only expect the Dart mutator to read snapshots. |
2640 reader->isolate()->AssertCurrentThreadIsMutator(); | 2201 reader->isolate()->AssertCurrentThreadIsMutator(); |
2641 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); | 2202 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2729 } | 2290 } |
2730 } | 2291 } |
2731 } | 2292 } |
2732 } | 2293 } |
2733 | 2294 |
2734 | 2295 |
2735 void RawOneByteString::WriteTo(SnapshotWriter* writer, | 2296 void RawOneByteString::WriteTo(SnapshotWriter* writer, |
2736 intptr_t object_id, | 2297 intptr_t object_id, |
2737 Snapshot::Kind kind, | 2298 Snapshot::Kind kind, |
2738 bool as_reference) { | 2299 bool as_reference) { |
2739 if (Snapshot::IncludesCode(kind)) { | |
2740 ASSERT(Snapshot::IncludesCode(kind)); | |
2741 ASSERT(Snapshot::IsFull(kind)); | |
2742 // Assert that hash is computed. | |
2743 if (ptr()->hash_ == NULL) { | |
2744 ptr()->hash_ = Smi::New(String::Hash(ptr()->data(), | |
2745 Smi::Value(ptr()->length_))); | |
2746 } | |
2747 ASSERT(ptr()->hash_ != NULL); | |
2748 // Write out the serialization header value for this object. | |
2749 writer->WriteInlinedObjectHeader(object_id); | |
2750 writer->WriteIndexedObject(kOneByteStringCid); | |
2751 writer->WriteTags(writer->GetObjectTags(this)); | |
2752 writer->Write<int32_t>(writer->GetObjectId(this)); | |
2753 return; | |
2754 } | |
2755 StringWriteTo(writer, | 2300 StringWriteTo(writer, |
2756 object_id, | 2301 object_id, |
2757 kind, | 2302 kind, |
2758 kOneByteStringCid, | 2303 kOneByteStringCid, |
2759 writer->GetObjectTags(this), | 2304 writer->GetObjectTags(this), |
2760 ptr()->length_, | 2305 ptr()->length_, |
2761 ptr()->hash_, | 2306 ptr()->hash_, |
2762 ptr()->data()); | 2307 ptr()->data()); |
2763 } | 2308 } |
2764 | 2309 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3010 | 2555 |
3011 RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader, | 2556 RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader, |
3012 intptr_t object_id, | 2557 intptr_t object_id, |
3013 intptr_t tags, | 2558 intptr_t tags, |
3014 Snapshot::Kind kind, | 2559 Snapshot::Kind kind, |
3015 bool as_reference) { | 2560 bool as_reference) { |
3016 ASSERT(reader != NULL); | 2561 ASSERT(reader != NULL); |
3017 | 2562 |
3018 LinkedHashMap& map = LinkedHashMap::ZoneHandle( | 2563 LinkedHashMap& map = LinkedHashMap::ZoneHandle( |
3019 reader->zone(), LinkedHashMap::null()); | 2564 reader->zone(), LinkedHashMap::null()); |
3020 if ((Snapshot::IsFull(kind) && !Snapshot::IncludesCode(kind)) || | 2565 if (Snapshot::IsFull(kind) || kind == Snapshot::kScript) { |
3021 kind == Snapshot::kScript) { | |
3022 // The immutable maps that seed map literals are not yet VM-internal, so | 2566 // The immutable maps that seed map literals are not yet VM-internal, so |
3023 // we don't reach this. | 2567 // we don't reach this. |
3024 UNREACHABLE(); | 2568 UNREACHABLE(); |
3025 } else { | 2569 } else { |
3026 // Since the map might contain itself as a key or value, allocate first. | 2570 // Since the map might contain itself as a key or value, allocate first. |
3027 if (Snapshot::IsFull(kind)) { | 2571 if (Snapshot::IsFull(kind)) { |
3028 map = reader->NewLinkedHashMap(); | 2572 map = reader->NewLinkedHashMap(); |
3029 } else { | 2573 } else { |
3030 map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind)); | 2574 map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind)); |
3031 } | 2575 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3069 data.SetAt(i, *reader->PassiveObjectHandle()); | 2613 data.SetAt(i, *reader->PassiveObjectHandle()); |
3070 } | 2614 } |
3071 return map.raw(); | 2615 return map.raw(); |
3072 } | 2616 } |
3073 | 2617 |
3074 | 2618 |
3075 void RawLinkedHashMap::WriteTo(SnapshotWriter* writer, | 2619 void RawLinkedHashMap::WriteTo(SnapshotWriter* writer, |
3076 intptr_t object_id, | 2620 intptr_t object_id, |
3077 Snapshot::Kind kind, | 2621 Snapshot::Kind kind, |
3078 bool as_reference) { | 2622 bool as_reference) { |
3079 if ((Snapshot::IsFull(kind) && !Snapshot::IncludesCode(kind)) || | 2623 if (Snapshot::IsFull(kind) || kind == Snapshot::kScript) { |
3080 kind == Snapshot::kScript) { | |
3081 // The immutable maps that seed map literals are not yet VM-internal, so | 2624 // The immutable maps that seed map literals are not yet VM-internal, so |
3082 // we don't reach this. | 2625 // we don't reach this. |
3083 } | 2626 } |
3084 ASSERT(writer != NULL); | 2627 ASSERT(writer != NULL); |
3085 | 2628 |
3086 // Write out the serialization header value for this object. | 2629 // Write out the serialization header value for this object. |
3087 writer->WriteInlinedObjectHeader(object_id); | 2630 writer->WriteInlinedObjectHeader(object_id); |
3088 | 2631 |
3089 // Write out the class and tags information. | 2632 // Write out the class and tags information. |
3090 writer->WriteIndexedObject(kLinkedHashMapCid); | 2633 writer->WriteIndexedObject(kLinkedHashMapCid); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3545 UNREACHABLE(); | 3088 UNREACHABLE(); |
3546 } | 3089 } |
3547 } | 3090 } |
3548 | 3091 |
3549 | 3092 |
3550 RawSendPort* SendPort::ReadFrom(SnapshotReader* reader, | 3093 RawSendPort* SendPort::ReadFrom(SnapshotReader* reader, |
3551 intptr_t object_id, | 3094 intptr_t object_id, |
3552 intptr_t tags, | 3095 intptr_t tags, |
3553 Snapshot::Kind kind, | 3096 Snapshot::Kind kind, |
3554 bool as_reference) { | 3097 bool as_reference) { |
3555 ASSERT(kind == Snapshot::kMessage || Snapshot::IncludesCode(kind)); | 3098 ASSERT(kind == Snapshot::kMessage); |
3556 | 3099 |
3557 uint64_t id = reader->Read<uint64_t>(); | 3100 uint64_t id = reader->Read<uint64_t>(); |
3558 uint64_t origin_id = reader->Read<uint64_t>(); | 3101 uint64_t origin_id = reader->Read<uint64_t>(); |
3559 | 3102 |
3560 SendPort& result = SendPort::ZoneHandle(reader->zone()); | 3103 SendPort& result = |
3561 if (Snapshot::IncludesCode(kind)) { | 3104 SendPort::ZoneHandle(reader->zone(), |
3562 // TODO(rmacnak): Reset fields in precompiled snapshots and assert | 3105 SendPort::New(id, origin_id)); |
3563 // this is unreachable. | |
3564 } else { | |
3565 result = SendPort::New(id, origin_id); | |
3566 } | |
3567 reader->AddBackRef(object_id, &result, kIsDeserialized); | 3106 reader->AddBackRef(object_id, &result, kIsDeserialized); |
3568 return result.raw(); | 3107 return result.raw(); |
3569 } | 3108 } |
3570 | 3109 |
3571 | 3110 |
3572 void RawSendPort::WriteTo(SnapshotWriter* writer, | 3111 void RawSendPort::WriteTo(SnapshotWriter* writer, |
3573 intptr_t object_id, | 3112 intptr_t object_id, |
3574 Snapshot::Kind kind, | 3113 Snapshot::Kind kind, |
3575 bool as_reference) { | 3114 bool as_reference) { |
3576 // Write out the serialization header value for this object. | 3115 // Write out the serialization header value for this object. |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3780 // We do not allow objects with native fields in an isolate message. | 3319 // We do not allow objects with native fields in an isolate message. |
3781 writer->SetWriteException(Exceptions::kArgument, | 3320 writer->SetWriteException(Exceptions::kArgument, |
3782 "Illegal argument in isolate message" | 3321 "Illegal argument in isolate message" |
3783 " : (object is a UserTag)"); | 3322 " : (object is a UserTag)"); |
3784 } else { | 3323 } else { |
3785 UNREACHABLE(); | 3324 UNREACHABLE(); |
3786 } | 3325 } |
3787 } | 3326 } |
3788 | 3327 |
3789 } // namespace dart | 3328 } // namespace dart |
OLD | NEW |