mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
[vm] Fix V8 snapshot profile handling of the dispatch table.
Fixes https://github.com/dart-lang/sdk/issues/45702. TEST=Tests listed in the issue above. Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try Change-Id: Ibf5e3ccf3828c01f9dda47de360314dabe8cb8a9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195272 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
parent
cf7bfc5d3c
commit
5909fd111d
2 changed files with 29 additions and 28 deletions
|
@ -6112,12 +6112,14 @@ intptr_t Serializer::AssignRef(ObjectPtr object) {
|
|||
}
|
||||
|
||||
intptr_t Serializer::AssignArtificialRef(ObjectPtr object) {
|
||||
ASSERT(!object.IsHeapObject() || !object.IsInstructions());
|
||||
ASSERT(heap_->GetObjectId(object) == kUnreachableReference);
|
||||
const intptr_t ref = -(next_ref_index_++);
|
||||
ASSERT(IsArtificialReference(ref));
|
||||
heap_->SetObjectId(object, ref);
|
||||
ASSERT(heap_->GetObjectId(object) == ref);
|
||||
if (object != nullptr) {
|
||||
ASSERT(!object.IsHeapObject() || !object.IsInstructions());
|
||||
ASSERT(heap_->GetObjectId(object) == kUnreachableReference);
|
||||
heap_->SetObjectId(object, ref);
|
||||
ASSERT(heap_->GetObjectId(object) == ref);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
@ -6133,7 +6135,11 @@ V8SnapshotProfileWriter::ObjectId Serializer::GetProfileId(
|
|||
ObjectPtr object) const {
|
||||
// Instructions are handled separately.
|
||||
ASSERT(!object->IsHeapObject() || !object->IsInstructions());
|
||||
intptr_t heap_id = UnsafeRefId(object);
|
||||
return GetProfileId(UnsafeRefId(object));
|
||||
}
|
||||
|
||||
V8SnapshotProfileWriter::ObjectId Serializer::GetProfileId(
|
||||
intptr_t heap_id) const {
|
||||
if (IsArtificialReference(heap_id)) {
|
||||
return {V8SnapshotProfileWriter::kArtificial, -heap_id};
|
||||
}
|
||||
|
@ -7086,13 +7092,24 @@ void Serializer::WriteDispatchTable(const Array& entries) {
|
|||
#if defined(DART_PRECOMPILER)
|
||||
if (kind() != Snapshot::kFullAOT) return;
|
||||
|
||||
AssignArtificialRef(entries.ptr());
|
||||
const auto& dispatch_table_snapshot_id = GetProfileId(entries.ptr());
|
||||
// Create an artifical node to which the bytes should be attributed. We
|
||||
// don't attribute them to entries.ptr(), as we don't want to attribute the
|
||||
// bytes for printing out a length of 0 to Object::null() when the dispatch
|
||||
// table is empty.
|
||||
const intptr_t profile_ref = AssignArtificialRef();
|
||||
const auto& dispatch_table_profile_id = GetProfileId(profile_ref);
|
||||
if (profile_writer_ != nullptr) {
|
||||
profile_writer_->AddRoot(dispatch_table_snapshot_id, "dispatch_table");
|
||||
profile_writer_->SetObjectType(dispatch_table_snapshot_id, "DispatchTable");
|
||||
profile_writer_->AddRoot(dispatch_table_profile_id, "dispatch_table");
|
||||
profile_writer_->SetObjectType(dispatch_table_profile_id, "DispatchTable");
|
||||
}
|
||||
WritingObjectScope scope(this, dispatch_table_profile_id);
|
||||
if (profile_writer_ != nullptr) {
|
||||
// We'll write the Array object as a property of the artificial dispatch
|
||||
// table node, so Code objects otherwise unreferenced will have it as an
|
||||
// ancestor.
|
||||
CreateArtificialNodeIfNeeded(entries.ptr());
|
||||
AttributePropertyRef(entries.ptr(), "<code entries>");
|
||||
}
|
||||
WritingObjectScope scope(this, dispatch_table_snapshot_id);
|
||||
|
||||
const intptr_t bytes_before = bytes_written();
|
||||
const intptr_t table_length = entries.IsNull() ? 0 : entries.Length();
|
||||
|
@ -7182,23 +7199,6 @@ void Serializer::WriteDispatchTable(const Array& entries) {
|
|||
Write(repeat_count);
|
||||
}
|
||||
dispatch_table_size_ = bytes_written() - bytes_before;
|
||||
|
||||
// If any bytes were written for the dispatch table, add the elements of
|
||||
// the dispatch table in the profile.
|
||||
if (profile_writer_ != nullptr && !entries.IsNull()) {
|
||||
for (intptr_t i = 0; i < entries.Length(); i++) {
|
||||
auto const code = Code::RawCast(entries.At(i));
|
||||
if (code == Code::null()) continue;
|
||||
profile_writer_->AttributeReferenceTo(
|
||||
dispatch_table_snapshot_id,
|
||||
{
|
||||
V8SnapshotProfileWriter::Reference::kElement,
|
||||
{.offset = i},
|
||||
},
|
||||
GetProfileId(code));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(DART_PRECOMPILER)
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ class Serializer : public ThreadStackResource {
|
|||
const char* type = nullptr,
|
||||
const char* name = nullptr);
|
||||
intptr_t AssignRef(ObjectPtr object);
|
||||
intptr_t AssignArtificialRef(ObjectPtr object);
|
||||
intptr_t AssignArtificialRef(ObjectPtr object = nullptr);
|
||||
|
||||
void Push(ObjectPtr object);
|
||||
|
||||
|
@ -317,6 +317,7 @@ class Serializer : public ThreadStackResource {
|
|||
void Align(intptr_t alignment) { stream_->Align(alignment); }
|
||||
|
||||
V8SnapshotProfileWriter::ObjectId GetProfileId(ObjectPtr object) const;
|
||||
V8SnapshotProfileWriter::ObjectId GetProfileId(intptr_t ref) const;
|
||||
|
||||
void WriteRootRef(ObjectPtr object, const char* name = nullptr) {
|
||||
intptr_t id = RefId(object);
|
||||
|
|
Loading…
Reference in a new issue