Change QuicWindowUpdateFrame to an inlined quic frame.

PiperOrigin-RevId: 438401196
diff --git a/quic/core/frames/quic_frame.cc b/quic/core/frames/quic_frame.cc
index 48bc12a..7717054 100644
--- a/quic/core/frames/quic_frame.cc
+++ b/quic/core/frames/quic_frame.cc
@@ -47,8 +47,8 @@
 QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
     : type(GOAWAY_FRAME), goaway_frame(frame) {}
 
-QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame)
-    : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {}
+QuicFrame::QuicFrame(QuicWindowUpdateFrame frame)
+    : window_update_frame(frame) {}
 
 QuicFrame::QuicFrame(QuicBlockedFrame* frame)
     : type(BLOCKED_FRAME), blocked_frame(frame) {}
@@ -96,7 +96,8 @@
       frame->type != PING_FRAME && frame->type != MAX_STREAMS_FRAME &&
       frame->type != STOP_WAITING_FRAME &&
       frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
-      frame->type != HANDSHAKE_DONE_FRAME) {
+      frame->type != HANDSHAKE_DONE_FRAME &&
+      frame->type != WINDOW_UPDATE_FRAME) {
     QUICHE_CHECK(!frame->delete_forbidden) << *frame;
   }
 #endif  // QUIC_FRAME_DEBUG
@@ -110,6 +111,7 @@
     case STREAMS_BLOCKED_FRAME:
     case STREAM_FRAME:
     case HANDSHAKE_DONE_FRAME:
+    case WINDOW_UPDATE_FRAME:
       break;
     case ACK_FRAME:
       delete frame->ack_frame;
@@ -126,9 +128,6 @@
     case BLOCKED_FRAME:
       delete frame->blocked_frame;
       break;
-    case WINDOW_UPDATE_FRAME:
-      delete frame->window_update_frame;
-      break;
     case PATH_CHALLENGE_FRAME:
       delete frame->path_challenge_frame;
       break;
@@ -200,7 +199,7 @@
     case GOAWAY_FRAME:
       return frame.goaway_frame->control_frame_id;
     case WINDOW_UPDATE_FRAME:
-      return frame.window_update_frame->control_frame_id;
+      return frame.window_update_frame.control_frame_id;
     case BLOCKED_FRAME:
       return frame.blocked_frame->control_frame_id;
     case STREAMS_BLOCKED_FRAME:
@@ -235,7 +234,7 @@
       frame->goaway_frame->control_frame_id = control_frame_id;
       return;
     case WINDOW_UPDATE_FRAME:
-      frame->window_update_frame->control_frame_id = control_frame_id;
+      frame->window_update_frame.control_frame_id = control_frame_id;
       return;
     case BLOCKED_FRAME:
       frame->blocked_frame->control_frame_id = control_frame_id;
@@ -283,7 +282,7 @@
       copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
       break;
     case WINDOW_UPDATE_FRAME:
-      copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
+      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
       break;
     case BLOCKED_FRAME:
       copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
@@ -345,7 +344,7 @@
       copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
       break;
     case WINDOW_UPDATE_FRAME:
-      copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
+      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
       break;
     case BLOCKED_FRAME:
       copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
@@ -449,7 +448,7 @@
       break;
     }
     case WINDOW_UPDATE_FRAME: {
-      os << "type { WINDOW_UPDATE_FRAME } " << *(frame.window_update_frame);
+      os << "type { WINDOW_UPDATE_FRAME } " << frame.window_update_frame;
       break;
     }
     case BLOCKED_FRAME: {
diff --git a/quic/core/frames/quic_frame.h b/quic/core/frames/quic_frame.h
index 7de9bb6..b690dfe 100644
--- a/quic/core/frames/quic_frame.h
+++ b/quic/core/frames/quic_frame.h
@@ -58,12 +58,12 @@
   explicit QuicFrame(QuicStreamsBlockedFrame frame);
   explicit QuicFrame(QuicStreamFrame stream_frame);
   explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame);
+  explicit QuicFrame(QuicWindowUpdateFrame frame);
 
   explicit QuicFrame(QuicAckFrame* frame);
   explicit QuicFrame(QuicRstStreamFrame* frame);
   explicit QuicFrame(QuicConnectionCloseFrame* frame);
   explicit QuicFrame(QuicGoAwayFrame* frame);
