Optimize FrameState for large linear scripts (bug 591836, r=dmandelin).
[mozilla-central.git] / js / src / methodjit / NunboxAssembler.h
blob341429c3f4603911e708bd0e96f82a8d5a9dcace
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>
25 * David Mandelin <dmandelin@mozilla.com>
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.
39 * ***** END LICENSE BLOCK ***** */
41 #if !defined jsjaeger_assembler_h__ && defined JS_METHODJIT && defined JS_NUNBOX32
42 #define jsjaeger_assembler_h__
44 #include "methodjit/BaseAssembler.h"
46 namespace js {
47 namespace mjit {
49 /*
50 * Don't use ImmTag. Use ImmType instead.
51 * TODO: ImmTag should really just be for internal use...
53 class ImmTag : public JSC::MacroAssembler::Imm32
55 public:
56 ImmTag(JSValueTag mask)
57 : Imm32(int32(mask))
58 { }
61 struct ImmType : ImmTag
63 ImmType(JSValueType type)
64 : ImmTag(JSVAL_TYPE_TO_TAG(type))
65 { }
68 class Assembler : public BaseAssembler
70 static const uint32 PAYLOAD_OFFSET = 0;
71 static const uint32 TAG_OFFSET = 4;
73 public:
74 static const JSC::MacroAssembler::Scale JSVAL_SCALE = JSC::MacroAssembler::TimesEight;
76 Address payloadOf(Address address) {
77 return address;
80 BaseIndex payloadOf(BaseIndex address) {
81 return address;
84 Address tagOf(Address address) {
85 return Address(address.base, address.offset + TAG_OFFSET);
88 BaseIndex tagOf(BaseIndex address) {
89 return BaseIndex(address.base, address.index, address.scale, address.offset + TAG_OFFSET);
92 void loadSlot(RegisterID obj, RegisterID clobber, uint32 slot, RegisterID type, RegisterID data) {
93 JS_ASSERT(type != data);
94 Address address(obj, offsetof(JSObject, fslots) + slot * sizeof(Value));
95 RegisterID activeAddressReg = obj;
96 if (slot >= JS_INITIAL_NSLOTS) {
97 loadPtr(Address(obj, offsetof(JSObject, dslots)), clobber);
98 address = Address(clobber, (slot - JS_INITIAL_NSLOTS) * sizeof(Value));
99 activeAddressReg = clobber;
101 if (activeAddressReg == type) {
102 loadPayload(address, data);
103 loadTypeTag(address, type);
104 } else {
105 loadTypeTag(address, type);
106 loadPayload(address, data);
110 void loadTypeTag(Address address, RegisterID reg) {
111 load32(tagOf(address), reg);
114 void loadTypeTag(BaseIndex address, RegisterID reg) {
115 load32(tagOf(address), reg);
118 void storeTypeTag(ImmType imm, Address address) {
119 store32(imm, tagOf(address));
122 void storeTypeTag(ImmType imm, BaseIndex address) {
123 store32(imm, tagOf(address));
126 void storeTypeTag(RegisterID reg, Address address) {
127 store32(reg, tagOf(address));
130 void storeTypeTag(RegisterID reg, BaseIndex address) {
131 store32(reg, tagOf(address));
134 void loadPayload(Address address, RegisterID reg) {
135 load32(payloadOf(address), reg);
138 void loadPayload(BaseIndex address, RegisterID reg) {
139 load32(payloadOf(address), reg);
142 void storePayload(RegisterID reg, Address address) {
143 store32(reg, payloadOf(address));
146 void storePayload(RegisterID reg, BaseIndex address) {
147 store32(reg, payloadOf(address));
150 void storePayload(Imm32 imm, Address address) {
151 store32(imm, payloadOf(address));
154 /* Loads type first, then payload, returning label after type load. */
155 Label loadValueAsComponents(Address address, RegisterID type, RegisterID payload) {
156 loadTypeTag(address, type);
157 Label l = label();
158 loadPayload(address, payload);
159 return l;
162 Label loadValueAsComponents(BaseIndex address, RegisterID type, RegisterID payload) {
163 loadTypeTag(address, type);
164 Label l = label();
165 loadPayload(address, payload);
166 return l;
170 * Stores type first, then payload.
172 void storeValue(const Value &v, Address address) {
173 jsval_layout jv;
174 jv.asBits = JSVAL_BITS(Jsvalify(v));
176 store32(ImmTag(jv.s.tag), tagOf(address));
177 store32(Imm32(jv.s.payload.u32), payloadOf(address));
180 void storeValue(const Value &v, BaseIndex address) {
181 jsval_layout jv;
182 jv.asBits = JSVAL_BITS(Jsvalify(v));
184 store32(ImmTag(jv.s.tag), tagOf(address));
185 store32(Imm32(jv.s.payload.u32), payloadOf(address));
189 * Performs type store before payload store, even for Undefined.
190 * Returns label after type store.
192 Label storeValueForIC(const Value &v, Address address) {
193 jsval_layout jv;
194 jv.asBits = JSVAL_BITS(Jsvalify(v));
196 store32(ImmTag(jv.s.tag), tagOf(address));
197 Label l = label();
198 store32(Imm32(jv.s.payload.u32), payloadOf(address));
199 return l;
202 void loadPrivate(Address privAddr, RegisterID to) {
203 loadPtr(privAddr, to);
206 void loadFunctionPrivate(RegisterID base, RegisterID to) {
207 Address privSlot(base, offsetof(JSObject, fslots) +
208 JSSLOT_PRIVATE * sizeof(Value));
209 loadPtr(privSlot, to);
212 Jump testNull(Assembler::Condition cond, RegisterID reg) {
213 return branch32(cond, reg, ImmTag(JSVAL_TAG_NULL));
216 Jump testNull(Assembler::Condition cond, Address address) {
217 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_NULL));
220 Jump testInt32(Assembler::Condition cond, RegisterID reg) {
221 return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
224 Jump testInt32(Assembler::Condition cond, Address address) {
225 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
228 Jump testNumber(Assembler::Condition cond, RegisterID reg) {
229 cond = (cond == Assembler::Equal) ? Assembler::BelowOrEqual : Assembler::Above;
230 return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
233 Jump testNumber(Assembler::Condition cond, Address address) {
234 cond = (cond == Assembler::Equal) ? Assembler::BelowOrEqual : Assembler::Above;
235 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
238 Jump testPrimitive(Assembler::Condition cond, RegisterID reg) {
239 cond = (cond == Assembler::NotEqual) ? Assembler::AboveOrEqual : Assembler::Below;
240 return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
243 Jump testPrimitive(Assembler::Condition cond, Address address) {
244 cond = (cond == Assembler::NotEqual) ? Assembler::AboveOrEqual : Assembler::Below;
245 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
248 Jump testObject(Assembler::Condition cond, RegisterID reg) {
249 return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
252 Jump testObject(Assembler::Condition cond, Address address) {
253 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
256 Jump testDouble(Assembler::Condition cond, RegisterID reg) {
257 Assembler::Condition opcond;
258 if (cond == Assembler::Equal)
259 opcond = Assembler::Below;
260 else
261 opcond = Assembler::AboveOrEqual;
262 return branch32(opcond, reg, ImmTag(JSVAL_TAG_CLEAR));
265 Jump testDouble(Assembler::Condition cond, Address address) {
266 Assembler::Condition opcond;
267 if (cond == Assembler::Equal)
268 opcond = Assembler::Below;
269 else
270 opcond = Assembler::AboveOrEqual;
271 return branch32(opcond, tagOf(address), ImmTag(JSVAL_TAG_CLEAR));
274 Jump testBoolean(Assembler::Condition cond, RegisterID reg) {
275 return branch32(cond, reg, ImmTag(JSVAL_TAG_BOOLEAN));
278 Jump testBoolean(Assembler::Condition cond, Address address) {
279 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_BOOLEAN));
282 Jump testString(Assembler::Condition cond, RegisterID reg) {
283 return branch32(cond, reg, ImmTag(JSVAL_TAG_STRING));
286 Jump testString(Assembler::Condition cond, Address address) {
287 return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_STRING));
291 } /* namespace js */
292 } /* namespace mjit */
294 #endif