Added RootScopes for AST roots.
Added RootScopes for AST roots.
1.1 --- a/jitcraft/AST.h Mon Jul 02 23:37:12 2012 -0700
1.2 +++ b/jitcraft/AST.h Tue Jul 03 00:21:37 2012 -0700
1.3 @@ -135,7 +135,7 @@
1.4
1.5 class Expression : public AstNode
1.6 {
1.7 - Type *type_;
1.8 + ScopedRoot<Type> type_;
1.9
1.10 public:
1.11 Expression(const SourcePosition &pos)
1.12 @@ -295,7 +295,7 @@
1.13
1.14 class StringLiteral : public Expression
1.15 {
1.16 - ByteArray *string_;
1.17 + ScopedRoot<ByteArray> string_;
1.18
1.19 public:
1.20 StringLiteral(const SourcePosition &pos, ByteArray *array)
2.1 --- a/jitcraft/Handles.h Mon Jul 02 23:37:12 2012 -0700
2.2 +++ b/jitcraft/Handles.h Tue Jul 03 00:21:37 2012 -0700
2.3 @@ -1,4 +1,5 @@
2.4 -/*
2.5 +/* vim: set ts=4 sw=4 tw=99 et:
2.6 + *
2.7 * Copyright (C) 2012 David Anderson
2.8 *
2.9 * This file is part of JITCraft.
2.10 @@ -84,6 +85,7 @@
2.11 }
2.12
2.13 public:
2.14 + // These are implemented in Zone.h.
2.15 inline explicit Local(Zone *zone, T *thing = NULL);
2.16 inline ~Local();
2.17
2.18 @@ -126,11 +128,13 @@
2.19 template <typename T>
2.20 class ScopedRoot
2.21 {
2.22 - T *thingp_;
2.23 + T **thingp_;
2.24
2.25 private:
2.26 - inline T **make(const T *&other);
2.27 - inline void assign(const T *&other) {
2.28 + // This is implemented in Zone.h.
2.29 + inline T **make(T *other);
2.30 +
2.31 + void assign(T *other) {
2.32 if (!thingp_)
2.33 thingp_ = make(other);
2.34 else
2.35 @@ -140,13 +144,15 @@
2.36 public:
2.37 ScopedRoot()
2.38 { }
2.39 - inline ScopedRoot(const T *&thing);
2.40 - inline ScopedRoot(const ScopedRoot<T> &other);
2.41 +
2.42 + // This is implemented in Zone.h.
2.43 + inline ScopedRoot(T *thing);
2.44 +
2.45 ScopedRoot &operator =(const ScopedRoot<T> &other) {
2.46 assign(*other);
2.47 return *this;
2.48 }
2.49 - ScopedRoot &operator =(const T *&other) {
2.50 + ScopedRoot &operator =(T *other) {
2.51 assign(other);
2.52 return *this;
2.53 }
2.54 @@ -154,10 +160,13 @@
2.55 return operator *();
2.56 }
2.57 T *operator *() const {
2.58 - return thingp_;
2.59 + return *thingp_;
2.60 + }
2.61 + operator T *() const {
2.62 + return thingp_ ? *thingp_ : NULL;
2.63 }
2.64 operator bool () const {
2.65 - return !!thingp_;
2.66 + return thingp_ && *thingp_;
2.67 }
2.68 };
2.69
2.70 @@ -168,33 +177,6 @@
2.71 thingp_ = reinterpret_cast<T * const*>(local.address());
2.72 }
2.73
2.74 -// A RootScope is necessary for using ScopedRoot<>.
2.75 -class RootScope
2.76 -{
2.77 - friend class Zone;
2.78 -
2.79 - struct Block
2.80 - {
2.81 - static const size_t kItemsPerBlock = 4096 / sizeof(Object *);
2.82 -
2.83 - Object **base;
2.84 - Object **ptr;
2.85 - Object **end;
2.86 - Block *prev;
2.87 -
2.88 - Block(Block *prev, Object **base)
2.89 - : base(base),
2.90 - ptr(base),
2.91 - end(base + kItemsPerBlock),
2.92 - prev(prev)
2.93 - {
2.94 - }
2.95 - };
2.96 -
2.97 - private:
2.98 -
2.99 -};
2.100 -
2.101 }
2.102
2.103 #endif // _include_jitcraft_rooting_h_
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/jitcraft/RootScopes.cpp Tue Jul 03 00:21:37 2012 -0700
3.3 @@ -0,0 +1,66 @@
3.4 +/* vim: set ts=4 sw=4 tw=99 et:
3.5 + *
3.6 + * Copyright (C) 2012 David Anderson
3.7 + *
3.8 + * This file is part of JITCraft.
3.9 + *
3.10 + * JITCraft is free software: you can redistribute it and/or modify it under
3.11 + * the terms of the GNU General Public License as published by the Free
3.12 + * Software Foundation, either version 3 of the License, or (at your option)
3.13 + * any later version.
3.14 + *
3.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
3.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3.18 + *
3.19 + * You should have received a copy of the GNU General Public License along with
3.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
3.21 + */
3.22 +#include "RootScopes.h"
3.23 +
3.24 +using namespace jc;
3.25 +
3.26 +RootScopeManager::RootScopeManager()
3.27 + : blocks_(&first_),
3.28 + first_(NULL),
3.29 + scope_(NULL)
3.30 +{
3.31 +}
3.32 +
3.33 +RootScopeManager::~RootScopeManager()
3.34 +{
3.35 + while (blocks_ != &first_) {
3.36 + Block *temp = blocks_;
3.37 + delete blocks_;
3.38 + blocks_ = temp;
3.39 + }
3.40 +}
3.41 +
3.42 +bool
3.43 +RootScopeManager::grow()
3.44 +{
3.45 + assert(blocks_->cur == blocks_->end);
3.46 +
3.47 + Block *block = new Block(blocks_);
3.48 + if (!block)
3.49 + return false;
3.50 +
3.51 + blocks_ = block;
3.52 + return true;
3.53 +}
3.54 +
3.55 +void
3.56 +RootScopeManager::unwindSlow(Object **pos)
3.57 +{
3.58 + for (;;) {
3.59 + if (pos >= blocks_->cur && pos <= blocks_->end)
3.60 + break;
3.61 + assert(blocks_ != &first_);
3.62 + Block *temp = blocks_;
3.63 + delete blocks_;
3.64 + blocks_ = temp;
3.65 + }
3.66 +
3.67 + blocks_->cur = pos;
3.68 +}
3.69 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/jitcraft/RootScopes.h Tue Jul 03 00:21:37 2012 -0700
4.3 @@ -0,0 +1,107 @@
4.4 +/* vim: set ts=4 sw=4 tw=99 et:
4.5 + *
4.6 + * Copyright (C) 2012 David Anderson
4.7 + *
4.8 + * This file is part of JITCraft.
4.9 + *
4.10 + * JITCraft is free software: you can redistribute it and/or modify it under
4.11 + * the terms of the GNU General Public License as published by the Free
4.12 + * Software Foundation, either version 3 of the License, or (at your option)
4.13 + * any later version.
4.14 + *
4.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
4.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
4.18 + *
4.19 + * You should have received a copy of the GNU General Public License along with
4.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
4.21 + */
4.22 +#ifndef _include_jc_root_scopes_h_
4.23 +#define _include_jc_root_scopes_h_
4.24 +
4.25 +#include "Objects.h"
4.26 +
4.27 +namespace jc {
4.28 +
4.29 +class RootScope;
4.30 +
4.31 +// A RootScopeManager is essentially a specialized PoolAllocator that can
4.32 +// only allocate Object ** entries. It is used to allow huge, temporary
4.33 +// heap data structures like ASTs to hold safe references to objects. When
4.34 +// the data structures is no longer needed, all of the roots are removed
4.35 +// at once.
4.36 +class RootScopeManager
4.37 +{
4.38 + static const size_t kObjectsPerBlock = 4096;
4.39 +
4.40 + struct Block {
4.41 + Object *objects[kObjectsPerBlock];
4.42 + Object **cur;
4.43 + Object **end;
4.44 + Block *prev;
4.45 +
4.46 + Block(Block *prev)
4.47 + : cur(objects),
4.48 + end(objects + kObjectsPerBlock),
4.49 + prev(prev)
4.50 + {
4.51 + }
4.52 + };
4.53 +
4.54 + private:
4.55 + bool grow();
4.56 + void unwindSlow(Object **position);
4.57 +
4.58 + public:
4.59 + RootScopeManager();
4.60 + ~RootScopeManager();
4.61 +
4.62 + Object **position() const {
4.63 + return blocks_->cur;
4.64 + }
4.65 +
4.66 + void unwind(Object **position) {
4.67 + if (position >= blocks_->cur && position <= blocks_->end) {
4.68 + blocks_->cur = position;
4.69 + return;
4.70 + }
4.71 + unwindSlow(position);
4.72 + }
4.73 +
4.74 + Object **make(Object *obj) {
4.75 + assert(scope_);
4.76 + if (blocks_->cur + 1 > blocks_->end) {
4.77 + if (!grow())
4.78 + return NULL;
4.79 + }
4.80 + Object **ptr = blocks_->cur;
4.81 + blocks_->cur++;
4.82 + *ptr = obj;
4.83 + return ptr;
4.84 + }
4.85 +
4.86 + RootScope **scope() {
4.87 + return &scope_;
4.88 + }
4.89 +
4.90 + private:
4.91 + Block *blocks_;
4.92 + Block first_;
4.93 + RootScope *scope_;
4.94 +};
4.95 +
4.96 +class RootScope
4.97 +{
4.98 + Zone *zone_;
4.99 + Object **position_;
4.100 + RootScope *prev_;
4.101 +
4.102 + public:
4.103 + // These are implemented in Zone.h.
4.104 + inline RootScope(Zone *zone);
4.105 + inline ~RootScope();
4.106 +};
4.107 +
4.108 +}
4.109 +
4.110 +#endif // _include_jc_root_scope_h_
5.1 --- a/jitcraft/Zone.h Mon Jul 02 23:37:12 2012 -0700
5.2 +++ b/jitcraft/Zone.h Tue Jul 03 00:21:37 2012 -0700
5.3 @@ -24,6 +24,7 @@
5.4 #include "Heap.h"
5.5 #include "Barriers.h"
5.6 #include "Handles.h"
5.7 +#include "RootScopes.h"
5.8
5.9 namespace jc {
5.10
5.11 @@ -42,6 +43,7 @@
5.12
5.13 // Root list.
5.14 Local<Object> *lastLocalRoot_;
5.15 + RootScopeManager rootScopes_;
5.16
5.17 public:
5.18 Zone();
5.19 @@ -72,6 +74,12 @@
5.20 Local<Object> **lastLocalRoot() {
5.21 return &lastLocalRoot_;
5.22 }
5.23 + Object **makeScopedRoot(Object *ptr) {
5.24 + return rootScopes_.make(ptr);
5.25 + }
5.26 + RootScopeManager &rootScopes() {
5.27 + return rootScopes_;
5.28 + }
5.29 };
5.30
5.31 // In a multi-threaded system, this would be a TLS variable.
5.32 @@ -118,6 +126,37 @@
5.33 *zone_->lastLocalRoot() = prev_;
5.34 }
5.35
5.36 +template <typename T>
5.37 +ScopedRoot<T>::ScopedRoot(T *thing)
5.38 + : thingp_(NULL)
5.39 +{
5.40 + // Type check that T is an Object.
5.41 + (void)static_cast<Object *>(thing);
5.42 +
5.43 + if (thing)
5.44 + assign(thing);
5.45 +}
5.46 +
5.47 +template <typename T> T **
5.48 +ScopedRoot<T>::make(T *other)
5.49 +{
5.50 + return reinterpret_cast<T **>(ZONE()->makeScopedRoot(other));
5.51 +}
5.52 +
5.53 +RootScope::RootScope(Zone *zone)
5.54 + : zone_(zone),
5.55 + position_(zone->rootScopes().position()),
5.56 + prev_(*zone->rootScopes().scope())
5.57 +{
5.58 + *zone->rootScopes().scope() = this;
5.59 +}
5.60 +
5.61 +RootScope::~RootScope()
5.62 +{
5.63 + zone_->rootScopes().unwind(position_);
5.64 + *zone_->rootScopes().scope() = prev_;
5.65 +}
5.66 +
5.67 }
5.68
5.69 #endif // _include_jitcraft_thread_h_
6.1 --- a/jitcraft/main.cpp Mon Jul 02 23:37:12 2012 -0700
6.2 +++ b/jitcraft/main.cpp Tue Jul 03 00:21:37 2012 -0700
6.3 @@ -25,6 +25,7 @@
6.4 #include "Code.h"
6.5 #include "Interpreter.h"
6.6 #include "Modules.h"
6.7 +#include "RootScopes.h"
6.8
6.9 using namespace jc;
6.10
6.11 @@ -58,6 +59,7 @@
6.12 if (!ZONE()->initialize())
6.13 return false;
6.14
6.15 + RootScope roots(ZONE());
6.16 CompileContext cc(ZONE());
6.17
6.18 Parser parser(cc, stream, length);