-  explicit QuicFrame(QuicWindowUpdateFrame* frame);
   explicit QuicFrame(QuicBlockedFrame* frame);
   explicit QuicFrame(QuicNewConnectionIdFrame* frame);
   explicit QuicFrame(QuicRetireConnectionIdFrame* frame);
@@ -91,6 +91,7 @@
     QuicStreamsBlockedFrame streams_blocked_frame;
     QuicStreamFrame stream_frame;
     QuicHandshakeDoneFrame handshake_done_frame;
+    QuicWindowUpdateFrame window_update_frame;
 
     // Out of line frames.
     struct {
@@ -101,7 +102,7 @@
 #endif  // QUIC_FRAME_DEBUG
 
       // TODO(wub): These frames can also be inlined without increasing the size
-      // of QuicFrame: QuicRstStreamFrame, QuicWindowUpdateFrame,
+      // of QuicFrame:
       // QuicBlockedFrame, QuicPathResponseFrame, QuicPathChallengeFrame and
       // QuicStopSendingFrame.
       union {
@@ -109,7 +110,6 @@
         QuicRstStreamFrame* rst_stream_frame;
         QuicConnectionCloseFrame* connection_close_frame;
         QuicGoAwayFrame* goaway_frame;
-        QuicWindowUpdateFrame* window_update_frame;
         QuicBlockedFrame* blocked_frame;
         QuicNewConnectionIdFrame* new_connection_id_frame;
         QuicRetireConnectionIdFrame* retire_connection_id_frame;
diff --git a/quic/core/frames/quic_frames_test.cc b/quic/core/frames/quic_frames_test.cc
index 6955094..07895eb 100644
--- a/quic/core/frames/quic_frames_test.cc
+++ b/quic/core/frames/quic_frames_test.cc
@@ -236,14 +236,13 @@
 }
 
 TEST_F(QuicFramesTest, WindowUpdateFrameToString) {
-  QuicWindowUpdateFrame window_update;
-  QuicFrame frame(&window_update);
+  QuicFrame frame((QuicWindowUpdateFrame()));
   SetControlFrameId(3, &frame);
   EXPECT_EQ(3u, GetControlFrameId(frame));
   std::ostringstream stream;
-  window_update.stream_id = 1;
-  window_update.max_data = 2;
-  stream << window_update;
+  frame.window_update_frame.stream_id = 1;
+  frame.window_update_frame.max_data = 2;
+  stream << frame.window_update_frame;
   EXPECT_EQ("{ control_frame_id: 3, stream_id: 1, max_data: 2 }\n",
             stream.str());
   EXPECT_TRUE(IsControlFrame(frame.type));
@@ -562,7 +561,7 @@
         frames.push_back(QuicFrame(new QuicGoAwayFrame()));
         break;
       case WINDOW_UPDATE_FRAME:
-        frames.push_back(QuicFrame(new QuicWindowUpdateFrame()));
+        frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
         break;
       case BLOCKED_FRAME:
         frames.push_back(QuicFrame(new QuicBlockedFrame()));
diff --git a/quic/core/frames/quic_window_update_frame.cc b/quic/core/frames/quic_window_update_frame.cc
index 4f21b57..c8fef31 100644
--- a/quic/core/frames/quic_window_update_frame.cc
+++ b/quic/core/frames/quic_window_update_frame.cc
@@ -4,13 +4,18 @@
 
 #include "quic/core/frames/quic_window_update_frame.h"
 
+#include "quic/core/quic_types.h"
+
 namespace quic {
 
+QuicWindowUpdateFrame::QuicWindowUpdateFrame()
+    : QuicInlinedFrame(WINDOW_UPDATE_FRAME) {}
+
 QuicWindowUpdateFrame::QuicWindowUpdateFrame(
-    QuicControlFrameId control_frame_id,
-    QuicStreamId stream_id,
+    QuicControlFrameId control_frame_id, QuicStreamId stream_id,
     QuicByteCount max_data)
-    : control_frame_id(control_frame_id),
+    : QuicInlinedFrame(WINDOW_UPDATE_FRAME),
+      control_frame_id(control_frame_id),
       stream_id(stream_id),
       max_data(max_data) {}
 
diff --git a/quic/core/frames/quic_window_update_frame.h b/quic/core/frames/quic_window_update_frame.h
index 372a4ea..3a8a1d7 100644
--- a/quic/core/frames/quic_window_update_frame.h
+++ b/quic/core/frames/quic_window_update_frame.h
@@ -7,6 +7,7 @@
 
 #include <ostream>
 
+#include "quic/core/frames/quic_inlined_frame.h"
 #include "quic/core/quic_constants.h"
 #include "quic/core/quic_types.h"
 
@@ -15,15 +16,16 @@
 // Flow control updates per-stream and at the connection level.
 // Based on SPDY's WINDOW_UPDATE frame, but uses an absolute max data bytes
 // rather than a window delta.
-struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame {
-  QuicWindowUpdateFrame() = default;
+struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame
+    : public QuicInlinedFrame<QuicWindowUpdateFrame> {
+  QuicWindowUpdateFrame();
   QuicWindowUpdateFrame(QuicControlFrameId control_frame_id,
-                        QuicStreamId stream_id,
-                        QuicByteCount max_data);
+                        QuicStreamId stream_id, QuicByteCount max_data);
 
   friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicWindowUpdateFrame& w);
+      std::ostream& os, const QuicWindowUpdateFrame& w);
+
+  QuicFrameType type;
 
   // A unique identifier of this control frame. 0 when this frame is received,
   // and non-zero when sent.
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index fee5ea4..bb27468 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -2237,7 +2237,7 @@
   QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1));
