Browse Source

chore: cherry-pick 5 changes from 1-M125 (#42572)

* chore: [29-x-y] cherry-pick 5 changes from 1-M125

* e7b64c6ee185 from v8
* 867c1001637e from DirectXShaderCompiler
* b922fcb61e3b from chromium
* bda89e1f7c71 from angle
* 0d9598145069 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Pedro Pontes 10 months ago
parent
commit
914d8f373e

+ 1 - 0
patches/DirectXShaderCompiler/.patches

@@ -2,3 +2,4 @@ cherry-pick-a65e511a14b4.patch
 cherry-pick-bc18aec94c82.patch
 cherry-pick-bd7aa9779873.patch
 cherry-pick-2a434fd0af6b.patch
+cherry-pick-867c1001637e.patch

+ 108 - 0
patches/DirectXShaderCompiler/cherry-pick-867c1001637e.patch

@@ -0,0 +1,108 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Antonio Maiorano <[email protected]>
+Date: Thu, 16 May 2024 14:24:27 -0400
+Subject: Fix invalid module bitcode when indexing a swizzled bool vector
+ (#6582)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When indexing a swizzled bool vector, some HLSL-specific code in
+EmitCXXMemberOrOperatorMemberCallExpr kicks in to handle the
+HLSLVecType. In this case, we’re dealing with an ExtVectorElt because of
+the swizzle, so this function creates a GEP, Load, and Store on the
+vector. However, boolean scalars are returned as type i11 while the
+store is storing to a bool, which is an i32, so we need to insert a cast
+before the store.
+
+Bug: chromium:338161969
+Change-Id: I45f8ec383be49210a10f725d8266b66fd30c34be
+Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5545820
+Reviewed-by: James Price <[email protected]>
+Reviewed-by: dan sinclair <[email protected]>
+
+diff --git a/tools/clang/lib/CodeGen/CGExpr.cpp b/tools/clang/lib/CodeGen/CGExpr.cpp
+index cc46d067e617f1032bd7bc3ea6f65276984df130..efef0593b334103e511d43e3986fed3c304d28a3 100644
+--- a/tools/clang/lib/CodeGen/CGExpr.cpp
++++ b/tools/clang/lib/CodeGen/CGExpr.cpp
+@@ -1137,6 +1137,12 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
+   return MDHelper.createRange(Min, End);
+ }
+ 
++static bool ShouldEmitRangeMD(llvm::Value *Value, QualType Ty) {
++  if (hasBooleanRepresentation(Ty))
++    return cast<llvm::IntegerType>(Value->getType())->getBitWidth() != 1;
++  return true;
++}
++
+ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
+                                                unsigned Alignment, QualType Ty,
+                                                SourceLocation Loc,
+@@ -1236,7 +1242,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
+       EmitCheck(std::make_pair(Check, Kind), "load_invalid_value", StaticArgs,
+                 EmitCheckValue(Load));
+     }
+-  } else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
++  } else if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
++             ShouldEmitRangeMD(Load, Ty))
+     if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
+       Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
+ 
+diff --git a/tools/clang/lib/CodeGen/CGExprCXX.cpp b/tools/clang/lib/CodeGen/CGExprCXX.cpp
+index 2efde7c30f7f25fed5b36fe7de062b31e6cd74a2..924a0f806e7a8acf310005a212bb3c50a3c519b9 100644
+--- a/tools/clang/lib/CodeGen/CGExprCXX.cpp
++++ b/tools/clang/lib/CodeGen/CGExprCXX.cpp
+@@ -235,12 +235,17 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
+ 
+           llvm::Constant *zero = Builder.getInt32(0);
+           llvm::Value *TmpThis = CreateTempAlloca(Ty);
++          QualType ElTy = hlsl::GetElementTypeOrType(Base->getType());
++          bool IsBool = ElTy->isSpecificBuiltinType(BuiltinType::Bool);
+           for (unsigned i = 0; i < Ty->getVectorNumElements(); i++) {
+             llvm::Value *EltIdx = Elts->getAggregateElement(i);
+             llvm::Value *EltGEP = Builder.CreateGEP(This, {zero, EltIdx});
+             llvm::Value *TmpEltGEP =
+                 Builder.CreateGEP(TmpThis, {zero, Builder.getInt32(i)});
+             llvm::Value *Elt = Builder.CreateLoad(EltGEP);
++            if (IsBool)
++              Elt = Builder.CreateTrunc(
++                  Elt, llvm::Type::getInt1Ty(getLLVMContext()));
+             Builder.CreateStore(Elt, TmpEltGEP);
+           }
+           This = TmpThis;
+diff --git a/tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl b/tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl
+new file mode 100644
+index 0000000000000000000000000000000000000000..a47482d204547d01b8f237bdde0765e61e6b7ab0
+--- /dev/null
++++ b/tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl
+@@ -0,0 +1,30 @@
++// Test indexing a swizzled bool vector
++// RUN: %dxc -fcgl -T cs_6_0 %s | FileCheck %s
++
++// This was asserting in Instructions.cpp with:
++// void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
++
++// Make sure load of i32 gets truncated to i1 when indexing bool vectors
++// CHECK:       [[TMP:%[a-z0-9\.]+]] = alloca <2 x i1>
++// CHECK:       [[VA0:%[a-z0-9\.]+]] = getelementptr <2 x i1>, <2 x i1>* [[TMP]], i32 0, i32 0,
++// CHECK-NEXT:  [[VA1:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds (<4 x i32>, <4 x i32>* @"\01?v_bool4@?1??main@@YAXXZ@3V?$vector@_N$03@@B", i32 0, i32 2),
++// CHECK-NEXT:  [[VA2:%[a-z0-9\.]+]] = trunc i32 [[VA1]] to i1,
++// CHECK-NEXT:  store i1 [[VA2]], i1* [[VA0]],
++// CHECK-NEXT:  [[VB0:%[a-z0-9\.]+]] = getelementptr <2 x i1>, <2 x i1>* [[TMP]], i32 0, i32 1,
++// CHECK-NEXT:  [[VB1:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds (<4 x i32>, <4 x i32>* @"\01?v_bool4@?1??main@@YAXXZ@3V?$vector@_N$03@@B", i32 0, i32 3),
++// CHECK-NEXT:  [[VB2:%[a-z0-9\.]+]] = trunc i32 [[VB1]] to i1,
++// CHECK-NEXT:  store i1 [[VB2]], i1* [[VB0]],
++
++
++cbuffer cbuffer_tint_symbol_3 : register(b0) {
++    uint4 global_uint4[1];
++};
++
++[numthreads(1, 1, 1)]
++void main() {
++    const bool4 v_bool4 = bool4(true, true, true, true);
++    const uint gx = global_uint4[0].x;
++    if (v_bool4.zw[gx] == 0) {
++        GroupMemoryBarrierWithGroupSync();
++    }
++}

