PageRenderTime 23ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/js/src/methodjit/InlineFrameAssembler.h

http://github.com/zpao/v8monkey
C Header | 161 lines | 79 code | 24 blank | 58 comment | 6 complexity | 1648acb1d5ea3117fed0d1bf00157685 MD5 | raw file
  1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2 * vim: set ts=4 sw=4 et tw=99:
  3 *
  4 * ***** BEGIN LICENSE BLOCK *****
  5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6 *
  7 * The contents of this file are subject to the Mozilla Public License Version
  8 * 1.1 (the "License"); you may not use this file except in compliance with
  9 * the License. You may obtain a copy of the License at
 10 * http://www.mozilla.org/MPL/
 11 *
 12 * Software distributed under the License is distributed on an "AS IS" basis,
 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 14 * for the specific language governing rights and limitations under the
 15 * License.
 16 *
 17 * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
 18 * May 28, 2008.
 19 *
 20 * The Initial Developer of the Original Code is
 21 *   Brendan Eich <brendan@mozilla.org>
 22 *
 23 * Contributor(s):
 24 *   David Anderson <danderson@mozilla.com>
 25 *
 26 * Alternatively, the contents of this file may be used under the terms of
 27 * either of the GNU General Public License Version 2 or later (the "GPL"),
 28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 29 * in which case the provisions of the GPL or the LGPL are applicable instead
 30 * of those above. If you wish to allow use of your version of this file only
 31 * under the terms of either the GPL or the LGPL, and not to allow others to
 32 * use your version of this file under the terms of the MPL, indicate your
 33 * decision by deleting the provisions above and replace them with the notice
 34 * and other provisions required by the GPL or the LGPL. If you do not delete
 35 * the provisions above, a recipient may use your version of this file under
 36 * the terms of any one of the MPL, the GPL or the LGPL.
 37 *
 38 * ***** END LICENSE BLOCK ***** */
 39
 40#if !defined jsjaeger_inl_frame_asm_h__ && defined JS_METHODJIT && defined JS_MONOIC
 41#define jsjaeger_inl_frame_asm_h__
 42
 43#include "assembler/assembler/MacroAssembler.h"
 44#include "assembler/assembler/CodeLocation.h"
 45#include "methodjit/MethodJIT.h"
 46#include "CodeGenIncludes.h"
 47
 48namespace js {
 49namespace mjit {
 50
 51struct AdjustedFrame {
 52    AdjustedFrame(uint32_t baseOffset)
 53     : baseOffset(baseOffset)
 54    { }
 55
 56    uint32_t baseOffset;
 57
 58    JSC::MacroAssembler::Address addrOf(uint32_t offset) {
 59        return JSC::MacroAssembler::Address(JSFrameReg, baseOffset + offset);
 60    }
 61};
 62
 63/*
 64 * This is used for emitting code to inline callee-side frame creation and
 65 * should jit code equivalent to StackFrame::initCallFrameCallerHalf.
 66 *
 67 * Once finished, JSFrameReg is advanced to be the new fp.
 68 */
 69class InlineFrameAssembler {
 70    typedef JSC::MacroAssembler::RegisterID RegisterID;
 71    typedef JSC::MacroAssembler::Address Address;
 72    typedef JSC::MacroAssembler::Imm32 Imm32;
 73    typedef JSC::MacroAssembler::ImmPtr ImmPtr;
 74    typedef JSC::MacroAssembler::DataLabelPtr DataLabelPtr;
 75
 76    Assembler &masm;
 77    FrameSize  frameSize;       // size of the caller's frame
 78    RegisterID funObjReg;       // register containing the function object (callee)
 79    uint32_t   flags;           // frame flags
 80
 81  public:
 82    /*
 83     * Register state, so consumers of this class can restrict which registers
 84     * can and can't be clobbered.
 85     */
 86    Registers  tempRegs;
 87
 88    InlineFrameAssembler(Assembler &masm, ic::CallICInfo &ic, uint32_t flags)
 89      : masm(masm), flags(flags), tempRegs(Registers::AvailRegs)
 90    {
 91        frameSize = ic.frameSize;
 92        funObjReg = ic.funObjReg;
 93        tempRegs.takeReg(funObjReg);
 94    }
 95
 96    InlineFrameAssembler(Assembler &masm, Compiler::CallGenInfo &gen, uint32_t flags)
 97      : masm(masm), flags(flags), tempRegs(Registers::AvailRegs)
 98    {
 99        frameSize = gen.frameSize;
100        funObjReg = gen.funObjReg;
101        tempRegs.takeReg(funObjReg);
102    }
103
104    DataLabelPtr assemble(void *ncode, jsbytecode *pc)
105    {
106        JS_ASSERT((flags & ~StackFrame::CONSTRUCTING) == 0);
107
108        /* Generate StackFrame::initCallFrameCallerHalf. */
109
110        /* Get the actual flags to write. */
111        JS_ASSERT(!(flags & ~StackFrame::CONSTRUCTING));
112        uint32_t flags = this->flags | StackFrame::FUNCTION;
113        if (frameSize.lowered(pc))
114            flags |= StackFrame::LOWERED_CALL_APPLY;
115
116        DataLabelPtr ncodePatch;
117        if (frameSize.isStatic()) {
118            uint32_t frameDepth = frameSize.staticLocalSlots();
119            AdjustedFrame newfp(sizeof(StackFrame) + frameDepth * sizeof(Value));
120
121            Address flagsAddr = newfp.addrOf(StackFrame::offsetOfFlags());
122            masm.store32(Imm32(flags), flagsAddr);
123            Address prevAddr = newfp.addrOf(StackFrame::offsetOfPrev());
124            masm.storePtr(JSFrameReg, prevAddr);
125            Address ncodeAddr = newfp.addrOf(StackFrame::offsetOfNcode());
126            ncodePatch = masm.storePtrWithPatch(ImmPtr(ncode), ncodeAddr);
127
128            masm.addPtr(Imm32(sizeof(StackFrame) + frameDepth * sizeof(Value)), JSFrameReg);
129        } else {
130            /*
131             * If the frame size is dynamic, then the fast path generated by
132             * generateFullCallStub must be used. Thus, this code is executed
133             * after stubs::SplatApplyArgs has been called. SplatApplyArgs
134             * stores the dynamic stack pointer (i.e., regs.sp after pushing a
135             * dynamic number of arguments) to VMFrame.regs, so we just load it
136             * here to get the new frame pointer.
137             */
138            RegisterID newfp = tempRegs.takeAnyReg().reg();
139            masm.loadPtr(FrameAddress(VMFrame::offsetOfRegsSp()), newfp);
140
141            Address flagsAddr(newfp, StackFrame::offsetOfFlags());
142            masm.store32(Imm32(flags), flagsAddr);
143            Address prevAddr(newfp, StackFrame::offsetOfPrev());
144            masm.storePtr(JSFrameReg, prevAddr);
145            Address ncodeAddr(newfp, StackFrame::offsetOfNcode());
146            ncodePatch = masm.storePtrWithPatch(ImmPtr(ncode), ncodeAddr);
147
148            masm.move(newfp, JSFrameReg);
149            tempRegs.putReg(newfp);
150        }
151
152        return ncodePatch;
153    }
154};
155
156
157} /* namespace mjit */
158} /* namespace js */
159
160#endif /* jsjaeger_inl_frame_asm_h__ */
161