-  frames.push_back(QuicFrame(&window_update));
+  frames.push_back(QuicFrame(window_update));
   frames.push_back(QuicFrame(frame2));
   frames.push_back(QuicFrame(frame3));
   EXPECT_FALSE(session_.WillingAndAbleToWrite());
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index fb16c11..9e86932 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -3283,8 +3283,7 @@
   // WINDOW_UPDATE.
   EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
       .WillOnce(Invoke([this]() {
-        connection_.SendControlFrame(
-            QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
+        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
       }));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   EXPECT_EQ(0u, writer_->window_update_frames().size());
@@ -3357,8 +3356,7 @@
   // with the ACK.
   EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
       .WillOnce(Invoke([this]() {
-        connection_.SendControlFrame(
-            QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
+        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
       }));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   ProcessDataPacket(11);
@@ -6985,9 +6983,9 @@
 TEST_P(QuicConnectionTest, WindowUpdate) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
-  QuicWindowUpdateFrame* window_update = new QuicWindowUpdateFrame();
-  window_update->stream_id = 3;
-  window_update->max_data = 1234;
+  QuicWindowUpdateFrame window_update;
+  window_update.stream_id = 3;
+  window_update.max_data = 1234;
   EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
   ProcessFramePacket(QuicFrame(window_update));
 }
@@ -7310,9 +7308,9 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Send a WINDOW_UPDATE frame.
-  QuicWindowUpdateFrame* window_update = new QuicWindowUpdateFrame();
-  window_update->stream_id = 3;
-  window_update->max_data = 1234;
+  QuicWindowUpdateFrame window_update;
+  window_update.stream_id = 3;
+  window_update.max_data = 1234;
   EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
   ProcessFramePacket(QuicFrame(window_update));
 
@@ -10973,7 +10971,7 @@
   frames.push_back(QuicFrame(&ack_frame));
   // Receiving stream frame causes something to send.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
-    connection_.SendControlFrame(QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
+    connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
     // Verify now the queued ACK contains packet number 2.
     EXPECT_TRUE(QuicPacketCreatorPeer::QueuedFrames(
                     QuicConnectionPeer::GetPacketCreator(&connection_))[0]
@@ -15181,7 +15179,7 @@
         frame = QuicFrame(&blocked_frame);
         break;
       case WINDOW_UPDATE_FRAME:
-        frame = QuicFrame(&window_update_frame);
+        frame = QuicFrame(window_update_frame);
         break;
       case PATH_CHALLENGE_FRAME:
         frame = QuicFrame(&path_challenge_frame);
diff --git a/quic/core/quic_control_frame_manager.cc b/quic/core/quic_control_frame_manager.cc
index 39e768c..aed8806 100644
--- a/quic/core/quic_control_frame_manager.cc
+++ b/quic/core/quic_control_frame_manager.cc
@@ -78,7 +78,7 @@
     QuicStreamId id, QuicStreamOffset byte_offset) {
   QUIC_DVLOG(1) << "Writing WINDOW_UPDATE_FRAME";
   WriteOrBufferQuicFrame(QuicFrame(
-      new QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
+      QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
 }
 
 void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
@@ -160,7 +160,7 @@
     return;
   }
   if (frame.type == WINDOW_UPDATE_FRAME) {
-    QuicStreamId stream_id = frame.window_update_frame->stream_id;
+    QuicStreamId stream_id = frame.window_update_frame.stream_id;
     if (window_update_frames_.contains(stream_id) &&
         id > window_update_frames_[stream_id]) {
       // Consider the older window update of the same stream as acked.
@@ -190,7 +190,7 @@
     return false;
   }
   if (frame.type == WINDOW_UPDATE_FRAME) {
-    QuicStreamId stream_id = frame.window_update_frame->stream_id;
+    QuicStreamId stream_id = frame.window_update_frame.stream_id;
     if (window_update_frames_.contains(stream_id) &&
         window_update_frames_[stream_id] == id) {
       window_update_frames_.erase(stream_id);
diff --git a/quic/core/quic_control_frame_manager_test.cc b/quic/core/quic_control_frame_manager_test.cc
index 6d20811..9b2073b 100644
--- a/quic/core/quic_control_frame_manager_test.cc
+++ b/quic/core/quic_control_frame_manager_test.cc
@@ -81,8 +81,7 @@
               QuicControlFrameManagerPeer::QueueSize(manager_.get()));
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
-    EXPECT_TRUE(
-        manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
 
@@ -116,12 +115,12 @@
   manager_->OnCanWrite();
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
 
-  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&window_update_)));
-  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(window_update_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
   EXPECT_EQ(number_of_frames_,
             QuicControlFrameManagerPeer::QueueSize(manager_.get()));
 
@@ -161,7 +160,7 @@
   // Lost control frames 1, 2, 3.
   manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
   manager_->OnControlFrameLost(QuicFrame(&goaway_));
-  manager_->OnControlFrameLost(QuicFrame(&window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
   EXPECT_TRUE(manager_->HasPendingRetransmission());
 
   // Ack control frame 2.
@@ -202,12 +201,12 @@
   // Retransmit control frame 3.
   EXPECT_CALL(*session_, WriteControlFrame(_, _))
       .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&window_update_),
+  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
                                                PTO_RETRANSMISSION));
 
   // Retransmit control frame 4, and connection is write blocked.
   EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(&window_update_),
+  EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
                                                 PTO_RETRANSMISSION));
 }
 
