[vm] Remove FindObject.

Before the calling convention change during the introduction of AOT, this was used to get code metadata associated with a frame. Its remaining non-test use is forming service IDs for code object, which can  use the regular visitors.

TEST=ci
Change-Id: Ica8eafe988d19eba8d905d9dc5907afbfd559118
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/296705
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Ryan Macnak 2023-04-21 22:41:28 +00:00 committed by Commit Queue
parent b5d63cb67f
commit 78daab15b3
17 changed files with 43 additions and 295 deletions

View file

@ -362,37 +362,6 @@ void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) {
old_space_.VisitObjectPointers(visitor);
}
InstructionsPtr Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
// Only executable pages can have RawInstructions objects.
ObjectPtr raw_obj = old_space_.FindObject(visitor, /*exec*/ true);
ASSERT((raw_obj == Object::null()) ||
(raw_obj->GetClassId() == kInstructionsCid));
return static_cast<InstructionsPtr>(raw_obj);
}
ObjectPtr Heap::FindOldObject(FindObjectVisitor* visitor) const {
return old_space_.FindObject(visitor, /*exec*/ false);
}
ObjectPtr Heap::FindNewObject(FindObjectVisitor* visitor) {
return new_space_.FindObject(visitor);
}
ObjectPtr Heap::FindObject(FindObjectVisitor* visitor) {
// The visitor must not allocate from the heap.
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = FindNewObject(visitor);
if (raw_obj != Object::null()) {
return raw_obj;
}
raw_obj = FindOldObject(visitor);
if (raw_obj != Object::null()) {
return raw_obj;
}
raw_obj = FindObjectInCodeSpace(visitor);
return raw_obj;
}
void Heap::NotifyIdle(int64_t deadline) {
Thread* thread = Thread::Current();
TIMELINE_FUNCTION_GC_DURATION(thread, "NotifyIdle");

View file

@ -111,19 +111,6 @@ class Heap {
bool CodeContains(uword addr) const;
bool DataContains(uword addr) const;
// Find an object by visiting all pointers in the specified heap space,
// the 'visitor' is used to determine if an object is found or not.
// The 'visitor' function should be set up to return true if the
// object is found, traversal through the heap space stops at that
// point.
// The 'visitor' function should return false if the object is not found,
// traversal through the heap space continues.
// Returns null object if nothing is found.
InstructionsPtr FindObjectInCodeSpace(FindObjectVisitor* visitor) const;
ObjectPtr FindOldObject(FindObjectVisitor* visitor) const;
ObjectPtr FindNewObject(FindObjectVisitor* visitor);
ObjectPtr FindObject(FindObjectVisitor* visitor);
void NotifyIdle(int64_t deadline);
void NotifyDestroyed();

View file

@ -43,7 +43,6 @@ heap_sources_tests = [
"freelist_test.cc",
"heap_test.cc",
"pages_test.cc",
"scavenger_test.cc",
"weak_table_test.cc",
"safepoint_test.cc",
]

View file

@ -212,48 +212,6 @@ TEST_CASE(ClassHeapStats) {
}
#endif // !PRODUCT
class FindOnly : public FindObjectVisitor {
public:
explicit FindOnly(ObjectPtr target) : target_(target) {
#if defined(DEBUG)
EXPECT_GT(Thread::Current()->no_safepoint_scope_depth(), 0);
#endif
}
virtual ~FindOnly() {}
virtual bool FindObject(ObjectPtr obj) const { return obj == target_; }
private:
ObjectPtr target_;
};
class FindNothing : public FindObjectVisitor {
public:
FindNothing() {}
virtual ~FindNothing() {}
virtual bool FindObject(ObjectPtr obj) const { return false; }
};
ISOLATE_UNIT_TEST_CASE(FindObject) {
Heap* heap = IsolateGroup::Current()->heap();
Heap::Space spaces[2] = {Heap::kOld, Heap::kNew};
for (size_t space = 0; space < ARRAY_SIZE(spaces); ++space) {
const String& obj = String::Handle(String::New("x", spaces[space]));
{
HeapIterationScope iteration(thread);
NoSafepointScope no_safepoint;
FindOnly find_only(obj.ptr());
EXPECT(obj.ptr() == heap->FindObject(&find_only));
}
}
{
HeapIterationScope iteration(thread);
NoSafepointScope no_safepoint;
FindNothing find_nothing;
EXPECT(Object::null() == heap->FindObject(&find_nothing));
}
}
ISOLATE_UNIT_TEST_CASE(IterateReadOnly) {
const String& obj = String::Handle(String::New("x", Heap::kOld));

View file

@ -255,24 +255,6 @@ void Page::ResetProgressBar() {
progress_bar_ = 0;
}
ObjectPtr Page::FindObject(FindObjectVisitor* visitor) const {
uword obj_addr = object_start();
uword end_addr = object_end();
if (visitor->VisitRange(obj_addr, end_addr)) {
while (obj_addr < end_addr) {
ObjectPtr raw_obj = UntaggedObject::FromAddr(obj_addr);
uword next_obj_addr = obj_addr + raw_obj->untag()->HeapSize();
if (visitor->VisitRange(obj_addr, next_obj_addr) &&
raw_obj->untag()->FindObject(visitor)) {
return raw_obj; // Found object, return it.
}
obj_addr = next_obj_addr;
}
ASSERT(obj_addr == end_addr);
}
return Object::null();
}
void Page::WriteProtect(bool read_only) {
ASSERT(!is_image());

View file

@ -17,7 +17,6 @@ namespace dart {
class ForwardingPage;
class ObjectVisitor;
class ObjectPointerVisitor;
class FindObjectVisitor;
class Thread;
class UnwindingRecords;
@ -115,8 +114,6 @@ class Page {
void VisitObjects(ObjectVisitor* visitor) const;
void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
ObjectPtr FindObject(FindObjectVisitor* visitor) const;
void WriteProtect(bool read_only);
constexpr static intptr_t OldObjectStartOffset() {

View file

@ -681,28 +681,6 @@ void PageSpace::ResetProgressBars() const {
}
}
ObjectPtr PageSpace::FindObject(FindObjectVisitor* visitor,
bool is_exec) const {
if (is_exec) {
for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
ObjectPtr obj = it.page()->FindObject(visitor);
if (obj != Object::null()) {
return obj;
}
}
} else {
for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
if (!it.page()->is_executable()) {
ObjectPtr obj = it.page()->FindObject(visitor);
if (obj != Object::null()) {
return obj;
}
}
}
}
return Object::null();
}
void PageSpace::WriteProtect(bool read_only) {
if (read_only) {
// Avoid MakeIterable trying to write to the heap.

View file

@ -212,8 +212,6 @@ class PageSpace {
void VisitRememberedCards(ObjectPointerVisitor* visitor) const;
void ResetProgressBars() const;
ObjectPtr FindObject(FindObjectVisitor* visitor, bool is_executable) const;
// Collect the garbage in the page space using mark-sweep or mark-compact.
void CollectGarbage(Thread* thread, bool compact, bool finalize);

View file

@ -1597,25 +1597,6 @@ void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
}
}
ObjectPtr Scavenger::FindObject(FindObjectVisitor* visitor) {
ASSERT(!scavenging_);
for (Page* page = to_->head(); page != nullptr; page = page->next()) {
uword cur = page->object_start();
if (!visitor->VisitRange(cur, page->object_end())) continue;
while (cur < page->object_end()) {
ObjectPtr raw_obj = UntaggedObject::FromAddr(cur);
uword next = cur + raw_obj->untag()->HeapSize();
if (visitor->VisitRange(cur, next) &&
raw_obj->untag()->FindObject(visitor)) {
return raw_obj; // Found object, return it.
}
cur = next;
}
ASSERT(cur == page->object_end());
}
return Object::null();
}
void Scavenger::TryAllocateNewTLAB(Thread* thread,
intptr_t min_size,
bool can_safepoint) {

View file

@ -130,8 +130,6 @@ class Scavenger {
// be part of the surviving objects.
bool Contains(uword addr) const { return to_->Contains(addr); }
ObjectPtr FindObject(FindObjectVisitor* visitor);
uword TryAllocate(Thread* thread, intptr_t size) {
uword addr = TryAllocateFromTLAB(thread, size);
if (LIKELY(addr != 0)) {

View file

@ -1,45 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/heap/scavenger.h"
#include "platform/assert.h"
#include "vm/unit_test.h"
#include "vm/visitor.h"
namespace dart {
// Expects to visit no objects (since the space should be empty).
class FailingObjectVisitor : public ObjectVisitor {
public:
FailingObjectVisitor() {}
void VisitObject(ObjectPtr obj) override { EXPECT(false); }
};
// Expects to visit no objects (since the space should be empty).
class FailingObjectPointerVisitor : public ObjectPointerVisitor {
public:
FailingObjectPointerVisitor() : ObjectPointerVisitor(nullptr) {}
void VisitPointers(ObjectPtr* first, ObjectPtr* last) override {
EXPECT(false);
}
#if defined(DART_COMPRESSED_POINTERS)
void VisitCompressedPointers(uword heap_base,
CompressedObjectPtr* first,
CompressedObjectPtr* last) override {
EXPECT(false);
}
#endif
};
// Expects to visit no objects (since the space should be empty).
class FailingFindObjectVisitor : public FindObjectVisitor {
public:
FailingFindObjectVisitor() {}
virtual bool FindObject(ObjectPtr obj) const {
EXPECT(false);
return false;
}
};
} // namespace dart

View file

@ -5162,21 +5162,22 @@ TEST_CASE(IsolateReload_StaticFieldInitialValueDoesnotChange) {
EXPECT_STREQ("42", SimpleInvokeStr(lib, "main"));
}
class FindNoInstancesOfClass : public FindObjectVisitor {
class CidCountingVisitor : public ObjectVisitor {
public:
explicit FindNoInstancesOfClass(intptr_t cid) : cid_(cid) {
#if defined(DEBUG)
EXPECT_GT(Thread::Current()->no_safepoint_scope_depth(), 0);
#endif
}
virtual ~FindNoInstancesOfClass() {}
explicit CidCountingVisitor(intptr_t cid) : cid_(cid) {}
virtual ~CidCountingVisitor() {}
virtual bool FindObject(ObjectPtr obj) const {
return obj->GetClassId() == cid_;
virtual void VisitObject(ObjectPtr obj) {
if (obj->GetClassId() == cid_) {
count_++;
}
}
intptr_t count() const { return count_; }
private:
intptr_t cid_;
intptr_t count_ = 0;
};
TEST_CASE(IsolateReload_DeleteStaticField) {
@ -5223,12 +5224,12 @@ TEST_CASE(IsolateReload_DeleteStaticField) {
{
HeapIterationScope iteration(thread);
NoSafepointScope no_safepoint;
FindNoInstancesOfClass find_only(cid);
Heap* heap = IsolateGroup::Current()->heap();
CidCountingVisitor counting_visitor(cid);
iteration.IterateObjects(&counting_visitor);
// We still expect to find references to static field values
// because they are not deleted after hot reload.
EXPECT_NE(heap->FindObject(&find_only), Object::null());
EXPECT_NE(counting_visitor.count(), 0);
}
}
}

View file

@ -18250,49 +18250,36 @@ void Code::NotifyCodeObservers(const char* name,
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
bool Code::SlowFindRawCodeVisitor::FindObject(ObjectPtr raw_obj) const {
return UntaggedCode::ContainsPC(raw_obj, pc_) &&
!Code::IsUnknownDartCode(Code::RawCast(raw_obj));
}
CodePtr Code::LookupCodeInIsolateGroup(IsolateGroup* isolate_group, uword pc) {
ASSERT((isolate_group == IsolateGroup::Current()) ||
(isolate_group == Dart::vm_isolate_group()));
if (isolate_group->heap() == nullptr) {
return Code::null();
}
HeapIterationScope heap_iteration_scope(Thread::Current());
SlowFindRawCodeVisitor visitor(pc);
ObjectPtr needle = isolate_group->heap()->FindOldObject(&visitor);
if (needle != Code::null()) {
return static_cast<CodePtr>(needle);
}
return Code::null();
}
CodePtr Code::LookupCode(uword pc) {
return LookupCodeInIsolateGroup(IsolateGroup::Current(), pc);
}
CodePtr Code::LookupCodeInVmIsolate(uword pc) {
return LookupCodeInIsolateGroup(Dart::vm_isolate_group(), pc);
}
// Given a pc and a timestamp, lookup the code.
CodePtr Code::FindCode(uword pc, int64_t timestamp) {
Code& code = Code::Handle(Code::LookupCode(pc));
if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
(code.PayloadStart() == pc)) {
// Found code in isolate.
return code.ptr();
}
code = Code::LookupCodeInVmIsolate(pc);
if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
(code.PayloadStart() == pc)) {
// Found code in VM isolate.
return code.ptr();
}
return Code::null();
class SlowFindCodeVisitor : public ObjectVisitor {
public:
SlowFindCodeVisitor(uword pc, int64_t timestamp)
: pc_(pc), timestamp_(timestamp), result_(Code::null()) {}
void VisitObject(ObjectPtr obj) {
if (!obj->IsCode()) return;
CodePtr code = static_cast<CodePtr>(obj);
if (Code::PayloadStartOf(code) != pc_) return;
#if !defined(PRODUCT)
if (code->untag()->compile_timestamp_ != timestamp_) return;
#endif
ASSERT(result_ == Code::null());
result_ = code;
}
CodePtr result() const { return result_; }
private:
uword pc_;
int64_t timestamp_;
CodePtr result_;
};
HeapIterationScope iteration(Thread::Current());
SlowFindCodeVisitor visitor(pc, timestamp);
iteration.IterateVMIsolateObjects(&visitor);
iteration.IterateOldObjectsNoImagePages(&visitor);
return visitor.result();
}
TokenPosition Code::GetTokenIndexOfPC(uword pc) const {

View file

@ -6937,8 +6937,6 @@ class Code : public Object {
CodeStatistics* stats = nullptr);
#endif
static CodePtr LookupCode(uword pc);
static CodePtr LookupCodeInVmIsolate(uword pc);
static CodePtr FindCode(uword pc, int64_t timestamp);
int32_t GetPointerOffsetAt(int index) const {
@ -7032,20 +7030,6 @@ class Code : public Object {
class PtrOffBits
: public BitField<int32_t, intptr_t, kPtrOffBit, kPtrOffSize> {};
class SlowFindRawCodeVisitor : public FindObjectVisitor {
public:
explicit SlowFindRawCodeVisitor(uword pc) : pc_(pc) {}
virtual ~SlowFindRawCodeVisitor() {}
// Check if object matches find condition.
virtual bool FindObject(ObjectPtr obj) const;
private:
const uword pc_;
DISALLOW_COPY_AND_ASSIGN(SlowFindRawCodeVisitor);
};
static constexpr intptr_t kEntrySize = sizeof(int32_t); // NOLINT
void set_compile_timestamp(int64_t timestamp) const {

View file

@ -416,11 +416,6 @@ void UntaggedObject::VisitPointersPrecise(ObjectPointerVisitor* visitor) {
}
}
bool UntaggedObject::FindObject(FindObjectVisitor* visitor) {
ASSERT(visitor != nullptr);
return visitor->FindObject(static_cast<ObjectPtr>(this));
}
// Most objects are visited with this function. It calls the from() and to()
// methods on the raw object to get the first and last cells that need
// visiting.

View file

@ -400,7 +400,6 @@ class UntaggedObject {
}
void Validate(IsolateGroup* isolate_group) const;
bool FindObject(FindObjectVisitor* visitor);
// This function may access the class-ID in the header, but it cannot access
// the actual class object, because the sliding compactor uses this function

View file

@ -101,26 +101,6 @@ class ObjectVisitor {
DISALLOW_COPY_AND_ASSIGN(ObjectVisitor);
};
// An object finder visitor interface.
class FindObjectVisitor {
public:
FindObjectVisitor() {}
virtual ~FindObjectVisitor() {}
// Allow to specify a address filter.
virtual uword filter_addr() const { return 0; }
bool VisitRange(uword begin_addr, uword end_addr) const {
uword addr = filter_addr();
return (addr == 0) || ((begin_addr <= addr) && (addr < end_addr));
}
// Check if object matches find condition.
virtual bool FindObject(ObjectPtr obj) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(FindObjectVisitor);
};
} // namespace dart
#endif // RUNTIME_VM_VISITOR_H_