Refactory array maps to allow arrays of structs.
Refactory array maps to allow arrays of structs.
1.1 --- a/src/Array.cpp Sat Aug 04 23:58:23 2012 -0700
1.2 +++ b/src/Array.cpp Sun Aug 05 00:31:20 2012 -0700
1.3 @@ -1,30 +1,32 @@
1.4 -/*
1.5 +/* vim: set ts=4 sw=4 tw=99 et:
1.6 + *
1.7 * Copyright (C) 2012 David Anderson
1.8 *
1.9 - * This file is part of JITCraft.
1.10 + * This file is part of SourcePawn.
1.11 *
1.12 - * JITCraft is free software: you can redistribute it and/or modify it under
1.13 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.14 * the terms of the GNU General Public License as published by the Free
1.15 * Software Foundation, either version 3 of the License, or (at your option)
1.16 * any later version.
1.17 *
1.18 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.19 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.20 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.21 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.22 *
1.23 * You should have received a copy of the GNU General Public License along with
1.24 - * JITCraft. If not, see http://www.gnu.org/licenses/.
1.25 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.26 */
1.27 #include <string.h>
1.28 #include "Array.h"
1.29 #include "Heap.h"
1.30 #include "Zone.h"
1.31 +#include "Structures.h"
1.32 #include "Heap-inl.h"
1.33
1.34 using namespace ke;
1.35
1.36 ArrayMap *
1.37 -ArrayMap::New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained)
1.38 +ArrayMap::New(Zone *zone, Handle<Type> type)
1.39 {
1.40 Local<Map> obj(zone, zone->allocateMap(MapKind_Array, sizeof(ArrayMap), MapKind_MetaArray));
1.41 if (!obj)
1.42 @@ -32,14 +34,13 @@
1.43
1.44 Local<ArrayMap> map(zone, ArrayMap::cast(obj));
1.45 map->type_ = type;
1.46 - map->contained_ = contained;
1.47 return map;
1.48 }
1.49
1.50 static inline size_t
1.51 SizeFor(Type *type, unsigned elements)
1.52 {
1.53 - if (type->levels() > 1)
1.54 + if (type->contained()->isTraceable())
1.55 return sizeof(Array) + elements * sizeof(ke::Object *);
1.56 if (type->contained()->isInt32())
1.57 return sizeof(Array) + elements * sizeof(int);
1.58 @@ -60,7 +61,30 @@
1.59
1.60 array->nelements_ = elements;
1.61 array->elements_ = (Array *)array + 1;
1.62 - memset(array->elements_, 0, elementBytes);
1.63 +
1.64 + if (map->type()->contained()->isArray()) {
1.65 + Local<ArrayMap> childMap(zone, ArrayMap::cast(map->type()->contained()->newMap()));
1.66 + Local<Array> child(zone);
1.67 + for (unsigned i = 0; i < elements; i++) {
1.68 + child = Array::New(zone, childMap, map->type()->contained()->elements(), tenure);
1.69 + if (!child)
1.70 + return NULL;
1.71 +
1.72 + array->writeObject(zone, i, child);
1.73 + }
1.74 + } else if (map->type()->contained()->isStruct()) {
1.75 + Local<StructMap> childMap(zone, StructMap::cast(map->type()->contained()->newMap()));
1.76 + Local<Struct> child(zone);
1.77 + for (unsigned i = 0; i < elements; i++) {
1.78 + child = Struct::New(zone, childMap, tenure);
1.79 + if (!child)
1.80 + return NULL;
1.81 +
1.82 + array->writeObject(zone, i, child);
1.83 + }
1.84 + } else {
1.85 + memset(array->elements_, 0, elementBytes);
1.86 + }
1.87 return array;
1.88 }
1.89
1.90 @@ -76,3 +100,4 @@
1.91 array->elements_ = buffer;
1.92 return array;
1.93 }
1.94 +
2.1 --- a/src/Array.h Sat Aug 04 23:58:23 2012 -0700
2.2 +++ b/src/Array.h Sun Aug 05 00:31:20 2012 -0700
2.3 @@ -109,25 +109,18 @@
2.4 class ArrayMap : public Map
2.5 {
2.6 Barriered<Type> type_;
2.7 - Barriered<ArrayMap> contained_;
2.8
2.9 public:
2.10 - static ArrayMap *New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained);
2.11 + static ArrayMap *New(Zone *zone, Handle<Type> type);
2.12
2.13 Type *type() {
2.14 return type_;
2.15 }
2.16 - ArrayMap *contained() {
2.17 - return contained_;
2.18 - }
2.19
2.20 // GC Descriptor.
2.21 static inline size_t offsetOfType() {
2.22 return OFFSETOF(ArrayMap, type_);
2.23 }
2.24 - static inline size_t offsetOfContained() {
2.25 - return OFFSETOF(ArrayMap, contained_);
2.26 - }
2.27 // End GC Descriptor.
2.28
2.29 static ArrayMap *cast(Object *obj) {
2.30 @@ -155,7 +148,7 @@
2.31 inline Object **
2.32 Array::objVec()
2.33 {
2.34 - assert(type()->levels() > 1);
2.35 + assert(type()->contained()->isTraceable());
2.36 return reinterpret_cast<Object **>(vec());
2.37 }
2.38
3.1 --- a/src/BytecodeCompiler.cpp Sat Aug 04 23:58:23 2012 -0700
3.2 +++ b/src/BytecodeCompiler.cpp Sun Aug 05 00:31:20 2012 -0700
3.3 @@ -539,11 +539,7 @@
3.4 node->right()->accept(this);
3.5 __ note_position(node->pos());
3.6 __ bounds();
3.7 -
3.8 - if (node->type()->isArray())
3.9 - __ getarray_o();
3.10 - else
3.11 - __ getarray(node->type());
3.12 + __ getarray(node->type());
3.13 }
3.14
3.15 void
3.16 @@ -741,15 +737,15 @@
3.17 static inline ArrayMap *
3.18 BuildArrayMap(Zone *zone, Handle<Type> type)
3.19 {
3.20 - Local<ArrayMap> contained(zone);
3.21 - if (type->levels() > 1) {
3.22 - Local<Type> containedType(zone, type->contained());
3.23 - contained = BuildArrayMap(zone, containedType);
3.24 - if (!contained)
3.25 - return NULL;
3.26 - }
3.27 + if (type->newMap())
3.28 + return ArrayMap::cast(type->newMap());
3.29
3.30 - return ArrayMap::New(zone, type, contained);
3.31 + Local<ArrayMap> map(zone, ArrayMap::New(zone, type));
3.32 + if (!map)
3.33 + return NULL;
3.34 +
3.35 + type->setNewMap(map);
3.36 + return map;
3.37 }
3.38
3.39 void
4.1 --- a/src/BytecodeEmitter.h Sat Aug 04 23:58:23 2012 -0700
4.2 +++ b/src/BytecodeEmitter.h Sun Aug 05 00:31:20 2012 -0700
4.3 @@ -366,6 +366,12 @@
4.4 }
4.5
4.6 void getarray(Type *type) {
4.7 + if (type->isTraceable()) {
4.8 + singleByteOp(OP_GETARRAY_O);
4.9 + markOop(1);
4.10 + return;
4.11 + }
4.12 +
4.13 switch (type->pod()) {
4.14 case PrimitiveType_Float:
4.15 singleByteOp(OP_GETARRAY_F);
4.16 @@ -447,10 +453,6 @@
4.17 writeUint32(var->slot());
4.18 }
4.19
4.20 - void getarray_o() {
4.21 - singleByteOp(OP_GETARRAY_O);
4.22 - markOop(1);
4.23 - }
4.24 void bounds() {
4.25 singleByteOp(OP_BOUNDS);
4.26 markOop(2);
5.1 --- a/src/Interpreter.cpp Sat Aug 04 23:58:23 2012 -0700
5.2 +++ b/src/Interpreter.cpp Sun Aug 05 00:31:20 2012 -0700
5.3 @@ -81,31 +81,6 @@
5.4 return true;
5.5 }
5.6
5.7 -// Generate an array with completely static sizes.
5.8 -static Array *
5.9 -GenerateArray(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
5.10 -{
5.11 - assert(map->type()->elements() != -1);
5.12 -
5.13 - Local<Array> array(zone, Array::New(zone, map, map->type()->elements(), tenure));
5.14 - if (!array)
5.15 - return NULL;
5.16 -
5.17 - if (map->type()->levels() == 1)
5.18 - return array;
5.19 -
5.20 - Local<ArrayMap> contained(zone, map->contained());
5.21 - Local<Array> sub(zone);
5.22 - for (unsigned i = 0; i < unsigned(map->type()->elements()); i++) {
5.23 - sub = GenerateArray(zone, contained, tenure);
5.24 - if (!sub)
5.25 - return NULL;
5.26 - array->writeObject(zone, i, sub);
5.27 - }
5.28 -
5.29 - return array;
5.30 -}
5.31 -
5.32 // Even though this function can fail, we immediately bail out, so it doesn't
5.33 // matter if we've leaving things unrooted.
5.34 static bool
5.35 @@ -766,7 +741,7 @@
5.36 {
5.37 Array *array = top.sp[-2].array;
5.38 int index = top.sp[-1].i32;
5.39 - top.sp[-2].array = Array::cast(array->readObject(index));
5.40 + top.sp[-2].obj = array->readObject(index);
5.41 top.sp--;
5.42 break;
5.43 }
5.44 @@ -783,7 +758,7 @@
5.45 {
5.46 Heap::Tenure tenure = (Heap::Tenure)top.pc[1];
5.47 Local<ArrayMap> map(zone, ArrayMap::cast(top.fp->code()->map(READ_UINT32(top.pc + 1))));
5.48 - Array *array = GenerateArray(zone, map, tenure);
5.49 + Array *array = Array::New(zone, map, map->type()->elements(), tenure);
5.50 if (!array)
5.51 goto error;
5.52 top.sp->obj = array;
6.1 --- a/src/ObjectVisitor.h Sat Aug 04 23:58:23 2012 -0700
6.2 +++ b/src/ObjectVisitor.h Sun Aug 05 00:31:20 2012 -0700
6.3 @@ -115,7 +115,7 @@
6.4
6.5 size_t iterateArray(Array *array, ArrayMap *map) {
6.6 assert(map->type()->isArray());
6.7 - if (map->contained()) {
6.8 + if (map->type()->contained()->isTraceable()) {
6.9 unsigned length = array->nelements();
6.10 Object **vec = array->objVec();
6.11 for (unsigned i = 0; i < length; i++)
6.12 @@ -126,7 +126,6 @@
6.13
6.14 size_t iterateArrayMap(ArrayMap *map) {
6.15 visitField(map, ArrayMap::offsetOfType());
6.16 - visitField(map, ArrayMap::offsetOfContained());
6.17 return sizeof(ArrayMap);
6.18 }
6.19
7.1 --- a/src/Opcodes.cpp Sat Aug 04 23:58:23 2012 -0700
7.2 +++ b/src/Opcodes.cpp Sun Aug 05 00:31:20 2012 -0700
7.3 @@ -249,11 +249,7 @@
7.4 case OP_NEWARRAY:
7.5 {
7.6 Heap::Tenure tenure = (Heap::Tenure)pc[1];
7.7 - ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc + 1)));
7.8 - for (; map; map = map->contained()) {
7.9 - Type *type = map->type();
7.10 - fprintf(fp, "[%d]", type->elements());
7.11 - }
7.12 + //ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc + 1)));
7.13 if (tenure == Heap::Tenure_Stack)
7.14 fprintf(fp, " ; lifo");
7.15 else if (tenure == Heap::Tenure_Old)
8.1 --- a/src/SemanticAnalysis.cpp Sat Aug 04 23:58:23 2012 -0700
8.2 +++ b/src/SemanticAnalysis.cpp Sun Aug 05 00:31:20 2012 -0700
8.3 @@ -379,10 +379,10 @@
8.4 if (!type)
8.5 return NULL;
8.6
8.7 - if (type->isConst()) {
8.8 - cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
8.9 - return NULL;
8.10 - }
8.11 + // if (type->isConst()) {
8.12 + // cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
8.13 + // return NULL;
8.14 + // }
8.15
8.16 return type;
8.17 }
9.1 --- a/src/Types.h Sat Aug 04 23:58:23 2012 -0700
9.2 +++ b/src/Types.h Sun Aug 05 00:31:20 2012 -0700
9.3 @@ -200,9 +200,13 @@
9.4
9.5 // Objects of this type can be created with this cached map.
9.6 Map *newMap() {
9.7 - assert(isStruct());
9.8 + assert(isStruct() || isArray());
9.9 return newMap_;
9.10 }
9.11 + void setNewMap(Map *map) {
9.12 + assert(!newMap());
9.13 + newMap_ = map;
9.14 + }
9.15
9.16 // GC Descriptor.
9.17 static inline size_t offsetOfContained() {
10.1 --- a/src/Zone.cpp Sat Aug 04 23:58:23 2012 -0700
10.2 +++ b/src/Zone.cpp Sun Aug 05 00:31:20 2012 -0700
10.3 @@ -116,8 +116,7 @@
10.4 if (!type)
10.5 return false;
10.6
10.7 - Local<ArrayMap> contained(this);
10.8 - genericArrayMap_ = ArrayMap::New(this, type, contained);
10.9 + genericArrayMap_ = ArrayMap::New(this, type);
10.10 if (!genericArrayMap_)
10.11 return false;
10.12
10.13 @@ -129,7 +128,7 @@
10.14 if (!type)
10.15 return false;
10.16
10.17 - charArrayMap_ = ArrayMap::New(this, type, contained);
10.18 + charArrayMap_ = ArrayMap::New(this, type);
10.19 if (!charArrayMap_)
10.20 return false;
10.21 }