From eeefeece125d1432ccd83c7fc3955b373f9f82ed Mon Sep 17 00:00:00 2001 From: Kunal Sareen Date: Tue, 18 Mar 2025 03:53:18 +0000 Subject: [PATCH 1/5] Make work packet buffer size configurable from one location --- src/plan/tracing.rs | 4 ++-- src/scheduler/gc_work.rs | 2 +- src/util/constants.rs | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plan/tracing.rs b/src/plan/tracing.rs index 739caa657a..4a75cfd8dd 100644 --- a/src/plan/tracing.rs +++ b/src/plan/tracing.rs @@ -3,7 +3,7 @@ use crate::scheduler::gc_work::{ProcessEdgesWork, SlotOf}; use crate::scheduler::{GCWorker, WorkBucketStage}; -use crate::util::ObjectReference; +use crate::util::{self, ObjectReference}; use crate::vm::SlotVisitor; /// This trait represents an object queue to enqueue objects during tracing. @@ -25,7 +25,7 @@ pub struct VectorQueue { impl VectorQueue { /// Reserve a capacity of this on first enqueue to avoid frequent resizing. - const CAPACITY: usize = 4096; + const CAPACITY: usize = util::constants::BUFFER_SIZE; /// Create an empty `VectorObjectQueue`. pub fn new() -> Self { diff --git a/src/scheduler/gc_work.rs b/src/scheduler/gc_work.rs index 28d04c6874..4f6e95aae1 100644 --- a/src/scheduler/gc_work.rs +++ b/src/scheduler/gc_work.rs @@ -556,7 +556,7 @@ pub trait ProcessEdgesWork: /// Higher capacity means the packet will take longer to finish, and may lead to /// bad load balancing. On the other hand, lower capacity would lead to higher cost /// on scheduling many small work packets. It is important to find a proper capacity. - const CAPACITY: usize = 4096; + const CAPACITY: usize = util::constants::BUFFER_SIZE; /// Do we update object reference? This has to be true for a moving GC. const OVERWRITE_REFERENCE: bool = true; /// If true, we do object scanning in this work packet with the same worker without scheduling overhead. diff --git a/src/util/constants.rs b/src/util/constants.rs index df119778f7..ad37e14ea3 100644 --- a/src/util/constants.rs +++ b/src/util/constants.rs @@ -22,6 +22,9 @@ pub const LOG_BYTES_IN_KBYTE: u8 = 10; /// The number of bytes in a kilobyte pub const BYTES_IN_KBYTE: usize = 1 << LOG_BYTES_IN_KBYTE; +/// Work packet buffer size +pub const BUFFER_SIZE: usize = 4096; + /// Some card scanning constants ported from Java MMTK. /// As we haven't implemented card scanning, these are not used at the moment. mod card_scanning { From 5a9f203631a514034c23d9d76e90a819929242b6 Mon Sep 17 00:00:00 2001 From: Kunal Sareen Date: Mon, 24 Mar 2025 04:28:29 +0000 Subject: [PATCH 2/5] Address review comments --- src/plan/tracing.rs | 6 +++--- src/scheduler/gc_work.rs | 5 ++++- src/util/constants.rs | 3 --- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plan/tracing.rs b/src/plan/tracing.rs index 4a75cfd8dd..e868ca03ff 100644 --- a/src/plan/tracing.rs +++ b/src/plan/tracing.rs @@ -1,9 +1,9 @@ //! This module contains code useful for tracing, //! i.e. visiting the reachable objects by traversing all or part of an object graph. -use crate::scheduler::gc_work::{ProcessEdgesWork, SlotOf}; +use crate::scheduler::gc_work::{EDGES_WORK_BUFFER_SIZE, ProcessEdgesWork, SlotOf}; use crate::scheduler::{GCWorker, WorkBucketStage}; -use crate::util::{self, ObjectReference}; +use crate::util::ObjectReference; use crate::vm::SlotVisitor; /// This trait represents an object queue to enqueue objects during tracing. @@ -25,7 +25,7 @@ pub struct VectorQueue { impl VectorQueue { /// Reserve a capacity of this on first enqueue to avoid frequent resizing. - const CAPACITY: usize = util::constants::BUFFER_SIZE; + const CAPACITY: usize = EDGES_WORK_BUFFER_SIZE; /// Create an empty `VectorObjectQueue`. pub fn new() -> Self { diff --git a/src/scheduler/gc_work.rs b/src/scheduler/gc_work.rs index 4f6e95aae1..05c7043fde 100644 --- a/src/scheduler/gc_work.rs +++ b/src/scheduler/gc_work.rs @@ -10,6 +10,9 @@ use crate::*; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; +/// Buffer size for [`ProcessEdgesWork`] work packets. +pub const EDGES_WORK_BUFFER_SIZE: usize = 4096; + pub struct ScheduleCollection; impl GCWork for ScheduleCollection { @@ -556,7 +559,7 @@ pub trait ProcessEdgesWork: /// Higher capacity means the packet will take longer to finish, and may lead to /// bad load balancing. On the other hand, lower capacity would lead to higher cost /// on scheduling many small work packets. It is important to find a proper capacity. - const CAPACITY: usize = util::constants::BUFFER_SIZE; + const CAPACITY: usize = EDGES_WORK_BUFFER_SIZE; /// Do we update object reference? This has to be true for a moving GC. const OVERWRITE_REFERENCE: bool = true; /// If true, we do object scanning in this work packet with the same worker without scheduling overhead. diff --git a/src/util/constants.rs b/src/util/constants.rs index ad37e14ea3..df119778f7 100644 --- a/src/util/constants.rs +++ b/src/util/constants.rs @@ -22,9 +22,6 @@ pub const LOG_BYTES_IN_KBYTE: u8 = 10; /// The number of bytes in a kilobyte pub const BYTES_IN_KBYTE: usize = 1 << LOG_BYTES_IN_KBYTE; -/// Work packet buffer size -pub const BUFFER_SIZE: usize = 4096; - /// Some card scanning constants ported from Java MMTK. /// As we haven't implemented card scanning, these are not used at the moment. mod card_scanning { From f25e41daf8015f834f3b2ab990c6d5afc3ae458b Mon Sep 17 00:00:00 2001 From: Kunal Sareen Date: Mon, 24 Mar 2025 04:31:53 +0000 Subject: [PATCH 3/5] Improve doccomment for the constant --- src/scheduler/gc_work.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/scheduler/gc_work.rs b/src/scheduler/gc_work.rs index 05c7043fde..3ea1482e7c 100644 --- a/src/scheduler/gc_work.rs +++ b/src/scheduler/gc_work.rs @@ -10,7 +10,10 @@ use crate::*; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; -/// Buffer size for [`ProcessEdgesWork`] work packets. +/// Buffer size for [`ProcessEdgesWork`] work packets. This constant is exposed to users so that +/// they can use this value for places in their binding that interface with the work packet system, +/// specifically the transitive closure via `ProcessEdgesWork` work packets such as roots gathering +/// code or weak reference processing. pub const EDGES_WORK_BUFFER_SIZE: usize = 4096; pub struct ScheduleCollection; From 570f755366137a64143f403f9adc7168fc81e041 Mon Sep 17 00:00:00 2001 From: Kunal Sareen Date: Mon, 24 Mar 2025 05:05:34 +0000 Subject: [PATCH 4/5] Address review comments --- src/scheduler/gc_work.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/scheduler/gc_work.rs b/src/scheduler/gc_work.rs index 3ea1482e7c..6ec06a608d 100644 --- a/src/scheduler/gc_work.rs +++ b/src/scheduler/gc_work.rs @@ -10,10 +10,12 @@ use crate::*; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; -/// Buffer size for [`ProcessEdgesWork`] work packets. This constant is exposed to users so that -/// they can use this value for places in their binding that interface with the work packet system, -/// specifically the transitive closure via `ProcessEdgesWork` work packets such as roots gathering -/// code or weak reference processing. +/// Buffer size for [`ProcessEdgesWork`] work packets. This constant is exposed to binding +/// developers so that they can use this value for places in their binding that interface with the +/// work packet system, specifically the transitive closure via `ProcessEdgesWork` work packets +/// such as roots gathering code or weak reference processing. In order to have better load +/// balancing, it is recommended that binding developers use this constant to split work up into +/// different work packets. pub const EDGES_WORK_BUFFER_SIZE: usize = 4096; pub struct ScheduleCollection; From 0fa644e7b1ef2c9b6eeacd8b05eea1add411afec Mon Sep 17 00:00:00 2001 From: Kunal Sareen Date: Mon, 24 Mar 2025 05:11:00 +0000 Subject: [PATCH 5/5] cargo fmt --- src/plan/tracing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plan/tracing.rs b/src/plan/tracing.rs index e868ca03ff..6876fe4a04 100644 --- a/src/plan/tracing.rs +++ b/src/plan/tracing.rs @@ -1,7 +1,7 @@ //! This module contains code useful for tracing, //! i.e. visiting the reachable objects by traversing all or part of an object graph. -use crate::scheduler::gc_work::{EDGES_WORK_BUFFER_SIZE, ProcessEdgesWork, SlotOf}; +use crate::scheduler::gc_work::{ProcessEdgesWork, SlotOf, EDGES_WORK_BUFFER_SIZE}; use crate::scheduler::{GCWorker, WorkBucketStage}; use crate::util::ObjectReference; use crate::vm::SlotVisitor;