mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:57:17 +00:00
[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:
parent
b5d63cb67f
commit
78daab15b3
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Reference in a new issue