Imported garbage collection allocator and converted Type to a gc object.
authorDavid Anderson <dvander@alliedmods.net>
Fri Jun 29 19:35:17 2012 -0700 (2012-06-29)
changeset 11a350c2cc736a
parent 10 0c3bcd50e361
child 12 75e385f68b7e
Imported garbage collection allocator and converted Type to a gc object.
jitcraft/Barriers.h
jitcraft/Handles-inl.h
jitcraft/Handles.h
jitcraft/Heap-inl.h
jitcraft/Heap.cpp
jitcraft/Heap.h
jitcraft/Platform-Windows.cpp
jitcraft/Platform.h
jitcraft/SemanticAnalysis.cpp
jitcraft/Spaces-inl.h
jitcraft/Spaces.cpp
jitcraft/Spaces.h
jitcraft/TypeManager.cpp
jitcraft/TypeManager.h
jitcraft/Types.cpp
jitcraft/Types.h
jitcraft/Utility.h
jitcraft/Zone.cpp
jitcraft/Zone.h
jitcraft/jitcraft.vcxproj
     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" />