Skip to content

Commit fbefcee

Browse files
authored
perf(ext/http): use smi for slab IDs (#18848)
1 parent 18170f2 commit fbefcee

File tree

1 file changed

+38
-42
lines changed

1 file changed

+38
-42
lines changed

ext/http/http_next.rs

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ macro_rules! with {
141141
($ref:ident, $mut:ident, $type:ty, $http:ident, $expr:expr) => {
142142
#[inline(always)]
143143
#[allow(dead_code)]
144-
pub(crate) fn $mut<T>(key: usize, f: impl FnOnce(&mut $type) -> T) -> T {
144+
pub(crate) fn $mut<T>(key: u32, f: impl FnOnce(&mut $type) -> T) -> T {
145145
SLAB.with(|slab| {
146146
let mut borrow = slab.borrow_mut();
147147
#[allow(unused_mut)] // TODO(mmastrac): compiler issue?
148-
let mut $http = match borrow.get_mut(key) {
148+
let mut $http = match borrow.get_mut(key as usize) {
149149
Some(http) => http,
150150
None => panic!(
151151
"Attemped to access invalid request {} ({} in total available)",
@@ -163,10 +163,10 @@ macro_rules! with {
163163

164164
#[inline(always)]
165165
#[allow(dead_code)]
166-
pub(crate) fn $ref<T>(key: usize, f: impl FnOnce(&$type) -> T) -> T {
166+
pub(crate) fn $ref<T>(key: u32, f: impl FnOnce(&$type) -> T) -> T {
167167
SLAB.with(|slab| {
168168
let borrow = slab.borrow();
169-
let $http = borrow.get(key).unwrap();
169+
let $http = borrow.get(key as usize).unwrap();
170170
#[cfg(__zombie_http_tracking)]
171171
if !$http.alive {
172172
panic!("Attempted to access a dead HTTP object")
@@ -211,7 +211,7 @@ with!(with_http, with_http_mut, HttpSlabRecord, http, http);
211211
fn slab_insert(
212212
request: Request,
213213
request_info: HttpConnectionProperties,
214-
) -> usize {
214+
) -> u32 {
215215
SLAB.with(|slab| {
216216
let (request_parts, request_body) = request.into_parts();
217217
slab.borrow_mut().insert(HttpSlabRecord {
@@ -224,7 +224,7 @@ fn slab_insert(
224224
#[cfg(__zombie_http_tracking)]
225225
alive: true,
226226
})
227-
})
227+
}) as u32
228228
}
229229

230230
#[op]
@@ -233,7 +233,7 @@ pub fn op_upgrade_raw(_index: usize) {}
233233
#[op]
234234
pub async fn op_upgrade(
235235
state: Rc<RefCell<OpState>>,
236-
index: usize,
236+
index: u32,
237237
headers: Vec<(ByteString, ByteString)>,
238238
) -> Result<(ResourceId, ZeroCopyBuf), AnyError> {
239239
// Stage 1: set the respnse to 101 Switching Protocols and send it
@@ -273,8 +273,8 @@ pub async fn op_upgrade(
273273
))
274274
}
275275

276-
#[op]
277-
pub fn op_set_promise_complete(index: usize, status: u16) {
276+
#[op(fast)]
277+
pub fn op_set_promise_complete(index: u32, status: u16) {
278278
with_resp_mut(index, |resp| {
279279
// The Javascript code will never provide a status that is invalid here (see 23_response.js)
280280
*resp.as_mut().unwrap().status_mut() =
@@ -287,7 +287,7 @@ pub fn op_set_promise_complete(index: usize, status: u16) {
287287

288288
#[op]
289289
pub fn op_get_request_method_and_url(
290-
index: usize,
290+
index: u32,
291291
) -> (String, Option<String>, String, String, Option<u16>) {
292292
// TODO(mmastrac): Passing method can be optimized
293293
with_http(index, |http| {
@@ -314,15 +314,15 @@ pub fn op_get_request_method_and_url(
314314
}
315315

316316
#[op]
317-
pub fn op_get_request_header(index: usize, name: String) -> Option<ByteString> {
317+
pub fn op_get_request_header(index: u32, name: String) -> Option<ByteString> {
318318
with_req(index, |req| {
319319
let value = req.headers.get(name);
320320
value.map(|value| value.as_bytes().into())
321321
})
322322
}
323323

324324
#[op]
325-
pub fn op_get_request_headers(index: usize) -> Vec<(ByteString, ByteString)> {
325+
pub fn op_get_request_headers(index: u32) -> Vec<(ByteString, ByteString)> {
326326
with_req(index, |req| {
327327
let headers = &req.headers;
328328
let mut vec = Vec::with_capacity(headers.len());
@@ -356,8 +356,8 @@ pub fn op_get_request_headers(index: usize) -> Vec<(ByteString, ByteString)> {
356356
})
357357
}
358358

359-
#[op]
360-
pub fn op_read_request_body(state: &mut OpState, index: usize) -> ResourceId {
359+
#[op(fast)]
360+
pub fn op_read_request_body(state: &mut OpState, index: u32) -> ResourceId {
361361
let incoming = with_req_body_mut(index, |body| body.take().unwrap());
362362
let body_resource = Rc::new(HttpRequestBody::new(incoming));
363363
let res = state.resource_table.add_rc(body_resource.clone());
@@ -367,24 +367,20 @@ pub fn op_read_request_body(state: &mut OpState, index: usize) -> ResourceId {
367367
res
368368
}
369369

370-
#[op]
371-
pub fn op_set_response_header(
372-
index: usize,
373-
name: ByteString,
374-
value: ByteString,
375-
) {
370+
#[op(fast)]
371+
pub fn op_set_response_header(index: u32, name: &str, value: &str) {
376372
with_resp_mut(index, |resp| {
377373
let resp_headers = resp.as_mut().unwrap().headers_mut();
378374
// These are valid latin-1 strings
379-
let name = HeaderName::from_bytes(&name).unwrap();
380-
let value = HeaderValue::from_bytes(&value).unwrap();
375+
let name = HeaderName::from_bytes(name.as_bytes()).unwrap();
376+
let value = HeaderValue::from_bytes(value.as_bytes()).unwrap();
381377
resp_headers.append(name, value);
382378
});
383379
}
384380

385381
#[op]
386382
pub fn op_set_response_headers(
387-
index: usize,
383+
index: u32,
388384
headers: Vec<(ByteString, ByteString)>,
389385
) {
390386
// TODO(mmastrac): Invalid headers should be handled?
@@ -400,10 +396,10 @@ pub fn op_set_response_headers(
400396
})
401397
}
402398

403-
#[op]
399+
#[op(fast)]
404400
pub fn op_set_response_body_resource(
405401
state: &mut OpState,
406-
index: usize,
402+
index: u32,
407403
stream_rid: ResourceId,
408404
auto_close: bool,
409405
) -> Result<(), AnyError> {
@@ -426,10 +422,10 @@ pub fn op_set_response_body_resource(
426422
Ok(())
427423
}
428424

429-
#[op]
425+
#[op(fast)]
430426
pub fn op_set_response_body_stream(
431427
state: &mut OpState,
432-
index: usize,
428+
index: u32,
433429
) -> Result<ResourceId, AnyError> {
434430
// TODO(mmastrac): what should this channel size be?
435431
let (tx, rx) = tokio::sync::mpsc::channel(1);
@@ -445,8 +441,8 @@ pub fn op_set_response_body_stream(
445441
Ok(state.resource_table.add(tx))
446442
}
447443

448-
#[op]
449-
pub fn op_set_response_body_text(index: usize, text: String) {
444+
#[op(fast)]
445+
pub fn op_set_response_body_text(index: u32, text: String) {
450446
if !text.is_empty() {
451447
with_resp_mut(index, move |response| {
452448
response
@@ -458,23 +454,23 @@ pub fn op_set_response_body_text(index: usize, text: String) {
458454
}
459455
}
460456

461-
#[op]
462-
pub fn op_set_response_body_bytes(index: usize, buffer: ZeroCopyBuf) {
457+
#[op(fast)]
458+
pub fn op_set_response_body_bytes(index: u32, buffer: &[u8]) {
463459
if !buffer.is_empty() {
464460
with_resp_mut(index, |response| {
465461
response
466462
.as_mut()
467463
.unwrap()
468464
.body_mut()
469-
.initialize(ResponseBytesInner::Bytes(BufView::from(buffer)))
465+
.initialize(ResponseBytesInner::Bytes(BufView::from(buffer.to_vec())))
470466
});
471467
};
472468
}
473469

474470
#[op]
475471
pub async fn op_http_track(
476472
state: Rc<RefCell<OpState>>,
477-
index: usize,
473+
index: u32,
478474
server_rid: ResourceId,
479475
) -> Result<(), AnyError> {
480476
let handle = with_resp(index, |resp| {
@@ -496,12 +492,12 @@ pub async fn op_http_track(
496492
}
497493

498494
#[pin_project(PinnedDrop)]
499-
pub struct SlabFuture<F: Future<Output = ()>>(usize, #[pin] F);
495+
pub struct SlabFuture<F: Future<Output = ()>>(u32, #[pin] F);
500496

501497
pub fn new_slab_future(
502498
request: Request,
503499
request_info: HttpConnectionProperties,
504-
tx: tokio::sync::mpsc::Sender<usize>,
500+
tx: tokio::sync::mpsc::Sender<u32>,
505501
) -> SlabFuture<impl Future<Output = ()>> {
506502
let index = slab_insert(request, request_info);
507503
let rx = with_promise(index, |promise| promise.clone());
@@ -521,11 +517,11 @@ impl<F: Future<Output = ()>> PinnedDrop for SlabFuture<F> {
521517
SLAB.with(|slab| {
522518
#[cfg(__zombie_http_tracking)]
523519
{
524-
slab.borrow_mut().get_mut(self.0).unwrap().alive = false;
520+
slab.borrow_mut().get_mut(self.0 as usize).unwrap().alive = false;
525521
}
526522
#[cfg(not(__zombie_http_tracking))]
527523
{
528-
slab.borrow_mut().remove(self.0);
524+
slab.borrow_mut().remove(self.0 as usize);
529525
}
530526
});
531527
}
@@ -589,7 +585,7 @@ fn serve_https(
589585
mut io: TlsStream,
590586
request_info: HttpConnectionProperties,
591587
cancel: RcRef<CancelHandle>,
592-
tx: tokio::sync::mpsc::Sender<usize>,
588+
tx: tokio::sync::mpsc::Sender<u32>,
593589
) -> JoinHandle<Result<(), AnyError>> {
594590
// TODO(mmastrac): This is faster if we can use tokio::spawn but then the send bounds get us
595591
let svc = service_fn(move |req: Request| {
@@ -614,7 +610,7 @@ fn serve_http(
614610
io: impl HttpServeStream,
615611
request_info: HttpConnectionProperties,
616612
cancel: RcRef<CancelHandle>,
617-
tx: tokio::sync::mpsc::Sender<usize>,
613+
tx: tokio::sync::mpsc::Sender<u32>,
618614
) -> JoinHandle<Result<(), AnyError>> {
619615
// TODO(mmastrac): This is faster if we can use tokio::spawn but then the send bounds get us
620616
let svc = service_fn(move |req: Request| {
@@ -627,7 +623,7 @@ fn serve_http_on(
627623
network_stream: NetworkStream,
628624
listen_properties: &HttpListenProperties,
629625
cancel: RcRef<CancelHandle>,
630-
tx: tokio::sync::mpsc::Sender<usize>,
626+
tx: tokio::sync::mpsc::Sender<u32>,
631627
) -> JoinHandle<Result<(), AnyError>> {
632628
// We always want some sort of peer address. If we can't get one, just make up one.
633629
let peer_address = network_stream.peer_address().unwrap_or_else(|_| {
@@ -659,7 +655,7 @@ fn serve_http_on(
659655
struct HttpJoinHandle(
660656
AsyncRefCell<Option<JoinHandle<Result<(), AnyError>>>>,
661657
CancelHandle,
662-
AsyncRefCell<tokio::sync::mpsc::Receiver<usize>>,
658+
AsyncRefCell<tokio::sync::mpsc::Receiver<u32>>,
663659
);
664660

665661
impl HttpJoinHandle {
@@ -798,7 +794,7 @@ pub async fn op_http_wait(
798794

799795
// Do we have a request?
800796
if let Some(req) = next {
801-
return Ok(req as u32);
797+
return Ok(req);
802798
}
803799

804800
// No - we're shutting down

0 commit comments

Comments
 (0)