jitcraft/Zone.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 10 02:11:13 2012 -0700 (2012-07-10)
changeset 68 b40b0e18a918
parent 67 b765a6383849
child 69 dfce0539a77d
permissions -rw-r--r--
Added support for ISourcePawnEngine natives.
dvander@45
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@45
     2
 *
dvander@0
     3
 * Copyright (C) 2012 David Anderson
dvander@0
     4
 *
dvander@0
     5
 * This file is part of JITCraft.
dvander@0
     6
 *
dvander@0
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@0
     8
 * the terms of the GNU General Public License as published by the Free
dvander@0
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@0
    10
 * any later version.
dvander@0
    11
 * 
dvander@0
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@0
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@0
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@0
    15
 *
dvander@0
    16
 * You should have received a copy of the GNU General Public License along with
dvander@0
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@0
    18
 */
dvander@0
    19
#include "Zone.h"
dvander@54
    20
#include "StringPool.h"
dvander@11
    21
#include "TypeManager.h"
dvander@61
    22
#include "GlobalRoots.h"
dvander@54
    23
#include "AllocatorPolicies.h"
dvander@65
    24
#include "Array.h"
dvander@0
    25
dvander@59
    26
using namespace ke;
dvander@0
    27
dvander@60
    28
Zone *ke::SingleThreadedZone;
dvander@0
    29
dvander@11
    30
Zone::Zone()
dvander@11
    31
  : heap_(this),
dvander@51
    32
    types_(NULL),
dvander@61
    33
    symbols_(NULL),
dvander@61
    34
    globalRoots_(NULL),
dvander@51
    35
    lastLocalRoot_(NULL)
dvander@11
    36
{
dvander@11
    37
}
dvander@11
    38
dvander@54
    39
Zone::~Zone()
dvander@54
    40
{
dvander@61
    41
    delete types_;
dvander@54
    42
    delete symbols_;
dvander@61
    43
    delete globalRoots_;
dvander@54
    44
}
dvander@54
    45
dvander@0
    46
bool
dvander@0
    47
Zone::initialize()
dvander@0
    48
{
dvander@0
    49
    if (!stack_.initialize())
dvander@0
    50
        return false;
dvander@11
    51
    if (!heap_.initialize())
dvander@11
    52
        return false;
dvander@11
    53
dvander@54
    54
    symbols_ = new StringPool(this);
dvander@54
    55
    if (!symbols_ || !symbols_->initialize())
dvander@54
    56
        return false;
dvander@54
    57
dvander@61
    58
    globalRoots_ = new GlobalRoots(this);
dvander@61
    59
    if (!globalRoots_ || !globalRoots_->initialize())
dvander@61
    60
        return false;
dvander@61
    61
dvander@11
    62
    maps_[MapKind_Meta] = heap_.metaMap();
dvander@12
    63
    if ((maps_[MapKind_Type] = allocateMap(MapKind_Type, sizeof(Map))) == NULL)
dvander@12
    64
        return false;
dvander@12
    65
    if ((maps_[MapKind_FixedArray] = allocateMap(MapKind_FixedArray, sizeof(Map))) == NULL)
dvander@12
    66
        return false;
dvander@12
    67
    if ((maps_[MapKind_ByteArray] = allocateMap(MapKind_ByteArray, sizeof(Map))) == NULL)
dvander@12
    68
        return false;
dvander@12
    69
    if ((maps_[MapKind_Code] = allocateMap(MapKind_Code, sizeof(Map))) == NULL)
dvander@12
    70
        return false;
dvander@14
    71
    if ((maps_[MapKind_Reference] = allocateMap(MapKind_Reference, sizeof(Map))) == NULL)
dvander@14
    72
        return false;
dvander@12
    73
    if ((maps_[MapKind_MetaArray] = allocateMap(MapKind_MetaArray, sizeof(Map))) == NULL)
dvander@11
    74
        return false;
dvander@14
    75
    if ((maps_[MapKind_Module] = allocateMap(MapKind_Module, sizeof(Map))) == NULL)
dvander@14
    76
        return false;
dvander@26
    77
    if ((maps_[MapKind_Function] = allocateMap(MapKind_Function, sizeof(Map))) == NULL)
dvander@26
    78
        return false;
dvander@54
    79
    if ((maps_[MapKind_String] = allocateMap(MapKind_String, sizeof(Map))) == NULL)
dvander@54
    80
        return false;
dvander@68
    81
    if ((maps_[MapKind_Native] = allocateMap(MapKind_Native, sizeof(Map))) == NULL)
dvander@68
    82
        return false;
dvander@53
    83
    if ((maps_[MapKind_FreeRegion] = allocateMap(MapKind_FreeRegion, sizeof(Map))) == NULL)
dvander@53
    84
        return false;
dvander@11
    85
dvander@11
    86
    types_ = new TypeManager(this);
dvander@11
    87
    if (!types_ || !types_->initialize())
dvander@11
    88
        return false;
dvander@11
    89
dvander@65
    90
    // Create the cached array maps for generic arrays. This is for the API
dvander@65
    91
    // version of Invoke(), which needs to make arrays very quickly from C++.
dvander@65
    92
    {
dvander@65
    93
        // Generic "cell" array (contents do not matter, just non-gc things).
dvander@65
    94
        Local<Type> type(this, types_->getPrimitive(PrimitiveType_Int32));
dvander@65
    95
        if (!type)
dvander@65
    96
            return false;
dvander@65
    97
dvander@67
    98
        type = types_->unsafeArray(type, Type::UNKNOWN_SIZE, false);
dvander@65
    99
        if (!type)
dvander@65
   100
            return false;
dvander@65
   101
dvander@65
   102
        Local<ArrayMap> contained(this);
dvander@65
   103
        genericArrayMap_ = ArrayMap::New(this, type, contained);
dvander@65
   104
        if (!genericArrayMap_)
dvander@65
   105
            return false;
dvander@65
   106
dvander@65
   107
        type = types_->getPrimitive(PrimitiveType_Char);
dvander@65
   108
        if (!type)
dvander@65
   109
            return false;
dvander@65
   110
dvander@67
   111
        type = types_->unsafeArray(type, Type::UNKNOWN_SIZE, false);
dvander@65
   112
        if (!type)
dvander@65
   113
            return false;
dvander@65
   114
dvander@65
   115
        charArrayMap_ = ArrayMap::New(this, type, contained);
dvander@65
   116
        if (!charArrayMap_)
dvander@65
   117
            return false;
dvander@65
   118
    }
dvander@65
   119
dvander@0
   120
    return true;
dvander@0
   121
}
dvander@12
   122
