1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
#pragma once
#include "GcType.h"
#include "Utils/InlineAtomics.h"
namespace storm {
/**
* Helper struct to access gc:d arrays. The preprocessor recognices this class, so it is
* properly marked for the gc.
*/
template <class T>
struct GcArray {
// Number of elements. Set on allocation and then not allowed to change.
const size_t count;
// Number of used elements. Ignored by the GC and its usage is up to the user of the array.
size_t filled;
// Data.
T v[1];
};
/**
* Variant used to pre-allocate a GcArray of a certain size somewhere.
*/
template <class T, size_t size>
struct GcPreArray {
const size_t count;
size_t filled;
T v[size];
GcPreArray() : count(size), filled(0) {}
// Specify a size that is possibly smaller thant the desired size.
explicit GcPreArray(size_t count) : count(min(size, count)), filled(0) {}
operator GcArray<T> *() const { return (GcArray<T> *)this; }
};
/**
* A GcArray of weak pointers.
*/
template <class T>
struct GcWeakArray {
// Number of elements. Tagged so the GC does not think it is a pointer.
const size_t countI;
// Number of splatted elements since reset. Tagged.
size_t splattedI;
// Data. Note: it is a good idea to *read* this using atomics/readOnce. Otherwise the
// compiler may choose to read the memory more than once, resulting in a possible splat
// between checking for null and reading the value a second time.
T *v[1];
// Number of elements.
inline size_t count() const { return countI >> 1; }
// Splatted elements.
inline size_t splatted() const { return readOnce(splattedI) >> 1; }
inline void splatted(size_t v) { writeOnce(splattedI, (v << 1) | 0x1); }
// Read elements safely.
inline T *read(size_t id) const { return readOnce(v[id]); }
// Write elements.
inline void write(size_t id, T *value) { return writeOnce(v[id], value); }
};
// Some common GcTypes for arrays, so we don't need to have multiple definitions of them hanging around.
extern const GcType pointerArrayType;
extern const GcType sizeArrayType; // size_t
extern const GcType wordArrayType;
extern const GcType natArrayType;
extern const GcType wcharArrayType;
extern const GcType byteArrayType;
}
|