Skip to content

Commit b3fbcef

Browse files
bartlomiejuclaude
andcommitted
feat: expose individual ResourceConstraints setters and getters
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 62cbd61 commit b3fbcef

File tree

3 files changed

+374
-0
lines changed

3 files changed

+374
-0
lines changed

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

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

0 commit comments

Comments
 (0)