Lichen

Changeset

883:754d84209719
2019-01-31 Paul Boddie raw files shortlog changelog graph Try using GC_generic_malloc_many to allocate multiple objects at once. float-preallocation
templates/native/float.c (file)
     1.1 --- a/templates/native/float.c	Sun Jan 27 01:08:28 2019 +0100
     1.2 +++ b/templates/native/float.c	Thu Jan 31 22:48:01 2019 +0100
     1.3 @@ -19,6 +19,7 @@
     1.4  #include <math.h>   /* pow */
     1.5  #include <stdio.h>  /* snprintf */
     1.6  #include <errno.h>  /* errno */
     1.7 +#include <gc/gc_inline.h>
     1.8  #include "native/common.h"
     1.9  #include "types.h"
    1.10  #include "exceptions.h"
    1.11 @@ -28,65 +29,50 @@
    1.12  #include "progtypes.h"
    1.13  #include "main.h"
    1.14  
    1.15 -/* A table of preallocated float instances. */
    1.16 +/* A list of preallocated float instances. */
    1.17  
    1.18 -struct float_table
    1.19 -{
    1.20 -    struct float_table *next;
    1.21 -    char data[];
    1.22 -};
    1.23 -
    1.24 -static struct float_table *next_float = 0;
    1.25 +static void *preallocated_floats;
    1.26  
    1.27  /* Preallocate some float instances. */
    1.28  
    1.29 -static void preallocate_floats(int num)
    1.30 -{
    1.31 -    struct float_table *latest;
    1.32 -    int i;
    1.33 -
    1.34 -    for (i = 0; i < num; i++)
    1.35 -    {
    1.36 -        /* Allocate a table entry. */
    1.37 +#define MULTIPLE(VALUE, STEP) (((VALUE) + (STEP) - 1) & (~((STEP) - 1)))
    1.38 +#define PTRFREE 0
    1.39  
    1.40 -        latest = (struct float_table *)
    1.41 -                 __ALLOCATE(1, sizeof(struct float_table *) +
    1.42 -                               __INSTANCESIZE(__builtins___float_float));
    1.43 -
    1.44 -        /* Reference the last entry from the new entry. */
    1.45 -
    1.46 -        latest->next = next_float;
    1.47 -        next_float = latest;
    1.48 -    }
    1.49 +static void preallocate_floats()
    1.50 +{
    1.51 +    GC_generic_malloc_many(MULTIPLE(__INSTANCESIZE(__builtins___float_float), GC_GRANULE_BYTES),
    1.52 +                           PTRFREE, &preallocated_floats);
    1.53  }
    1.54  
    1.55  static __attr new_float(double n)
    1.56  {
    1.57 -    struct float_table *this_float;
    1.58 +    __ref obj, next;
    1.59      __attr attr;
    1.60  
    1.61 -    if (!next_float)
    1.62 -        preallocate_floats(1000);
    1.63 +    if (!preallocated_floats)
    1.64 +        preallocate_floats();
    1.65 +
    1.66 +    obj = preallocated_floats;
    1.67  
    1.68 -    /* Reference the next preallocated entry. */
    1.69 +    /* Obtain the next object in the free list from the address in the first
    1.70 +       word of the current object. */
    1.71  
    1.72 -    this_float = next_float;
    1.73 +    next = (__ref) *((void **) preallocated_floats);
    1.74  
    1.75      /* Initialise the embedded instance. */
    1.76  
    1.77 -    __init((__ref) &this_float->data,
    1.78 +    __init(obj,
    1.79             &__INSTANCETABLE(__builtins___float_float),
    1.80             &__builtins___float_float);
    1.81  
    1.82      /* Populate the float with the value. */
    1.83  
    1.84 -    attr = __ATTRVALUE(&this_float->data);
    1.85 +    attr = __ATTRVALUE(obj);
    1.86      __set_trailing_data(attr, __builtins___float_float, n);
    1.87  
    1.88      /* Make the next entry available and detach it from this one. */
    1.89  
    1.90 -    next_float = this_float->next;
    1.91 -    this_float->next = 0;
    1.92 +    preallocated_floats = next;
    1.93  
    1.94      return attr;
    1.95  }