jitcraft/Heap.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 02 01:52:57 2012 -0700 (2012-07-02)
changeset 26 a48382113da6
parent 14 0784ac5cc347
child 27 28697d267222
permissions -rw-r--r--
Added a Function object to sit in between Module and Code.
dvander@11
     1
/*
dvander@11
     2
 * Copyright (C) 2012 David Anderson
dvander@11
     3
 *
dvander@11
     4
 * This file is part of JITCraft.
dvander@11
     5
 *
dvander@11
     6
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@11
     7
 * the terms of the GNU General Public License as published by the Free
dvander@11
     8
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@11
     9
 * any later version.
dvander@11
    10
 * 
dvander@11
    11
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@11
    12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@11
    13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@11
    14
 *
dvander@11
    15
 * You should have received a copy of the GNU General Public License along with
dvander@11
    16
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@11
    17
 */
dvander@11
    18
#ifndef _include_jitcraft_objects_h_
dvander@11
    19
#define _include_jitcraft_objects_h_
dvander@11
    20
dvander@11
    21
#include "Utility.h"
dvander@11
    22
#include "Spaces.h"
dvander@13
    23
#include "Barriers.h"
dvander@11
    24
dvander@11
    25
namespace jc {
dvander@11
    26
dvander@11
    27
class Zone;
dvander@11
    28
dvander@11
    29
// Macros for laying out objects.
dvander@11
    30
#define OBJECT_FIELD(Type, name)                    \
dvander@11
    31
    Type fld_##name##_;
dvander@11
    32
dvander@12
    33
// :TODO: refactor these now that objects are no longer tagged.
dvander@11
    34
#define RAW_FIELD_ADDRESS(ptr)                      \
dvander@12
    35
    (reinterpret_cast<uintptr_t>(ptr))
dvander@11
    36
#define TYPED_FIELD_ADDRESS(Type, ptr)              \
dvander@11
    37
    (reinterpret_cast<Type *>(RAW_FIELD_ADDRESS(ptr)))
dvander@11
    38
#define OBJ_FIELD_OFFSET(obj, ptr)                  \
dvander@11
    39
    (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(obj))
dvander@11
    40
#define READ_FIELD(name)                            \
dvander@11
    41
    read(&fld_##name##_)
dvander@11
    42
#define WRITE_FIELD(name, val)                      \
dvander@11
    43
    write(&fld_##name##_, val)
dvander@11
    44
#define READ_FIELD_OBJ(name)                        \
dvander@11
    45
    read(reinterpret_cast<Object **>(&fld_##name##_))
dvander@11
    46
#define WRITE_FIELD_OBJ(env, name, val)             \
dvander@11
    47
    write(env, reinterpret_cast<Object **>(&fld_##name##_), val)
dvander@11
    48
#define WRITE_FIELD_OBJ_NO_BARRIER(name, val)  \
dvander@11
    49
    writeNoBarrier(reinterpret_cast<Object **>(&fld_##name##_), val)
dvander@11
    50
dvander@11
    51
// Garbage-collection objects require a header to describe their layout. This
dvander@11
    52
// header is called a "map". The different kinds of maps are enumerated below.
dvander@11
    53
class Map;
dvander@11
    54
dvander@11
    55
enum MapKind
dvander@11
    56
{
dvander@12
    57
    // Represents Type objects.
dvander@12
    58
    MapKind_Type,
dvander@12
    59
dvander@14
    60
    // Represents basic data structures. When adding to this, don't forget
dvander@14
    61
    // to update Zone::initialize(), or you'll get a NULL crash trying to
dvander@14
    62
    // allocate, since these maps are cached.
dvander@12
    63
    MapKind_FixedArray,
dvander@12
    64
    MapKind_ByteArray,
dvander@12
    65
    MapKind_Code,
dvander@14
    66
    MapKind_Reference,
dvander@14
    67
    MapKind_Module,
dvander@26
    68
    MapKind_Function,
dvander@11
    69
dvander@14
    70
    // Used to represent Arrays. This does not have a canonical map.
dvander@12
    71
    MapKind_Array,
dvander@12
    72
dvander@12
    73
    // These represent special Map subclasses that require special tracing.
dvander@12
    74
    MapKinds_Special,
dvander@12
    75
    MapKind_Meta,           // (default map class)
dvander@12
    76
    MapKind_MetaArray,      // ArrayMap instances
dvander@12
    77
    MapKinds_EndSpecial,
dvander@11
    78
dvander@11
    79
    MapKinds_Total
dvander@11
    80
};
dvander@11
    81
dvander@12
    82
typedef void * VoidPtr;
dvander@11
    83
dvander@11
    84
// All garbage collected objects must inherit from GCObject. Note that using
dvander@11
    85
// virtual functions is illegal, as the |map| field would be displaced.
dvander@12
    86
class Object
dvander@11
    87
{
dvander@13
    88
    Barriered<Map> map_;
dvander@11
    89
dvander@11
    90
  public:
dvander@11
    91
    void init(Map *map) {
dvander@13
    92
        map_ = map;
dvander@11
    93
    }
dvander@11
    94
dvander@11
    95
    Map *map() {
dvander@13
    96
        return map_;
dvander@11
    97
    }
dvander@12
    98
    inline bool is(MapKind map);
dvander@13
    99
dvander@13
   100
    inline void write(Zone *zone, Object **ptr, Object *value);
dvander@11
   101
};
dvander@11
   102
dvander@12
   103
// Maps describe the layout of GCObjects. Every GCObject requires a map.
dvander@12
   104
class Map : public Object
dvander@11
   105
{
dvander@13
   106
    MapKind kind_;
dvander@11
   107
dvander@11
   108
  public:
dvander@11
   109
    void setKind(MapKind kind) {
dvander@13
   110
        kind_ = kind;
dvander@11
   111
    }
dvander@11
   112
    MapKind kind() {
dvander@13
   113
        return kind_;
dvander@11
   114
    }
dvander@12
   115
dvander@12
   116
    static inline Map *cast(Object *obj) {
dvander@12
   117
        // Note that ArrayMap is a map, but a special one: since it is non-
dvander@12
   118
        assert(obj->map()->kind() > MapKinds_Special &&
dvander@12
   119
               obj->map()->kind() < MapKinds_EndSpecial);
dvander@12
   120
        return reinterpret_cast<Map *>(obj);
dvander@12
   121
    }
dvander@11
   122
};
dvander@11
   123
dvander@11
   124
// Heap-allocated objects go here. Heaps are thread-local.
dvander@11
   125
class Heap
dvander@11
   126
{
dvander@11
   127
    Zone *zone_;
dvander@12
   128
    HeapStack lifoSpace_;
dvander@11
   129
    OldSpace mapSpace_;
dvander@11
   130
    OldSpace oldSpace_;
dvander@11
   131
dvander@11
   132
    Map *metaMap_;
dvander@11
   133
dvander@11
   134
  public:
dvander@11
   135
    enum Tenure {
dvander@12
   136
        // Default, objects go into the nursery.
dvander@11
   137
        Tenure_Default,
dvander@12
   138
        
dvander@12
   139
        // If objects are proven to not escape the stack, they can go into
dvander@12
   140
        // a LIFO arena. Allocation on the LIFO arena is not guaranteed to
dvander@12
   141
        // succeed; thus, objects may still be allocated in other arenas.
dvander@12
   142
        Tenure_Stack,
dvander@12
   143
dvander@12
   144
        // Objects that should not go into the nursery (i.e. are expected
dvander@12
   145
        // to be long-living) go here.
dvander@11
   146
        Tenure_Old
dvander@11
   147
    };
dvander@11
   148
dvander@11
   149
  private:
dvander@12
   150
    Address newOldObject(size_t bytes);
dvander@12
   151
    inline Address newStackObject(size_t bytes);
dvander@11
   152
    inline Address newObject(size_t bytes, Tenure pretenure);
dvander@11
   153
dvander@11
   154
  public:
dvander@11
   155
    Heap(Zone *zone);
dvander@11
   156
    bool initialize();
dvander@11
   157
dvander@11
   158
    inline Object *allocate(Map *map, size_t byes, Tenure pretenure);
dvander@11
   159
    Map *allocateMap(MapKind kind, size_t bytes);
dvander@11
   160
dvander@11
   161
    Map *metaMap() {
dvander@11
   162
        return metaMap_;
dvander@11
   163
    }
dvander@12
   164
    inline Address lifoPosition() const {
dvander@12
   165
        return lifoSpace_.position();
dvander@12
   166
    }
dvander@12
   167
    inline void unwindLifo(Address to) {
dvander@12
   168
        lifoSpace_.unwind(to);
dvander@12
   169
    }
dvander@11
   170
};
dvander@11
   171
dvander@11
   172
inline bool
dvander@11
   173
Object::is(MapKind kind)
dvander@11
   174
{
dvander@12
   175
    return map()->kind() == kind;
dvander@11
   176
}
dvander@11
   177
dvander@11
   178
}
dvander@11
   179
dvander@11
   180
#endif //_include_jitcraft_objects_h_