Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / methodjit / MonoIC.h
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 frameDepth_ : 16;
57     uint32 argc_;
58   public:
59     void initStatic(uint32 frameDepth, uint32 argc) {
60         JS_ASSERT(frameDepth > 0);
61         frameDepth_ = frameDepth;
62         argc_ = argc;
63     }
64
65     void initDynamic() {
66         frameDepth_ = 0;
67         argc_ = -1;  /* quiet gcc */
68     }
69
70     bool isStatic() const {
71         return frameDepth_ > 0;
72     }
73
74     bool isDynamic() const {
75         return frameDepth_ == 0;
76     }
77
78     uint32 staticLocalSlots() const {
79         JS_ASSERT(isStatic());
80         return frameDepth_;
81     }
82
83     uint32 staticArgc() const {
84         JS_ASSERT(isStatic());
85         return argc_;
86     }
87
88     uint32 getArgc(VMFrame &f) const {
89         return isStatic() ? staticArgc() : f.u.call.dynamicArgc;
90     }
91 };
92
93 namespace ic {
94
95 struct GlobalNameIC
96 {
97     typedef JSC::MacroAssembler::RegisterID RegisterID;
98
99     JSC::CodeLocationLabel  fastPathStart;
100     JSC::CodeLocationCall   slowPathCall;
101
102     /*
103      * - ARM and x64 always emit exactly one instruction which needs to be
104      *   patched. On ARM, the label points to the patched instruction, whilst
105      *   on x64 it points to the instruction after it.
106      * - For x86, the label "load" points to the start of the load/store
107      *   sequence, which may consist of one or two "mov" instructions. Because
108      *   of this, x86 is the only platform which requires non-trivial patching
109      *   code.
110      */
111     int32 loadStoreOffset   : 15;
112     int32 shapeOffset       : 15;
113     bool usePropertyCache   : 1;
114 };
115
116 struct GetGlobalNameIC : public GlobalNameIC
117 {
118 };
119
120 struct SetGlobalNameIC : public GlobalNameIC
121 {
122     JSC::CodeLocationLabel  slowPathStart;
123
124     /* Dynamically generted stub for method-write checks. */
125     JSC::JITCode            extraStub;
126
127     /* SET only, if we had to generate an out-of-line path. */
128     int inlineShapeJump : 10;   /* Offset into inline path for shape jump. */
129     int extraShapeGuard : 6;    /* Offset into stub for shape guard. */
130     bool objConst : 1;          /* True if the object is constant. */
131     RegisterID objReg   : 5;    /* Register for object, if objConst is false. */
132     RegisterID shapeReg : 5;    /* Register for shape; volatile. */
133     bool hasExtraStub : 1;      /* Extra stub is preset. */
134
135     int fastRejoinOffset : 16;  /* Offset from fastPathStart to rejoin. */
136     int extraStoreOffset : 16;  /* Offset into store code. */
137
138     /* SET only. */
139     ValueRemat vr;              /* RHS value. */
140
141     void patchInlineShapeGuard(Repatcher &repatcher, int32 shape);
142     void patchExtraShapeGuard(Repatcher &repatcher, int32 shape);
143 };
144
145 struct TraceICInfo {
146     TraceICInfo() {}
147
148     JSC::CodeLocationLabel stubEntry;
149     JSC::CodeLocationLabel jumpTarget;
150     JSC::CodeLocationJump traceHint;
151     JSC::CodeLocationJump slowTraceHint;
152 #ifdef DEBUG
153     jsbytecode *jumpTargetPC;
154 #endif
155     
156     /* This data is used by the tracing JIT. */
157     void *traceData;
158     uintN traceEpoch;
159     uint32 loopCounter;
160     uint32 loopCounterStart;
161
162     bool initialized : 1;
163     bool hasSlowTraceHint : 1;
164 };
165
166 static const uint16 BAD_TRACEIC_INDEX = (uint16)0xffff;
167
168 void JS_FASTCALL GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic);
169 void JS_FASTCALL SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic);
170
171 struct EqualityICInfo {
172     typedef JSC::MacroAssembler::RegisterID RegisterID;
173
174     JSC::CodeLocationLabel stubEntry;
175     JSC::CodeLocationCall stubCall;
176     BoolStub stub;
177     JSC::CodeLocationLabel target;
178     JSC::CodeLocationLabel fallThrough;
179     JSC::CodeLocationJump jumpToStub;
180
181     ValueRemat lvr, rvr;
182
183     bool generated : 1;
184     JSC::MacroAssembler::RegisterID tempReg : 5;
185     Assembler::Condition cond;
186 };
187
188 JSBool JS_FASTCALL Equality(VMFrame &f, ic::EqualityICInfo *ic);
189
190 /* See MonoIC.cpp, CallCompiler for more information on call ICs. */
191 struct CallICInfo {
192     typedef JSC::MacroAssembler::RegisterID RegisterID;
193
194     enum PoolIndex {
195         Pool_ScriptStub,
196         Pool_ClosureStub,
197         Pool_NativeStub,
198         Total_Pools
199     };
200
201     JSC::ExecutablePool *pools[Total_Pools];
202
203     /* Used for rooting and reification. */
204     JSObject *fastGuardedObject;
205     JSObject *fastGuardedNative;
206
207     /* PC at the call site. */
208     jsbytecode *pc;
209
210     FrameSize frameSize;
211
212     /* Function object identity guard. */
213     JSC::CodeLocationDataLabelPtr funGuard;
214
215     /* Starting point for all slow call paths. */
216     JSC::CodeLocationLabel slowPathStart;
217
218     /* Inline to OOL jump, redirected by stubs. */
219     JSC::CodeLocationJump funJump;
220
221     /* Offset to inline scripted call, from funGuard. */
222     uint32 hotJumpOffset   : 16;
223     uint32 joinPointOffset : 16;
224
225     /* Out of line slow call. */
226     uint32 oolCallOffset   : 16;
227
228     /* Jump to patch for out-of-line scripted calls. */
229     uint32 oolJumpOffset   : 16;
230
231     /* Label for out-of-line call to IC function. */
232     uint32 icCallOffset    : 16;
233
234     /* Offset for deep-fun check to rejoin at. */
235     uint32 hotPathOffset   : 16;
236
237     /* Join point for all slow call paths. */
238     uint32 slowJoinOffset  : 16;
239
240     RegisterID funObjReg : 5;
241     RegisterID funPtrReg : 5;
242     bool hit : 1;
243     bool hasJsFunCheck : 1;
244
245     inline void reset() {
246         fastGuardedObject = NULL;
247         fastGuardedNative = NULL;
248         hit = false;
249         hasJsFunCheck = false;
250         pools[0] = pools[1] = pools[2] = NULL;
251     }
252
253     inline void releasePools() {
254         releasePool(Pool_ScriptStub);
255         releasePool(Pool_ClosureStub);
256         releasePool(Pool_NativeStub);
257     }
258
259     inline void releasePool(PoolIndex index) {
260         if (pools[index]) {
261             pools[index]->release();
262             pools[index] = NULL;
263         }
264     }
265 };
266
267 void * JS_FASTCALL New(VMFrame &f, ic::CallICInfo *ic);
268 void * JS_FASTCALL Call(VMFrame &f, ic::CallICInfo *ic);
269 void JS_FASTCALL NativeNew(VMFrame &f, ic::CallICInfo *ic);
270 void JS_FASTCALL NativeCall(VMFrame &f, ic::CallICInfo *ic);
271 JSBool JS_FASTCALL SplatApplyArgs(VMFrame &f);
272
273 void PurgeMICs(JSContext *cx, JSScript *script);
274 void SweepCallICs(JSContext *cx, JSScript *script, bool purgeAll);
275
276 } /* namespace ic */
277 } /* namespace mjit */
278 } /* namespace js */
279
280 #endif /* jsjaeger_mono_ic_h__ */
281