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 : * David Mandelin <dmandelin@mozilla.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #if !defined jsjaeger_mono_ic_h__ && defined JS_METHODJIT && defined JS_MONOIC
42 : #define jsjaeger_mono_ic_h__
43 :
44 : #include "assembler/assembler/MacroAssembler.h"
45 : #include "assembler/assembler/CodeLocation.h"
46 : #include "assembler/moco/MocoStubs.h"
47 : #include "methodjit/MethodJIT.h"
48 : #include "CodeGenIncludes.h"
49 : #include "methodjit/ICRepatcher.h"
50 :
51 : namespace js {
52 : namespace mjit {
53 :
54 : class FrameSize
55 : {
56 : uint32_t frameDepth_ : 16;
57 : uint32_t argc_;
58 : public:
59 443243 : void initStatic(uint32_t frameDepth, uint32_t argc) {
60 443243 : JS_ASSERT(frameDepth > 0);
61 443243 : frameDepth_ = frameDepth;
62 443243 : argc_ = argc;
63 443243 : }
64 :
65 1670 : void initDynamic() {
66 1670 : frameDepth_ = 0;
67 1670 : argc_ = -1; /* quiet gcc */
68 1670 : }
69 :
70 3318332 : bool isStatic() const {
71 3318332 : return frameDepth_ > 0;
72 : }
73 :
74 328862 : bool isDynamic() const {
75 328862 : return frameDepth_ == 0;
76 : }
77 :
78 594080 : uint32_t staticLocalSlots() const {
79 594080 : JS_ASSERT(isStatic());
80 594080 : return frameDepth_;
81 : }
82 :
83 1170827 : uint32_t staticArgc() const {
84 1170827 : JS_ASSERT(isStatic());
85 1170827 : return argc_;
86 : }
87 :
88 136268 : uint32_t getArgc(VMFrame &f) const {
89 136268 : return isStatic() ? staticArgc() : f.u.call.dynamicArgc;
90 : }
91 :
92 : bool lowered(jsbytecode *pc) const {
93 : return isDynamic() || staticArgc() != GET_ARGC(pc);
94 : }
95 :
96 183501 : RejoinState rejoinState(jsbytecode *pc, bool native) {
97 183501 : if (isStatic()) {
98 181210 : if (staticArgc() == GET_ARGC(pc))
99 179513 : return native ? REJOIN_NATIVE : REJOIN_CALL_PROLOGUE;
100 1697 : JS_ASSERT(staticArgc() == GET_ARGC(pc) - 1);
101 1697 : return native ? REJOIN_NATIVE_LOWERED : REJOIN_CALL_PROLOGUE_LOWERED_CALL;
102 : }
103 2291 : return native ? REJOIN_NATIVE_LOWERED : REJOIN_CALL_PROLOGUE_LOWERED_APPLY;
104 : }
105 :
106 202336 : bool lowered(jsbytecode *pc) {
107 202336 : return !isStatic() || staticArgc() != GET_ARGC(pc);
108 : }
109 : };
110 :
111 : namespace ic {
112 :
113 : struct GlobalNameIC
114 : {
115 : typedef JSC::MacroAssembler::RegisterID RegisterID;
116 :
117 : JSC::CodeLocationLabel fastPathStart;
118 : JSC::CodeLocationCall slowPathCall;
119 :
120 : /*
121 : * - ARM and x64 always emit exactly one instruction which needs to be
122 : * patched. On ARM, the label points to the patched instruction, whilst
123 : * on x64 it points to the instruction after it.
124 : * - For x86, the label "load" points to the start of the load/store
125 : * sequence, which may consist of one or two "mov" instructions. Because
126 : * of this, x86 is the only platform which requires non-trivial patching
127 : * code.
128 : */
129 : int32_t loadStoreOffset : 15;
130 : int32_t shapeOffset : 15;
131 : };
132 :
133 : struct GetGlobalNameIC : public GlobalNameIC
134 : {
135 : };
136 :
137 : struct SetGlobalNameIC : public GlobalNameIC
138 : {
139 : JSC::CodeLocationLabel slowPathStart;
140 :
141 : /* Dynamically generted stub for method-write checks. */
142 : JSC::JITCode extraStub;
143 :
144 : /* SET only, if we had to generate an out-of-line path. */
145 : int32_t inlineShapeJump : 10; /* Offset into inline path for shape jump. */
146 : int32_t extraShapeGuard : 6; /* Offset into stub for shape guard. */
147 : bool objConst : 1; /* True if the object is constant. */
148 : RegisterID objReg : 5; /* Register for object, if objConst is false. */
149 : RegisterID shapeReg : 5; /* Register for shape; volatile. */
150 : bool hasExtraStub : 1; /* Extra stub is preset. */
151 :
152 : int32_t fastRejoinOffset : 16; /* Offset from fastPathStart to rejoin. */
153 : int32_t extraStoreOffset : 16; /* Offset into store code. */
154 :
155 : /* SET only. */
156 : ValueRemat vr; /* RHS value. */
157 :
158 : void patchInlineShapeGuard(Repatcher &repatcher, const Shape *shape);
159 : void patchExtraShapeGuard(Repatcher &repatcher, const Shape *shape);
160 : };
161 :
162 : void JS_FASTCALL GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic);
163 : void JS_FASTCALL SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic);
164 :
165 : struct EqualityICInfo {
166 : typedef JSC::MacroAssembler::RegisterID RegisterID;
167 :
168 : JSC::CodeLocationLabel stubEntry;
169 : JSC::CodeLocationCall stubCall;
170 : BoolStub stub;
171 : JSC::CodeLocationLabel target;
172 : JSC::CodeLocationLabel fallThrough;
173 : JSC::CodeLocationJump jumpToStub;
174 :
175 : ValueRemat lvr, rvr;
176 :
177 : bool generated : 1;
178 : JSC::MacroAssembler::RegisterID tempReg : 5;
179 : Assembler::Condition cond;
180 : };
181 :
182 : JSBool JS_FASTCALL Equality(VMFrame &f, ic::EqualityICInfo *ic);
183 :
184 : /* See MonoIC.cpp, CallCompiler for more information on call ICs. */
185 : struct CallICInfo {
186 : typedef JSC::MacroAssembler::RegisterID RegisterID;
187 :
188 : /* Linked list entry for all ICs guarding on the same JIT entry point in fastGuardedObject. */
189 : JSCList links;
190 :
191 : enum PoolIndex {
192 : Pool_ScriptStub,
193 : Pool_ClosureStub,
194 : Total_Pools
195 : };
196 :
197 : JSC::ExecutablePool *pools[Total_Pools];
198 :
199 : /* Used for rooting and reification. */
200 : JSObject *fastGuardedObject;
201 : JSObject *fastGuardedNative;
202 :
203 : /* Return site for scripted calls at this site, with PC and inlining state. */
204 : CallSite *call;
205 :
206 : FrameSize frameSize;
207 :
208 : /* Function object identity guard. */
209 : JSC::CodeLocationDataLabelPtr funGuard;
210 :
211 : /* Starting point for all slow call paths. */
212 : JSC::CodeLocationLabel slowPathStart;
213 :
214 : /* Inline to OOL jump, redirected by stubs. */
215 : JSC::CodeLocationJump funJump;
216 :
217 : /* Offset to inline scripted call, from funGuard. */
218 : uint32_t hotJumpOffset : 16;
219 : uint32_t joinPointOffset : 16;
220 :
221 : /* Out of line slow call. */
222 : uint32_t oolCallOffset : 16;
223 :
224 : /* Jump to patch for out-of-line scripted calls. */
225 : uint32_t oolJumpOffset : 16;
226 :
227 : /* Label for out-of-line call to IC function. */
228 : uint32_t icCallOffset : 16;
229 :
230 : /* Offset for deep-fun check to rejoin at. */
231 : uint32_t hotPathOffset : 16;
232 :
233 : /* Join point for all slow call paths. */
234 : uint32_t slowJoinOffset : 16;
235 :
236 : RegisterID funObjReg : 5;
237 : bool hit : 1;
238 : bool hasJsFunCheck : 1;
239 : bool typeMonitored : 1;
240 :
241 147336 : inline void reset() {
242 147336 : fastGuardedObject = NULL;
243 147336 : fastGuardedNative = NULL;
244 147336 : hit = false;
245 147336 : hasJsFunCheck = false;
246 147336 : PodArrayZero(pools);
247 147336 : }
248 :
249 147336 : inline void releasePools() {
250 147336 : releasePool(Pool_ScriptStub);
251 147336 : releasePool(Pool_ClosureStub);
252 147336 : }
253 :
254 307676 : inline void releasePool(PoolIndex index) {
255 307676 : if (pools[index]) {
256 2613 : pools[index]->release();
257 2613 : pools[index] = NULL;
258 : }
259 307676 : }
260 :
261 13004 : inline void purgeGuardedObject() {
262 13004 : JS_ASSERT(fastGuardedObject);
263 13004 : releasePool(CallICInfo::Pool_ClosureStub);
264 13004 : hasJsFunCheck = false;
265 13004 : fastGuardedObject = NULL;
266 13004 : JS_REMOVE_LINK(&links);
267 13004 : }
268 : };
269 :
270 : void * JS_FASTCALL New(VMFrame &f, ic::CallICInfo *ic);
271 : void * JS_FASTCALL Call(VMFrame &f, ic::CallICInfo *ic);
272 : void * JS_FASTCALL NativeNew(VMFrame &f, ic::CallICInfo *ic);
273 : void * JS_FASTCALL NativeCall(VMFrame &f, ic::CallICInfo *ic);
274 : JSBool JS_FASTCALL SplatApplyArgs(VMFrame &f);
275 :
276 : void GenerateArgumentCheckStub(VMFrame &f);
277 :
278 : } /* namespace ic */
279 : } /* namespace mjit */
280 : } /* namespace js */
281 :
282 : #endif /* jsjaeger_mono_ic_h__ */
283 :
|