Browse Source

chore: cherry-pick f666cceb92c2 from dawn (#40265)

* chore: cherry-pick f666cceb92c2 from dawn

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Pedro Pontes 1 year ago
parent
commit
37882e805a
3 changed files with 199 additions and 1 deletions
  1. 3 1
      patches/config.json
  2. 1 0
      patches/dawn/.patches
  3. 195 0
      patches/dawn/cherry-pick-f666cceb92c2.patch

+ 3 - 1
patches/config.json

@@ -21,5 +21,7 @@
 
   "src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
 
-  "src/electron/patches/webrtc": "src/third_party/webrtc"
+  "src/electron/patches/webrtc": "src/third_party/webrtc",
+
+  "src/electron/patches/dawn": "src/third_party/dawn"
 }

+ 1 - 0
patches/dawn/.patches

@@ -0,0 +1 @@
+cherry-pick-f666cceb92c2.patch

+ 195 - 0
patches/dawn/cherry-pick-f666cceb92c2.patch

@@ -0,0 +1,195 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Ben Clayton <[email protected]>
+Date: Tue, 17 Oct 2023 14:53:45 +0000
+Subject: Add support for large allocations
+
+From the BumpAllocator.
+
+Bug: chromium:1491912
+Change-Id: I632fea8de1451358aa24f8a8d05c07d7f6823d7d
+Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/155840
+Kokoro: Ben Clayton <[email protected]>
+Reviewed-by: Antonio Maiorano <[email protected]>
+
+diff --git a/src/tint/symbol_table.cc b/src/tint/symbol_table.cc
+index cdea0a488f2a57ec12628eff29d31eaea2889d7d..66461a9f427542752568edab386da026a3682ee1 100644
+--- a/src/tint/symbol_table.cc
++++ b/src/tint/symbol_table.cc
+@@ -37,8 +37,10 @@ Symbol SymbolTable::Register(std::string_view name) {
+ }
+ 
+ Symbol SymbolTable::RegisterInternal(std::string_view name) {
+-    char* name_mem = name_allocator_.Allocate(name.length() + 1);
++    char* name_mem = utils::Bitcast<char*>(name_allocator_.Allocate(name.length() + 1));
+     if (name_mem == nullptr) {
++        tint::diag::List diags;
++        TINT_ICE(Utils, diags) << "failed to allocate memory for symbol's string";
+         return Symbol();
+     }
+ 
+diff --git a/src/tint/utils/bump_allocator.h b/src/tint/utils/bump_allocator.h
+index 302f924bcb6695c01bc36d28c39d3c32482e82a5..6f41c18fb71d70ec8813f0ef781bac2824fef476 100644
+--- a/src/tint/utils/bump_allocator.h
++++ b/src/tint/utils/bump_allocator.h
+@@ -15,11 +15,14 @@
+ #ifndef SRC_TINT_UTILS_BUMP_ALLOCATOR_H_
+ #define SRC_TINT_UTILS_BUMP_ALLOCATOR_H_
+ 
++#include <algorithm>
+ #include <array>
++#include <cstddef>
+ #include <cstring>
+ #include <utility>
+ 
+ #include "src/tint/utils/bitcast.h"
++#include "src/tint/utils/compiler_macros.h"
+ #include "src/tint/utils/math.h"
+ 
+ namespace tint::utils {
+@@ -29,14 +32,17 @@ constexpr size_t kBlockSize = 64 * 1024;
+ /// A allocator for chunks of memory. The memory is owned by the BumpAllocator. When the
+ /// BumpAllocator is freed all of the allocated memory is freed.
+ class BumpAllocator {
+-    /// Block is linked list of memory blocks.
++    /// BlockHeader is linked list of memory blocks.
+     /// Blocks are allocated out of heap memory.
+-    struct Block {
+-        uint8_t data[kBlockSize];
+-        Block* next;
++    struct BlockHeader {
++        BlockHeader* next;
+     };
+ 
+   public:
++    /// The default size for a block's data. Allocations can be greater than this, but smaller
++    /// allocations will use this size.
++    static constexpr size_t kDefaultBlockDataSize = 64 * 1024;
++
+     /// Constructor
+     BumpAllocator() = default;
+ 
+@@ -61,38 +67,43 @@ class BumpAllocator {
+     /// Allocates @p size_in_bytes from the current block, or from a newly allocated block if the
+     /// current block is full.
+     /// @param size_in_bytes the number of bytes to allocate
+-    /// @returns the pointer to the allocated memory or |nullptr| if the memory can not be allocated
+-    char* Allocate(size_t size_in_bytes) {
+-        auto& block = data.block;
+-        if (block.current_offset + size_in_bytes > kBlockSize) {
++    /// @returns the pointer to the allocated memory or `nullptr` if the memory can not be allocated
++    std::byte* Allocate(size_t size_in_bytes) {
++        if (TINT_UNLIKELY(data.current_offset + size_in_bytes < size_in_bytes)) {
++            return nullptr;  // integer overflow
++        }
++        if (data.current_offset + size_in_bytes > data.current_data_size) {
+             // Allocate a new block from the heap
+-            auto* prev_block = block.current;
+-            block.current = new Block;
+-            if (!block.current) {
++            auto* prev_block = data.current;
++            size_t data_size = std::max(size_in_bytes, kDefaultBlockDataSize);
++            data.current = Bitcast<BlockHeader*>(new (std::nothrow)
++                                                     std::byte[sizeof(BlockHeader) + data_size]);
++            if (TINT_UNLIKELY(!data.current)) {
+                 return nullptr;  // out of memory
+             }
+-            block.current->next = nullptr;
+-            block.current_offset = 0;
++            data.current->next = nullptr;
++            data.current_data_size = data_size;
++            data.current_offset = 0;
+             if (prev_block) {
+-                prev_block->next = block.current;
++                prev_block->next = data.current;
+             } else {
+-                block.root = block.current;
++                data.root = data.current;
+             }
+         }
+ 
+-        auto* base = &block.current->data[0];
+-        auto* ptr = reinterpret_cast<char*>(base + block.current_offset);
+-        block.current_offset += size_in_bytes;
++        auto* base = Bitcast<std::byte*>(data.current) + sizeof(BlockHeader);
++        auto* ptr = base + data.current_offset;
++        data.current_offset += size_in_bytes;
+         data.count++;
+         return ptr;
+     }
+ 
+     /// Frees all allocations from the allocator.
+     void Reset() {
+-        auto* block = data.block.root;
++        auto* block = data.root;
+         while (block != nullptr) {
+             auto* next = block->next;
+-            delete block;
++            delete[] Bitcast<std::byte*>(block);
+             block = next;
+         }
+         data = {};
+@@ -106,18 +117,16 @@ class BumpAllocator {
+     BumpAllocator& operator=(const BumpAllocator&) = delete;
+ 
+     struct {
+-        struct {
+-            /// The root block of the block linked list
+-            Block* root = nullptr;
+-            /// The current (end) block of the blocked linked list.
+-            /// New allocations come from this block
+-            Block* current = nullptr;
+-            /// The byte offset in #current for the next allocation.
+-            /// Initialized with kBlockSize so that the first allocation triggers a block
+-            /// allocation.
+-            size_t current_offset = kBlockSize;
+-        } block;
+-
++        /// The root block of the block linked list
++        BlockHeader* root = nullptr;
++        /// The current (end) block of the blocked linked list.
++        /// New allocations come from this block
++        BlockHeader* current = nullptr;
++        /// The byte offset in #current for the next allocation.
++        size_t current_offset = 0;
++        /// The size of the #current, excluding the header size
++        size_t current_data_size = 0;
++        /// Total number of allocations
+         size_t count = 0;
+     } data;
+ };
+diff --git a/src/tint/utils/bump_allocator_test.cc b/src/tint/utils/bump_allocator_test.cc
+index 4f224558fdd7baa943e8b7b09765d64d01a9f3e6..cd840fe5e023e26bc308904a881333de2b8e7c16 100644
+--- a/src/tint/utils/bump_allocator_test.cc
++++ b/src/tint/utils/bump_allocator_test.cc
+@@ -21,6 +21,31 @@ namespace {
+ 
+ using BumpAllocatorTest = testing::Test;
+ 
++TEST_F(BumpAllocatorTest, AllocationSizes) {
++    BumpAllocator allocator;
++    for (size_t n : {1u, 0x10u, 0x100u, 0x1000u, 0x10000u, 0x100000u,  //
++                     2u, 0x34u, 0x567u, 0x8912u, 0x34567u, 0x891234u}) {
++        auto ptr = allocator.Allocate(n);
++        memset(ptr, 0x42, n);
++    }
++}
++
++TEST_F(BumpAllocatorTest, AllocationSizesAroundBlockSize) {
++    for (size_t n : {
++             BumpAllocator::kDefaultBlockDataSize - sizeof(void*),
++             BumpAllocator::kDefaultBlockDataSize - 4,
++             BumpAllocator::kDefaultBlockDataSize - 1,
++             BumpAllocator::kDefaultBlockDataSize,
++             BumpAllocator::kDefaultBlockDataSize + 1,
++             BumpAllocator::kDefaultBlockDataSize + 4,
++             BumpAllocator::kDefaultBlockDataSize + sizeof(void*),
++         }) {
++        BumpAllocator allocator;
++        auto* ptr = allocator.Allocate(n);
++        memset(ptr, 0x42, n);
++    }
++}
++
+ TEST_F(BumpAllocatorTest, Count) {
+     for (size_t n : {0u, 1u, 10u, 16u, 20u, 32u, 50u, 64u, 100u, 256u, 300u, 512u, 500u, 512u}) {
+         BumpAllocator allocator;