jitcraft/Zone.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jul 09 22:25:52 2012 -0700 (2012-07-09)
changeset 67 b765a6383849
parent 65 7c942b5adebc
child 68 b40b0e18a918
permissions -rw-r--r--
Implemented const for references and arrays.
     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_FreeRegion] = allocateMap(MapKind_FreeRegion, sizeof(Map))) == NULL)
    82         return false;
    83 
    84     types_ = new TypeManager(this);
    85     if (!types_ || !types_->initialize())
    86         return false;
    87 
    88     // Create the cached array maps for generic arrays. This is for the API
    89     // version of Invoke(), which needs to make arrays very quickly from C++.
    90     {
    91         // Generic "cell" array (contents do not matter, just non-gc things).
    92         Local<Type> type(this, types_->getPrimitive(PrimitiveType_Int32));
    93         if (!type)
    94             return false;
    95 
    96         type = types_->unsafeArray(type, Type::UNKNOWN_SIZE, false);
    97         if (!type)
    98             return false;
    99 
   100         Local<ArrayMap> contained(this);
   101         genericArrayMap_ = ArrayMap::New(this, type, contained);
   102         if (!genericArrayMap_)
   103             return false;
   104 
   105         type = types_->getPrimitive(PrimitiveType_Char);
   106         if (!type)
   107             return false;
   108 
   109         type = types_->unsafeArray(type, Type::UNKNOWN_SIZE, false);
   110         if (!type)
   111             return false;
   112 
   113         charArrayMap_ = ArrayMap::New(this, type, contained);
   114         if (!charArrayMap_)
   115             return false;
   116     }
   117 
   118     return true;
   119 }
   120 
   121 Map *
   122 Zone::allocateMap(MapKind kind, size_t bytes, MapKind parent)
   123 {
   124     assert(maps_[parent]);
   125     Map *map = heap_.allocateMap(kind, bytes);
   126     if (!map)
   127         return NULL;
   128     map->init(maps_[parent]);
   129     return map;
   130 }
   131 
   132 void
   133 Zone::accept(VirtualObjectVisitor *visitor)
   134 {
   135     for (unsigned i = 0; i < MapKinds_Total; i++)
   136         visitor->visit(maps_[i].address());
   137     visitor->visit(charArrayMap_.address());
   138     visitor->visit(genericArrayMap_.address());
   139     types()->accept(visitor);
   140 
   141     Local<Object> *local = lastLocalRoot_;
   142     while (local) {
   143         visitor->visit(local->address());
   144         local = local->prev();
   145     }
   146 
   147     globalRoots_->accept(visitor);
   148     rootScopes_.accept(visitor);
   149 
   150     stack_.accept(visitor);
   151 }
   152 
   153 String *
   154 Zone::makeSymbol(const char *str, size_t length)
   155 {
   156     return symbols_->add(str, length);
   157 }
   158 
   159 String *
   160 Zone::makeSymbol(const char *str)
   161 {
   162     return makeSymbol(str, strlen(str));
   163 }
   164 
   165 void
   166 ZoneAllocatorPolicy::reportOutOfMemory()
   167 {
   168     // :TODO: report
   169     assert(false);
   170 }
   171 
   172 void
   173 ZoneAllocatorPolicy::reportAllocationOverflow()
   174 {
   175     // :TODO: report
   176     assert(false);
   177 }