Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion changelog.d/8464-closure-unwind-family.md

This file was deleted.

1 change: 1 addition & 0 deletions changelog.d/8482-revert-c-unwind-family.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
revert: back out #8464's blanket `extern "C-unwind"` conversion of the closure dispatch family. Measured on three sweeps: main carried **16** gap regressions both before the batch (`526e0b502`) and with the string PRs but without it (`3627657c7`), and **36** with it (`15a30d7f6`) — plus a newly-red `gc-stress`. It also did not fix the abort it was written for (#8479 still reproduces on Linux with the change in place). Converting a frame to `C-unwind` turns LLVM `call` into `invoke` and lets unwinding actually run through frames that were never designed to be unwound through — which holds locks, raw pointers and GC state — so the conversion cost stability without buying the fix.
4 changes: 2 additions & 2 deletions crates/perry-runtime/src/closure/dispatch/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ unsafe fn read_function_name_property(closure_ptr: usize) -> Option<String> {
/// `.name` is set to `"bound " + target.name` and `.length` to
/// `max(0, target.length - boundArgs.length)`, matching Node. Refs #2840.
#[no_mangle]
pub unsafe extern "C-unwind" fn js_function_bind(
pub unsafe extern "C" fn js_function_bind(
target_value: f64,
args_ptr: *const f64,
args_len: usize,
Expand Down Expand Up @@ -489,7 +489,7 @@ pub unsafe extern "C-unwind" fn js_function_bind(
/// survives the bitcode pipeline. See project_auto_optimize_keepalive_3320.
#[cfg(feature = "keepalive-anchors")]
#[used]
static KEEP_JS_FUNCTION_BIND: unsafe extern "C-unwind" fn(f64, *const f64, usize) -> f64 =
static KEEP_JS_FUNCTION_BIND: unsafe extern "C" fn(f64, *const f64, usize) -> f64 =
js_function_bind;

/// Reify a `Function.prototype.{bind,call,apply}` (or any function method)
Expand Down
73 changes: 32 additions & 41 deletions crates/perry-runtime/src/closure/dispatch/calln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use super::*;

/// Call a closure with 0 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call0(closure: *const ClosureHeader) -> f64 {
pub extern "C" fn js_closure_call0(closure: *const ClosureHeader) -> f64 {
let func_ptr = get_valid_func_ptr(closure);
if func_ptr.is_null() {
return dispatch_proxy_callee_or_throw(closure, &[]);
Expand All @@ -26,7 +26,7 @@ pub extern "C-unwind" fn js_closure_call0(closure: *const ClosureHeader) -> f64
dispatch_with_arity(closure, func_ptr, &[], declared)
},
_ => {
let func: extern "C-unwind" fn(*const ClosureHeader) -> f64 =
let func: extern "C" fn(*const ClosureHeader) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure)
}
Expand Down Expand Up @@ -84,7 +84,7 @@ pub extern "C-unwind" fn js_closure_call2(
dispatch_with_arity(closure, func_ptr, &[arg0, arg1], declared)
},
_ => {
let func: extern "C-unwind" fn(*const ClosureHeader, f64, f64) -> f64 =
let func: extern "C" fn(*const ClosureHeader, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1)
}
Expand All @@ -93,7 +93,7 @@ pub extern "C-unwind" fn js_closure_call2(

/// Call a closure with 3 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call3(
pub extern "C" fn js_closure_call3(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand All @@ -117,7 +117,7 @@ pub extern "C-unwind" fn js_closure_call3(
dispatch_with_arity(closure, func_ptr, &[arg0, arg1, arg2], declared)
},
_ => {
let func: extern "C-unwind" fn(*const ClosureHeader, f64, f64, f64) -> f64 =
let func: extern "C" fn(*const ClosureHeader, f64, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1, arg2)
}
Expand All @@ -126,7 +126,7 @@ pub extern "C-unwind" fn js_closure_call3(

/// Call a closure with 4 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call4(
pub extern "C" fn js_closure_call4(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -157,7 +157,7 @@ pub extern "C-unwind" fn js_closure_call4(
dispatch_with_arity(closure, func_ptr, &[arg0, arg1, arg2, arg3], declared)
},
_ => {
let func: extern "C-unwind" fn(*const ClosureHeader, f64, f64, f64, f64) -> f64 =
let func: extern "C" fn(*const ClosureHeader, f64, f64, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1, arg2, arg3)
}
Expand All @@ -166,7 +166,7 @@ pub extern "C-unwind" fn js_closure_call4(

/// Call a closure with 5 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call5(
pub extern "C" fn js_closure_call5(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -202,14 +202,14 @@ pub extern "C-unwind" fn js_closure_call5(
};
}
}
let func: extern "C-unwind" fn(*const ClosureHeader, f64, f64, f64, f64, f64) -> f64 =
let func: extern "C" fn(*const ClosureHeader, f64, f64, f64, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1, arg2, arg3, arg4)
}

/// Call a closure with 6 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call6(
pub extern "C" fn js_closure_call6(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -251,7 +251,7 @@ pub extern "C-unwind" fn js_closure_call6(
};
}
}
let func: extern "C-unwind" fn(*const ClosureHeader, f64, f64, f64, f64, f64, f64) -> f64 =
let func: extern "C" fn(*const ClosureHeader, f64, f64, f64, f64, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1, arg2, arg3, arg4, arg5)
}
Expand Down Expand Up @@ -291,7 +291,7 @@ pub(crate) fn dispatch_rest_or_declared_arity(

/// Call a closure with 7 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call7(
pub extern "C" fn js_closure_call7(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand All @@ -316,14 +316,14 @@ pub extern "C-unwind" fn js_closure_call7(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 7) {
return result;
}
let func: extern "C-unwind" fn(*const ClosureHeader, f64, f64, f64, f64, f64, f64, f64) -> f64 =
let func: extern "C" fn(*const ClosureHeader, f64, f64, f64, f64, f64, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
}

/// Call a closure with 8 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call8(
pub extern "C" fn js_closure_call8(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand All @@ -349,23 +349,14 @@ pub extern "C-unwind" fn js_closure_call8(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 8) {
return result;
}
let func: extern "C-unwind" fn(
*const ClosureHeader,
f64,
f64,
f64,
f64,
f64,
f64,
f64,
f64,
) -> f64 = unsafe { std::mem::transmute(func_ptr) };
let func: extern "C" fn(*const ClosureHeader, f64, f64, f64, f64, f64, f64, f64, f64) -> f64 =
unsafe { std::mem::transmute(func_ptr) };
func(closure, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
}

/// Call a closure with 9 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call9(
pub extern "C" fn js_closure_call9(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand All @@ -392,7 +383,7 @@ pub extern "C-unwind" fn js_closure_call9(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 9) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -411,7 +402,7 @@ pub extern "C-unwind" fn js_closure_call9(

/// Call a closure with 10 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call10(
pub extern "C" fn js_closure_call10(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -439,7 +430,7 @@ pub extern "C-unwind" fn js_closure_call10(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 10) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -459,7 +450,7 @@ pub extern "C-unwind" fn js_closure_call10(

/// Call a closure with 11 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call11(
pub extern "C" fn js_closure_call11(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -494,7 +485,7 @@ pub extern "C-unwind" fn js_closure_call11(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 11) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -515,7 +506,7 @@ pub extern "C-unwind" fn js_closure_call11(

/// Call a closure with 12 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call12(
pub extern "C" fn js_closure_call12(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -551,7 +542,7 @@ pub extern "C-unwind" fn js_closure_call12(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 12) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -573,7 +564,7 @@ pub extern "C-unwind" fn js_closure_call12(

/// Call a closure with 13 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call13(
pub extern "C" fn js_closure_call13(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -610,7 +601,7 @@ pub extern "C-unwind" fn js_closure_call13(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 13) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -633,7 +624,7 @@ pub extern "C-unwind" fn js_closure_call13(

/// Call a closure with 14 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call14(
pub extern "C" fn js_closure_call14(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -672,7 +663,7 @@ pub extern "C-unwind" fn js_closure_call14(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 14) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -697,7 +688,7 @@ pub extern "C-unwind" fn js_closure_call14(

/// Call a closure with 15 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call15(
pub extern "C" fn js_closure_call15(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -739,7 +730,7 @@ pub extern "C-unwind" fn js_closure_call15(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 15) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand All @@ -765,7 +756,7 @@ pub extern "C-unwind" fn js_closure_call15(

/// Call a closure with 16 arguments, returning f64
#[no_mangle]
pub extern "C-unwind" fn js_closure_call16(
pub extern "C" fn js_closure_call16(
closure: *const ClosureHeader,
arg0: f64,
arg1: f64,
Expand Down Expand Up @@ -808,7 +799,7 @@ pub extern "C-unwind" fn js_closure_call16(
if let Some(result) = dispatch_rest_or_declared_arity(closure, func_ptr, &args, 16) {
return result;
}
let func: extern "C-unwind" fn(
let func: extern "C" fn(
*const ClosureHeader,
f64,
f64,
Expand Down
8 changes: 4 additions & 4 deletions crates/perry-runtime/src/closure/dispatch/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ macro_rules! define_direct_call_site {
) => {
$(#[$meta])*
#[derive(Clone, Copy)]
pub struct $site(Option<extern "C-unwind" fn(*const ClosureHeader, $(define_direct_call_site!(@f64 $arg)),+) -> f64>);
pub struct $site(Option<extern "C" fn(*const ClosureHeader, $(define_direct_call_site!(@f64 $arg)),+) -> f64>);

impl $site {
/// Resolve `closure` once, before the loop.
Expand All @@ -98,7 +98,7 @@ macro_rules! define_direct_call_site {
$site(resolve_direct_func_ptr(closure, $arity).map(|func_ptr| unsafe {
std::mem::transmute::<
*const u8,
extern "C-unwind" fn(*const ClosureHeader, $(define_direct_call_site!(@f64 $arg)),+) -> f64,
extern "C" fn(*const ClosureHeader, $(define_direct_call_site!(@f64 $arg)),+) -> f64,
>(func_ptr)
}))
}
Expand Down Expand Up @@ -174,11 +174,11 @@ mod tests {

// A capture-less body behind a real `ClosureHeader`, the same way
// `array/tests.rs` and `array/typed_array_receiver_tests.rs` build theirs.
extern "C-unwind" fn add3(_c: *const ClosureHeader, a: f64, b: f64, c: f64) -> f64 {
extern "C" fn add3(_c: *const ClosureHeader, a: f64, b: f64, c: f64) -> f64 {
a * 100.0 + b * 10.0 + c
}

extern "C-unwind" fn sum2(_c: *const ClosureHeader, a: f64, b: f64) -> f64 {
extern "C" fn sum2(_c: *const ClosureHeader, a: f64, b: f64) -> f64 {
a + b
}

Expand Down
4 changes: 2 additions & 2 deletions crates/perry-runtime/src/closure/dispatch/value_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ pub unsafe extern "C-unwind" fn js_native_call_value(
/// rather than xmm0 — matching the trampoline's `extern "C"` int-arg
/// expectation.
#[no_mangle]
pub unsafe extern "C-unwind" fn js_closure_call_array(
pub unsafe extern "C" fn js_closure_call_array(
closure_env: i64,
args_ptr: *const f64,
args_len: i64,
Expand Down Expand Up @@ -661,7 +661,7 @@ pub unsafe extern "C-unwind" fn js_closure_call_array(
/// `lower_expr` produces for a closure-typed expression). A null/undefined
/// box returns TAG_UNDEFINED.
#[no_mangle]
pub unsafe extern "C-unwind" fn js_closure_call_apply_with_spread(
pub unsafe extern "C" fn js_closure_call_apply_with_spread(
closure_box: f64,
regular_args: *const f64,
regular_count: i64,
Expand Down
5 changes: 2 additions & 3 deletions crates/perry-runtime/src/closure/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,15 +954,14 @@ pub unsafe fn dispatch_with_arity(
macro_rules! arm {
(@ty $i:tt) => { f64 };
($($i:tt),* $(,)?) => {{
let f: extern "C-unwind" fn(*const ClosureHeader $(, arm!(@ty $i))*) -> f64 =
let f: extern "C" fn(*const ClosureHeader $(, arm!(@ty $i))*) -> f64 =
std::mem::transmute(func_ptr);
f(closure $(, a!($i))*)
}};
}
match k {
0 => {
let f: extern "C-unwind" fn(*const ClosureHeader) -> f64 =
std::mem::transmute(func_ptr);
let f: extern "C" fn(*const ClosureHeader) -> f64 = std::mem::transmute(func_ptr);
f(closure)
}
1 => arm!(0),
Expand Down
Loading
Loading