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 :
48 : namespace js {
49 : namespace mjit {
50 :
51 : struct AdjustedFrame {
52 147359 : AdjustedFrame(uint32_t baseOffset)
53 147359 : : baseOffset(baseOffset)
54 147359 : { }
55 :
56 : uint32_t baseOffset;
57 :
58 442077 : JSC::MacroAssembler::Address addrOf(uint32_t offset) {
59 442077 : 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 : */
69 : class 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 1998 : InlineFrameAssembler(Assembler &masm, ic::CallICInfo &ic, uint32_t flags)
89 1998 : : masm(masm), flags(flags), tempRegs(Registers::AvailRegs)
90 : {
91 1998 : frameSize = ic.frameSize;
92 1998 : funObjReg = ic.funObjReg;
93 1998 : tempRegs.takeReg(funObjReg);
94 1998 : }
95 :
96 147359 : InlineFrameAssembler(Assembler &masm, Compiler::CallGenInfo &gen, uint32_t flags)
97 147359 : : masm(masm), flags(flags), tempRegs(Registers::AvailRegs)
98 : {
99 147359 : frameSize = gen.frameSize;
100 147359 : funObjReg = gen.funObjReg;
101 147359 : tempRegs.takeReg(funObjReg);
102 147359 : }
103 :
104 149357 : DataLabelPtr assemble(void *ncode, jsbytecode *pc)
105 : {
106 149357 : JS_ASSERT((flags & ~StackFrame::CONSTRUCTING) == 0);
107 :
108 : /* Generate StackFrame::initCallFrameCallerHalf. */
109 :
110 : /* Get the actual flags to write. */
111 149357 : JS_ASSERT(!(flags & ~StackFrame::CONSTRUCTING));
112 149357 : uint32_t flags = this->flags | StackFrame::FUNCTION;
113 149357 : if (frameSize.lowered(pc))
114 3531 : flags |= StackFrame::LOWERED_CALL_APPLY;
115 :
116 149357 : DataLabelPtr ncodePatch;
117 149357 : if (frameSize.isStatic()) {
118 147359 : uint32_t frameDepth = frameSize.staticLocalSlots();
119 147359 : AdjustedFrame newfp(sizeof(StackFrame) + frameDepth * sizeof(Value));
120 :
121 147359 : Address flagsAddr = newfp.addrOf(StackFrame::offsetOfFlags());
122 147359 : masm.store32(Imm32(flags), flagsAddr);
123 147359 : Address prevAddr = newfp.addrOf(StackFrame::offsetOfPrev());
124 147359 : masm.storePtr(JSFrameReg, prevAddr);
125 147359 : Address ncodeAddr = newfp.addrOf(StackFrame::offsetOfNcode());
126 147359 : ncodePatch = masm.storePtrWithPatch(ImmPtr(ncode), ncodeAddr);
127 :
128 147359 : 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 1998 : RegisterID newfp = tempRegs.takeAnyReg().reg();
139 1998 : masm.loadPtr(FrameAddress(VMFrame::offsetOfRegsSp()), newfp);
140 :
141 1998 : Address flagsAddr(newfp, StackFrame::offsetOfFlags());
142 1998 : masm.store32(Imm32(flags), flagsAddr);
143 1998 : Address prevAddr(newfp, StackFrame::offsetOfPrev());
144 1998 : masm.storePtr(JSFrameReg, prevAddr);
145 1998 : Address ncodeAddr(newfp, StackFrame::offsetOfNcode());
146 1998 : ncodePatch = masm.storePtrWithPatch(ImmPtr(ncode), ncodeAddr);
147 :
148 1998 : masm.move(newfp, JSFrameReg);
149 1998 : 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 :
|