Skip to content
This repository was archived by the owner on Mar 24, 2022. It is now read-only.

Commit dfdd17c

Browse files
committed
Allow use of pinned heap registers
1 parent e95a1bf commit dfdd17c

13 files changed

Lines changed: 111 additions & 14 deletions

File tree

benchmarks/lucet-benchmarks/src/context.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ fn context_init(c: &mut Criterion) {
99

1010
c.bench_function("context_init", move |b| {
1111
b.iter(|| {
12-
ContextHandle::create_and_init(&mut *stack, f as usize, &[]).unwrap();
12+
ContextHandle::create_and_init(&mut *stack, f as usize, &[], std::ptr::null_mut())
13+
.unwrap();
1314
})
1415
});
1516
}
@@ -22,7 +23,13 @@ fn context_swap_return(c: &mut Criterion) {
2223
b.iter_batched(
2324
|| {
2425
let mut stack = vec![0u64; 1024].into_boxed_slice();
25-
let child = ContextHandle::create_and_init(&mut *stack, f as usize, &[]).unwrap();
26+
let child = ContextHandle::create_and_init(
27+
&mut *stack,
28+
f as usize,
29+
&[],
30+
std::ptr::null_mut(),
31+
)
32+
.unwrap();
2633
(stack, child)
2734
},
2835
|(stack, mut child)| unsafe {
@@ -44,8 +51,13 @@ fn context_init_swap_return(c: &mut Criterion) {
4451
|| vec![0u64; 1024].into_boxed_slice(),
4552
|mut stack| {
4653
let mut parent = ContextHandle::new();
47-
let mut child =
48-
ContextHandle::create_and_init(&mut *stack, f as usize, &[]).unwrap();
54+
let mut child = ContextHandle::create_and_init(
55+
&mut *stack,
56+
f as usize,
57+
&[],
58+
std::ptr::null_mut(),
59+
)
60+
.unwrap();
4961
unsafe { Context::swap(&mut parent, &mut child) };
5062
stack
5163
},
@@ -332,8 +344,13 @@ fn context_init_swap_return_many_args(c: &mut Criterion) {
332344
|| vec![0u64; 1024].into_boxed_slice(),
333345
|mut stack| {
334346
let mut parent = ContextHandle::new();
335-
let mut child =
336-
ContextHandle::create_and_init(&mut *stack, f as usize, &args).unwrap();
347+
let mut child = ContextHandle::create_and_init(
348+
&mut *stack,
349+
f as usize,
350+
&args,
351+
std::ptr::null_mut(),
352+
)
353+
.unwrap();
337354
unsafe { Context::swap(&mut parent, &mut child) };
338355
stack
339356
},

lucet-module/src/module_data.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ pub struct ModuleFeatures {
5959
pub lzcnt: bool,
6060
pub popcnt: bool,
6161
pub instruction_count: bool,
62+
pub pinned_heap: bool,
63+
pub pinned_heap_register: u16,
6264
_hidden: (),
6365
}
6466

@@ -75,6 +77,8 @@ impl ModuleFeatures {
7577
lzcnt: false,
7678
popcnt: false,
7779
instruction_count: false,
80+
pinned_heap: false,
81+
pinned_heap_register: 0,
7882
_hidden: (),
7983
}
8084
}

lucet-runtime/lucet-runtime-internals/src/alloc/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ macro_rules! alloc_tests {
656656
inst.alloc_mut().stack_u64_mut(),
657657
heap_touching_child as usize,
658658
&[Val::CPtr(heap_ptr)],
659+
heap_ptr,
659660
)
660661
.expect("context init succeeds");
661662
Context::swap(&mut parent, &mut child);
@@ -705,6 +706,7 @@ macro_rules! alloc_tests {
705706
inst.alloc_mut().stack_u64_mut(),
706707
stack_pattern_child as usize,
707708
&[Val::CPtr(heap_ptr)],
709+
heap_ptr,
708710
)
709711
.expect("context init succeeds");
710712
Context::swap(&mut parent, &mut child);

lucet-runtime/lucet-runtime-internals/src/context/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,10 @@ impl ContextHandle {
208208
stack: &mut [u64],
209209
fptr: usize,
210210
args: &[Val],
211+
heap: *mut core::ffi::c_void,
211212
) -> Result<ContextHandle, Error> {
212213
let mut child = ContextHandle::new();
213-
Context::init(stack, &mut child, fptr, args)?;
214+
Context::init(stack, &mut child, fptr, args, heap)?;
214215
Ok(child)
215216
}
216217
}
@@ -303,6 +304,7 @@ impl Context {
303304
/// &mut child,
304305
/// entrypoint as usize,
305306
/// &[Val::U64(120), Val::F32(3.14)],
307+
/// std::ptr::null_mut(),
306308
/// );
307309
/// assert!(res.is_ok());
308310
/// ```
@@ -326,6 +328,7 @@ impl Context {
326328
/// &mut child,
327329
/// entrypoint as usize,
328330
/// &[Val::U64(120), Val::F32(3.14)],
331+
/// std::ptr::null_mut(),
329332
/// );
330333
/// assert!(res.is_ok());
331334
/// ```
@@ -367,6 +370,7 @@ impl Context {
367370
child: &mut Context,
368371
fptr: usize,
369372
args: &[Val],
373+
heap: *mut core::ffi::c_void,
370374
) -> Result<(), Error> {
371375
Context::init_with_callback(
372376
stack,
@@ -375,6 +379,7 @@ impl Context {
375379
ptr::null_mut(),
376380
fptr,
377381
args,
382+
heap,
378383
)
379384
}
380385

@@ -393,6 +398,7 @@ impl Context {
393398
callback_data: *mut Instance,
394399
fptr: usize,
395400
args: &[Val],
401+
heap: *mut core::ffi::c_void,
396402
) -> Result<(), Error> {
397403
if !stack_is_aligned(stack) {
398404
return Err(Error::UnalignedStack);
@@ -475,6 +481,10 @@ impl Context {
475481
// even at the entrypoint of the guest.
476482
child.gpr.rbp = child as *const Context as u64;
477483

484+
// Heap pinning: r15 is not used to pass any parameters on Windows/POSIX abis, we simply set this to be the value of the heap always.
485+
// This value will be used only when the lucet module loaded is compiled requiring use of the pinned heap register.
486+
child.gpr.r15 = heap as u64;
487+
478488
Ok(())
479489
}
480490

@@ -547,6 +557,7 @@ impl Context {
547557
/// &mut child,
548558
/// entrypoint as usize,
549559
/// &[],
560+
/// std::ptr::null_mut(),
550561
/// ).unwrap();
551562
///
552563
/// unsafe { Context::swap(&mut parent, &mut child); }

lucet-runtime/lucet-runtime-internals/src/context/tests/c_child.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ macro_rules! init_and_swap {
5555
&mut *$stack,
5656
$fn as usize,
5757
&[$( $args ),*],
58+
std::ptr::null_mut(),
5859
).unwrap()));
5960

6061
child_regs = child;

lucet-runtime/lucet-runtime-internals/src/context/tests/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ fn init_rejects_unaligned() {
3131
let mut stack_unaligned = unsafe { slice::from_raw_parts_mut(ptr, len) };
3232

3333
// now we have the unaligned stack, let's make sure it blows up right
34-
let res = ContextHandle::create_and_init(&mut stack_unaligned, dummy as usize, &[]);
34+
let res = ContextHandle::create_and_init(
35+
&mut stack_unaligned,
36+
dummy as usize,
37+
&[],
38+
std::ptr::null_mut(),
39+
);
3540

3641
if let Err(Error::UnalignedStack) = res {
3742
assert!(true);

lucet-runtime/lucet-runtime-internals/src/context/tests/rust_child.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ macro_rules! init_and_swap {
5151
&mut *$stack,
5252
$fn as usize,
5353
&[$( $args ),*],
54+
std::ptr::null_mut(),
5455
).unwrap();
5556
CHILD = Some(child);
5657

lucet-runtime/lucet-runtime-internals/src/instance.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,8 @@ impl Instance {
973973

974974
self.entrypoint = Some(func);
975975

976-
let mut args_with_vmctx = vec![Val::from(self.alloc.slot().heap)];
976+
let heap = self.alloc.slot().heap;
977+
let mut args_with_vmctx = vec![Val::from(heap)];
977978
args_with_vmctx.extend_from_slice(args);
978979

979980
let self_ptr = self as *mut _;
@@ -984,6 +985,7 @@ impl Instance {
984985
self_ptr,
985986
func.ptr.as_usize(),
986987
&args_with_vmctx,
988+
heap,
987989
)?;
988990

989991
self.install_activator();

lucetc/lucetc/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ pub fn run(opts: &Options) -> Result<(), Error> {
100100
.with_bindings(bindings)
101101
.with_opt_level(opts.opt_level)
102102
.with_cpu_features(opts.cpu_features.clone())
103-
.with_target(opts.target.clone());
103+
.with_target(opts.target.clone())
104+
.with_pinned_heap(opts.pinned_heap);
104105

105106
if let Some(validator) = validator.take() {
106107
c.validator(validator);

lucetc/lucetc/options.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ pub struct Options {
120120
pub pk_path: Option<PathBuf>,
121121
pub sk_path: Option<PathBuf>,
122122
pub count_instructions: bool,
123+
pub pinned_heap: bool,
123124
pub error_style: ErrorStyle,
124125
pub target: Triple,
125126
}
@@ -211,6 +212,7 @@ impl Options {
211212
let sk_path = m.value_of("sk_path").map(PathBuf::from);
212213
let pk_path = m.value_of("pk_path").map(PathBuf::from);
213214
let count_instructions = m.is_present("count_instructions");
215+
let pinned_heap = m.is_present("pinned_heap");
214216

215217
let error_style = match m.value_of("error_style") {
216218
None => ErrorStyle::default(),
@@ -239,6 +241,7 @@ impl Options {
239241
sk_path,
240242
pk_path,
241243
count_instructions,
244+
pinned_heap,
242245
error_style,
243246
target,
244247
})
@@ -452,6 +455,12 @@ SSE3 but not AVX:
452455
.takes_value(false)
453456
.help("Instrument the produced binary to count the number of wasm operations the translated program executes")
454457
)
458+
.arg(
459+
Arg::with_name("pinned_heap")
460+
.long("--pinned-heap-reg")
461+
.takes_value(false)
462+
.help("This feature is not stable - it may be removed in the future! Pin a register to use as this module's heap base. Typically improves performance.")
463+
)
455464
.arg(
456465
Arg::with_name("error_style")
457466
.long("error-style")

0 commit comments

Comments
 (0)