michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "jit/RematerializedFrame.h" michael@0: #include "jit/IonFrames.h" michael@0: michael@0: #include "vm/ArgumentsObject.h" michael@0: michael@0: #include "jsscriptinlines.h" michael@0: #include "jit/IonFrames-inl.h" michael@0: michael@0: using namespace js; michael@0: using namespace jit; michael@0: michael@0: struct CopyValueToRematerializedFrame michael@0: { michael@0: Value *slots; michael@0: michael@0: CopyValueToRematerializedFrame(Value *slots) michael@0: : slots(slots) michael@0: { } michael@0: michael@0: void operator()(const Value &v) { michael@0: *slots++ = v; michael@0: } michael@0: }; michael@0: michael@0: RematerializedFrame::RematerializedFrame(JSContext *cx, uint8_t *top, InlineFrameIterator &iter) michael@0: : prevUpToDate_(false), michael@0: top_(top), michael@0: frameNo_(iter.frameNo()), michael@0: numActualArgs_(iter.numActualArgs()), michael@0: script_(iter.script()) michael@0: { michael@0: CopyValueToRematerializedFrame op(slots_); michael@0: iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &returnValue_, michael@0: &argsObj_, &thisValue_, ReadFrame_Actuals); michael@0: } michael@0: michael@0: /* static */ RematerializedFrame * michael@0: RematerializedFrame::New(JSContext *cx, uint8_t *top, InlineFrameIterator &iter) michael@0: { michael@0: unsigned numFormals = iter.isFunctionFrame() ? iter.callee()->nargs() : 0; michael@0: size_t numBytes = sizeof(RematerializedFrame) + michael@0: (Max(numFormals, iter.numActualArgs()) + michael@0: iter.script()->nfixed()) * sizeof(Value) - michael@0: sizeof(Value); // 1 Value included in sizeof(RematerializedFrame) michael@0: michael@0: void *buf = cx->calloc_(numBytes); michael@0: if (!buf) michael@0: return nullptr; michael@0: michael@0: return new (buf) RematerializedFrame(cx, top, iter); michael@0: } michael@0: michael@0: CallObject & michael@0: RematerializedFrame::callObj() const michael@0: { michael@0: JS_ASSERT(hasCallObj()); michael@0: michael@0: JSObject *scope = scopeChain(); michael@0: while (!scope->is()) michael@0: scope = scope->enclosingScope(); michael@0: return scope->as(); michael@0: } michael@0: michael@0: void michael@0: RematerializedFrame::mark(JSTracer *trc) michael@0: { michael@0: gc::MarkScriptRoot(trc, &script_, "remat ion frame script"); michael@0: gc::MarkObjectRoot(trc, &scopeChain_, "remat ion frame scope chain"); michael@0: gc::MarkValueRoot(trc, &returnValue_, "remat ion frame return value"); michael@0: gc::MarkValueRoot(trc, &thisValue_, "remat ion frame this"); michael@0: gc::MarkValueRootRange(trc, slots_, slots_ + numActualArgs_ + script_->nfixed(), michael@0: "remat ion frame stack"); michael@0: } michael@0: michael@0: void michael@0: RematerializedFrame::dump() michael@0: { michael@0: fprintf(stderr, " Rematerialized Optimized Frame%s\n", inlined() ? " (inlined)" : ""); michael@0: if (isFunctionFrame()) { michael@0: fprintf(stderr, " callee fun: "); michael@0: #ifdef DEBUG michael@0: js_DumpObject(callee()); michael@0: #else michael@0: fprintf(stderr, "?\n"); michael@0: #endif michael@0: } else { michael@0: fprintf(stderr, " global frame, no callee\n"); michael@0: } michael@0: michael@0: fprintf(stderr, " file %s line %u\n", michael@0: script()->filename(), (unsigned) script()->lineno()); michael@0: michael@0: fprintf(stderr, " script = %p\n", (void*) script()); michael@0: michael@0: if (isFunctionFrame()) { michael@0: fprintf(stderr, " scope chain: "); michael@0: #ifdef DEBUG michael@0: js_DumpObject(scopeChain()); michael@0: #else michael@0: fprintf(stderr, "?\n"); michael@0: #endif michael@0: michael@0: if (hasArgsObj()) { michael@0: fprintf(stderr, " args obj: "); michael@0: #ifdef DEBUG michael@0: js_DumpObject(&argsObj()); michael@0: #else michael@0: fprintf(stderr, "?\n"); michael@0: #endif michael@0: } michael@0: michael@0: fprintf(stderr, " this: "); michael@0: #ifdef DEBUG michael@0: js_DumpValue(thisValue()); michael@0: #else michael@0: fprintf(stderr, "?\n"); michael@0: #endif michael@0: michael@0: for (unsigned i = 0; i < numActualArgs(); i++) { michael@0: if (i < numFormalArgs()) michael@0: fprintf(stderr, " formal (arg %d): ", i); michael@0: else michael@0: fprintf(stderr, " overflown (arg %d): ", i); michael@0: #ifdef DEBUG michael@0: js_DumpValue(argv()[i]); michael@0: #else michael@0: fprintf(stderr, "?\n"); michael@0: #endif michael@0: } michael@0: michael@0: for (unsigned i = 0; i < script()->nfixed(); i++) { michael@0: fprintf(stderr, " local %d: ", i); michael@0: #ifdef DEBUG michael@0: js_DumpValue(locals()[i]); michael@0: #else michael@0: fprintf(stderr, "?\n"); michael@0: #endif michael@0: } michael@0: } michael@0: michael@0: fputc('\n', stderr); michael@0: }