+ 1 - 0
patches/angle/.patches

@@ -2,3 +2,4 @@ m123_vulkan_fix_access_to_inactive_attributes.patch
 cherry-pick-f6672dbbe223.patch
 cherry-pick-ba3b4e239620.patch
 cherry-pick-c67f290ef0f0.patch
+cherry-pick-bda89e1f7c71.patch

+ 74 - 0
patches/angle/cherry-pick-bda89e1f7c71.patch

@@ -0,0 +1,74 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Shahbaz Youssefi <[email protected]>
+Date: Thu, 2 May 2024 11:17:33 -0400
+Subject: M124: Vulkan: Turn SPIR-V limitations to crash instead of security
+ bug
+
+The input shader can be made complex in a number of different ways,
+resulting in instructions with a length higher than what can fit in
+SPIR-V (i.e. 16 bits).  Ideally, the translator would catch such complex
+usage early on and gracefully fail compilation.  However, as a safety
+net, this change makes sure such a case is detected when the SPIR-V
+instruction is being generated and turned into a crash.  This makes sure
+such bugs are no longer security bugs.
+
+Bug: chromium:335613092
+Change-Id: Iab16b49ed80929fc343b4c7bffce306919de2e96
+Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5547611
+Reviewed-by: Roman Lavrov <[email protected]>
+
+diff --git a/scripts/code_generation_hashes/SPIR-V_helpers.json b/scripts/code_generation_hashes/SPIR-V_helpers.json
+index cb1b596b6d02f35e2817cac53ace42d64e33bffd..944cf1a2cbd34a0e28e7cfad4b874344f662512b 100644
+--- a/scripts/code_generation_hashes/SPIR-V_helpers.json
++++ b/scripts/code_generation_hashes/SPIR-V_helpers.json
+@@ -1,8 +1,8 @@
+ {
+   "src/common/spirv/gen_spirv_builder_and_parser.py":
+-    "e95670a30a4eda80a146b61c986fb03c",
++    "868a697edbc38c95e36be54cf5c71435",
+   "src/common/spirv/spirv_instruction_builder_autogen.cpp":
+-    "1b5f60a24d459e7a30c29cf7acfa2106",
++    "c149de371bcd571bd31cc8eb1e517910",
+   "src/common/spirv/spirv_instruction_builder_autogen.h":
+     "56b1309d8afabb2b64d7e16f0c4a4898",
+   "src/common/spirv/spirv_instruction_parser_autogen.cpp":
+diff --git a/src/common/spirv/gen_spirv_builder_and_parser.py b/src/common/spirv/gen_spirv_builder_and_parser.py
+index 5e8e9bc4e8914cf2173a8fa720446f6647dd065e..c7e1f401b380f3b4fe0bd6b9178b42ee5ac41250 100755
+--- a/src/common/spirv/gen_spirv_builder_and_parser.py
++++ b/src/common/spirv/gen_spirv_builder_and_parser.py
+@@ -93,6 +93,15 @@ uint32_t MakeLengthOp(size_t length, spv::Op op)
+     ASSERT(length <= 0xFFFFu);
+     ASSERT(op <= 0xFFFFu);
+ 
++    // It's easy for a complex shader to be crafted to hit the length limit,
++    // turn that into a crash instead of a security bug.  Ideally, the compiler
++    // would gracefully fail compilation, so this is more of a safety net.
++    if (ANGLE_UNLIKELY(length > 0xFFFFu))
++    {
++        ERR() << "Complex shader not representible in SPIR-V";
++        ANGLE_CRASH();
++    }
++
+     return static_cast<uint32_t>(length) << 16 | op;
+ }
+ }  // anonymous namespace
+diff --git a/src/common/spirv/spirv_instruction_builder_autogen.cpp b/src/common/spirv/spirv_instruction_builder_autogen.cpp
+index 3c73c58e3c0141f3e00a61eab784d3e3b96dff8e..6e6ad6f510cb76588f61dacee8dbcac5a544d8d1 100644
+--- a/src/common/spirv/spirv_instruction_builder_autogen.cpp
++++ b/src/common/spirv/spirv_instruction_builder_autogen.cpp
+@@ -25,6 +25,15 @@ uint32_t MakeLengthOp(size_t length, spv::Op op)
+     ASSERT(length <= 0xFFFFu);
+     ASSERT(op <= 0xFFFFu);
+ 
++    // It's easy for a complex shader to be crafted to hit the length limit,
++    // turn that into a crash instead of a security bug.  Ideally, the compiler
++    // would gracefully fail compilation, so this is more of a safety net.
++    if (ANGLE_UNLIKELY(length > 0xFFFFu))
++    {
++        ERR() << "Complex shader not representible in SPIR-V";
++        ANGLE_CRASH();
++    }
++
+     return static_cast<uint32_t>(length) << 16 | op;
+ }
+ }  // anonymous namespace

