11#[ cfg( target_os = "linux" ) ]
22use std:: time:: Duration ;
33
4- use hyperlight_host:: sandbox:: { is_hypervisor_present , SandboxConfiguration } ;
5- use hyperlight_host:: { GuestBinary , HyperlightError , Result } ;
4+ use hyperlight_host:: sandbox:: SandboxConfiguration ;
5+ use hyperlight_host:: { is_hypervisor_present , GuestBinary , HyperlightError , Result } ;
66
77use super :: proto_js_sandbox:: ProtoJSSandbox ;
88use crate :: HostPrintFn ;
@@ -13,16 +13,35 @@ pub struct SandboxBuilder {
1313 host_print_fn : Option < HostPrintFn > ,
1414}
1515
16- const MIN_STACK_SIZE : u64 = 256 * 1024 ;
17- // The minimum heap size is 4096KB.
16+ /// The minimum scratch size for the JS runtime sandbox.
17+ ///
18+ /// The scratch region provides writable physical memory for:
19+ /// - I/O buffers (input + output data)
20+ /// - Page table copies (proportional to snapshot size — our ~13 MB guest
21+ /// binary + heap produce ~72 KiB of page tables)
22+ /// - Dynamically allocated pages (GDT/IDT, stack growth, Copy-on-Write
23+ /// resolution during QuickJS initialisation)
24+ /// - Exception stack and metadata (2 pages at the top)
25+ ///
26+ /// Hyperlight's default scratch (288 KiB) is far too small for the JS
27+ /// runtime guest: after fixed overheads there are only ~44 free pages,
28+ /// which are exhausted during init. 1 MiB (0x10_0000) matches
29+ /// hyperlight's own "large guest" test configuration and gives
30+ /// comfortable headroom.
31+ const MIN_SCRATCH_SIZE : usize = 0x10_0000 ; // 1 MiB
32+
33+ /// The minimum heap size is 4 MiB. The QuickJS engine needs a
34+ /// reasonable amount of heap during initialisation for builtins,
35+ /// global objects, and the bytecode compiler. This lives in the
36+ /// identity-mapped snapshot region (NOT scratch).
1837const MIN_HEAP_SIZE : u64 = 4096 * 1024 ;
1938
2039impl SandboxBuilder {
2140 /// Create a new SandboxBuilder
2241 pub fn new ( ) -> Self {
2342 let mut config = SandboxConfiguration :: default ( ) ;
24- config. set_stack_size ( MIN_STACK_SIZE ) ;
2543 config. set_heap_size ( MIN_HEAP_SIZE ) ;
44+ config. set_scratch_size ( MIN_SCRATCH_SIZE ) ;
2645
2746 Self {
2847 config,
@@ -52,13 +71,14 @@ impl SandboxBuilder {
5271 self
5372 }
5473
55- /// Set the guest stack size
56- /// This is the size of the stack that code executing in the guest can use.
57- /// If this value is too small then the guest will fail with a stack overflow error
58- /// The default value (and minimum) is set to the value of the MIN_STACK_SIZE const.
59- pub fn with_guest_stack_size ( mut self , guest_stack_size : u64 ) -> Self {
60- if guest_stack_size > MIN_STACK_SIZE {
61- self . config . set_stack_size ( guest_stack_size) ;
74+ /// Set the guest scratch size in bytes.
75+ /// The scratch region provides writable memory for the guest, including the
76+ /// dynamically-sized stack. Increase this if your guest code needs deep
77+ /// recursion or large local variables.
78+ /// Values smaller than the default (288KiB) are ignored.
79+ pub fn with_guest_scratch_size ( mut self , guest_scratch_size : usize ) -> Self {
80+ if guest_scratch_size > MIN_SCRATCH_SIZE {
81+ self . config . set_scratch_size ( guest_scratch_size) ;
6282 }
6383 self
6484 }
0 commit comments