@@ -288,9 +287,9 @@
   manager_->OnCanWrite();
 
   // Mark all 3 window updates as lost.
-  manager_->OnControlFrameLost(QuicFrame(&window_update_));
-  manager_->OnControlFrameLost(QuicFrame(&window_update2));
-  manager_->OnControlFrameLost(QuicFrame(&window_update3));
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update2));
+  manager_->OnControlFrameLost(QuicFrame(window_update3));
   EXPECT_TRUE(manager_->HasPendingRetransmission());
   EXPECT_TRUE(manager_->WillingToWrite());
 
@@ -299,7 +298,7 @@
       .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
   manager_->OnCanWrite();
   EXPECT_EQ(number_of_frames_ + 2u,
-            frame_.window_update_frame->control_frame_id);
+            frame_.window_update_frame.control_frame_id);
   EXPECT_FALSE(manager_->HasPendingRetransmission());
   EXPECT_FALSE(manager_->WillingToWrite());
   DeleteFrame(&frame_);
@@ -320,9 +319,9 @@
   manager_->OnCanWrite();
 
   // Mark all 3 window updates as lost.
-  manager_->OnControlFrameLost(QuicFrame(&window_update_));
-  manager_->OnControlFrameLost(QuicFrame(&window_update2));
-  manager_->OnControlFrameLost(QuicFrame(&window_update3));
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update2));
+  manager_->OnControlFrameLost(QuicFrame(window_update3));
   EXPECT_TRUE(manager_->HasPendingRetransmission());
   EXPECT_TRUE(manager_->WillingToWrite());
 
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 303ec74..d155bf7 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -673,7 +673,7 @@
       // For IETF QUIC, this could be either a MAX DATA or MAX STREAM DATA.
       // GetWindowUpdateFrameSize figures this out and returns the correct
       // length.
