@@ -16,8 +16,8 @@ limitations under the License.
1616#[ cfg( target_os = "linux" ) ]
1717use std:: time:: Duration ;
1818
19- use hyperlight_host:: sandbox:: { is_hypervisor_present , SandboxConfiguration } ;
20- use hyperlight_host:: { GuestBinary , HyperlightError , Result } ;
19+ use hyperlight_host:: sandbox:: SandboxConfiguration ;
20+ use hyperlight_host:: { is_hypervisor_present , GuestBinary , HyperlightError , Result } ;
2121
2222use super :: proto_js_sandbox:: ProtoJSSandbox ;
2323use crate :: HostPrintFn ;
@@ -28,16 +28,35 @@ pub struct SandboxBuilder {
2828 host_print_fn : Option < HostPrintFn > ,
2929}
3030
31- const MIN_STACK_SIZE : u64 = 256 * 1024 ;
32- // The minimum heap size is 4096KB.
31+ /// The minimum scratch size for the JS runtime sandbox.
32+ ///
33+ /// The scratch region provides writable physical memory for:
34+ /// - I/O buffers (input + output data)
35+ /// - Page table copies (proportional to snapshot size — our ~13 MB guest
36+ /// binary + heap produce ~72 KiB of page tables)
37+ /// - Dynamically allocated pages (GDT/IDT, stack growth, Copy-on-Write
38+ /// resolution during QuickJS initialisation)
39+ /// - Exception stack and metadata (2 pages at the top)
40+ ///
41+ /// Hyperlight's default scratch (288 KiB) is far too small for the JS
42+ /// runtime guest: after fixed overheads there are only ~44 free pages,
43+ /// which are exhausted during init. 1 MiB (0x10_0000) matches
44+ /// hyperlight's own "large guest" test configuration and gives
45+ /// comfortable headroom.
46+ const MIN_SCRATCH_SIZE : usize = 0x10_0000 ; // 1 MiB
47+
48+ /// The minimum heap size is 4 MiB. The QuickJS engine needs a
49+ /// reasonable amount of heap during initialisation for builtins,
50+ /// global objects, and the bytecode compiler. This lives in the
51+ /// identity-mapped snapshot region (NOT scratch).
3352const MIN_HEAP_SIZE : u64 = 4096 * 1024 ;
3453
3554impl SandboxBuilder {
3655 /// Create a new SandboxBuilder
3756 pub fn new ( ) -> Self {
3857 let mut config = SandboxConfiguration :: default ( ) ;
39- config. set_stack_size ( MIN_STACK_SIZE ) ;
4058 config. set_heap_size ( MIN_HEAP_SIZE ) ;
59+ config. set_scratch_size ( MIN_SCRATCH_SIZE ) ;
4160
4261 Self {
4362 config,
@@ -67,13 +86,14 @@ impl SandboxBuilder {
6786 self
6887 }
6988
70- /// Set the guest stack size
71- /// This is the size of the stack that code executing in the guest can use.
72- /// If this value is too small then the guest will fail with a stack overflow error
73- /// The default value (and minimum) is set to the value of the MIN_STACK_SIZE const.
74- pub fn with_guest_stack_size ( mut self , guest_stack_size : u64 ) -> Self {
75- if guest_stack_size > MIN_STACK_SIZE {
76- self . config . set_stack_size ( guest_stack_size) ;
89+ /// Set the guest scratch size in bytes.
90+ /// The scratch region provides writable memory for the guest, including the
91+ /// dynamically-sized stack. Increase this if your guest code needs deep
92+ /// recursion or large local variables.
93+ /// Values smaller than the default (288KiB) are ignored.
94+ pub fn with_guest_scratch_size ( mut self , guest_scratch_size : usize ) -> Self {
95+ if guest_scratch_size > MIN_SCRATCH_SIZE {
96+ self . config . set_scratch_size ( guest_scratch_size) ;
7797 }
7898 self
7999 }
0 commit comments