mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm] Delay allocating the ObjectIdRing until the first service request or response.
Avoids GC overhead when the VM service is not in use. Change-Id: Ic2e752c17fdd01045e30dd62e16f20896a9fc64e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/146440 Reviewed-by: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
f6d0f462fb
commit
147f0e3d94
|
@ -296,8 +296,9 @@ void Become::FollowForwardingPointers(Thread* thread) {
|
|||
isolate_group->ForEachIsolate(
|
||||
[&](Isolate* isolate) {
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ASSERT(ring != NULL);
|
||||
ring->VisitPointers(&pointer_visitor);
|
||||
if (ring != nullptr) {
|
||||
ring->VisitPointers(&pointer_visitor);
|
||||
}
|
||||
},
|
||||
/*at_safepoint=*/true);
|
||||
#endif // !PRODUCT
|
||||
|
|
|
@ -418,7 +418,10 @@ void CompactorTask::RunEnteredIsolateGroup() {
|
|||
TIMELINE_FUNCTION_GC_DURATION(thread, "ForwardObjectIdRing");
|
||||
isolate_group_->ForEachIsolate(
|
||||
[&](Isolate* isolate) {
|
||||
isolate->object_id_ring()->VisitPointers(compactor_);
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
if (ring != nullptr) {
|
||||
ring->VisitPointers(compactor_);
|
||||
}
|
||||
},
|
||||
/*at_safepoint=*/true);
|
||||
break;
|
||||
|
|
|
@ -1475,9 +1475,6 @@ Isolate::Isolate(IsolateGroup* isolate_group,
|
|||
#undef ISOLATE_METRIC_CONSTRUCTORS
|
||||
reload_every_n_stack_overflow_checks_(FLAG_reload_every),
|
||||
#endif // !defined(PRODUCT)
|
||||
#if !defined(PRODUCT)
|
||||
object_id_ring_(new ObjectIdRing()),
|
||||
#endif
|
||||
start_time_micros_(OS::GetCurrentMonotonicMicros()),
|
||||
random_(),
|
||||
mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
|
||||
|
@ -2780,7 +2777,10 @@ void IsolateGroup::VisitStackPointers(ObjectPointerVisitor* visitor,
|
|||
void IsolateGroup::VisitObjectIdRingPointers(ObjectPointerVisitor* visitor) {
|
||||
#if !defined(PRODUCT)
|
||||
for (Isolate* isolate : isolates_) {
|
||||
isolate->object_id_ring()->VisitPointers(visitor);
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
if (ring != nullptr) {
|
||||
ring->VisitPointers(visitor);
|
||||
}
|
||||
}
|
||||
#endif // !defined(PRODUCT)
|
||||
}
|
||||
|
@ -2840,6 +2840,15 @@ intptr_t IsolateGroup::GetClassSizeForHeapWalkAt(intptr_t cid) {
|
|||
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
ObjectIdRing* Isolate::EnsureObjectIdRing() {
|
||||
if (object_id_ring_ == nullptr) {
|
||||
object_id_ring_ = new ObjectIdRing();
|
||||
}
|
||||
return object_id_ring_;
|
||||
}
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
void Isolate::AddPendingDeopt(uword fp, uword pc) {
|
||||
// GrowableArray::Add is not atomic and may be interrupt by a profiler
|
||||
// stack walk.
|
||||
|
|
|
@ -955,7 +955,8 @@ class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
|
|||
}
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
ObjectIdRing* object_id_ring() { return object_id_ring_; }
|
||||
ObjectIdRing* object_id_ring() const { return object_id_ring_; }
|
||||
ObjectIdRing* EnsureObjectIdRing();
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
void AddPendingDeopt(uword fp, uword pc);
|
||||
|
|
|
@ -41,7 +41,7 @@ JSONStream::JSONStream(intptr_t buf_size)
|
|||
ObjectIdRing* ring = NULL;
|
||||
Isolate* isolate = Isolate::Current();
|
||||
if (isolate != NULL) {
|
||||
ring = isolate->object_id_ring();
|
||||
ring = isolate->EnsureObjectIdRing();
|
||||
}
|
||||
default_id_zone_.Init(ring, ObjectIdRing::kAllocateId);
|
||||
}
|
||||
|
|
|
@ -86,16 +86,16 @@ void ObjectIdRing::PrintJSON(JSONStream* js) {
|
|||
}
|
||||
}
|
||||
|
||||
ObjectIdRing::ObjectIdRing(int32_t capacity) {
|
||||
ASSERT(capacity > 0);
|
||||
ObjectIdRing::ObjectIdRing() {
|
||||
serial_num_ = 0;
|
||||
wrapped_ = false;
|
||||
table_ = NULL;
|
||||
SetCapacityAndMaxSerial(capacity, kMaxId);
|
||||
SetCapacityAndMaxSerial(kDefaultCapacity, kMaxId);
|
||||
}
|
||||
|
||||
void ObjectIdRing::SetCapacityAndMaxSerial(int32_t capacity,
|
||||
int32_t max_serial) {
|
||||
ASSERT(capacity > 0);
|
||||
ASSERT(max_serial <= kMaxId);
|
||||
capacity_ = capacity;
|
||||
if (table_ != NULL) {
|
||||
|
|
|
@ -39,7 +39,7 @@ class ObjectIdRing {
|
|||
static const int32_t kInvalidId = -1;
|
||||
static const int32_t kDefaultCapacity = 8192;
|
||||
|
||||
explicit ObjectIdRing(int32_t capacity = kDefaultCapacity);
|
||||
ObjectIdRing();
|
||||
~ObjectIdRing();
|
||||
|
||||
// Adds the argument to the ring and returns its id. Note we do not allow
|
||||
|
|
|
@ -52,7 +52,7 @@ class ObjectIdRingTestHelper {
|
|||
// Test that serial number wrapping works.
|
||||
ISOLATE_UNIT_TEST_CASE(ObjectIdRingSerialWrapTest) {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
ObjectIdRingTestHelper::SetCapacityAndMaxSerial(ring, 2, 4);
|
||||
intptr_t id;
|
||||
ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
|
||||
|
@ -137,7 +137,7 @@ TEST_CASE(ObjectIdRingScavengeMoveTest) {
|
|||
EXPECT_EQ(3, list_length);
|
||||
|
||||
Isolate* isolate = thread->isolate();
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
|
||||
|
||||
{
|
||||
|
@ -196,7 +196,7 @@ TEST_CASE(ObjectIdRingScavengeMoveTest) {
|
|||
// Test that the ring table is updated with nulls when the old GC collects.
|
||||
ISOLATE_UNIT_TEST_CASE(ObjectIdRingOldGCTest) {
|
||||
Isolate* isolate = thread->isolate();
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
|
||||
ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
|
||||
intptr_t raw_obj_id1 = -1;
|
||||
|
@ -241,7 +241,7 @@ ISOLATE_UNIT_TEST_CASE(ObjectIdRingOldGCTest) {
|
|||
// overridden by new entries.
|
||||
ISOLATE_UNIT_TEST_CASE(ObjectIdRingExpiredEntryTest) {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
|
||||
// Insert an object and check we can look it up.
|
||||
String& obj = String::Handle(String::New("I will expire"));
|
||||
|
|
|
@ -1685,8 +1685,7 @@ static ObjectPtr LookupObjectId(Thread* thread,
|
|||
return Object::null();
|
||||
}
|
||||
|
||||
ObjectIdRing* ring = thread->isolate()->object_id_ring();
|
||||
ASSERT(ring != NULL);
|
||||
ObjectIdRing* ring = thread->isolate()->EnsureObjectIdRing();
|
||||
intptr_t id = -1;
|
||||
if (!GetIntegerId(arg, &id)) {
|
||||
*kind = ObjectIdRing::kInvalid;
|
||||
|
|
|
@ -186,7 +186,7 @@ ISOLATE_UNIT_TEST_CASE(Service_IsolateStickyError) {
|
|||
ISOLATE_UNIT_TEST_CASE(Service_IdZones) {
|
||||
Zone* zone = thread->zone();
|
||||
Isolate* isolate = thread->isolate();
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
|
||||
const String& test_a = String::Handle(zone, String::New("a"));
|
||||
const String& test_b = String::Handle(zone, String::New("b"));
|
||||
|
@ -384,7 +384,7 @@ ISOLATE_UNIT_TEST_CASE(Service_PcDescriptors) {
|
|||
const PcDescriptors& descriptors =
|
||||
PcDescriptors::Handle(code_c.pc_descriptors());
|
||||
EXPECT(!descriptors.IsNull());
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
intptr_t id = ring->GetIdForObject(descriptors.raw());
|
||||
|
||||
// Build a mock message handler and wrap it in a dart port.
|
||||
|
@ -455,7 +455,7 @@ ISOLATE_UNIT_TEST_CASE(Service_LocalVarDescriptors) {
|
|||
const LocalVarDescriptors& descriptors =
|
||||
LocalVarDescriptors::Handle(code_c.GetLocalVarDescriptors());
|
||||
// Generate an ID for this object.
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ObjectIdRing* ring = isolate->EnsureObjectIdRing();
|
||||
intptr_t id = ring->GetIdForObject(descriptors.raw());
|
||||
|
||||
// Build a mock message handler and wrap it in a dart port.
|
||||
|
|
Loading…
Reference in a new issue