Fix FileSystem.cpp build on GCC.
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/.
26 #include "NativeTable.h"
31 Stack::Stack(Zone *zone)
46 buffer_ = (char *)malloc(STACK_SIZE);
50 top_.sp = reinterpret_cast<LocalSlot *>(buffer_);
53 end_ = buffer_ + STACK_SIZE;
57 InvokeArgs::~InvokeArgs()
59 stack_->popInvokeFrame(*this);
62 NativeArgs::~NativeArgs()
64 stack_->popNativeFrame(*this);
68 SizeForCodeFrame(Code *code)
70 return sizeof(Frame) +
71 sizeof(void *) * (code->maxLoopDepth()) +
72 sizeof(LocalSlot) * (code->nlocals() + code->maxStackDepth());
76 Stack::pushInvokeFrame(Handle<Function> fun, InvokeArgs &args)
78 size_t nbytes = SizeForCodeFrame(fun->code()) +
79 sizeof(LocalSlot) * fun->nargs();
80 if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
85 memset(top_.sp, 0, sizeof(LocalSlot) * fun->nargs());
87 args.nargs_ = fun->nargs();
89 top_.sp += fun->nargs();
91 Frame *frame = reinterpret_cast<Frame *>(top_.sp);
92 new (frame) Frame(top_.fp, top_.pc, fun, fun->code(), zone_->heap().lifoPosition());
94 top_.pc = frame->code()->start();
95 top_.sp = frame->stackBase();
102 Stack::pushModuleFrame(Handle<Module> module, InvokeArgs &args)
104 size_t nbytes = SizeForCodeFrame(module->code());
105 if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
110 args.args_ = top_.sp;
114 Frame *frame = reinterpret_cast<Frame *>(top_.sp);
115 new (frame) Frame(top_.fp, top_.pc, NULL, module->code(), zone_->heap().lifoPosition());
117 top_.pc = frame->code()->start();
118 top_.sp = frame->stackBase();
125 Stack::pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc)
127 size_t nbytes = sizeof(intptr_t) * argc + sizeof(Frame);
128 if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
133 memset(top_.sp, 0, sizeof(intptr_t) * argc);
134 args.argsBase_ = top_.sp;
136 top_.sp = reinterpret_cast<LocalSlot *>(reinterpret_cast<intptr_t *>(top_.sp) + argc);
138 Frame *frame = reinterpret_cast<Frame *>(top_.sp);
139 new (frame) Frame(top_.fp, top_.pc, native, zone_->heap().lifoPosition());
142 top_.sp = reinterpret_cast<LocalSlot *>(frame + 1);
149 Stack::pushInlineFrame(Handle<Function> fun)
151 Code *code = fun->code();
152 size_t nbytes = SizeForCodeFrame(code);
153 if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
154 zone_->reportError(Message_TooMuchRecursion);
158 Frame *frame = reinterpret_cast<Frame *>(top_.sp);
159 new (frame) Frame(top_.fp, top_.pc, fun, code, zone_->heap().lifoPosition());
160 memset(frame->locals(), 0, sizeof(LocalSlot) * code->nlocals());
162 top_.pc = frame->code()->start();
163 top_.sp = frame->stackBase();
171 Stack::popInlineFrame()
173 zone_->heap().unwindLifo(top_.fp->lifoPosition());
175 Frame *prev = top_.fp->prev();
176 Function *fun = top_.fp->fun();
178 top_.pc = top_.fp->prevpc();
179 top_.sp = reinterpret_cast<LocalSlot *>(top_.fp) - fun->nargs();
185 Stack::popInvokeFrame(InvokeArgs &args)
187 zone_->heap().unwindLifo(top_.fp->lifoPosition());
189 top_.pc = top_.fp->prevpc();
190 top_.sp = args.args_;
191 top_.fp = top_.fp->prev();
195 Stack::popNativeFrame(NativeArgs &args)
197 zone_->heap().unwindLifo(top_.fp->lifoPosition());
199 top_.pc = top_.fp->prevpc();
200 top_.sp = args.argsBase_;
201 top_.fp = top_.fp->prev();
205 Frame::enterLoop(Zone *zone)
207 assert(loopDepth_ < code_->maxLoopDepth());
208 loopStack()[loopDepth_] = zone->heap().lifoPosition();
213 Frame::leaveLoop(Zone *zone)
215 assert(loopDepth_ > 0);
217 zone->heap().unwindLifo(loopStack()[loopDepth_]);
221 Frame::accept(VirtualObjectVisitor *visitor)
223 visitor->visit(reinterpret_cast<Object **>(&callee_));
224 visitor->visit(reinterpret_cast<Object **>(&code_));
228 TraceFunctionFrame(VirtualObjectVisitor *visitor, Frame *fp, LocalSlot *sp, bytecode *pc)
230 Code *code = fp->code();
231 LocalSlot *slots = fp->locals();
233 // Trace local variables.
234 for (unsigned i = 0; i < code->nlocals(); i++) {
235 Type *type = code->localType(i);
236 if (type->isTraceable())
237 visitor->visit(&slots[i].obj);
240 // Trace arguments, if a function call. Note that this means we usually
241 // mark arguments twice, once on the caller side and once on the callee.
242 // This makes it easier to deal with invoke frames which have no caller.
243 if (Function *fun = fp->maybeFun()) {
244 for (unsigned i = 0; i < fun->nargs(); i++) {
245 Type *type = fun->argType(i);
246 if (type->isTraceable())
247 visitor->visit(&fp->arg(i).obj);
251 // Finally, trace stack slots. Not every gc-point in the bytecode will
252 // have a safepoint; since they are actually uncommon, we don't emit
253 // them unless at least one stack slot would be marked.
254 if (uint8 *safepoint = code->safepointAt(code->pcToOffset(pc))) {
255 LocalSlot *base = fp->stackBase();
256 unsigned stackDepth = unsigned(sp - fp->stackBase());
257 assert(stackDepth <= code->maxStackDepth());
259 for (unsigned i = 0; i < stackDepth; i++) {
260 if (safepoint[i / 8] & (1 << (i % 8)))
261 visitor->visit(&base[i].obj);
267 Stack::accept(VirtualObjectVisitor *visitor)
269 LocalSlot *sp = top_.sp;
270 bytecode *pc = top_.pc;
272 for (Frame *frame = top_.fp; frame; frame = frame->prev()) {
273 if (!frame->isNative())
274 TraceFunctionFrame(visitor, frame, sp, pc);
275 frame->accept(visitor);
277 sp = reinterpret_cast<LocalSlot *>(frame);
278 pc = frame->prevpc();
283 Stack::isInCallStack(Handle<Module> module)
285 for (Frame *frame = top_.fp; frame; frame = frame->prev()) {
286 if (frame->code()->module() == module)
292 StackIter::StackIter(Zone *zone)
293 : pc_(zone->stack().top()->pc),
294 fp_(zone->stack().top()->fp)
299 StackIter::done() const
305 StackIter::function() const
308 return ZONE()->nativeTable()->name(fp_->native()->index())->chars();
309 if (Function *fun = fp_->maybeFun())
310 return fun->name()->chars();
315 StackIter::lineNumber() const
319 if (fp_->maybeFun()) {
320 unsigned offs = fp_->code()->pcToOffset(pc_);
321 return fp_->code()->pcToSource(offs).line;
323 return fp_->code()->lineNumber();
327 StackIter::source() const
331 return fp_->code()->module()->path()
332 ? fp_->code()->module()->path()->chars()