Imported garbage collection allocator and converted Type to a gc object.
Imported garbage collection allocator and converted Type to a gc object.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/jitcraft/Barriers.h Fri Jun 29 19:35:17 2012 -0700
1.3 @@ -0,0 +1,58 @@
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_barriers_h_
1.22 +#define _include_jitcraft_barriers_h_
1.23 +
1.24 +namespace jc {
1.25 +
1.26 +// Used to store unbarriered heap locations.
1.27 +template <typename T>
1.28 +class Unbarriered
1.29 +{
1.30 + Object *obj_;
1.31 +
1.32 + public:
1.33 + Unbarriered()
1.34 + : obj_(NULL)
1.35 + {
1.36 + }
1.37 +
1.38 + T *operator ->() const {
1.39 + return operator *();
1.40 + }
1.41 + T *operator *() const {
1.42 + return static_cast<T *>(obj_);
1.43 + }
1.44 + Unbarriered &operator =(T *obj) {
1.45 + obj_ = obj;
1.46 + return *this;
1.47 + }
1.48 + Object **addr() {
1.49 + return &obj_;
1.50 + }
1.51 + operator bool () const {
1.52 + return !!obj_;
1.53 + }
1.54 + operator T*() const {
1.55 + return static_cast<T *>(obj_);
1.56 + }
1.57 +};
1.58 +
1.59 +}
1.60 +
1.61 +#endif // _include_jitcraft_barriers_h_
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/jitcraft/Handles-inl.h Fri Jun 29 19:35:17 2012 -0700
2.3 @@ -0,0 +1,62 @@
2.4 +/*
2.5 + * Copyright (C) 2012 David Anderson
2.6 + *
2.7 + * This file is part of JITCraft.
2.8 + *
2.9 + * JITCraft is free software: you can redistribute it and/or modify it under
2.10 + * the terms of the GNU General Public License as published by the Free
2.11 + * Software Foundation, either version 3 of the License, or (at your option)
2.12 + * any later version.
2.13 + *
2.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
2.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2.17 + *
2.18 + * You should have received a copy of the GNU General Public License along with
2.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
2.20 + */
2.21 +#ifndef _include_jitcraft_rooting_inl_h_
2.22 +#define _include_jitcraft_rooting_inl_h_
2.23 +
2.24 +#include "Heap.h"
2.25 +
2.26 +namespace jc {
2.27 +
2.28 +template <typename T>
2.29 +Local<T>::Local(Environment *env)
2.30 + : zone_(env->zone()), thing_(NULL)
2.31 +{
2.32 + prev_ = zone_->registerThingLocal(toRaw());
2.33 +}
2.34 +
2.35 +template <typename T>
2.36 +Local<T>::Local(Environment *env, T *thing)
2.37 + : zone_(env->zone()), thing_(thing)
2.38 +{
2.39 + prev_ = zone_->registerThingLocal(toRaw());
2.40 +}
2.41 +
2.42 +template <typename T>
2.43 +Local<T>::Local(Zone *zone)
2.44 + : zone_(zone), thing_(NULL)
2.45 +{
2.46 + prev_ = zone_->registerThingLocal(toRaw());
2.47 +}
2.48 +
2.49 +template <typename T>
2.50 +Local<T>::Local(Zone *zone, T *thing)
2.51 + : zone_(zone), thing_(thing)
2.52 +{
2.53 + prev_ = zone_->registerThingLocal(toRaw());
2.54 +}
2.55 +
2.56 +
2.57 +template <typename T>
2.58 +Local<T>::~Local()
2.59 +{
2.60 + zone_->deregisterThingLocal(toRaw(), prev_);
2.61 +}
2.62 +
2.63 +}
2.64 +
2.65 +#endif // _include_jitcraft_rooting_inl_h_
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/jitcraft/Handles.h Fri Jun 29 19:35:17 2012 -0700
3.3 @@ -0,0 +1,134 @@
3.4 +/*
3.5 + * Copyright (C) 2012 David Anderson
3.6 + *
3.7 + * This file is part of JITCraft.
3.8 + *
3.9 + * JITCraft is free software: you can redistribute it and/or modify it under
3.10 + * the terms of the GNU General Public License as published by the Free
3.11 + * Software Foundation, either version 3 of the License, or (at your option)
3.12 + * any later version.
3.13 + *
3.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
3.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3.17 + *
3.18 + * You should have received a copy of the GNU General Public License along with
3.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
3.20 + */
3.21 +#ifndef _include_jitcraft_rooting_h_
3.22 +#define _include_jitcraft_rooting_h_
3.23 +
3.24 +#include "Heap.h"
3.25 +
3.26 +namespace jc {
3.27 +
3.28 +class Zone;
3.29 +
3.30 +template <typename T> class Local;
3.31 +template <typename T> class ScopedRoot;
3.32 +
3.33 +template <typename T>
3.34 +class Handle
3.35 +{
3.36 + T * const *thingp_;
3.37 +
3.38 + public:
3.39 + template <typename S> Handle(const Handle<S> &handle) {
3.40 + typeCheck<S>();
3.41 + thingp_ = reinterpret_cast<const T **>(handle.thingp_);
3.42 + }
3.43 + template <typename S> inline Handle(const Local<S> &local);
3.44 + template <typename S> inline Handle(const ScopedRoot<S> &root);
3.45 +
3.46 + public:
3.47 + T *operator ->() {
3.48 + return *thingp_;
3.49 + }
3.50 + T *operator *() {
3.51 + return *thingp_;
3.52 + }
3.53 + operator T() { return *thingp_; }
3.54 + operator bool() const {
3.55 + return thingp_ && *thingp_;
3.56 + }
3.57 + T **addr() const {
3.58 + return thingp_;
3.59 + }
3.60 +
3.61 + private:
3.62 + template <typename S>
3.63 + void typeCheck() {
3.64 +#ifdef DEBUG
3.65 + T *v1 = NULL;
3.66 + S *v2 = NULL;
3.67 + v1 = v2;
3.68 + (void)v1;
3.69 +#endif
3.70 + }
3.71 +};
3.72 +
3.73 +template <typename T>
3.74 +class Local
3.75 +{
3.76 + friend class Zone;
3.77 +
3.78 + Zone *zone_;
3.79 + Local<Object> *prev_;
3.80 + T *thing_;
3.81 +
3.82 + Local<Object> *prev() {
3.83 + return prev_;
3.84 + }
3.85 + Local<Object> *toRaw() {
3.86 + return reinterpret_cast<Local<Object>*>(this);
3.87 + }
3.88 +
3.89 + public:
3.90 + inline explicit Local(Zone *zone);
3.91 + inline explicit Local(Zone *zone, T *thing);
3.92 + inline ~Local();
3.93 +
3.94 + const Local &operator =(T *thing) {
3.95 + thing_ = thing;
3.96 + return *this;
3.97 + }
3.98 + T *operator ->() const {
3.99 + return operator *();
3.100 + }
3.101 + T *operator *() const {
3.102 + return thing_;
3.103 + }
3.104 + operator bool () const {
3.105 + return !!thing_;
3.106 + }
3.107 +
3.108 + Object **addr() {
3.109 + return (Object **)&thing_;
3.110 + }
3.111 + Object * const *addr() const {
3.112 + return (Object * const *)&thing_;
3.113 + }
3.114 + operator T *() {
3.115 + return thing_;
3.116 + }
3.117 +
3.118 + private:
3.119 + // Disallow heap allocation.
3.120 + void *operator new(size_t size);
3.121 + void *operator new[](size_t size);
3.122 +
3.123 + // Disallow copy construction.
3.124 + Local(const Local<T> &other);
3.125 + Local &operator =(const Local &other);
3.126 +};
3.127 +
3.128 +template <typename T> template <typename S> inline
3.129 +Handle<T>::Handle(const Local<S> &local)
3.130 +{
3.131 + typeCheck<S>();
3.132 + thingp_ = reinterpret_cast<T * const*>(local.addr());
3.133 +}
3.134 +
3.135 +}
3.136 +
3.137 +#endif // _include_jitcraft_rooting_h_
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/jitcraft/Heap-inl.h Fri Jun 29 19:35:17 2012 -0700
4.3 @@ -0,0 +1,102 @@
4.4 +/*
4.5 + * Copyright (C) 2012 David Anderson
4.6 + *
4.7 + * This file is part of JITCraft.
4.8 + *
4.9 + * JITCraft is free software: you can redistribute it and/or modify it under
4.10 + * the terms of the GNU General Public License as published by the Free
4.11 + * Software Foundation, either version 3 of the License, or (at your option)
4.12 + * any later version.
4.13 + *
4.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
4.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
4.17 + *
4.18 + * You should have received a copy of the GNU General Public License along with
4.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
4.20 + */
4.21 +#ifndef _include_jitcraft_heap_inl_h_
4.22 +#define _include_jitcraft_heap_inl_h_
4.23 +
4.24 +#include "Heap.h"
4.25 +
4.26 +namespace jc {
4.27 +
4.28 +static inline Object *
4.29 +InitAddressIntoObject(Address address, Map *map)
4.30 +{
4.31 + uintptr_t untagged = reinterpret_cast<uintptr_t>(address);
4.32 + assert(IsAligned(untagged, kObjectAlignment));
4.33 +
4.34 + Address tagged = reinterpret_cast<Address>(untagged | kObjectTag);
4.35 + GCObject *obj = reinterpret_cast<GCObject *>(tagged);
4.36 + obj->init(map);
4.37 + return obj;
4.38 +}
4.39 +
4.40 +Address
4.41 +Heap::newObject(size_t bytes, Tenure age)
4.42 +{
4.43 +#if 0
4.44 + if (bytes >= kLargeObjectThreshold)
4.45 + return newLargeObject(bytes);
4.46 +#endif
4.47 +
4.48 +#if 0
4.49 + if (age == Tenure_Default) {
4.50 + if (Address addr = newSpace_.allocate(bytes))
4.51 + return addr;
4.52 +
4.53 + scavenge();
4.54 + if (Address addr = newSpace_.allocate(bytes))
4.55 + return addr;
4.56 + }
4.57 +#endif
4.58 +
4.59 + // Try an old-space allocation.
4.60 + if (Address addr = newOldObject(bytes))
4.61 + return addr;
4.62 +
4.63 + // Uh-oh - perform a collection.
4.64 + assert(false);
4.65 +
4.66 +#if 0
4.67 + return newOldObject(bytes);
4.68 +#endif
4.69 + return NULL;
4.70 +}
4.71 +
4.72 +Object *
4.73 +Heap::allocate(Map *map, size_t bytes, Tenure age)
4.74 +{
4.75 + size_t actualBytes = Align(bytes, kObjectAlignment);
4.76 + Address address = newObject(actualBytes, age);
4.77 + if (!address) {
4.78 + assert(false);
4.79 + return NULL;
4.80 + }
4.81 + return InitAddressIntoObject(address, map);
4.82 +}
4.83 +
4.84 +Object *GCObject::read(Object **ptr)
4.85 +{
4.86 + return *TYPED_FIELD_ADDRESS(Object *, ptr);
4.87 +}
4.88 +
4.89 +void
4.90 +GCObject::write(Zone *zone, Object **ptr, Object *obj)
4.91 +{
4.92 + //env->writeBarrier(this, OBJ_FIELD_OFFSET(this, ptr), obj);
4.93 + *TYPED_FIELD_ADDRESS(Object *, ptr) = obj;
4.94 +}
4.95 +
4.96 +void
4.97 +GCObject::writeNoBarrier(Object **ptr, Object *obj)
4.98 +{
4.99 + *TYPED_FIELD_ADDRESS(Object *, ptr) = obj;
4.100 +}
4.101 +
4.102 +}
4.103 +
4.104 +#endif // _include_jitcraft_heap_inl_h_
4.105 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/jitcraft/Heap.cpp Fri Jun 29 19:35:17 2012 -0700
5.3 @@ -0,0 +1,69 @@
5.4 +/*
5.5 + * Copyright (C) 2012 David Anderson
5.6 + *
5.7 + * This file is part of JITCraft.
5.8 + *
5.9 + * JITCraft is free software: you can redistribute it and/or modify it under
5.10 + * the terms of the GNU General Public License as published by the Free
5.11 + * Software Foundation, either version 3 of the License, or (at your option)
5.12 + * any later version.
5.13 + *
5.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
5.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
5.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5.17 + *
5.18 + * You should have received a copy of the GNU General Public License along with
5.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
5.20 + */
5.21 +#include "Heap.h"
5.22 +#include "Heap-inl.h"
5.23 +#include "Spaces-inl.h"
5.24 +
5.25 +using namespace jc;
5.26 +
5.27 +Heap::Heap(Zone *zone)
5.28 + : zone_(zone)
5.29 +{
5.30 +}
5.31 +
5.32 +bool
5.33 +Heap::initialize()
5.34 +{
5.35 + if (!oldSpace_.initialize())
5.36 + return false;
5.37 + if (!mapSpace_.initialize())
5.38 + return false;
5.39 +
5.40 + if ((metaMap_ = allocateMap(MapKind_Meta, sizeof(Map))) == NULL)
5.41 + return false;
5.42 + metaMap_->init(metaMap_);
5.43 +
5.44 + return true;
5.45 +}
5.46 +
5.47 +Map *
5.48 +Heap::allocateMap(MapKind kind, size_t bytes)
5.49 +{
5.50 + size_t actualBytes = Align(bytes, kObjectAlignment);
5.51 +
5.52 + Address addr = mapSpace_.allocate(actualBytes);
5.53 + if (!addr) {
5.54 + assert(false);
5.55 + return NULL;
5.56 + }
5.57 +
5.58 + // Note that we use a NULL type initially, and reinterpret-cast to get
5.59 + // the Type pointer, so we can allocate the self-referencing meta type.
5.60 + Object *obj = InitAddressIntoObject(addr, NULL);
5.61 + Map *map = reinterpret_cast<Map *>(obj);
5.62 + map->setKind(kind);
5.63 + map->init(metaMap_);
5.64 +
5.65 + return map;
5.66 +}
5.67 +
5.68 +Address
5.69 +Heap::newOldObject(size_t bytes)
5.70 +{
5.71 + return oldSpace_.allocate(bytes);
5.72 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/jitcraft/Heap.h Fri Jun 29 19:35:17 2012 -0700
6.3 @@ -0,0 +1,203 @@
6.4 +/*
6.5 + * Copyright (C) 2012 David Anderson
6.6 + *
6.7 + * This file is part of JITCraft.
6.8 + *
6.9 + * JITCraft is free software: you can redistribute it and/or modify it under
6.10 + * the terms of the GNU General Public License as published by the Free
6.11 + * Software Foundation, either version 3 of the License, or (at your option)
6.12 + * any later version.
6.13 + *
6.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
6.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6.17 + *
6.18 + * You should have received a copy of the GNU General Public License along with
6.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
6.20 + */
6.21 +#ifndef _include_jitcraft_objects_h_
6.22 +#define _include_jitcraft_objects_h_
6.23 +
6.24 +#include "Utility.h"
6.25 +#include "Spaces.h"
6.26 +
6.27 +namespace jc {
6.28 +
6.29 +class Zone;
6.30 +
6.31 +// The heap object hierarchy is as follows:
6.32 +//
6.33 +// Object
6.34 +// Integer
6.35 +// HeapObject
6.36 +// ..
6.37 +//
6.38 +// Objects in Keima have a special encoding to efficiently handle small
6.39 +// integers. The last three bits of pointers participating in the object
6.40 +// hierarchy are as follows:
6.41 +//
6.42 +// ??0 - Remaining bits are a signed integer, representing the
6.43 +// language type "int".
6.44 +// 001 - Object pointer (base address is -1).
6.45 +// 011 - Failure pointer, remaining bits describe failure.
6.46 +
6.47 +static const uintptr_t kObjectTag = 0x1;
6.48 +static const uintptr_t kFailureTag = 0x3;
6.49 +
6.50 +// Macros for laying out objects.
6.51 +#define OBJECT_FIELD(Type, name) \
6.52 + Type fld_##name##_;
6.53 +
6.54 +// Since object fields are offset, special getters and setters must be used.
6.55 +// These getters and setters also trigger necessary read and write barriers.
6.56 +#define RAW_FIELD_ADDRESS(ptr) \
6.57 + (reinterpret_cast<uintptr_t>(ptr) - kObjectTag)
6.58 +#define TYPED_FIELD_ADDRESS(Type, ptr) \
6.59 + (reinterpret_cast<Type *>(RAW_FIELD_ADDRESS(ptr)))
6.60 +#define OBJ_FIELD_OFFSET(obj, ptr) \
6.61 + (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(obj))
6.62 +#define READ_FIELD(name) \
6.63 + read(&fld_##name##_)
6.64 +#define WRITE_FIELD(name, val) \
6.65 + write(&fld_##name##_, val)
6.66 +#define READ_FIELD_OBJ(name) \
6.67 + read(reinterpret_cast<Object **>(&fld_##name##_))
6.68 +#define WRITE_FIELD_OBJ(env, name, val) \
6.69 + write(env, reinterpret_cast<Object **>(&fld_##name##_), val)
6.70 +#define WRITE_FIELD_OBJ_NO_BARRIER(name, val) \
6.71 + writeNoBarrier(reinterpret_cast<Object **>(&fld_##name##_), val)
6.72 +
6.73 +// Garbage-collection objects require a header to describe their layout. This
6.74 +// header is called a "map". The different kinds of maps are enumerated below.
6.75 +class Map;
6.76 +
6.77 +enum MapKind
6.78 +{
6.79 + // This kind is used by the prototypical Map object, since Map objects
6.80 + // themselves require Maps.
6.81 + MapKind_Meta,
6.82 +
6.83 + // Used to represent a Type object.
6.84 + MapKind_Type,
6.85 +
6.86 + MapKinds_Total
6.87 +};
6.88 +
6.89 +class GCObject;
6.90 +
6.91 +class Object
6.92 +{
6.93 + public:
6.94 + bool isGCObject() {
6.95 + return !!(reinterpret_cast<uintptr_t>(this) & kObjectTag);
6.96 + }
6.97 + GCObject *toGCObject() {
6.98 + return reinterpret_cast<GCObject *>(this);
6.99 + }
6.100 + inline bool is(MapKind kind);
6.101 +};
6.102 +
6.103 +typedef void * CrapPtr;
6.104 +
6.105 +// All garbage collected objects must inherit from GCObject. Note that using
6.106 +// virtual functions is illegal, as the |map| field would be displaced.
6.107 +class GCObject : public Object
6.108 +{
6.109 + OBJECT_FIELD(Map *, map);
6.110 +
6.111 + protected:
6.112 + // Basic accessors for reading/writing object fields.
6.113 +#define SIMPLE_ACCESSORS(Type) \
6.114 + Type read(Type *ptr) { \
6.115 + return *TYPED_FIELD_ADDRESS(Type, ptr); \
6.116 + } \
6.117 + void write(Type *ptr, const Type &value) { \
6.118 + *TYPED_FIELD_ADDRESS(Type, ptr) = value; \
6.119 + }
6.120 +
6.121 + SIMPLE_ACCESSORS(bool);
6.122 + SIMPLE_ACCESSORS(uint8);
6.123 +#if 0
6.124 + SIMPLE_ACCESSORS(int8);
6.125 + SIMPLE_ACCESSORS(int16);
6.126 + SIMPLE_ACCESSORS(uint16);
6.127 + SIMPLE_ACCESSORS(int64);
6.128 + SIMPLE_ACCESSORS(uint64);
6.129 +#endif
6.130 + SIMPLE_ACCESSORS(CrapPtr);
6.131 + SIMPLE_ACCESSORS(int32);
6.132 + SIMPLE_ACCESSORS(uint32);
6.133 + SIMPLE_ACCESSORS(float);
6.134 + SIMPLE_ACCESSORS(double);
6.135 +
6.136 +#undef SIMPLE_ACCESSORS
6.137 +
6.138 + inline Object *read(Object **ptr);
6.139 + inline void write(Zone *zone, Object **ptr, Object *obj);
6.140 + inline void writeNoBarrier(Object **ptr, Object *obj);
6.141 +
6.142 + public:
6.143 + void init(Map *map) {
6.144 + WRITE_FIELD_OBJ_NO_BARRIER(map, (Object *)map);
6.145 + }
6.146 +
6.147 + Map *map() {
6.148 + return (Map *)READ_FIELD_OBJ(map);
6.149 + }
6.150 +};
6.151 +
6.152 +class Map : public GCObject
6.153 +{
6.154 + OBJECT_FIELD(uint32, mapKind);
6.155 +
6.156 + public:
6.157 + void setKind(MapKind kind) {
6.158 + WRITE_FIELD(mapKind, kind);
6.159 + }
6.160 + MapKind kind() {
6.161 + return static_cast<MapKind>(READ_FIELD(mapKind));
6.162 + }
6.163 +};
6.164 +
6.165 +// Heap-allocated objects go here. Heaps are thread-local.
6.166 +class Heap
6.167 +{
6.168 + Zone *zone_;
6.169 + OldSpace mapSpace_;
6.170 + OldSpace oldSpace_;
6.171 +
6.172 + Map *metaMap_;
6.173 +
6.174 + public:
6.175 + enum Tenure {
6.176 + Tenure_Default,
6.177 + Tenure_Old
6.178 + };
6.179 +
6.180 + private:
6.181 + inline Address newObject(size_t bytes, Tenure pretenure);
6.182 + Address newOldObject(size_t bytes);
6.183 +
6.184 + public:
6.185 + Heap(Zone *zone);
6.186 + bool initialize();
6.187 +
6.188 + inline Object *allocate(Map *map, size_t byes, Tenure pretenure);
6.189 + Map *allocateMap(MapKind kind, size_t bytes);
6.190 +
6.191 + Map *metaMap() {
6.192 + return metaMap_;
6.193 + }
6.194 +};
6.195 +
6.196 +inline bool
6.197 +Object::is(MapKind kind)
6.198 +{
6.199 + if (!isGCObject())
6.200 + return false;
6.201 + return toGCObject()->map()->kind() == kind;
6.202 +}
6.203 +
6.204 +}
6.205 +
6.206 +#endif //_include_jitcraft_objects_h_
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/jitcraft/Platform-Windows.cpp Fri Jun 29 19:35:17 2012 -0700
7.3 @@ -0,0 +1,115 @@
7.4 +/*
7.5 + * Copyright (C) 2012 David Anderson
7.6 + *
7.7 + * This file is part of JITCraft.
7.8 + *
7.9 + * JITCraft is free software: you can redistribute it and/or modify it under
7.10 + * the terms of the GNU General Public License as published by the Free
7.11 + * Software Foundation, either version 3 of the License, or (at your option)
7.12 + * any later version.
7.13 + *
7.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
7.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
7.17 + *
7.18 + * You should have received a copy of the GNU General Public License along with
7.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
7.20 + */
7.21 +
7.22 +// :TODO: move into utility-style include
7.23 +#define WIN32_LEAN_AND_MEAN
7.24 +#include <Windows.h>
7.25 +#include "Platform.h"
7.26 +
7.27 +using namespace jc;
7.28 +
7.29 +static inline DWORD
7.30 +ToProtBits(OS::Protection prot)
7.31 +{
7.32 + switch (prot) {
7.33 + case OS::Prot_ReadWrite:
7.34 + return PAGE_READWRITE;
7.35 + case OS::Prot_ReadWriteExecute:
7.36 + return PAGE_EXECUTE_READWRITE;
7.37 + default:
7.38 + assert(prot == OS::Prot_ReadExecute);
7.39 + return PAGE_EXECUTE_READ;
7.40 + }
7.41 +}
7.42 +
7.43 +Address
7.44 +OS::MapMemory(size_t amount, MapMode mode, Protection prot_)
7.45 +{
7.46 + DWORD prot = ToProtBits(prot_);
7.47 + DWORD type = MEM_RESERVE;
7.48 + if (mode == Map_Commit)
7.49 + type |= MEM_COMMIT;
7.50 +
7.51 + return (Address)VirtualAlloc(NULL, amount, type, prot);
7.52 +}
7.53 +
7.54 +bool
7.55 +OS::CommitMemory(Address address, size_t amount, Protection prot_)
7.56 +{
7.57 + DWORD prot = ToProtBits(prot_);
7.58 + return !!VirtualAlloc(address, amount, MEM_COMMIT, prot);
7.59 +}
7.60 +
7.61 +void
7.62 +OS::UnmapMemory(Address address, size_t size)
7.63 +{
7.64 + VirtualFree(address, 0, MEM_RELEASE);
7.65 +}
7.66 +
7.67 +OS::AlignableMapping
7.68 +OS::MapAlignedMemory(size_t amount, size_t alignment, MapMode mode)
7.69 +{
7.70 + Address addr = MapMemory(amount, mode, OS::Prot_ReadWrite);
7.71 + if (!addr)
7.72 + return AlignableMapping(NULL, alignment, 0);
7.73 +
7.74 + if (!IsAligned(addr, alignment)) {
7.75 + UnmapMemory(addr, amount);
7.76 +
7.77 + // Try to grab the next available aligned address.
7.78 + addr = AlignedBase(addr, alignment);
7.79 + addr = MapMemoryAt(addr + alignment, amount, mode, OS::Prot_ReadWrite);
7.80 + while (!addr) {
7.81 + // Try to over-allocate to get the right region. This can race
7.82 + // with other threads; we expect this to be rare. If this turns
7.83 + // out to be a problem, the API is set up such that we can just
7.84 + // return two pointers: the base, and the aligned address into
7.85 + // the over-allocated region.
7.86 + addr = MapMemory(amount + alignment, mode, OS::Prot_ReadWrite);
7.87 + if (!addr)
7.88 + return AlignableMapping(NULL, alignment, 0);
7.89 + UnmapMemory(addr, amount + alignment);
7.90 + addr = AlignedBase(addr, alignment);
7.91 + addr = MapMemoryAt(addr + alignment, amount, mode, OS::Prot_ReadWrite);
7.92 + }
7.93 + }
7.94 +
7.95 + return AlignableMapping(addr, alignment, amount);
7.96 +}
7.97 +
7.98 +Address
7.99 +OS::MapMemoryAt(Address address, size_t amount, MapMode mode, Protection prot_)
7.100 +{
7.101 + DWORD bits = ToProtBits(prot_);
7.102 + DWORD flags = MEM_RESERVE;
7.103 + if (mode == Map_Commit)
7.104 + flags |= MEM_COMMIT;
7.105 +
7.106 + Address x = (Address)VirtualAlloc((LPVOID)address, amount, flags, bits);
7.107 + if (!x) {
7.108 + DWORD err = GetLastError();
7.109 + return x;
7.110 + }
7.111 + return x;
7.112 +}
7.113 +
7.114 +void
7.115 +OS::UnmapAlignedMemory(Address address, size_t size)
7.116 +{
7.117 + OS::UnmapMemory(address, size);
7.118 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/jitcraft/Platform.h Fri Jun 29 19:35:17 2012 -0700
8.3 @@ -0,0 +1,92 @@
8.4 +/*
8.5 + * Copyright (C) 2012 David Anderson
8.6 + *
8.7 + * This file is part of JITCraft.
8.8 + *
8.9 + * JITCraft is free software: you can redistribute it and/or modify it under
8.10 + * the terms of the GNU General Public License as published by the Free
8.11 + * Software Foundation, either version 3 of the License, or (at your option)
8.12 + * any later version.
8.13 + *
8.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
8.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8.17 + *
8.18 + * You should have received a copy of the GNU General Public License along with
8.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
8.20 + */
8.21 +#ifndef _include_jitcraft_platform_h_
8.22 +#define _include_jitcraft_platform_h_
8.23 +
8.24 +#include "Utility.h"
8.25 +
8.26 +namespace jc {
8.27 +
8.28 +namespace OS {
8.29 + enum Protection {
8.30 + Prot_ReadWrite, // rw-, for the heap
8.31 + Prot_ReadExecute, // r-x, for code
8.32 + Prot_ReadWriteExecute // rwx, if disabling r-x for code.
8.33 + };
8.34 +
8.35 + enum MapMode {
8.36 + Map_Reserve, // don't ask for actual pages yet
8.37 + Map_Commit // ask for pages right away
8.38 + };
8.39 +
8.40 + Address MapMemory(size_t amount, MapMode mode, Protection prot);
8.41 + bool CommitMemory(Address address, size_t amount, Protection prot);
8.42 + void UnmapMemory(Address address, size_t size);
8.43 +
8.44 + class AlignableMapping {
8.45 + Address base_;
8.46 + Address aligned_;
8.47 + size_t size_;
8.48 +
8.49 + public:
8.50 + AlignableMapping(Address ptr, size_t alignment, size_t size)
8.51 + : base_(ptr),
8.52 + size_(size)
8.53 + {
8.54 + aligned_ = base_;
8.55 + if (!IsAligned(aligned_, alignment))
8.56 + aligned_ = AlignedBase(aligned_, alignment) + alignment;
8.57 + }
8.58 +
8.59 + AlignableMapping() : base_(NULL), aligned_(NULL), size_(0)
8.60 + {
8.61 + }
8.62 +
8.63 + Address base() const {
8.64 + return base_;
8.65 + }
8.66 + bool isValid() const {
8.67 + return !!base_;
8.68 + }
8.69 + size_t size() const {
8.70 + return size_;
8.71 + }
8.72 + Address aligned() const {
8.73 + return aligned_;
8.74 + }
8.75 + };
8.76 +
8.77 + AlignableMapping MapAlignedMemory(size_t amount, size_t alignment, MapMode mode);
8.78 + void UnmapAlignedMemory(Address address, size_t size);
8.79 +
8.80 + // The default alignment of memory returned via MapMemory().
8.81 + // :TODO: better ifdefs
8.82 +#ifdef _MSC_VER
8.83 + static const size_t kMapAlignment = 64 * kKB;
8.84 +#else
8.85 + static const size_t kMapAlignment = 4 * kKB;
8.86 +#endif
8.87 +
8.88 + // Internal OS:: use only.
8.89 + Address MapMemoryAt(Address address, size_t amount, MapMode mode, Protection prot);
8.90 + AlignableMapping Shared_MapAlignableMemory(size_t amount, size_t alignment, MapMode mode);
8.91 +}
8.92 +
8.93 +}
8.94 +
8.95 +#endif // _include_jitcraft_platform_h_
9.1 --- a/jitcraft/SemanticAnalysis.cpp Thu Jun 28 01:38:56 2012 -0700
9.2 +++ b/jitcraft/SemanticAnalysis.cpp Fri Jun 29 19:35:17 2012 -0700
9.3 @@ -17,6 +17,8 @@
9.4 */
9.5 #include "SemanticAnalysis.h"
9.6 #include "Types.h"
9.7 +#include "Zone.h"
9.8 +#include "TypeManager.h"
9.9
9.10 using namespace jc;
9.11
9.12 @@ -235,7 +237,7 @@
9.13 void
9.14 SemanticAnalysis::visit(VariableDeclaration *node)
9.15 {
9.16 - Type *type = Type::NewPrimitive(node->tag());
9.17 + Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
9.18 if (!type)
9.19 return;
9.20
9.21 @@ -267,7 +269,7 @@
9.22 }
9.23 }
9.24
9.25 - type = Type::NewUnsafeArray(type, size);
9.26 + type = ZONE()->types()->unsafeArray(type, size);
9.27 }
9.28 } else {
9.29 if (node->initialization()) {
9.30 @@ -282,8 +284,7 @@
9.31 void
9.32 SemanticAnalysis::visit(IntegerLiteral *node)
9.33 {
9.34 - Type *type = Type::NewPrimitive(NULL);
9.35 - node->setType(type);
9.36 + node->setType(ZONE()->types()->getPrimitive(PrimitiveType_Int32));
9.37 }
9.38
9.39 void
9.40 @@ -335,7 +336,7 @@
9.41 // :TODO: test "enum Float { ..."
9.42 Name *tag = node->name();
9.43
9.44 - Type *type = Type::NewPrimitive(tag);
9.45 + Type *type = ZONE()->types()->getPrimitiveForTag(tag);
9.46 if (!type)
9.47 return;
9.48
9.49 @@ -361,7 +362,7 @@
9.50 void
9.51 SemanticAnalysis::visit(FloatLiteral *node)
9.52 {
9.53 - Type *type = Type::NewPrimitive(PrimitiveType_Float);
9.54 + Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);
9.55 if (!type)
9.56 return;
9.57
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/jitcraft/Spaces-inl.h Fri Jun 29 19:35:17 2012 -0700
10.3 @@ -0,0 +1,47 @@
10.4 +/*
10.5 + * Copyright (C) 2012 David Anderson
10.6 + *
10.7 + * This file is part of JITCraft.
10.8 + *
10.9 + * JITCraft is free software: you can redistribute it and/or modify it under
10.10 + * the terms of the GNU General Public License as published by the Free
10.11 + * Software Foundation, either version 3 of the License, or (at your option)
10.12 + * any later version.
10.13 + *
10.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
10.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10.17 + *
10.18 + * You should have received a copy of the GNU General Public License along with
10.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
10.20 + */
10.21 +#ifndef _include_jitcraft_spaces_inl_h_
10.22 +#define _include_jitcraft_spaces_inl_h_
10.23 +
10.24 +namespace jc {
10.25 +
10.26 +Address
10.27 +HeapChunk::allocate(size_t nbytes)
10.28 +{
10.29 + if (cursor_ + nbytes > end_)
10.30 + return NULL;
10.31 +
10.32 + Address address = cursor_;
10.33 + cursor_ += nbytes;
10.34 + return address;
10.35 +}
10.36 +
10.37 +Address
10.38 +OldSpace::allocate(size_t nbytes)
10.39 +{
10.40 + assert(IsAligned(nbytes, kObjectAlignment));
10.41 +
10.42 + if (Address addr = last_->allocate(nbytes))
10.43 + return addr;
10.44 +
10.45 + return allocateSlow(nbytes);
10.46 +}
10.47 +
10.48 +}
10.49 +
10.50 +#endif // _include_jitcraft_spaces_inl_h_
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/jitcraft/Spaces.cpp Fri Jun 29 19:35:17 2012 -0700
11.3 @@ -0,0 +1,82 @@
11.4 +/*
11.5 + * Copyright (C) 2012 David Anderson
11.6 + *
11.7 + * This file is part of JITCraft.
11.8 + *
11.9 + * JITCraft is free software: you can redistribute it and/or modify it under
11.10 + * the terms of the GNU General Public License as published by the Free
11.11 + * Software Foundation, either version 3 of the License, or (at your option)
11.12 + * any later version.
11.13 + *
11.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
11.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11.17 + *
11.18 + * You should have received a copy of the GNU General Public License along with
11.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
11.20 + */
11.21 +#include "Spaces.h"
11.22 +#include "Platform.h"
11.23 +#include "Spaces-inl.h"
11.24 +
11.25 +using namespace jc;
11.26 +
11.27 +HeapChunk *
11.28 +HeapChunk::New(HeapChunk *prev, size_t size)
11.29 +{
11.30 + OS::AlignableMapping map =
11.31 + OS::MapAlignedMemory(size, HeapChunk::kAlignment, OS::Map_Commit);
11.32 +
11.33 + if (!map.base())
11.34 + return NULL;
11.35 +
11.36 + HeapChunk *chunk = reinterpret_cast<HeapChunk *>(map.aligned());
11.37 + chunk->base_ = map.base();
11.38 + chunk->end_ = map.base() + map.size();
11.39 + chunk->cursor_ = chunk->first();
11.40 + if (prev)
11.41 + prev->next_ = chunk;
11.42 +
11.43 + return chunk;
11.44 +}
11.45 +
11.46 +void
11.47 +HeapChunk::Destroy(HeapChunk *chunk)
11.48 +{
11.49 + OS::UnmapAlignedMemory(chunk->base(), chunk->size());
11.50 +}
11.51 +
11.52 +OldSpace::OldSpace()
11.53 + : first_(NULL),
11.54 + last_(NULL)
11.55 +{
11.56 +}
11.57 +
11.58 +bool
11.59 +OldSpace::initialize()
11.60 +{
11.61 + first_ = HeapChunk::New(first_, HeapChunk::kDefaultSize);
11.62 + last_ = first_;
11.63 +
11.64 + return !!first_;
11.65 +}
11.66 +
11.67 +Address
11.68 +OldSpace::allocateSlow(size_t nbytes)
11.69 +{
11.70 + HeapChunk *chunk = HeapChunk::New(last_, HeapChunk::kDefaultSize);
11.71 + if (!chunk)
11.72 + return NULL;
11.73 +
11.74 + return chunk->allocate(nbytes);
11.75 +}
11.76 +
11.77 +OldSpace::~OldSpace()
11.78 +{
11.79 + while (first_) {
11.80 + HeapChunk *temp = first_->next();
11.81 + HeapChunk::Destroy(first_);
11.82 + first_ = temp;
11.83 + }
11.84 +}
11.85 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/jitcraft/Spaces.h Fri Jun 29 19:35:17 2012 -0700
12.3 @@ -0,0 +1,126 @@
12.4 +/*
12.5 + * Copyright (C) 2012 David Anderson
12.6 + *
12.7 + * This file is part of JITCraft.
12.8 + *
12.9 + * JITCraft is free software: you can redistribute it and/or modify it under
12.10 + * the terms of the GNU General Public License as published by the Free
12.11 + * Software Foundation, either version 3 of the License, or (at your option)
12.12 + * any later version.
12.13 + *
12.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
12.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12.17 + *
12.18 + * You should have received a copy of the GNU General Public License along with
12.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
12.20 + */
12.21 +#ifndef _include_jitcraft_spaces_h_
12.22 +#define _include_jitcraft_spaces_h_
12.23 +
12.24 +#include "Utility.h"
12.25 +
12.26 +namespace jc {
12.27 +
12.28 +static const size_t kObjectAlignment = 8;
12.29 +
12.30 +class HeapChunk
12.31 +{
12.32 + HeapChunk *next_;
12.33 +
12.34 + // Base address, from OS::AlignableMapping.
12.35 + Address base_;
12.36 +
12.37 + // End of the allocated region.
12.38 + Address end_;
12.39 +
12.40 + // Current allocation point.
12.41 + Address cursor_;
12.42 +
12.43 + public:
12.44 + static const size_t kMaxObjectSize = 1 * kGB;
12.45 + static const size_t kDefaultSize = 256 * kKB;
12.46 + static const size_t kAlignment = 256 * kKB;
12.47 +
12.48 + // All objects must be allocated in the first kAlignment bytes of the
12.49 + // chunk. Every object is at least 8 bytes (kPointerAlignment), so we
12.50 + // reserve one mark bit for every possible object address in the chunk
12.51 + // (including, for simplicity, unallocatable addresses at the start).
12.52 + //
12.53 + // The number of mark bits needed is:
12.54 + //
12.55 + // MaxObjectsPerChunk = kAlignment / kPointerAlignment
12.56 + // = 32KB
12.57 + //
12.58 + // The number of bytes needed for these mark bits is:
12.59 + //
12.60 + // NumMarkBytes = MaxObjectsPerChunk / 8
12.61 + // = 4KB
12.62 + //
12.63 + // The number of uint32s needed to store these bytes is:
12.64 + //
12.65 + // NumMarkWords = NumMarkBytes / sizeof(uint32)
12.66 + // = 1024
12.67 + static const size_t kMaxObjectsPerChunk = kAlignment / kObjectAlignment;
12.68 + static const size_t kMarkBits = kMaxObjectsPerChunk;
12.69 + static const size_t kMarkBytes = kMarkBits / 8;
12.70 + static const size_t kMarkWords = kMarkBytes / sizeof(uint32);
12.71 +
12.72 + static inline size_t offsetToMarkBits()
12.73 + {
12.74 + return Align(sizeof(HeapChunk), kObjectAlignment);
12.75 + }
12.76 +
12.77 + static inline size_t offsetToFirst()
12.78 + {
12.79 + assert(IsAligned(kMarkBytes, kObjectAlignment));
12.80 + return offsetToMarkBits() + kMarkBytes;
12.81 + }
12.82 +
12.83 + public:
12.84 + static HeapChunk *New(HeapChunk *prev, size_t size);
12.85 + static void Destroy(HeapChunk *chunk);
12.86 +
12.87 + public:
12.88 + inline Address allocate(size_t nbytes);
12.89 +
12.90 + HeapChunk *next() {
12.91 + return next_;
12.92 + }
12.93 + Address base() {
12.94 + return base_;
12.95 + }
12.96 + Address end() {
12.97 + return end_;
12.98 + }
12.99 + size_t size() {
12.100 + return end() - base();
12.101 + }
12.102 + Address first() {
12.103 + return reinterpret_cast<Address>(this) + offsetToFirst();
12.104 + }
12.105 + uint32 *markBits() {
12.106 + return reinterpret_cast<uint32 *>(reinterpret_cast<Address>(this) +
12.107 + offsetToMarkBits());
12.108 + }
12.109 +};
12.110 +
12.111 +class OldSpace
12.112 +{
12.113 + HeapChunk *first_;
12.114 + HeapChunk *last_;
12.115 +
12.116 + public:
12.117 + OldSpace();
12.118 + ~OldSpace();
12.119 +
12.120 + bool initialize();
12.121 +
12.122 + public:
12.123 + inline Address allocate(size_t nbytes);
12.124 + Address allocateSlow(size_t nbytes);
12.125 +};
12.126 +
12.127 +}
12.128 +
12.129 +#endif // _include_jitcraft_spaces_h_
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/jitcraft/TypeManager.cpp Fri Jun 29 19:35:17 2012 -0700
13.3 @@ -0,0 +1,55 @@
13.4 +/*
13.5 + * Copyright (C) 2012 David Anderson
13.6 + *
13.7 + * This file is part of JITCraft.
13.8 + *
13.9 + * JITCraft is free software: you can redistribute it and/or modify it under
13.10 + * the terms of the GNU General Public License as published by the Free
13.11 + * Software Foundation, either version 3 of the License, or (at your option)
13.12 + * any later version.
13.13 + *
13.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13.17 + *
13.18 + * You should have received a copy of the GNU General Public License along with
13.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
13.20 + */
13.21 +#include "Types.h"
13.22 +#include "TypeManager.h"
13.23 +
13.24 +using namespace jc;
13.25 +
13.26 +
13.27 +TypeManager::TypeManager(Zone *zone)
13.28 + : zone_(zone)
13.29 +{
13.30 +}
13.31 +
13.32 +bool
13.33 +TypeManager::initialize()
13.34 +{
13.35 + if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, NULL)) == NULL)
13.36 + return false;
13.37 + if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, "Float")) == NULL)
13.38 + return false;
13.39 + return true;
13.40 +}
13.41 +
13.42 +Type *
13.43 +TypeManager::getPrimitiveForTag(Name *tag)
13.44 +{
13.45 + if (tag == NULL)
13.46 + return getPrimitive(PrimitiveType_Int32);
13.47 + if (strcmp(tag, "Float") == 0)
13.48 + return getPrimitive(PrimitiveType_Float);
13.49 + assert(!"tag cache");
13.50 + return NULL;
13.51 +}
13.52 +
13.53 +Type *
13.54 +TypeManager::unsafeArray(Type *contained, int elements)
13.55 +{
13.56 + // :TODO: cache this.
13.57 + return Type::NewUnsafeArray(zone_, contained, elements);
13.58 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/jitcraft/TypeManager.h Fri Jun 29 19:35:17 2012 -0700
14.3 @@ -0,0 +1,47 @@
14.4 +/*
14.5 + * Copyright (C) 2012 David Anderson
14.6 + *
14.7 + * This file is part of JITCraft.
14.8 + *
14.9 + * JITCraft is free software: you can redistribute it and/or modify it under
14.10 + * the terms of the GNU General Public License as published by the Free
14.11 + * Software Foundation, either version 3 of the License, or (at your option)
14.12 + * any later version.
14.13 + *
14.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
14.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14.17 + *
14.18 + * You should have received a copy of the GNU General Public License along with
14.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
14.20 + */
14.21 +#ifndef _include_jitcraft_type_manager_h_
14.22 +#define _include_jitcraft_type_manager_h_
14.23 +
14.24 +#include "Barriers.h"
14.25 +#include "Types.h"
14.26 +
14.27 +namespace jc {
14.28 +
14.29 +class TypeManager
14.30 +{
14.31 + Zone *zone_;
14.32 +
14.33 + // Primitive type cache.
14.34 + Unbarriered<Type> primitiveTypes_[PrimitiveTypes_Total];
14.35 +
14.36 + public:
14.37 + TypeManager(Zone *zone);
14.38 +
14.39 + bool initialize();
14.40 +
14.41 + Type *getPrimitiveForTag(Name *tag);
14.42 + Type *getPrimitive(PrimitiveType type) {
14.43 + return primitiveTypes_[type];
14.44 + }
14.45 + Type *unsafeArray(Type *contained, int elements);
14.46 +};
14.47 +
14.48 +}
14.49 +
14.50 +#endif // _include_jitcraft_type_manager_h_
15.1 --- a/jitcraft/Types.cpp Thu Jun 28 01:38:56 2012 -0700
15.2 +++ b/jitcraft/Types.cpp Fri Jun 29 19:35:17 2012 -0700
15.3 @@ -16,43 +16,57 @@
15.4 * JITCraft. If not, see http://www.gnu.org/licenses/.
15.5 */
15.6 #include "Types.h"
15.7 +#include "Zone.h"
15.8 +#include "Heap-inl.h"
15.9
15.10 using namespace jc;
15.11
15.12 -Type *
15.13 -Type::NewPrimitive(Name *tag)
15.14 +void
15.15 +Type::initPrimitive(Name *tag)
15.16 +{
15.17 + WRITE_FIELD(kind, PRIMITIVE);
15.18 + WRITE_FIELD(tag, CrapPtr(tag));
15.19 + WRITE_FIELD_OBJ_NO_BARRIER(contained, NULL);
15.20 +
15.21 + if (tag && strcmp(tag, "Float") == 0)
15.22 + WRITE_FIELD(primitive, PrimitiveType_Float);
15.23 + else
15.24 + WRITE_FIELD(primitive, PrimitiveType_Int32);
15.25 +}
15.26 +
15.27 +void
15.28 +Type::initInlineArray(Type *contained, int elements)
15.29 {
15.30 - Type *type = new Type;
15.31 - type->kind_ = PRIMITIVE;
15.32 - type->tag_ = tag;
15.33 -
15.34 - if (tag && strcmp(tag, "Float") == 0)
15.35 - type->primitive_ = PrimitiveType_Float;
15.36 + WRITE_FIELD(kind, UNSAFE_ARRAY);
15.37 + WRITE_FIELD(tag, NULL);
15.38 + WRITE_FIELD_OBJ_NO_BARRIER(contained, contained);
15.39 + WRITE_FIELD(elements, elements);
15.40 + if (contained->isPrimitive())
15.41 + WRITE_FIELD(levels, 1);
15.42 else
15.43 - type->primitive_ = PrimitiveType_Int32;
15.44 + WRITE_FIELD(levels, contained->levels() + 1);
15.45 +}
15.46 +
15.47 +Type *
15.48 +Type::NewPrimitive(Zone *zone, Name *tag)
15.49 +{
15.50 + Object *obj = zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old);
15.51 + if (!obj)
15.52 + return NULL;
15.53 +
15.54 + Type *type = Type::cast(obj);
15.55 + type->initPrimitive(tag);
15.56 return type;
15.57 }
15.58
15.59 Type *
15.60 -Type::NewPrimitive(PrimitiveType prim)
15.61 +Type::NewUnsafeArray(Zone *zone, Type *contained, int elements)
15.62 {
15.63 - Type *type = new Type;
15.64 - type->kind_ = PRIMITIVE;
15.65 - type->tag_ = NULL;
15.66 - type->primitive_ = prim;
15.67 + Object *obj = zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old);
15.68 + if (!obj)
15.69 + return NULL;
15.70 +
15.71 + Type *type = Type::cast(obj);
15.72 + type->initInlineArray(contained, elements);
15.73 return type;
15.74 }
15.75 -
15.76 -Type *
15.77 -Type::NewUnsafeArray(Type *contained, int elements)
15.78 -{
15.79 - Type *type = new Type;
15.80 - type->kind_ = UNSAFE_ARRAY;
15.81 - type->contained_ = contained;
15.82 - type->elements_ = elements;
15.83 - if (contained->isPrimitive())
15.84 - type->levels_ = 1;
15.85 - else
15.86 - type->levels_ = contained->levels() + 1;
15.87 - return type;
15.88 -}
16.1 --- a/jitcraft/Types.h Thu Jun 28 01:38:56 2012 -0700
16.2 +++ b/jitcraft/Types.h Fri Jun 29 19:35:17 2012 -0700
16.3 @@ -19,88 +19,97 @@
16.4 #define _include_jc_types_h_
16.5
16.6 #include "StringPool.h"
16.7 +#include "Heap.h"
16.8
16.9 namespace jc {
16.10
16.11 enum PrimitiveType
16.12 {
16.13 PrimitiveType_Int32,
16.14 - PrimitiveType_Float
16.15 + PrimitiveType_Float,
16.16 + PrimitiveTypes_Total
16.17 };
16.18
16.19 -class Type
16.20 +class Type : public GCObject
16.21 {
16.22 enum Kind {
16.23 PRIMITIVE,
16.24 UNSAFE_ARRAY
16.25 };
16.26
16.27 + private:
16.28 + void initPrimitive(Name *tag);
16.29 + void initInlineArray(Type *contained, int elements);
16.30 + Kind kind() {
16.31 + return (Kind)READ_FIELD(kind);
16.32 + }
16.33 +
16.34 public:
16.35 static const int UNKNOWN_SIZE = -1;
16.36 static const size_t MAX_UNSAFE_ARRAY_DEPTH = 5;
16.37 -
16.38 - static Type *NewPrimitive(Name *tag);
16.39 - static Type *NewPrimitive(PrimitiveType type);
16.40 - static Type *NewUnsafeArray(Type *contained, int elements);
16.41 +
16.42 + static Type *NewPrimitive(Zone *zone, Name *tag);
16.43 + static Type *NewUnsafeArray(Zone *zone, Type *contained, int elements);
16.44
16.45 - bool isPrimitive() const {
16.46 - return kind_ == PRIMITIVE;
16.47 + static Type *cast(Object *obj) {
16.48 + assert(obj->is(MapKind_Type));
16.49 + return (Type *)obj;
16.50 }
16.51 - bool isArray() const {
16.52 +
16.53 + bool isPrimitive() {
16.54 + return kind() == PRIMITIVE;
16.55 + }
16.56 + bool isArray() {
16.57 return isUnsafeArray();
16.58 }
16.59 - bool isUnsafeArray() const {
16.60 - return kind_ == UNSAFE_ARRAY;
16.61 + bool isUnsafeArray() {
16.62 + return kind() == UNSAFE_ARRAY;
16.63 }
16.64 - PrimitiveType primitive() const {
16.65 + PrimitiveType primitive() {
16.66 assert(isPrimitive());
16.67 - return primitive_;
16.68 + return (PrimitiveType)READ_FIELD(primitive);
16.69 }
16.70 - Type *contained() const {
16.71 + Type *contained() {
16.72 assert(isArray());
16.73 - return contained_;
16.74 + return Type::cast(READ_FIELD_OBJ(contained));
16.75 }
16.76 - int elements() const {
16.77 + int elements() {
16.78 assert(isArray());
16.79 - return elements_;
16.80 + return READ_FIELD(elements);
16.81 }
16.82 - unsigned levels() const {
16.83 + unsigned levels() {
16.84 assert(isArray());
16.85 - return levels_;
16.86 + return READ_FIELD(levels);
16.87 }
16.88 - Name *tag() const {
16.89 + Name *tag() {
16.90 assert(isPrimitive());
16.91 - return tag_;
16.92 + return (Name *)READ_FIELD(tag);
16.93 }
16.94 - Type *innermost() const {
16.95 + Type *innermost() {
16.96 assert(isArray());
16.97 Type *temp = contained();
16.98 while (temp->isArray())
16.99 temp = temp->contained();
16.100 return temp;
16.101 }
16.102 - bool isFloat() const {
16.103 + bool isFloat() {
16.104 return isPrimitive() && primitive() == PrimitiveType_Float;
16.105 }
16.106 - bool isInt() const {
16.107 + bool isInt() {
16.108 return isPrimitive() && primitive() == PrimitiveType_Int32;
16.109 }
16.110
16.111 private:
16.112 - Kind kind_;
16.113 -
16.114 - // If a primitive type, these tell the kind of type.
16.115 - Name *tag_;
16.116 - PrimitiveType primitive_;
16.117 + OBJECT_FIELD(uint8, kind);
16.118
16.119 - // The contained type of an array.
16.120 - Type *contained_;
16.121 + // Primitives only.
16.122 + OBJECT_FIELD(uint8, primitive);
16.123 + OBJECT_FIELD(CrapPtr, tag);
16.124
16.125 - // The number of elements in the array.
16.126 - int elements_;
16.127 -
16.128 - // Levels deep this array goes (minimum is 1).
16.129 - unsigned levels_;
16.130 + // Arrays only.
16.131 + OBJECT_FIELD(int32, elements);
16.132 + OBJECT_FIELD(uint32, levels);
16.133 + OBJECT_FIELD(Type *, contained);
16.134 };
16.135
16.136 class BoxedPrimitive
17.1 --- a/jitcraft/Utility.h Thu Jun 28 01:38:56 2012 -0700
17.2 +++ b/jitcraft/Utility.h Fri Jun 29 19:35:17 2012 -0700
17.3 @@ -20,11 +20,26 @@
17.4
17.5 #include <assert.h>
17.6 #include <intrin.h>
17.7 +#include <stdint.h>
17.8 +
17.9 +#ifdef _MSC_VER
17.10 +# pragma warning(disable:4355)
17.11 +#endif
17.12
17.13 namespace jc {
17.14
17.15 static const size_t kMallocAlignment = sizeof(void *) * 2;
17.16
17.17 +typedef uint8_t uint8;
17.18 +typedef int32_t int32;
17.19 +typedef uint32_t uint32;
17.20 +
17.21 +typedef uint8 * Address;
17.22 +
17.23 +static const size_t kKB = 1024;
17.24 +static const size_t kMB = 1024 * kKB;
17.25 +static const size_t kGB = 1024 * kMB;
17.26 +
17.27 template <typename T>
17.28 class AutoVec
17.29 {
17.30 @@ -100,6 +115,21 @@
17.31 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
17.32 #define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
17.33
17.34 +template <typename T>
17.35 +static inline bool
17.36 +IsAligned(T addr, size_t alignment)
17.37 +{
17.38 + assert(IsPowerOfTwo(alignment));
17.39 + return !(uintptr_t(addr) & (alignment - 1));
17.40 +}
17.41 +
17.42 +static inline Address
17.43 +AlignedBase(Address addr, size_t alignment)
17.44 +{
17.45 + assert(IsPowerOfTwo(alignment));
17.46 + return Address(uintptr_t(addr) & ~(alignment - 1));
17.47 +}
17.48 +
17.49 }
17.50
17.51 #endif // _include_jitcraft_utility_h_
18.1 --- a/jitcraft/Zone.cpp Thu Jun 28 01:38:56 2012 -0700
18.2 +++ b/jitcraft/Zone.cpp Fri Jun 29 19:35:17 2012 -0700
18.3 @@ -16,11 +16,18 @@
18.4 * JITCraft. If not, see http://www.gnu.org/licenses/.
18.5 */
18.6 #include "Zone.h"
18.7 +#include "TypeManager.h"
18.8
18.9 using namespace jc;
18.10
18.11 Zone jc::SingleThreadedZone;
18.12
18.13 +Zone::Zone()
18.14 + : heap_(this),
18.15 + types_(NULL)
18.16 +{
18.17 +}
18.18 +
18.19 bool
18.20 Zone::initialize()
18.21 {
18.22 @@ -28,5 +35,16 @@
18.23 return false;
18.24 if (!unsafeStack_.initialize())
18.25 return false;
18.26 + if (!heap_.initialize())
18.27 + return false;
18.28 +
18.29 + maps_[MapKind_Meta] = heap_.metaMap();
18.30 + if ((maps_[MapKind_Type] = heap_.allocateMap(MapKind_Type, sizeof(Map))) == NULL)
18.31 + return false;
18.32 +
18.33 + types_ = new TypeManager(this);
18.34 + if (!types_ || !types_->initialize())
18.35 + return false;
18.36 +
18.37 return true;
18.38 }
19.1 --- a/jitcraft/Zone.h Thu Jun 28 01:38:56 2012 -0700
19.2 +++ b/jitcraft/Zone.h Fri Jun 29 19:35:17 2012 -0700
19.3 @@ -20,16 +20,27 @@
19.4
19.5 #include "PoolAllocator.h"
19.6 #include "Stack.h"
19.7 +#include "Heap.h"
19.8 +#include "Barriers.h"
19.9
19.10 namespace jc {
19.11
19.12 +class TypeManager;
19.13 +
19.14 class Zone
19.15 {
19.16 PoolAllocator pool_;
19.17 Stack stack_;
19.18 UnsafeStack unsafeStack_;
19.19 + Heap heap_;
19.20 +
19.21 + // Map cache.
19.22 + Unbarriered<Map> maps_[MapKinds_Total];
19.23 +
19.24 + TypeManager *types_;
19.25
19.26 public:
19.27 + Zone();
19.28 bool initialize();
19.29
19.30 PoolAllocator &pool() {
19.31 @@ -41,6 +52,16 @@
19.32 UnsafeStack &unsafeStack() {
19.33 return unsafeStack_;
19.34 }
19.35 + Heap &heap() {
19.36 + return heap_;
19.37 + }
19.38 + Object *allocate(MapKind kind, size_t bytes, Heap::Tenure tenure = Heap::Tenure_Default) {
19.39 + assert(maps_[kind]);
19.40 + return heap_.allocate(maps_[kind], bytes, tenure);
19.41 + }
19.42 + TypeManager *types() const {
19.43 + return types_;
19.44 + }
19.45 };
19.46
19.47 // In a multi-threaded system, this would be a TLS variable.
20.1 --- a/jitcraft/jitcraft.vcxproj Thu Jun 28 01:38:56 2012 -0700
20.2 +++ b/jitcraft/jitcraft.vcxproj Fri Jun 29 19:35:17 2012 -0700
20.3 @@ -76,37 +76,50 @@
20.4 <ItemGroup>
20.5 <ClCompile Include="BytecodeCompiler.cpp" />
20.6 <ClCompile Include="BytecodeEmitter.cpp" />
20.7 + <ClCompile Include="Heap.cpp" />
20.8 <ClCompile Include="Interpreter.cpp" />
20.9 <ClCompile Include="main.cpp" />
20.10 <ClCompile Include="Modules.cpp" />
20.11 <ClCompile Include="NameBinding.cpp" />
20.12 <ClCompile Include="Opcodes.cpp" />
20.13 <ClCompile Include="Parser.cpp" />
20.14 + <ClCompile Include="Platform-Windows.cpp" />
20.15 <ClCompile Include="PoolAllocator.cpp" />
20.16 <ClCompile Include="Scanner.cpp" />
20.17 <ClCompile Include="Scopes.cpp" />
20.18 <ClCompile Include="SemanticAnalysis.cpp" />
20.19 + <ClCompile Include="Spaces.cpp" />
20.20 <ClCompile Include="Stack.cpp" />
20.21 + <ClCompile Include="TypeManager.cpp" />
20.22 <ClCompile Include="Types.cpp" />
20.23 <ClCompile Include="Zone.cpp" />
20.24 </ItemGroup>
20.25 <ItemGroup>
20.26 <ClInclude Include="AST.h" />
20.27 + <ClInclude Include="Barriers.h" />
20.28 <ClInclude Include="BytecodeEmitter.h" />
20.29 <ClInclude Include="BytecodeCompiler.h" />
20.30 + <ClInclude Include="Handles-inl.h" />
20.31 <ClInclude Include="HashTable.h" />
20.32 + <ClInclude Include="Heap-inl.h" />
20.33 <ClInclude Include="Interpreter.h" />
20.34 <ClInclude Include="Modules.h" />
20.35 <ClInclude Include="NameBinding.h" />
20.36 + <ClInclude Include="Heap.h" />
20.37 <ClInclude Include="Opcodes.h" />
20.38 <ClInclude Include="Parser.h" />
20.39 + <ClInclude Include="Platform.h" />
20.40 <ClInclude Include="PoolAllocator.h" />
20.41 + <ClInclude Include="Handles.h" />
20.42 <ClInclude Include="Scanner.h" />
20.43 <ClInclude Include="Scopes.h" />
20.44 <ClInclude Include="Code.h" />
20.45 <ClInclude Include="SemanticAnalysis.h" />
20.46 + <ClInclude Include="Spaces-inl.h" />
20.47 + <ClInclude Include="Spaces.h" />
20.48 <ClInclude Include="Stack.h" />
20.49 <ClInclude Include="StringPool.h" />
20.50 + <ClInclude Include="TypeManager.h" />
20.51 <ClInclude Include="Types.h" />
20.52 <ClInclude Include="UnsafeArray.h" />
20.53 <ClInclude Include="Zone.h" />