dvander@12: /* dvander@12: * Copyright (C) 2012 David Anderson dvander@12: * dvander@12: * This file is part of JITCraft. dvander@12: * dvander@12: * JITCraft is free software: you can redistribute it and/or modify it under dvander@12: * the terms of the GNU General Public License as published by the Free dvander@12: * Software Foundation, either version 3 of the License, or (at your option) dvander@12: * any later version. dvander@12: * dvander@12: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY dvander@12: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@12: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@12: * dvander@12: * You should have received a copy of the GNU General Public License along with dvander@12: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@12: */ dvander@12: #ifndef _include_jitcraft_array_h_ dvander@12: #define _include_jitcraft_array_h_ dvander@12: dvander@12: #include "Heap.h" dvander@27: #include "Handles.h" dvander@12: #include "Types.h" dvander@12: dvander@59: namespace ke { dvander@12: dvander@12: class ArrayMap; dvander@12: dvander@12: class Array : public Object dvander@12: { dvander@12: friend class ArrayMap; dvander@12: dvander@13: uint32 nelements_; dvander@13: void *elements_; dvander@12: dvander@12: public: dvander@27: static Array *New(Zone *zone, Handle map, uint32 elements, dvander@12: Heap::Tenure = Heap::Tenure_Default); dvander@169: static Array *NewString(Zone *zone, Handle map, Address buffer, size_t length, Heap::Tenure = Heap::Tenure_Default); dvander@65: static Array *NewExternal(Zone *zone, Handle map, uint32 nelements, dvander@65: void *elements, Heap::Tenure = Heap::Tenure_Default); dvander@12: dvander@155: uint32 length() { dvander@13: return nelements_; dvander@12: } dvander@21: void *vec() { dvander@21: return elements_; dvander@21: } dvander@21: dvander@12: inline int *int32Vec(); dvander@12: inline float *floatVec(); dvander@12: inline Object **objVec(); dvander@21: inline char *chars(); dvander@21: dvander@21: inline Type *type(); dvander@21: inline size_t elementSize(); dvander@12: dvander@12: int readInt32(size_t index) { dvander@155: assert(index < length()); dvander@12: return int32Vec()[index]; dvander@12: } dvander@12: void writeInt32(size_t index, int i) { dvander@155: assert(index < length()); dvander@12: int32Vec()[index] = i; dvander@12: } dvander@21: char readChar(size_t index) { dvander@155: assert(index < length()); dvander@21: return chars()[index]; dvander@21: } dvander@21: void writeChar(size_t index, char c) { dvander@155: assert(index < length()); dvander@21: chars()[index] = c; dvander@21: } dvander@12: float readFloat(size_t index) { dvander@155: assert(index < length()); dvander@12: return floatVec()[index]; dvander@12: } dvander@12: void writeFloat(size_t index, float f) { dvander@155: assert(index < length()); dvander@12: floatVec()[index] = f; dvander@12: } dvander@17: inline void *slotPtr(size_t index); dvander@12: Object *readObject(size_t index) { dvander@155: assert(index < length()); dvander@12: return objVec()[index]; dvander@12: } dvander@12: void writeObject(Zone *zone, size_t index, Object *ptr) { dvander@155: assert(index < length()); dvander@12: write(zone, &objVec()[index], ptr); dvander@12: } dvander@12: dvander@65: bool isExternal() { dvander@65: // Inline arrays always have their elements pointing at the next slot. dvander@65: Address buffer = reinterpret_cast
(elements_); dvander@65: return buffer != reinterpret_cast
(this + 1); dvander@65: } dvander@65: dvander@44: static inline size_t SizeOf(Array *array) { dvander@65: if (array->isExternal()) dvander@65: return sizeof(Array); dvander@155: return sizeof(Array) + array->length() * array->elementSize(); dvander@44: } dvander@44: dvander@12: static Array *cast(Object *obj) { dvander@31: assert(!obj || obj->is(MapKind_Array)); dvander@12: return reinterpret_cast(obj); dvander@12: } dvander@12: }; dvander@12: dvander@12: class ArrayMap : public Map dvander@12: { dvander@13: Barriered type_; dvander@12: dvander@12: public: dvander@154: static ArrayMap *New(Zone *zone, Handle type); dvander@169: static ArrayMap *Attach(Zone *zone, Handle type); dvander@12: dvander@12: Type *type() { dvander@13: return type_; dvander@12: } dvander@44: dvander@44: // GC Descriptor. dvander@44: static inline size_t offsetOfType() { danderson@91: return OFFSETOF(ArrayMap, type_); dvander@44: } dvander@44: // End GC Descriptor. dvander@12: dvander@12: static ArrayMap *cast(Object *obj) { dvander@12: assert(!obj || obj->is(MapKind_MetaArray)); dvander@12: return reinterpret_cast(obj); dvander@12: } dvander@12: }; dvander@12: dvander@12: inline int * dvander@12: Array::int32Vec() dvander@12: { dvander@21: assert(type()->levels() == 1); dvander@21: assert(type()->contained()->isInt32()); dvander@12: return reinterpret_cast(vec()); dvander@12: } dvander@12: dvander@12: inline float * dvander@12: Array::floatVec() dvander@12: { dvander@21: assert(type()->levels() == 1); dvander@21: assert(type()->contained()->isFloat()); dvander@12: return reinterpret_cast(vec()); dvander@12: } dvander@12: dvander@12: inline Object ** dvander@12: Array::objVec() dvander@12: { dvander@154: assert(type()->contained()->isTraceable()); dvander@12: return reinterpret_cast(vec()); dvander@12: } dvander@12: dvander@17: inline void * dvander@17: Array::slotPtr(size_t index) dvander@17: { dvander@21: assert(type()->contained()->primitive() == PrimitiveType_Int32 || dvander@21: type()->contained()->primitive() == PrimitiveType_Float); dvander@155: assert(index < length()); dvander@17: return reinterpret_cast(vec()) + index; dvander@17: } dvander@17: dvander@21: inline char * dvander@21: Array::chars() dvander@21: { dvander@21: assert(type()->levels() == 1); dvander@21: assert(type()->contained()->primitive() == PrimitiveType_Char); dvander@21: return reinterpret_cast(vec()); dvander@21: } dvander@21: dvander@21: inline Type * dvander@21: Array::type() dvander@21: { dvander@21: return ArrayMap::cast(map())->type(); dvander@21: } dvander@21: dvander@21: inline size_t dvander@21: Array::elementSize() dvander@21: { dvander@72: assert(type()->isArray()); dvander@72: if (type()->contained()->isArray()) dvander@21: return sizeof(Object *); dvander@21: switch (type()->contained()->primitive()) { dvander@21: case PrimitiveType_Float: dvander@21: return sizeof(float); dvander@21: case PrimitiveType_Int32: dvander@21: return sizeof(int); dvander@21: default: dvander@21: assert(type()->contained()->primitive() == PrimitiveType_Char); dvander@21: return sizeof(char); dvander@21: } dvander@21: } dvander@21: dvander@12: } dvander@12: dvander@12: #endif // _include_jitcraft_array_h_