src/RootScopes.h
author David Anderson <dvander@alliedmods.net>
Sat Nov 17 19:23:39 2012 -0800 (2012-11-17)
changeset 200 e0a601465746
parent 86 32ad0523b309
child 261 219b49bf4a03
permissions -rw-r--r--
Fix OS X build.
     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 #ifndef _include_jc_root_scopes_h_
    20 #define _include_jc_root_scopes_h_
    21 
    22 #include "../include/keima.h"
    23 #include "Objects.h"
    24 #include "VirtualObjectVisitor.h"
    25 
    26 namespace ke {
    27 
    28 class RootScope;
    29 
    30 // A RootScopeManager is essentially a specialized PoolAllocator that can
    31 // only allocate Object ** entries. It is used to allow huge, temporary
    32 // heap data structures like ASTs to hold safe references to objects. When
    33 // the data structures is no longer needed, all of the roots are removed
    34 // at once.
    35 class RootScopeManager
    36 {
    37     static const size_t kObjectsPerBlock = 4096;
    38 
    39     struct Block {
    40         Object *objects[kObjectsPerBlock];
    41         Object **cur;
    42         Object **end;
    43         Block *prev;
    44 
    45         Block(Block *prev)
    46           : cur(objects),
    47             end(objects + kObjectsPerBlock),
    48             prev(prev)
    49         {
    50         }
    51     };
    52 
    53   private:
    54     bool grow();
    55     void unwindSlow(Object **position);
    56 
    57   public:
    58     RootScopeManager();
    59     ~RootScopeManager();
    60 
    61     Object **position() const {
    62         return blocks_->cur;
    63     }
    64 
    65     void unwind(Object **position) {
    66         if (position >= blocks_->cur && position <= blocks_->end) {
    67             blocks_->cur = position;
    68             return;
    69         }
    70         unwindSlow(position);
    71     }
    72 
    73     Object **make(Object *obj) {
    74         assert(scope_);
    75         if (blocks_->cur + 1 > blocks_->end) {
    76             if (!grow())
    77                 return NULL;
    78         }
    79         Object **ptr = blocks_->cur;
    80         blocks_->cur++;
    81         *ptr = obj;
    82         return ptr;
    83     }
    84 
    85     Ke::HandleScope **scope() {
    86         return &scope_;
    87     }
    88 
    89     void accept(VirtualObjectVisitor *visitor);
    90 
    91   private:
    92     Block *blocks_;
    93     Block first_;
    94     Ke::HandleScope *scope_;
    95 };
    96 
    97 class RootScope : public Ke::HandleScope
    98 {
    99   public:
   100     // These are implemented in Zone.h.
   101     inline RootScope(Zone *zone);
   102 };
   103 
   104 }
   105 
   106 #endif // _include_jc_root_scope_h_