Optimize QuicStream memory layout This CL reorders fields of QuicStream and converts booleans to bitfields. This saves 48 bytes, bringing the size from 1088 to 1040. PiperOrigin-RevId: 838915555
diff --git a/quiche/quic/core/quic_stream.cc b/quiche/quic/core/quic_stream.cc index 2b2395e..ecb7421 100644 --- a/quiche/quic/core/quic_stream.cc +++ b/quiche/quic/core/quic_stream.cc
@@ -7,7 +7,6 @@ #include <algorithm> #include <cstdint> #include <limits> -#include <memory> #include <optional> #include <string> #include <utility> @@ -43,7 +42,6 @@ #include "quiche/quic/platform/api/quic_logging.h" #include "quiche/common/platform/api/quiche_logging.h" #include "quiche/common/platform/api/quiche_reference_counted.h" -#include "quiche/common/quiche_buffer_allocator.h" #include "quiche/common/quiche_mem_slice.h" using spdy::SpdyPriority; @@ -386,12 +384,28 @@ QuicFlowController* connection_flow_controller, QuicTime::Delta pending_duration) : sequencer_(std::move(sequencer)), - id_(id), session_(session), stream_delegate_(session), stream_bytes_read_(stream_bytes_read), stream_error_(QuicResetStreamError::NoError()), + id_(id), connection_error_(QUIC_NO_ERROR), + flow_controller_(std::move(flow_controller)), + connection_flow_controller_(connection_flow_controller), + busy_counter_(0), + send_buffer_( + session->connection()->helper()->GetStreamSendBufferAllocator()), + buffered_data_threshold_(GetQuicFlag(quic_buffered_data_threshold)), + deadline_(QuicTime::Zero()), + creation_time_(session->connection()->clock()->ApproximateNow()), + pending_duration_(pending_duration), + reliable_size_(0), + type_(VersionIsIetfQuic(session->transport_version()) && type != CRYPTO + ? QuicUtils::GetStreamType(id_, session->perspective(), + session->IsIncomingStream(id_), + session->version()) + : type), + perspective_(session->perspective()), read_side_closed_(false), write_side_closed_(false), write_side_data_recvd_state_notified_(false), @@ -404,26 +418,10 @@ rst_stream_at_sent_(false), rst_received_(false), stop_sending_sent_(false), - flow_controller_(std::move(flow_controller)), - connection_flow_controller_(connection_flow_controller), stream_contributes_to_connection_flow_control_(true), - busy_counter_(0), add_random_padding_after_fin_(false), - send_buffer_( - session->connection()->helper()->GetStreamSendBufferAllocator()), - buffered_data_threshold_(GetQuicFlag(quic_buffered_data_threshold)), is_static_(is_static), - deadline_(QuicTime::Zero()), - was_draining_(false), - type_(VersionIsIetfQuic(session->transport_version()) && type != CRYPTO - ? QuicUtils::GetStreamType(id_, session->perspective(), - session->IsIncomingStream(id_), - session->version()) - : type), - creation_time_(session->connection()->clock()->ApproximateNow()), - pending_duration_(pending_duration), - perspective_(session->perspective()), - reliable_size_(0) { + was_draining_(false) { if (type_ == WRITE_UNIDIRECTIONAL) { fin_received_ = true; CloseReadSide();
diff --git a/quiche/quic/core/quic_stream.h b/quiche/quic/core/quic_stream.h index 587a0f5..25ad82e 100644 --- a/quiche/quic/core/quic_stream.h +++ b/quiche/quic/core/quic_stream.h
@@ -19,29 +19,31 @@ #include <cstddef> #include <cstdint> -#include <list> -#include <memory> #include <optional> #include <string> #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "quiche/http2/core/spdy_protocol.h" #include "quiche/quic/core/frames/quic_connection_close_frame.h" #include "quiche/quic/core/frames/quic_reset_stream_at_frame.h" #include "quiche/quic/core/frames/quic_rst_stream_frame.h" +#include "quiche/quic/core/frames/quic_stream_frame.h" +#include "quiche/quic/core/frames/quic_window_update_frame.h" +#include "quiche/quic/core/quic_ack_listener_interface.h" #include "quiche/quic/core/quic_error_codes.h" #include "quiche/quic/core/quic_flow_controller.h" -#include "quiche/quic/core/quic_packets.h" +#include "quiche/quic/core/quic_interval_set.h" #include "quiche/quic/core/quic_stream_priority.h" #include "quiche/quic/core/quic_stream_send_buffer.h" #include "quiche/quic/core/quic_stream_send_buffer_base.h" #include "quiche/quic/core/quic_stream_send_buffer_inlining.h" #include "quiche/quic/core/quic_stream_sequencer.h" +#include "quiche/quic/core/quic_time.h" #include "quiche/quic/core/quic_types.h" -#include "quiche/quic/core/session_notifier_interface.h" +#include "quiche/quic/core/quic_versions.h" #include "quiche/quic/core/stream_delegate_interface.h" -#include "quiche/quic/platform/api/quic_export.h" +#include "quiche/quic/platform/api/quic_flags.h" +#include "quiche/common/platform/api/quiche_export.h" #include "quiche/common/platform/api/quiche_reference_counted.h" #include "quiche/common/quiche_mem_slice.h" @@ -573,7 +575,6 @@ void MaybeCloseStreamWithBufferedReset(); QuicStreamSequencer sequencer_; - QuicStreamId id_; // Pointer to the owning QuicSession object. // TODO(b/136274541): Remove session pointer from streams. QuicSession* session_; @@ -587,63 +588,23 @@ // Stream error code received from a RstStreamFrame or error code sent by the // visitor or sequencer in the RstStreamFrame. QuicResetStreamError stream_error_; + + QuicStreamId id_; + // Connection error code due to which the stream was closed. |stream_error_| // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers // should check |connection_error_|. QuicErrorCode connection_error_; - // True if the read side is closed and further frames should be rejected. - bool read_side_closed_; - // True if the write side is closed, and further writes should fail. - bool write_side_closed_; - - // True if OnWriteSideInDataRecvdState() has already been called. - bool write_side_data_recvd_state_notified_; - - // True if the subclass has written a FIN with WriteOrBufferData, but it was - // buffered in queued_data_ rather than being sent to the session. - bool fin_buffered_; - // True if a FIN has been sent to the session. - bool fin_sent_; - // True if a FIN is waiting to be acked. - bool fin_outstanding_; - // True if a FIN is lost. - bool fin_lost_; - - // True if this stream has received (and the sequencer has accepted) a - // StreamFrame with the FIN set. - bool fin_received_; - - // True if an RST_STREAM or RESET_STREAM_AT has been sent to the session. - // In combination with fin_sent_, used to ensure that a FIN, RST_STREAM, or - // RESET_STREAM_AT is always sent to terminate the stream. - bool rst_sent_; - bool rst_stream_at_sent_; - - // True if this stream has received a RST_STREAM frame. - bool rst_received_; - - // True if the stream has sent STOP_SENDING to the session. - bool stop_sending_sent_; - std::optional<QuicFlowController> flow_controller_; // The connection level flow controller. Not owned. QuicFlowController* connection_flow_controller_; - // Special streams, such as the crypto and headers streams, do not respect - // connection level flow control limits (but are stream level flow control - // limited). - bool stream_contributes_to_connection_flow_control_; - // A counter incremented when OnCanWrite() is called and no progress is made. // For debugging only. size_t busy_counter_; - // Indicates whether paddings will be added after the fin is consumed for this - // stream. - bool add_random_padding_after_fin_; - // Send buffer of this stream. Send buffer is cleaned up when data gets acked // or discarded. QuicStreamSendBufferInlining send_buffer_; @@ -651,20 +612,9 @@ // Latched value of quic_buffered_data_threshold. const QuicByteCount buffered_data_threshold_; - // If true, then this stream has precedence over other streams for write - // scheduling. - const bool is_static_; - // If initialized, reset this stream at this deadline. QuicTime deadline_; - // True if this stream has entered draining state. - bool was_draining_; - - // Indicates whether this stream is bidirectional, read unidirectional or - // write unidirectional. - const StreamType type_; - // Creation time of this stream, as reported by the QuicClock. const QuicTime creation_time_; @@ -675,14 +625,65 @@ // When RESET_STREAM_AT arrives,buffer it for when reliable_size is consumed. std::optional<QuicResetStreamAtFrame> buffered_reset_stream_at_; - Perspective perspective_; - - const bool notify_ack_listener_earlier_ = - GetQuicReloadableFlag(quic_notify_ack_listener_earlier); - // If the stream is reset, outgoing data up to reliable_size_will be // delivered (and acknowledged) before the write side of the stream is closed. QuicStreamOffset reliable_size_; + + // Indicates whether this stream is bidirectional, read unidirectional or + // write unidirectional. + const StreamType type_; + + Perspective perspective_; + + // True if the read side is closed and further frames should be rejected. + bool read_side_closed_ : 1; + // True if the write side is closed, and further writes should fail. + bool write_side_closed_ : 1; + // True if OnWriteSideInDataRecvdState() has already been called. + bool write_side_data_recvd_state_notified_ : 1; + + const bool notify_ack_listener_earlier_ : 1 = + GetQuicReloadableFlag(quic_notify_ack_listener_earlier); + + // True if the subclass has written a FIN with WriteOrBufferData, but it was + // buffered in queued_data_ rather than being sent to the session. + bool fin_buffered_ : 1; + // True if a FIN has been sent to the session. + bool fin_sent_ : 1; + // True if a FIN is waiting to be acked. + bool fin_outstanding_ : 1; + // True if a FIN is lost. + bool fin_lost_ : 1; + // True if this stream has received (and the sequencer has accepted) a + // StreamFrame with the FIN set. + bool fin_received_ : 1; + + // True if an RST_STREAM or RESET_STREAM_AT has been sent to the session. + // In combination with fin_sent_, used to ensure that a FIN, RST_STREAM, or + // RESET_STREAM_AT is always sent to terminate the stream. + bool rst_sent_ : 1; + bool rst_stream_at_sent_ : 1; + // True if this stream has received a RST_STREAM frame. + bool rst_received_ : 1; + + // True if the stream has sent STOP_SENDING to the session. + bool stop_sending_sent_ : 1; + + // Special streams, such as the crypto and headers streams, do not respect + // connection level flow control limits (but are stream level flow control + // limited). + bool stream_contributes_to_connection_flow_control_ : 1; + + // Indicates whether paddings will be added after the fin is consumed for this + // stream. + bool add_random_padding_after_fin_ : 1; + + // If true, then this stream has precedence over other streams for write + // scheduling. + const bool is_static_ : 1; + + // True if this stream has entered draining state. + bool was_draining_ : 1; }; } // namespace quic