diff -r c4b1341297e5 -r ba85a47ee414 src/RootScopes.h --- a/src/RootScopes.h Mon Jun 10 00:46:29 2013 +0100 +++ b/src/RootScopes.h Mon Jun 10 01:04:43 2013 +0100 @@ -1,106 +1,106 @@ -/* vim: set ts=4 sw=4 tw=99 et: - * - * Copyright (C) 2012 David Anderson - * - * This file is part of SourcePawn. - * - * SourcePawn is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * SourcePawn. If not, see http://www.gnu.org/licenses/. - */ -#ifndef _include_jc_root_scopes_h_ -#define _include_jc_root_scopes_h_ - -#include "../include/keima.h" -#include "Objects.h" -#include "VirtualObjectVisitor.h" - -namespace ke { - -class RootScope; - -// A RootScopeManager is essentially a specialized PoolAllocator that can -// only allocate Object ** entries. It is used to allow huge, temporary -// heap data structures like ASTs to hold safe references to objects. When -// the data structures is no longer needed, all of the roots are removed -// at once. -class RootScopeManager -{ - static const size_t kObjectsPerBlock = 4096; - - struct Block { - Object *objects[kObjectsPerBlock]; - Object **cur; - Object **end; - Block *prev; - - Block(Block *prev) - : cur(objects), - end(objects + kObjectsPerBlock), - prev(prev) - { - } - }; - - private: - bool grow(); - void unwindSlow(Object **position); - - public: - RootScopeManager(); - ~RootScopeManager(); - - Object **position() const { - return blocks_->cur; - } - - void unwind(Object **position) { - if (position >= blocks_->cur && position <= blocks_->end) { - blocks_->cur = position; - return; - } - unwindSlow(position); - } - - Object **make(Object *obj) { - assert(scope_); - if (blocks_->cur + 1 > blocks_->end) { - if (!grow()) - return NULL; - } - Object **ptr = blocks_->cur; - blocks_->cur++; - *ptr = obj; - return ptr; - } - - Ke::HandleScope **scope() { - return &scope_; - } - - void accept(VirtualObjectVisitor *visitor); - - private: - Block *blocks_; - Block first_; - Ke::HandleScope *scope_; -}; - -class RootScope : public Ke::HandleScope -{ - public: - // These are implemented in Zone.h. - inline RootScope(Zone *zone); -}; - -} - -#endif // _include_jc_root_scope_h_ +/* vim: set ts=4 sw=4 tw=99 et: + * + * Copyright (C) 2012 David Anderson + * + * This file is part of SourcePawn. + * + * SourcePawn is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * SourcePawn. If not, see http://www.gnu.org/licenses/. + */ +#ifndef _include_jc_root_scopes_h_ +#define _include_jc_root_scopes_h_ + +#include "../include/keima.h" +#include "Objects.h" +#include "VirtualObjectVisitor.h" + +namespace ke { + +class RootScope; + +// A RootScopeManager is essentially a specialized PoolAllocator that can +// only allocate Object ** entries. It is used to allow huge, temporary +// heap data structures like ASTs to hold safe references to objects. When +// the data structures is no longer needed, all of the roots are removed +// at once. +class RootScopeManager +{ + static const size_t kObjectsPerBlock = 4096; + + struct Block { + Object *objects[kObjectsPerBlock]; + Object **cur; + Object **end; + Block *prev; + + Block(Block *prev) + : cur(objects), + end(objects + kObjectsPerBlock), + prev(prev) + { + } + }; + + private: + bool grow(); + void unwindSlow(Object **position); + + public: + RootScopeManager(); + ~RootScopeManager(); + + Object **position() const { + return blocks_->cur; + } + + void unwind(Object **position) { + if (position >= blocks_->cur && position <= blocks_->end) { + blocks_->cur = position; + return; + } + unwindSlow(position); + } + + Object **make(Object *obj) { + assert(scope_); + if (blocks_->cur + 1 > blocks_->end) { + if (!grow()) + return NULL; + } + Object **ptr = blocks_->cur; + blocks_->cur++; + *ptr = obj; + return ptr; + } + + Ke::HandleScope **scope() { + return &scope_; + } + + void accept(VirtualObjectVisitor *visitor); + + private: + Block *blocks_; + Block first_; + Ke::HandleScope *scope_; +}; + +class RootScope : public Ke::HandleScope +{ + public: + // These are implemented in Zone.h. + inline RootScope(Zone *zone); +}; + +} + +#endif // _include_jc_root_scope_h_