ICs for scripted calls (bug 587698, r=dmandelin).
[mozilla-central.git] / js / src / methodjit / InlineFrameAssembler.h
blob5b4c9f3e83193244d4cdcf2036a1339b2ef96b18
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=4 sw=4 et tw=99:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
17 * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
18 * May 28, 2008.
20 * The Initial Developer of the Original Code is
21 * Brendan Eich <brendan@mozilla.org>
23 * Contributor(s):
24 * David Anderson <danderson@mozilla.com>
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.
38 * ***** END LICENSE BLOCK ***** */
40 #if !defined jsjaeger_inl_frame_asm_h__ && defined JS_METHODJIT && defined JS_MONOIC
41 #define jsjaeger_inl_frame_asm_h__
43 #include "assembler/assembler/MacroAssembler.h"
44 #include "assembler/assembler/CodeLocation.h"
45 #include "methodjit/MethodJIT.h"
46 #include "CodeGenIncludes.h"
48 namespace js {
49 namespace mjit {
51 struct AdjustedFrame {
52 AdjustedFrame(uint32 baseOffset)
53 : baseOffset(baseOffset)
54 { }
56 uint32 baseOffset;
58 JSC::MacroAssembler::Address addrOf(uint32 offset) {
59 return JSC::MacroAssembler::Address(JSFrameReg, baseOffset + offset);
64 * This is used for emitting code to inline callee-side frame creation.
65 * Specifically, it initializes the following members:
67 * savedPC
68 * argc
69 * flags
70 * scopeChain
71 * argv
72 * thisv
73 * down
75 * Once finished, JSFrameReg is advanced to be the new fp.
77 class InlineFrameAssembler {
78 typedef JSC::MacroAssembler::RegisterID RegisterID;
79 typedef JSC::MacroAssembler::Address Address;
80 typedef JSC::MacroAssembler::Imm32 Imm32;
81 typedef JSC::MacroAssembler::ImmPtr ImmPtr;
83 Assembler &masm;
84 bool isConstantThis; // Is |thisv| constant?
85 Value constantThis; // If so, this is the value.
86 uint32 frameDepth; // script->nfixed + stack depth at caller call site
87 uint32 argc; // number of args being passed to the function
88 RegisterID funObjReg; // register containing the function object (callee)
89 jsbytecode *pc; // bytecode location at the caller call site
90 uint32 flags; // frame flags
92 public:
94 * Register state, so consumers of this class can restrict which registers
95 * can and can't be clobbered.
97 Registers tempRegs;
99 InlineFrameAssembler(Assembler &masm, JSContext *cx, ic::CallICInfo &ic, uint32 flags)
100 : masm(masm), flags(flags)
102 isConstantThis = ic.isConstantThis;
103 constantThis = ic.constantThis;
104 frameDepth = ic.frameDepth;
105 argc = ic.argc;
106 funObjReg = ic.funObjReg;
107 pc = cx->regs->pc;
108 tempRegs.takeReg(ic.funPtrReg);
109 tempRegs.takeReg(funObjReg);
112 InlineFrameAssembler(Assembler &masm, Compiler::CallGenInfo &gen, jsbytecode *pc, uint32 flags)
113 : masm(masm), pc(pc), flags(flags)
115 isConstantThis = gen.isConstantThis;
116 constantThis = gen.constantThis;
117 frameDepth = gen.frameDepth;
118 argc = gen.argc;
119 funObjReg = gen.funObjReg;
120 tempRegs.takeReg(funObjReg);
123 inline void assemble()
125 RegisterID t0 = tempRegs.takeAnyReg();
127 /* Note: savedPC goes into the down frame. */
128 masm.storePtr(ImmPtr(pc), Address(JSFrameReg, offsetof(JSStackFrame, savedPC)));
130 AdjustedFrame adj(sizeof(JSStackFrame) + frameDepth * sizeof(Value));
131 masm.store32(Imm32(argc), adj.addrOf(offsetof(JSStackFrame, argc)));
132 masm.store32(Imm32(flags), adj.addrOf(offsetof(JSStackFrame, flags)));
133 masm.loadPtr(Address(funObjReg, offsetof(JSObject, parent)), t0);
134 masm.storePtr(t0, adj.addrOf(JSStackFrame::offsetScopeChain()));
135 masm.addPtr(Imm32(adj.baseOffset - (argc * sizeof(Value))), JSFrameReg, t0);
136 masm.storePtr(t0, adj.addrOf(offsetof(JSStackFrame, argv)));
138 Address targetThis = adj.addrOf(JSStackFrame::offsetThisValue());
139 if (isConstantThis) {
140 masm.storeValue(constantThis, targetThis);
141 } else {
142 Address thisvAddr = Address(t0, -int32(sizeof(Value) * 1));
143 #ifdef JS_NUNBOX32
144 RegisterID t1 = tempRegs.takeAnyReg();
145 masm.loadPayload(thisvAddr, t1);
146 masm.storePayload(t1, targetThis);
147 masm.loadTypeTag(thisvAddr, t1);
148 masm.storeTypeTag(t1, targetThis);
149 tempRegs.putReg(t1);
150 #elif JS_PUNBOX64
151 masm.loadPtr(thisvAddr, t0);
152 masm.storePtr(t0, targetThis);
153 #endif
156 masm.storePtr(JSFrameReg, adj.addrOf(offsetof(JSStackFrame, down)));
158 /* Adjust JSFrameReg. Callee fills in the rest. */
159 masm.addPtr(Imm32(sizeof(JSStackFrame) + sizeof(Value) * frameDepth), JSFrameReg);
161 tempRegs.putReg(t0);
166 } /* namespace mjit */
167 } /* namespace js */
169 #endif /* jsjaeger_inl_frame_asm_h__ */