jitcraft/Heap.h
author David Anderson <dvander@alliedmods.net>
Sat Jun 30 20:20:39 2012 -0700 (2012-06-30)
changeset 13 627b6b94e774
parent 12 75e385f68b7e
child 14 0784ac5cc347
permissions -rw-r--r--
Removed OBJECT_FIELD and READ and WRITE macros.
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@12
    60
    // Represents basic data structures.
dvander@12
    61
    MapKind_FixedArray,
dvander@12
    62
    MapKind_ByteArray,
dvander@12
    63
    MapKind_Code,
dvander@11
    64
dvander@12
    65
    // Used to represent Arrays. These two map kinds do not have canonical
dvander@12
    66
    // maps.
dvander@12
    67
    MapKind_Array,
dvander@12
    68
dvander@12
    69
    // These represent special Map subclasses that require special tracing.
dvander@12
    70
    MapKinds_Special,
dvander@12
    71
    MapKind_Meta,           // (default map class)
dvander@12
    72
    MapKind_MetaArray,      // ArrayMap instances
dvander@12
    73
    MapKinds_EndSpecial,
dvander@11
    74
dvander@11
    75
    MapKinds_Total
dvander@11
    76
};
dvander@11
    77
dvander@12
    78
typedef void * VoidPtr;
dvander@11
    79
dvander@11
    80
// All garbage collected objects must inherit from GCObject. Note that using
dvander@11
    81
// virtual functions is illegal, as the |map| field would be displaced.
dvander@12
    82
class Object
dvander@11
    83
{
dvander@13
    84
    Barriered<Map> map_;
dvander@11
    85
dvander@11
    86
  public:
dvander@11
    87
    void init(Map *map) {
dvander@13
    88
        map_ = map;
dvander@11
    89
    }
dvander@11
    90
dvander@11
    91
    Map *map() {
dvander@13
    92
        return map_;
dvander@11
    93
    }
dvander@12
    94
    inline bool is(MapKind map);
dvander@13
    95
dvander@13
    96
    inline void write(Zone *zone, Object **ptr, Object *value);
dvander@11
    97
};
dvander@11
    98
dvander@12
    99
// Maps describe the layout of GCObjects. Every GCObject requires a map.
dvander@12
   100
class Map : public Object
dvander@11
   101
{
dvander@13
   102
    MapKind kind_;
dvander@11
   103
dvander@11
   104
  public:
dvander@11
   105
    void setKind(MapKind kind) {
dvander@13
   106
        kind_ = kind;
dvander@11
   107
    }
dvander@11
   108
    MapKind kind() {
dvander@13
   109
        return kind_;
dvander@11
   110
    }
dvander@12
   111
dvander@12
   112
    static inline Map *cast(Object *obj) {
dvander@12
   113
        // Note that ArrayMap is a map, but a special one: since it is non-
dvander@12
   114
        assert(obj->map()->kind() > MapKinds_Special &&
dvander@12
   115
               obj->map()->kind() < MapKinds_EndSpecial);
dvander@12
   116
        return reinterpret_cast<Map *>(obj);
dvander@12
   117
    }
dvander@11
   118
};
dvander@11
   119
dvander@11
   120
// Heap-allocated objects go here. Heaps are thread-local.
dvander@11
   121
class Heap
dvander@11
   122
{
dvander@11
   123
    Zone *zone_;
dvander@12
   124
    HeapStack lifoSpace_;
dvander@11
   125
    OldSpace mapSpace_;
dvander@11
   126
    OldSpace oldSpace_;
dvander@11
   127
dvander@11
   128
    Map *metaMap_;
dvander@11
   129
dvander@11
   130
  public:
dvander@11
   131
    enum Tenure {
dvander@12
   132
        // Default, objects go into the nursery.
dvander@11
   133
        Tenure_Default,
dvander@12
   134
        
dvander@12
   135
        // If objects are proven to not escape the stack, they can go into
dvander@12
   136
        // a LIFO arena. Allocation on the LIFO arena is not guaranteed to
dvander@12
   137
        // succeed; thus, objects may still be allocated in other arenas.
dvander@12
   138
        Tenure_Stack,
dvander@12
   139
dvander@12
   140
        // Objects that should not go into the nursery (i.e. are expected
dvander@12
   141
        // to be long-living) go here.
dvander@11
   142
        Tenure_Old
dvander@11
   143
    };
dvander@11
   144
dvander@11
   145
  private:
dvander@12
   146
    Address newOldObject(size_t bytes);
dvander@12
   147
    inline Address newStackObject(size_t bytes);
dvander@11
   148
    inline Address newObject(size_t bytes, Tenure pretenure);
dvander@11
   149
dvander@11
   150
  public:
dvander@11
   151
    Heap(Zone *zone);
dvander@11
   152
    bool initialize();
dvander@11
   153
dvander@11
   154
    inline Object *allocate(Map *map, size_t byes, Tenure pretenure);
dvander@11
   155
    Map *allocateMap(MapKind kind, size_t bytes);
dvander@11
   156
dvander@11
   157
    Map *metaMap() {
dvander@11
   158
        return metaMap_;
dvander@11
   159
    }
dvander@12
   160
    inline Address lifoPosition() const {
dvander@12
   161
        return lifoSpace_.position();
dvander@12
   162
    }
dvander@12
   163
    inline void unwindLifo(Address to) {
dvander@12
   164
        lifoSpace_.unwind(to);
dvander@12
   165
    }
dvander@11
   166
};
dvander@11
   167
dvander@11
   168
inline bool
dvander@11
   169
Object::is(MapKind kind)
dvander@11
   170
{
dvander@12
   171
    return map()->kind() == kind;
dvander@11
   172
}
dvander@11
   173
dvander@11
   174
}
dvander@11
   175
dvander@11
   176
#endif //_include_jitcraft_objects_h_