Implemented gcmaps and stack frame tracing.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
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)
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.
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/.
22 #include "TypeManager.h"
26 Scope::Scope(PoolAllocator &pool, Kind kind, Scope *enclosing)
29 maxContainedLocals_(0),
41 enclosing_->children_.push_back(this);
50 assert(enclosing_->children_[enclosing_->children_.size() - 1] == this);
51 enclosing_->children_.pop_back();
53 for (size_t i = 0; i < children_.size(); i++)
54 enclosing_->children_.push_back(children_[i]);
58 Scope::unlinkIfEmpty()
68 Scope::localLookup(Name *name)
70 for (size_t i = 0; i < names_.size(); i++) {
71 if (names_[i]->name() == name)
78 Scope::lookup(Name *name)
80 for (Scope *scope = this; scope; scope = scope->enclosing()) {
81 if (BoundName *bound = scope->localLookup(name))
88 Scope::declareVariable(Name *name, const SourcePosition &pos)
90 assert(!localLookup(name));
92 Variable *var = new (pool_) Variable(this, name, pos);
93 names_.push_back(var);
98 Scope::declareArgument(Name *name, const SourcePosition &pos)
100 assert(kind() == FUNCTION);
101 Variable *var = declareVariable(name, pos);
102 names_.push_back(var);
103 parameters_.push_back(var);
108 Scope::declareFunction(Name *name, const SourcePosition &pos)
110 assert(!localLookup(name));
111 assert(kind() == GLOBAL);
113 NamedFunction *fun = new (pool_) NamedFunction(this, name, pos);
114 names_.push_back(fun);
119 Scope::declareEnum(Name *name, const SourcePosition &pos)
121 NamedEnum *e = new (pool_) NamedEnum(this, name, pos);
127 Scope::declareConstant(Name *name, const SourcePosition &pos)
129 NamedConstant *constant = new (pool_) NamedConstant(this, name, pos);
130 names_.push_back(constant);
135 Scope::allocateGlobals()
137 assert(kind() == GLOBAL);
139 for (size_t i = 0; i < children_.size(); i++) {
140 assert(children_[i]->kind() == FUNCTION);
141 children_[i]->allocate();
144 for (size_t i = 0; i < names_.size(); i++) {
145 BoundName *name = names_[i];
147 if (name->kind() == BoundName::FUNCTION) {
148 NamedFunction *fun = name->toNamedFunction();
149 fun->allocate(numFunctions_++);
155 Scope::allocate(Variable *var)
157 if (!var->unallocated())
160 var->allocate(Variable::STACK, maxContainedLocals_ + locals_);
167 maxContainedLocals_ = 0;
168 for (size_t i = 0; i < children_.size(); i++) {
169 Scope *scope = children_[i];
171 if (scope->maxContainedLocals() > maxContainedLocals_)
172 maxContainedLocals_ = scope->maxContainedLocals();
175 for (size_t i = 0; i < parameters_.size(); i++)
176 parameters_[i]->allocate(Variable::PARAMETER, i);
180 for (size_t i = 0; i < names_.size(); i++) {
181 if (names_[i]->kind() != BoundName::VARIABLE)
184 allocate(names_[i]->toVariable());
187 maxContainedLocals_ += locals_;
191 Scope::Bind(ParseTree *tree)
193 for (size_t i = 0; i < tree->unbound()->size(); i++) {
194 NameProxy *proxy = tree->unbound()->at(i);
195 BoundName *name = tree->scope()->lookup(proxy->name());
207 Scope::Allocate(ParseTree *tree)
209 tree->scope()->allocateGlobals();
213 Scope::setUsesLifoHeap()
215 // Only one lifo slot is needed per scope.
219 // If the parent of this scope is the function scope, then this is the
220 // function's block scope, and the lifo slot is part of the Frame instead.
221 // Note we can get a function scope here if we're making a temporary in a
222 // function with no local variables.
223 if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
226 Local<Type> type(ZONE(), ZONE()->types()->getPrimitive(PrimitiveType_Native));
230 lifoSlot_ = new (pool_) Variable(this, NULL, SourcePosition());
231 lifoSlot_->setType(type);