+ 2 - 0
patches/chromium/.patches

@@ -144,3 +144,5 @@ cherry-pick-b2cc7b7ac538.patch
 feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch
 cherry-pick-03609e39be8c.patch
 x11_use_localized_display_label_only_for_browser_process.patch
+cherry-pick-b922fcb61e3b.patch
+cherry-pick-0d9598145069.patch

+ 805 - 0
patches/chromium/cherry-pick-0d9598145069.patch

@@ -0,0 +1,805 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Brendon Tiszka <[email protected]>
+Date: Mon, 20 May 2024 18:33:53 +0000
+Subject: Fix bugs in GLES* command handlers
+
+If the command buffer is in an invalid state then we can't trust
+the contents of the get buffer.
+
+(cherry picked from commit 374789ab8f5eeac24e2e335af825d34b8c3fde81)
+
+Bug: 340822365,40947303
+Change-Id: I465d617e5056877fb464dd59df983a9e8d866b85
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5542488
+Commit-Queue: Brendon Tiszka <[email protected]>
+Reviewed-by: Geoff Lang <[email protected]>
+Cr-Original-Commit-Position: refs/heads/main@{#1301529}
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5550571
+Reviewed-by: Brendon Tiszka <[email protected]>
+Owners-Override: Prudhvikumar Bommana <[email protected]>
+Bot-Commit: Rubber Stamper <[email protected]>
+Cr-Commit-Position: refs/branch-heads/6367@{#1205}
+Cr-Branched-From: d158c6dc6e3604e6f899041972edf26087a49740-refs/heads/main@{#1274542}
+
+diff --git a/gpu/command_buffer/build_cmd_buffer_lib.py b/gpu/command_buffer/build_cmd_buffer_lib.py
+index b8ca818edd2d225ea6309f202edbba6e957f1f35..4f1aa8efefd3ef8591aad3e90fc57f4b78347317 100644
+--- a/gpu/command_buffer/build_cmd_buffer_lib.py
++++ b/gpu/command_buffer/build_cmd_buffer_lib.py
+@@ -2954,7 +2954,9 @@ class GETnHandler(TypeHandler):
+   result->SetNumResults(0);
+   helper_->%(func_name)s(%(arg_string)s,
+       GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(%(last_arg_name)s);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -4456,7 +4458,9 @@ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
+       f.write(
+           "  helper_->%s(%s, GetResultShmId(), result.offset());\n" %
+               (func.name, arg_string))
+-      f.write("  WaitForCmd();\n")
++      f.write("  if (!WaitForCmd()) {\n")
++      f.write("    return %s; \n" % error_value)
++      f.write("  }\n")
+       f.write("  %s result_value = *result" % func.return_type)
+       if func.return_type == "GLboolean":
+         f.write(" != 0")
+diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
+index e02399bcbdc6b2e642751038aa47ecfdf80e587c..ad9aa976ec776ff6be69c57c701bbcfc7cdfbd93 100644
+--- a/gpu/command_buffer/client/gles2_implementation.cc
++++ b/gpu/command_buffer/client/gles2_implementation.cc
+@@ -595,7 +595,9 @@ GLenum GLES2Implementation::GetGLError() {
+   }
+   *result = GL_NO_ERROR;
+   helper_->GetError(GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_NO_ERROR;
++  }
+   GLenum error = *result;
+   if (error == GL_NO_ERROR) {
+     error = GetClientSideGLError();
+@@ -720,7 +722,9 @@ GLboolean GLES2Implementation::IsEnabled(GLenum cap) {
+     }
+     *result = 0;
+     helper_->IsEnabled(cap, GetResultShmId(), result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return GL_FALSE;
++    }
+     state = (*result) != 0;
+   }
+ 
+@@ -741,7 +745,9 @@ GLboolean GLES2Implementation::IsEnablediOES(GLenum target, GLuint index) {
+     auto result = GetResultAs<Result>();
+     *result = 0;
+     helper_->IsEnablediOES(target, index, GetResultShmId(), result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return GL_FALSE;
++    }
+     state = (*result) != 0;
+   }
+ 
+@@ -1360,7 +1366,9 @@ GLuint GLES2Implementation::GetMaxValueInBufferCHROMIUMHelper(GLuint buffer_id,
+   *result = 0;
+   helper_->GetMaxValueInBufferCHROMIUM(buffer_id, count, type, offset,
+                                        GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return 0;
++  }
+   return *result;
+ }
+ 
+@@ -1663,7 +1671,9 @@ void GLES2Implementation::GetVertexAttribPointerv(GLuint index,
+     result->SetNumResults(0);
+     helper_->GetVertexAttribPointerv(index, pname, GetResultShmId(),
+                                      result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(ptr);
+     GPU_CLIENT_LOG_CODE_BLOCK(num_results = result->GetNumResults());
+   }
+@@ -1738,7 +1748,9 @@ GLint GLES2Implementation::GetAttribLocationHelper(GLuint program,
+   *result = -1;
+   helper_->GetAttribLocation(program, kResultBucketId, GetResultShmId(),
+                              result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return -1;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -1766,7 +1778,9 @@ GLint GLES2Implementation::GetUniformLocationHelper(GLuint program,
+   *result = -1;
+   helper_->GetUniformLocation(program, kResultBucketId, GetResultShmId(),
+                               result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return -1;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -1799,7 +1813,9 @@ bool GLES2Implementation::GetUniformIndicesHelper(GLuint program,
+   result->SetNumResults(0);
+   helper_->GetUniformIndices(program, kResultBucketId, GetResultShmId(),
+                              result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   if (result->GetNumResults() != count) {
+     return false;
+   }
+@@ -1859,7 +1875,9 @@ GLint GLES2Implementation::GetFragDataIndexEXTHelper(GLuint program,
+   *result = -1;
+   helper_->GetFragDataIndexEXT(program, kResultBucketId, GetResultShmId(),
+                                result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return -1;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -1888,7 +1906,9 @@ GLint GLES2Implementation::GetFragDataLocationHelper(GLuint program,
+   *result = -1;
+   helper_->GetFragDataLocation(program, kResultBucketId, GetResultShmId(),
+                                result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return -1;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -1917,7 +1937,9 @@ GLuint GLES2Implementation::GetUniformBlockIndexHelper(GLuint program,
+   *result = GL_INVALID_INDEX;
+   helper_->GetUniformBlockIndex(program, kResultBucketId, GetResultShmId(),
+                                 result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_INVALID_INDEX;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -1962,7 +1984,9 @@ GLuint GLES2Implementation::GetProgramResourceIndexHelper(
+   *result = GL_INVALID_INDEX;
+   helper_->GetProgramResourceIndex(program, program_interface, kResultBucketId,
+                                    GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_INVALID_INDEX;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -2007,7 +2031,9 @@ bool GLES2Implementation::GetProgramResourceNameHelper(GLuint program,
+     helper_->GetProgramResourceName(program, program_interface, index,
+                                     kResultBucketId, GetResultShmId(),
+                                     result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return false;
++    }
+     success = !!*result;
+   }
+   if (success) {
+@@ -2066,7 +2092,9 @@ bool GLES2Implementation::GetProgramResourceivHelper(GLuint program,
+   helper_->GetProgramResourceiv(program, program_interface, index,
+                                 kResultBucketId, GetResultShmId(),
+                                 result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   if (length) {
+     *length = result->GetNumResults();
+   }
+@@ -2138,7 +2166,9 @@ GLint GLES2Implementation::GetProgramResourceLocationHelper(
+   helper_->GetProgramResourceLocation(program, program_interface,
+                                       kResultBucketId, GetResultShmId(),
+                                       result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return -1;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   return *result;
+ }
+@@ -4015,7 +4045,9 @@ bool GLES2Implementation::GetActiveAttribHelper(GLuint program,
+   result->success = false;
+   helper_->GetActiveAttrib(program, index, kResultBucketId, GetResultShmId(),
+                            result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   bool success = !!result->success;
+   if (success) {
+     if (size) {
+@@ -4083,7 +4115,9 @@ bool GLES2Implementation::GetActiveUniformHelper(GLuint program,
+   result->success = false;
+   helper_->GetActiveUniform(program, index, kResultBucketId, GetResultShmId(),
+                             result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   bool success = !!result->success;
+   if (success) {
+     if (size) {
+@@ -4150,7 +4184,9 @@ bool GLES2Implementation::GetActiveUniformBlockNameHelper(GLuint program,
+   *result = 0;
+   helper_->GetActiveUniformBlockName(program, index, kResultBucketId,
+                                      GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   bool success = !!result;
+   if (success) {
+     // Note: this can invalidate |result|.
+@@ -4197,7 +4233,9 @@ bool GLES2Implementation::GetActiveUniformBlockivHelper(GLuint program,
+   result->SetNumResults(0);
+   helper_->GetActiveUniformBlockiv(program, index, pname, GetResultShmId(),
+                                    result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   if (result->GetNumResults() > 0) {
+     if (params) {
+       result->CopyResult(params);
+@@ -4254,7 +4292,9 @@ bool GLES2Implementation::GetActiveUniformsivHelper(GLuint program,
+   result->SetNumResults(0);
+   helper_->GetActiveUniformsiv(program, kResultBucketId, pname,
+                                GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   bool success = result->GetNumResults() == count;
+   if (success) {
+     if (params) {
+@@ -4330,7 +4370,9 @@ void GLES2Implementation::GetAttachedShaders(GLuint program,
+                               transfer_buffer_->GetOffset(result),
+                               checked_size);
+   int32_t token = helper_->InsertToken();
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   if (count) {
+     *count = result->GetNumResults();
+   }
+@@ -4372,7 +4414,9 @@ void GLES2Implementation::GetShaderPrecisionFormat(GLenum shadertype,
+       result->success = false;
+       helper_->GetShaderPrecisionFormat(shadertype, precisiontype,
+                                         GetResultShmId(), result.offset());
+-      WaitForCmd();
++      if (!WaitForCmd()) {
++        return;
++      }
+       if (result->success)
+         static_state_.shader_precisions[key] = *result;
+     }
+@@ -4485,7 +4529,9 @@ bool GLES2Implementation::GetTransformFeedbackVaryingHelper(GLuint program,
+   result->success = false;
+   helper_->GetTransformFeedbackVarying(program, index, kResultBucketId,
+                                        GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   if (result->success) {
+     if (size) {
+       *size = result->size;
+@@ -4553,7 +4599,9 @@ void GLES2Implementation::GetUniformfv(GLuint program,
+     }
+     result->SetNumResults(0);
+     helper_->GetUniformfv(program, location, GetResultShmId(), result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -4581,7 +4629,9 @@ void GLES2Implementation::GetUniformiv(GLuint program,
+     }
+     result->SetNumResults(0);
+     helper_->GetUniformiv(program, location, GetResultShmId(), result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -4610,7 +4660,9 @@ void GLES2Implementation::GetUniformuiv(GLuint program,
+     result->SetNumResults(0);
+     helper_->GetUniformuiv(program, location, GetResultShmId(),
+                            result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -4788,7 +4840,9 @@ void GLES2Implementation::ReadbackARGBImagePixelsINTERNAL(
+       dst_sk_color_type, dst_sk_alpha_type, shm_id, shm_offset,
+       color_space_offset, pixels_offset, mailbox_offset);
+ 
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   if (!*readback_result) {
+     return;
+   }
+@@ -4936,7 +4990,9 @@ void GLES2Implementation::ReadPixels(GLint xoffset,
+     helper_->ReadPixels(xoffset, y_index, width, num_rows, format, type,
+                         buffer.shm_id(), buffer.offset(), GetResultShmId(),
+                         result.offset(), false);
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      break;
++    }
+     // If it was not marked as successful exit.
+     if (!result->success) {
+       break;
+@@ -5645,7 +5701,9 @@ void GLES2Implementation::GetVertexAttribfv(GLuint index,
+     }
+     result->SetNumResults(0);
+     helper_->GetVertexAttribfv(index, pname, GetResultShmId(), result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -5678,7 +5736,9 @@ void GLES2Implementation::GetVertexAttribiv(GLuint index,
+     }
+     result->SetNumResults(0);
+     helper_->GetVertexAttribiv(index, pname, GetResultShmId(), result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -5712,7 +5772,9 @@ void GLES2Implementation::GetVertexAttribIiv(GLuint index,
+     result->SetNumResults(0);
+     helper_->GetVertexAttribIiv(index, pname, GetResultShmId(),
+                                 result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -5746,7 +5808,9 @@ void GLES2Implementation::GetVertexAttribIuiv(GLuint index,
+     result->SetNumResults(0);
+     helper_->GetVertexAttribIuiv(index, pname, GetResultShmId(),
+                                  result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     result->CopyResult(params);
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -5781,7 +5845,9 @@ GLboolean GLES2Implementation::EnableFeatureCHROMIUM(const char* feature) {
+   *result = 0;
+   helper_->EnableFeatureCHROMIUM(kResultBucketId, GetResultShmId(),
+                                  result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return false;
++  }
+   helper_->SetBucketSize(kResultBucketId, 0);
+   GPU_CLIENT_LOG("   returned " << GLES2Util::GetStringBool(*result));
+   return *result != 0;
+@@ -5936,7 +6002,9 @@ void* GLES2Implementation::MapBufferRange(GLenum target,
+                             GetResultShmId(), result.offset());
+     // TODO(zmo): For write only mode with MAP_INVALID_*_BIT, we should
+     // consider an early return without WaitForCmd(). crbug.com/465804.
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return nullptr;
++    }
+     if (*result) {
+       const GLbitfield kInvalidateBits =
+           GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
+@@ -7211,7 +7279,9 @@ GLenum GLES2Implementation::ClientWaitSync(GLsync sync,
+     *result = GL_WAIT_FAILED;
+     helper_->ClientWaitSync(ToGLuint(sync), flags, timeout, GetResultShmId(),
+                             result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return GL_WAIT_FAILED;
++    }
+     localResult = *result;
+     GPU_CLIENT_LOG("returned " << localResult);
+   }
+@@ -7289,7 +7359,9 @@ void GLES2Implementation::GetInternalformativ(GLenum target,
+     result->SetNumResults(0);
+     helper_->GetInternalformativ(target, format, pname, GetResultShmId(),
+                                  result.offset());
+-    WaitForCmd();
++    if (!WaitForCmd()) {
++      return;
++    }
+     GPU_CLIENT_LOG_CODE_BLOCK({
+       for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+         GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+index 5db0583dceea74aaa819979d2253bb0ae5b03413..9e578e3f4c69a16098250ff22e04b8b4e0391d1b 100644
+--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
++++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+@@ -207,7 +207,9 @@ GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) {
+   }
+   *result = 0;
+   helper_->CheckFramebufferStatus(target, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FRAMEBUFFER_UNSUPPORTED;
++  }
+   GLenum result_value = *result;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -882,7 +884,9 @@ void GLES2Implementation::GetBooleanv(GLenum pname, GLboolean* params) {
+   }
+   result->SetNumResults(0);
+   helper_->GetBooleanv(pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -910,7 +914,9 @@ void GLES2Implementation::GetBooleani_v(GLenum pname,
+   }
+   result->SetNumResults(0);
+   helper_->GetBooleani_v(pname, index, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(data);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -939,7 +945,9 @@ void GLES2Implementation::GetBufferParameteri64v(GLenum target,
+   result->SetNumResults(0);
+   helper_->GetBufferParameteri64v(target, pname, GetResultShmId(),
+                                   result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -969,7 +977,9 @@ void GLES2Implementation::GetBufferParameteriv(GLenum target,
+   result->SetNumResults(0);
+   helper_->GetBufferParameteriv(target, pname, GetResultShmId(),
+                                 result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -994,7 +1004,9 @@ void GLES2Implementation::GetFloatv(GLenum pname, GLfloat* params) {
+   }
+   result->SetNumResults(0);
+   helper_->GetFloatv(pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1029,7 +1041,9 @@ void GLES2Implementation::GetFramebufferAttachmentParameteriv(GLenum target,
+   result->SetNumResults(0);
+   helper_->GetFramebufferAttachmentParameteriv(
+       target, attachment, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1054,7 +1068,9 @@ void GLES2Implementation::GetInteger64v(GLenum pname, GLint64* params) {
+   }
+   result->SetNumResults(0);
+   helper_->GetInteger64v(pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1082,7 +1098,9 @@ void GLES2Implementation::GetIntegeri_v(GLenum pname,
+   }
+   result->SetNumResults(0);
+   helper_->GetIntegeri_v(pname, index, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(data);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1109,7 +1127,9 @@ void GLES2Implementation::GetInteger64i_v(GLenum pname,
+   }
+   result->SetNumResults(0);
+   helper_->GetInteger64i_v(pname, index, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(data);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1135,7 +1155,9 @@ void GLES2Implementation::GetIntegerv(GLenum pname, GLint* params) {
+   }
+   result->SetNumResults(0);
+   helper_->GetIntegerv(pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1163,7 +1185,9 @@ void GLES2Implementation::GetProgramiv(GLuint program,
+   }
+   result->SetNumResults(0);
+   helper_->GetProgramiv(program, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1220,7 +1244,9 @@ void GLES2Implementation::GetRenderbufferParameteriv(GLenum target,
+   result->SetNumResults(0);
+   helper_->GetRenderbufferParameteriv(target, pname, GetResultShmId(),
+                                       result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1249,7 +1275,9 @@ void GLES2Implementation::GetSamplerParameterfv(GLuint sampler,
+   result->SetNumResults(0);
+   helper_->GetSamplerParameterfv(sampler, pname, GetResultShmId(),
+                                  result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1279,7 +1307,9 @@ void GLES2Implementation::GetSamplerParameteriv(GLuint sampler,
+   result->SetNumResults(0);
+   helper_->GetSamplerParameteriv(sampler, pname, GetResultShmId(),
+                                  result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1307,7 +1337,9 @@ void GLES2Implementation::GetShaderiv(GLuint shader,
+   }
+   result->SetNumResults(0);
+   helper_->GetShaderiv(shader, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1396,7 +1428,9 @@ void GLES2Implementation::GetSynciv(GLsync sync,
+   }
+   result->SetNumResults(0);
+   helper_->GetSynciv(ToGLuint(sync), pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(values);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1427,7 +1461,9 @@ void GLES2Implementation::GetTexParameterfv(GLenum target,
+   }
+   result->SetNumResults(0);
+   helper_->GetTexParameterfv(target, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1456,7 +1492,9 @@ void GLES2Implementation::GetTexParameteriv(GLenum target,
+   }
+   result->SetNumResults(0);
+   helper_->GetTexParameteriv(target, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -1541,7 +1579,9 @@ GLboolean GLES2Implementation::IsBuffer(GLuint buffer) {
+   }
+   *result = 0;
+   helper_->IsBuffer(buffer, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1560,7 +1600,9 @@ GLboolean GLES2Implementation::IsFramebuffer(GLuint framebuffer) {
+   }
+   *result = 0;
+   helper_->IsFramebuffer(framebuffer, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1578,7 +1620,9 @@ GLboolean GLES2Implementation::IsProgram(GLuint program) {
+   }
+   *result = 0;
+   helper_->IsProgram(program, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1597,7 +1641,9 @@ GLboolean GLES2Implementation::IsRenderbuffer(GLuint renderbuffer) {
+   }
+   *result = 0;
+   helper_->IsRenderbuffer(renderbuffer, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1615,7 +1661,9 @@ GLboolean GLES2Implementation::IsSampler(GLuint sampler) {
+   }
+   *result = 0;
+   helper_->IsSampler(sampler, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1633,7 +1681,9 @@ GLboolean GLES2Implementation::IsShader(GLuint shader) {
+   }
+   *result = 0;
+   helper_->IsShader(shader, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1651,7 +1701,9 @@ GLboolean GLES2Implementation::IsSync(GLsync sync) {
+   }
+   *result = 0;
+   helper_->IsSync(ToGLuint(sync), GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1669,7 +1721,9 @@ GLboolean GLES2Implementation::IsTexture(GLuint texture) {
+   }
+   *result = 0;
+   helper_->IsTexture(texture, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -1689,7 +1743,9 @@ GLboolean GLES2Implementation::IsTransformFeedback(GLuint transformfeedback) {
+   *result = 0;
+   helper_->IsTransformFeedback(transformfeedback, GetResultShmId(),
+                                result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -3093,7 +3149,9 @@ GLboolean GLES2Implementation::IsVertexArrayOES(GLuint array) {
+   }
+   *result = 0;
+   helper_->IsVertexArrayOES(array, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return GL_FALSE;
++  }
+   GLboolean result_value = *result != 0;
+   GPU_CLIENT_LOG("returned " << result_value);
+   CheckGLError();
+@@ -3187,7 +3245,9 @@ void GLES2Implementation::GetProgramInterfaceiv(GLuint program,
+   result->SetNumResults(0);
+   helper_->GetProgramInterfaceiv(program, program_interface, pname,
+                                  GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -3905,7 +3965,9 @@ void GLES2Implementation::GetFramebufferPixelLocalStorageParameterfvANGLE(
+   result->SetNumResults(0);
+   helper_->GetFramebufferPixelLocalStorageParameterfvANGLE(
+       plane, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+@@ -3939,7 +4001,9 @@ void GLES2Implementation::GetFramebufferPixelLocalStorageParameterivANGLE(
+   result->SetNumResults(0);
+   helper_->GetFramebufferPixelLocalStorageParameterivANGLE(
+       plane, pname, GetResultShmId(), result.offset());
+-  WaitForCmd();
++  if (!WaitForCmd()) {
++    return;
++  }
+   result->CopyResult(params);
+   GPU_CLIENT_LOG_CODE_BLOCK({
+     for (int32_t i = 0; i < result->GetNumResults(); ++i) {

+ 89 - 0
patches/chromium/cherry-pick-b922fcb61e3b.patch

@@ -0,0 +1,89 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: rubberyuzu <[email protected]>
+Date: Fri, 17 May 2024 02:53:09 +0000
+Subject: Use WeakPtr for delegate_
+
+This CL starts using a WeakPtr for `delegate_`. This is because
+`ReportFeaturesToDelegate()` is posted and when it's executed,
+`delegate_` might be destroyed.
+
+(cherry picked from commit da7a6845e589dc71da9898f7e181a7c88a62e2e1)
+
+Bug: 336012573
+Change-Id: I9aa5ee7ae7d484d4208e6bdd8ea2853763d69a6b
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5493004
+Reviewed-by: Kentaro Hara <[email protected]>
+Commit-Queue: Yuzu Saijo <[email protected]>
+Reviewed-by: Fergal Daly <[email protected]>
+Cr-Original-Commit-Position: refs/heads/main@{#1297242}
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5547038
+Auto-Submit: Yuzu Saijo <[email protected]>
+Commit-Queue: Kentaro Hara <[email protected]>
+Cr-Commit-Position: refs/branch-heads/6367@{#1190}
+Cr-Branched-From: d158c6dc6e3604e6f899041972edf26087a49740-refs/heads/main@{#1274542}
+
+diff --git a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
+index e2f7dc1ff4384fa2e0dcb07539b269cdbb3f0c89..6bb65c49603e8efd3a84cabc6bf77a8a0fb359be 100644
+--- a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
++++ b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
+@@ -22,9 +22,13 @@ BackForwardCacheDisablingFeatureTracker::
+ 
+ void BackForwardCacheDisablingFeatureTracker::SetDelegate(
+     FrameOrWorkerScheduler::Delegate* delegate) {
++  // This function is only called when initializing. `delegate_` should be
++  // nullptr at first.
+   DCHECK(!delegate_);
+-  delegate_ = delegate;
+-  // `delegate` might be nullptr on tests.
++  // `delegate` can be nullptr for tests.
++  if (delegate) {
++    delegate_ = (*delegate).AsWeakPtr();
++  }
+ }
+ 
+ void BackForwardCacheDisablingFeatureTracker::Reset() {
+@@ -162,7 +166,13 @@ void BackForwardCacheDisablingFeatureTracker::ReportFeaturesToDelegate() {
+   last_reported_sticky_ = sticky_features_and_js_locations_;
+   FrameOrWorkerScheduler::Delegate::BlockingDetails details(
+       non_sticky_features_and_js_locations_, sticky_features_and_js_locations_);
+-  delegate_->UpdateBackForwardCacheDisablingFeatures(details);
++
++  // Check if the delegate still exists. This check is necessary because
++  // `FrameOrWorkerScheduler::Delegate` might be destroyed and thus `delegate_`
++  // might be gone when `ReportFeaturesToDelegate() is executed.
++  if (delegate_) {
++    delegate_->UpdateBackForwardCacheDisablingFeatures(details);
++  }
+ }
+ 
+ }  // namespace scheduler
+diff --git a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
+index c78d791aa7c40a6775e84f79fd1a5e357328581e..1ec5cc4627cc71a941df32ecd989a5897f796dce 100644
+--- a/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
++++ b/third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
+@@ -119,8 +119,7 @@ class PLATFORM_EXPORT BackForwardCacheDisablingFeatureTracker {
+   BFCacheBlockingFeatureAndLocations non_sticky_features_and_js_locations_;
+   BFCacheBlockingFeatureAndLocations sticky_features_and_js_locations_;
+ 
+-  raw_ptr<FrameOrWorkerScheduler::Delegate, DanglingUntriaged> delegate_ =
+-      nullptr;
++  base::WeakPtr<FrameOrWorkerScheduler::Delegate> delegate_ = nullptr;
+   raw_ptr<ThreadSchedulerBase, DanglingUntriaged> scheduler_;
+ 
+   base::WeakPtrFactory<BackForwardCacheDisablingFeatureTracker> weak_factory_{
+diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
+index 82befdeabdce4904002d6b35aaef8a796b613209..7f95ec0339cc2baabbae05a1a9b332e4dbc23bf5 100644
+--- a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
++++ b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
+@@ -149,6 +149,11 @@ class PLATFORM_EXPORT FrameOrWorkerScheduler {
+     // changed when a blocking feature and its JS location are registered or
+     // removed.
+     virtual void UpdateBackForwardCacheDisablingFeatures(BlockingDetails) = 0;
++
++    base::WeakPtr<Delegate> AsWeakPtr() {
++      return weak_ptr_factory_.GetWeakPtr();
++    }
++    base::WeakPtrFactory<Delegate> weak_ptr_factory_{this};
+   };
+ 
+   virtual ~FrameOrWorkerScheduler();

+ 1 - 0
patches/v8/.patches

@@ -5,3 +5,4 @@ cherry-pick-f320600cd1f4.patch
 cherry-pick-b3c01ac1e60a.patch
 cherry-pick-6503a987d966.patch
 cherry-pick-3e037e195e50.patch
+cherry-pick-e7b64c6ee185.patch

+ 31 - 0
patches/v8/cherry-pick-e7b64c6ee185.patch

@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Matthias Liedtke <[email protected]>
+Date: Fri, 10 May 2024 10:38:29 +0200
+Subject: Merged: [builtins] HasOnlySimpleElements is false for non-JSObjects
+
+Bug: 338908243
+(cherry picked from commit cc05792346fb017eaa961ee7d35cf1f9bb53bb0a)
+
+Change-Id: I9b5c2333924a54169ea3fa48e67e7db2ec67f6b9
+Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5545380
+Reviewed-by: Jakob Kummerow <[email protected]>
+Commit-Queue: Matthias Liedtke <[email protected]>
+Auto-Submit: Matthias Liedtke <[email protected]>
+Commit-Queue: Jakob Kummerow <[email protected]>
+Cr-Commit-Position: refs/branch-heads/12.4@{#34}
+Cr-Branched-From: 309640da62fae0485c7e4f64829627c92d53b35d-refs/heads/12.4.254@{#1}
+Cr-Branched-From: 5dc24701432278556a9829d27c532f974643e6df-refs/heads/main@{#92862}
+
+diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc
+index 60dc19367aa38997721ed85df6210f9de3a44313..dc82b658df09e5850ef2688fae1d748cb9873917 100644
+--- a/src/builtins/builtins-array.cc
++++ b/src/builtins/builtins-array.cc
+@@ -51,7 +51,7 @@ inline bool HasOnlySimpleElements(Isolate* isolate,
+   DisallowGarbageCollection no_gc;
+   PrototypeIterator iter(isolate, receiver, kStartAtReceiver);
+   for (; !iter.IsAtEnd(); iter.Advance()) {
+-    if (IsJSProxy(iter.GetCurrent())) return false;
++    if (!IsJSObject(iter.GetCurrent())) return false;
+     Tagged<JSObject> current = iter.GetCurrent<JSObject>();
+     if (!HasSimpleElements(current)) return false;
+   }