[PATCH 4/5] d3dcompiler: Introduce an array_reserve() helper.

Zebediah Figura z.figura12 at gmail.com
Tue Mar 24 19:18:36 CDT 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/d3dcompiler_43/bytecodewriter.c      | 75 +++++++++++------------
 dlls/d3dcompiler_43/d3dcompiler_private.h |  6 +-
 2 files changed, 37 insertions(+), 44 deletions(-)

diff --git a/dlls/d3dcompiler_43/bytecodewriter.c b/dlls/d3dcompiler_43/bytecodewriter.c
index 5a02eb7cf81..90857f76e66 100644
--- a/dlls/d3dcompiler_43/bytecodewriter.c
+++ b/dlls/d3dcompiler_43/bytecodewriter.c
@@ -27,6 +27,35 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(bytecodewriter);
 
+static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
+{
+    unsigned int max_capacity, new_capacity;
+    void *new_elements;
+
+    if (count <= *capacity)
+        return TRUE;
+
+    max_capacity = ~(unsigned int)0 / size;
+    if (count > max_capacity)
+        return FALSE;
+
+    new_capacity = max(8, *capacity);
+    while (new_capacity < count && new_capacity <= max_capacity / 2)
+        new_capacity *= 2;
+    if (new_capacity < count)
+        new_capacity = count;
+
+    if (!(new_elements = d3dcompiler_realloc(*elements, new_capacity * size)))
+    {
+        ERR("Failed to allocate memory.\n");
+        return FALSE;
+    }
+
+    *elements = new_elements;
+    *capacity = new_capacity;
+    return TRUE;
+}
+
 /****************************************************************
  * General assembler shader construction helper routines follow *
  ****************************************************************/
@@ -73,30 +102,11 @@ struct instruction *alloc_instr(unsigned int srcs) {
  *  instr: Instruction to add to the shader
  */
 BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
-    struct instruction      **new_instructions;
-
     if(!shader) return FALSE;
 
-    if(shader->instr_alloc_size == 0) {
-        shader->instr = d3dcompiler_alloc(sizeof(*shader->instr) * INSTRARRAY_INITIAL_SIZE);
-        if(!shader->instr) {
-            ERR("Failed to allocate the shader instruction array\n");
-            return FALSE;
-        }
-        shader->instr_alloc_size = INSTRARRAY_INITIAL_SIZE;
-    } else if(shader->instr_alloc_size == shader->num_instrs) {
-        new_instructions = d3dcompiler_realloc(shader->instr,
-                                       sizeof(*shader->instr) * (shader->instr_alloc_size) * 2);
-        if(!new_instructions) {
-            ERR("Failed to grow the shader instruction array\n");
-            return FALSE;
-        }
-        shader->instr = new_instructions;
-        shader->instr_alloc_size = shader->instr_alloc_size * 2;
-    } else if(shader->num_instrs > shader->instr_alloc_size) {
-        ERR("More instructions than allocated. This should not happen\n");
+    if (!array_reserve((void **)&shader->instr, &shader->instr_alloc_size,
+            shader->num_instrs + 1, sizeof(*shader->instr)))
         return FALSE;
-    }
 
     shader->instr[shader->num_instrs] = instr;
     shader->num_instrs++;
@@ -310,13 +320,6 @@ static struct bytecode_buffer *allocate_buffer(void) {
 
     ret = d3dcompiler_alloc(sizeof(*ret));
     if(!ret) return NULL;
-
-    ret->alloc_size = BYTECODEBUFFER_INITIAL_SIZE;
-    ret->data = d3dcompiler_alloc(sizeof(DWORD) * ret->alloc_size);
-    if(!ret->data) {
-        d3dcompiler_free(ret);
-        return NULL;
-    }
     ret->state = S_OK;
     return ret;
 }
@@ -324,18 +327,12 @@ static struct bytecode_buffer *allocate_buffer(void) {
 static void put_dword(struct bytecode_buffer *buffer, DWORD value) {
     if(FAILED(buffer->state)) return;
 
-    if(buffer->alloc_size == buffer->size) {
-        DWORD *newarray;
-        buffer->alloc_size *= 2;
-        newarray = d3dcompiler_realloc(buffer->data,
-                               sizeof(DWORD) * buffer->alloc_size);
-        if(!newarray) {
-            ERR("Failed to grow the buffer data memory\n");
-            buffer->state = E_OUTOFMEMORY;
-            return;
-        }
-        buffer->data = newarray;
+    if (!array_reserve((void **)&buffer->data, &buffer->alloc_size, buffer->size + 1, sizeof(*buffer->data)))
+    {
+        buffer->state = E_OUTOFMEMORY;
+        return;
     }
+
     buffer->data[buffer->size++] = value;
 }
 
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index b9caf595804..650d5fc520d 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -115,7 +115,6 @@ struct samplerdecl {
     DWORD                   mod;
 };
 
-#define INSTRARRAY_INITIAL_SIZE 8
 struct bwriter_shader {
     enum shader_type        type;
     unsigned char major_version, minor_version;
@@ -293,12 +292,9 @@ static inline void set_parse_status(enum parse_status *current, enum parse_statu
         *current = PARSE_WARN;
 }
 
-/* A reasonable value as initial size */
-#define BYTECODEBUFFER_INITIAL_SIZE 32
 struct bytecode_buffer {
     DWORD *data;
-    DWORD size;
-    DWORD alloc_size;
+    unsigned int size, alloc_size;
     /* For tracking rare out of memory situations without passing
      * return values around everywhere
      */
-- 
2.25.1




More information about the wine-devel mailing list