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
7 changes: 5 additions & 2 deletions src/rust/jsg-bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ are ignored.
- Both buffer-copy implementations allocate new storage and copy the bytes. The length and sum
cases read existing storage. String sizes are in UTF-16 code units; native strings are UTF-8.
Ordinary numeric arrays use Rust `Vec<f64>` and C++ `kj::Array<double>`.
- Numeric results use Rust `f64` and C++ `double`; integer inputs, storage, and arithmetic
remain integer-typed in both. The Rust callback checks and casts `Local<Value>` to `Function`.
- Integer results, such as lengths, counts and sums of bytes, use Rust `u32` and C++ `uint32_t`;
results that are numbers in general (`number`, `union`, the array and struct cases, and the
callback) use `f64` and `double`. A fast integer argument reaches Rust as a `double` and
converts with the slow path's checks, while C++ JSG receives it as a `uint32_t`, so the
`dispatch/u32` cases compare different argument conversions as well. The Rust callback checks and casts `Local<Value>` to `Function`.
The C++ callback benchmark calls V8 directly, not through `jsg::Function`.
- `allocate-collect/N` times the creation of N objects followed by garbage collection. Other
collection benchmarks keep objects alive. `native/lifetime/N` times the creation of one
Expand Down
23 changes: 10 additions & 13 deletions src/rust/jsg-bench/bench.c++
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ class Node final: public Object {
uint32_t getValue() {
return value;
}
double getJsValue() {
return value;
}
void setChild(Ref<Node> node) {
child = kj::mv(node);
}
Expand All @@ -65,7 +62,7 @@ class Node final: public Object {
}

JSG_RESOURCE_TYPE(Node) {
JSG_READONLY_PROTOTYPE_PROPERTY(value, getJsValue);
JSG_READONLY_PROTOTYPE_PROPERTY(value, getValue);
JSG_READONLY_PROTOTYPE_PROPERTY(child, getChild);
JSG_METHOD(setChild);
}
Expand All @@ -85,10 +82,10 @@ class Target final: public Object {

void noop() {}
static void staticNoop() {}
double add(uint32_t a) {
uint32_t add(uint32_t a) {
return a + 1;
}
double addFour(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
uint32_t addFour(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
return a + b + c + d;
}
double number(double a) {
Expand All @@ -100,13 +97,13 @@ class Target final: public Object {
v8::Local<v8::Value> raw(v8::Local<v8::Value> a) {
return a;
}
double getValue() {
uint32_t getValue() {
return value;
}
void setValue(uint32_t a) {
value = a;
}
double optional(jsg::Optional<uint32_t> a) {
uint32_t optional(jsg::Optional<uint32_t> a) {
return a.orDefault(7);
}

Expand All @@ -122,7 +119,7 @@ class Target final: public Object {
KJ_UNREACHABLE;
}

double stringLen(kj::String a) {
uint32_t stringLen(kj::String a) {
return static_cast<uint32_t>(a.size());
}
kj::String stringEcho(kj::String a) {
Expand Down Expand Up @@ -153,18 +150,18 @@ class Target final: public Object {
Octet octetMake() {
return {1, 2, 3, 4, 5, 6, 7, 8};
}
double bytesLen(v8::Local<v8::Uint8Array> a) {
uint32_t bytesLen(v8::Local<v8::Uint8Array> a) {
return static_cast<uint32_t>(a->ByteLength());
}
double bytesCopy(v8::Local<v8::Uint8Array> a) {
uint32_t bytesCopy(v8::Local<v8::Uint8Array> a) {
auto bytes = kj::heapArray(a->ByteLength() == 0
? kj::ArrayPtr<const kj::byte>()
: kj::arrayPtr(static_cast<const kj::byte*>(a->Buffer()->Data()) + a->ByteOffset(),
a->ByteLength()));
benchmark::DoNotOptimize(bytes.begin());
return static_cast<uint32_t>(bytes.size());
}
double bytesSum(v8::Local<v8::Uint8Array> a) {
uint32_t bytesSum(v8::Local<v8::Uint8Array> a) {
if (a->ByteLength() == 0) return 0;
auto bytes = kj::arrayPtr(
static_cast<const kj::byte*>(a->Buffer()->Data()) + a->ByteOffset(), a->ByteLength());
Expand All @@ -178,7 +175,7 @@ class Target final: public Object {
Ref<Node> sameNode() {
return child.addRef();
}
double takeNode(Ref<Node> a) {
uint32_t takeNode(Ref<Node> a) {
return a->getValue();
}
double callback(Lock& js, v8::Local<v8::Function> a, double n) {
Expand Down
48 changes: 22 additions & 26 deletions src/rust/jsg-bench/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ impl Node {
}

#[jsg_property(prototype)]
fn get_value(&self) -> f64 {
self.value.get().into()
fn get_value(&self) -> u32 {
self.value.get()
}

#[jsg_method]
Expand Down Expand Up @@ -112,13 +112,13 @@ impl Target {
fn static_noop() {}

#[jsg_method]
fn add(&self, a: u32) -> f64 {
(a + 1).into()
fn add(&self, a: u32) -> u32 {
a + 1
}

#[jsg_method]
fn add_four(&self, a: u32, b: u32, c: u32, d: u32) -> f64 {
(a + b + c + d).into()
fn add_four(&self, a: u32, b: u32, c: u32, d: u32) -> u32 {
a + b + c + d
}

#[jsg_method]
Expand All @@ -137,8 +137,8 @@ impl Target {
}

#[jsg_property(prototype)]
fn get_value(&self) -> f64 {
self.value.get().into()
fn get_value(&self) -> u32 {
self.value.get()
}

#[jsg_property(prototype)]
Expand All @@ -147,8 +147,8 @@ impl Target {
}

#[jsg_property(instance)]
fn get_own(&self) -> f64 {
self.value.get().into()
fn get_own(&self) -> u32 {
self.value.get()
}

#[jsg_property(instance)]
Expand All @@ -157,8 +157,8 @@ impl Target {
}

#[jsg_method]
fn optional(&self, a: Option<u32>) -> f64 {
a.unwrap_or(7).into()
fn optional(&self, a: Option<u32>) -> u32 {
a.unwrap_or(7)
}

#[jsg_method]
Expand All @@ -170,8 +170,8 @@ impl Target {
}

#[jsg_method]
fn string_len(&self, a: String) -> f64 {
(a.len() as u32).into()
fn string_len(&self, a: String) -> u32 {
a.len() as u32
}

#[jsg_method]
Expand Down Expand Up @@ -224,24 +224,20 @@ impl Target {
}

#[jsg_method]
fn bytes_len(&self, a: v8::Local<'_, v8::Uint8Array>) -> f64 {
(a.byte_length() as u32).into()
fn bytes_len(&self, a: v8::Local<'_, v8::Uint8Array>) -> u32 {
a.byte_length() as u32
}

#[jsg_method]
fn bytes_copy<'s>(&self, lock: &mut jsg::Lock<'s>, a: v8::Local<'s, v8::Uint8Array>) -> f64 {
fn bytes_copy<'s>(&self, lock: &mut jsg::Lock<'s>, a: v8::Local<'s, v8::Uint8Array>) -> u32 {
let a = a.as_slice(lock).to_vec();
black_box(&a);
(a.len() as u32).into()
a.len() as u32
}

#[jsg_method]
fn bytes_sum<'s>(&self, lock: &mut jsg::Lock<'s>, a: v8::Local<'s, v8::Uint8Array>) -> f64 {
a.as_slice(lock)
.iter()
.map(|&x| u32::from(x))
.sum::<u32>()
.into()
fn bytes_sum<'s>(&self, lock: &mut jsg::Lock<'s>, a: v8::Local<'s, v8::Uint8Array>) -> u32 {
a.as_slice(lock).iter().map(|&x| u32::from(x)).sum()
}

#[jsg_method]
Expand All @@ -255,8 +251,8 @@ impl Target {
}

#[jsg_method]
fn take_node(&self, a: jsg::Rc<Node>) -> f64 {
a.value.get().into()
fn take_node(&self, a: jsg::Rc<Node>) -> u32 {
a.value.get()
}

#[jsg_method]
Expand Down
20 changes: 10 additions & 10 deletions src/rust/jsg-compile-tests/method-receiver-is-shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,28 @@ impl Counter {
pub fn nested(self: &&Self) {} //~ ERROR a resource method takes `&self`

#[jsg_method]
pub fn explicit<'a>(self: &'a Self) -> f64 {
f64::from(self.count)
pub fn explicit<'a>(self: &'a Self) -> u32 {
self.count
}

#[jsg_property(prototype)]
pub fn get_total(&self) -> f64 {
f64::from(self.count)
pub fn get_total(&self) -> u32 {
self.count
}

#[jsg_property(prototype)]
pub fn set_total(&mut self, _v: f64) {
pub fn set_total(&mut self, _v: u32) {
//~^ ERROR a resource method takes `&self`
}

#[jsg_property(instance)]
pub fn get_current(&mut self) -> f64 {
pub fn get_current(&mut self) -> u32 {
//~^ ERROR a resource method takes `&self`
f64::from(self.count)
self.count
}

#[jsg_property(instance)]
pub fn set_current(&mut self, _v: f64) {
pub fn set_current(&mut self, _v: u32) {
//~^ ERROR a resource method takes `&self`
}

Expand All @@ -63,9 +63,9 @@ impl Counter {
}

// A rejected method is still emitted, so its callers add no errors of their own.
fn _calls(mut counter: Counter) -> f64 {
fn _calls(mut counter: Counter) -> u32 {
counter.increment();
let _ = counter.get_current();
counter.consume();
0.0
0
}
6 changes: 6 additions & 0 deletions src/rust/jsg-compile-tests/ok-local-casts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ macro_rules! supertypes {
}

pub fn all() {
supertypes!(Boolean: Value);
supertypes!(Number: Value);
supertypes!(Integer: Number, Value);
supertypes!(Int32: Integer, Number, Value);
supertypes!(Uint32: Integer, Number, Value);
supertypes!(Name: Value);
supertypes!(String: Name, Value);
supertypes!(Symbol: Name, Value);
Expand All @@ -30,6 +35,7 @@ pub fn all() {
supertypes!(Date: Object, Value);
supertypes!(Function: Object, Value);
supertypes!(Array: Object, Value);
supertypes!(Promise: Object, Value);
supertypes!(ArrayBuffer: Object, Value);
supertypes!(ArrayBufferView: Object, Value);
supertypes!(TypedArray: ArrayBufferView, Object, Value);
Expand Down
14 changes: 7 additions & 7 deletions src/rust/jsg-compile-tests/ok-this-parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ impl Counter {
}

#[jsg_method]
pub fn imported(this: Rc<Self>) -> f64 {
f64::from(this.count.get())
pub fn imported(this: Rc<Self>) -> u32 {
this.count.get()
}

#[jsg_method]
Expand All @@ -37,7 +37,7 @@ impl Counter {
by: u32,
) -> jsg::Result<v8::Local<'s, v8::Value>> {
this.count.set(this.count.get() + by);
f64::from(this.count.get()).to_js(lock)
this.count.get().to_js(lock)
}

#[jsg_method]
Expand All @@ -56,8 +56,8 @@ impl Counter {
}

#[jsg_property]
pub fn get_total(this: jsg::Rc<Self>) -> f64 {
f64::from(this.count.get())
pub fn get_total(this: jsg::Rc<Self>) -> u32 {
this.count.get()
}

#[jsg_property]
Expand All @@ -66,8 +66,8 @@ impl Counter {
}

#[jsg_property(instance)]
pub fn get_current(this: jsg::Rc<Self>) -> f64 {
f64::from(this.count.get())
pub fn get_current(this: jsg::Rc<Self>) -> u32 {
this.count.get()
}

#[jsg_inspect_property]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct Borrowed;
#[jsg_resource]
impl Borrowed {
#[jsg_wildcard_property]
pub fn get<'a>(self: &'a Self, name: &str) -> Option<f64> {
pub fn get<'a>(self: &'a Self, name: &str) -> Option<u32> {
let _ = (self, name);
None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ impl Counter {
}

#[jsg_property]
pub fn get_total(&self, this: jsg::Rc<Self>) -> f64 {
pub fn get_total(&self, this: jsg::Rc<Self>) -> u32 {
//~^ ERROR `this` must be the first parameter
let _ = this;
f64::from(self.count.get())
self.count.get()
}

#[jsg_property]
pub fn set_total(lock: &mut jsg::Lock, this: jsg::Rc<Self>, v: f64) {
pub fn set_total(lock: &mut jsg::Lock, this: jsg::Rc<Self>, v: u32) {
//~^ ERROR `this` must be the first parameter
let _ = (lock, this, v);
}
Expand Down
8 changes: 4 additions & 4 deletions src/rust/jsg-macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ setter on `Object.prototype` runs, and what it throws is passed on.
```rust
#[jsg_struct]
pub struct CaaRecord {
pub critical: f64,
pub critical: u8,
pub tag: String,
pub value: String,
}
Expand Down Expand Up @@ -310,16 +310,16 @@ use std::cell::{Cell, RefCell};
use jsg_macros::{jsg_resource, jsg_property};

#[jsg_resource]
struct Counter { value: Cell<f64>, id: RefCell<String>, kind: String }
struct Counter { value: Cell<u32>, id: RefCell<String>, kind: String }

#[jsg_resource]
impl Counter {
// Prototype — read/write (setter detected from `set_` prefix)
#[jsg_property(prototype)]
pub fn get_value(&self) -> f64 { self.value.get() }
pub fn get_value(&self) -> u32 { self.value.get() }

#[jsg_property(prototype)]
pub fn set_value(&self, v: f64) { self.value.set(v); }
pub fn set_value(&self, v: u32) { self.value.set(v); }

// Prototype — read-only (explicit `readonly`)
#[jsg_property(prototype, readonly)]
Expand Down
Loading
Loading