Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: use v8::Value for strings in fast API #945

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
46 changes: 17 additions & 29 deletions Cargo.lock

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

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ deno_ops = { version = "0.192.0", path = "./ops" }
serde_v8 = { version = "0.225.0", path = "./serde_v8" }
deno_core_testing = { path = "./testing" }

v8 = { version = "0.106.0", default-features = false }
v8 = { version = "130.0.1", default-features = false }
deno_ast = { version = "=0.40.0", features = ["transpiling"] }
deno_unsync = "0.4.0"
deno_core_icudata = "0.0.73"
deno_core_icudata = "0.74.0"

anyhow = "1"
bencher = "0.1"
Expand Down Expand Up @@ -92,3 +92,6 @@ codegen-units = 1
incremental = true
lto = true
opt-level = 'z' # Optimize for size

[patch.crates-io]
v8 = { path = "../rusty_v8" }
6 changes: 6 additions & 0 deletions core/benches/ops/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ fn bench_op_string(b: &mut Bencher) {
bench_op(b, BENCH_COUNT, "op_string", 1, "accum += op_string('this is a reasonably long string that we would like to get the length of!');");
}

/// A string function with a numeric return value.
fn bench_op_string_constring(b: &mut Bencher) {
bench_op(b, BENCH_COUNT, "op_string", 1, "accum += op_string('this is a reasonably long string that we would like to get the length of!' + String(accum));");
}

/// A string function with a numeric return value.
fn bench_op_string_large_1000(b: &mut Bencher) {
bench_op(
Expand Down Expand Up @@ -510,6 +515,7 @@ benchmark_group!(
bench_op_string_bytestring,
bench_op_string_bytestring_no_side_effects,
bench_op_string,
bench_op_string_constring,
bench_op_string_large_1000,
bench_op_string_large_1000000,
bench_op_string_onebyte,
Expand Down
5 changes: 3 additions & 2 deletions core/ops_builtin_v8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::OpState;
use anyhow::Error;
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
use std::cell::RefCell;
use std::rc::Rc;
use v8::ValueDeserializerHelper;
Expand Down Expand Up @@ -67,13 +68,13 @@ pub fn op_leak_tracing_submit(
scope: &mut v8::HandleScope,
#[smi] kind: u8,
#[smi] id: i32,
#[string] trace: &str,
#[string] trace: Cow<'_, str>,
) {
let context_state = JsRealm::state_from_scope(scope);
context_state.activity_traces.submit(
RuntimeActivityType::from_u8(kind),
id as _,
trace,
&trace,
);
}

Expand Down
41 changes: 35 additions & 6 deletions core/runtime/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,39 @@ pub fn to_string_ptr(string: &v8::fast_api::FastApiOneByteString) -> String {
}
}

pub fn to_cow_byte_ptr(
string: &v8::fast_api::FastApiOneByteString,
) -> Cow<[u8]> {
string.as_bytes().into()
#[inline(always)]
pub fn to_string_view<'a>(
scope: &mut v8::Isolate,
value: v8::Local<'a, v8::Value>,
) -> Option<v8::ValueView<'a>> {
if !value.is_string() {
return None;
}

// SAFETY: We checked is_string above.
let string: v8::Local<'a, v8::String> = unsafe { std::mem::transmute(value) };

let string_view = v8::ValueView::new(scope, string);

Some(string_view)
}

#[inline(always)]
pub fn to_str_from_view<'a, const N: usize>(
string: &'a v8::ValueView<'_>,
buffer: &'a mut [MaybeUninit<u8>; N],
) -> Cow<'a, str> {
string.to_rust_cow_lossy(buffer)
}

#[inline(always)]
pub fn to_cow_one_byte_from_view<'a>(
string: &'a v8::ValueView<'_>,
) -> Result<Cow<'a, [u8]>, &'static str> {
match string.data() {
v8::ValueViewData::OneByte(data) => Ok(Cow::Borrowed(data)),
v8::ValueViewData::TwoByte(_) => Err("expected one-byte String"),
}
}

/// Converts a [`v8::Value`] to an owned string.
Expand Down Expand Up @@ -276,7 +305,7 @@ pub fn to_cow_one_byte(
string: &v8::Value,
) -> Result<Cow<'static, [u8]>, &'static str> {
if !string.is_string() {
return Err("expected String");
return Err("expected string");
}

// SAFETY: We checked is_string above
Expand All @@ -288,7 +317,7 @@ pub fn to_cow_one_byte(
}

if !string.is_onebyte() && !string.contains_only_onebyte() {
return Err("expected one-byte String");
return Err("expected one-byte string");
}

// Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid
Expand Down
2 changes: 1 addition & 1 deletion core/runtime/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn v8_init(
) {
#[cfg(feature = "include_icu_data")]
{
v8::icu::set_common_data_73(deno_core_icudata::ICU_DATA).unwrap();
v8::icu::set_common_data_74(deno_core_icudata::ICU_DATA).unwrap();
}

let base_flags = concat!(
Expand Down
Loading