1.1 --- a/src/Array.cpp Sun Sep 16 19:02:23 2012 -0700
1.2 +++ b/src/Array.cpp Sun Sep 16 21:34:10 2012 -0700
1.3 @@ -18,6 +18,7 @@
1.4 */
1.5 #include <string.h>
1.6 #include "Array.h"
1.7 +#include "FixedArray.h"
1.8 #include "Heap.h"
1.9 #include "Zone.h"
1.10 #include "Structures.h"
1.11 @@ -58,37 +59,60 @@
1.12 return map;
1.13 }
1.14
1.15 -static inline size_t
1.16 -SizeFor(Type *type, unsigned elements)
1.17 -{
1.18 - if (type->contained()->isTraceable())
1.19 - return sizeof(Array) + elements * sizeof(ke::Object *);
1.20 - if (type->contained()->isInt32())
1.21 - return sizeof(Array) + elements * sizeof(int);
1.22 - if (type->contained()->primitive() == PrimitiveType_Char)
1.23 - return sizeof(Array) + elements * sizeof(char);
1.24 - assert(type->contained()->isFloat());
1.25 - return elements * sizeof(float);
1.26 -}
1.27 -
1.28 Array *
1.29 Array::NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure)
1.30 {
1.31 - if (nelements > (INT_MAX / SizeFor(map->type(), 1))) {
1.32 + if (nelements > (INT_MAX / SizeForElement(map->type()))) {
1.33 zone->reportError(Message_ArraySizeTooBig);
1.34 return NULL;
1.35 }
1.36
1.37 - size_t elementBytes = SizeFor(map->type(), nelements);
1.38 - size_t bytes = sizeof(Array) + elementBytes;
1.39 + size_t bytes = sizeof(Array);
1.40 + if (map->type()->hasInlineElements())
1.41 + bytes += SizeForElement(map->type()) * nelements;
1.42 +
1.43 Local<Array> array(zone, Array::cast(zone->allocate(map, bytes, tenure)));
1.44 if (!array)
1.45 return NULL;
1.46
1.47 - array->nelements_ = nelements;
1.48 - array->elements_ = (Array *)array + 1;
1.49 - memset(array->vec(), 0, elementBytes);
1.50 + array->length_ = 0;
1.51 + array->elements_ = NULL;
1.52 +
1.53 + if (map->type()->hasInlineElements()) {
1.54 + // This must be a fixed array containing no traceables.
1.55 + assert(nelements > 0);
1.56 + assert(map->type()->isFixedLength());
1.57 + assert(!map->type()->contained()->isTraceable());
1.58 +
1.59 + // Compute an interior |elements_| pointer, such that if elements_
1.60 + // is accessed like a FixedArray, we reach the appropriate vector.
1.61 + array->elements_ = Address((Array *)array + 1) - ByteArray::offsetToElements();
1.62 + array->length_ = nelements;
1.63 + memset(array->bytes(), 0, SizeForElement(map->type()) * nelements);
1.64 + return array;
1.65 + }
1.66
1.67 + // If there is nothing to allocate, we don't bother creating elements yet.
1.68 + if (!nelements)
1.69 + return array;
1.70 +
1.71 + if (!map->type()->contained()->isTraceable()) {
1.72 + size_t nbytes = SizeForElement(map->type()) * nelements;
1.73 + Local<ByteArray> elements(zone, ByteArray::New(zone, nbytes, tenure));
1.74 + if (!elements)
1.75 + return NULL;
1.76 +
1.77 + array->updateLengthAndElements(zone, nelements, elements);
1.78 + return array;
1.79 + }
1.80 +
1.81 + Local<FixedArray> elements(zone, FixedArray::New(zone, nelements, tenure));
1.82 + if (!elements)
1.83 + return NULL;
1.84 +
1.85 + array->updateLengthAndElements(zone, nelements, elements);
1.86 +
1.87 + // If this is an array of structs, we're required to allocate those structs now.
1.88 if (map->type()->contained()->isStruct()) {
1.89 Local<StructMap> childMap(zone, StructMap::cast(map->type()->contained()->newMap()));
1.90 Local<Struct> child(zone);
1.91 @@ -97,7 +121,7 @@
1.92 if (!child)
1.93 return NULL;
1.94
1.95 - array->writeObject(zone, i, child);
1.96 + elements->set(zone, i, child);
1.97 }
1.98 }
1.99
1.100 @@ -211,15 +235,15 @@
1.101 }
1.102
1.103 Array *
1.104 -Array::NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements, void *buffer,
1.105 +Array::NewExternal(Zone *zone, Handle<ArrayMap> map, void *buffer, unsigned length,
1.106 Heap::Tenure tenure)
1.107 {
1.108 Local<Array> array(zone, Array::cast(zone->allocate(map, sizeof(Array), tenure)));
1.109 if (!array)
1.110 return NULL;
1.111
1.112 - array->nelements_ = nelements;
1.113 - array->elements_ = buffer;
1.114 + array->length_ = length;
1.115 + array->elements_ = Address(buffer) - ByteArray::offsetToElements();
1.116 return array;
1.117 }
1.118