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