Skip to content

Commit

Permalink
perf: reduce generated error handling code in ops (#1033)
Browse files Browse the repository at this point in the history
deno release build is about 700kb smaller with this patch
  • Loading branch information
ry authored Jan 7, 2025
1 parent 7d5a499 commit abe12fd
Show file tree
Hide file tree
Showing 34 changed files with 177 additions and 888 deletions.
30 changes: 30 additions & 0 deletions core/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,36 @@ pub fn format_frame<F: ErrorFormat>(frame: &JsStackFrame) -> String {
result
}

pub fn throw_error_one_byte_info(
info: &v8::FunctionCallbackInfo,
message: &str,
) {
let mut scope = unsafe { v8::CallbackScope::new(info) };
throw_error_one_byte(&mut scope, message);
}

pub fn throw_error_anyhow<S>(scope: &mut v8::CallbackScope<'_>, message: S)
where
S: Into<deno_core::anyhow::Error>,
{
// TODO(mmastrac): This might be allocating too much, even if it's on the error path
let e: deno_core::anyhow::Error = message.into();
let msg = deno_core::v8::String::new(scope, &format!("{}", e)).unwrap();
let exc = deno_core::v8::Exception::type_error(scope, msg);
scope.throw_exception(exc);
}

pub fn throw_error_one_byte(scope: &mut v8::CallbackScope, message: &str) {
let msg = deno_core::v8::String::new_from_one_byte(
scope,
message.as_bytes(),
deno_core::v8::NewStringType::Normal,
)
.unwrap();
let exc = deno_core::v8::Exception::type_error(scope, msg);
scope.throw_exception(exc);
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
3 changes: 3 additions & 0 deletions core/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ extern crate self as deno_core;
pub mod _ops {
pub use super::cppgc::make_cppgc_object;
pub use super::cppgc::try_unwrap_cppgc_object;
pub use super::error::throw_error_anyhow;
pub use super::error::throw_error_one_byte;
pub use super::error::throw_error_one_byte_info;
pub use super::error::throw_type_error;
pub use super::error_codes::get_error_code;
pub use super::extensions::Op;
Expand Down
4 changes: 1 addition & 3 deletions ops/op2/dispatch_fast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,7 @@ fn throw_type_error(
let message = format!("{message}");
quote!({
let mut scope = #create_scope;
let msg = deno_core::v8::String::new_from_one_byte(&mut scope, #message.as_bytes(), deno_core::v8::NewStringType::Normal).unwrap();
let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
scope.throw_exception(exc);
deno_core::_ops::throw_error_one_byte(&mut scope, #message);
// SAFETY: All fast return types have zero as a valid value
return unsafe { std::mem::zeroed() };
})
Expand Down
31 changes: 5 additions & 26 deletions ops/op2/dispatch_slow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,17 +1190,8 @@ fn throw_type_error(
// Sanity check ASCII and a valid/reasonable message size
debug_assert!(message.is_ascii() && message.len() < 1024);

let maybe_scope = if generator_state.needs_scope {
quote!()
} else {
with_scope(generator_state)
};

Ok(gs_quote!(generator_state(scope) => {
#maybe_scope
let msg = deno_core::v8::String::new_from_one_byte(&mut #scope, #message.as_bytes(), deno_core::v8::NewStringType::Normal).unwrap();
let exc = deno_core::v8::Exception::type_error(&mut #scope, msg);
#scope.throw_exception(exc);
Ok(gs_quote!(generator_state(info) => {
deno_core::_ops::throw_error_one_byte_info(&#info, #message);
return 1;
}))
}
Expand All @@ -1218,10 +1209,7 @@ fn throw_type_error_string(

Ok(gs_quote!(generator_state(scope) => {
#maybe_scope
// TODO(mmastrac): This might be allocating too much, even if it's on the error path
let msg = deno_core::v8::String::new(&mut #scope, &format!("{}", deno_core::anyhow::Error::from(#message))).unwrap();
let exc = deno_core::v8::Exception::type_error(&mut #scope, msg);
#scope.throw_exception(exc);
deno_core::_ops::throw_error_anyhow(&mut #scope, #message);
return 1;
}))
}
Expand All @@ -1231,17 +1219,8 @@ fn throw_type_error_static_string(
generator_state: &mut GeneratorState,
message: &Ident,
) -> Result<TokenStream, V8MappingError> {
let maybe_scope = if generator_state.needs_scope {
quote!()
} else {
with_scope(generator_state)
};

Ok(gs_quote!(generator_state(scope) => {
#maybe_scope
let msg = deno_core::v8::String::new_from_one_byte(&mut #scope, #message.as_bytes(), deno_core::v8::NewStringType::Normal).unwrap();
let exc = deno_core::v8::Exception::type_error(&mut #scope, msg);
#scope.throw_exception(exc);
Ok(gs_quote!(generator_state(info) => {
deno_core::_ops::throw_error_one_byte_info(&#info, #message);
return 1;
}))
}
10 changes: 1 addition & 9 deletions ops/op2/test_cases/async/async_arg_return.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions ops/op2/test_cases/async/async_arg_return_result.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 2 additions & 16 deletions ops/op2/test_cases/async/async_cppgc.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 2 additions & 18 deletions ops/op2/test_cases/async/async_jsbuffer.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions ops/op2/test_cases/async/async_result_impl.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions ops/op2/test_cases/async/async_result_smi.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions ops/op2/test_cases/async/async_v8_global.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 2 additions & 18 deletions ops/op2/test_cases/sync/add.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 5 additions & 20 deletions ops/op2/test_cases/sync/add_options.out

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit abe12fd

Please sign in to comment.