Skip to content

perf: costly zero initialization of buffer #66

@abh1nav10

Description

@abh1nav10

The hyper::io::Read::poll_read implementation for HyperStream currently zero initializes the uninitialized ReadBufCursor and then passes it to futures_util::AsyncRead::poll_read implementation for MaybeTlsStream.

Tokio performs the following cast before passing its buffer to std::io::Read::read

 let b = unsafe { &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]) };

Is it not UB according to Rust's memory model as the compiler may make any assumption based on the information that it is properly initialized? I think it works because we advance the cursor according to the number of bytes read and read only from the initialized portion from there onwards and also there's no other way to prevent the zero initialization and still be using std::io::Read::read.
Are we not doing the same cast keeping in mind the UB?
If that's not the case, maybe we can also do the cast to prevent the zero initialization the way tokio does and then pass the buffer to futures_util::AsyncRead::poll_read, get the number of bytes that have been read and then advance the cursor accordingly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions