blob: 4fb7fec43821ad1caa6476bf361169c0c34b8f25 [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
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "code-stubs.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000034#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "string-stream.h"
36#include "zone.h"
37
38namespace v8 {
39namespace internal {
40
41// Forward declarations.
42class HBasicBlock;
43class HEnvironment;
44class HInstruction;
45class HLoopInformation;
46class HValue;
47class LInstruction;
48class LChunkBuilder;
49
50
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000051#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000052 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000053 V(ControlInstruction) \
54 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055
56
57#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000058 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059 V(AccessArgumentsAt) \
60 V(Add) \
61 V(ApplyArguments) \
62 V(ArgumentsElements) \
63 V(ArgumentsLength) \
64 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065 V(ArrayLiteral) \
66 V(BitAnd) \
67 V(BitNot) \
68 V(BitOr) \
69 V(BitXor) \
70 V(BlockEntry) \
71 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000072 V(CallConstantFunction) \
73 V(CallFunction) \
74 V(CallGlobal) \
75 V(CallKeyed) \
76 V(CallKnownGlobal) \
77 V(CallNamed) \
78 V(CallNew) \
79 V(CallRuntime) \
80 V(CallStub) \
81 V(Change) \
82 V(CheckFunction) \
83 V(CheckInstanceType) \
84 V(CheckMap) \
85 V(CheckNonSmi) \
86 V(CheckPrototypeMaps) \
87 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000088 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000089 V(Compare) \
90 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000091 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000092 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000093 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000094 V(DeleteProperty) \
95 V(Deoptimize) \
96 V(Div) \
97 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000098 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +000099 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000101 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(GlobalObject) \
103 V(GlobalReceiver) \
104 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000105 V(HasInstanceType) \
106 V(HasCachedArrayIndex) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000107 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000109 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000110 V(InvokeFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000112 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000114 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000115 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000117 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000119 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000120 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000121 V(LoadGlobalCell) \
122 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000123 V(LoadKeyedFastElement) \
124 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000125 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000127 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128 V(LoadNamedGeneric) \
129 V(Mod) \
130 V(Mul) \
131 V(ObjectLiteral) \
132 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000133 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000135 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(PushArgument) \
137 V(RegExpLiteral) \
138 V(Return) \
139 V(Sar) \
140 V(Shl) \
141 V(Shr) \
142 V(Simulate) \
143 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000144 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000145 V(StoreGlobalCell) \
146 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000148 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000149 V(StoreKeyedGeneric) \
150 V(StoreNamedField) \
151 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000152 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000153 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000154 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000155 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000157 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000159 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(Typeof) \
161 V(TypeofIs) \
162 V(UnaryMathOperation) \
163 V(UnknownOSRValue) \
164 V(ValueOf)
165
166#define GVN_FLAG_LIST(V) \
167 V(Calls) \
168 V(InobjectFields) \
169 V(BackingStoreFields) \
170 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000171 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000172 V(GlobalVars) \
173 V(Maps) \
174 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000175 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(OsrEntries)
177
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000178#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 virtual bool Is##type() const { return true; } \
180 static H##type* cast(HValue* value) { \
181 ASSERT(value->Is##type()); \
182 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000183 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000184
185
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000186#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000187 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000188 static H##type* cast(HValue* value) { \
189 ASSERT(value->Is##type()); \
190 return reinterpret_cast<H##type*>(value); \
191 } \
192 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193
194
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195class Range: public ZoneObject {
196 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000197 Range()
198 : lower_(kMinInt),
199 upper_(kMaxInt),
200 next_(NULL),
201 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000202
203 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000204 : lower_(lower),
205 upper_(upper),
206 next_(NULL),
207 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000208
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209 int32_t upper() const { return upper_; }
210 int32_t lower() const { return lower_; }
211 Range* next() const { return next_; }
212 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
213 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215 int32_t Mask() const;
216 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
217 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
218 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
219 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000220 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
221 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
222 bool IsInSmiRange() const {
223 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000225 void KeepOrder();
226 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000227
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 void StackUpon(Range* other) {
229 Intersect(other);
230 next_ = other;
231 }
232
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000233 void Intersect(Range* other);
234 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000236 void AddConstant(int32_t value);
237 void Sar(int32_t value);
238 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000239 bool AddAndCheckOverflow(Range* other);
240 bool SubAndCheckOverflow(Range* other);
241 bool MulAndCheckOverflow(Range* other);
242
243 private:
244 int32_t lower_;
245 int32_t upper_;
246 Range* next_;
247 bool can_be_minus_zero_;
248};
249
250
251class Representation {
252 public:
253 enum Kind {
254 kNone,
255 kTagged,
256 kDouble,
257 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000258 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000259 kNumRepresentations
260 };
261
262 Representation() : kind_(kNone) { }
263
264 static Representation None() { return Representation(kNone); }
265 static Representation Tagged() { return Representation(kTagged); }
266 static Representation Integer32() { return Representation(kInteger32); }
267 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000268 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000270 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000271 return kind_ == other.kind_;
272 }
273
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000274 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000275 bool IsNone() const { return kind_ == kNone; }
276 bool IsTagged() const { return kind_ == kTagged; }
277 bool IsInteger32() const { return kind_ == kInteger32; }
278 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000279 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000280 bool IsSpecialization() const {
281 return kind_ == kInteger32 || kind_ == kDouble;
282 }
283 const char* Mnemonic() const;
284
285 private:
286 explicit Representation(Kind k) : kind_(k) { }
287
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000288 // Make sure kind fits in int8.
289 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
290
291 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000292};
293
294
295class HType {
296 public:
297 HType() : type_(kUninitialized) { }
298
299 static HType Tagged() { return HType(kTagged); }
300 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
301 static HType TaggedNumber() { return HType(kTaggedNumber); }
302 static HType Smi() { return HType(kSmi); }
303 static HType HeapNumber() { return HType(kHeapNumber); }
304 static HType String() { return HType(kString); }
305 static HType Boolean() { return HType(kBoolean); }
306 static HType NonPrimitive() { return HType(kNonPrimitive); }
307 static HType JSArray() { return HType(kJSArray); }
308 static HType JSObject() { return HType(kJSObject); }
309 static HType Uninitialized() { return HType(kUninitialized); }
310
311 // Return the weakest (least precise) common type.
312 HType Combine(HType other) {
313 return HType(static_cast<Type>(type_ & other.type_));
314 }
315
316 bool Equals(const HType& other) {
317 return type_ == other.type_;
318 }
319
320 bool IsSubtypeOf(const HType& other) {
321 return Combine(other).Equals(other);
322 }
323
324 bool IsTagged() {
325 ASSERT(type_ != kUninitialized);
326 return ((type_ & kTagged) == kTagged);
327 }
328
329 bool IsTaggedPrimitive() {
330 ASSERT(type_ != kUninitialized);
331 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
332 }
333
334 bool IsTaggedNumber() {
335 ASSERT(type_ != kUninitialized);
336 return ((type_ & kTaggedNumber) == kTaggedNumber);
337 }
338
339 bool IsSmi() {
340 ASSERT(type_ != kUninitialized);
341 return ((type_ & kSmi) == kSmi);
342 }
343
344 bool IsHeapNumber() {
345 ASSERT(type_ != kUninitialized);
346 return ((type_ & kHeapNumber) == kHeapNumber);
347 }
348
349 bool IsString() {
350 ASSERT(type_ != kUninitialized);
351 return ((type_ & kString) == kString);
352 }
353
354 bool IsBoolean() {
355 ASSERT(type_ != kUninitialized);
356 return ((type_ & kBoolean) == kBoolean);
357 }
358
359 bool IsNonPrimitive() {
360 ASSERT(type_ != kUninitialized);
361 return ((type_ & kNonPrimitive) == kNonPrimitive);
362 }
363
364 bool IsJSArray() {
365 ASSERT(type_ != kUninitialized);
366 return ((type_ & kJSArray) == kJSArray);
367 }
368
369 bool IsJSObject() {
370 ASSERT(type_ != kUninitialized);
371 return ((type_ & kJSObject) == kJSObject);
372 }
373
374 bool IsUninitialized() {
375 return type_ == kUninitialized;
376 }
377
378 static HType TypeFromValue(Handle<Object> value);
379
380 const char* ToString();
381 const char* ToShortString();
382
383 private:
384 enum Type {
385 kTagged = 0x1, // 0000 0000 0000 0001
386 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
387 kTaggedNumber = 0xd, // 0000 0000 0000 1101
388 kSmi = 0x1d, // 0000 0000 0001 1101
389 kHeapNumber = 0x2d, // 0000 0000 0010 1101
390 kString = 0x45, // 0000 0000 0100 0101
391 kBoolean = 0x85, // 0000 0000 1000 0101
392 kNonPrimitive = 0x101, // 0000 0001 0000 0001
393 kJSObject = 0x301, // 0000 0011 0000 0001
394 kJSArray = 0x701, // 0000 0111 1000 0001
395 kUninitialized = 0x1fff // 0001 1111 1111 1111
396 };
397
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000398 // Make sure type fits in int16.
399 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
400
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000401 explicit HType(Type t) : type_(t) { }
402
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000403 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000404};
405
406
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000407class HUseListNode: public ZoneObject {
408 public:
409 HUseListNode(HValue* value, int index, HUseListNode* tail)
410 : tail_(tail), value_(value), index_(index) {
411 }
412
413 HUseListNode* tail() const { return tail_; }
414 HValue* value() const { return value_; }
415 int index() const { return index_; }
416
417 void set_tail(HUseListNode* list) { tail_ = list; }
418
419#ifdef DEBUG
420 void Zap() {
421 tail_ = reinterpret_cast<HUseListNode*>(1);
422 value_ = NULL;
423 index_ = -1;
424 }
425#endif
426
427 private:
428 HUseListNode* tail_;
429 HValue* value_;
430 int index_;
431};
432
433
434// We reuse use list nodes behind the scenes as uses are added and deleted.
435// This class is the safe way to iterate uses while deleting them.
436class HUseIterator BASE_EMBEDDED {
437 public:
438 bool Done() { return current_ == NULL; }
439 void Advance();
440
441 HValue* value() {
442 ASSERT(!Done());
443 return value_;
444 }
445
446 int index() {
447 ASSERT(!Done());
448 return index_;
449 }
450
451 private:
452 explicit HUseIterator(HUseListNode* head);
453
454 HUseListNode* current_;
455 HUseListNode* next_;
456 HValue* value_;
457 int index_;
458
459 friend class HValue;
460};
461
462
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000463class HValue: public ZoneObject {
464 public:
465 static const int kNoNumber = -1;
466
467 // There must be one corresponding kDepends flag for every kChanges flag and
468 // the order of the kChanges flags must be exactly the same as of the kDepends
469 // flags.
470 enum Flag {
471 // Declare global value numbering flags.
472 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
473 GVN_FLAG_LIST(DECLARE_DO)
474 #undef DECLARE_DO
475 kFlexibleRepresentation,
476 kUseGVN,
477 kCanOverflow,
478 kBailoutOnMinusZero,
479 kCanBeDivByZero,
480 kIsArguments,
481 kTruncatingToInt32,
482 kLastFlag = kTruncatingToInt32
483 };
484
485 STATIC_ASSERT(kLastFlag < kBitsPerInt);
486
487 static const int kChangesToDependsFlagsLeftShift = 1;
488
489 static int ChangesFlagsMask() {
490 int result = 0;
491 // Create changes mask.
492#define DECLARE_DO(type) result |= (1 << kChanges##type);
493 GVN_FLAG_LIST(DECLARE_DO)
494#undef DECLARE_DO
495 return result;
496 }
497
498 static int DependsFlagsMask() {
499 return ConvertChangesToDependsFlags(ChangesFlagsMask());
500 }
501
502 static int ConvertChangesToDependsFlags(int flags) {
503 return flags << kChangesToDependsFlagsLeftShift;
504 }
505
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000506 static HValue* cast(HValue* value) { return value; }
507
508 enum Opcode {
509 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000510 #define DECLARE_OPCODE(type) k##type,
511 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
512 kPhi
513 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000514 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000515 virtual Opcode opcode() const = 0;
516
517 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
518 #define DECLARE_PREDICATE(type) \
519 bool Is##type() const { return opcode() == k##type; }
520 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
521 #undef DECLARE_PREDICATE
522 bool IsPhi() const { return opcode() == kPhi; }
523
524 // Declare virtual predicates for abstract HInstruction or HValue
525 #define DECLARE_PREDICATE(type) \
526 virtual bool Is##type() const { return false; }
527 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
528 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000529
530 HValue() : block_(NULL),
531 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000532 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000533 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000534 range_(NULL),
535 flags_(0) {}
536 virtual ~HValue() {}
537
538 HBasicBlock* block() const { return block_; }
539 void SetBlock(HBasicBlock* block);
540
541 int id() const { return id_; }
542 void set_id(int id) { id_ = id; }
543
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000544 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000545
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000546 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000547 Representation representation() const { return representation_; }
548 void ChangeRepresentation(Representation r) {
549 // Representation was already set and is allowed to be changed.
550 ASSERT(!representation_.IsNone());
551 ASSERT(!r.IsNone());
552 ASSERT(CheckFlag(kFlexibleRepresentation));
553 RepresentationChanged(r);
554 representation_ = r;
555 }
556
557 HType type() const { return type_; }
558 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000559 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000560 type_ = type;
561 }
562
563 // An operation needs to override this function iff:
564 // 1) it can produce an int32 output.
565 // 2) the true value of its output can potentially be minus zero.
566 // The implementation must set a flag so that it bails out in the case where
567 // it would otherwise output what should be a minus zero as an int32 zero.
568 // If the operation also exists in a form that takes int32 and outputs int32
569 // then the operation should return its input value so that we can propagate
570 // back. There are two operations that need to propagate back to more than
571 // one input. They are phi and binary add. They always return NULL and
572 // expect the caller to take care of things.
573 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
574 visited->Add(id());
575 return NULL;
576 }
577
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578 bool IsDefinedAfter(HBasicBlock* other) const;
579
580 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000581 virtual int OperandCount() = 0;
582 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000583 void SetOperandAt(int index, HValue* value);
584
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000585 void DeleteAndReplaceWith(HValue* other);
586 bool HasNoUses() const { return use_list_ == NULL; }
587 bool HasMultipleUses() const {
588 return use_list_ != NULL && use_list_->tail() != NULL;
589 }
590 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000591 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000592
593 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000594 void SetFlag(Flag f) { flags_ |= (1 << f); }
595 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
596 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
597
598 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
599 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
600 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000601
602 Range* range() const { return range_; }
603 bool HasRange() const { return range_ != NULL; }
604 void AddNewRange(Range* r);
605 void RemoveLastAddedRange();
606 void ComputeInitialRange();
607
608 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000609 virtual Representation RequiredInputRepresentation(int index) const = 0;
610
611 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612 return representation();
613 }
614
615 // This gives the instruction an opportunity to replace itself with an
616 // instruction that does the same in some better way. To replace an
617 // instruction with a new one, first add the new instruction to the graph,
618 // then return it. Return NULL to have the instruction deleted.
619 virtual HValue* Canonicalize() { return this; }
620
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000621 bool Equals(HValue* other);
622 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000623
624 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000625 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000626 void PrintNameTo(StringStream* stream);
627 static void PrintTypeTo(HType type, StringStream* stream);
628
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000629 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000630
631 // Updated the inferred type of this instruction and returns true if
632 // it has changed.
633 bool UpdateInferredType();
634
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000635 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000636
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000637#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000638 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000639#endif
640
641 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000642 // This function must be overridden for instructions with flag kUseGVN, to
643 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000644 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000645 UNREACHABLE();
646 return false;
647 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648 virtual void RepresentationChanged(Representation to) { }
649 virtual Range* InferRange();
650 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000651 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652 void clear_block() {
653 ASSERT(block_ != NULL);
654 block_ = NULL;
655 }
656
657 void set_representation(Representation r) {
658 // Representation is set-once.
659 ASSERT(representation_.IsNone() && !r.IsNone());
660 representation_ = r;
661 }
662
663 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000664 // A flag mask to mark an instruction as having arbitrary side effects.
665 static int AllSideEffects() {
666 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
667 }
668
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000669 // Remove the matching use from the use list if present. Returns the
670 // removed list node or NULL.
671 HUseListNode* RemoveUse(HValue* value, int index);
672
673 void ReplaceAllUsesWith(HValue* other);
674
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000675 void RegisterUse(int index, HValue* new_value);
676
677 HBasicBlock* block_;
678
679 // The id of this instruction in the hydrogen graph, assigned when first
680 // added to the graph. Reflects creation order.
681 int id_;
682
683 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000685 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000686 Range* range_;
687 int flags_;
688
689 DISALLOW_COPY_AND_ASSIGN(HValue);
690};
691
692
693class HInstruction: public HValue {
694 public:
695 HInstruction* next() const { return next_; }
696 HInstruction* previous() const { return previous_; }
697
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000698 virtual void PrintTo(StringStream* stream);
699 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000700
701 bool IsLinked() const { return block() != NULL; }
702 void Unlink();
703 void InsertBefore(HInstruction* next);
704 void InsertAfter(HInstruction* previous);
705
706 int position() const { return position_; }
707 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
708 void set_position(int position) { position_ = position; }
709
710 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
711
712#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000713 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000714#endif
715
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000716 // Returns whether this is some kind of deoptimizing check
717 // instruction.
718 virtual bool IsCheckInstruction() const { return false; }
719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000720 virtual bool IsCall() { return false; }
721
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000722 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000723
724 protected:
725 HInstruction()
726 : next_(NULL),
727 previous_(NULL),
728 position_(RelocInfo::kNoPosition) {
729 SetFlag(kDependsOnOsrEntries);
730 }
731
732 virtual void DeleteFromGraph() { Unlink(); }
733
734 private:
735 void InitializeAsFirst(HBasicBlock* block) {
736 ASSERT(!IsLinked());
737 SetBlock(block);
738 }
739
740 HInstruction* next_;
741 HInstruction* previous_;
742 int position_;
743
744 friend class HBasicBlock;
745};
746
747
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000748class HControlInstruction: public HInstruction {
749 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000750 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
751 : first_successor_(first), second_successor_(second) {
752 }
753
754 HBasicBlock* FirstSuccessor() const { return first_successor_; }
755 HBasicBlock* SecondSuccessor() const { return second_successor_; }
756
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000757 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000758
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000759 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000760
761 private:
762 HBasicBlock* first_successor_;
763 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000764};
765
766
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000767template<int NumElements>
768class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000769 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000770 HOperandContainer() : elems_() { }
771
772 int length() { return NumElements; }
773 HValue*& operator[](int i) {
774 ASSERT(i < length());
775 return elems_[i];
776 }
777
778 private:
779 HValue* elems_[NumElements];
780};
781
782
783template<>
784class HOperandContainer<0> {
785 public:
786 int length() { return 0; }
787 HValue*& operator[](int i) {
788 UNREACHABLE();
789 static HValue* t = 0;
790 return t;
791 }
792};
793
794
795template<int V>
796class HTemplateInstruction : public HInstruction {
797 public:
798 int OperandCount() { return V; }
799 HValue* OperandAt(int i) { return inputs_[i]; }
800
801 protected:
802 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
803
804 private:
805 HOperandContainer<V> inputs_;
806};
807
808
809template<int V>
810class HTemplateControlInstruction : public HControlInstruction {
811 public:
812 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
813 : HControlInstruction(first, second) { }
814 int OperandCount() { return V; }
815 HValue* OperandAt(int i) { return inputs_[i]; }
816
817 protected:
818 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
819
820 private:
821 HOperandContainer<V> inputs_;
822};
823
824
825class HBlockEntry: public HTemplateInstruction<0> {
826 public:
827 virtual Representation RequiredInputRepresentation(int index) const {
828 return Representation::None();
829 }
830
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000831 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000832};
833
834
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000835class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000836 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000837 explicit HDeoptimize(int environment_length)
838 : HControlInstruction(NULL, NULL),
839 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000840
841 virtual Representation RequiredInputRepresentation(int index) const {
842 return Representation::None();
843 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000844
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000845 virtual int OperandCount() { return values_.length(); }
846 virtual HValue* OperandAt(int index) { return values_[index]; }
847
848 void AddEnvironmentValue(HValue* value) {
849 values_.Add(NULL);
850 SetOperandAt(values_.length() - 1, value);
851 }
852
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000853 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000854
855 protected:
856 virtual void InternalSetOperandAt(int index, HValue* value) {
857 values_[index] = value;
858 }
859
860 private:
861 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000862};
863
864
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000865class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000866 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000867 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868 : HTemplateControlInstruction<0>(target, NULL),
869 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000871 void set_include_stack_check(bool include_stack_check) {
872 include_stack_check_ = include_stack_check;
873 }
874 bool include_stack_check() const { return include_stack_check_; }
875
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000876 virtual Representation RequiredInputRepresentation(int index) const {
877 return Representation::None();
878 }
879
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000880 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000881
882 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000883 bool include_stack_check_;
884};
885
886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000887class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000888 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000889 explicit HUnaryControlInstruction(HValue* value,
890 HBasicBlock* true_target,
891 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000892 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000893 SetOperandAt(0, value);
894 }
895
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000896 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000897
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000898 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899};
900
901
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000902class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000904 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
905 : HUnaryControlInstruction(value, true_target, false_target) {
906 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907 }
908
909 virtual Representation RequiredInputRepresentation(int index) const {
910 return Representation::None();
911 }
912
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000913 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000914};
915
916
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000917class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000918 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000919 HCompareMap(HValue* value,
920 Handle<Map> map,
921 HBasicBlock* true_target,
922 HBasicBlock* false_target)
923 : HUnaryControlInstruction(value, true_target, false_target),
924 map_(map) {
925 ASSERT(true_target != NULL);
926 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927 ASSERT(!map.is_null());
928 }
929
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000930 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000931
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932 Handle<Map> map() const { return map_; }
933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000934 virtual Representation RequiredInputRepresentation(int index) const {
935 return Representation::Tagged();
936 }
937
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000938 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000939
940 private:
941 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942};
943
944
945class HReturn: public HUnaryControlInstruction {
946 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000947 explicit HReturn(HValue* value)
948 : HUnaryControlInstruction(value, NULL, NULL) {
949 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000951 virtual Representation RequiredInputRepresentation(int index) const {
952 return Representation::Tagged();
953 }
954
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000955 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000956};
957
958
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000959class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000961 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
962
963 virtual Representation RequiredInputRepresentation(int index) const {
964 return Representation::None();
965 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000966
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000967 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000968};
969
970
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000971class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000972 public:
973 explicit HUnaryOperation(HValue* value) {
974 SetOperandAt(0, value);
975 }
976
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000977 HValue* value() { return OperandAt(0); }
978 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979};
980
981
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000982class HThrow: public HUnaryOperation {
983 public:
984 explicit HThrow(HValue* value) : HUnaryOperation(value) {
985 SetAllSideEffects();
986 }
987
988 virtual Representation RequiredInputRepresentation(int index) const {
989 return Representation::Tagged();
990 }
991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000992 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000993};
994
995
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996class HChange: public HUnaryOperation {
997 public:
998 HChange(HValue* value,
999 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001000 Representation to,
1001 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001002 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001003 ASSERT(!from.IsNone() && !to.IsNone());
1004 ASSERT(!from.Equals(to));
1005 set_representation(to);
1006 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001007 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001008 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1009 value->range()->IsInSmiRange()) {
1010 set_type(HType::Smi());
1011 }
1012 }
1013
1014 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1015
1016 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001017 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001018 virtual Representation RequiredInputRepresentation(int index) const {
1019 return from_;
1020 }
1021
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001022 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001023
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001024 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001025
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001026 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001027
1028 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001029 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001030 if (!other->IsChange()) return false;
1031 HChange* change = HChange::cast(other);
1032 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001033 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001034 }
1035
1036 private:
1037 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001038};
1039
1040
1041class HSimulate: public HInstruction {
1042 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001043 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001044 : ast_id_(ast_id),
1045 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001046 values_(2),
1047 assigned_indexes_(2) {}
1048 virtual ~HSimulate() {}
1049
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001050 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001051
1052 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1053 int ast_id() const { return ast_id_; }
1054 void set_ast_id(int id) {
1055 ASSERT(!HasAstId());
1056 ast_id_ = id;
1057 }
1058
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001059 int pop_count() const { return pop_count_; }
1060 const ZoneList<HValue*>* values() const { return &values_; }
1061 int GetAssignedIndexAt(int index) const {
1062 ASSERT(HasAssignedIndexAt(index));
1063 return assigned_indexes_[index];
1064 }
1065 bool HasAssignedIndexAt(int index) const {
1066 return assigned_indexes_[index] != kNoIndex;
1067 }
1068 void AddAssignedValue(int index, HValue* value) {
1069 AddValue(index, value);
1070 }
1071 void AddPushedValue(HValue* value) {
1072 AddValue(kNoIndex, value);
1073 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001074 virtual int OperandCount() { return values_.length(); }
1075 virtual HValue* OperandAt(int index) { return values_[index]; }
1076
1077 virtual Representation RequiredInputRepresentation(int index) const {
1078 return Representation::None();
1079 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001080
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001081 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001082
1083#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001084 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085#endif
1086
1087 protected:
1088 virtual void InternalSetOperandAt(int index, HValue* value) {
1089 values_[index] = value;
1090 }
1091
1092 private:
1093 static const int kNoIndex = -1;
1094 void AddValue(int index, HValue* value) {
1095 assigned_indexes_.Add(index);
1096 // Resize the list of pushed values.
1097 values_.Add(NULL);
1098 // Set the operand through the base method in HValue to make sure that the
1099 // use lists are correctly updated.
1100 SetOperandAt(values_.length() - 1, value);
1101 }
1102 int ast_id_;
1103 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104 ZoneList<HValue*> values_;
1105 ZoneList<int> assigned_indexes_;
1106};
1107
1108
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001109class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110 public:
1111 HStackCheck() { }
1112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001113 virtual Representation RequiredInputRepresentation(int index) const {
1114 return Representation::None();
1115 }
1116
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001117 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001118};
1119
1120
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001121class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001122 public:
1123 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1124 : closure_(closure), function_(function) {
1125 }
1126
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001127 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001128
1129 Handle<JSFunction> closure() const { return closure_; }
1130 FunctionLiteral* function() const { return function_; }
1131
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001132 virtual Representation RequiredInputRepresentation(int index) const {
1133 return Representation::None();
1134 }
1135
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001136 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001137
1138 private:
1139 Handle<JSFunction> closure_;
1140 FunctionLiteral* function_;
1141};
1142
1143
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001144class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001145 public:
1146 HLeaveInlined() {}
1147
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001148 virtual Representation RequiredInputRepresentation(int index) const {
1149 return Representation::None();
1150 }
1151
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001152 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001153};
1154
1155
1156class HPushArgument: public HUnaryOperation {
1157 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001158 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1159 set_representation(Representation::Tagged());
1160 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001161
1162 virtual Representation RequiredInputRepresentation(int index) const {
1163 return Representation::Tagged();
1164 }
1165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001166 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001167
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001168 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169};
1170
1171
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001172class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001174 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001175 set_representation(Representation::Tagged());
1176 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001177 }
1178
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001179 virtual Representation RequiredInputRepresentation(int index) const {
1180 return Representation::None();
1181 }
1182
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001183 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001184
1185 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001186 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001187};
1188
1189
1190class HOuterContext: public HUnaryOperation {
1191 public:
1192 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1193 set_representation(Representation::Tagged());
1194 SetFlag(kUseGVN);
1195 }
1196
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001197 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001198
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001199 virtual Representation RequiredInputRepresentation(int index) const {
1200 return Representation::Tagged();
1201 }
1202
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001203 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001204 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001205};
1206
1207
1208class HGlobalObject: public HUnaryOperation {
1209 public:
1210 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1211 set_representation(Representation::Tagged());
1212 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001213 }
1214
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001215 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001217 virtual Representation RequiredInputRepresentation(int index) const {
1218 return Representation::Tagged();
1219 }
1220
ager@chromium.org378b34e2011-01-28 08:04:38 +00001221 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001222 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001223};
1224
1225
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001226class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001227 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001228 explicit HGlobalReceiver(HValue* global_object)
1229 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001230 set_representation(Representation::Tagged());
1231 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001232 }
1233
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001234 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001236 virtual Representation RequiredInputRepresentation(int index) const {
1237 return Representation::Tagged();
1238 }
1239
ager@chromium.org378b34e2011-01-28 08:04:38 +00001240 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001241 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001242};
1243
1244
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001245template <int V>
1246class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001247 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001248 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001249 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1250 this->set_representation(Representation::Tagged());
1251 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001252 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001254 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001255
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001256 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001258 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001259
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001260 private:
1261 int argument_count_;
1262};
1263
1264
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001265class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001266 public:
1267 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001268 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001269 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001270 }
1271
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001272 virtual Representation RequiredInputRepresentation(int index) const {
1273 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001274 }
1275
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001276 virtual void PrintDataTo(StringStream* stream);
1277
1278 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001279};
1280
1281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001282class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001283 public:
1284 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001285 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001286 SetOperandAt(0, first);
1287 SetOperandAt(1, second);
1288 }
1289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001290 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001292 virtual Representation RequiredInputRepresentation(int index) const {
1293 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001294 }
1295
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001296 HValue* first() { return OperandAt(0); }
1297 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001298};
1299
1300
danno@chromium.org160a7b02011-04-18 15:51:38 +00001301class HInvokeFunction: public HBinaryCall {
1302 public:
1303 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1304 : HBinaryCall(context, function, argument_count) {
1305 }
1306
1307 virtual Representation RequiredInputRepresentation(int index) const {
1308 return Representation::Tagged();
1309 }
1310
1311 HValue* context() { return first(); }
1312 HValue* function() { return second(); }
1313
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001314 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001315};
1316
1317
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001318class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001319 public:
1320 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001322
1323 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001324
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001326 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001327 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328 }
1329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001330 virtual void PrintDataTo(StringStream* stream);
1331
1332 virtual Representation RequiredInputRepresentation(int index) const {
1333 return Representation::None();
1334 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001336 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001337
1338 private:
1339 Handle<JSFunction> function_;
1340};
1341
1342
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001343class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001344 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001345 HCallKeyed(HValue* context, HValue* key, int argument_count)
1346 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001347 }
1348
1349 virtual Representation RequiredInputRepresentation(int index) const {
1350 return Representation::Tagged();
1351 }
1352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001353 HValue* context() { return first(); }
1354 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001356 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001357};
1358
1359
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001360class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001361 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001362 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1363 : HUnaryCall(context, argument_count), name_(name) {
1364 }
1365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001366 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001368 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001369 Handle<String> name() const { return name_; }
1370
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001371 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001373 virtual Representation RequiredInputRepresentation(int index) const {
1374 return Representation::Tagged();
1375 }
1376
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377 private:
1378 Handle<String> name_;
1379};
1380
1381
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001382class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001384 HCallFunction(HValue* context, int argument_count)
1385 : HUnaryCall(context, argument_count) {
1386 }
1387
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001388 HValue* context() { return value(); }
1389
1390 virtual Representation RequiredInputRepresentation(int index) const {
1391 return Representation::Tagged();
1392 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001393
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001394 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001395};
1396
1397
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001398class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001399 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001400 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1401 : HUnaryCall(context, argument_count), name_(name) {
1402 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001406 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407 Handle<String> name() const { return name_; }
1408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001409 virtual Representation RequiredInputRepresentation(int index) const {
1410 return Representation::Tagged();
1411 }
1412
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001413 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001414
1415 private:
1416 Handle<String> name_;
1417};
1418
1419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001420class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001422 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001423 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001425 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001426
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427 Handle<JSFunction> target() const { return target_; }
1428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001429 virtual Representation RequiredInputRepresentation(int index) const {
1430 return Representation::None();
1431 }
1432
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001433 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001434
1435 private:
1436 Handle<JSFunction> target_;
1437};
1438
1439
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001440class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001442 HCallNew(HValue* context, HValue* constructor, int argument_count)
1443 : HBinaryCall(context, constructor, argument_count) {
1444 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001445
1446 virtual Representation RequiredInputRepresentation(int index) const {
1447 return Representation::Tagged();
1448 }
1449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001450 HValue* context() { return first(); }
1451 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001452
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001453 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001454};
1455
1456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001457class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001458 public:
1459 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001460 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001461 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001462 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1463 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001465 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001466 Handle<String> name() const { return name_; }
1467
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001468 virtual Representation RequiredInputRepresentation(int index) const {
1469 return Representation::None();
1470 }
1471
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001472 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001473
1474 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001475 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001476 Handle<String> name_;
1477};
1478
1479
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001480class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001481 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001482 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001483 // The length of an array is stored as a tagged value in the array
1484 // object. It is guaranteed to be 32 bit integer, but it can be
1485 // represented as either a smi or heap number.
1486 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001488 SetFlag(kDependsOnArrayLengths);
1489 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001490 }
1491
1492 virtual Representation RequiredInputRepresentation(int index) const {
1493 return Representation::Tagged();
1494 }
1495
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001496 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001497
1498 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001499 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001500};
1501
1502
1503class HFixedArrayLength: public HUnaryOperation {
1504 public:
1505 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1506 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001507 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001508 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001509 }
1510
1511 virtual Representation RequiredInputRepresentation(int index) const {
1512 return Representation::Tagged();
1513 }
1514
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001515 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001516
1517 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001518 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519};
1520
1521
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001522class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001523 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001524 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001525 set_representation(Representation::Integer32());
1526 // The result of this instruction is idempotent as long as its inputs don't
1527 // change. The length of a pixel array cannot change once set, so it's not
1528 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1529 SetFlag(kUseGVN);
1530 }
1531
1532 virtual Representation RequiredInputRepresentation(int index) const {
1533 return Representation::Tagged();
1534 }
1535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001536 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001537
1538 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001539 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001540};
1541
1542
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001543class HBitNot: public HUnaryOperation {
1544 public:
1545 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1546 set_representation(Representation::Integer32());
1547 SetFlag(kUseGVN);
1548 SetFlag(kTruncatingToInt32);
1549 }
1550
1551 virtual Representation RequiredInputRepresentation(int index) const {
1552 return Representation::Integer32();
1553 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001554 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001556 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001557
1558 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001559 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001560};
1561
1562
1563class HUnaryMathOperation: public HUnaryOperation {
1564 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001565 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566 : HUnaryOperation(value), op_(op) {
1567 switch (op) {
1568 case kMathFloor:
1569 case kMathRound:
1570 case kMathCeil:
1571 set_representation(Representation::Integer32());
1572 break;
1573 case kMathAbs:
1574 set_representation(Representation::Tagged());
1575 SetFlag(kFlexibleRepresentation);
1576 break;
1577 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001578 case kMathPowHalf:
1579 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001580 case kMathSin:
1581 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001582 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001583 break;
1584 default:
1585 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 }
1587 SetFlag(kUseGVN);
1588 }
1589
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001590 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001591
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001592 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593
1594 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1595
1596 virtual Representation RequiredInputRepresentation(int index) const {
1597 switch (op_) {
1598 case kMathFloor:
1599 case kMathRound:
1600 case kMathCeil:
1601 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001602 case kMathPowHalf:
1603 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001604 case kMathSin:
1605 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607 case kMathAbs:
1608 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001609 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001610 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001611 return Representation::None();
1612 }
1613 }
1614
1615 virtual HValue* Canonicalize() {
1616 // If the input is integer32 then we replace the floor instruction
1617 // with its inputs. This happens before the representation changes are
1618 // introduced.
1619 if (op() == kMathFloor) {
1620 if (value()->representation().IsInteger32()) return value();
1621 }
1622 return this;
1623 }
1624
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001625 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001626 const char* OpName() const;
1627
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001628 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001629
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001630 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001631 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001632 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1633 return op_ == b->op();
1634 }
1635
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001636 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001637 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001638};
1639
1640
1641class HLoadElements: public HUnaryOperation {
1642 public:
1643 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1644 set_representation(Representation::Tagged());
1645 SetFlag(kUseGVN);
1646 SetFlag(kDependsOnMaps);
1647 }
1648
1649 virtual Representation RequiredInputRepresentation(int index) const {
1650 return Representation::Tagged();
1651 }
1652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001653 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001654
1655 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001656 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001657};
1658
1659
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001660class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001661 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001662 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001663 : HUnaryOperation(value) {
1664 set_representation(Representation::External());
1665 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001666 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001667 // change once set, so it's no necessary to introduce any additional
1668 // dependencies on top of the inputs.
1669 SetFlag(kUseGVN);
1670 }
1671
1672 virtual Representation RequiredInputRepresentation(int index) const {
1673 return Representation::Tagged();
1674 }
1675
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001676 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001677
1678 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001679 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001680};
1681
1682
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001683class HCheckMap: public HUnaryOperation {
1684 public:
1685 HCheckMap(HValue* value, Handle<Map> map)
1686 : HUnaryOperation(value), map_(map) {
1687 set_representation(Representation::Tagged());
1688 SetFlag(kUseGVN);
1689 SetFlag(kDependsOnMaps);
1690 }
1691
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001692 virtual bool IsCheckInstruction() const { return true; }
1693
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001694 virtual Representation RequiredInputRepresentation(int index) const {
1695 return Representation::Tagged();
1696 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001697 virtual void PrintDataTo(StringStream* stream);
1698 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001699
1700#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001701 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001702#endif
1703
1704 Handle<Map> map() const { return map_; }
1705
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001706 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707
1708 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001709 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710 HCheckMap* b = HCheckMap::cast(other);
1711 return map_.is_identical_to(b->map());
1712 }
1713
1714 private:
1715 Handle<Map> map_;
1716};
1717
1718
1719class HCheckFunction: public HUnaryOperation {
1720 public:
1721 HCheckFunction(HValue* value, Handle<JSFunction> function)
1722 : HUnaryOperation(value), target_(function) {
1723 set_representation(Representation::Tagged());
1724 SetFlag(kUseGVN);
1725 }
1726
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001727 virtual bool IsCheckInstruction() const { return true; }
1728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001729 virtual Representation RequiredInputRepresentation(int index) const {
1730 return Representation::Tagged();
1731 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001732 virtual void PrintDataTo(StringStream* stream);
1733 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001734
1735#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001736 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001737#endif
1738
1739 Handle<JSFunction> target() const { return target_; }
1740
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001741 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001742
1743 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001744 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745 HCheckFunction* b = HCheckFunction::cast(other);
1746 return target_.is_identical_to(b->target());
1747 }
1748
1749 private:
1750 Handle<JSFunction> target_;
1751};
1752
1753
1754class HCheckInstanceType: public HUnaryOperation {
1755 public:
1756 // Check that the instance type is in the range [first, last] where
1757 // both first and last are included.
1758 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1759 : HUnaryOperation(value), first_(first), last_(last) {
1760 ASSERT(first <= last);
1761 set_representation(Representation::Tagged());
1762 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001763 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1764 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1765 // A particular string instance type can change because of GC or
1766 // externalization, but the value still remains a string.
1767 SetFlag(kDependsOnMaps);
1768 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001769 }
1770
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001771 virtual bool IsCheckInstruction() const { return true; }
1772
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001773 virtual Representation RequiredInputRepresentation(int index) const {
1774 return Representation::Tagged();
1775 }
1776
1777#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001778 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001779#endif
1780
danno@chromium.org160a7b02011-04-18 15:51:38 +00001781 virtual HValue* Canonicalize() {
1782 if (!value()->type().IsUninitialized() &&
1783 value()->type().IsString() &&
1784 first() == FIRST_STRING_TYPE &&
1785 last() == LAST_STRING_TYPE) {
1786 return NULL;
1787 }
1788 return this;
1789 }
1790
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001791 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1792
1793 InstanceType first() const { return first_; }
1794 InstanceType last() const { return last_; }
1795
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001796 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001797
1798 protected:
1799 // TODO(ager): It could be nice to allow the ommision of instance
1800 // type checks if we have already performed an instance type check
1801 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001802 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1804 return (first_ == b->first()) && (last_ == b->last());
1805 }
1806
1807 private:
1808 InstanceType first_;
1809 InstanceType last_;
1810};
1811
1812
1813class HCheckNonSmi: public HUnaryOperation {
1814 public:
1815 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1816 set_representation(Representation::Tagged());
1817 SetFlag(kUseGVN);
1818 }
1819
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001820 virtual bool IsCheckInstruction() const { return true; }
1821
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001822 virtual Representation RequiredInputRepresentation(int index) const {
1823 return Representation::Tagged();
1824 }
1825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001826 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001827
1828#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001829 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830#endif
1831
danno@chromium.org160a7b02011-04-18 15:51:38 +00001832 virtual HValue* Canonicalize() {
1833 HType value_type = value()->type();
1834 if (!value_type.IsUninitialized() &&
1835 (value_type.IsHeapNumber() ||
1836 value_type.IsString() ||
1837 value_type.IsBoolean() ||
1838 value_type.IsNonPrimitive())) {
1839 return NULL;
1840 }
1841 return this;
1842 }
1843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001844 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001845
1846 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001847 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848};
1849
1850
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001851class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001852 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001853 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1854 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001855 SetFlag(kUseGVN);
1856 SetFlag(kDependsOnMaps);
1857 }
1858
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001859 virtual bool IsCheckInstruction() const { return true; }
1860
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001861#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001862 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001863#endif
1864
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001865 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001866 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001868 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001870 virtual Representation RequiredInputRepresentation(int index) const {
1871 return Representation::None();
1872 }
1873
1874 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001875 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001876 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1877 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1878 return hash;
1879 }
1880
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001881 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001882 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001883 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001884 return prototype_.is_identical_to(b->prototype()) &&
1885 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001886 }
1887
1888 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001889 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001890 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001891};
1892
1893
1894class HCheckSmi: public HUnaryOperation {
1895 public:
1896 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1897 set_representation(Representation::Tagged());
1898 SetFlag(kUseGVN);
1899 }
1900
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001901 virtual bool IsCheckInstruction() const { return true; }
1902
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001903 virtual Representation RequiredInputRepresentation(int index) const {
1904 return Representation::Tagged();
1905 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001906 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001907
1908#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001909 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001910#endif
1911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001912 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001913
1914 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001915 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916};
1917
1918
1919class HPhi: public HValue {
1920 public:
1921 explicit HPhi(int merged_index)
1922 : inputs_(2),
1923 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001924 phi_id_(-1),
1925 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001926 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1927 non_phi_uses_[i] = 0;
1928 indirect_uses_[i] = 0;
1929 }
1930 ASSERT(merged_index >= 0);
1931 set_representation(Representation::Tagged());
1932 SetFlag(kFlexibleRepresentation);
1933 }
1934
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001935 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001936 bool double_occurred = false;
1937 bool int32_occurred = false;
1938 for (int i = 0; i < OperandCount(); ++i) {
1939 HValue* value = OperandAt(i);
1940 if (value->representation().IsDouble()) double_occurred = true;
1941 if (value->representation().IsInteger32()) int32_occurred = true;
1942 if (value->representation().IsTagged()) return Representation::Tagged();
1943 }
1944
1945 if (double_occurred) return Representation::Double();
1946 if (int32_occurred) return Representation::Integer32();
1947 return Representation::None();
1948 }
1949
1950 virtual Range* InferRange();
1951 virtual Representation RequiredInputRepresentation(int index) const {
1952 return representation();
1953 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001954 virtual HType CalculateInferredType();
1955 virtual int OperandCount() { return inputs_.length(); }
1956 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1957 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001958 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001959 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001960
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001961 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001962
1963 int merged_index() const { return merged_index_; }
1964
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001965 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966
1967#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001968 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001969#endif
1970
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971 void InitRealUses(int id);
1972 void AddNonPhiUsesFrom(HPhi* other);
1973 void AddIndirectUsesTo(int* use_count);
1974
1975 int tagged_non_phi_uses() const {
1976 return non_phi_uses_[Representation::kTagged];
1977 }
1978 int int32_non_phi_uses() const {
1979 return non_phi_uses_[Representation::kInteger32];
1980 }
1981 int double_non_phi_uses() const {
1982 return non_phi_uses_[Representation::kDouble];
1983 }
1984 int tagged_indirect_uses() const {
1985 return indirect_uses_[Representation::kTagged];
1986 }
1987 int int32_indirect_uses() const {
1988 return indirect_uses_[Representation::kInteger32];
1989 }
1990 int double_indirect_uses() const {
1991 return indirect_uses_[Representation::kDouble];
1992 }
1993 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001994 bool is_live() { return is_live_; }
1995 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001997 static HPhi* cast(HValue* value) {
1998 ASSERT(value->IsPhi());
1999 return reinterpret_cast<HPhi*>(value);
2000 }
2001 virtual Opcode opcode() const { return HValue::kPhi; }
2002
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002003 protected:
2004 virtual void DeleteFromGraph();
2005 virtual void InternalSetOperandAt(int index, HValue* value) {
2006 inputs_[index] = value;
2007 }
2008
2009 private:
2010 ZoneList<HValue*> inputs_;
2011 int merged_index_;
2012
2013 int non_phi_uses_[Representation::kNumRepresentations];
2014 int indirect_uses_[Representation::kNumRepresentations];
2015 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002016 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002017};
2018
2019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002020class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002021 public:
2022 HArgumentsObject() {
2023 set_representation(Representation::Tagged());
2024 SetFlag(kIsArguments);
2025 }
2026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002027 virtual Representation RequiredInputRepresentation(int index) const {
2028 return Representation::None();
2029 }
2030
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002031 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002032};
2033
2034
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002035class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002036 public:
2037 HConstant(Handle<Object> handle, Representation r);
2038
2039 Handle<Object> handle() const { return handle_; }
2040
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002041 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002042
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002043 virtual Representation RequiredInputRepresentation(int index) const {
2044 return Representation::None();
2045 }
2046
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002047 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002048 virtual void PrintDataTo(StringStream* stream);
2049 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002050 bool IsInteger() const { return handle_->IsSmi(); }
2051 HConstant* CopyToRepresentation(Representation r) const;
2052 HConstant* CopyToTruncatedInt32() const;
2053 bool HasInteger32Value() const { return has_int32_value_; }
2054 int32_t Integer32Value() const {
2055 ASSERT(HasInteger32Value());
2056 return int32_value_;
2057 }
2058 bool HasDoubleValue() const { return has_double_value_; }
2059 double DoubleValue() const {
2060 ASSERT(HasDoubleValue());
2061 return double_value_;
2062 }
2063 bool HasStringValue() const { return handle_->IsString(); }
2064
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002065 bool ToBoolean() const;
2066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002067 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002068 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002069 return reinterpret_cast<intptr_t>(*handle());
2070 }
2071
2072#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002073 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002074#endif
2075
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002076 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002077
2078 protected:
2079 virtual Range* InferRange();
2080
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002081 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082 HConstant* other_constant = HConstant::cast(other);
2083 return handle().is_identical_to(other_constant->handle());
2084 }
2085
2086 private:
2087 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088
2089 // The following two values represent the int32 and the double value of the
2090 // given constant if there is a lossless conversion between the constant
2091 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002092 bool has_int32_value_ : 1;
2093 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002094 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095 double double_value_;
2096};
2097
2098
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002099class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100 public:
2101 HBinaryOperation(HValue* left, HValue* right) {
2102 ASSERT(left != NULL && right != NULL);
2103 SetOperandAt(0, left);
2104 SetOperandAt(1, right);
2105 }
2106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002107 HValue* left() { return OperandAt(0); }
2108 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109
2110 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2111 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002112 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002113 if (IsCommutative() && left()->IsConstant()) return right();
2114 return left();
2115 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002116 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117 if (IsCommutative() && left()->IsConstant()) return left();
2118 return right();
2119 }
2120
2121 virtual bool IsCommutative() const { return false; }
2122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002123 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124};
2125
2126
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002127class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002128 public:
2129 HApplyArguments(HValue* function,
2130 HValue* receiver,
2131 HValue* length,
2132 HValue* elements) {
2133 set_representation(Representation::Tagged());
2134 SetOperandAt(0, function);
2135 SetOperandAt(1, receiver);
2136 SetOperandAt(2, length);
2137 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002138 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002139 }
2140
2141 virtual Representation RequiredInputRepresentation(int index) const {
2142 // The length is untagged, all other inputs are tagged.
2143 return (index == 2)
2144 ? Representation::Integer32()
2145 : Representation::Tagged();
2146 }
2147
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002148 HValue* function() { return OperandAt(0); }
2149 HValue* receiver() { return OperandAt(1); }
2150 HValue* length() { return OperandAt(2); }
2151 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002152
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002153 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002154};
2155
2156
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002157class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002158 public:
2159 HArgumentsElements() {
2160 // The value produced by this instruction is a pointer into the stack
2161 // that looks as if it was a smi because of alignment.
2162 set_representation(Representation::Tagged());
2163 SetFlag(kUseGVN);
2164 }
2165
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002166 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002168 virtual Representation RequiredInputRepresentation(int index) const {
2169 return Representation::None();
2170 }
2171
ager@chromium.org378b34e2011-01-28 08:04:38 +00002172 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002173 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174};
2175
2176
2177class HArgumentsLength: public HUnaryOperation {
2178 public:
2179 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2180 set_representation(Representation::Integer32());
2181 SetFlag(kUseGVN);
2182 }
2183
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002184 virtual Representation RequiredInputRepresentation(int index) const {
2185 return Representation::Tagged();
2186 }
2187
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002188 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002189
2190 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002191 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002192};
2193
2194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002195class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002196 public:
2197 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2198 set_representation(Representation::Tagged());
2199 SetFlag(kUseGVN);
2200 SetOperandAt(0, arguments);
2201 SetOperandAt(1, length);
2202 SetOperandAt(2, index);
2203 }
2204
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002205 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002206
2207 virtual Representation RequiredInputRepresentation(int index) const {
2208 // The arguments elements is considered tagged.
2209 return index == 0
2210 ? Representation::Tagged()
2211 : Representation::Integer32();
2212 }
2213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002214 HValue* arguments() { return OperandAt(0); }
2215 HValue* length() { return OperandAt(1); }
2216 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002217
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002218 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002219
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002220 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002221};
2222
2223
2224class HBoundsCheck: public HBinaryOperation {
2225 public:
2226 HBoundsCheck(HValue* index, HValue* length)
2227 : HBinaryOperation(index, length) {
2228 SetFlag(kUseGVN);
2229 }
2230
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002231 virtual bool IsCheckInstruction() const { return true; }
2232
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002233 virtual Representation RequiredInputRepresentation(int index) const {
2234 return Representation::Integer32();
2235 }
2236
2237#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002238 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239#endif
2240
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002241 HValue* index() { return left(); }
2242 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002244 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002245
2246 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002247 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248};
2249
2250
2251class HBitwiseBinaryOperation: public HBinaryOperation {
2252 public:
2253 HBitwiseBinaryOperation(HValue* left, HValue* right)
2254 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002255 set_representation(Representation::Tagged());
2256 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002257 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002258 }
2259
2260 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002261 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002262 }
2263
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002264 virtual void RepresentationChanged(Representation to) {
2265 if (!to.IsTagged()) {
2266 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002267 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002268 SetFlag(kTruncatingToInt32);
2269 SetFlag(kUseGVN);
2270 }
2271 }
2272
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002273 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002274
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002275 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276};
2277
2278
2279class HArithmeticBinaryOperation: public HBinaryOperation {
2280 public:
2281 HArithmeticBinaryOperation(HValue* left, HValue* right)
2282 : HBinaryOperation(left, right) {
2283 set_representation(Representation::Tagged());
2284 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002285 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002286 }
2287
2288 virtual void RepresentationChanged(Representation to) {
2289 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002290 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002291 SetFlag(kUseGVN);
2292 }
2293 }
2294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002295 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002296 virtual Representation RequiredInputRepresentation(int index) const {
2297 return representation();
2298 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002299 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002300 if (left()->representation().Equals(right()->representation())) {
2301 return left()->representation();
2302 }
2303 return HValue::InferredRepresentation();
2304 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002305};
2306
2307
2308class HCompare: public HBinaryOperation {
2309 public:
2310 HCompare(HValue* left, HValue* right, Token::Value token)
2311 : HBinaryOperation(left, right), token_(token) {
2312 ASSERT(Token::IsCompareOp(token));
2313 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002314 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315 }
2316
2317 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002318
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002319 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002320 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002321 }
2322
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002323 virtual Representation RequiredInputRepresentation(int index) const {
2324 return input_representation_;
2325 }
2326 Representation GetInputRepresentation() const {
2327 return input_representation_;
2328 }
2329 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002330 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002332 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002334 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002335 return HValue::Hashcode() * 7 + token_;
2336 }
2337
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002338 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339
2340 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002341 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002342 HCompare* comp = HCompare::cast(other);
2343 return token_ == comp->token();
2344 }
2345
2346 private:
2347 Representation input_representation_;
2348 Token::Value token_;
2349};
2350
2351
2352class HCompareJSObjectEq: public HBinaryOperation {
2353 public:
2354 HCompareJSObjectEq(HValue* left, HValue* right)
2355 : HBinaryOperation(left, right) {
2356 set_representation(Representation::Tagged());
2357 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002358 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002359 }
2360
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002361 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002362 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002363 }
2364
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002365 virtual Representation RequiredInputRepresentation(int index) const {
2366 return Representation::Tagged();
2367 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002368 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002370 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002371
2372 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374};
2375
2376
2377class HUnaryPredicate: public HUnaryOperation {
2378 public:
2379 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2380 set_representation(Representation::Tagged());
2381 SetFlag(kUseGVN);
2382 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002383
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002384 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002385 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002386 }
2387
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002388 virtual Representation RequiredInputRepresentation(int index) const {
2389 return Representation::Tagged();
2390 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002391 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002392};
2393
2394
2395class HIsNull: public HUnaryPredicate {
2396 public:
2397 HIsNull(HValue* value, bool is_strict)
2398 : HUnaryPredicate(value), is_strict_(is_strict) { }
2399
2400 bool is_strict() const { return is_strict_; }
2401
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002402 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002403
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002404 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002405 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002406 HIsNull* b = HIsNull::cast(other);
2407 return is_strict_ == b->is_strict();
2408 }
2409
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002410 private:
2411 bool is_strict_;
2412};
2413
2414
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002415class HIsObject: public HUnaryPredicate {
2416 public:
2417 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2418
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002419 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002420
2421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002422 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002423};
2424
2425
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002426class HIsSmi: public HUnaryPredicate {
2427 public:
2428 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2429
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002430 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002431
2432 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002433 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002434};
2435
2436
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002437class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002438 public:
2439 HIsConstructCall() {
2440 set_representation(Representation::Tagged());
2441 SetFlag(kUseGVN);
2442 }
2443
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002444 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002445 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002446 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002448 virtual Representation RequiredInputRepresentation(int index) const {
2449 return Representation::None();
2450 }
2451
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002452 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002453
2454 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002455 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002456};
2457
2458
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002459class HHasInstanceType: public HUnaryPredicate {
2460 public:
2461 HHasInstanceType(HValue* value, InstanceType type)
2462 : HUnaryPredicate(value), from_(type), to_(type) { }
2463 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2464 : HUnaryPredicate(value), from_(from), to_(to) {
2465 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2466 }
2467
2468 InstanceType from() { return from_; }
2469 InstanceType to() { return to_; }
2470
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002471 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002472
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002473 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002474
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002475 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002476 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002477 HHasInstanceType* b = HHasInstanceType::cast(other);
2478 return (from_ == b->from()) && (to_ == b->to());
2479 }
2480
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002481 private:
2482 InstanceType from_;
2483 InstanceType to_; // Inclusive range, not all combinations work.
2484};
2485
2486
2487class HHasCachedArrayIndex: public HUnaryPredicate {
2488 public:
2489 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2490
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002491 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002492
2493 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002494 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002495};
2496
2497
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002498class HGetCachedArrayIndex: public HUnaryPredicate {
2499 public:
2500 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2501
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002502 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002503
2504 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002505 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002506};
2507
2508
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002509class HClassOfTest: public HUnaryPredicate {
2510 public:
2511 HClassOfTest(HValue* value, Handle<String> class_name)
2512 : HUnaryPredicate(value), class_name_(class_name) { }
2513
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002514 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002516 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002517
2518 Handle<String> class_name() const { return class_name_; }
2519
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002520 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002521 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002522 HClassOfTest* b = HClassOfTest::cast(other);
2523 return class_name_.is_identical_to(b->class_name_);
2524 }
2525
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002526 private:
2527 Handle<String> class_name_;
2528};
2529
2530
2531class HTypeofIs: public HUnaryPredicate {
2532 public:
2533 HTypeofIs(HValue* value, Handle<String> type_literal)
2534 : HUnaryPredicate(value), type_literal_(type_literal) { }
2535
2536 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002537 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002539 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540
2541 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002542 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002543 HTypeofIs* b = HTypeofIs::cast(other);
2544 return type_literal_.is_identical_to(b->type_literal_);
2545 }
2546
2547 private:
2548 Handle<String> type_literal_;
2549};
2550
2551
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002552class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002554 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2555 SetOperandAt(0, context);
2556 SetOperandAt(1, left);
2557 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002558 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002559 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560 }
2561
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002562 HValue* context() { return OperandAt(0); }
2563 HValue* left() { return OperandAt(1); }
2564 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002565
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002566 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002567 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002568 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002569
2570 virtual Representation RequiredInputRepresentation(int index) const {
2571 return Representation::Tagged();
2572 }
2573
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002574 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002575
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002576 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002577};
2578
2579
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002580class HInstanceOfKnownGlobal: public HUnaryOperation {
2581 public:
2582 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2583 : HUnaryOperation(left), function_(right) {
2584 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002585 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002586 }
2587
2588 Handle<JSFunction> function() { return function_; }
2589
2590 virtual Representation RequiredInputRepresentation(int index) const {
2591 return Representation::Tagged();
2592 }
2593
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002594 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002595
2596 private:
2597 Handle<JSFunction> function_;
2598};
2599
2600
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002601class HPower: public HBinaryOperation {
2602 public:
2603 HPower(HValue* left, HValue* right)
2604 : HBinaryOperation(left, right) {
2605 set_representation(Representation::Double());
2606 SetFlag(kUseGVN);
2607 }
2608
2609 virtual Representation RequiredInputRepresentation(int index) const {
2610 return (index == 1) ? Representation::None() : Representation::Double();
2611 }
2612
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002613 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002614
2615 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002616 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002617};
2618
2619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620class HAdd: public HArithmeticBinaryOperation {
2621 public:
2622 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2623 SetFlag(kCanOverflow);
2624 }
2625
2626 // Add is only commutative if two integer values are added and not if two
2627 // tagged values are added (because it might be a String concatenation).
2628 virtual bool IsCommutative() const {
2629 return !representation().IsTagged();
2630 }
2631
2632 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2633
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002634 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002635
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002636 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002637
2638 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002639 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641 virtual Range* InferRange();
2642};
2643
2644
2645class HSub: public HArithmeticBinaryOperation {
2646 public:
2647 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2648 SetFlag(kCanOverflow);
2649 }
2650
2651 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002653 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002654
2655 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002656 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002657
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002658 virtual Range* InferRange();
2659};
2660
2661
2662class HMul: public HArithmeticBinaryOperation {
2663 public:
2664 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2665 SetFlag(kCanOverflow);
2666 }
2667
2668 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2669
2670 // Only commutative if it is certain that not two objects are multiplicated.
2671 virtual bool IsCommutative() const {
2672 return !representation().IsTagged();
2673 }
2674
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002675 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676
2677 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002678 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002679
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680 virtual Range* InferRange();
2681};
2682
2683
2684class HMod: public HArithmeticBinaryOperation {
2685 public:
2686 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2687 SetFlag(kCanBeDivByZero);
2688 }
2689
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002690 bool HasPowerOf2Divisor() {
2691 if (right()->IsConstant() &&
2692 HConstant::cast(right())->HasInteger32Value()) {
2693 int32_t value = HConstant::cast(right())->Integer32Value();
2694 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2695 }
2696
2697 return false;
2698 }
2699
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002700 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2701
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002702 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002703
2704 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002705 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002706
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707 virtual Range* InferRange();
2708};
2709
2710
2711class HDiv: public HArithmeticBinaryOperation {
2712 public:
2713 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2714 SetFlag(kCanBeDivByZero);
2715 SetFlag(kCanOverflow);
2716 }
2717
2718 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2719
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002720 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721
2722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002723 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002724
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725 virtual Range* InferRange();
2726};
2727
2728
2729class HBitAnd: public HBitwiseBinaryOperation {
2730 public:
2731 HBitAnd(HValue* left, HValue* right)
2732 : HBitwiseBinaryOperation(left, right) { }
2733
2734 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002735 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002737 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738
2739 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002740 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002741
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002742 virtual Range* InferRange();
2743};
2744
2745
2746class HBitXor: public HBitwiseBinaryOperation {
2747 public:
2748 HBitXor(HValue* left, HValue* right)
2749 : HBitwiseBinaryOperation(left, right) { }
2750
2751 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002752 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002753
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002754 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002755
2756 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002757 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002758};
2759
2760
2761class HBitOr: public HBitwiseBinaryOperation {
2762 public:
2763 HBitOr(HValue* left, HValue* right)
2764 : HBitwiseBinaryOperation(left, right) { }
2765
2766 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002767 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002769 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002770
2771 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002772 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002773
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 virtual Range* InferRange();
2775};
2776
2777
2778class HShl: public HBitwiseBinaryOperation {
2779 public:
2780 HShl(HValue* left, HValue* right)
2781 : HBitwiseBinaryOperation(left, right) { }
2782
2783 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002784 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002785
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002786 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002787
2788 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790};
2791
2792
2793class HShr: public HBitwiseBinaryOperation {
2794 public:
2795 HShr(HValue* left, HValue* right)
2796 : HBitwiseBinaryOperation(left, right) { }
2797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002798 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002800 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002801
2802 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002803 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002804};
2805
2806
2807class HSar: public HBitwiseBinaryOperation {
2808 public:
2809 HSar(HValue* left, HValue* right)
2810 : HBitwiseBinaryOperation(left, right) { }
2811
2812 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002813 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002815 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002816
2817 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002818 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002819};
2820
2821
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002822class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002823 public:
2824 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2825 SetFlag(kChangesOsrEntries);
2826 }
2827
2828 int ast_id() const { return ast_id_; }
2829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002830 virtual Representation RequiredInputRepresentation(int index) const {
2831 return Representation::None();
2832 }
2833
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002834 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835
2836 private:
2837 int ast_id_;
2838};
2839
2840
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002841class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002842 public:
2843 explicit HParameter(unsigned index) : index_(index) {
2844 set_representation(Representation::Tagged());
2845 }
2846
2847 unsigned index() const { return index_; }
2848
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002849 virtual void PrintDataTo(StringStream* stream);
2850
2851 virtual Representation RequiredInputRepresentation(int index) const {
2852 return Representation::None();
2853 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002854
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002855 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002856
2857 private:
2858 unsigned index_;
2859};
2860
2861
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002862class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002864 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2865 : HUnaryCall(context, argument_count),
2866 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002867 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002868 }
2869
2870 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002871
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002872 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002873
2874 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2875 transcendental_type_ = transcendental_type;
2876 }
2877 TranscendentalCache::Type transcendental_type() {
2878 return transcendental_type_;
2879 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002880
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002881 virtual void PrintDataTo(StringStream* stream);
2882
2883 virtual Representation RequiredInputRepresentation(int index) const {
2884 return Representation::Tagged();
2885 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002886
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002887 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002888
2889 private:
2890 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002891 TranscendentalCache::Type transcendental_type_;
2892};
2893
2894
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002895class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002896 public:
2897 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002899 virtual Representation RequiredInputRepresentation(int index) const {
2900 return Representation::None();
2901 }
2902
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002903 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002904};
2905
2906
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002907class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002909 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002910 : cell_(cell), check_hole_value_(check_hole_value) {
2911 set_representation(Representation::Tagged());
2912 SetFlag(kUseGVN);
2913 SetFlag(kDependsOnGlobalVars);
2914 }
2915
2916 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2917 bool check_hole_value() const { return check_hole_value_; }
2918
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002919 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002921 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002922 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923 return reinterpret_cast<intptr_t>(*cell_);
2924 }
2925
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002926 virtual Representation RequiredInputRepresentation(int index) const {
2927 return Representation::None();
2928 }
2929
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002930 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931
2932 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002933 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002934 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002935 return cell_.is_identical_to(b->cell());
2936 }
2937
2938 private:
2939 Handle<JSGlobalPropertyCell> cell_;
2940 bool check_hole_value_;
2941};
2942
2943
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002944class HLoadGlobalGeneric: public HBinaryOperation {
2945 public:
2946 HLoadGlobalGeneric(HValue* context,
2947 HValue* global_object,
2948 Handle<Object> name,
2949 bool for_typeof)
2950 : HBinaryOperation(context, global_object),
2951 name_(name),
2952 for_typeof_(for_typeof) {
2953 set_representation(Representation::Tagged());
2954 SetAllSideEffects();
2955 }
2956
2957 HValue* context() { return OperandAt(0); }
2958 HValue* global_object() { return OperandAt(1); }
2959 Handle<Object> name() const { return name_; }
2960 bool for_typeof() const { return for_typeof_; }
2961
2962 virtual void PrintDataTo(StringStream* stream);
2963
2964 virtual Representation RequiredInputRepresentation(int index) const {
2965 return Representation::Tagged();
2966 }
2967
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002968 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002969
2970 private:
2971 Handle<Object> name_;
2972 bool for_typeof_;
2973};
2974
2975
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002976class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002977 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002978 HStoreGlobalCell(HValue* value,
2979 Handle<JSGlobalPropertyCell> cell,
2980 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002981 : HUnaryOperation(value),
2982 cell_(cell),
2983 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984 SetFlag(kChangesGlobalVars);
2985 }
2986
2987 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002988 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989
2990 virtual Representation RequiredInputRepresentation(int index) const {
2991 return Representation::Tagged();
2992 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002993 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002995 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002997 private:
2998 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002999 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000};
3001
3002
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003003class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3004 public:
3005 HStoreGlobalGeneric(HValue* context,
3006 HValue* global_object,
3007 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003008 HValue* value,
3009 bool strict_mode)
3010 : name_(name),
3011 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003012 SetOperandAt(0, context);
3013 SetOperandAt(1, global_object);
3014 SetOperandAt(2, value);
3015 set_representation(Representation::Tagged());
3016 SetAllSideEffects();
3017 }
3018
3019 HValue* context() { return OperandAt(0); }
3020 HValue* global_object() { return OperandAt(1); }
3021 Handle<Object> name() const { return name_; }
3022 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003023 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003024
3025 virtual void PrintDataTo(StringStream* stream);
3026
3027 virtual Representation RequiredInputRepresentation(int index) const {
3028 return Representation::Tagged();
3029 }
3030
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003031 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003032
3033 private:
3034 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003035 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003036};
3037
3038
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003039class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003040 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003041 HLoadContextSlot(HValue* context , int slot_index)
3042 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003043 set_representation(Representation::Tagged());
3044 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003045 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003046 }
3047
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003048 int slot_index() const { return slot_index_; }
3049
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003050 virtual Representation RequiredInputRepresentation(int index) const {
3051 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003052 }
3053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003054 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003055
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003056 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003057
3058 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003059 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003060 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003061 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003062 }
3063
3064 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003065 int slot_index_;
3066};
3067
3068
3069static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3070 return !value->type().IsSmi() &&
3071 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3072}
3073
3074
3075class HStoreContextSlot: public HBinaryOperation {
3076 public:
3077 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3078 : HBinaryOperation(context, value), slot_index_(slot_index) {
3079 SetFlag(kChangesContextSlots);
3080 }
3081
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003082 HValue* context() { return OperandAt(0); }
3083 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003084 int slot_index() const { return slot_index_; }
3085
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003086 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003087 return StoringValueNeedsWriteBarrier(value());
3088 }
3089
3090 virtual Representation RequiredInputRepresentation(int index) const {
3091 return Representation::Tagged();
3092 }
3093
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003094 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003095
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003096 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003097
3098 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003099 int slot_index_;
3100};
3101
3102
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103class HLoadNamedField: public HUnaryOperation {
3104 public:
3105 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3106 : HUnaryOperation(object),
3107 is_in_object_(is_in_object),
3108 offset_(offset) {
3109 set_representation(Representation::Tagged());
3110 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003111 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112 if (is_in_object) {
3113 SetFlag(kDependsOnInobjectFields);
3114 } else {
3115 SetFlag(kDependsOnBackingStoreFields);
3116 }
3117 }
3118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003119 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120 bool is_in_object() const { return is_in_object_; }
3121 int offset() const { return offset_; }
3122
3123 virtual Representation RequiredInputRepresentation(int index) const {
3124 return Representation::Tagged();
3125 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003126 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003128 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129
3130 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003131 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132 HLoadNamedField* b = HLoadNamedField::cast(other);
3133 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3134 }
3135
3136 private:
3137 bool is_in_object_;
3138 int offset_;
3139};
3140
3141
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003142class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3143 public:
3144 HLoadNamedFieldPolymorphic(HValue* object,
3145 ZoneMapList* types,
3146 Handle<String> name);
3147
3148 HValue* object() { return OperandAt(0); }
3149 ZoneMapList* types() { return &types_; }
3150 Handle<String> name() { return name_; }
3151 bool need_generic() { return need_generic_; }
3152
3153 virtual Representation RequiredInputRepresentation(int index) const {
3154 return Representation::Tagged();
3155 }
3156
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003157 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003158
3159 static const int kMaxLoadPolymorphism = 4;
3160
3161 protected:
3162 virtual bool DataEquals(HValue* value);
3163
3164 private:
3165 ZoneMapList types_;
3166 Handle<String> name_;
3167 bool need_generic_;
3168};
3169
3170
3171
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003172class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003174 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3175 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003177 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178 }
3179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003180 HValue* context() { return OperandAt(0); }
3181 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 Handle<Object> name() const { return name_; }
3183
3184 virtual Representation RequiredInputRepresentation(int index) const {
3185 return Representation::Tagged();
3186 }
3187
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003188 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003189
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190 private:
3191 Handle<Object> name_;
3192};
3193
3194
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003195class HLoadFunctionPrototype: public HUnaryOperation {
3196 public:
3197 explicit HLoadFunctionPrototype(HValue* function)
3198 : HUnaryOperation(function) {
3199 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003200 SetFlag(kUseGVN);
3201 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003202 }
3203
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003204 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003205
3206 virtual Representation RequiredInputRepresentation(int index) const {
3207 return Representation::Tagged();
3208 }
3209
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003210 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003211
3212 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003213 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003214};
3215
3216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003217class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003218 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003219 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003220 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003221 SetFlag(kDependsOnArrayElements);
3222 SetFlag(kUseGVN);
3223 }
3224
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003225 HValue* object() { return OperandAt(0); }
3226 HValue* key() { return OperandAt(1); }
3227
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003228 virtual Representation RequiredInputRepresentation(int index) const {
3229 // The key is supposed to be Integer32.
3230 return (index == 1) ? Representation::Integer32()
3231 : Representation::Tagged();
3232 }
3233
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003234 virtual void PrintDataTo(StringStream* stream);
3235
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003236 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003237
3238 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003239 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003240};
3241
3242
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003243class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003244 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003245 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3246 HValue* key,
3247 ExternalArrayType array_type)
3248 : HBinaryOperation(external_elements, key),
3249 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003250 if (array_type == kExternalFloatArray ||
3251 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003252 set_representation(Representation::Double());
3253 } else {
3254 set_representation(Representation::Integer32());
3255 }
3256 SetFlag(kDependsOnSpecializedArrayElements);
3257 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003258 SetFlag(kDependsOnCalls);
3259 SetFlag(kUseGVN);
3260 }
3261
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003262 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003263
3264 virtual Representation RequiredInputRepresentation(int index) const {
3265 // The key is supposed to be Integer32, but the base pointer
3266 // for the element load is a naked pointer.
3267 return (index == 1) ? Representation::Integer32()
3268 : Representation::External();
3269 }
3270
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003271 HValue* external_pointer() { return OperandAt(0); }
3272 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003273 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003274
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003275 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003276
3277 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003278 virtual bool DataEquals(HValue* other) {
3279 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3280 HLoadKeyedSpecializedArrayElement* cast_other =
3281 HLoadKeyedSpecializedArrayElement::cast(other);
3282 return array_type_ == cast_other->array_type();
3283 }
3284
3285 private:
3286 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003287};
3288
3289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003290class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003291 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003292 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3293 set_representation(Representation::Tagged());
3294 SetOperandAt(0, obj);
3295 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003296 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003297 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003298 }
3299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003300 HValue* object() { return OperandAt(0); }
3301 HValue* key() { return OperandAt(1); }
3302 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003303
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003304 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003305
3306 virtual Representation RequiredInputRepresentation(int index) const {
3307 return Representation::Tagged();
3308 }
3309
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003310 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003311};
3312
3313
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003314class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003315 public:
3316 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003317 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003318 HValue* val,
3319 bool in_object,
3320 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003321 : HBinaryOperation(obj, val),
3322 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003323 is_in_object_(in_object),
3324 offset_(offset) {
3325 if (is_in_object_) {
3326 SetFlag(kChangesInobjectFields);
3327 } else {
3328 SetFlag(kChangesBackingStoreFields);
3329 }
3330 }
3331
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003332 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003333
3334 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003335 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003336 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003337 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003338
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003339 HValue* object() { return OperandAt(0); }
3340 HValue* value() { return OperandAt(1); }
3341
3342 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003343 bool is_in_object() const { return is_in_object_; }
3344 int offset() const { return offset_; }
3345 Handle<Map> transition() const { return transition_; }
3346 void set_transition(Handle<Map> map) { transition_ = map; }
3347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003348 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003349 return StoringValueNeedsWriteBarrier(value());
3350 }
3351
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003352 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003353 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003354 bool is_in_object_;
3355 int offset_;
3356 Handle<Map> transition_;
3357};
3358
3359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003360class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003361 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003362 HStoreNamedGeneric(HValue* context,
3363 HValue* object,
3364 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003365 HValue* value,
3366 bool strict_mode)
3367 : name_(name),
3368 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003369 SetOperandAt(0, object);
3370 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003371 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003372 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003373 }
3374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003375 HValue* object() { return OperandAt(0); }
3376 HValue* value() { return OperandAt(1); }
3377 HValue* context() { return OperandAt(2); }
3378 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003379 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003381 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003382
3383 virtual Representation RequiredInputRepresentation(int index) const {
3384 return Representation::Tagged();
3385 }
3386
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003387 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003388
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003389 private:
3390 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003391 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003392};
3393
3394
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003395class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003396 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003397 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3398 SetOperandAt(0, obj);
3399 SetOperandAt(1, key);
3400 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401 SetFlag(kChangesArrayElements);
3402 }
3403
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003404 virtual Representation RequiredInputRepresentation(int index) const {
3405 // The key is supposed to be Integer32.
3406 return (index == 1) ? Representation::Integer32()
3407 : Representation::Tagged();
3408 }
3409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003410 HValue* object() { return OperandAt(0); }
3411 HValue* key() { return OperandAt(1); }
3412 HValue* value() { return OperandAt(2); }
3413
3414 bool NeedsWriteBarrier() {
3415 return StoringValueNeedsWriteBarrier(value());
3416 }
3417
3418 virtual void PrintDataTo(StringStream* stream);
3419
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003420 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003421};
3422
3423
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003424class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003425 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003426 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3427 HValue* key,
3428 HValue* val,
3429 ExternalArrayType array_type)
3430 : array_type_(array_type) {
3431 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003432 SetOperandAt(0, external_elements);
3433 SetOperandAt(1, key);
3434 SetOperandAt(2, val);
3435 }
3436
3437 virtual void PrintDataTo(StringStream* stream);
3438
3439 virtual Representation RequiredInputRepresentation(int index) const {
3440 if (index == 0) {
3441 return Representation::External();
3442 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003443 if (index == 2 && (array_type() == kExternalFloatArray ||
3444 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003445 return Representation::Double();
3446 } else {
3447 return Representation::Integer32();
3448 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003449 }
3450 }
3451
3452 HValue* external_pointer() { return OperandAt(0); }
3453 HValue* key() { return OperandAt(1); }
3454 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003455 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003456
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003457 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3458
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003459 private:
3460 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003461};
3462
3463
3464class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003466 HStoreKeyedGeneric(HValue* context,
3467 HValue* object,
3468 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003469 HValue* value,
3470 bool strict_mode)
3471 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003472 SetOperandAt(0, object);
3473 SetOperandAt(1, key);
3474 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003475 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003476 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003477 }
3478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003479 HValue* object() { return OperandAt(0); }
3480 HValue* key() { return OperandAt(1); }
3481 HValue* value() { return OperandAt(2); }
3482 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003483 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003484
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003485 virtual Representation RequiredInputRepresentation(int index) const {
3486 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003487 }
3488
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003489 virtual void PrintDataTo(StringStream* stream);
3490
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003491 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003492
3493 private:
3494 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003495};
3496
3497
danno@chromium.org160a7b02011-04-18 15:51:38 +00003498class HStringAdd: public HBinaryOperation {
3499 public:
3500 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3501 set_representation(Representation::Tagged());
3502 SetFlag(kUseGVN);
3503 SetFlag(kDependsOnMaps);
3504 }
3505
3506 virtual Representation RequiredInputRepresentation(int index) const {
3507 return Representation::Tagged();
3508 }
3509
3510 virtual HType CalculateInferredType() {
3511 return HType::String();
3512 }
3513
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003514 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003515
3516 protected:
3517 virtual bool DataEquals(HValue* other) { return true; }
3518};
3519
3520
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003521class HStringCharCodeAt: public HBinaryOperation {
3522 public:
3523 HStringCharCodeAt(HValue* string, HValue* index)
3524 : HBinaryOperation(string, index) {
3525 set_representation(Representation::Integer32());
3526 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003527 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003528 }
3529
3530 virtual Representation RequiredInputRepresentation(int index) const {
3531 // The index is supposed to be Integer32.
3532 return (index == 1) ? Representation::Integer32()
3533 : Representation::Tagged();
3534 }
3535
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003536 HValue* string() { return OperandAt(0); }
3537 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003538
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003539 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003540
3541 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003542 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003543
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003544 virtual Range* InferRange() {
3545 return new Range(0, String::kMaxUC16CharCode);
3546 }
3547};
3548
3549
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003550class HStringCharFromCode: public HUnaryOperation {
3551 public:
3552 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3553 set_representation(Representation::Tagged());
3554 SetFlag(kUseGVN);
3555 }
3556
3557 virtual Representation RequiredInputRepresentation(int index) const {
3558 return Representation::Integer32();
3559 }
3560
3561 virtual bool DataEquals(HValue* other) { return true; }
3562
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003563 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003564};
3565
3566
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003567class HStringLength: public HUnaryOperation {
3568 public:
3569 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3570 set_representation(Representation::Tagged());
3571 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003572 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003573 }
3574
3575 virtual Representation RequiredInputRepresentation(int index) const {
3576 return Representation::Tagged();
3577 }
3578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003580 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3581 return HType::Smi();
3582 }
3583
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003584 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003585
3586 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003587 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003588
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003589 virtual Range* InferRange() {
3590 return new Range(0, String::kMaxLength);
3591 }
3592};
3593
3594
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003595template <int V>
3596class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003597 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003598 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003600 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003601 }
3602
3603 int literal_index() const { return literal_index_; }
3604 int depth() const { return depth_; }
3605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003606 private:
3607 int literal_index_;
3608 int depth_;
3609};
3610
3611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003612class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613 public:
3614 HArrayLiteral(Handle<FixedArray> constant_elements,
3615 int length,
3616 int literal_index,
3617 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003618 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619 length_(length),
3620 constant_elements_(constant_elements) {}
3621
3622 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3623 int length() const { return length_; }
3624
3625 bool IsCopyOnWrite() const;
3626
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003627 virtual Representation RequiredInputRepresentation(int index) const {
3628 return Representation::None();
3629 }
3630
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003631 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632
3633 private:
3634 int length_;
3635 Handle<FixedArray> constant_elements_;
3636};
3637
3638
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003639class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003640 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003641 HObjectLiteral(HValue* context,
3642 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643 bool fast_elements,
3644 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003645 int depth,
3646 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003647 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003648 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003649 fast_elements_(fast_elements),
3650 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003651 SetOperandAt(0, context);
3652 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003654 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003655 Handle<FixedArray> constant_properties() const {
3656 return constant_properties_;
3657 }
3658 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003659 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003661 virtual Representation RequiredInputRepresentation(int index) const {
3662 return Representation::Tagged();
3663 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003664
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003665 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003666
3667 private:
3668 Handle<FixedArray> constant_properties_;
3669 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003670 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003671};
3672
3673
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003674class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003675 public:
3676 HRegExpLiteral(Handle<String> pattern,
3677 Handle<String> flags,
3678 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003679 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680 pattern_(pattern),
3681 flags_(flags) { }
3682
3683 Handle<String> pattern() { return pattern_; }
3684 Handle<String> flags() { return flags_; }
3685
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003686 virtual Representation RequiredInputRepresentation(int index) const {
3687 return Representation::None();
3688 }
3689
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003690 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691
3692 private:
3693 Handle<String> pattern_;
3694 Handle<String> flags_;
3695};
3696
3697
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003698class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003699 public:
3700 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3701 : shared_info_(shared), pretenure_(pretenure) {
3702 set_representation(Representation::Tagged());
3703 }
3704
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003705 virtual Representation RequiredInputRepresentation(int index) const {
3706 return Representation::None();
3707 }
3708
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003709 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003710
3711 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3712 bool pretenure() const { return pretenure_; }
3713
3714 private:
3715 Handle<SharedFunctionInfo> shared_info_;
3716 bool pretenure_;
3717};
3718
3719
3720class HTypeof: public HUnaryOperation {
3721 public:
3722 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3723 set_representation(Representation::Tagged());
3724 }
3725
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003726 virtual Representation RequiredInputRepresentation(int index) const {
3727 return Representation::Tagged();
3728 }
3729
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003730 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731};
3732
3733
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003734class HToFastProperties: public HUnaryOperation {
3735 public:
3736 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3737 // This instruction is not marked as having side effects, but
3738 // changes the map of the input operand. Use it only when creating
3739 // object literals.
3740 ASSERT(value->IsObjectLiteral());
3741 set_representation(Representation::Tagged());
3742 }
3743
3744 virtual Representation RequiredInputRepresentation(int index) const {
3745 return Representation::Tagged();
3746 }
3747
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003748 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003749};
3750
3751
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003752class HValueOf: public HUnaryOperation {
3753 public:
3754 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3755 set_representation(Representation::Tagged());
3756 }
3757
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003758 virtual Representation RequiredInputRepresentation(int index) const {
3759 return Representation::Tagged();
3760 }
3761
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003762 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003763};
3764
3765
3766class HDeleteProperty: public HBinaryOperation {
3767 public:
3768 HDeleteProperty(HValue* obj, HValue* key)
3769 : HBinaryOperation(obj, key) {
3770 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003771 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003772 }
3773
3774 virtual Representation RequiredInputRepresentation(int index) const {
3775 return Representation::Tagged();
3776 }
3777
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003778 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003779
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003780 HValue* object() { return left(); }
3781 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003782};
3783
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003784
3785class HIn: public HTemplateInstruction<2> {
3786 public:
3787 HIn(HValue* key, HValue* object) {
3788 SetOperandAt(0, key);
3789 SetOperandAt(1, object);
3790 set_representation(Representation::Tagged());
3791 SetAllSideEffects();
3792 }
3793
3794 HValue* key() { return OperandAt(0); }
3795 HValue* object() { return OperandAt(1); }
3796
3797 virtual Representation RequiredInputRepresentation(int index) const {
3798 return Representation::Tagged();
3799 }
3800
3801 virtual HType CalculateInferredType() {
3802 return HType::Boolean();
3803 }
3804
3805 virtual void PrintDataTo(StringStream* stream);
3806
3807 DECLARE_CONCRETE_INSTRUCTION(In)
3808};
3809
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003810#undef DECLARE_INSTRUCTION
3811#undef DECLARE_CONCRETE_INSTRUCTION
3812
3813} } // namespace v8::internal
3814
3815#endif // V8_HYDROGEN_INSTRUCTIONS_H_