mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
perf(ext/ffi): Optimise common pointer related APIs (#15144)
This commit is contained in:
parent
4e71a9424e
commit
244c00d95b
3 changed files with 66 additions and 21 deletions
|
@ -32,77 +32,77 @@
|
||||||
getUint8(offset = 0) {
|
getUint8(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_u8",
|
"op_ffi_read_u8",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getInt8(offset = 0) {
|
getInt8(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_i8",
|
"op_ffi_read_i8",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUint16(offset = 0) {
|
getUint16(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_u16",
|
"op_ffi_read_u16",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getInt16(offset = 0) {
|
getInt16(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_i16",
|
"op_ffi_read_i16",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUint32(offset = 0) {
|
getUint32(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_u32",
|
"op_ffi_read_u32",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getInt32(offset = 0) {
|
getInt32(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_i32",
|
"op_ffi_read_i32",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBigUint64(offset = 0) {
|
getBigUint64(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_u64",
|
"op_ffi_read_u64",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBigInt64(offset = 0) {
|
getBigInt64(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_u64",
|
"op_ffi_read_u64",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFloat32(offset = 0) {
|
getFloat32(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_f32",
|
"op_ffi_read_f32",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFloat64(offset = 0) {
|
getFloat64(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_read_f64",
|
"op_ffi_read_f64",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCString(offset = 0) {
|
getCString(offset = 0) {
|
||||||
return core.opSync(
|
return core.opSync(
|
||||||
"op_ffi_cstr_read",
|
"op_ffi_cstr_read",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
copyInto(destination, offset = 0) {
|
copyInto(destination, offset = 0) {
|
||||||
core.opSync(
|
core.opSync(
|
||||||
"op_ffi_buf_copy_into",
|
"op_ffi_buf_copy_into",
|
||||||
this.pointer + BigInt(offset),
|
offset ? this.pointer + BigInt(offset) : this.pointer,
|
||||||
destination,
|
destination,
|
||||||
destination.byteLength,
|
destination.byteLength,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1873,7 +1873,7 @@ fn op_ffi_call_nonblocking<'scope>(
|
||||||
fn op_ffi_ptr_of<FP, 'scope>(
|
fn op_ffi_ptr_of<FP, 'scope>(
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
state: &mut deno_core::OpState,
|
state: &mut deno_core::OpState,
|
||||||
buf: ZeroCopyBuf,
|
buf: serde_v8::Value<'scope>,
|
||||||
) -> Result<serde_v8::Value<'scope>, AnyError>
|
) -> Result<serde_v8::Value<'scope>, AnyError>
|
||||||
where
|
where
|
||||||
FP: FfiPermissions + 'static,
|
FP: FfiPermissions + 'static,
|
||||||
|
@ -1882,8 +1882,33 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
let pointer = if let Ok(value) =
|
||||||
|
v8::Local::<v8::ArrayBufferView>::try_from(buf.v8_value)
|
||||||
|
{
|
||||||
|
let backing_store = value
|
||||||
|
.buffer(scope)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
type_error("Invalid FFI ArrayBufferView, expected data in the buffer")
|
||||||
|
})?
|
||||||
|
.get_backing_store();
|
||||||
|
let byte_offset = value.byte_offset();
|
||||||
|
if byte_offset > 0 {
|
||||||
|
&backing_store[byte_offset..] as *const _ as *const u8
|
||||||
|
} else {
|
||||||
|
&backing_store[..] as *const _ as *const u8
|
||||||
|
}
|
||||||
|
} else if let Ok(value) = v8::Local::<v8::ArrayBuffer>::try_from(buf.v8_value)
|
||||||
|
{
|
||||||
|
let backing_store = value.get_backing_store();
|
||||||
|
&backing_store[..] as *const _ as *const u8
|
||||||
|
} else {
|
||||||
|
return Err(type_error(
|
||||||
|
"Invalid FFI buffer, expected ArrayBuffer, or ArrayBufferView",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
let big_int: v8::Local<v8::Value> =
|
let big_int: v8::Local<v8::Value> =
|
||||||
v8::BigInt::new_from_u64(scope, buf.as_ptr() as u64).into();
|
v8::BigInt::new_from_u64(scope, pointer as u64).into();
|
||||||
Ok(big_int.into())
|
Ok(big_int.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,11 +1940,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op]
|
#[op(v8)]
|
||||||
fn op_ffi_cstr_read<FP>(
|
fn op_ffi_cstr_read<FP, 'scope>(
|
||||||
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
state: &mut deno_core::OpState,
|
state: &mut deno_core::OpState,
|
||||||
ptr: u64,
|
ptr: u64,
|
||||||
) -> Result<String, AnyError>
|
) -> Result<serde_v8::Value<'scope>, AnyError>
|
||||||
where
|
where
|
||||||
FP: FfiPermissions + 'static,
|
FP: FfiPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -1928,10 +1954,15 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
let ptr = ptr as *const c_char;
|
// SAFETY: Pointer is user provided.
|
||||||
// SAFETY: ptr is user provided
|
let cstr = unsafe { CStr::from_ptr(ptr as *const c_char) }.to_bytes();
|
||||||
// lifetime validity is not an issue because we allocate a new string.
|
let value: v8::Local<v8::Value> =
|
||||||
Ok(unsafe { CStr::from_ptr(ptr) }.to_str()?.to_string())
|
v8::String::new_from_utf8(scope, cstr, v8::NewStringType::Normal)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
type_error("Invalid CString pointer, string exceeds max length")
|
||||||
|
})?
|
||||||
|
.into();
|
||||||
|
Ok(value.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
|
|
|
@ -571,3 +571,17 @@ Deno.bench("nop_many_parameters_nonblocking()", () => {
|
||||||
buffer2,
|
buffer2,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.bench("Deno.UnsafePointer.of", () => {
|
||||||
|
Deno.UnsafePointer.of(buffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
const cstringBuffer = new TextEncoder().encode("Best believe it!\0");
|
||||||
|
// Make sure the buffer does not get collected
|
||||||
|
globalThis.cstringBuffer = cstringBuffer;
|
||||||
|
const cstringPointerView = new Deno.UnsafePointerView(
|
||||||
|
Deno.UnsafePointer.of(cstringBuffer),
|
||||||
|
);
|
||||||
|
Deno.bench("Deno.UnsafePointerView#getCString", () => {
|
||||||
|
cstringPointerView.getCString();
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue