Skip to content

Commit 50067f0

Browse files
bartlomiejuclaude
andauthored
feat: expose individual ResourceConstraints setters and getters (#1918)
Add bindings for the V8 ResourceConstraints API so that embedders can set individual heap generation limits instead of only using the high-level ConfigureDefaultsFromHeapSize helper. New APIs on CreateParams: - set_max_old_generation_size_in_bytes / max_old_generation_size_in_bytes - set_max_young_generation_size_in_bytes / max_young_generation_size_in_bytes - set_code_range_size_in_bytes / code_range_size_in_bytes - set_stack_limit / stack_limit - set_initial_old_generation_size_in_bytes / initial_old_generation_size_in_bytes - set_initial_young_generation_size_in_bytes / initial_young_generation_size_in_bytes This is needed by Deno to properly implement Node.js-compatible worker thread resource limits (maxOldGenerationSizeMb, maxYoungGenerationSizeMb, codeRangeSizeMb, stackSizeMb). --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent dbdaa01 commit 50067f0

File tree

4 files changed

+366
-2
lines changed

4 files changed

+366
-2
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ jobs:
143143
uses: cargo-bins/cargo-binstall@main
144144

145145
- name: Install nextest
146-
run: cargo binstall cargo-nextest --secure --locked --no-confirm
146+
run: cargo binstall cargo-nextest@0.9.126 --secure --locked --no-confirm
147147
env:
148148
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
149149

@@ -293,7 +293,7 @@ jobs:
293293
uses: cargo-bins/cargo-binstall@main
294294

295295
- name: Install nextest
296-
run: cargo binstall cargo-nextest --secure --locked
296+
run: cargo binstall cargo-nextest@0.9.126 --secure --locked
297297

298298
- name: Install python
299299
uses: actions/setup-python@v5

src/binding.cc

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,66 @@ void v8__ResourceConstraints__ConfigureDefaults(
432432
constraints->ConfigureDefaults(physical_memory, virtual_memory_limit);
433433
}
434434

435+
size_t v8__ResourceConstraints__max_old_generation_size_in_bytes(
436+
const v8::ResourceConstraints* constraints) {
437+
return constraints->max_old_generation_size_in_bytes();
438+
}
439+
440+
void v8__ResourceConstraints__set_max_old_generation_size_in_bytes(
441+
v8::ResourceConstraints* constraints, size_t limit) {
442+
constraints->set_max_old_generation_size_in_bytes(limit);
443+
}
444+
445+
size_t v8__ResourceConstraints__max_young_generation_size_in_bytes(
446+
const v8::ResourceConstraints* constraints) {
447+
return constraints->max_young_generation_size_in_bytes();
448+
}
449+
450+
void v8__ResourceConstraints__set_max_young_generation_size_in_bytes(
451+
v8::ResourceConstraints* constraints, size_t limit) {
452+
constraints->set_max_young_generation_size_in_bytes(limit);
453+
}
454+
455+
size_t v8__ResourceConstraints__code_range_size_in_bytes(
456+
const v8::ResourceConstraints* constraints) {
457+
return constraints->code_range_size_in_bytes();
458+
}
459+
460+
void v8__ResourceConstraints__set_code_range_size_in_bytes(
461+
v8::ResourceConstraints* constraints, size_t limit) {
462+
constraints->set_code_range_size_in_bytes(limit);
463+
}
464+
465+
uint32_t* v8__ResourceConstraints__stack_limit(
466+
const v8::ResourceConstraints* constraints) {
467+
return constraints->stack_limit();
468+
}
469+
470+
void v8__ResourceConstraints__set_stack_limit(
471+
v8::ResourceConstraints* constraints, uint32_t* value) {
472+
constraints->set_stack_limit(value);
473+
}
474+
475+
size_t v8__ResourceConstraints__initial_old_generation_size_in_bytes(
476+
const v8::ResourceConstraints* constraints) {
477+
return constraints->initial_old_generation_size_in_bytes();
478+
}
479+
480+
void v8__ResourceConstraints__set_initial_old_generation_size_in_bytes(
481+
v8::ResourceConstraints* constraints, size_t initial_size) {
482+
constraints->set_initial_old_generation_size_in_bytes(initial_size);
483+
}
484+
485+
size_t v8__ResourceConstraints__initial_young_generation_size_in_bytes(
486+
const v8::ResourceConstraints* constraints) {
487+
return constraints->initial_young_generation_size_in_bytes();
488+
}
489+
490+
void v8__ResourceConstraints__set_initial_young_generation_size_in_bytes(
491+
v8::ResourceConstraints* constraints, size_t initial_size) {
492+
constraints->set_initial_young_generation_size_in_bytes(initial_size);
493+
}
494+
435495
void v8__HandleScope__CONSTRUCT(uninit_t<v8::HandleScope>* buf,
436496
v8::Isolate* isolate) {
437497
construct_in_place<v8::HandleScope>(buf, isolate);

src/isolate_create_params.rs

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,110 @@ impl CreateParams {
173173
self
174174
}
175175

176+
/// Returns the maximum size of the old generation in bytes.
177+
pub fn max_old_generation_size_in_bytes(&self) -> usize {
178+
self.raw.constraints.max_old_generation_size_in_bytes()
179+
}
180+
181+
/// Sets the maximum size of the old generation in bytes. When the old
182+
/// generation approaches this limit, V8 will perform series of garbage
183+
/// collections and invoke the NearHeapLimitCallback.
184+
pub fn set_max_old_generation_size_in_bytes(mut self, limit: usize) -> Self {
185+
self
186+
.raw
187+
.constraints
188+
.set_max_old_generation_size_in_bytes(limit);
189+
self
190+
}
191+
192+
/// Returns the maximum size of the young generation in bytes.
193+
pub fn max_young_generation_size_in_bytes(&self) -> usize {
194+
self.raw.constraints.max_young_generation_size_in_bytes()
195+
}
196+
197+
/// Sets the maximum size of the young generation in bytes. The young
198+
/// generation consists of two semi-spaces and a large object space. This
199+
/// affects frequency of Scavenge garbage collections.
200+
pub fn set_max_young_generation_size_in_bytes(
201+
mut self,
202+
limit: usize,
203+
) -> Self {
204+
self
205+
.raw
206+
.constraints
207+
.set_max_young_generation_size_in_bytes(limit);
208+
self
209+
}
210+
211+
/// Returns the code range size in bytes.
212+
pub fn code_range_size_in_bytes(&self) -> usize {
213+
self.raw.constraints.code_range_size_in_bytes()
214+
}
215+
216+
/// Sets the amount of virtual memory reserved for generated code in bytes.
217+
/// This is relevant for 64-bit architectures that rely on code range for
218+
/// calls in code.
219+
pub fn set_code_range_size_in_bytes(mut self, limit: usize) -> Self {
220+
self.raw.constraints.set_code_range_size_in_bytes(limit);
221+
self
222+
}
223+
224+
/// Returns the stack limit (the address beyond which the VM's stack may
225+
/// not grow), or null if not set.
226+
pub fn stack_limit(&self) -> *mut u32 {
227+
self.raw.constraints.stack_limit()
228+
}
229+
230+
/// Sets the address beyond which the VM's stack may not grow.
231+
///
232+
/// # Safety
233+
///
234+
/// The caller must ensure that the pointer remains valid for the lifetime
235+
/// of the isolate, and points to a valid stack boundary.
236+
pub unsafe fn set_stack_limit(mut self, value: *mut u32) -> Self {
237+
self.raw.constraints.set_stack_limit(value);
238+
self
239+
}
240+
241+
/// Returns the initial size of the old generation in bytes.
242+
pub fn initial_old_generation_size_in_bytes(&self) -> usize {
243+
self.raw.constraints.initial_old_generation_size_in_bytes()
244+
}
245+
246+
/// Sets the initial size of the old generation in bytes. Setting the
247+
/// initial size avoids ineffective garbage collections at startup if the
248+
/// live set is large.
249+
pub fn set_initial_old_generation_size_in_bytes(
250+
mut self,
251+
initial_size: usize,
252+
) -> Self {
253+
self
254+
.raw
255+
.constraints
256+
.set_initial_old_generation_size_in_bytes(initial_size);
257+
self
258+
}
259+
260+
/// Returns the initial size of the young generation in bytes.
261+
pub fn initial_young_generation_size_in_bytes(&self) -> usize {
262+
self
263+
.raw
264+
.constraints
265+
.initial_young_generation_size_in_bytes()
266+
}
267+
268+
/// Sets the initial size of the young generation in bytes.
269+
pub fn set_initial_young_generation_size_in_bytes(
270+
mut self,
271+
initial_size: usize,
272+
) -> Self {
273+
self
274+
.raw
275+
.constraints
276+
.set_initial_young_generation_size_in_bytes(initial_size);
277+
self
278+
}
279+
176280
/// A CppHeap used to construct the Isolate. V8 takes ownership of the
177281
/// CppHeap passed this way.
178282
pub fn cpp_heap(mut self, heap: UniqueRef<Heap>) -> Self {
@@ -267,6 +371,48 @@ pub(crate) mod raw {
267371
physical_memory: u64,
268372
virtual_memory_limit: u64,
269373
);
374+
fn v8__ResourceConstraints__max_old_generation_size_in_bytes(
375+
constraints: *const ResourceConstraints,
376+
) -> usize;
377+
fn v8__ResourceConstraints__set_max_old_generation_size_in_bytes(
378+
constraints: *mut ResourceConstraints,
379+
limit: usize,
380+
);
381+
fn v8__ResourceConstraints__max_young_generation_size_in_bytes(
382+
constraints: *const ResourceConstraints,
383+
) -> usize;
384+
fn v8__ResourceConstraints__set_max_young_generation_size_in_bytes(
385+
constraints: *mut ResourceConstraints,
386+
limit: usize,
387+
);
388+
fn v8__ResourceConstraints__code_range_size_in_bytes(
389+
constraints: *const ResourceConstraints,
390+
) -> usize;
391+
fn v8__ResourceConstraints__set_code_range_size_in_bytes(
392+
constraints: *mut ResourceConstraints,
393+
limit: usize,
394+
);
395+
fn v8__ResourceConstraints__stack_limit(
396+
constraints: *const ResourceConstraints,
397+
) -> *mut u32;
398+
fn v8__ResourceConstraints__set_stack_limit(
399+
constraints: *mut ResourceConstraints,
400+
value: *mut u32,
401+
);
402+
fn v8__ResourceConstraints__initial_old_generation_size_in_bytes(
403+
constraints: *const ResourceConstraints,
404+
) -> usize;
405+
fn v8__ResourceConstraints__set_initial_old_generation_size_in_bytes(
406+
constraints: *mut ResourceConstraints,
407+
initial_size: usize,
408+
);
409+
fn v8__ResourceConstraints__initial_young_generation_size_in_bytes(
410+
constraints: *const ResourceConstraints,
411+
) -> usize;
412+
fn v8__ResourceConstraints__set_initial_young_generation_size_in_bytes(
413+
constraints: *mut ResourceConstraints,
414+
initial_size: usize,
415+
);
270416
}
271417

272418
impl ResourceConstraints {
@@ -297,5 +443,87 @@ pub(crate) mod raw {
297443
);
298444
}
299445
}
446+
447+
pub fn max_old_generation_size_in_bytes(&self) -> usize {
448+
unsafe { v8__ResourceConstraints__max_old_generation_size_in_bytes(self) }
449+
}
450+
451+
pub fn set_max_old_generation_size_in_bytes(&mut self, limit: usize) {
452+
unsafe {
453+
v8__ResourceConstraints__set_max_old_generation_size_in_bytes(
454+
self, limit,
455+
);
456+
}
457+
}
458+
459+
pub fn max_young_generation_size_in_bytes(&self) -> usize {
460+
unsafe {
461+
v8__ResourceConstraints__max_young_generation_size_in_bytes(self)
462+
}
463+
}
464+
465+
pub fn set_max_young_generation_size_in_bytes(&mut self, limit: usize) {
466+
unsafe {
467+
v8__ResourceConstraints__set_max_young_generation_size_in_bytes(
468+
self, limit,
469+
);
470+
}
471+
}
472+
473+
pub fn code_range_size_in_bytes(&self) -> usize {
474+
unsafe { v8__ResourceConstraints__code_range_size_in_bytes(self) }
475+
}
476+
477+
pub fn set_code_range_size_in_bytes(&mut self, limit: usize) {
478+
unsafe {
479+
v8__ResourceConstraints__set_code_range_size_in_bytes(self, limit);
480+
}
481+
}
482+
483+
pub fn stack_limit(&self) -> *mut u32 {
484+
unsafe { v8__ResourceConstraints__stack_limit(self) }
485+
}
486+
487+
pub fn set_stack_limit(&mut self, value: *mut u32) {
488+
unsafe {
489+
v8__ResourceConstraints__set_stack_limit(self, value);
490+
}
491+
}
492+
493+
pub fn initial_old_generation_size_in_bytes(&self) -> usize {
494+
unsafe {
495+
v8__ResourceConstraints__initial_old_generation_size_in_bytes(self)
496+
}
497+
}
498+
499+
pub fn set_initial_old_generation_size_in_bytes(
500+
&mut self,
501+
initial_size: usize,
502+
) {
503+
unsafe {
504+
v8__ResourceConstraints__set_initial_old_generation_size_in_bytes(
505+
self,
506+
initial_size,
507+
);
508+
}
509+
}
510+
511+
pub fn initial_young_generation_size_in_bytes(&self) -> usize {
512+
unsafe {
513+
v8__ResourceConstraints__initial_young_generation_size_in_bytes(self)
514+
}
515+
}
516+
517+
pub fn set_initial_young_generation_size_in_bytes(
518+
&mut self,
519+
initial_size: usize,
520+
) {
521+
unsafe {
522+
v8__ResourceConstraints__set_initial_young_generation_size_in_bytes(
523+
self,
524+
initial_size,
525+
);
526+
}
527+
}
300528
}
301529
}

0 commit comments

Comments
 (0)