-      return GetWindowUpdateFrameSize(version, *frame.window_update_frame);
+      return GetWindowUpdateFrameSize(version, frame.window_update_frame);
     case BLOCKED_FRAME:
       return GetBlockedFrameSize(version, *frame.blocked_frame);
     case NEW_CONNECTION_ID_FRAME:
@@ -972,7 +972,7 @@
         }
         break;
       case WINDOW_UPDATE_FRAME:
-        if (!AppendWindowUpdateFrame(*frame.window_update_frame, &writer)) {
+        if (!AppendWindowUpdateFrame(frame.window_update_frame, &writer)) {
           QUIC_BUG(quic_bug_10850_25) << "AppendWindowUpdateFrame failed";
           return 0;
         }
@@ -1124,15 +1124,15 @@
       case WINDOW_UPDATE_FRAME:
         // Depending on whether there is a stream ID or not, will be either a
         // MAX STREAM DATA frame or a MAX DATA frame.
-        if (frame.window_update_frame->stream_id ==
+        if (frame.window_update_frame.stream_id ==
             QuicUtils::GetInvalidStreamId(transport_version())) {
-          if (!AppendMaxDataFrame(*frame.window_update_frame, writer)) {
+          if (!AppendMaxDataFrame(frame.window_update_frame, writer)) {
             QUIC_BUG(quic_bug_10850_38)
                 << "AppendMaxDataFrame failed: " << detailed_error();
             return 0;
           }
         } else {
-          if (!AppendMaxStreamDataFrame(*frame.window_update_frame, writer)) {
+          if (!AppendMaxStreamDataFrame(frame.window_update_frame, writer)) {
             QUIC_BUG(quic_bug_10850_39)
                 << "AppendMaxStreamDataFrame failed: " << detailed_error();
             return 0;
@@ -5263,7 +5263,7 @@
     case WINDOW_UPDATE_FRAME:
       // Depending on whether there is a stream ID or not, will be either a
       // MAX_STREAM_DATA frame or a MAX_DATA frame.
-      if (frame.window_update_frame->stream_id ==
+      if (frame.window_update_frame.stream_id ==
           QuicUtils::GetInvalidStreamId(transport_version())) {
         type_byte = IETF_MAX_DATA;
       } else {
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 150f2b8..a34fb04 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -9624,7 +9624,7 @@
   window_update_frame.stream_id = kStreamId;
   window_update_frame.max_data = 0x1122334455667788;
 
-  QuicFrames frames = {QuicFrame(&window_update_frame)};
+  QuicFrames frames = {QuicFrame(window_update_frame)};
 
   // clang-format off
   unsigned char packet[] = {
@@ -9712,7 +9712,7 @@
   window_update_frame.stream_id = kStreamId;
   window_update_frame.max_data = 0x1122334455667788;
 
-  QuicFrames frames = {QuicFrame(&window_update_frame)};
+  QuicFrames frames = {QuicFrame(window_update_frame)};
 
   // clang-format off
   unsigned char packet_ietf[] = {
@@ -9758,7 +9758,7 @@
       QuicUtils::GetInvalidStreamId(framer_.transport_version());
   window_update_frame.max_data = 0x1122334455667788;
 
-  QuicFrames frames = {QuicFrame(&window_update_frame)};
+  QuicFrames frames = {QuicFrame(window_update_frame)};
 
   // clang-format off
   unsigned char packet_ietf[] = {
@@ -12566,7 +12566,7 @@
   EXPECT_EQ(QuicFramer::GetWindowUpdateFrameSize(framer_.transport_version(),
                                                  window_update),
             QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&window_update)));
+                framer_.transport_version(), QuicFrame(window_update)));
 
   QuicBlockedFrame blocked(4, 3, 1024);
   EXPECT_EQ(
diff --git a/quic/core/quic_packets_test.cc b/quic/core/quic_packets_test.cc
index ce7cf8e..7568d22 100644
--- a/quic/core/quic_packets_test.cc
+++ b/quic/core/quic_packets_test.cc
@@ -78,8 +78,7 @@
   SerializedPacket packet(QuicPacketNumber(1), PACKET_1BYTE_PACKET_NUMBER,
                           buffer.data(), buffer.length(), /*has_ack=*/false,
                           /*has_stop_waiting=*/false);
-  packet.retransmittable_frames.push_back(
-      QuicFrame(new QuicWindowUpdateFrame()));
+  packet.retransmittable_frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
   packet.retransmittable_frames.push_back(QuicFrame(QuicStreamFrame()));
 
   QuicAckFrame ack_frame(InitAckFrame(1));
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index 5abc651..ee751dc 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -2488,7 +2488,7 @@
   QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1));
-  frames.push_back(QuicFrame(&window_update));
+  frames.push_back(QuicFrame(window_update));
   frames.push_back(QuicFrame(frame2));
   frames.push_back(QuicFrame(frame3));
   EXPECT_FALSE(session_.WillingAndAbleToWrite());
diff --git a/quic/core/quic_trace_visitor.cc b/quic/core/quic_trace_visitor.cc
index f603f58..31543f1 100644
--- a/quic/core/quic_trace_visitor.cc
+++ b/quic/core/quic_trace_visitor.cc
@@ -173,15 +173,15 @@
       break;
 
     case WINDOW_UPDATE_FRAME: {
-      bool is_connection = frame.window_update_frame->stream_id == 0;
+      bool is_connection = frame.window_update_frame.stream_id == 0;
       frame_record->set_frame_type(is_connection ? quic_trace::MAX_DATA
                                                  : quic_trace::MAX_STREAM_DATA);
 
       quic_trace::FlowControlInfo* info =
           frame_record->mutable_flow_control_info();
-      info->set_max_data(frame.window_update_frame->max_data);
+      info->set_max_data(frame.window_update_frame.max_data);
       if (!is_connection) {
-        info->set_stream_id(frame.window_update_frame->stream_id);
+        info->set_stream_id(frame.window_update_frame.stream_id);
       }
       break;
     }
@@ -194,7 +194,7 @@
       quic_trace::FlowControlInfo* info =
           frame_record->mutable_flow_control_info();
       if (!is_connection) {
-        info->set_stream_id(frame.window_update_frame->stream_id);
+        info->set_stream_id(frame.window_update_frame.stream_id);
       }
       break;
     }
@@ -272,9 +272,7 @@
   event->set_event_type(quic_trace::PACKET_RECEIVED);
   event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
 
-  // TODO(vasilvv): consider removing this copy.
-  QuicWindowUpdateFrame copy_of_update = frame;
-  PopulateFrameInfo(QuicFrame(&copy_of_update), event->add_frames());
+  PopulateFrameInfo(QuicFrame(frame), event->add_frames());
 }
 
 void QuicTraceVisitor::OnSuccessfulVersionNegotiation(
diff --git a/quic/core/quic_unacked_packet_map_test.cc b/quic/core/quic_unacked_packet_map_test.cc
index 07efee9..a4870cc 100644
--- a/quic/core/quic_unacked_packet_map_test.cc
+++ b/quic/core/quic_unacked_packet_map_test.cc
@@ -556,7 +556,7 @@
   QuicGoAwayFrame go_away(3, QUIC_PEER_GOING_AWAY, 5, "Going away.");
 
   QuicTransmissionInfo info1;
-  info1.retransmittable_frames.push_back(QuicFrame(&window_update));
+  info1.retransmittable_frames.push_back(QuicFrame(window_update));
   info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
   info1.retransmittable_frames.push_back(QuicFrame(stream_frame2));
 
diff --git a/quic/test_tools/simple_session_notifier.cc b/quic/test_tools/simple_session_notifier.cc
index d2be965..7f67fdd 100644
--- a/quic/test_tools/simple_session_notifier.cc
+++ b/quic/test_tools/simple_session_notifier.cc
@@ -116,8 +116,8 @@
   const bool had_buffered_data =
       HasBufferedStreamData() || HasBufferedControlFrames();
   QuicControlFrameId control_frame_id = ++last_control_frame_id_;
-  control_frames_.emplace_back((
-      QuicFrame(new QuicWindowUpdateFrame(control_frame_id, id, byte_offset))));
+  control_frames_.emplace_back(
+      (QuicFrame(QuicWindowUpdateFrame(control_frame_id, id, byte_offset))));
   if (had_buffered_data) {
     QUIC_DLOG(WARNING) << "Connection is write blocked";
     return;