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