Refactory array maps to allow arrays of structs.
authorDavid Anderson <dvander@alliedmods.net>
Sun Aug 05 00:31:20 2012 -0700 (2012-08-05)
changeset 154a85a0303bcb8
parent 153 fc91c4a3dfe2
child 155 7926a7921fa3
Refactory array maps to allow arrays of structs.
src/Array.cpp
src/Array.h
src/BytecodeCompiler.cpp
src/BytecodeEmitter.h
src/Interpreter.cpp
src/ObjectVisitor.h
src/Opcodes.cpp
src/SemanticAnalysis.cpp
src/Types.h
src/Zone.cpp
     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      }