jitcraft/Spaces.h
author David Anderson <dvander@alliedmods.net>
Sun Jul 01 14:52:57 2012 -0700 (2012-07-01)
changeset 21 af5d8e985502
parent 12 75e385f68b7e
child 49 a92afa7484fd
permissions -rw-r--r--
Added initial String: support.
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_spaces_h_
dvander@11
    19
#define _include_jitcraft_spaces_h_
dvander@11
    20
dvander@11
    21
#include "Utility.h"
dvander@12
    22
#include "Platform.h"
dvander@11
    23
dvander@11
    24
namespace jc {
dvander@11
    25
dvander@11
    26
static const size_t kObjectAlignment = 8;
dvander@11
    27
dvander@12
    28
// The heap stack is designed for structures which are known to not escape the
dvander@12
    29
// program stack, and can thus be quickly allocated in a LIFO manner.
dvander@12
    30
// 
dvander@12
    31
class HeapStack
dvander@12
    32
{
dvander@12
    33
    OS::AlignableMapping map_;
dvander@12
    34
    Address buffer_;
dvander@12
    35
    Address pos_;
dvander@12
    36
    Address end_;
dvander@12
    37
dvander@12
    38
  private:
dvander@12
    39
    static const size_t kStackSize = 1024 * 1024;
dvander@12
    40
dvander@12
    41
  public:
dvander@12
    42
    HeapStack();
dvander@12
    43
    ~HeapStack();
dvander@12
    44
    bool initialize();
dvander@12
    45
dvander@12
    46
  public:
dvander@12
    47
    Address position() const {
dvander@12
    48
        return pos_;
dvander@12
    49
    }
dvander@12
    50
    inline Address allocate(size_t nbytes);
dvander@12
    51
    inline void unwind(Address to);
dvander@12
    52
};
dvander@12
    53
dvander@11
    54
class HeapChunk
dvander@11
    55
{
dvander@11
    56
    HeapChunk *next_;
dvander@11
    57
dvander@11
    58
    // Base address, from OS::AlignableMapping.
dvander@11
    59
    Address base_;
dvander@11
    60
dvander@11
    61
    // End of the allocated region.
dvander@11
    62
    Address end_;
dvander@11
    63
dvander@11
    64
    // Current allocation point.
dvander@11
    65
    Address cursor_;
dvander@11
    66
dvander@11
    67
  public:
dvander@11
    68
    static const size_t kMaxObjectSize = 1 * kGB;
dvander@11
    69
    static const size_t kDefaultSize = 256 * kKB;
dvander@11
    70
    static const size_t kAlignment = 256 * kKB;
dvander@11
    71
dvander@11
    72
    // All objects must be allocated in the first kAlignment bytes of the
dvander@11
    73
    // chunk. Every object is at least 8 bytes (kPointerAlignment), so we
dvander@11
    74
    // reserve one mark bit for every possible object address in the chunk
dvander@11
    75
    // (including, for simplicity, unallocatable addresses at the start).
dvander@11
    76
    //
dvander@11
    77
    // The number of mark bits needed is:
dvander@11
    78
    //
dvander@11
    79
    // MaxObjectsPerChunk = kAlignment / kPointerAlignment 
dvander@11
    80
    //                    = 32KB
dvander@11
    81
    //
dvander@11
    82
    // The number of bytes needed for these mark bits is:
dvander@11
    83
    //
dvander@11
    84
    // NumMarkBytes       = MaxObjectsPerChunk / 8
dvander@11
    85
    //                    = 4KB
dvander@11
    86
    //
dvander@11
    87
    // The number of uint32s needed to store these bytes is:
dvander@11
    88
    //
dvander@11
    89
    // NumMarkWords       = NumMarkBytes / sizeof(uint32)
dvander@11
    90
    //                    = 1024
dvander@11
    91
    static const size_t kMaxObjectsPerChunk = kAlignment / kObjectAlignment;
dvander@11
    92
    static const size_t kMarkBits = kMaxObjectsPerChunk;
dvander@11
    93
    static const size_t kMarkBytes = kMarkBits / 8;
dvander@11
    94
    static const size_t kMarkWords = kMarkBytes / sizeof(uint32);
dvander@11
    95
dvander@11
    96
    static inline size_t offsetToMarkBits()
dvander@11
    97
    {
dvander@11
    98
        return Align(sizeof(HeapChunk), kObjectAlignment);
dvander@11
    99
    }
dvander@11
   100
dvander@11
   101
    static inline size_t offsetToFirst()
dvander@11
   102
    {
dvander@11
   103
        assert(IsAligned(kMarkBytes, kObjectAlignment));
dvander@11
   104
        return offsetToMarkBits() + kMarkBytes;
dvander@11
   105
    }
dvander@11
   106
dvander@11
   107
  public:
dvander@11
   108
    static HeapChunk *New(HeapChunk *prev, size_t size);
dvander@11
   109
    static void Destroy(HeapChunk *chunk);
dvander@11
   110
dvander@11
   111
  public:
dvander@11
   112
    inline Address allocate(size_t nbytes);
dvander@11
   113
dvander@11
   114
    HeapChunk *next() {
dvander@11
   115
        return next_;
dvander@11
   116
    }
dvander@11
   117
    Address base() {
dvander@11
   118
        return base_;
dvander@11
   119
    }
dvander@11
   120
    Address end() {
dvander@11
   121
        return end_;
dvander@11
   122
    }
dvander@11
   123
    size_t size() {
dvander@11
   124
        return end() - base();
dvander@11
   125
    }
dvander@11
   126
    Address first() {
dvander@11
   127
        return reinterpret_cast<Address>(this) + offsetToFirst();
dvander@11
   128
    }
dvander@11
   129
    uint32 *markBits() {
dvander@11
   130
        return reinterpret_cast<uint32 *>(reinterpret_cast<Address>(this) +
dvander@11
   131
                                          offsetToMarkBits());
dvander@11
   132
    }
dvander@11
   133
};
dvander@11
   134
dvander@11
   135
class OldSpace
dvander@11
   136
{
dvander@11
   137
    HeapChunk *first_;
dvander@11
   138
    HeapChunk *last_;
dvander@11
   139
dvander@11
   140
  public:
dvander@11
   141
    OldSpace();
dvander@11
   142
    ~OldSpace();
dvander@11
   143
dvander@11
   144
    bool initialize();
dvander@11
   145
dvander@11
   146
  public:
dvander@11
   147
    inline Address allocate(size_t nbytes);
dvander@11
   148
    Address allocateSlow(size_t nbytes);
dvander@11
   149
};
dvander@11
   150
dvander@11
   151
}
dvander@11
   152
dvander@11
   153
#endif // _include_jitcraft_spaces_h_