dvander@12
   123
Map *
dvander@12
   124
Zone::allocateMap(MapKind kind, size_t bytes, MapKind parent)
dvander@12
   125
{
dvander@12
   126
    assert(maps_[parent]);
dvander@12
   127
    Map *map = heap_.allocateMap(kind, bytes);
dvander@12
   128
    if (!map)
dvander@12
   129
        return NULL;
dvander@12
   130
    map->init(maps_[parent]);
dvander@12
   131
    return map;
dvander@12
   132
}
dvander@45
   133
dvander@45
   134
void
dvander@45
   135
Zone::accept(VirtualObjectVisitor *visitor)
dvander@45
   136
{
dvander@45
   137
    for (unsigned i = 0; i < MapKinds_Total; i++)
dvander@45
   138
        visitor->visit(maps_[i].address());
dvander@65
   139
    visitor->visit(charArrayMap_.address());
dvander@65
   140
    visitor->visit(genericArrayMap_.address());
dvander@45
   141
    types()->accept(visitor);
dvander@45
   142
dvander@45
   143
    Local<Object> *local = lastLocalRoot_;
dvander@45
   144
    while (local) {
dvander@45
   145
        visitor->visit(local->address());
dvander@45
   146
        local = local->prev();
dvander@45
   147
    }
dvander@45
   148
dvander@61
   149
    globalRoots_->accept(visitor);
dvander@45
   150
    rootScopes_.accept(visitor);
dvander@51
   151
dvander@51
   152
    stack_.accept(visitor);
dvander@45
   153
}
dvander@45
   154
dvander@54
   155
String *
dvander@54
   156
Zone::makeSymbol(const char *str, size_t length)
dvander@54
   157
{
dvander@54
   158
    return symbols_->add(str, length);
dvander@54
   159
}
dvander@54
   160
dvander@54
   161
String *
dvander@54
   162
Zone::makeSymbol(const char *str)
dvander@54
   163
{
dvander@54
   164
    return makeSymbol(str, strlen(str));
dvander@54
   165
}
dvander@54
   166
dvander@54
   167
void
dvander@54
   168
ZoneAllocatorPolicy::reportOutOfMemory()
dvander@54
   169
{
dvander@54
   170
    // :TODO: report
dvander@54
   171
    assert(false);
dvander@54
   172
}
dvander@54
   173
dvander@54
   174
void
dvander@54
   175
ZoneAllocatorPolicy::reportAllocationOverflow()
dvander@54
   176
{
dvander@54
   177
    // :TODO: report
dvander@54
   178
    assert(false);
dvander@54
   179
}