blob: 401c2e4a0376b33ad9c00df5d78b46026dbe901c [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
48class HInstruction;
49class HLoopInformation;
50class HValue;
51class LInstruction;
52class LChunkBuilder;
53
54
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000055#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 V(ControlInstruction) \
58 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059
60
61#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000062 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000063 V(AccessArgumentsAt) \
64 V(Add) \
65 V(ApplyArguments) \
66 V(ArgumentsElements) \
67 V(ArgumentsLength) \
68 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ArrayLiteral) \
70 V(BitAnd) \
71 V(BitNot) \
72 V(BitOr) \
73 V(BitXor) \
74 V(BlockEntry) \
75 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000076 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000077 V(CallConstantFunction) \
78 V(CallFunction) \
79 V(CallGlobal) \
80 V(CallKeyed) \
81 V(CallKnownGlobal) \
82 V(CallNamed) \
83 V(CallNew) \
84 V(CallRuntime) \
85 V(CallStub) \
86 V(Change) \
87 V(CheckFunction) \
88 V(CheckInstanceType) \
89 V(CheckMap) \
90 V(CheckNonSmi) \
91 V(CheckPrototypeMaps) \
92 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000093 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000094 V(ClassOfTestAndBranch) \
95 V(CompareIDAndBranch) \
96 V(CompareGeneric) \
97 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000098 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000099 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000101 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000105 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000107 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000108 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000109 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000111 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(GlobalObject) \
113 V(GlobalReceiver) \
114 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000115 V(HasCachedArrayIndexAndBranch) \
116 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000117 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000119 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000120 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000121 V(IsConstructCallAndBranch) \
122 V(IsNullAndBranch) \
123 V(IsObjectAndBranch) \
124 V(IsSmiAndBranch) \
125 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000126 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000128 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000130 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000131 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000132 V(LoadGlobalCell) \
133 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadKeyedFastElement) \
135 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000136 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000138 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139 V(LoadNamedGeneric) \
140 V(Mod) \
141 V(Mul) \
142 V(ObjectLiteral) \
143 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000144 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000145 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000146 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(PushArgument) \
148 V(RegExpLiteral) \
149 V(Return) \
150 V(Sar) \
151 V(Shl) \
152 V(Shr) \
153 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000154 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000156 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000157 V(StoreGlobalCell) \
158 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159 V(StoreKeyedFastElement) \
160 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000161 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000162 V(StoreNamedField) \
163 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000164 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000165 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000166 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000167 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000168 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000169 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000171 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000172 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000173 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000174 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(UnaryMathOperation) \
176 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000177 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178 V(ValueOf)
179
180#define GVN_FLAG_LIST(V) \
181 V(Calls) \
182 V(InobjectFields) \
183 V(BackingStoreFields) \
184 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000185 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000186 V(GlobalVars) \
187 V(Maps) \
188 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000189 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000190 V(OsrEntries)
191
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000192#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193 virtual bool Is##type() const { return true; } \
194 static H##type* cast(HValue* value) { \
195 ASSERT(value->Is##type()); \
196 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000197 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198
199
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000200#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000202 static H##type* cast(HValue* value) { \
203 ASSERT(value->Is##type()); \
204 return reinterpret_cast<H##type*>(value); \
205 } \
206 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207
208
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209class Range: public ZoneObject {
210 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000211 Range()
212 : lower_(kMinInt),
213 upper_(kMaxInt),
214 next_(NULL),
215 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216
217 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000218 : lower_(lower),
219 upper_(upper),
220 next_(NULL),
221 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000223 int32_t upper() const { return upper_; }
224 int32_t lower() const { return lower_; }
225 Range* next() const { return next_; }
226 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
227 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 int32_t Mask() const;
230 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
231 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
232 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
233 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000234 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
235 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
236 bool IsInSmiRange() const {
237 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000239 void KeepOrder();
240 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000241
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000242 void StackUpon(Range* other) {
243 Intersect(other);
244 next_ = other;
245 }
246
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 void Intersect(Range* other);
248 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000249
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000250 void AddConstant(int32_t value);
251 void Sar(int32_t value);
252 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000253 bool AddAndCheckOverflow(Range* other);
254 bool SubAndCheckOverflow(Range* other);
255 bool MulAndCheckOverflow(Range* other);
256
257 private:
258 int32_t lower_;
259 int32_t upper_;
260 Range* next_;
261 bool can_be_minus_zero_;
262};
263
264
265class Representation {
266 public:
267 enum Kind {
268 kNone,
269 kTagged,
270 kDouble,
271 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000272 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 kNumRepresentations
274 };
275
276 Representation() : kind_(kNone) { }
277
278 static Representation None() { return Representation(kNone); }
279 static Representation Tagged() { return Representation(kTagged); }
280 static Representation Integer32() { return Representation(kInteger32); }
281 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000282 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000284 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000285 return kind_ == other.kind_;
286 }
287
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000288 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000289 bool IsNone() const { return kind_ == kNone; }
290 bool IsTagged() const { return kind_ == kTagged; }
291 bool IsInteger32() const { return kind_ == kInteger32; }
292 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000293 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000294 bool IsSpecialization() const {
295 return kind_ == kInteger32 || kind_ == kDouble;
296 }
297 const char* Mnemonic() const;
298
299 private:
300 explicit Representation(Kind k) : kind_(k) { }
301
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000302 // Make sure kind fits in int8.
303 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
304
305 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000306};
307
308
309class HType {
310 public:
311 HType() : type_(kUninitialized) { }
312
313 static HType Tagged() { return HType(kTagged); }
314 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
315 static HType TaggedNumber() { return HType(kTaggedNumber); }
316 static HType Smi() { return HType(kSmi); }
317 static HType HeapNumber() { return HType(kHeapNumber); }
318 static HType String() { return HType(kString); }
319 static HType Boolean() { return HType(kBoolean); }
320 static HType NonPrimitive() { return HType(kNonPrimitive); }
321 static HType JSArray() { return HType(kJSArray); }
322 static HType JSObject() { return HType(kJSObject); }
323 static HType Uninitialized() { return HType(kUninitialized); }
324
325 // Return the weakest (least precise) common type.
326 HType Combine(HType other) {
327 return HType(static_cast<Type>(type_ & other.type_));
328 }
329
330 bool Equals(const HType& other) {
331 return type_ == other.type_;
332 }
333
334 bool IsSubtypeOf(const HType& other) {
335 return Combine(other).Equals(other);
336 }
337
338 bool IsTagged() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kTagged) == kTagged);
341 }
342
343 bool IsTaggedPrimitive() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
346 }
347
348 bool IsTaggedNumber() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kTaggedNumber) == kTaggedNumber);
351 }
352
353 bool IsSmi() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kSmi) == kSmi);
356 }
357
358 bool IsHeapNumber() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kHeapNumber) == kHeapNumber);
361 }
362
363 bool IsString() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kString) == kString);
366 }
367
368 bool IsBoolean() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kBoolean) == kBoolean);
371 }
372
373 bool IsNonPrimitive() {
374 ASSERT(type_ != kUninitialized);
375 return ((type_ & kNonPrimitive) == kNonPrimitive);
376 }
377
378 bool IsJSArray() {
379 ASSERT(type_ != kUninitialized);
380 return ((type_ & kJSArray) == kJSArray);
381 }
382
383 bool IsJSObject() {
384 ASSERT(type_ != kUninitialized);
385 return ((type_ & kJSObject) == kJSObject);
386 }
387
388 bool IsUninitialized() {
389 return type_ == kUninitialized;
390 }
391
392 static HType TypeFromValue(Handle<Object> value);
393
394 const char* ToString();
395 const char* ToShortString();
396
397 private:
398 enum Type {
399 kTagged = 0x1, // 0000 0000 0000 0001
400 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
401 kTaggedNumber = 0xd, // 0000 0000 0000 1101
402 kSmi = 0x1d, // 0000 0000 0001 1101
403 kHeapNumber = 0x2d, // 0000 0000 0010 1101
404 kString = 0x45, // 0000 0000 0100 0101
405 kBoolean = 0x85, // 0000 0000 1000 0101
406 kNonPrimitive = 0x101, // 0000 0001 0000 0001
407 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000408 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000409 kUninitialized = 0x1fff // 0001 1111 1111 1111
410 };
411
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000412 // Make sure type fits in int16.
413 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
414
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000415 explicit HType(Type t) : type_(t) { }
416
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000417 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000418};
419
420
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000421class HUseListNode: public ZoneObject {
422 public:
423 HUseListNode(HValue* value, int index, HUseListNode* tail)
424 : tail_(tail), value_(value), index_(index) {
425 }
426
427 HUseListNode* tail() const { return tail_; }
428 HValue* value() const { return value_; }
429 int index() const { return index_; }
430
431 void set_tail(HUseListNode* list) { tail_ = list; }
432
433#ifdef DEBUG
434 void Zap() {
435 tail_ = reinterpret_cast<HUseListNode*>(1);
436 value_ = NULL;
437 index_ = -1;
438 }
439#endif
440
441 private:
442 HUseListNode* tail_;
443 HValue* value_;
444 int index_;
445};
446
447
448// We reuse use list nodes behind the scenes as uses are added and deleted.
449// This class is the safe way to iterate uses while deleting them.
450class HUseIterator BASE_EMBEDDED {
451 public:
452 bool Done() { return current_ == NULL; }
453 void Advance();
454
455 HValue* value() {
456 ASSERT(!Done());
457 return value_;
458 }
459
460 int index() {
461 ASSERT(!Done());
462 return index_;
463 }
464
465 private:
466 explicit HUseIterator(HUseListNode* head);
467
468 HUseListNode* current_;
469 HUseListNode* next_;
470 HValue* value_;
471 int index_;
472
473 friend class HValue;
474};
475
476
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000477class HValue: public ZoneObject {
478 public:
479 static const int kNoNumber = -1;
480
481 // There must be one corresponding kDepends flag for every kChanges flag and
482 // the order of the kChanges flags must be exactly the same as of the kDepends
483 // flags.
484 enum Flag {
485 // Declare global value numbering flags.
486 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
487 GVN_FLAG_LIST(DECLARE_DO)
488 #undef DECLARE_DO
489 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000490 // Participate in Global Value Numbering, i.e. elimination of
491 // unnecessary recomputations. If an instruction sets this flag, it must
492 // implement DataEquals(), which will be used to determine if other
493 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000494 kUseGVN,
495 kCanOverflow,
496 kBailoutOnMinusZero,
497 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000498 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000499 kIsArguments,
500 kTruncatingToInt32,
501 kLastFlag = kTruncatingToInt32
502 };
503
504 STATIC_ASSERT(kLastFlag < kBitsPerInt);
505
506 static const int kChangesToDependsFlagsLeftShift = 1;
507
508 static int ChangesFlagsMask() {
509 int result = 0;
510 // Create changes mask.
511#define DECLARE_DO(type) result |= (1 << kChanges##type);
512 GVN_FLAG_LIST(DECLARE_DO)
513#undef DECLARE_DO
514 return result;
515 }
516
517 static int DependsFlagsMask() {
518 return ConvertChangesToDependsFlags(ChangesFlagsMask());
519 }
520
521 static int ConvertChangesToDependsFlags(int flags) {
522 return flags << kChangesToDependsFlagsLeftShift;
523 }
524
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000525 static HValue* cast(HValue* value) { return value; }
526
527 enum Opcode {
528 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000529 #define DECLARE_OPCODE(type) k##type,
530 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
531 kPhi
532 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000534 virtual Opcode opcode() const = 0;
535
536 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
537 #define DECLARE_PREDICATE(type) \
538 bool Is##type() const { return opcode() == k##type; }
539 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
540 #undef DECLARE_PREDICATE
541 bool IsPhi() const { return opcode() == kPhi; }
542
543 // Declare virtual predicates for abstract HInstruction or HValue
544 #define DECLARE_PREDICATE(type) \
545 virtual bool Is##type() const { return false; }
546 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
547 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000548
549 HValue() : block_(NULL),
550 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000552 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553 range_(NULL),
554 flags_(0) {}
555 virtual ~HValue() {}
556
557 HBasicBlock* block() const { return block_; }
558 void SetBlock(HBasicBlock* block);
559
560 int id() const { return id_; }
561 void set_id(int id) { id_ = id; }
562
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000563 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000565 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566 Representation representation() const { return representation_; }
567 void ChangeRepresentation(Representation r) {
568 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569 ASSERT(!r.IsNone());
570 ASSERT(CheckFlag(kFlexibleRepresentation));
571 RepresentationChanged(r);
572 representation_ = r;
573 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000574 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000575
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000576 virtual bool IsConvertibleToInteger() const { return true; }
577
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578 HType type() const { return type_; }
579 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000580 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581 type_ = type;
582 }
583
584 // An operation needs to override this function iff:
585 // 1) it can produce an int32 output.
586 // 2) the true value of its output can potentially be minus zero.
587 // The implementation must set a flag so that it bails out in the case where
588 // it would otherwise output what should be a minus zero as an int32 zero.
589 // If the operation also exists in a form that takes int32 and outputs int32
590 // then the operation should return its input value so that we can propagate
591 // back. There are two operations that need to propagate back to more than
592 // one input. They are phi and binary add. They always return NULL and
593 // expect the caller to take care of things.
594 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
595 visited->Add(id());
596 return NULL;
597 }
598
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599 bool IsDefinedAfter(HBasicBlock* other) const;
600
601 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000602 virtual int OperandCount() = 0;
603 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000604 void SetOperandAt(int index, HValue* value);
605
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000606 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000607 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000608 bool HasNoUses() const { return use_list_ == NULL; }
609 bool HasMultipleUses() const {
610 return use_list_ != NULL && use_list_->tail() != NULL;
611 }
612 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000613 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000614
615 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000616 void SetFlag(Flag f) { flags_ |= (1 << f); }
617 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
618 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
619
620 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
621 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
622 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000623
624 Range* range() const { return range_; }
625 bool HasRange() const { return range_ != NULL; }
626 void AddNewRange(Range* r);
627 void RemoveLastAddedRange();
628 void ComputeInitialRange();
629
630 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000631 virtual Representation RequiredInputRepresentation(int index) const = 0;
632
633 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000634 return representation();
635 }
636
637 // This gives the instruction an opportunity to replace itself with an
638 // instruction that does the same in some better way. To replace an
639 // instruction with a new one, first add the new instruction to the graph,
640 // then return it. Return NULL to have the instruction deleted.
641 virtual HValue* Canonicalize() { return this; }
642
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000643 bool Equals(HValue* other);
644 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645
646 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000647 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000649 void PrintTypeTo(StringStream* stream);
650 void PrintRangeTo(StringStream* stream);
651 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000653 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654
655 // Updated the inferred type of this instruction and returns true if
656 // it has changed.
657 bool UpdateInferredType();
658
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000659 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000661#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000662 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663#endif
664
665 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000666 // This function must be overridden for instructions with flag kUseGVN, to
667 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000668 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000669 UNREACHABLE();
670 return false;
671 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000672 virtual void RepresentationChanged(Representation to) { }
673 virtual Range* InferRange();
674 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000675 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000676 void clear_block() {
677 ASSERT(block_ != NULL);
678 block_ = NULL;
679 }
680
681 void set_representation(Representation r) {
682 // Representation is set-once.
683 ASSERT(representation_.IsNone() && !r.IsNone());
684 representation_ = r;
685 }
686
687 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000688 // A flag mask to mark an instruction as having arbitrary side effects.
689 static int AllSideEffects() {
690 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
691 }
692
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000693 // Remove the matching use from the use list if present. Returns the
694 // removed list node or NULL.
695 HUseListNode* RemoveUse(HValue* value, int index);
696
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000697 void RegisterUse(int index, HValue* new_value);
698
699 HBasicBlock* block_;
700
701 // The id of this instruction in the hydrogen graph, assigned when first
702 // added to the graph. Reflects creation order.
703 int id_;
704
705 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000706 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000707 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000708 Range* range_;
709 int flags_;
710
711 DISALLOW_COPY_AND_ASSIGN(HValue);
712};
713
714
715class HInstruction: public HValue {
716 public:
717 HInstruction* next() const { return next_; }
718 HInstruction* previous() const { return previous_; }
719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000720 virtual void PrintTo(StringStream* stream);
721 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000722
723 bool IsLinked() const { return block() != NULL; }
724 void Unlink();
725 void InsertBefore(HInstruction* next);
726 void InsertAfter(HInstruction* previous);
727
728 int position() const { return position_; }
729 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
730 void set_position(int position) { position_ = position; }
731
732 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
733
734#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000735 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000736#endif
737
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000738 virtual bool IsCall() { return false; }
739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000740 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000741
742 protected:
743 HInstruction()
744 : next_(NULL),
745 previous_(NULL),
746 position_(RelocInfo::kNoPosition) {
747 SetFlag(kDependsOnOsrEntries);
748 }
749
750 virtual void DeleteFromGraph() { Unlink(); }
751
752 private:
753 void InitializeAsFirst(HBasicBlock* block) {
754 ASSERT(!IsLinked());
755 SetBlock(block);
756 }
757
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000758 void PrintMnemonicTo(StringStream* stream);
759
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000760 HInstruction* next_;
761 HInstruction* previous_;
762 int position_;
763
764 friend class HBasicBlock;
765};
766
767
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000768template<int V>
769class HTemplateInstruction : public HInstruction {
770 public:
771 int OperandCount() { return V; }
772 HValue* OperandAt(int i) { return inputs_[i]; }
773
774 protected:
775 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
776
777 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000778 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000779};
780
781
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000782class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000783 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000784 virtual HBasicBlock* SuccessorAt(int i) = 0;
785 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000786 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000787
788 virtual void PrintDataTo(StringStream* stream);
789
790 HBasicBlock* FirstSuccessor() {
791 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
792 }
793 HBasicBlock* SecondSuccessor() {
794 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
795 }
796
797 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
798};
799
800
801class HSuccessorIterator BASE_EMBEDDED {
802 public:
803 explicit HSuccessorIterator(HControlInstruction* instr)
804 : instr_(instr), current_(0) { }
805
806 bool Done() { return current_ >= instr_->SuccessorCount(); }
807 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
808 void Advance() { current_++; }
809
810 private:
811 HControlInstruction* instr_;
812 int current_;
813};
814
815
816template<int S, int V>
817class HTemplateControlInstruction: public HControlInstruction {
818 public:
819 int SuccessorCount() { return S; }
820 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000821 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000822
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000823 int OperandCount() { return V; }
824 HValue* OperandAt(int i) { return inputs_[i]; }
825
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000827 protected:
828 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
829
830 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000831 EmbeddedContainer<HBasicBlock*, S> successors_;
832 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000833};
834
835
836class HBlockEntry: public HTemplateInstruction<0> {
837 public:
838 virtual Representation RequiredInputRepresentation(int index) const {
839 return Representation::None();
840 }
841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000842 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000843};
844
845
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000846// We insert soft-deoptimize when we hit code with unknown typefeedback,
847// so that we get a chance of re-optimizing with useful typefeedback.
848// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
849class HSoftDeoptimize: public HTemplateInstruction<0> {
850 public:
851 virtual Representation RequiredInputRepresentation(int index) const {
852 return Representation::None();
853 }
854
855 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
856};
857
858
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000859class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000860 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000861 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000862
863 virtual Representation RequiredInputRepresentation(int index) const {
864 return Representation::None();
865 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000866
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000867 virtual int OperandCount() { return values_.length(); }
868 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000869 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000871 virtual int SuccessorCount() { return 0; }
872 virtual HBasicBlock* SuccessorAt(int i) {
873 UNREACHABLE();
874 return NULL;
875 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000876 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
877 UNREACHABLE();
878 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000879
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000880 void AddEnvironmentValue(HValue* value) {
881 values_.Add(NULL);
882 SetOperandAt(values_.length() - 1, value);
883 }
884
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000885 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000887 enum UseEnvironment {
888 kNoUses,
889 kUseAll
890 };
891
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000892 protected:
893 virtual void InternalSetOperandAt(int index, HValue* value) {
894 values_[index] = value;
895 }
896
897 private:
898 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899};
900
901
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000902class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000904 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000905 SetSuccessorAt(0, target);
906 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000908 virtual Representation RequiredInputRepresentation(int index) const {
909 return Representation::None();
910 }
911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000912 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913};
914
915
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000916class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918 HUnaryControlInstruction(HValue* value,
919 HBasicBlock* true_target,
920 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000922 SetSuccessorAt(0, true_target);
923 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000924 }
925
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000926 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000928 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000929};
930
931
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000932class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000933 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000934 HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000935 : HUnaryControlInstruction(value, true_target, false_target) {
936 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000937 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000938 explicit HBranch(HValue* value)
939 : HUnaryControlInstruction(value, NULL, NULL) { }
940
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941
942 virtual Representation RequiredInputRepresentation(int index) const {
943 return Representation::None();
944 }
945
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000946 DECLARE_CONCRETE_INSTRUCTION(Branch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947};
948
949
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000950class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000951 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000952 HCompareMap(HValue* value,
953 Handle<Map> map,
954 HBasicBlock* true_target,
955 HBasicBlock* false_target)
956 : HUnaryControlInstruction(value, true_target, false_target),
957 map_(map) {
958 ASSERT(true_target != NULL);
959 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960 ASSERT(!map.is_null());
961 }
962
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000963 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000964
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965 Handle<Map> map() const { return map_; }
966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000967 virtual Representation RequiredInputRepresentation(int index) const {
968 return Representation::Tagged();
969 }
970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000971 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000972
973 private:
974 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000975};
976
977
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000978class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000980 explicit HReturn(HValue* value) {
981 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000982 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000984 virtual Representation RequiredInputRepresentation(int index) const {
985 return Representation::Tagged();
986 }
987
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000988 virtual void PrintDataTo(StringStream* stream);
989
990 HValue* value() { return OperandAt(0); }
991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000992 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000993};
994
995
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000996class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000998 virtual Representation RequiredInputRepresentation(int index) const {
999 return Representation::None();
1000 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001001
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001002 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001003};
1004
1005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001006class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001007 public:
1008 explicit HUnaryOperation(HValue* value) {
1009 SetOperandAt(0, value);
1010 }
1011
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001012 static HUnaryOperation* cast(HValue* value) {
1013 return reinterpret_cast<HUnaryOperation*>(value);
1014 }
1015
1016 virtual bool CanTruncateToInt32() const {
1017 return CheckFlag(kTruncatingToInt32);
1018 }
1019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001020 HValue* value() { return OperandAt(0); }
1021 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022};
1023
1024
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001025class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001026 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001027 HThrow(HValue* context, HValue* value) {
1028 SetOperandAt(0, context);
1029 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001030 SetAllSideEffects();
1031 }
1032
1033 virtual Representation RequiredInputRepresentation(int index) const {
1034 return Representation::Tagged();
1035 }
1036
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001037 HValue* context() { return OperandAt(0); }
1038 HValue* value() { return OperandAt(1); }
1039
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001040 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001041};
1042
1043
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001044class HUseConst: public HUnaryOperation {
1045 public:
1046 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1047
1048 virtual Representation RequiredInputRepresentation(int index) const {
1049 return Representation::None();
1050 }
1051
1052 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1053};
1054
1055
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001056class HForceRepresentation: public HTemplateInstruction<1> {
1057 public:
1058 HForceRepresentation(HValue* value, Representation required_representation) {
1059 SetOperandAt(0, value);
1060 set_representation(required_representation);
1061 }
1062
1063 HValue* value() { return OperandAt(0); }
1064
1065 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1066
1067 virtual Representation RequiredInputRepresentation(int index) const {
1068 return representation(); // Same as the output representation.
1069 }
1070
1071 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1072};
1073
1074
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001075class HChange: public HUnaryOperation {
1076 public:
1077 HChange(HValue* value,
1078 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001079 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001080 bool is_truncating,
1081 bool deoptimize_on_undefined)
1082 : HUnaryOperation(value),
1083 from_(from),
1084 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085 ASSERT(!from.IsNone() && !to.IsNone());
1086 ASSERT(!from.Equals(to));
1087 set_representation(to);
1088 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001089 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001090 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1091 value->range()->IsInSmiRange()) {
1092 set_type(HType::Smi());
1093 }
1094 }
1095
1096 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1097
1098 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001099 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001100 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001101 virtual Representation RequiredInputRepresentation(int index) const {
1102 return from_;
1103 }
1104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001105 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001106
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001107 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108
1109 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001110 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001111 if (!other->IsChange()) return false;
1112 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001113 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001114 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115 }
1116
1117 private:
1118 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001119 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001120};
1121
1122
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001123class HClampToUint8: public HUnaryOperation {
1124 public:
1125 explicit HClampToUint8(HValue* value)
1126 : HUnaryOperation(value),
1127 input_rep_(Representation::None()) {
1128 SetFlag(kFlexibleRepresentation);
1129 set_representation(Representation::Tagged());
1130 SetFlag(kUseGVN);
1131 }
1132
1133 virtual Representation RequiredInputRepresentation(int index) const {
1134 return input_rep_;
1135 }
1136
1137 virtual Representation InferredRepresentation() {
1138 // TODO(danno): Inference on input types should happen separately from
1139 // return representation.
1140 Representation new_rep = value()->representation();
1141 if (input_rep_.IsNone()) {
1142 if (!new_rep.IsNone()) {
1143 input_rep_ = new_rep;
1144 return Representation::Integer32();
1145 } else {
1146 return Representation::None();
1147 }
1148 } else {
1149 return Representation::Integer32();
1150 }
1151 }
1152
1153 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1154
1155 protected:
1156 virtual bool DataEquals(HValue* other) { return true; }
1157
1158 private:
1159 Representation input_rep_;
1160};
1161
1162
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001163class HToInt32: public HUnaryOperation {
1164 public:
1165 explicit HToInt32(HValue* value)
1166 : HUnaryOperation(value) {
1167 set_representation(Representation::Integer32());
1168 SetFlag(kUseGVN);
1169 }
1170
1171 virtual Representation RequiredInputRepresentation(int index) const {
1172 return Representation::None();
1173 }
1174
1175 virtual bool CanTruncateToInt32() const {
1176 return true;
1177 }
1178
1179 virtual HValue* Canonicalize() {
1180 if (value()->representation().IsInteger32()) {
1181 return value();
1182 } else {
1183 return this;
1184 }
1185 }
1186
1187 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1188
1189 protected:
1190 virtual bool DataEquals(HValue* other) { return true; }
1191};
1192
1193
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194class HSimulate: public HInstruction {
1195 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001196 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001197 : ast_id_(ast_id),
1198 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001199 values_(2),
1200 assigned_indexes_(2) {}
1201 virtual ~HSimulate() {}
1202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001204
1205 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1206 int ast_id() const { return ast_id_; }
1207 void set_ast_id(int id) {
1208 ASSERT(!HasAstId());
1209 ast_id_ = id;
1210 }
1211
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001212 int pop_count() const { return pop_count_; }
1213 const ZoneList<HValue*>* values() const { return &values_; }
1214 int GetAssignedIndexAt(int index) const {
1215 ASSERT(HasAssignedIndexAt(index));
1216 return assigned_indexes_[index];
1217 }
1218 bool HasAssignedIndexAt(int index) const {
1219 return assigned_indexes_[index] != kNoIndex;
1220 }
1221 void AddAssignedValue(int index, HValue* value) {
1222 AddValue(index, value);
1223 }
1224 void AddPushedValue(HValue* value) {
1225 AddValue(kNoIndex, value);
1226 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227 virtual int OperandCount() { return values_.length(); }
1228 virtual HValue* OperandAt(int index) { return values_[index]; }
1229
1230 virtual Representation RequiredInputRepresentation(int index) const {
1231 return Representation::None();
1232 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001234 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001235
1236#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001237 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238#endif
1239
1240 protected:
1241 virtual void InternalSetOperandAt(int index, HValue* value) {
1242 values_[index] = value;
1243 }
1244
1245 private:
1246 static const int kNoIndex = -1;
1247 void AddValue(int index, HValue* value) {
1248 assigned_indexes_.Add(index);
1249 // Resize the list of pushed values.
1250 values_.Add(NULL);
1251 // Set the operand through the base method in HValue to make sure that the
1252 // use lists are correctly updated.
1253 SetOperandAt(values_.length() - 1, value);
1254 }
1255 int ast_id_;
1256 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257 ZoneList<HValue*> values_;
1258 ZoneList<int> assigned_indexes_;
1259};
1260
1261
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001262class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001264 enum Type {
1265 kFunctionEntry,
1266 kBackwardsBranch
1267 };
1268
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001269 HStackCheck(HValue* context, Type type) : type_(type) {
1270 SetOperandAt(0, context);
1271 }
1272
1273 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001275 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001276 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001277 }
1278
ager@chromium.org04921a82011-06-27 13:21:41 +00001279 void Eliminate() {
1280 // The stack check eliminator might try to eliminate the same stack
1281 // check instruction multiple times.
1282 if (IsLinked()) {
1283 DeleteFromGraph();
1284 }
1285 }
1286
1287 bool is_function_entry() { return type_ == kFunctionEntry; }
1288 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1289
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001290 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001291
1292 private:
1293 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294};
1295
1296
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001297class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001298 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001299 HEnterInlined(Handle<JSFunction> closure,
1300 FunctionLiteral* function,
1301 CallKind call_kind)
1302 : closure_(closure),
1303 function_(function),
1304 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305 }
1306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308
1309 Handle<JSFunction> closure() const { return closure_; }
1310 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001311 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001313 virtual Representation RequiredInputRepresentation(int index) const {
1314 return Representation::None();
1315 }
1316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001317 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318
1319 private:
1320 Handle<JSFunction> closure_;
1321 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001322 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323};
1324
1325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327 public:
1328 HLeaveInlined() {}
1329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001330 virtual Representation RequiredInputRepresentation(int index) const {
1331 return Representation::None();
1332 }
1333
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001334 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335};
1336
1337
1338class HPushArgument: public HUnaryOperation {
1339 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001340 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1341 set_representation(Representation::Tagged());
1342 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343
1344 virtual Representation RequiredInputRepresentation(int index) const {
1345 return Representation::Tagged();
1346 }
1347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001348 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001349
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001350 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001351};
1352
1353
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001354class HThisFunction: public HTemplateInstruction<0> {
1355 public:
1356 HThisFunction() {
1357 set_representation(Representation::Tagged());
1358 SetFlag(kUseGVN);
1359 }
1360
1361 virtual Representation RequiredInputRepresentation(int index) const {
1362 return Representation::None();
1363 }
1364
1365 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1366
1367 protected:
1368 virtual bool DataEquals(HValue* other) { return true; }
1369};
1370
1371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001374 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001375 set_representation(Representation::Tagged());
1376 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001377 }
1378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001379 virtual Representation RequiredInputRepresentation(int index) const {
1380 return Representation::None();
1381 }
1382
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001383 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001384
1385 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001386 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001387};
1388
1389
1390class HOuterContext: public HUnaryOperation {
1391 public:
1392 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1393 set_representation(Representation::Tagged());
1394 SetFlag(kUseGVN);
1395 }
1396
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001397 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001398
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001399 virtual Representation RequiredInputRepresentation(int index) const {
1400 return Representation::Tagged();
1401 }
1402
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001403 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001405};
1406
1407
1408class HGlobalObject: public HUnaryOperation {
1409 public:
1410 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1411 set_representation(Representation::Tagged());
1412 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413 }
1414
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001415 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001417 virtual Representation RequiredInputRepresentation(int index) const {
1418 return Representation::Tagged();
1419 }
1420
ager@chromium.org378b34e2011-01-28 08:04:38 +00001421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001422 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423};
1424
1425
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001426class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001428 explicit HGlobalReceiver(HValue* global_object)
1429 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430 set_representation(Representation::Tagged());
1431 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432 }
1433
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001434 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001436 virtual Representation RequiredInputRepresentation(int index) const {
1437 return Representation::Tagged();
1438 }
1439
ager@chromium.org378b34e2011-01-28 08:04:38 +00001440 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001442};
1443
1444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445template <int V>
1446class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001447 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001449 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1450 this->set_representation(Representation::Tagged());
1451 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001452 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001454 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001455
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001456 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001459
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001460 private:
1461 int argument_count_;
1462};
1463
1464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001466 public:
1467 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001468 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001469 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001470 }
1471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001472 virtual Representation RequiredInputRepresentation(int index) const {
1473 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001474 }
1475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476 virtual void PrintDataTo(StringStream* stream);
1477
1478 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001479};
1480
1481
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001482class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001483 public:
1484 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001485 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001486 SetOperandAt(0, first);
1487 SetOperandAt(1, second);
1488 }
1489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001490 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001492 virtual Representation RequiredInputRepresentation(int index) const {
1493 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001494 }
1495
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001496 HValue* first() { return OperandAt(0); }
1497 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498};
1499
1500
danno@chromium.org160a7b02011-04-18 15:51:38 +00001501class HInvokeFunction: public HBinaryCall {
1502 public:
1503 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1504 : HBinaryCall(context, function, argument_count) {
1505 }
1506
1507 virtual Representation RequiredInputRepresentation(int index) const {
1508 return Representation::Tagged();
1509 }
1510
1511 HValue* context() { return first(); }
1512 HValue* function() { return second(); }
1513
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001514 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001515};
1516
1517
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001518class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519 public:
1520 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001521 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522
1523 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001524
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001525 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001526 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001527 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 }
1529
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001530 virtual void PrintDataTo(StringStream* stream);
1531
1532 virtual Representation RequiredInputRepresentation(int index) const {
1533 return Representation::None();
1534 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001536 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537
1538 private:
1539 Handle<JSFunction> function_;
1540};
1541
1542
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001543class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001544 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001545 HCallKeyed(HValue* context, HValue* key, int argument_count)
1546 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547 }
1548
1549 virtual Representation RequiredInputRepresentation(int index) const {
1550 return Representation::Tagged();
1551 }
1552
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001553 HValue* context() { return first(); }
1554 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001556 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001557};
1558
1559
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001560class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001562 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1563 : HUnaryCall(context, argument_count), name_(name) {
1564 }
1565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001566 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001567
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001568 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001569 Handle<String> name() const { return name_; }
1570
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001571 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001573 virtual Representation RequiredInputRepresentation(int index) const {
1574 return Representation::Tagged();
1575 }
1576
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577 private:
1578 Handle<String> name_;
1579};
1580
1581
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001582class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001583 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001584 HCallFunction(HValue* context, int argument_count)
1585 : HUnaryCall(context, argument_count) {
1586 }
1587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001588 HValue* context() { return value(); }
1589
1590 virtual Representation RequiredInputRepresentation(int index) const {
1591 return Representation::Tagged();
1592 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001594 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595};
1596
1597
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001598class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001600 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1601 : HUnaryCall(context, argument_count), name_(name) {
1602 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001604 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001606 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607 Handle<String> name() const { return name_; }
1608
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001609 virtual Representation RequiredInputRepresentation(int index) const {
1610 return Representation::Tagged();
1611 }
1612
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001613 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614
1615 private:
1616 Handle<String> name_;
1617};
1618
1619
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001620class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001622 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001625 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001626
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001627 Handle<JSFunction> target() const { return target_; }
1628
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001629 virtual Representation RequiredInputRepresentation(int index) const {
1630 return Representation::None();
1631 }
1632
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001633 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634
1635 private:
1636 Handle<JSFunction> target_;
1637};
1638
1639
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001640class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001641 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001642 HCallNew(HValue* context, HValue* constructor, int argument_count)
1643 : HBinaryCall(context, constructor, argument_count) {
1644 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001645
1646 virtual Representation RequiredInputRepresentation(int index) const {
1647 return Representation::Tagged();
1648 }
1649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001650 HValue* context() { return first(); }
1651 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001653 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654};
1655
1656
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001657class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001658 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001659 HCallRuntime(HValue* context,
1660 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001661 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001662 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001663 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1664 SetOperandAt(0, context);
1665 }
1666
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001667 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001668
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001669 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001670 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671 Handle<String> name() const { return name_; }
1672
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001673 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001674 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001675 }
1676
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001677 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001678
1679 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001680 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001681 Handle<String> name_;
1682};
1683
1684
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001685class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001687 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001688 // The length of an array is stored as a tagged value in the array
1689 // object. It is guaranteed to be 32 bit integer, but it can be
1690 // represented as either a smi or heap number.
1691 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001692 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001693 SetFlag(kDependsOnArrayLengths);
1694 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695 }
1696
1697 virtual Representation RequiredInputRepresentation(int index) const {
1698 return Representation::Tagged();
1699 }
1700
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001701 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001702
1703 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001704 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001705};
1706
1707
1708class HFixedArrayLength: public HUnaryOperation {
1709 public:
1710 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1711 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001712 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001713 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001714 }
1715
1716 virtual Representation RequiredInputRepresentation(int index) const {
1717 return Representation::Tagged();
1718 }
1719
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001720 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001721
1722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001723 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001724};
1725
1726
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001727class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001728 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001729 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001730 set_representation(Representation::Integer32());
1731 // The result of this instruction is idempotent as long as its inputs don't
1732 // change. The length of a pixel array cannot change once set, so it's not
1733 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1734 SetFlag(kUseGVN);
1735 }
1736
1737 virtual Representation RequiredInputRepresentation(int index) const {
1738 return Representation::Tagged();
1739 }
1740
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001741 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001742
1743 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001744 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001745};
1746
1747
whesse@chromium.org7b260152011-06-20 15:33:18 +00001748class HElementsKind: public HUnaryOperation {
1749 public:
1750 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1751 set_representation(Representation::Integer32());
1752 SetFlag(kUseGVN);
1753 SetFlag(kDependsOnMaps);
1754 }
1755
1756 virtual Representation RequiredInputRepresentation(int index) const {
1757 return Representation::Tagged();
1758 }
1759
1760 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1761
1762 protected:
1763 virtual bool DataEquals(HValue* other) { return true; }
1764};
1765
1766
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767class HBitNot: public HUnaryOperation {
1768 public:
1769 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1770 set_representation(Representation::Integer32());
1771 SetFlag(kUseGVN);
1772 SetFlag(kTruncatingToInt32);
1773 }
1774
1775 virtual Representation RequiredInputRepresentation(int index) const {
1776 return Representation::Integer32();
1777 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001778 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001779
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001780 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001781
1782 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001783 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001784};
1785
1786
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001787class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001789 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1790 : op_(op) {
1791 SetOperandAt(0, context);
1792 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793 switch (op) {
1794 case kMathFloor:
1795 case kMathRound:
1796 case kMathCeil:
1797 set_representation(Representation::Integer32());
1798 break;
1799 case kMathAbs:
1800 set_representation(Representation::Tagged());
1801 SetFlag(kFlexibleRepresentation);
1802 break;
1803 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001804 case kMathPowHalf:
1805 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001806 case kMathSin:
1807 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001808 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001809 break;
1810 default:
1811 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001812 }
1813 SetFlag(kUseGVN);
1814 }
1815
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001816 HValue* context() { return OperandAt(0); }
1817 HValue* value() { return OperandAt(1); }
1818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001819 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001820
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001821 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001822
1823 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1824
1825 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001826 if (index == 0) {
1827 return Representation::Tagged();
1828 } else {
1829 switch (op_) {
1830 case kMathFloor:
1831 case kMathRound:
1832 case kMathCeil:
1833 case kMathSqrt:
1834 case kMathPowHalf:
1835 case kMathLog:
1836 case kMathSin:
1837 case kMathCos:
1838 return Representation::Double();
1839 case kMathAbs:
1840 return representation();
1841 default:
1842 UNREACHABLE();
1843 return Representation::None();
1844 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001845 }
1846 }
1847
1848 virtual HValue* Canonicalize() {
1849 // If the input is integer32 then we replace the floor instruction
1850 // with its inputs. This happens before the representation changes are
1851 // introduced.
1852 if (op() == kMathFloor) {
1853 if (value()->representation().IsInteger32()) return value();
1854 }
1855 return this;
1856 }
1857
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001858 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001859 const char* OpName() const;
1860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001861 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001863 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001864 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001865 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1866 return op_ == b->op();
1867 }
1868
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001870 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001871};
1872
1873
1874class HLoadElements: public HUnaryOperation {
1875 public:
1876 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1877 set_representation(Representation::Tagged());
1878 SetFlag(kUseGVN);
1879 SetFlag(kDependsOnMaps);
1880 }
1881
1882 virtual Representation RequiredInputRepresentation(int index) const {
1883 return Representation::Tagged();
1884 }
1885
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001886 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001887
1888 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001889 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001890};
1891
1892
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001893class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001894 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001895 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001896 : HUnaryOperation(value) {
1897 set_representation(Representation::External());
1898 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001899 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001900 // change once set, so it's no necessary to introduce any additional
1901 // dependencies on top of the inputs.
1902 SetFlag(kUseGVN);
1903 }
1904
1905 virtual Representation RequiredInputRepresentation(int index) const {
1906 return Representation::Tagged();
1907 }
1908
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001909 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001910
1911 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001912 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001913};
1914
1915
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916class HCheckMap: public HUnaryOperation {
1917 public:
1918 HCheckMap(HValue* value, Handle<Map> map)
1919 : HUnaryOperation(value), map_(map) {
1920 set_representation(Representation::Tagged());
1921 SetFlag(kUseGVN);
1922 SetFlag(kDependsOnMaps);
1923 }
1924
1925 virtual Representation RequiredInputRepresentation(int index) const {
1926 return Representation::Tagged();
1927 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001928 virtual void PrintDataTo(StringStream* stream);
1929 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930
1931#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001932 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001933#endif
1934
1935 Handle<Map> map() const { return map_; }
1936
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001937 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001938
1939 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001940 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001941 HCheckMap* b = HCheckMap::cast(other);
1942 return map_.is_identical_to(b->map());
1943 }
1944
1945 private:
1946 Handle<Map> map_;
1947};
1948
1949
1950class HCheckFunction: public HUnaryOperation {
1951 public:
1952 HCheckFunction(HValue* value, Handle<JSFunction> function)
1953 : HUnaryOperation(value), target_(function) {
1954 set_representation(Representation::Tagged());
1955 SetFlag(kUseGVN);
1956 }
1957
1958 virtual Representation RequiredInputRepresentation(int index) const {
1959 return Representation::Tagged();
1960 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001961 virtual void PrintDataTo(StringStream* stream);
1962 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963
1964#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001965 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966#endif
1967
1968 Handle<JSFunction> target() const { return target_; }
1969
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001970 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971
1972 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001973 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974 HCheckFunction* b = HCheckFunction::cast(other);
1975 return target_.is_identical_to(b->target());
1976 }
1977
1978 private:
1979 Handle<JSFunction> target_;
1980};
1981
1982
1983class HCheckInstanceType: public HUnaryOperation {
1984 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001985 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1986 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001987 }
1988 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1989 return new HCheckInstanceType(value, IS_JS_ARRAY);
1990 }
1991 static HCheckInstanceType* NewIsString(HValue* value) {
1992 return new HCheckInstanceType(value, IS_STRING);
1993 }
1994 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1995 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996 }
1997
1998 virtual Representation RequiredInputRepresentation(int index) const {
1999 return Representation::Tagged();
2000 }
2001
2002#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002003 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002004#endif
2005
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002006 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002007
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002008 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2009 void GetCheckInterval(InstanceType* first, InstanceType* last);
2010 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002011
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002012 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013
2014 protected:
2015 // TODO(ager): It could be nice to allow the ommision of instance
2016 // type checks if we have already performed an instance type check
2017 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002018 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002019 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002020 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002021 }
2022
2023 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002024 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002025 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002026 IS_JS_ARRAY,
2027 IS_STRING,
2028 IS_SYMBOL,
2029 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2030 };
2031
2032 HCheckInstanceType(HValue* value, Check check)
2033 : HUnaryOperation(value), check_(check) {
2034 set_representation(Representation::Tagged());
2035 SetFlag(kUseGVN);
2036 }
2037
2038 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002039};
2040
2041
2042class HCheckNonSmi: public HUnaryOperation {
2043 public:
2044 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2045 set_representation(Representation::Tagged());
2046 SetFlag(kUseGVN);
2047 }
2048
2049 virtual Representation RequiredInputRepresentation(int index) const {
2050 return Representation::Tagged();
2051 }
2052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002053 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054
2055#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002056 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057#endif
2058
danno@chromium.org160a7b02011-04-18 15:51:38 +00002059 virtual HValue* Canonicalize() {
2060 HType value_type = value()->type();
2061 if (!value_type.IsUninitialized() &&
2062 (value_type.IsHeapNumber() ||
2063 value_type.IsString() ||
2064 value_type.IsBoolean() ||
2065 value_type.IsNonPrimitive())) {
2066 return NULL;
2067 }
2068 return this;
2069 }
2070
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002071 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002072
2073 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002074 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002075};
2076
2077
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002078class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002079 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002080 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2081 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082 SetFlag(kUseGVN);
2083 SetFlag(kDependsOnMaps);
2084 }
2085
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002086#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002087 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088#endif
2089
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002090 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002093 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002094
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002095 virtual Representation RequiredInputRepresentation(int index) const {
2096 return Representation::None();
2097 }
2098
2099 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002100 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002101 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2102 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2103 return hash;
2104 }
2105
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002107 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002108 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002109 return prototype_.is_identical_to(b->prototype()) &&
2110 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111 }
2112
2113 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002114 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116};
2117
2118
2119class HCheckSmi: public HUnaryOperation {
2120 public:
2121 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2122 set_representation(Representation::Tagged());
2123 SetFlag(kUseGVN);
2124 }
2125
2126 virtual Representation RequiredInputRepresentation(int index) const {
2127 return Representation::Tagged();
2128 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002129 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002130
2131#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002132 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002133#endif
2134
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002135 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002136
2137 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002138 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002139};
2140
2141
2142class HPhi: public HValue {
2143 public:
2144 explicit HPhi(int merged_index)
2145 : inputs_(2),
2146 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002147 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002148 is_live_(false),
2149 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002150 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2151 non_phi_uses_[i] = 0;
2152 indirect_uses_[i] = 0;
2153 }
2154 ASSERT(merged_index >= 0);
2155 set_representation(Representation::Tagged());
2156 SetFlag(kFlexibleRepresentation);
2157 }
2158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002159 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160 bool double_occurred = false;
2161 bool int32_occurred = false;
2162 for (int i = 0; i < OperandCount(); ++i) {
2163 HValue* value = OperandAt(i);
2164 if (value->representation().IsDouble()) double_occurred = true;
2165 if (value->representation().IsInteger32()) int32_occurred = true;
2166 if (value->representation().IsTagged()) return Representation::Tagged();
2167 }
2168
2169 if (double_occurred) return Representation::Double();
2170 if (int32_occurred) return Representation::Integer32();
2171 return Representation::None();
2172 }
2173
2174 virtual Range* InferRange();
2175 virtual Representation RequiredInputRepresentation(int index) const {
2176 return representation();
2177 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002178 virtual HType CalculateInferredType();
2179 virtual int OperandCount() { return inputs_.length(); }
2180 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2181 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002182 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002183 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002184
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002185 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002186
2187 int merged_index() const { return merged_index_; }
2188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002189 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002190
2191#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002192 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002193#endif
2194
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195 void InitRealUses(int id);
2196 void AddNonPhiUsesFrom(HPhi* other);
2197 void AddIndirectUsesTo(int* use_count);
2198
2199 int tagged_non_phi_uses() const {
2200 return non_phi_uses_[Representation::kTagged];
2201 }
2202 int int32_non_phi_uses() const {
2203 return non_phi_uses_[Representation::kInteger32];
2204 }
2205 int double_non_phi_uses() const {
2206 return non_phi_uses_[Representation::kDouble];
2207 }
2208 int tagged_indirect_uses() const {
2209 return indirect_uses_[Representation::kTagged];
2210 }
2211 int int32_indirect_uses() const {
2212 return indirect_uses_[Representation::kInteger32];
2213 }
2214 int double_indirect_uses() const {
2215 return indirect_uses_[Representation::kDouble];
2216 }
2217 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002218 bool is_live() { return is_live_; }
2219 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002220
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002221 static HPhi* cast(HValue* value) {
2222 ASSERT(value->IsPhi());
2223 return reinterpret_cast<HPhi*>(value);
2224 }
2225 virtual Opcode opcode() const { return HValue::kPhi; }
2226
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002227 virtual bool IsConvertibleToInteger() const {
2228 return is_convertible_to_integer_;
2229 }
2230
2231 void set_is_convertible_to_integer(bool b) {
2232 is_convertible_to_integer_ = b;
2233 }
2234
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235 protected:
2236 virtual void DeleteFromGraph();
2237 virtual void InternalSetOperandAt(int index, HValue* value) {
2238 inputs_[index] = value;
2239 }
2240
2241 private:
2242 ZoneList<HValue*> inputs_;
2243 int merged_index_;
2244
2245 int non_phi_uses_[Representation::kNumRepresentations];
2246 int indirect_uses_[Representation::kNumRepresentations];
2247 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002248 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002249 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002250};
2251
2252
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002253class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002254 public:
2255 HArgumentsObject() {
2256 set_representation(Representation::Tagged());
2257 SetFlag(kIsArguments);
2258 }
2259
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002260 virtual Representation RequiredInputRepresentation(int index) const {
2261 return Representation::None();
2262 }
2263
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002264 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265};
2266
2267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002268class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002269 public:
2270 HConstant(Handle<Object> handle, Representation r);
2271
2272 Handle<Object> handle() const { return handle_; }
2273
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002274 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002275
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002276 virtual Representation RequiredInputRepresentation(int index) const {
2277 return Representation::None();
2278 }
2279
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002280 virtual bool IsConvertibleToInteger() const {
2281 if (handle_->IsSmi()) return true;
2282 if (handle_->IsHeapNumber() &&
2283 (HeapNumber::cast(*handle_)->value() ==
2284 static_cast<double>(NumberToInt32(*handle_)))) return true;
2285 return false;
2286 }
2287
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002288 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002289 virtual void PrintDataTo(StringStream* stream);
2290 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002291 bool IsInteger() const { return handle_->IsSmi(); }
2292 HConstant* CopyToRepresentation(Representation r) const;
2293 HConstant* CopyToTruncatedInt32() const;
2294 bool HasInteger32Value() const { return has_int32_value_; }
2295 int32_t Integer32Value() const {
2296 ASSERT(HasInteger32Value());
2297 return int32_value_;
2298 }
2299 bool HasDoubleValue() const { return has_double_value_; }
2300 double DoubleValue() const {
2301 ASSERT(HasDoubleValue());
2302 return double_value_;
2303 }
2304 bool HasStringValue() const { return handle_->IsString(); }
2305
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002306 bool ToBoolean() const;
2307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002308 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002309 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310 return reinterpret_cast<intptr_t>(*handle());
2311 }
2312
2313#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002314 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315#endif
2316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002317 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002318
2319 protected:
2320 virtual Range* InferRange();
2321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002322 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002323 HConstant* other_constant = HConstant::cast(other);
2324 return handle().is_identical_to(other_constant->handle());
2325 }
2326
2327 private:
2328 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002329
2330 // The following two values represent the int32 and the double value of the
2331 // given constant if there is a lossless conversion between the constant
2332 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002333 bool has_int32_value_ : 1;
2334 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002335 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336 double double_value_;
2337};
2338
2339
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002340class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002341 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002342 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002344 SetOperandAt(0, context);
2345 SetOperandAt(1, left);
2346 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002347 }
2348
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002349 HValue* context() { return OperandAt(0); }
2350 HValue* left() { return OperandAt(1); }
2351 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002352
2353 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2354 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002356 if (IsCommutative() && left()->IsConstant()) return right();
2357 return left();
2358 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002359 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002360 if (IsCommutative() && left()->IsConstant()) return left();
2361 return right();
2362 }
2363
2364 virtual bool IsCommutative() const { return false; }
2365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002366 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002367};
2368
2369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002370class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002371 public:
2372 HApplyArguments(HValue* function,
2373 HValue* receiver,
2374 HValue* length,
2375 HValue* elements) {
2376 set_representation(Representation::Tagged());
2377 SetOperandAt(0, function);
2378 SetOperandAt(1, receiver);
2379 SetOperandAt(2, length);
2380 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002381 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002382 }
2383
2384 virtual Representation RequiredInputRepresentation(int index) const {
2385 // The length is untagged, all other inputs are tagged.
2386 return (index == 2)
2387 ? Representation::Integer32()
2388 : Representation::Tagged();
2389 }
2390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002391 HValue* function() { return OperandAt(0); }
2392 HValue* receiver() { return OperandAt(1); }
2393 HValue* length() { return OperandAt(2); }
2394 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002395
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002396 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002397};
2398
2399
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002400class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002401 public:
2402 HArgumentsElements() {
2403 // The value produced by this instruction is a pointer into the stack
2404 // that looks as if it was a smi because of alignment.
2405 set_representation(Representation::Tagged());
2406 SetFlag(kUseGVN);
2407 }
2408
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002409 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002411 virtual Representation RequiredInputRepresentation(int index) const {
2412 return Representation::None();
2413 }
2414
ager@chromium.org378b34e2011-01-28 08:04:38 +00002415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002417};
2418
2419
2420class HArgumentsLength: public HUnaryOperation {
2421 public:
2422 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2423 set_representation(Representation::Integer32());
2424 SetFlag(kUseGVN);
2425 }
2426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002427 virtual Representation RequiredInputRepresentation(int index) const {
2428 return Representation::Tagged();
2429 }
2430
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002431 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002432
2433 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002434 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002435};
2436
2437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002438class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002439 public:
2440 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2441 set_representation(Representation::Tagged());
2442 SetFlag(kUseGVN);
2443 SetOperandAt(0, arguments);
2444 SetOperandAt(1, length);
2445 SetOperandAt(2, index);
2446 }
2447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002448 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002449
2450 virtual Representation RequiredInputRepresentation(int index) const {
2451 // The arguments elements is considered tagged.
2452 return index == 0
2453 ? Representation::Tagged()
2454 : Representation::Integer32();
2455 }
2456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002457 HValue* arguments() { return OperandAt(0); }
2458 HValue* length() { return OperandAt(1); }
2459 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002460
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002461 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002463 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002464};
2465
2466
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002467class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002468 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002469 HBoundsCheck(HValue* index, HValue* length) {
2470 SetOperandAt(0, index);
2471 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002472 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002473 SetFlag(kUseGVN);
2474 }
2475
2476 virtual Representation RequiredInputRepresentation(int index) const {
2477 return Representation::Integer32();
2478 }
2479
2480#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002481 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002482#endif
2483
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002484 HValue* index() { return OperandAt(0); }
2485 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002487 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002488
2489 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002490 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002491};
2492
2493
2494class HBitwiseBinaryOperation: public HBinaryOperation {
2495 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002496 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2497 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002498 set_representation(Representation::Tagged());
2499 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002500 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002501 }
2502
2503 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002504 return index == 0
2505 ? Representation::Tagged()
2506 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002507 }
2508
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002509 virtual void RepresentationChanged(Representation to) {
2510 if (!to.IsTagged()) {
2511 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002512 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002513 SetFlag(kTruncatingToInt32);
2514 SetFlag(kUseGVN);
2515 }
2516 }
2517
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002518 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002519
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002520 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521};
2522
2523
2524class HArithmeticBinaryOperation: public HBinaryOperation {
2525 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002526 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2527 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002528 set_representation(Representation::Tagged());
2529 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002530 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531 }
2532
2533 virtual void RepresentationChanged(Representation to) {
2534 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002535 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536 SetFlag(kUseGVN);
2537 }
2538 }
2539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002540 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002541 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002542 return index == 0
2543 ? Representation::Tagged()
2544 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002545 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002547 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 if (left()->representation().Equals(right()->representation())) {
2549 return left()->representation();
2550 }
2551 return HValue::InferredRepresentation();
2552 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553};
2554
2555
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002556class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002557 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002558 HCompareGeneric(HValue* context,
2559 HValue* left,
2560 HValue* right,
2561 Token::Value token)
2562 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002563 ASSERT(Token::IsCompareOp(token));
2564 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002565 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002566 }
2567
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002568 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002569 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002570 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002571
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002572 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002573 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002574 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002575
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002576 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002577 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002579 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002580
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002581 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2582
2583 private:
2584 Token::Value token_;
2585};
2586
2587
2588class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2589 public:
2590 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2591 : token_(token) {
2592 ASSERT(Token::IsCompareOp(token));
2593 SetOperandAt(0, left);
2594 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002595 }
2596
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002597 HValue* left() { return OperandAt(0); }
2598 HValue* right() { return OperandAt(1); }
2599 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002600
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002601 void SetInputRepresentation(Representation r);
2602 Representation GetInputRepresentation() const {
2603 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604 }
2605
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002606 virtual Representation RequiredInputRepresentation(int index) const {
2607 return input_representation_;
2608 }
2609 virtual void PrintDataTo(StringStream* stream);
2610
2611 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2612
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002613 private:
2614 Representation input_representation_;
2615 Token::Value token_;
2616};
2617
2618
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002619class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002621 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2622 SetOperandAt(0, left);
2623 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002624 }
2625
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002626 HValue* left() { return OperandAt(0); }
2627 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002628
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002629 virtual Representation RequiredInputRepresentation(int index) const {
2630 return Representation::Tagged();
2631 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002632
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002633 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002634};
2635
2636
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002637class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002638 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002639 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2640 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002641 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002642 }
2643
2644 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002645 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002646 int right() const { return right_; }
2647
whesse@chromium.org7b260152011-06-20 15:33:18 +00002648 virtual Representation RequiredInputRepresentation(int index) const {
2649 return Representation::Integer32();
2650 }
2651
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002652 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002653
2654 private:
2655 const Token::Value op_;
2656 const int right_;
2657};
2658
2659
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002660class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002661 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002662 HIsNullAndBranch(HValue* value, bool is_strict)
2663 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002664
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002665 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002666
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002667 virtual Representation RequiredInputRepresentation(int index) const {
2668 return Representation::Tagged();
2669 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002670
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002671 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002672
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002673 private:
2674 bool is_strict_;
2675};
2676
2677
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002678class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002679 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002680 explicit HIsObjectAndBranch(HValue* value)
2681 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002682
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002683 virtual Representation RequiredInputRepresentation(int index) const {
2684 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002685 }
2686
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002687 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2688};
2689
2690
2691class HIsSmiAndBranch: public HUnaryControlInstruction {
2692 public:
2693 explicit HIsSmiAndBranch(HValue* value)
2694 : HUnaryControlInstruction(value, NULL, NULL) { }
2695
2696 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2697
2698 virtual Representation RequiredInputRepresentation(int index) const {
2699 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002700 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002701
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002702 protected:
2703 virtual bool DataEquals(HValue* other) { return true; }
2704};
2705
2706
2707class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2708 public:
2709 explicit HIsUndetectableAndBranch(HValue* value)
2710 : HUnaryControlInstruction(value, NULL, NULL) { }
2711
2712 virtual Representation RequiredInputRepresentation(int index) const {
2713 return Representation::Tagged();
2714 }
2715
2716 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2717};
2718
2719
2720class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2721 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002722 virtual Representation RequiredInputRepresentation(int index) const {
2723 return Representation::None();
2724 }
2725
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002726 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002727};
2728
2729
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002730class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002731 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002732 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2733 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2734 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2735 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2737 }
2738
2739 InstanceType from() { return from_; }
2740 InstanceType to() { return to_; }
2741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002742 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002744 virtual Representation RequiredInputRepresentation(int index) const {
2745 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002746 }
2747
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002748 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2749
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750 private:
2751 InstanceType from_;
2752 InstanceType to_; // Inclusive range, not all combinations work.
2753};
2754
2755
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002756class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002758 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2759 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002761 virtual Representation RequiredInputRepresentation(int index) const {
2762 return Representation::Tagged();
2763 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002764
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002765 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766};
2767
2768
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002769class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002770 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002771 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2772 set_representation(Representation::Tagged());
2773 SetFlag(kUseGVN);
2774 }
2775
2776 virtual Representation RequiredInputRepresentation(int index) const {
2777 return Representation::Tagged();
2778 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002779
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002780 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002781
2782 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002783 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002784};
2785
2786
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002787class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002789 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2790 : HUnaryControlInstruction(value, NULL, NULL),
2791 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002793 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2794
2795 virtual Representation RequiredInputRepresentation(int index) const {
2796 return Representation::Tagged();
2797 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002798
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002799 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002800
2801 Handle<String> class_name() const { return class_name_; }
2802
2803 private:
2804 Handle<String> class_name_;
2805};
2806
2807
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002808class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002810 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2811 : HUnaryControlInstruction(value, NULL, NULL),
2812 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813
2814 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002815 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002816
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002817 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002818
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002819 virtual Representation RequiredInputRepresentation(int index) const {
2820 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002821 }
2822
2823 private:
2824 Handle<String> type_literal_;
2825};
2826
2827
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002828class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002829 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002830 HInstanceOf(HValue* context, HValue* left, HValue* right)
2831 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002832 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002833 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002834 }
2835
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836 virtual Representation RequiredInputRepresentation(int index) const {
2837 return Representation::Tagged();
2838 }
2839
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002840 virtual HType CalculateInferredType();
2841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002842 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002844 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002845};
2846
2847
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002848class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002849 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002850 HInstanceOfKnownGlobal(HValue* context,
2851 HValue* left,
2852 Handle<JSFunction> right)
2853 : function_(right) {
2854 SetOperandAt(0, context);
2855 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002856 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002857 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002858 }
2859
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002860 HValue* context() { return OperandAt(0); }
2861 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002862 Handle<JSFunction> function() { return function_; }
2863
2864 virtual Representation RequiredInputRepresentation(int index) const {
2865 return Representation::Tagged();
2866 }
2867
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002868 virtual HType CalculateInferredType();
2869
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002870 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002871
2872 private:
2873 Handle<JSFunction> function_;
2874};
2875
2876
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002877class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002878 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002879 HPower(HValue* left, HValue* right) {
2880 SetOperandAt(0, left);
2881 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002882 set_representation(Representation::Double());
2883 SetFlag(kUseGVN);
2884 }
2885
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002886 HValue* left() { return OperandAt(0); }
2887 HValue* right() { return OperandAt(1); }
2888
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002889 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002890 return index == 0
2891 ? Representation::Double()
2892 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002893 }
2894
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002895 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002896
2897 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002898 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002899};
2900
2901
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902class HAdd: public HArithmeticBinaryOperation {
2903 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002904 HAdd(HValue* context, HValue* left, HValue* right)
2905 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002906 SetFlag(kCanOverflow);
2907 }
2908
2909 // Add is only commutative if two integer values are added and not if two
2910 // tagged values are added (because it might be a String concatenation).
2911 virtual bool IsCommutative() const {
2912 return !representation().IsTagged();
2913 }
2914
2915 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2916
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002917 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002918
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002919 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920
2921 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002922 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002923
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 virtual Range* InferRange();
2925};
2926
2927
2928class HSub: public HArithmeticBinaryOperation {
2929 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002930 HSub(HValue* context, HValue* left, HValue* right)
2931 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932 SetFlag(kCanOverflow);
2933 }
2934
2935 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2936
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002937 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002938
2939 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002940 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002941
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002942 virtual Range* InferRange();
2943};
2944
2945
2946class HMul: public HArithmeticBinaryOperation {
2947 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002948 HMul(HValue* context, HValue* left, HValue* right)
2949 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950 SetFlag(kCanOverflow);
2951 }
2952
2953 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2954
2955 // Only commutative if it is certain that not two objects are multiplicated.
2956 virtual bool IsCommutative() const {
2957 return !representation().IsTagged();
2958 }
2959
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002960 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002961
2962 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002963 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002964
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002965 virtual Range* InferRange();
2966};
2967
2968
2969class HMod: public HArithmeticBinaryOperation {
2970 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002971 HMod(HValue* context, HValue* left, HValue* right)
2972 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002973 SetFlag(kCanBeDivByZero);
2974 }
2975
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002976 bool HasPowerOf2Divisor() {
2977 if (right()->IsConstant() &&
2978 HConstant::cast(right())->HasInteger32Value()) {
2979 int32_t value = HConstant::cast(right())->Integer32Value();
2980 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2981 }
2982
2983 return false;
2984 }
2985
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002986 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2987
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002988 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989
2990 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002991 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002992
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993 virtual Range* InferRange();
2994};
2995
2996
2997class HDiv: public HArithmeticBinaryOperation {
2998 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002999 HDiv(HValue* context, HValue* left, HValue* right)
3000 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001 SetFlag(kCanBeDivByZero);
3002 SetFlag(kCanOverflow);
3003 }
3004
3005 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3006
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003007 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008
3009 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003010 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003011
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012 virtual Range* InferRange();
3013};
3014
3015
3016class HBitAnd: public HBitwiseBinaryOperation {
3017 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003018 HBitAnd(HValue* context, HValue* left, HValue* right)
3019 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003020
3021 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003022 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003024 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025
3026 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003027 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003028
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003029 virtual Range* InferRange();
3030};
3031
3032
3033class HBitXor: public HBitwiseBinaryOperation {
3034 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003035 HBitXor(HValue* context, HValue* left, HValue* right)
3036 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003037
3038 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003039 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003040
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003041 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003042
3043 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003044 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003045};
3046
3047
3048class HBitOr: public HBitwiseBinaryOperation {
3049 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003050 HBitOr(HValue* context, HValue* left, HValue* right)
3051 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003052
3053 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003054 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003055
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003056 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003057
3058 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003059 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061 virtual Range* InferRange();
3062};
3063
3064
3065class HShl: public HBitwiseBinaryOperation {
3066 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003067 HShl(HValue* context, HValue* left, HValue* right)
3068 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003069
3070 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003071 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003073 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003074
3075 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003076 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077};
3078
3079
3080class HShr: public HBitwiseBinaryOperation {
3081 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003082 HShr(HValue* context, HValue* left, HValue* right)
3083 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003084
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003085 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003086
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003087 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003088
3089 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003090 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091};
3092
3093
3094class HSar: public HBitwiseBinaryOperation {
3095 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003096 HSar(HValue* context, HValue* left, HValue* right)
3097 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098
3099 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003100 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003102 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003103
3104 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003105 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003106};
3107
3108
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003109class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 public:
3111 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3112 SetFlag(kChangesOsrEntries);
3113 }
3114
3115 int ast_id() const { return ast_id_; }
3116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003117 virtual Representation RequiredInputRepresentation(int index) const {
3118 return Representation::None();
3119 }
3120
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003121 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122
3123 private:
3124 int ast_id_;
3125};
3126
3127
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003128class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129 public:
3130 explicit HParameter(unsigned index) : index_(index) {
3131 set_representation(Representation::Tagged());
3132 }
3133
3134 unsigned index() const { return index_; }
3135
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003136 virtual void PrintDataTo(StringStream* stream);
3137
3138 virtual Representation RequiredInputRepresentation(int index) const {
3139 return Representation::None();
3140 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003142 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003143
3144 private:
3145 unsigned index_;
3146};
3147
3148
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003149class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003150 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003151 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3152 : HUnaryCall(context, argument_count),
3153 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155 }
3156
3157 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003159 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160
3161 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3162 transcendental_type_ = transcendental_type;
3163 }
3164 TranscendentalCache::Type transcendental_type() {
3165 return transcendental_type_;
3166 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003168 virtual void PrintDataTo(StringStream* stream);
3169
3170 virtual Representation RequiredInputRepresentation(int index) const {
3171 return Representation::Tagged();
3172 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003174 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003175
3176 private:
3177 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178 TranscendentalCache::Type transcendental_type_;
3179};
3180
3181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003182class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003183 public:
3184 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3185
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003186 virtual Representation RequiredInputRepresentation(int index) const {
3187 return Representation::None();
3188 }
3189
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003190 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191};
3192
3193
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003194class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003195 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003196 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197 : cell_(cell), check_hole_value_(check_hole_value) {
3198 set_representation(Representation::Tagged());
3199 SetFlag(kUseGVN);
3200 SetFlag(kDependsOnGlobalVars);
3201 }
3202
3203 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3204 bool check_hole_value() const { return check_hole_value_; }
3205
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003206 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003207
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003208 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003209 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003210 return reinterpret_cast<intptr_t>(*cell_);
3211 }
3212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003213 virtual Representation RequiredInputRepresentation(int index) const {
3214 return Representation::None();
3215 }
3216
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003217 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003218
3219 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003220 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003221 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003222 return cell_.is_identical_to(b->cell());
3223 }
3224
3225 private:
3226 Handle<JSGlobalPropertyCell> cell_;
3227 bool check_hole_value_;
3228};
3229
3230
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003231class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003232 public:
3233 HLoadGlobalGeneric(HValue* context,
3234 HValue* global_object,
3235 Handle<Object> name,
3236 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003237 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003238 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003239 SetOperandAt(0, context);
3240 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003241 set_representation(Representation::Tagged());
3242 SetAllSideEffects();
3243 }
3244
3245 HValue* context() { return OperandAt(0); }
3246 HValue* global_object() { return OperandAt(1); }
3247 Handle<Object> name() const { return name_; }
3248 bool for_typeof() const { return for_typeof_; }
3249
3250 virtual void PrintDataTo(StringStream* stream);
3251
3252 virtual Representation RequiredInputRepresentation(int index) const {
3253 return Representation::Tagged();
3254 }
3255
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003256 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003257
3258 private:
3259 Handle<Object> name_;
3260 bool for_typeof_;
3261};
3262
3263
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003264class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003265 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003266 HStoreGlobalCell(HValue* value,
3267 Handle<JSGlobalPropertyCell> cell,
3268 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003269 : HUnaryOperation(value),
3270 cell_(cell),
3271 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003272 SetFlag(kChangesGlobalVars);
3273 }
3274
3275 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003276 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003277
3278 virtual Representation RequiredInputRepresentation(int index) const {
3279 return Representation::Tagged();
3280 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003281 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003282
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003283 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003284
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003285 private:
3286 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003287 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003288};
3289
3290
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003291class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3292 public:
3293 HStoreGlobalGeneric(HValue* context,
3294 HValue* global_object,
3295 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003296 HValue* value,
3297 bool strict_mode)
3298 : name_(name),
3299 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003300 SetOperandAt(0, context);
3301 SetOperandAt(1, global_object);
3302 SetOperandAt(2, value);
3303 set_representation(Representation::Tagged());
3304 SetAllSideEffects();
3305 }
3306
3307 HValue* context() { return OperandAt(0); }
3308 HValue* global_object() { return OperandAt(1); }
3309 Handle<Object> name() const { return name_; }
3310 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003311 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003312
3313 virtual void PrintDataTo(StringStream* stream);
3314
3315 virtual Representation RequiredInputRepresentation(int index) const {
3316 return Representation::Tagged();
3317 }
3318
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003319 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003320
3321 private:
3322 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003323 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003324};
3325
3326
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003327class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003328 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003329 HLoadContextSlot(HValue* context , int slot_index)
3330 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003331 set_representation(Representation::Tagged());
3332 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003333 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003334 }
3335
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003336 int slot_index() const { return slot_index_; }
3337
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003338 virtual Representation RequiredInputRepresentation(int index) const {
3339 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003340 }
3341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003342 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003343
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003344 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003345
3346 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003347 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003348 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003349 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003350 }
3351
3352 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003353 int slot_index_;
3354};
3355
3356
3357static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003358 return !value->type().IsBoolean()
3359 && !value->type().IsSmi()
3360 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003361}
3362
3363
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003364class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003365 public:
3366 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003367 : slot_index_(slot_index) {
3368 SetOperandAt(0, context);
3369 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003370 SetFlag(kChangesContextSlots);
3371 }
3372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003373 HValue* context() { return OperandAt(0); }
3374 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003375 int slot_index() const { return slot_index_; }
3376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003377 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003378 return StoringValueNeedsWriteBarrier(value());
3379 }
3380
3381 virtual Representation RequiredInputRepresentation(int index) const {
3382 return Representation::Tagged();
3383 }
3384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003385 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003386
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003387 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003388
3389 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003390 int slot_index_;
3391};
3392
3393
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394class HLoadNamedField: public HUnaryOperation {
3395 public:
3396 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3397 : HUnaryOperation(object),
3398 is_in_object_(is_in_object),
3399 offset_(offset) {
3400 set_representation(Representation::Tagged());
3401 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003402 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403 if (is_in_object) {
3404 SetFlag(kDependsOnInobjectFields);
3405 } else {
3406 SetFlag(kDependsOnBackingStoreFields);
3407 }
3408 }
3409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003410 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003411 bool is_in_object() const { return is_in_object_; }
3412 int offset() const { return offset_; }
3413
3414 virtual Representation RequiredInputRepresentation(int index) const {
3415 return Representation::Tagged();
3416 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003417 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003418
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003419 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003420
3421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003422 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003423 HLoadNamedField* b = HLoadNamedField::cast(other);
3424 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3425 }
3426
3427 private:
3428 bool is_in_object_;
3429 int offset_;
3430};
3431
3432
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003433class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003434 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003435 HLoadNamedFieldPolymorphic(HValue* context,
3436 HValue* object,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003437 ZoneMapList* types,
3438 Handle<String> name);
3439
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003440 HValue* context() { return OperandAt(0); }
3441 HValue* object() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003442 ZoneMapList* types() { return &types_; }
3443 Handle<String> name() { return name_; }
3444 bool need_generic() { return need_generic_; }
3445
3446 virtual Representation RequiredInputRepresentation(int index) const {
3447 return Representation::Tagged();
3448 }
3449
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003450 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003451
3452 static const int kMaxLoadPolymorphism = 4;
3453
3454 protected:
3455 virtual bool DataEquals(HValue* value);
3456
3457 private:
3458 ZoneMapList types_;
3459 Handle<String> name_;
3460 bool need_generic_;
3461};
3462
3463
3464
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003465class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003466 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003467 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003468 : name_(name) {
3469 SetOperandAt(0, context);
3470 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003471 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003472 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003473 }
3474
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003475 HValue* context() { return OperandAt(0); }
3476 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003477 Handle<Object> name() const { return name_; }
3478
3479 virtual Representation RequiredInputRepresentation(int index) const {
3480 return Representation::Tagged();
3481 }
3482
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003483 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003484
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003485 private:
3486 Handle<Object> name_;
3487};
3488
3489
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003490class HLoadFunctionPrototype: public HUnaryOperation {
3491 public:
3492 explicit HLoadFunctionPrototype(HValue* function)
3493 : HUnaryOperation(function) {
3494 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003495 SetFlag(kUseGVN);
3496 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003500
3501 virtual Representation RequiredInputRepresentation(int index) const {
3502 return Representation::Tagged();
3503 }
3504
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003505 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003506
3507 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003508 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003509};
3510
3511
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003512class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003513 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003514 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3515 SetOperandAt(0, obj);
3516 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003517 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003518 SetFlag(kDependsOnArrayElements);
3519 SetFlag(kUseGVN);
3520 }
3521
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003522 HValue* object() { return OperandAt(0); }
3523 HValue* key() { return OperandAt(1); }
3524
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003525 virtual Representation RequiredInputRepresentation(int index) const {
3526 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003527 return index == 0
3528 ? Representation::Tagged()
3529 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003530 }
3531
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003532 virtual void PrintDataTo(StringStream* stream);
3533
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003534 bool RequiresHoleCheck() const;
3535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003536 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003537
3538 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003539 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003540};
3541
3542
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003543class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003544 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003545 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3546 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003547 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003548 : elements_kind_(elements_kind) {
3549 SetOperandAt(0, external_elements);
3550 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003551 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3552 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003553 set_representation(Representation::Double());
3554 } else {
3555 set_representation(Representation::Integer32());
3556 }
3557 SetFlag(kDependsOnSpecializedArrayElements);
3558 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003559 SetFlag(kDependsOnCalls);
3560 SetFlag(kUseGVN);
3561 }
3562
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003563 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003564
3565 virtual Representation RequiredInputRepresentation(int index) const {
3566 // The key is supposed to be Integer32, but the base pointer
3567 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003568 return index == 0
3569 ? Representation::External()
3570 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003571 }
3572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003573 HValue* external_pointer() { return OperandAt(0); }
3574 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003575 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003576
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003577 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003578
3579 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003580 virtual bool DataEquals(HValue* other) {
3581 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3582 HLoadKeyedSpecializedArrayElement* cast_other =
3583 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003584 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003585 }
3586
3587 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003588 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003589};
3590
3591
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003592class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003593 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003594 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003595 set_representation(Representation::Tagged());
3596 SetOperandAt(0, obj);
3597 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003598 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003599 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003600 }
3601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003602 HValue* object() { return OperandAt(0); }
3603 HValue* key() { return OperandAt(1); }
3604 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003605
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003606 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003607
3608 virtual Representation RequiredInputRepresentation(int index) const {
3609 return Representation::Tagged();
3610 }
3611
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003612 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613};
3614
3615
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003616class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003617 public:
3618 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003619 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620 HValue* val,
3621 bool in_object,
3622 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003623 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003624 is_in_object_(in_object),
3625 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003626 SetOperandAt(0, obj);
3627 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628 if (is_in_object_) {
3629 SetFlag(kChangesInobjectFields);
3630 } else {
3631 SetFlag(kChangesBackingStoreFields);
3632 }
3633 }
3634
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003635 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636
3637 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003638 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003639 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003640 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003642 HValue* object() { return OperandAt(0); }
3643 HValue* value() { return OperandAt(1); }
3644
3645 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003646 bool is_in_object() const { return is_in_object_; }
3647 int offset() const { return offset_; }
3648 Handle<Map> transition() const { return transition_; }
3649 void set_transition(Handle<Map> map) { transition_ = map; }
3650
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003651 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003652 return StoringValueNeedsWriteBarrier(value());
3653 }
3654
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003655 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003656 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003657 bool is_in_object_;
3658 int offset_;
3659 Handle<Map> transition_;
3660};
3661
3662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003663class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003664 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003665 HStoreNamedGeneric(HValue* context,
3666 HValue* object,
3667 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003668 HValue* value,
3669 bool strict_mode)
3670 : name_(name),
3671 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003672 SetOperandAt(0, object);
3673 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003674 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003675 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003676 }
3677
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003678 HValue* object() { return OperandAt(0); }
3679 HValue* value() { return OperandAt(1); }
3680 HValue* context() { return OperandAt(2); }
3681 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003682 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003683
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003684 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003685
3686 virtual Representation RequiredInputRepresentation(int index) const {
3687 return Representation::Tagged();
3688 }
3689
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003690 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003692 private:
3693 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003694 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695};
3696
3697
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003698class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003699 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003700 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3701 SetOperandAt(0, obj);
3702 SetOperandAt(1, key);
3703 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003704 SetFlag(kChangesArrayElements);
3705 }
3706
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003707 virtual Representation RequiredInputRepresentation(int index) const {
3708 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003709 return index == 1
3710 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003711 : Representation::Tagged();
3712 }
3713
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003714 HValue* object() { return OperandAt(0); }
3715 HValue* key() { return OperandAt(1); }
3716 HValue* value() { return OperandAt(2); }
3717
3718 bool NeedsWriteBarrier() {
3719 return StoringValueNeedsWriteBarrier(value());
3720 }
3721
3722 virtual void PrintDataTo(StringStream* stream);
3723
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003724 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003725};
3726
3727
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003728class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003729 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003730 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3731 HValue* key,
3732 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003733 JSObject::ElementsKind elements_kind)
3734 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003735 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003736 SetOperandAt(0, external_elements);
3737 SetOperandAt(1, key);
3738 SetOperandAt(2, val);
3739 }
3740
3741 virtual void PrintDataTo(StringStream* stream);
3742
3743 virtual Representation RequiredInputRepresentation(int index) const {
3744 if (index == 0) {
3745 return Representation::External();
3746 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003747 bool float_or_double_elements =
3748 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3749 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3750 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003751 return Representation::Double();
3752 } else {
3753 return Representation::Integer32();
3754 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003755 }
3756 }
3757
3758 HValue* external_pointer() { return OperandAt(0); }
3759 HValue* key() { return OperandAt(1); }
3760 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003761 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003762
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003763 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3764
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003765 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003766 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003767};
3768
3769
3770class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003771 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003772 HStoreKeyedGeneric(HValue* context,
3773 HValue* object,
3774 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003775 HValue* value,
3776 bool strict_mode)
3777 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003778 SetOperandAt(0, object);
3779 SetOperandAt(1, key);
3780 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003781 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003782 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003783 }
3784
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003785 HValue* object() { return OperandAt(0); }
3786 HValue* key() { return OperandAt(1); }
3787 HValue* value() { return OperandAt(2); }
3788 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003789 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003790
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003791 virtual Representation RequiredInputRepresentation(int index) const {
3792 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003793 }
3794
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003795 virtual void PrintDataTo(StringStream* stream);
3796
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003797 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003798
3799 private:
3800 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003801};
3802
3803
danno@chromium.org160a7b02011-04-18 15:51:38 +00003804class HStringAdd: public HBinaryOperation {
3805 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003806 HStringAdd(HValue* context, HValue* left, HValue* right)
3807 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003808 set_representation(Representation::Tagged());
3809 SetFlag(kUseGVN);
3810 SetFlag(kDependsOnMaps);
3811 }
3812
3813 virtual Representation RequiredInputRepresentation(int index) const {
3814 return Representation::Tagged();
3815 }
3816
3817 virtual HType CalculateInferredType() {
3818 return HType::String();
3819 }
3820
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003821 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003822
3823 protected:
3824 virtual bool DataEquals(HValue* other) { return true; }
3825};
3826
3827
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003828class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003829 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003830 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3831 SetOperandAt(0, context);
3832 SetOperandAt(1, string);
3833 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003834 set_representation(Representation::Integer32());
3835 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003836 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003837 }
3838
3839 virtual Representation RequiredInputRepresentation(int index) const {
3840 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003841 return index == 2
3842 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003843 : Representation::Tagged();
3844 }
3845
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003846 HValue* context() { return OperandAt(0); }
3847 HValue* string() { return OperandAt(1); }
3848 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003849
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003850 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003851
3852 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003853 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003854
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003855 virtual Range* InferRange() {
3856 return new Range(0, String::kMaxUC16CharCode);
3857 }
3858};
3859
3860
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003861class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003862 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003863 HStringCharFromCode(HValue* context, HValue* char_code) {
3864 SetOperandAt(0, context);
3865 SetOperandAt(1, char_code);
3866 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003867 SetFlag(kUseGVN);
3868 }
3869
3870 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003871 return index == 0
3872 ? Representation::Tagged()
3873 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003874 }
3875
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003876 HValue* context() { return OperandAt(0); }
3877 HValue* value() { return OperandAt(1); }
3878
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003879 virtual bool DataEquals(HValue* other) { return true; }
3880
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003881 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003882};
3883
3884
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003885class HStringLength: public HUnaryOperation {
3886 public:
3887 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3888 set_representation(Representation::Tagged());
3889 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003890 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003891 }
3892
3893 virtual Representation RequiredInputRepresentation(int index) const {
3894 return Representation::Tagged();
3895 }
3896
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003897 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003898 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3899 return HType::Smi();
3900 }
3901
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003902 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003903
3904 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003905 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003906
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003907 virtual Range* InferRange() {
3908 return new Range(0, String::kMaxLength);
3909 }
3910};
3911
3912
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003913template <int V>
3914class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003915 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003916 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003917 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003918 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003919 }
3920
3921 int literal_index() const { return literal_index_; }
3922 int depth() const { return depth_; }
3923
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003924 private:
3925 int literal_index_;
3926 int depth_;
3927};
3928
3929
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003930class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003931 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003932 HArrayLiteral(HValue* context,
3933 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003934 int length,
3935 int literal_index,
3936 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003937 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003938 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003939 constant_elements_(constant_elements) {
3940 SetOperandAt(0, context);
3941 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003942
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003943 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003944 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3945 int length() const { return length_; }
3946
3947 bool IsCopyOnWrite() const;
3948
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003949 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003950 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003951 }
3952
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003953 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003954
3955 private:
3956 int length_;
3957 Handle<FixedArray> constant_elements_;
3958};
3959
3960
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003961class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003962 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003963 HObjectLiteral(HValue* context,
3964 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003965 bool fast_elements,
3966 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003967 int depth,
3968 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003969 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003970 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003971 fast_elements_(fast_elements),
3972 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003973 SetOperandAt(0, context);
3974 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003975
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003976 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003977 Handle<FixedArray> constant_properties() const {
3978 return constant_properties_;
3979 }
3980 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003981 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003983 virtual Representation RequiredInputRepresentation(int index) const {
3984 return Representation::Tagged();
3985 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003986
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003987 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988
3989 private:
3990 Handle<FixedArray> constant_properties_;
3991 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003992 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003993};
3994
3995
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003996class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003997 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003998 HRegExpLiteral(HValue* context,
3999 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004000 Handle<String> flags,
4001 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004002 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004003 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004004 flags_(flags) {
4005 SetOperandAt(0, context);
4006 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004007
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004008 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004009 Handle<String> pattern() { return pattern_; }
4010 Handle<String> flags() { return flags_; }
4011
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004012 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004013 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004014 }
4015
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004016 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004017
4018 private:
4019 Handle<String> pattern_;
4020 Handle<String> flags_;
4021};
4022
4023
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004024class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004025 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004026 HFunctionLiteral(HValue* context,
4027 Handle<SharedFunctionInfo> shared,
4028 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004029 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004030 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004031 set_representation(Representation::Tagged());
4032 }
4033
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004034 HValue* context() { return OperandAt(0); }
4035
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004036 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004037 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004038 }
4039
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004040 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004041
4042 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4043 bool pretenure() const { return pretenure_; }
4044
4045 private:
4046 Handle<SharedFunctionInfo> shared_info_;
4047 bool pretenure_;
4048};
4049
4050
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004051class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004052 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004053 explicit HTypeof(HValue* context, HValue* value) {
4054 SetOperandAt(0, context);
4055 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004056 set_representation(Representation::Tagged());
4057 }
4058
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004059 HValue* context() { return OperandAt(0); }
4060 HValue* value() { return OperandAt(1); }
4061
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004062 virtual Representation RequiredInputRepresentation(int index) const {
4063 return Representation::Tagged();
4064 }
4065
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004066 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004067};
4068
4069
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004070class HToFastProperties: public HUnaryOperation {
4071 public:
4072 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4073 // This instruction is not marked as having side effects, but
4074 // changes the map of the input operand. Use it only when creating
4075 // object literals.
4076 ASSERT(value->IsObjectLiteral());
4077 set_representation(Representation::Tagged());
4078 }
4079
4080 virtual Representation RequiredInputRepresentation(int index) const {
4081 return Representation::Tagged();
4082 }
4083
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004084 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004085};
4086
4087
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004088class HValueOf: public HUnaryOperation {
4089 public:
4090 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4091 set_representation(Representation::Tagged());
4092 }
4093
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004094 virtual Representation RequiredInputRepresentation(int index) const {
4095 return Representation::Tagged();
4096 }
4097
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004098 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004099};
4100
4101
4102class HDeleteProperty: public HBinaryOperation {
4103 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004104 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4105 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004106 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004107 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004108 }
4109
4110 virtual Representation RequiredInputRepresentation(int index) const {
4111 return Representation::Tagged();
4112 }
4113
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004114 virtual HType CalculateInferredType();
4115
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004116 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004117
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004118 HValue* object() { return left(); }
4119 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004120};
4121
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004122
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004123class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004124 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004125 HIn(HValue* context, HValue* key, HValue* object) {
4126 SetOperandAt(0, context);
4127 SetOperandAt(1, key);
4128 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004129 set_representation(Representation::Tagged());
4130 SetAllSideEffects();
4131 }
4132
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004133 HValue* context() { return OperandAt(0); }
4134 HValue* key() { return OperandAt(1); }
4135 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004136
4137 virtual Representation RequiredInputRepresentation(int index) const {
4138 return Representation::Tagged();
4139 }
4140
4141 virtual HType CalculateInferredType() {
4142 return HType::Boolean();
4143 }
4144
4145 virtual void PrintDataTo(StringStream* stream);
4146
4147 DECLARE_CONCRETE_INSTRUCTION(In)
4148};
4149
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004150#undef DECLARE_INSTRUCTION
4151#undef DECLARE_CONCRETE_INSTRUCTION
4152
4153} } // namespace v8::internal
4154
4155#endif // V8_HYDROGEN_INSTRUCTIONS_H_