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_valueinfo_h__ && defined JS_METHODJIT
41 : #define jsjaeger_valueinfo_h__
42 :
43 : #include "jsapi.h"
44 : #include "jsnum.h"
45 : #include "jstypes.h"
46 : #include "methodjit/MachineRegs.h"
47 : #include "methodjit/RematInfo.h"
48 : #include "assembler/assembler/MacroAssembler.h"
49 :
50 : namespace js {
51 : namespace mjit {
52 :
53 : class FrameEntry
54 40806 : {
55 : friend class FrameState;
56 : friend class ImmutableSync;
57 :
58 : public:
59 :
60 : /* Accessors for entries which are known constants. */
61 :
62 43952350 : bool isConstant() const {
63 43952350 : if (isCopy())
64 4699719 : return false;
65 39252631 : return data.isConstant();
66 : }
67 :
68 : const jsval_layout &getConstant() const {
69 : JS_ASSERT(isConstant());
70 : return v_;
71 : }
72 :
73 3849830 : Value getValue() const {
74 3849830 : JS_ASSERT(isConstant());
75 3849830 : return IMPL_TO_JSVAL(v_);
76 : }
77 :
78 : #if defined JS_NUNBOX32
79 2375341 : uint32_t getPayload() const {
80 2375341 : JS_ASSERT(isConstant());
81 2375341 : return v_.s.payload.u32;
82 : }
83 : #elif defined JS_PUNBOX64
84 : uint64_t getPayload() const {
85 : JS_ASSERT(isConstant());
86 : return v_.asBits & JSVAL_PAYLOAD_MASK;
87 : }
88 : #endif
89 :
90 : /* For a constant double FrameEntry, truncate to an int32. */
91 1086 : void convertConstantDoubleToInt32(JSContext *cx) {
92 1086 : JS_ASSERT(isType(JSVAL_TYPE_DOUBLE) && isConstant());
93 : int32_t value;
94 1086 : ToInt32(cx, getValue(), &value);
95 :
96 1086 : Value newValue = Int32Value(value);
97 1086 : setConstant(newValue);
98 1086 : }
99 :
100 : /*
101 : * Accessors for entries whose type is known. Any entry can have a known
102 : * type, and constant entries must have one.
103 : */
104 :
105 124190770 : bool isTypeKnown() const {
106 124190770 : return backing()->type.isConstant();
107 : }
108 :
109 : /*
110 : * The known type should not be used in generated code if it is JSVAL_TYPE_DOUBLE.
111 : * In such cases either the value is constant, in memory or in a floating point register.
112 : */
113 21636694 : JSValueType getKnownType() const {
114 21636694 : JS_ASSERT(isTypeKnown());
115 21636694 : return backing()->knownType;
116 : }
117 :
118 : #if defined JS_NUNBOX32
119 2376540 : JSValueTag getKnownTag() const {
120 2376540 : JS_ASSERT(backing()->v_.s.tag != JSVAL_TAG_CLEAR);
121 2376540 : return backing()->v_.s.tag;
122 : }
123 : #elif defined JS_PUNBOX64
124 : JSValueShiftedTag getKnownTag() const {
125 : return JSValueShiftedTag(backing()->v_.asBits & JSVAL_TAG_MASK);
126 : }
127 : #endif
128 :
129 : // Return true iff the type of this value is definitely known to be type_.
130 78653134 : bool isType(JSValueType type_) const {
131 78653134 : return isTypeKnown() && getKnownType() == type_;
132 : }
133 :
134 : // Return true iff the type of this value is definitely known not to be type_.
135 3233088 : bool isNotType(JSValueType type_) const {
136 3233088 : return isTypeKnown() && getKnownType() != type_;
137 : }
138 :
139 : // Return true if the type of this value is definitely type_, or is unknown
140 : // and thus potentially type_ at runtime.
141 655062 : bool mightBeType(JSValueType type_) const {
142 655062 : return !isNotType(type_);
143 : }
144 :
145 : /* Accessors for entries which are copies of other mutable entries. */
146 :
147 776307140 : bool isCopy() const { return !!copy; }
148 15085557 : bool isCopied() const { return copied != 0; }
149 :
150 151544936 : const FrameEntry *backing() const {
151 151544936 : return isCopy() ? copyOf() : this;
152 : }
153 :
154 479337 : bool hasSameBacking(const FrameEntry *other) const {
155 479337 : return backing() == other->backing();
156 : }
157 :
158 : private:
159 805213 : void setType(JSValueType type_) {
160 805213 : JS_ASSERT(!isCopy() && type_ != JSVAL_TYPE_UNKNOWN);
161 805213 : type.setConstant();
162 : #if defined JS_NUNBOX32
163 805213 : v_.s.tag = JSVAL_TYPE_TO_TAG(type_);
164 : #elif defined JS_PUNBOX64
165 : v_.asBits &= JSVAL_PAYLOAD_MASK;
166 : v_.asBits |= JSVAL_TYPE_TO_SHIFTED_TAG(type_);
167 : #endif
168 805213 : knownType = type_;
169 805213 : }
170 :
171 2606451 : void track(uint32_t index) {
172 2606451 : copied = 0;
173 2606451 : copy = NULL;
174 2606451 : index_ = index;
175 2606451 : tracked = true;
176 2606451 : }
177 :
178 40921357 : void clear() {
179 40921357 : JS_ASSERT(copied == 0);
180 40921357 : if (copy) {
181 6070087 : JS_ASSERT(copy->copied != 0);
182 6070087 : copy->copied--;
183 6070087 : copy = NULL;
184 : }
185 40921357 : }
186 :
187 459486147 : uint32_t trackerIndex() {
188 459486147 : return index_;
189 : }
190 :
191 : /*
192 : * Marks the FE as unsynced & invalid.
193 : */
194 9050693 : void resetUnsynced() {
195 9050693 : clear();
196 9050693 : type.unsync();
197 9050693 : data.unsync();
198 9050693 : type.invalidate();
199 9050693 : data.invalidate();
200 9050693 : }
201 :
202 : /*
203 : * Marks the FE as synced & in memory.
204 : */
205 3583204 : void resetSynced() {
206 3583204 : clear();
207 3583204 : type.setMemory();
208 3583204 : data.setMemory();
209 3583204 : }
210 :
211 : /*
212 : * Marks the FE as having a constant.
213 : */
214 3269103 : void setConstant(const Value &v) {
215 3269103 : clear();
216 3269103 : type.unsync();
217 3269103 : data.unsync();
218 3269103 : type.setConstant();
219 3269103 : data.setConstant();
220 3269103 : v_ = JSVAL_TO_IMPL(v);
221 3269103 : if (v.isDouble())
222 10864 : knownType = JSVAL_TYPE_DOUBLE;
223 : else
224 3258239 : knownType = v.extractNonDoubleType();
225 3269103 : }
226 :
227 40349115 : FrameEntry *copyOf() const {
228 40349115 : JS_ASSERT(isCopy());
229 40349115 : JS_ASSERT_IF(!copy->temporary, copy < this);
230 40349115 : return copy;
231 : }
232 :
233 : /*
234 : * Set copy index.
235 : */
236 6579659 : void setCopyOf(FrameEntry *fe) {
237 6579659 : clear();
238 6579659 : copy = fe;
239 6579659 : if (fe) {
240 6079841 : type.invalidate();
241 6079841 : data.invalidate();
242 6079841 : fe->copied++;
243 : }
244 6579659 : }
245 :
246 89212991 : inline bool isTracked() const {
247 89212991 : return tracked;
248 : }
249 :
250 2601657 : inline void untrack() {
251 2601657 : tracked = false;
252 2601657 : }
253 :
254 60663 : inline bool dataInRegister(AnyRegisterID reg) const {
255 60663 : JS_ASSERT(!copy);
256 60663 : return reg.isReg()
257 158859 : ? (data.inRegister() && data.reg() == reg.reg())
258 219522 : : (data.inFPRegister() && data.fpreg() == reg.fpreg());
259 : }
260 :
261 : private:
262 : JSValueType knownType;
263 : jsval_layout v_;
264 : RematInfo type;
265 : RematInfo data;
266 : uint32_t index_;
267 : FrameEntry *copy;
268 : bool tracked;
269 : bool temporary;
270 :
271 : /* Number of copies of this entry. */
272 : uint32_t copied;
273 :
274 : /*
275 : * Offset of the last loop in which this entry was written or had a loop
276 : * register assigned.
277 : */
278 : uint32_t lastLoop;
279 : };
280 :
281 : } /* namespace mjit */
282 : } /* namespace js */
283 :
284 : #endif /* jsjaeger_valueinfo_h__ */
285 :
|