1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/Array.h Tue Jul 24 23:53:34 2012 -0700
1.3 @@ -0,0 +1,204 @@
1.4 +/*
1.5 + * Copyright (C) 2012 David Anderson
1.6 + *
1.7 + * This file is part of JITCraft.
1.8 + *
1.9 + * JITCraft is free software: you can redistribute it and/or modify it under
1.10 + * the terms of the GNU General Public License as published by the Free
1.11 + * Software Foundation, either version 3 of the License, or (at your option)
1.12 + * any later version.
1.13 + *
1.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License along with
1.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.20 + */
1.21 +#ifndef _include_jitcraft_array_h_
1.22 +#define _include_jitcraft_array_h_
1.23 +
1.24 +#include "Heap.h"
1.25 +#include "Handles.h"
1.26 +#include "Types.h"
1.27 +
1.28 +namespace ke {
1.29 +
1.30 +class ArrayMap;
1.31 +
1.32 +class Array : public Object
1.33 +{
1.34 + friend class ArrayMap;
1.35 +
1.36 + uint32 nelements_;
1.37 + void *elements_;
1.38 +
1.39 + public:
1.40 + static Array *New(Zone *zone, Handle<ArrayMap> map, uint32 elements,
1.41 + Heap::Tenure = Heap::Tenure_Default);
1.42 + static Array *NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements,
1.43 + void *elements, Heap::Tenure = Heap::Tenure_Default);
1.44 +
1.45 + uint32 nelements() {
1.46 + return nelements_;
1.47 + }
1.48 + void *vec() {
1.49 + return elements_;
1.50 + }
1.51 +
1.52 + inline int *int32Vec();
1.53 + inline float *floatVec();
1.54 + inline Object **objVec();
1.55 + inline char *chars();
1.56 +
1.57 + inline Type *type();
1.58 + inline size_t elementSize();
1.59 +
1.60 + int readInt32(size_t index) {
1.61 + assert(index < nelements());
1.62 + return int32Vec()[index];
1.63 + }
1.64 + void writeInt32(size_t index, int i) {
1.65 + assert(index < nelements());
1.66 + int32Vec()[index] = i;
1.67 + }
1.68 + char readChar(size_t index) {
1.69 + assert(index < nelements());
1.70 + return chars()[index];
1.71 + }
1.72 + void writeChar(size_t index, char c) {
1.73 + assert(index < nelements());
1.74 + chars()[index] = c;
1.75 + }
1.76 + float readFloat(size_t index) {
1.77 + assert(index < nelements());
1.78 + return floatVec()[index];
1.79 + }
1.80 + void writeFloat(size_t index, float f) {
1.81 + assert(index < nelements());
1.82 + floatVec()[index] = f;
1.83 + }
1.84 + inline void *slotPtr(size_t index);
1.85 + Object *readObject(size_t index) {
1.86 + assert(index < nelements());
1.87 + return objVec()[index];
1.88 + }
1.89 + void writeObject(Zone *zone, size_t index, Object *ptr) {
1.90 + assert(index < nelements());
1.91 + write(zone, &objVec()[index], ptr);
1.92 + }
1.93 +
1.94 + bool isExternal() {
1.95 + // Inline arrays always have their elements pointing at the next slot.
1.96 + Address buffer = reinterpret_cast<Address>(elements_);
1.97 + return buffer != reinterpret_cast<Address>(this + 1);
1.98 + }
1.99 +
1.100 + static inline size_t SizeOf(Array *array) {
1.101 + if (array->isExternal())
1.102 + return sizeof(Array);
1.103 + return sizeof(Array) + array->nelements() * array->elementSize();
1.104 + }
1.105 +
1.106 + static Array *cast(Object *obj) {
1.107 + assert(!obj || obj->is(MapKind_Array));
1.108 + return reinterpret_cast<Array *>(obj);
1.109 + }
1.110 +};
1.111 +
1.112 +class ArrayMap : public Map
1.113 +{
1.114 + Barriered<Type> type_;
1.115 + Barriered<ArrayMap> contained_;
1.116 +
1.117 + public:
1.118 + static ArrayMap *New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained);
1.119 +
1.120 + Type *type() {
1.121 + return type_;
1.122 + }
1.123 + ArrayMap *contained() {
1.124 + return contained_;
1.125 + }
1.126 +
1.127 + // GC Descriptor.
1.128 + static inline size_t offsetOfType() {
1.129 + return offsetof(ArrayMap, type_);
1.130 + }
1.131 + static inline size_t offsetOfContained() {
1.132 + return offsetof(ArrayMap, contained_);
1.133 + }
1.134 + // End GC Descriptor.
1.135 +
1.136 + static ArrayMap *cast(Object *obj) {
1.137 + assert(!obj || obj->is(MapKind_MetaArray));
1.138 + return reinterpret_cast<ArrayMap *>(obj);
1.139 + }
1.140 +};
1.141 +
1.142 +inline int *
1.143 +Array::int32Vec()
1.144 +{
1.145 + assert(type()->levels() == 1);
1.146 + assert(type()->contained()->isInt32());
1.147 + return reinterpret_cast<int *>(vec());
1.148 +}
1.149 +
1.150 +inline float *
1.151 +Array::floatVec()
1.152 +{
1.153 + assert(type()->levels() == 1);
1.154 + assert(type()->contained()->isFloat());
1.155 + return reinterpret_cast<float *>(vec());
1.156 +}
1.157 +
1.158 +inline Object **
1.159 +Array::objVec()
1.160 +{
1.161 + assert(type()->levels() > 1);
1.162 + return reinterpret_cast<Object **>(vec());
1.163 +}
1.164 +
1.165 +inline void *
1.166 +Array::slotPtr(size_t index)
1.167 +{
1.168 + assert(type()->contained()->primitive() == PrimitiveType_Int32 ||
1.169 + type()->contained()->primitive() == PrimitiveType_Float);
1.170 + assert(index < nelements());
1.171 + return reinterpret_cast<int *>(vec()) + index;
1.172 +}
1.173 +
1.174 +inline char *
1.175 +Array::chars()
1.176 +{
1.177 + assert(type()->levels() == 1);
1.178 + assert(type()->contained()->primitive() == PrimitiveType_Char);
1.179 + return reinterpret_cast<char *>(vec());
1.180 +}
1.181 +
1.182 +inline Type *
1.183 +Array::type()
1.184 +{
1.185 + return ArrayMap::cast(map())->type();
1.186 +}
1.187 +
1.188 +inline size_t
1.189 +Array::elementSize()
1.190 +{
1.191 + assert(type()->isArray());
1.192 + if (type()->contained()->isArray())
1.193 + return sizeof(Object *);
1.194 + switch (type()->contained()->primitive()) {
1.195 + case PrimitiveType_Float:
1.196 + return sizeof(float);
1.197 + case PrimitiveType_Int32:
1.198 + return sizeof(int);
1.199 + default:
1.200 + assert(type()->contained()->primitive() == PrimitiveType_Char);
1.201 + return sizeof(char);
1.202 + }
1.203 +}
1.204 +
1.205 +}
1.206 +
1.207 +#endif // _include_jitcraft_array_h_