blob: 5a502e5cd116e2d54f8510d12f92d17158e021f3 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
38#include "zone.h"
39
40namespace v8 {
41namespace internal {
42
43// Forward declarations.
44class HBasicBlock;
45class HEnvironment;
46class HInstruction;
47class HLoopInformation;
48class HValue;
49class LInstruction;
50class LChunkBuilder;
51
52
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000053#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 V(ControlInstruction) \
56 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057
58
59#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000060 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061 V(AccessArgumentsAt) \
62 V(Add) \
63 V(ApplyArguments) \
64 V(ArgumentsElements) \
65 V(ArgumentsLength) \
66 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067 V(ArrayLiteral) \
68 V(BitAnd) \
69 V(BitNot) \
70 V(BitOr) \
71 V(BitXor) \
72 V(BlockEntry) \
73 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000074 V(CallConstantFunction) \
75 V(CallFunction) \
76 V(CallGlobal) \
77 V(CallKeyed) \
78 V(CallKnownGlobal) \
79 V(CallNamed) \
80 V(CallNew) \
81 V(CallRuntime) \
82 V(CallStub) \
83 V(Change) \
84 V(CheckFunction) \
85 V(CheckInstanceType) \
86 V(CheckMap) \
87 V(CheckNonSmi) \
88 V(CheckPrototypeMaps) \
89 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000090 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000091 V(Compare) \
92 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000093 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000094 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000095 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000096 V(DeleteProperty) \
97 V(Deoptimize) \
98 V(Div) \
99 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000100 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000101 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000103 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000104 V(GlobalObject) \
105 V(GlobalReceiver) \
106 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000107 V(HasInstanceType) \
108 V(HasCachedArrayIndex) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000109 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000111 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000112 V(InvokeFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000114 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000116 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000117 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000119 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000121 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000122 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000123 V(LoadGlobalCell) \
124 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadKeyedFastElement) \
126 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000127 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000129 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130 V(LoadNamedGeneric) \
131 V(Mod) \
132 V(Mul) \
133 V(ObjectLiteral) \
134 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000135 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000137 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(PushArgument) \
139 V(RegExpLiteral) \
140 V(Return) \
141 V(Sar) \
142 V(Shl) \
143 V(Shr) \
144 V(Simulate) \
145 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000146 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000147 V(StoreGlobalCell) \
148 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000149 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000150 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000151 V(StoreKeyedGeneric) \
152 V(StoreNamedField) \
153 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000154 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000155 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000156 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000157 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000159 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000161 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000162 V(Typeof) \
163 V(TypeofIs) \
164 V(UnaryMathOperation) \
165 V(UnknownOSRValue) \
166 V(ValueOf)
167
168#define GVN_FLAG_LIST(V) \
169 V(Calls) \
170 V(InobjectFields) \
171 V(BackingStoreFields) \
172 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000173 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(GlobalVars) \
175 V(Maps) \
176 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000177 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178 V(OsrEntries)
179
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000180#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 virtual bool Is##type() const { return true; } \
182 static H##type* cast(HValue* value) { \
183 ASSERT(value->Is##type()); \
184 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000185 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000186
187
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000188#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000189 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000190 static H##type* cast(HValue* value) { \
191 ASSERT(value->Is##type()); \
192 return reinterpret_cast<H##type*>(value); \
193 } \
194 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195
196
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197class Range: public ZoneObject {
198 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000199 Range()
200 : lower_(kMinInt),
201 upper_(kMaxInt),
202 next_(NULL),
203 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204
205 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000206 : lower_(lower),
207 upper_(upper),
208 next_(NULL),
209 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000210
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211 int32_t upper() const { return upper_; }
212 int32_t lower() const { return lower_; }
213 Range* next() const { return next_; }
214 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
215 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000217 int32_t Mask() const;
218 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
219 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
220 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
221 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000222 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
223 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
224 bool IsInSmiRange() const {
225 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000227 void KeepOrder();
228 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000229
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230 void StackUpon(Range* other) {
231 Intersect(other);
232 next_ = other;
233 }
234
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000235 void Intersect(Range* other);
236 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000238 void AddConstant(int32_t value);
239 void Sar(int32_t value);
240 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000241 bool AddAndCheckOverflow(Range* other);
242 bool SubAndCheckOverflow(Range* other);
243 bool MulAndCheckOverflow(Range* other);
244
245 private:
246 int32_t lower_;
247 int32_t upper_;
248 Range* next_;
249 bool can_be_minus_zero_;
250};
251
252
253class Representation {
254 public:
255 enum Kind {
256 kNone,
257 kTagged,
258 kDouble,
259 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000260 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000261 kNumRepresentations
262 };
263
264 Representation() : kind_(kNone) { }
265
266 static Representation None() { return Representation(kNone); }
267 static Representation Tagged() { return Representation(kTagged); }
268 static Representation Integer32() { return Representation(kInteger32); }
269 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000270 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000271
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000272 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 return kind_ == other.kind_;
274 }
275
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000276 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000277 bool IsNone() const { return kind_ == kNone; }
278 bool IsTagged() const { return kind_ == kTagged; }
279 bool IsInteger32() const { return kind_ == kInteger32; }
280 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000281 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282 bool IsSpecialization() const {
283 return kind_ == kInteger32 || kind_ == kDouble;
284 }
285 const char* Mnemonic() const;
286
287 private:
288 explicit Representation(Kind k) : kind_(k) { }
289
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000290 // Make sure kind fits in int8.
291 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
292
293 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000294};
295
296
297class HType {
298 public:
299 HType() : type_(kUninitialized) { }
300
301 static HType Tagged() { return HType(kTagged); }
302 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
303 static HType TaggedNumber() { return HType(kTaggedNumber); }
304 static HType Smi() { return HType(kSmi); }
305 static HType HeapNumber() { return HType(kHeapNumber); }
306 static HType String() { return HType(kString); }
307 static HType Boolean() { return HType(kBoolean); }
308 static HType NonPrimitive() { return HType(kNonPrimitive); }
309 static HType JSArray() { return HType(kJSArray); }
310 static HType JSObject() { return HType(kJSObject); }
311 static HType Uninitialized() { return HType(kUninitialized); }
312
313 // Return the weakest (least precise) common type.
314 HType Combine(HType other) {
315 return HType(static_cast<Type>(type_ & other.type_));
316 }
317
318 bool Equals(const HType& other) {
319 return type_ == other.type_;
320 }
321
322 bool IsSubtypeOf(const HType& other) {
323 return Combine(other).Equals(other);
324 }
325
326 bool IsTagged() {
327 ASSERT(type_ != kUninitialized);
328 return ((type_ & kTagged) == kTagged);
329 }
330
331 bool IsTaggedPrimitive() {
332 ASSERT(type_ != kUninitialized);
333 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
334 }
335
336 bool IsTaggedNumber() {
337 ASSERT(type_ != kUninitialized);
338 return ((type_ & kTaggedNumber) == kTaggedNumber);
339 }
340
341 bool IsSmi() {
342 ASSERT(type_ != kUninitialized);
343 return ((type_ & kSmi) == kSmi);
344 }
345
346 bool IsHeapNumber() {
347 ASSERT(type_ != kUninitialized);
348 return ((type_ & kHeapNumber) == kHeapNumber);
349 }
350
351 bool IsString() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kString) == kString);
354 }
355
356 bool IsBoolean() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kBoolean) == kBoolean);
359 }
360
361 bool IsNonPrimitive() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kNonPrimitive) == kNonPrimitive);
364 }
365
366 bool IsJSArray() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kJSArray) == kJSArray);
369 }
370
371 bool IsJSObject() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kJSObject) == kJSObject);
374 }
375
376 bool IsUninitialized() {
377 return type_ == kUninitialized;
378 }
379
380 static HType TypeFromValue(Handle<Object> value);
381
382 const char* ToString();
383 const char* ToShortString();
384
385 private:
386 enum Type {
387 kTagged = 0x1, // 0000 0000 0000 0001
388 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
389 kTaggedNumber = 0xd, // 0000 0000 0000 1101
390 kSmi = 0x1d, // 0000 0000 0001 1101
391 kHeapNumber = 0x2d, // 0000 0000 0010 1101
392 kString = 0x45, // 0000 0000 0100 0101
393 kBoolean = 0x85, // 0000 0000 1000 0101
394 kNonPrimitive = 0x101, // 0000 0001 0000 0001
395 kJSObject = 0x301, // 0000 0011 0000 0001
396 kJSArray = 0x701, // 0000 0111 1000 0001
397 kUninitialized = 0x1fff // 0001 1111 1111 1111
398 };
399
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000400 // Make sure type fits in int16.
401 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
402
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000403 explicit HType(Type t) : type_(t) { }
404
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000405 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000406};
407
408
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000409class HUseListNode: public ZoneObject {
410 public:
411 HUseListNode(HValue* value, int index, HUseListNode* tail)
412 : tail_(tail), value_(value), index_(index) {
413 }
414
415 HUseListNode* tail() const { return tail_; }
416 HValue* value() const { return value_; }
417 int index() const { return index_; }
418
419 void set_tail(HUseListNode* list) { tail_ = list; }
420
421#ifdef DEBUG
422 void Zap() {
423 tail_ = reinterpret_cast<HUseListNode*>(1);
424 value_ = NULL;
425 index_ = -1;
426 }
427#endif
428
429 private:
430 HUseListNode* tail_;
431 HValue* value_;
432 int index_;
433};
434
435
436// We reuse use list nodes behind the scenes as uses are added and deleted.
437// This class is the safe way to iterate uses while deleting them.
438class HUseIterator BASE_EMBEDDED {
439 public:
440 bool Done() { return current_ == NULL; }
441 void Advance();
442
443 HValue* value() {
444 ASSERT(!Done());
445 return value_;
446 }
447
448 int index() {
449 ASSERT(!Done());
450 return index_;
451 }
452
453 private:
454 explicit HUseIterator(HUseListNode* head);
455
456 HUseListNode* current_;
457 HUseListNode* next_;
458 HValue* value_;
459 int index_;
460
461 friend class HValue;
462};
463
464
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000465class HValue: public ZoneObject {
466 public:
467 static const int kNoNumber = -1;
468
469 // There must be one corresponding kDepends flag for every kChanges flag and
470 // the order of the kChanges flags must be exactly the same as of the kDepends
471 // flags.
472 enum Flag {
473 // Declare global value numbering flags.
474 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
475 GVN_FLAG_LIST(DECLARE_DO)
476 #undef DECLARE_DO
477 kFlexibleRepresentation,
478 kUseGVN,
479 kCanOverflow,
480 kBailoutOnMinusZero,
481 kCanBeDivByZero,
482 kIsArguments,
483 kTruncatingToInt32,
484 kLastFlag = kTruncatingToInt32
485 };
486
487 STATIC_ASSERT(kLastFlag < kBitsPerInt);
488
489 static const int kChangesToDependsFlagsLeftShift = 1;
490
491 static int ChangesFlagsMask() {
492 int result = 0;
493 // Create changes mask.
494#define DECLARE_DO(type) result |= (1 << kChanges##type);
495 GVN_FLAG_LIST(DECLARE_DO)
496#undef DECLARE_DO
497 return result;
498 }
499
500 static int DependsFlagsMask() {
501 return ConvertChangesToDependsFlags(ChangesFlagsMask());
502 }
503
504 static int ConvertChangesToDependsFlags(int flags) {
505 return flags << kChangesToDependsFlagsLeftShift;
506 }
507
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000508 static HValue* cast(HValue* value) { return value; }
509
510 enum Opcode {
511 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000512 #define DECLARE_OPCODE(type) k##type,
513 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
514 kPhi
515 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000516 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000517 virtual Opcode opcode() const = 0;
518
519 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
520 #define DECLARE_PREDICATE(type) \
521 bool Is##type() const { return opcode() == k##type; }
522 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
523 #undef DECLARE_PREDICATE
524 bool IsPhi() const { return opcode() == kPhi; }
525
526 // Declare virtual predicates for abstract HInstruction or HValue
527 #define DECLARE_PREDICATE(type) \
528 virtual bool Is##type() const { return false; }
529 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
530 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000531
532 HValue() : block_(NULL),
533 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000534 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000535 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000536 range_(NULL),
537 flags_(0) {}
538 virtual ~HValue() {}
539
540 HBasicBlock* block() const { return block_; }
541 void SetBlock(HBasicBlock* block);
542
543 int id() const { return id_; }
544 void set_id(int id) { id_ = id; }
545
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000546 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000547
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000548 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000549 Representation representation() const { return representation_; }
550 void ChangeRepresentation(Representation r) {
551 // Representation was already set and is allowed to be changed.
552 ASSERT(!representation_.IsNone());
553 ASSERT(!r.IsNone());
554 ASSERT(CheckFlag(kFlexibleRepresentation));
555 RepresentationChanged(r);
556 representation_ = r;
557 }
558
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000559 virtual bool IsConvertibleToInteger() const { return true; }
560
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000561 HType type() const { return type_; }
562 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000563 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564 type_ = type;
565 }
566
567 // An operation needs to override this function iff:
568 // 1) it can produce an int32 output.
569 // 2) the true value of its output can potentially be minus zero.
570 // The implementation must set a flag so that it bails out in the case where
571 // it would otherwise output what should be a minus zero as an int32 zero.
572 // If the operation also exists in a form that takes int32 and outputs int32
573 // then the operation should return its input value so that we can propagate
574 // back. There are two operations that need to propagate back to more than
575 // one input. They are phi and binary add. They always return NULL and
576 // expect the caller to take care of things.
577 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
578 visited->Add(id());
579 return NULL;
580 }
581
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582 bool IsDefinedAfter(HBasicBlock* other) const;
583
584 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000585 virtual int OperandCount() = 0;
586 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000587 void SetOperandAt(int index, HValue* value);
588
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000589 void DeleteAndReplaceWith(HValue* other);
590 bool HasNoUses() const { return use_list_ == NULL; }
591 bool HasMultipleUses() const {
592 return use_list_ != NULL && use_list_->tail() != NULL;
593 }
594 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000595 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000596
597 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000598 void SetFlag(Flag f) { flags_ |= (1 << f); }
599 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
600 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
601
602 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
603 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
604 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000605
606 Range* range() const { return range_; }
607 bool HasRange() const { return range_ != NULL; }
608 void AddNewRange(Range* r);
609 void RemoveLastAddedRange();
610 void ComputeInitialRange();
611
612 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000613 virtual Representation RequiredInputRepresentation(int index) const = 0;
614
615 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000616 return representation();
617 }
618
619 // This gives the instruction an opportunity to replace itself with an
620 // instruction that does the same in some better way. To replace an
621 // instruction with a new one, first add the new instruction to the graph,
622 // then return it. Return NULL to have the instruction deleted.
623 virtual HValue* Canonicalize() { return this; }
624
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000625 bool Equals(HValue* other);
626 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000627
628 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000629 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000630 void PrintNameTo(StringStream* stream);
631 static void PrintTypeTo(HType type, StringStream* stream);
632
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000633 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000634
635 // Updated the inferred type of this instruction and returns true if
636 // it has changed.
637 bool UpdateInferredType();
638
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000639 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000640
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000641#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000642 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000643#endif
644
645 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000646 // This function must be overridden for instructions with flag kUseGVN, to
647 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000648 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000649 UNREACHABLE();
650 return false;
651 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652 virtual void RepresentationChanged(Representation to) { }
653 virtual Range* InferRange();
654 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000655 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000656 void clear_block() {
657 ASSERT(block_ != NULL);
658 block_ = NULL;
659 }
660
661 void set_representation(Representation r) {
662 // Representation is set-once.
663 ASSERT(representation_.IsNone() && !r.IsNone());
664 representation_ = r;
665 }
666
667 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000668 // A flag mask to mark an instruction as having arbitrary side effects.
669 static int AllSideEffects() {
670 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
671 }
672
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000673 // Remove the matching use from the use list if present. Returns the
674 // removed list node or NULL.
675 HUseListNode* RemoveUse(HValue* value, int index);
676
677 void ReplaceAllUsesWith(HValue* other);
678
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000679 void RegisterUse(int index, HValue* new_value);
680
681 HBasicBlock* block_;
682
683 // The id of this instruction in the hydrogen graph, assigned when first
684 // added to the graph. Reflects creation order.
685 int id_;
686
687 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000689 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000690 Range* range_;
691 int flags_;
692
693 DISALLOW_COPY_AND_ASSIGN(HValue);
694};
695
696
697class HInstruction: public HValue {
698 public:
699 HInstruction* next() const { return next_; }
700 HInstruction* previous() const { return previous_; }
701
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000702 virtual void PrintTo(StringStream* stream);
703 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000704
705 bool IsLinked() const { return block() != NULL; }
706 void Unlink();
707 void InsertBefore(HInstruction* next);
708 void InsertAfter(HInstruction* previous);
709
710 int position() const { return position_; }
711 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
712 void set_position(int position) { position_ = position; }
713
714 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
715
716#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000717 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000718#endif
719
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000720 // Returns whether this is some kind of deoptimizing check
721 // instruction.
722 virtual bool IsCheckInstruction() const { return false; }
723
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000724 virtual bool IsCall() { return false; }
725
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000726 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000727
728 protected:
729 HInstruction()
730 : next_(NULL),
731 previous_(NULL),
732 position_(RelocInfo::kNoPosition) {
733 SetFlag(kDependsOnOsrEntries);
734 }
735
736 virtual void DeleteFromGraph() { Unlink(); }
737
738 private:
739 void InitializeAsFirst(HBasicBlock* block) {
740 ASSERT(!IsLinked());
741 SetBlock(block);
742 }
743
744 HInstruction* next_;
745 HInstruction* previous_;
746 int position_;
747
748 friend class HBasicBlock;
749};
750
751
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000752class HControlInstruction: public HInstruction {
753 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000754 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
755 : first_successor_(first), second_successor_(second) {
756 }
757
758 HBasicBlock* FirstSuccessor() const { return first_successor_; }
759 HBasicBlock* SecondSuccessor() const { return second_successor_; }
760
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000761 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000762
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000763 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000764
765 private:
766 HBasicBlock* first_successor_;
767 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000768};
769
770
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000771template<int NumElements>
772class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000773 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000774 HOperandContainer() : elems_() { }
775
776 int length() { return NumElements; }
777 HValue*& operator[](int i) {
778 ASSERT(i < length());
779 return elems_[i];
780 }
781
782 private:
783 HValue* elems_[NumElements];
784};
785
786
787template<>
788class HOperandContainer<0> {
789 public:
790 int length() { return 0; }
791 HValue*& operator[](int i) {
792 UNREACHABLE();
793 static HValue* t = 0;
794 return t;
795 }
796};
797
798
799template<int V>
800class HTemplateInstruction : public HInstruction {
801 public:
802 int OperandCount() { return V; }
803 HValue* OperandAt(int i) { return inputs_[i]; }
804
805 protected:
806 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
807
808 private:
809 HOperandContainer<V> inputs_;
810};
811
812
813template<int V>
814class HTemplateControlInstruction : public HControlInstruction {
815 public:
816 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
817 : HControlInstruction(first, second) { }
818 int OperandCount() { return V; }
819 HValue* OperandAt(int i) { return inputs_[i]; }
820
821 protected:
822 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
823
824 private:
825 HOperandContainer<V> inputs_;
826};
827
828
829class HBlockEntry: public HTemplateInstruction<0> {
830 public:
831 virtual Representation RequiredInputRepresentation(int index) const {
832 return Representation::None();
833 }
834
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000835 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000836};
837
838
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000839class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000840 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000841 explicit HDeoptimize(int environment_length)
842 : HControlInstruction(NULL, NULL),
843 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000844
845 virtual Representation RequiredInputRepresentation(int index) const {
846 return Representation::None();
847 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000848
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 virtual int OperandCount() { return values_.length(); }
850 virtual HValue* OperandAt(int index) { return values_[index]; }
851
852 void AddEnvironmentValue(HValue* value) {
853 values_.Add(NULL);
854 SetOperandAt(values_.length() - 1, value);
855 }
856
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000857 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000858
859 protected:
860 virtual void InternalSetOperandAt(int index, HValue* value) {
861 values_[index] = value;
862 }
863
864 private:
865 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000866};
867
868
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000869class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000871 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000872 : HTemplateControlInstruction<0>(target, NULL),
873 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000874
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000875 void set_include_stack_check(bool include_stack_check) {
876 include_stack_check_ = include_stack_check;
877 }
878 bool include_stack_check() const { return include_stack_check_; }
879
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000880 virtual Representation RequiredInputRepresentation(int index) const {
881 return Representation::None();
882 }
883
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000884 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000885
886 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887 bool include_stack_check_;
888};
889
890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000891class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000892 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000893 explicit HUnaryControlInstruction(HValue* value,
894 HBasicBlock* true_target,
895 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000896 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000897 SetOperandAt(0, value);
898 }
899
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000900 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000901
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000902 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903};
904
905
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000906class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000908 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
909 : HUnaryControlInstruction(value, true_target, false_target) {
910 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911 }
912
913 virtual Representation RequiredInputRepresentation(int index) const {
914 return Representation::None();
915 }
916
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000917 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000918};
919
920
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000921class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000922 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000923 HCompareMap(HValue* value,
924 Handle<Map> map,
925 HBasicBlock* true_target,
926 HBasicBlock* false_target)
927 : HUnaryControlInstruction(value, true_target, false_target),
928 map_(map) {
929 ASSERT(true_target != NULL);
930 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000931 ASSERT(!map.is_null());
932 }
933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000934 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000935
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936 Handle<Map> map() const { return map_; }
937
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000938 virtual Representation RequiredInputRepresentation(int index) const {
939 return Representation::Tagged();
940 }
941
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000942 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943
944 private:
945 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000946};
947
948
949class HReturn: public HUnaryControlInstruction {
950 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000951 explicit HReturn(HValue* value)
952 : HUnaryControlInstruction(value, NULL, NULL) {
953 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000954
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000955 virtual Representation RequiredInputRepresentation(int index) const {
956 return Representation::Tagged();
957 }
958
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000959 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960};
961
962
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000963class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000965 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
966
967 virtual Representation RequiredInputRepresentation(int index) const {
968 return Representation::None();
969 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000971 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000972};
973
974
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000975class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976 public:
977 explicit HUnaryOperation(HValue* value) {
978 SetOperandAt(0, value);
979 }
980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000981 HValue* value() { return OperandAt(0); }
982 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983};
984
985
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000986class HThrow: public HUnaryOperation {
987 public:
988 explicit HThrow(HValue* value) : HUnaryOperation(value) {
989 SetAllSideEffects();
990 }
991
992 virtual Representation RequiredInputRepresentation(int index) const {
993 return Representation::Tagged();
994 }
995
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000996 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000997};
998
999
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000class HChange: public HUnaryOperation {
1001 public:
1002 HChange(HValue* value,
1003 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001004 Representation to,
1005 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001006 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001007 ASSERT(!from.IsNone() && !to.IsNone());
1008 ASSERT(!from.Equals(to));
1009 set_representation(to);
1010 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001011 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001012 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1013 value->range()->IsInSmiRange()) {
1014 set_type(HType::Smi());
1015 }
1016 }
1017
1018 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1019
1020 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001021 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022 virtual Representation RequiredInputRepresentation(int index) const {
1023 return from_;
1024 }
1025
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001026 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001027
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001028 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001029
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001030 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001031
1032 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001033 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001034 if (!other->IsChange()) return false;
1035 HChange* change = HChange::cast(other);
1036 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001037 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001038 }
1039
1040 private:
1041 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001042};
1043
1044
1045class HSimulate: public HInstruction {
1046 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001047 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001048 : ast_id_(ast_id),
1049 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001050 values_(2),
1051 assigned_indexes_(2) {}
1052 virtual ~HSimulate() {}
1053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001054 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001055
1056 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1057 int ast_id() const { return ast_id_; }
1058 void set_ast_id(int id) {
1059 ASSERT(!HasAstId());
1060 ast_id_ = id;
1061 }
1062
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063 int pop_count() const { return pop_count_; }
1064 const ZoneList<HValue*>* values() const { return &values_; }
1065 int GetAssignedIndexAt(int index) const {
1066 ASSERT(HasAssignedIndexAt(index));
1067 return assigned_indexes_[index];
1068 }
1069 bool HasAssignedIndexAt(int index) const {
1070 return assigned_indexes_[index] != kNoIndex;
1071 }
1072 void AddAssignedValue(int index, HValue* value) {
1073 AddValue(index, value);
1074 }
1075 void AddPushedValue(HValue* value) {
1076 AddValue(kNoIndex, value);
1077 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001078 virtual int OperandCount() { return values_.length(); }
1079 virtual HValue* OperandAt(int index) { return values_[index]; }
1080
1081 virtual Representation RequiredInputRepresentation(int index) const {
1082 return Representation::None();
1083 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001084
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001085 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001086
1087#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001088 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001089#endif
1090
1091 protected:
1092 virtual void InternalSetOperandAt(int index, HValue* value) {
1093 values_[index] = value;
1094 }
1095
1096 private:
1097 static const int kNoIndex = -1;
1098 void AddValue(int index, HValue* value) {
1099 assigned_indexes_.Add(index);
1100 // Resize the list of pushed values.
1101 values_.Add(NULL);
1102 // Set the operand through the base method in HValue to make sure that the
1103 // use lists are correctly updated.
1104 SetOperandAt(values_.length() - 1, value);
1105 }
1106 int ast_id_;
1107 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108 ZoneList<HValue*> values_;
1109 ZoneList<int> assigned_indexes_;
1110};
1111
1112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001113class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001114 public:
1115 HStackCheck() { }
1116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001117 virtual Representation RequiredInputRepresentation(int index) const {
1118 return Representation::None();
1119 }
1120
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001121 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001122};
1123
1124
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001125class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126 public:
1127 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1128 : closure_(closure), function_(function) {
1129 }
1130
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001131 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001132
1133 Handle<JSFunction> closure() const { return closure_; }
1134 FunctionLiteral* function() const { return function_; }
1135
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001136 virtual Representation RequiredInputRepresentation(int index) const {
1137 return Representation::None();
1138 }
1139
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001140 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001141
1142 private:
1143 Handle<JSFunction> closure_;
1144 FunctionLiteral* function_;
1145};
1146
1147
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001148class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001149 public:
1150 HLeaveInlined() {}
1151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001152 virtual Representation RequiredInputRepresentation(int index) const {
1153 return Representation::None();
1154 }
1155
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001156 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001157};
1158
1159
1160class HPushArgument: public HUnaryOperation {
1161 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001162 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1163 set_representation(Representation::Tagged());
1164 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001165
1166 virtual Representation RequiredInputRepresentation(int index) const {
1167 return Representation::Tagged();
1168 }
1169
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001170 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001171
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001172 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173};
1174
1175
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001176class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001177 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001178 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001179 set_representation(Representation::Tagged());
1180 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001181 }
1182
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001183 virtual Representation RequiredInputRepresentation(int index) const {
1184 return Representation::None();
1185 }
1186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001187 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001188
1189 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001190 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001191};
1192
1193
1194class HOuterContext: public HUnaryOperation {
1195 public:
1196 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1197 set_representation(Representation::Tagged());
1198 SetFlag(kUseGVN);
1199 }
1200
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001201 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 virtual Representation RequiredInputRepresentation(int index) const {
1204 return Representation::Tagged();
1205 }
1206
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001207 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001208 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001209};
1210
1211
1212class HGlobalObject: public HUnaryOperation {
1213 public:
1214 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1215 set_representation(Representation::Tagged());
1216 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001217 }
1218
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001219 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001220
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001221 virtual Representation RequiredInputRepresentation(int index) const {
1222 return Representation::Tagged();
1223 }
1224
ager@chromium.org378b34e2011-01-28 08:04:38 +00001225 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001226 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001227};
1228
1229
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001230class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001231 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001232 explicit HGlobalReceiver(HValue* global_object)
1233 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001234 set_representation(Representation::Tagged());
1235 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001236 }
1237
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001238 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001239
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001240 virtual Representation RequiredInputRepresentation(int index) const {
1241 return Representation::Tagged();
1242 }
1243
ager@chromium.org378b34e2011-01-28 08:04:38 +00001244 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001245 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001246};
1247
1248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001249template <int V>
1250class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001251 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001252 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001253 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1254 this->set_representation(Representation::Tagged());
1255 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001256 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001258 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001259
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001260 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001261
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001262 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001264 private:
1265 int argument_count_;
1266};
1267
1268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001269class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001270 public:
1271 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001272 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001273 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001274 }
1275
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001276 virtual Representation RequiredInputRepresentation(int index) const {
1277 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001278 }
1279
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001280 virtual void PrintDataTo(StringStream* stream);
1281
1282 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001283};
1284
1285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001286class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001287 public:
1288 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001289 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001290 SetOperandAt(0, first);
1291 SetOperandAt(1, second);
1292 }
1293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001294 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001295
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001296 virtual Representation RequiredInputRepresentation(int index) const {
1297 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001298 }
1299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001300 HValue* first() { return OperandAt(0); }
1301 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302};
1303
1304
danno@chromium.org160a7b02011-04-18 15:51:38 +00001305class HInvokeFunction: public HBinaryCall {
1306 public:
1307 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1308 : HBinaryCall(context, function, argument_count) {
1309 }
1310
1311 virtual Representation RequiredInputRepresentation(int index) const {
1312 return Representation::Tagged();
1313 }
1314
1315 HValue* context() { return first(); }
1316 HValue* function() { return second(); }
1317
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001318 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001319};
1320
1321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001322class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323 public:
1324 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001325 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001326
1327 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001328
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001330 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001331 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001332 }
1333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001334 virtual void PrintDataTo(StringStream* stream);
1335
1336 virtual Representation RequiredInputRepresentation(int index) const {
1337 return Representation::None();
1338 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001339
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001340 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001341
1342 private:
1343 Handle<JSFunction> function_;
1344};
1345
1346
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001347class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001348 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001349 HCallKeyed(HValue* context, HValue* key, int argument_count)
1350 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001351 }
1352
1353 virtual Representation RequiredInputRepresentation(int index) const {
1354 return Representation::Tagged();
1355 }
1356
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001357 HValue* context() { return first(); }
1358 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001359
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001360 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001361};
1362
1363
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001364class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001365 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001366 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1367 : HUnaryCall(context, argument_count), name_(name) {
1368 }
1369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001370 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373 Handle<String> name() const { return name_; }
1374
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001375 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001377 virtual Representation RequiredInputRepresentation(int index) const {
1378 return Representation::Tagged();
1379 }
1380
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001381 private:
1382 Handle<String> name_;
1383};
1384
1385
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001386class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001387 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001388 HCallFunction(HValue* context, int argument_count)
1389 : HUnaryCall(context, argument_count) {
1390 }
1391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001392 HValue* context() { return value(); }
1393
1394 virtual Representation RequiredInputRepresentation(int index) const {
1395 return Representation::Tagged();
1396 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001397
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001398 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001399};
1400
1401
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001402class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001404 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1405 : HUnaryCall(context, argument_count), name_(name) {
1406 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001408 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001410 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411 Handle<String> name() const { return name_; }
1412
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001413 virtual Representation RequiredInputRepresentation(int index) const {
1414 return Representation::Tagged();
1415 }
1416
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001417 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001418
1419 private:
1420 Handle<String> name_;
1421};
1422
1423
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001424class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001425 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001426 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001427 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001429 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001430
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001431 Handle<JSFunction> target() const { return target_; }
1432
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001433 virtual Representation RequiredInputRepresentation(int index) const {
1434 return Representation::None();
1435 }
1436
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001437 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438
1439 private:
1440 Handle<JSFunction> target_;
1441};
1442
1443
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001444class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001445 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001446 HCallNew(HValue* context, HValue* constructor, int argument_count)
1447 : HBinaryCall(context, constructor, argument_count) {
1448 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449
1450 virtual Representation RequiredInputRepresentation(int index) const {
1451 return Representation::Tagged();
1452 }
1453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001454 HValue* context() { return first(); }
1455 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001456
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001457 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001458};
1459
1460
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001461class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001462 public:
1463 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001464 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001465 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1467 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001468
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001469 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001470 Handle<String> name() const { return name_; }
1471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001472 virtual Representation RequiredInputRepresentation(int index) const {
1473 return Representation::None();
1474 }
1475
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001476 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477
1478 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001479 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001480 Handle<String> name_;
1481};
1482
1483
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001484class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001485 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001486 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487 // The length of an array is stored as a tagged value in the array
1488 // object. It is guaranteed to be 32 bit integer, but it can be
1489 // represented as either a smi or heap number.
1490 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001491 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001492 SetFlag(kDependsOnArrayLengths);
1493 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001494 }
1495
1496 virtual Representation RequiredInputRepresentation(int index) const {
1497 return Representation::Tagged();
1498 }
1499
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001500 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001501
1502 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001503 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001504};
1505
1506
1507class HFixedArrayLength: public HUnaryOperation {
1508 public:
1509 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1510 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001511 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001512 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001513 }
1514
1515 virtual Representation RequiredInputRepresentation(int index) const {
1516 return Representation::Tagged();
1517 }
1518
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001519 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001520
1521 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001522 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001523};
1524
1525
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001526class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001527 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001528 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001529 set_representation(Representation::Integer32());
1530 // The result of this instruction is idempotent as long as its inputs don't
1531 // change. The length of a pixel array cannot change once set, so it's not
1532 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1533 SetFlag(kUseGVN);
1534 }
1535
1536 virtual Representation RequiredInputRepresentation(int index) const {
1537 return Representation::Tagged();
1538 }
1539
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001540 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001541
1542 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001543 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001544};
1545
1546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547class HBitNot: public HUnaryOperation {
1548 public:
1549 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1550 set_representation(Representation::Integer32());
1551 SetFlag(kUseGVN);
1552 SetFlag(kTruncatingToInt32);
1553 }
1554
1555 virtual Representation RequiredInputRepresentation(int index) const {
1556 return Representation::Integer32();
1557 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001558 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001560 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001561
1562 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001563 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001564};
1565
1566
1567class HUnaryMathOperation: public HUnaryOperation {
1568 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001569 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001570 : HUnaryOperation(value), op_(op) {
1571 switch (op) {
1572 case kMathFloor:
1573 case kMathRound:
1574 case kMathCeil:
1575 set_representation(Representation::Integer32());
1576 break;
1577 case kMathAbs:
1578 set_representation(Representation::Tagged());
1579 SetFlag(kFlexibleRepresentation);
1580 break;
1581 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001582 case kMathPowHalf:
1583 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001584 case kMathSin:
1585 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001587 break;
1588 default:
1589 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001590 }
1591 SetFlag(kUseGVN);
1592 }
1593
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001594 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001596 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
1598 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1599
1600 virtual Representation RequiredInputRepresentation(int index) const {
1601 switch (op_) {
1602 case kMathFloor:
1603 case kMathRound:
1604 case kMathCeil:
1605 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001606 case kMathPowHalf:
1607 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001608 case kMathSin:
1609 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001610 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001611 case kMathAbs:
1612 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001613 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001614 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615 return Representation::None();
1616 }
1617 }
1618
1619 virtual HValue* Canonicalize() {
1620 // If the input is integer32 then we replace the floor instruction
1621 // with its inputs. This happens before the representation changes are
1622 // introduced.
1623 if (op() == kMathFloor) {
1624 if (value()->representation().IsInteger32()) return value();
1625 }
1626 return this;
1627 }
1628
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001629 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001630 const char* OpName() const;
1631
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001632 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001634 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001635 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001636 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1637 return op_ == b->op();
1638 }
1639
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001640 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001641 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001642};
1643
1644
1645class HLoadElements: public HUnaryOperation {
1646 public:
1647 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1648 set_representation(Representation::Tagged());
1649 SetFlag(kUseGVN);
1650 SetFlag(kDependsOnMaps);
1651 }
1652
1653 virtual Representation RequiredInputRepresentation(int index) const {
1654 return Representation::Tagged();
1655 }
1656
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001657 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001658
1659 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001660 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001661};
1662
1663
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001664class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001665 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001666 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001667 : HUnaryOperation(value) {
1668 set_representation(Representation::External());
1669 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001670 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001671 // change once set, so it's no necessary to introduce any additional
1672 // dependencies on top of the inputs.
1673 SetFlag(kUseGVN);
1674 }
1675
1676 virtual Representation RequiredInputRepresentation(int index) const {
1677 return Representation::Tagged();
1678 }
1679
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001680 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001681
1682 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001683 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001684};
1685
1686
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001687class HCheckMap: public HUnaryOperation {
1688 public:
1689 HCheckMap(HValue* value, Handle<Map> map)
1690 : HUnaryOperation(value), map_(map) {
1691 set_representation(Representation::Tagged());
1692 SetFlag(kUseGVN);
1693 SetFlag(kDependsOnMaps);
1694 }
1695
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001696 virtual bool IsCheckInstruction() const { return true; }
1697
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001698 virtual Representation RequiredInputRepresentation(int index) const {
1699 return Representation::Tagged();
1700 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001701 virtual void PrintDataTo(StringStream* stream);
1702 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001703
1704#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001705 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001706#endif
1707
1708 Handle<Map> map() const { return map_; }
1709
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001710 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001711
1712 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001713 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001714 HCheckMap* b = HCheckMap::cast(other);
1715 return map_.is_identical_to(b->map());
1716 }
1717
1718 private:
1719 Handle<Map> map_;
1720};
1721
1722
1723class HCheckFunction: public HUnaryOperation {
1724 public:
1725 HCheckFunction(HValue* value, Handle<JSFunction> function)
1726 : HUnaryOperation(value), target_(function) {
1727 set_representation(Representation::Tagged());
1728 SetFlag(kUseGVN);
1729 }
1730
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001731 virtual bool IsCheckInstruction() const { return true; }
1732
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001733 virtual Representation RequiredInputRepresentation(int index) const {
1734 return Representation::Tagged();
1735 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001736 virtual void PrintDataTo(StringStream* stream);
1737 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001738
1739#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001740 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001741#endif
1742
1743 Handle<JSFunction> target() const { return target_; }
1744
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001745 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746
1747 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001748 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001749 HCheckFunction* b = HCheckFunction::cast(other);
1750 return target_.is_identical_to(b->target());
1751 }
1752
1753 private:
1754 Handle<JSFunction> target_;
1755};
1756
1757
1758class HCheckInstanceType: public HUnaryOperation {
1759 public:
1760 // Check that the instance type is in the range [first, last] where
1761 // both first and last are included.
1762 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1763 : HUnaryOperation(value), first_(first), last_(last) {
1764 ASSERT(first <= last);
1765 set_representation(Representation::Tagged());
1766 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001767 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1768 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1769 // A particular string instance type can change because of GC or
1770 // externalization, but the value still remains a string.
1771 SetFlag(kDependsOnMaps);
1772 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001773 }
1774
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001775 virtual bool IsCheckInstruction() const { return true; }
1776
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001777 virtual Representation RequiredInputRepresentation(int index) const {
1778 return Representation::Tagged();
1779 }
1780
1781#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001782 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001783#endif
1784
danno@chromium.org160a7b02011-04-18 15:51:38 +00001785 virtual HValue* Canonicalize() {
1786 if (!value()->type().IsUninitialized() &&
1787 value()->type().IsString() &&
1788 first() == FIRST_STRING_TYPE &&
1789 last() == LAST_STRING_TYPE) {
1790 return NULL;
1791 }
1792 return this;
1793 }
1794
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1796
1797 InstanceType first() const { return first_; }
1798 InstanceType last() const { return last_; }
1799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001800 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801
1802 protected:
1803 // TODO(ager): It could be nice to allow the ommision of instance
1804 // type checks if we have already performed an instance type check
1805 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001806 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001807 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1808 return (first_ == b->first()) && (last_ == b->last());
1809 }
1810
1811 private:
1812 InstanceType first_;
1813 InstanceType last_;
1814};
1815
1816
1817class HCheckNonSmi: public HUnaryOperation {
1818 public:
1819 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1820 set_representation(Representation::Tagged());
1821 SetFlag(kUseGVN);
1822 }
1823
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001824 virtual bool IsCheckInstruction() const { return true; }
1825
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001826 virtual Representation RequiredInputRepresentation(int index) const {
1827 return Representation::Tagged();
1828 }
1829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001830 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001831
1832#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001833 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001834#endif
1835
danno@chromium.org160a7b02011-04-18 15:51:38 +00001836 virtual HValue* Canonicalize() {
1837 HType value_type = value()->type();
1838 if (!value_type.IsUninitialized() &&
1839 (value_type.IsHeapNumber() ||
1840 value_type.IsString() ||
1841 value_type.IsBoolean() ||
1842 value_type.IsNonPrimitive())) {
1843 return NULL;
1844 }
1845 return this;
1846 }
1847
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001848 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001849
1850 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001851 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001852};
1853
1854
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001855class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001856 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001857 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1858 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001859 SetFlag(kUseGVN);
1860 SetFlag(kDependsOnMaps);
1861 }
1862
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001863 virtual bool IsCheckInstruction() const { return true; }
1864
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001865#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001866 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867#endif
1868
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001869 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001870 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001871
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001872 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001873
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001874 virtual Representation RequiredInputRepresentation(int index) const {
1875 return Representation::None();
1876 }
1877
1878 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001879 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001880 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1881 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1882 return hash;
1883 }
1884
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001885 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001886 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001887 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001888 return prototype_.is_identical_to(b->prototype()) &&
1889 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001890 }
1891
1892 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001893 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001894 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001895};
1896
1897
1898class HCheckSmi: public HUnaryOperation {
1899 public:
1900 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1901 set_representation(Representation::Tagged());
1902 SetFlag(kUseGVN);
1903 }
1904
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001905 virtual bool IsCheckInstruction() const { return true; }
1906
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001907 virtual Representation RequiredInputRepresentation(int index) const {
1908 return Representation::Tagged();
1909 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001910 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911
1912#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001913 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001914#endif
1915
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001916 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001917
1918 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001919 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001920};
1921
1922
1923class HPhi: public HValue {
1924 public:
1925 explicit HPhi(int merged_index)
1926 : inputs_(2),
1927 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001928 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001929 is_live_(false),
1930 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001931 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1932 non_phi_uses_[i] = 0;
1933 indirect_uses_[i] = 0;
1934 }
1935 ASSERT(merged_index >= 0);
1936 set_representation(Representation::Tagged());
1937 SetFlag(kFlexibleRepresentation);
1938 }
1939
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001940 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001941 bool double_occurred = false;
1942 bool int32_occurred = false;
1943 for (int i = 0; i < OperandCount(); ++i) {
1944 HValue* value = OperandAt(i);
1945 if (value->representation().IsDouble()) double_occurred = true;
1946 if (value->representation().IsInteger32()) int32_occurred = true;
1947 if (value->representation().IsTagged()) return Representation::Tagged();
1948 }
1949
1950 if (double_occurred) return Representation::Double();
1951 if (int32_occurred) return Representation::Integer32();
1952 return Representation::None();
1953 }
1954
1955 virtual Range* InferRange();
1956 virtual Representation RequiredInputRepresentation(int index) const {
1957 return representation();
1958 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001959 virtual HType CalculateInferredType();
1960 virtual int OperandCount() { return inputs_.length(); }
1961 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1962 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001964 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001965
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001966 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001967
1968 int merged_index() const { return merged_index_; }
1969
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001970 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971
1972#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001973 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974#endif
1975
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001976 void InitRealUses(int id);
1977 void AddNonPhiUsesFrom(HPhi* other);
1978 void AddIndirectUsesTo(int* use_count);
1979
1980 int tagged_non_phi_uses() const {
1981 return non_phi_uses_[Representation::kTagged];
1982 }
1983 int int32_non_phi_uses() const {
1984 return non_phi_uses_[Representation::kInteger32];
1985 }
1986 int double_non_phi_uses() const {
1987 return non_phi_uses_[Representation::kDouble];
1988 }
1989 int tagged_indirect_uses() const {
1990 return indirect_uses_[Representation::kTagged];
1991 }
1992 int int32_indirect_uses() const {
1993 return indirect_uses_[Representation::kInteger32];
1994 }
1995 int double_indirect_uses() const {
1996 return indirect_uses_[Representation::kDouble];
1997 }
1998 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001999 bool is_live() { return is_live_; }
2000 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002001
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002002 static HPhi* cast(HValue* value) {
2003 ASSERT(value->IsPhi());
2004 return reinterpret_cast<HPhi*>(value);
2005 }
2006 virtual Opcode opcode() const { return HValue::kPhi; }
2007
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002008 virtual bool IsConvertibleToInteger() const {
2009 return is_convertible_to_integer_;
2010 }
2011
2012 void set_is_convertible_to_integer(bool b) {
2013 is_convertible_to_integer_ = b;
2014 }
2015
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002016 protected:
2017 virtual void DeleteFromGraph();
2018 virtual void InternalSetOperandAt(int index, HValue* value) {
2019 inputs_[index] = value;
2020 }
2021
2022 private:
2023 ZoneList<HValue*> inputs_;
2024 int merged_index_;
2025
2026 int non_phi_uses_[Representation::kNumRepresentations];
2027 int indirect_uses_[Representation::kNumRepresentations];
2028 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002029 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002030 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031};
2032
2033
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002034class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002035 public:
2036 HArgumentsObject() {
2037 set_representation(Representation::Tagged());
2038 SetFlag(kIsArguments);
2039 }
2040
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002041 virtual Representation RequiredInputRepresentation(int index) const {
2042 return Representation::None();
2043 }
2044
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002045 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002046};
2047
2048
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002049class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002050 public:
2051 HConstant(Handle<Object> handle, Representation r);
2052
2053 Handle<Object> handle() const { return handle_; }
2054
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002055 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002057 virtual Representation RequiredInputRepresentation(int index) const {
2058 return Representation::None();
2059 }
2060
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002061 virtual bool IsConvertibleToInteger() const {
2062 if (handle_->IsSmi()) return true;
2063 if (handle_->IsHeapNumber() &&
2064 (HeapNumber::cast(*handle_)->value() ==
2065 static_cast<double>(NumberToInt32(*handle_)))) return true;
2066 return false;
2067 }
2068
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002069 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070 virtual void PrintDataTo(StringStream* stream);
2071 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002072 bool IsInteger() const { return handle_->IsSmi(); }
2073 HConstant* CopyToRepresentation(Representation r) const;
2074 HConstant* CopyToTruncatedInt32() const;
2075 bool HasInteger32Value() const { return has_int32_value_; }
2076 int32_t Integer32Value() const {
2077 ASSERT(HasInteger32Value());
2078 return int32_value_;
2079 }
2080 bool HasDoubleValue() const { return has_double_value_; }
2081 double DoubleValue() const {
2082 ASSERT(HasDoubleValue());
2083 return double_value_;
2084 }
2085 bool HasStringValue() const { return handle_->IsString(); }
2086
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002087 bool ToBoolean() const;
2088
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002089 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002090 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091 return reinterpret_cast<intptr_t>(*handle());
2092 }
2093
2094#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002095 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096#endif
2097
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002098 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099
2100 protected:
2101 virtual Range* InferRange();
2102
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002103 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002104 HConstant* other_constant = HConstant::cast(other);
2105 return handle().is_identical_to(other_constant->handle());
2106 }
2107
2108 private:
2109 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002110
2111 // The following two values represent the int32 and the double value of the
2112 // given constant if there is a lossless conversion between the constant
2113 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002114 bool has_int32_value_ : 1;
2115 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117 double double_value_;
2118};
2119
2120
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002121class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122 public:
2123 HBinaryOperation(HValue* left, HValue* right) {
2124 ASSERT(left != NULL && right != NULL);
2125 SetOperandAt(0, left);
2126 SetOperandAt(1, right);
2127 }
2128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002129 HValue* left() { return OperandAt(0); }
2130 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002131
2132 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2133 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002134 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002135 if (IsCommutative() && left()->IsConstant()) return right();
2136 return left();
2137 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002138 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002139 if (IsCommutative() && left()->IsConstant()) return left();
2140 return right();
2141 }
2142
2143 virtual bool IsCommutative() const { return false; }
2144
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002145 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002146};
2147
2148
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002149class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002150 public:
2151 HApplyArguments(HValue* function,
2152 HValue* receiver,
2153 HValue* length,
2154 HValue* elements) {
2155 set_representation(Representation::Tagged());
2156 SetOperandAt(0, function);
2157 SetOperandAt(1, receiver);
2158 SetOperandAt(2, length);
2159 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002160 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161 }
2162
2163 virtual Representation RequiredInputRepresentation(int index) const {
2164 // The length is untagged, all other inputs are tagged.
2165 return (index == 2)
2166 ? Representation::Integer32()
2167 : Representation::Tagged();
2168 }
2169
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002170 HValue* function() { return OperandAt(0); }
2171 HValue* receiver() { return OperandAt(1); }
2172 HValue* length() { return OperandAt(2); }
2173 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002175 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002176};
2177
2178
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002179class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002180 public:
2181 HArgumentsElements() {
2182 // The value produced by this instruction is a pointer into the stack
2183 // that looks as if it was a smi because of alignment.
2184 set_representation(Representation::Tagged());
2185 SetFlag(kUseGVN);
2186 }
2187
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002188 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002189
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002190 virtual Representation RequiredInputRepresentation(int index) const {
2191 return Representation::None();
2192 }
2193
ager@chromium.org378b34e2011-01-28 08:04:38 +00002194 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002195 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002196};
2197
2198
2199class HArgumentsLength: public HUnaryOperation {
2200 public:
2201 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2202 set_representation(Representation::Integer32());
2203 SetFlag(kUseGVN);
2204 }
2205
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002206 virtual Representation RequiredInputRepresentation(int index) const {
2207 return Representation::Tagged();
2208 }
2209
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002210 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002211
2212 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002213 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002214};
2215
2216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002217class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002218 public:
2219 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2220 set_representation(Representation::Tagged());
2221 SetFlag(kUseGVN);
2222 SetOperandAt(0, arguments);
2223 SetOperandAt(1, length);
2224 SetOperandAt(2, index);
2225 }
2226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002227 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002228
2229 virtual Representation RequiredInputRepresentation(int index) const {
2230 // The arguments elements is considered tagged.
2231 return index == 0
2232 ? Representation::Tagged()
2233 : Representation::Integer32();
2234 }
2235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002236 HValue* arguments() { return OperandAt(0); }
2237 HValue* length() { return OperandAt(1); }
2238 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002240 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002241
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002242 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243};
2244
2245
2246class HBoundsCheck: public HBinaryOperation {
2247 public:
2248 HBoundsCheck(HValue* index, HValue* length)
2249 : HBinaryOperation(index, length) {
2250 SetFlag(kUseGVN);
2251 }
2252
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002253 virtual bool IsCheckInstruction() const { return true; }
2254
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002255 virtual Representation RequiredInputRepresentation(int index) const {
2256 return Representation::Integer32();
2257 }
2258
2259#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002260 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002261#endif
2262
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002263 HValue* index() { return left(); }
2264 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002266 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002267
2268 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002269 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002270};
2271
2272
2273class HBitwiseBinaryOperation: public HBinaryOperation {
2274 public:
2275 HBitwiseBinaryOperation(HValue* left, HValue* right)
2276 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002277 set_representation(Representation::Tagged());
2278 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002279 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002280 }
2281
2282 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002283 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284 }
2285
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002286 virtual void RepresentationChanged(Representation to) {
2287 if (!to.IsTagged()) {
2288 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002289 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002290 SetFlag(kTruncatingToInt32);
2291 SetFlag(kUseGVN);
2292 }
2293 }
2294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002295 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002296
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002297 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002298};
2299
2300
2301class HArithmeticBinaryOperation: public HBinaryOperation {
2302 public:
2303 HArithmeticBinaryOperation(HValue* left, HValue* right)
2304 : HBinaryOperation(left, right) {
2305 set_representation(Representation::Tagged());
2306 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002307 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002308 }
2309
2310 virtual void RepresentationChanged(Representation to) {
2311 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002312 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002313 SetFlag(kUseGVN);
2314 }
2315 }
2316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002317 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002318 virtual Representation RequiredInputRepresentation(int index) const {
2319 return representation();
2320 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002321 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002322 if (left()->representation().Equals(right()->representation())) {
2323 return left()->representation();
2324 }
2325 return HValue::InferredRepresentation();
2326 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002327};
2328
2329
2330class HCompare: public HBinaryOperation {
2331 public:
2332 HCompare(HValue* left, HValue* right, Token::Value token)
2333 : HBinaryOperation(left, right), token_(token) {
2334 ASSERT(Token::IsCompareOp(token));
2335 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002336 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002337 }
2338
2339 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002340
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002341 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002342 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002343 }
2344
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002345 virtual Representation RequiredInputRepresentation(int index) const {
2346 return input_representation_;
2347 }
2348 Representation GetInputRepresentation() const {
2349 return input_representation_;
2350 }
2351 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002352 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002353
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002354 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002356 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002357 return HValue::Hashcode() * 7 + token_;
2358 }
2359
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002360 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361
2362 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002363 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002364 HCompare* comp = HCompare::cast(other);
2365 return token_ == comp->token();
2366 }
2367
2368 private:
2369 Representation input_representation_;
2370 Token::Value token_;
2371};
2372
2373
2374class HCompareJSObjectEq: public HBinaryOperation {
2375 public:
2376 HCompareJSObjectEq(HValue* left, HValue* right)
2377 : HBinaryOperation(left, right) {
2378 set_representation(Representation::Tagged());
2379 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002380 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002381 }
2382
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002383 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002384 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002385 }
2386
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002387 virtual Representation RequiredInputRepresentation(int index) const {
2388 return Representation::Tagged();
2389 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002390 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002391
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002392 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002393
2394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002395 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002396};
2397
2398
2399class HUnaryPredicate: public HUnaryOperation {
2400 public:
2401 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2402 set_representation(Representation::Tagged());
2403 SetFlag(kUseGVN);
2404 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002405
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002406 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002407 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002408 }
2409
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002410 virtual Representation RequiredInputRepresentation(int index) const {
2411 return Representation::Tagged();
2412 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002413 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002414};
2415
2416
2417class HIsNull: public HUnaryPredicate {
2418 public:
2419 HIsNull(HValue* value, bool is_strict)
2420 : HUnaryPredicate(value), is_strict_(is_strict) { }
2421
2422 bool is_strict() const { return is_strict_; }
2423
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002424 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002425
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002426 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002427 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002428 HIsNull* b = HIsNull::cast(other);
2429 return is_strict_ == b->is_strict();
2430 }
2431
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002432 private:
2433 bool is_strict_;
2434};
2435
2436
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002437class HIsObject: public HUnaryPredicate {
2438 public:
2439 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2440
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002441 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002442
2443 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002444 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002445};
2446
2447
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002448class HIsSmi: public HUnaryPredicate {
2449 public:
2450 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2451
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002452 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002453
2454 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002455 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002456};
2457
2458
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002459class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002460 public:
2461 HIsConstructCall() {
2462 set_representation(Representation::Tagged());
2463 SetFlag(kUseGVN);
2464 }
2465
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002466 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002467 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002468 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002469
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002470 virtual Representation RequiredInputRepresentation(int index) const {
2471 return Representation::None();
2472 }
2473
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002474 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002475
2476 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002477 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002478};
2479
2480
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002481class HHasInstanceType: public HUnaryPredicate {
2482 public:
2483 HHasInstanceType(HValue* value, InstanceType type)
2484 : HUnaryPredicate(value), from_(type), to_(type) { }
2485 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2486 : HUnaryPredicate(value), from_(from), to_(to) {
2487 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2488 }
2489
2490 InstanceType from() { return from_; }
2491 InstanceType to() { return to_; }
2492
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002493 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002494
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002495 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002496
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002497 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002498 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002499 HHasInstanceType* b = HHasInstanceType::cast(other);
2500 return (from_ == b->from()) && (to_ == b->to());
2501 }
2502
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002503 private:
2504 InstanceType from_;
2505 InstanceType to_; // Inclusive range, not all combinations work.
2506};
2507
2508
2509class HHasCachedArrayIndex: public HUnaryPredicate {
2510 public:
2511 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2512
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002513 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002514
2515 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002516 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002517};
2518
2519
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002520class HGetCachedArrayIndex: public HUnaryPredicate {
2521 public:
2522 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2523
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002524 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002525
2526 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002527 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002528};
2529
2530
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531class HClassOfTest: public HUnaryPredicate {
2532 public:
2533 HClassOfTest(HValue* value, Handle<String> class_name)
2534 : HUnaryPredicate(value), class_name_(class_name) { }
2535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002536 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002537
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002538 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002539
2540 Handle<String> class_name() const { return class_name_; }
2541
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002542 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002543 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002544 HClassOfTest* b = HClassOfTest::cast(other);
2545 return class_name_.is_identical_to(b->class_name_);
2546 }
2547
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 private:
2549 Handle<String> class_name_;
2550};
2551
2552
2553class HTypeofIs: public HUnaryPredicate {
2554 public:
2555 HTypeofIs(HValue* value, Handle<String> type_literal)
2556 : HUnaryPredicate(value), type_literal_(type_literal) { }
2557
2558 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002559 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002561 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002562
2563 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002564 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002565 HTypeofIs* b = HTypeofIs::cast(other);
2566 return type_literal_.is_identical_to(b->type_literal_);
2567 }
2568
2569 private:
2570 Handle<String> type_literal_;
2571};
2572
2573
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002574class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002576 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2577 SetOperandAt(0, context);
2578 SetOperandAt(1, left);
2579 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002580 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002581 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002582 }
2583
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002584 HValue* context() { return OperandAt(0); }
2585 HValue* left() { return OperandAt(1); }
2586 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002587
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002588 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002589 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002590 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002591
2592 virtual Representation RequiredInputRepresentation(int index) const {
2593 return Representation::Tagged();
2594 }
2595
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002596 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002597
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002598 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002599};
2600
2601
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002602class HInstanceOfKnownGlobal: public HUnaryOperation {
2603 public:
2604 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2605 : HUnaryOperation(left), function_(right) {
2606 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002607 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002608 }
2609
2610 Handle<JSFunction> function() { return function_; }
2611
2612 virtual Representation RequiredInputRepresentation(int index) const {
2613 return Representation::Tagged();
2614 }
2615
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002616 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002617
2618 private:
2619 Handle<JSFunction> function_;
2620};
2621
2622
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002623class HPower: public HBinaryOperation {
2624 public:
2625 HPower(HValue* left, HValue* right)
2626 : HBinaryOperation(left, right) {
2627 set_representation(Representation::Double());
2628 SetFlag(kUseGVN);
2629 }
2630
2631 virtual Representation RequiredInputRepresentation(int index) const {
2632 return (index == 1) ? Representation::None() : Representation::Double();
2633 }
2634
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002635 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002636
2637 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002638 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002639};
2640
2641
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002642class HAdd: public HArithmeticBinaryOperation {
2643 public:
2644 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2645 SetFlag(kCanOverflow);
2646 }
2647
2648 // Add is only commutative if two integer values are added and not if two
2649 // tagged values are added (because it might be a String concatenation).
2650 virtual bool IsCommutative() const {
2651 return !representation().IsTagged();
2652 }
2653
2654 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2655
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002656 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002657
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002658 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002659
2660 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002661 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002662
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002663 virtual Range* InferRange();
2664};
2665
2666
2667class HSub: public HArithmeticBinaryOperation {
2668 public:
2669 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2670 SetFlag(kCanOverflow);
2671 }
2672
2673 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2674
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002675 DECLARE_CONCRETE_INSTRUCTION(Sub)
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 HMul: public HArithmeticBinaryOperation {
2685 public:
2686 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2687 SetFlag(kCanOverflow);
2688 }
2689
2690 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2691
2692 // Only commutative if it is certain that not two objects are multiplicated.
2693 virtual bool IsCommutative() const {
2694 return !representation().IsTagged();
2695 }
2696
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002697 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002698
2699 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002700 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002701
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002702 virtual Range* InferRange();
2703};
2704
2705
2706class HMod: public HArithmeticBinaryOperation {
2707 public:
2708 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2709 SetFlag(kCanBeDivByZero);
2710 }
2711
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002712 bool HasPowerOf2Divisor() {
2713 if (right()->IsConstant() &&
2714 HConstant::cast(right())->HasInteger32Value()) {
2715 int32_t value = HConstant::cast(right())->Integer32Value();
2716 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2717 }
2718
2719 return false;
2720 }
2721
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2723
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002724 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725
2726 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002727 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002729 virtual Range* InferRange();
2730};
2731
2732
2733class HDiv: public HArithmeticBinaryOperation {
2734 public:
2735 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2736 SetFlag(kCanBeDivByZero);
2737 SetFlag(kCanOverflow);
2738 }
2739
2740 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2741
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002742 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743
2744 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002745 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002746
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747 virtual Range* InferRange();
2748};
2749
2750
2751class HBitAnd: public HBitwiseBinaryOperation {
2752 public:
2753 HBitAnd(HValue* left, HValue* right)
2754 : HBitwiseBinaryOperation(left, right) { }
2755
2756 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002757 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002758
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002759 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760
2761 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002762 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002763
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764 virtual Range* InferRange();
2765};
2766
2767
2768class HBitXor: public HBitwiseBinaryOperation {
2769 public:
2770 HBitXor(HValue* left, HValue* right)
2771 : HBitwiseBinaryOperation(left, right) { }
2772
2773 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002774 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002775
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002776 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002777
2778 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002779 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002780};
2781
2782
2783class HBitOr: public HBitwiseBinaryOperation {
2784 public:
2785 HBitOr(HValue* left, HValue* right)
2786 : HBitwiseBinaryOperation(left, right) { }
2787
2788 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002791 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792
2793 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002794 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002795
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002796 virtual Range* InferRange();
2797};
2798
2799
2800class HShl: public HBitwiseBinaryOperation {
2801 public:
2802 HShl(HValue* left, HValue* right)
2803 : HBitwiseBinaryOperation(left, right) { }
2804
2805 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002806 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002808 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002809
2810 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002811 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002812};
2813
2814
2815class HShr: public HBitwiseBinaryOperation {
2816 public:
2817 HShr(HValue* left, HValue* right)
2818 : HBitwiseBinaryOperation(left, right) { }
2819
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002820 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002821
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002822 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002823
2824 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002825 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826};
2827
2828
2829class HSar: public HBitwiseBinaryOperation {
2830 public:
2831 HSar(HValue* left, HValue* right)
2832 : HBitwiseBinaryOperation(left, right) { }
2833
2834 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002835 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002837 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002838
2839 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002840 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002841};
2842
2843
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002844class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002845 public:
2846 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2847 SetFlag(kChangesOsrEntries);
2848 }
2849
2850 int ast_id() const { return ast_id_; }
2851
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002852 virtual Representation RequiredInputRepresentation(int index) const {
2853 return Representation::None();
2854 }
2855
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002856 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002857
2858 private:
2859 int ast_id_;
2860};
2861
2862
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002863class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002864 public:
2865 explicit HParameter(unsigned index) : index_(index) {
2866 set_representation(Representation::Tagged());
2867 }
2868
2869 unsigned index() const { return index_; }
2870
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002871 virtual void PrintDataTo(StringStream* stream);
2872
2873 virtual Representation RequiredInputRepresentation(int index) const {
2874 return Representation::None();
2875 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002876
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002877 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002878
2879 private:
2880 unsigned index_;
2881};
2882
2883
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002884class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002885 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002886 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2887 : HUnaryCall(context, argument_count),
2888 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002889 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002890 }
2891
2892 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002893
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002894 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895
2896 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2897 transcendental_type_ = transcendental_type;
2898 }
2899 TranscendentalCache::Type transcendental_type() {
2900 return transcendental_type_;
2901 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002902
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002903 virtual void PrintDataTo(StringStream* stream);
2904
2905 virtual Representation RequiredInputRepresentation(int index) const {
2906 return Representation::Tagged();
2907 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002909 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002910
2911 private:
2912 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913 TranscendentalCache::Type transcendental_type_;
2914};
2915
2916
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002917class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002918 public:
2919 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2920
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002921 virtual Representation RequiredInputRepresentation(int index) const {
2922 return Representation::None();
2923 }
2924
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002925 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002926};
2927
2928
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002929class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002931 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932 : cell_(cell), check_hole_value_(check_hole_value) {
2933 set_representation(Representation::Tagged());
2934 SetFlag(kUseGVN);
2935 SetFlag(kDependsOnGlobalVars);
2936 }
2937
2938 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2939 bool check_hole_value() const { return check_hole_value_; }
2940
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002941 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002942
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002943 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002944 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945 return reinterpret_cast<intptr_t>(*cell_);
2946 }
2947
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002948 virtual Representation RequiredInputRepresentation(int index) const {
2949 return Representation::None();
2950 }
2951
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002952 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002953
2954 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002955 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002956 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002957 return cell_.is_identical_to(b->cell());
2958 }
2959
2960 private:
2961 Handle<JSGlobalPropertyCell> cell_;
2962 bool check_hole_value_;
2963};
2964
2965
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002966class HLoadGlobalGeneric: public HBinaryOperation {
2967 public:
2968 HLoadGlobalGeneric(HValue* context,
2969 HValue* global_object,
2970 Handle<Object> name,
2971 bool for_typeof)
2972 : HBinaryOperation(context, global_object),
2973 name_(name),
2974 for_typeof_(for_typeof) {
2975 set_representation(Representation::Tagged());
2976 SetAllSideEffects();
2977 }
2978
2979 HValue* context() { return OperandAt(0); }
2980 HValue* global_object() { return OperandAt(1); }
2981 Handle<Object> name() const { return name_; }
2982 bool for_typeof() const { return for_typeof_; }
2983
2984 virtual void PrintDataTo(StringStream* stream);
2985
2986 virtual Representation RequiredInputRepresentation(int index) const {
2987 return Representation::Tagged();
2988 }
2989
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002990 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002991
2992 private:
2993 Handle<Object> name_;
2994 bool for_typeof_;
2995};
2996
2997
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002998class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003000 HStoreGlobalCell(HValue* value,
3001 Handle<JSGlobalPropertyCell> cell,
3002 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003003 : HUnaryOperation(value),
3004 cell_(cell),
3005 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003006 SetFlag(kChangesGlobalVars);
3007 }
3008
3009 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003010 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011
3012 virtual Representation RequiredInputRepresentation(int index) const {
3013 return Representation::Tagged();
3014 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003015 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003017 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019 private:
3020 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003021 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022};
3023
3024
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003025class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3026 public:
3027 HStoreGlobalGeneric(HValue* context,
3028 HValue* global_object,
3029 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003030 HValue* value,
3031 bool strict_mode)
3032 : name_(name),
3033 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003034 SetOperandAt(0, context);
3035 SetOperandAt(1, global_object);
3036 SetOperandAt(2, value);
3037 set_representation(Representation::Tagged());
3038 SetAllSideEffects();
3039 }
3040
3041 HValue* context() { return OperandAt(0); }
3042 HValue* global_object() { return OperandAt(1); }
3043 Handle<Object> name() const { return name_; }
3044 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003045 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003046
3047 virtual void PrintDataTo(StringStream* stream);
3048
3049 virtual Representation RequiredInputRepresentation(int index) const {
3050 return Representation::Tagged();
3051 }
3052
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003053 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003054
3055 private:
3056 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003057 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003058};
3059
3060
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003061class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003062 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003063 HLoadContextSlot(HValue* context , int slot_index)
3064 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003065 set_representation(Representation::Tagged());
3066 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003067 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003068 }
3069
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003070 int slot_index() const { return slot_index_; }
3071
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003072 virtual Representation RequiredInputRepresentation(int index) const {
3073 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003074 }
3075
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003076 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003078 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003079
3080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003082 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003083 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003084 }
3085
3086 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003087 int slot_index_;
3088};
3089
3090
3091static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3092 return !value->type().IsSmi() &&
3093 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3094}
3095
3096
3097class HStoreContextSlot: public HBinaryOperation {
3098 public:
3099 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3100 : HBinaryOperation(context, value), slot_index_(slot_index) {
3101 SetFlag(kChangesContextSlots);
3102 }
3103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104 HValue* context() { return OperandAt(0); }
3105 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003106 int slot_index() const { return slot_index_; }
3107
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003108 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003109 return StoringValueNeedsWriteBarrier(value());
3110 }
3111
3112 virtual Representation RequiredInputRepresentation(int index) const {
3113 return Representation::Tagged();
3114 }
3115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003116 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003117
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003118 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003119
3120 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003121 int slot_index_;
3122};
3123
3124
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125class HLoadNamedField: public HUnaryOperation {
3126 public:
3127 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3128 : HUnaryOperation(object),
3129 is_in_object_(is_in_object),
3130 offset_(offset) {
3131 set_representation(Representation::Tagged());
3132 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003133 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 if (is_in_object) {
3135 SetFlag(kDependsOnInobjectFields);
3136 } else {
3137 SetFlag(kDependsOnBackingStoreFields);
3138 }
3139 }
3140
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003141 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 bool is_in_object() const { return is_in_object_; }
3143 int offset() const { return offset_; }
3144
3145 virtual Representation RequiredInputRepresentation(int index) const {
3146 return Representation::Tagged();
3147 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003148 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003150 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151
3152 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003153 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154 HLoadNamedField* b = HLoadNamedField::cast(other);
3155 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3156 }
3157
3158 private:
3159 bool is_in_object_;
3160 int offset_;
3161};
3162
3163
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003164class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3165 public:
3166 HLoadNamedFieldPolymorphic(HValue* object,
3167 ZoneMapList* types,
3168 Handle<String> name);
3169
3170 HValue* object() { return OperandAt(0); }
3171 ZoneMapList* types() { return &types_; }
3172 Handle<String> name() { return name_; }
3173 bool need_generic() { return need_generic_; }
3174
3175 virtual Representation RequiredInputRepresentation(int index) const {
3176 return Representation::Tagged();
3177 }
3178
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003179 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003180
3181 static const int kMaxLoadPolymorphism = 4;
3182
3183 protected:
3184 virtual bool DataEquals(HValue* value);
3185
3186 private:
3187 ZoneMapList types_;
3188 Handle<String> name_;
3189 bool need_generic_;
3190};
3191
3192
3193
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003194class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003195 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003196 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3197 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003199 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003200 }
3201
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003202 HValue* context() { return OperandAt(0); }
3203 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003204 Handle<Object> name() const { return name_; }
3205
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(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003212 private:
3213 Handle<Object> name_;
3214};
3215
3216
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003217class HLoadFunctionPrototype: public HUnaryOperation {
3218 public:
3219 explicit HLoadFunctionPrototype(HValue* function)
3220 : HUnaryOperation(function) {
3221 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003222 SetFlag(kUseGVN);
3223 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003224 }
3225
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003226 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003227
3228 virtual Representation RequiredInputRepresentation(int index) const {
3229 return Representation::Tagged();
3230 }
3231
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003232 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003233
3234 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003235 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003236};
3237
3238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003239class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003240 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003241 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003242 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243 SetFlag(kDependsOnArrayElements);
3244 SetFlag(kUseGVN);
3245 }
3246
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003247 HValue* object() { return OperandAt(0); }
3248 HValue* key() { return OperandAt(1); }
3249
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003250 virtual Representation RequiredInputRepresentation(int index) const {
3251 // The key is supposed to be Integer32.
3252 return (index == 1) ? Representation::Integer32()
3253 : Representation::Tagged();
3254 }
3255
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003256 virtual void PrintDataTo(StringStream* stream);
3257
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003258 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003259
3260 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003261 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003262};
3263
3264
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003265class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003266 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003267 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3268 HValue* key,
3269 ExternalArrayType array_type)
3270 : HBinaryOperation(external_elements, key),
3271 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003272 if (array_type == kExternalFloatArray ||
3273 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003274 set_representation(Representation::Double());
3275 } else {
3276 set_representation(Representation::Integer32());
3277 }
3278 SetFlag(kDependsOnSpecializedArrayElements);
3279 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003280 SetFlag(kDependsOnCalls);
3281 SetFlag(kUseGVN);
3282 }
3283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003284 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003285
3286 virtual Representation RequiredInputRepresentation(int index) const {
3287 // The key is supposed to be Integer32, but the base pointer
3288 // for the element load is a naked pointer.
3289 return (index == 1) ? Representation::Integer32()
3290 : Representation::External();
3291 }
3292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003293 HValue* external_pointer() { return OperandAt(0); }
3294 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003295 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003296
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003297 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003298
3299 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003300 virtual bool DataEquals(HValue* other) {
3301 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3302 HLoadKeyedSpecializedArrayElement* cast_other =
3303 HLoadKeyedSpecializedArrayElement::cast(other);
3304 return array_type_ == cast_other->array_type();
3305 }
3306
3307 private:
3308 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003309};
3310
3311
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003312class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003313 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003314 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3315 set_representation(Representation::Tagged());
3316 SetOperandAt(0, obj);
3317 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003318 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003319 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003320 }
3321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003322 HValue* object() { return OperandAt(0); }
3323 HValue* key() { return OperandAt(1); }
3324 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003326 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327
3328 virtual Representation RequiredInputRepresentation(int index) const {
3329 return Representation::Tagged();
3330 }
3331
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003332 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003333};
3334
3335
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003336class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003337 public:
3338 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003339 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003340 HValue* val,
3341 bool in_object,
3342 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003343 : HBinaryOperation(obj, val),
3344 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003345 is_in_object_(in_object),
3346 offset_(offset) {
3347 if (is_in_object_) {
3348 SetFlag(kChangesInobjectFields);
3349 } else {
3350 SetFlag(kChangesBackingStoreFields);
3351 }
3352 }
3353
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003354 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003355
3356 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003357 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003358 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003359 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003361 HValue* object() { return OperandAt(0); }
3362 HValue* value() { return OperandAt(1); }
3363
3364 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003365 bool is_in_object() const { return is_in_object_; }
3366 int offset() const { return offset_; }
3367 Handle<Map> transition() const { return transition_; }
3368 void set_transition(Handle<Map> map) { transition_ = map; }
3369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003370 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003371 return StoringValueNeedsWriteBarrier(value());
3372 }
3373
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003374 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003375 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003376 bool is_in_object_;
3377 int offset_;
3378 Handle<Map> transition_;
3379};
3380
3381
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003382class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003383 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003384 HStoreNamedGeneric(HValue* context,
3385 HValue* object,
3386 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003387 HValue* value,
3388 bool strict_mode)
3389 : name_(name),
3390 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003391 SetOperandAt(0, object);
3392 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003393 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003394 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003395 }
3396
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003397 HValue* object() { return OperandAt(0); }
3398 HValue* value() { return OperandAt(1); }
3399 HValue* context() { return OperandAt(2); }
3400 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003401 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003402
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003403 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003404
3405 virtual Representation RequiredInputRepresentation(int index) const {
3406 return Representation::Tagged();
3407 }
3408
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003409 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003411 private:
3412 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003413 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003414};
3415
3416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003417class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003418 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003419 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3420 SetOperandAt(0, obj);
3421 SetOperandAt(1, key);
3422 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003423 SetFlag(kChangesArrayElements);
3424 }
3425
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003426 virtual Representation RequiredInputRepresentation(int index) const {
3427 // The key is supposed to be Integer32.
3428 return (index == 1) ? Representation::Integer32()
3429 : Representation::Tagged();
3430 }
3431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003432 HValue* object() { return OperandAt(0); }
3433 HValue* key() { return OperandAt(1); }
3434 HValue* value() { return OperandAt(2); }
3435
3436 bool NeedsWriteBarrier() {
3437 return StoringValueNeedsWriteBarrier(value());
3438 }
3439
3440 virtual void PrintDataTo(StringStream* stream);
3441
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003442 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003443};
3444
3445
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003446class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003447 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003448 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3449 HValue* key,
3450 HValue* val,
3451 ExternalArrayType array_type)
3452 : array_type_(array_type) {
3453 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003454 SetOperandAt(0, external_elements);
3455 SetOperandAt(1, key);
3456 SetOperandAt(2, val);
3457 }
3458
3459 virtual void PrintDataTo(StringStream* stream);
3460
3461 virtual Representation RequiredInputRepresentation(int index) const {
3462 if (index == 0) {
3463 return Representation::External();
3464 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003465 if (index == 2 && (array_type() == kExternalFloatArray ||
3466 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003467 return Representation::Double();
3468 } else {
3469 return Representation::Integer32();
3470 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003471 }
3472 }
3473
3474 HValue* external_pointer() { return OperandAt(0); }
3475 HValue* key() { return OperandAt(1); }
3476 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003477 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003478
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003479 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3480
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003481 private:
3482 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003483};
3484
3485
3486class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003488 HStoreKeyedGeneric(HValue* context,
3489 HValue* object,
3490 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003491 HValue* value,
3492 bool strict_mode)
3493 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003494 SetOperandAt(0, object);
3495 SetOperandAt(1, key);
3496 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003497 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003498 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003499 }
3500
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003501 HValue* object() { return OperandAt(0); }
3502 HValue* key() { return OperandAt(1); }
3503 HValue* value() { return OperandAt(2); }
3504 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003505 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003506
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003507 virtual Representation RequiredInputRepresentation(int index) const {
3508 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003509 }
3510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003511 virtual void PrintDataTo(StringStream* stream);
3512
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003513 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003514
3515 private:
3516 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003517};
3518
3519
danno@chromium.org160a7b02011-04-18 15:51:38 +00003520class HStringAdd: public HBinaryOperation {
3521 public:
3522 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3523 set_representation(Representation::Tagged());
3524 SetFlag(kUseGVN);
3525 SetFlag(kDependsOnMaps);
3526 }
3527
3528 virtual Representation RequiredInputRepresentation(int index) const {
3529 return Representation::Tagged();
3530 }
3531
3532 virtual HType CalculateInferredType() {
3533 return HType::String();
3534 }
3535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003536 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003537
3538 protected:
3539 virtual bool DataEquals(HValue* other) { return true; }
3540};
3541
3542
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003543class HStringCharCodeAt: public HBinaryOperation {
3544 public:
3545 HStringCharCodeAt(HValue* string, HValue* index)
3546 : HBinaryOperation(string, index) {
3547 set_representation(Representation::Integer32());
3548 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003549 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003550 }
3551
3552 virtual Representation RequiredInputRepresentation(int index) const {
3553 // The index is supposed to be Integer32.
3554 return (index == 1) ? Representation::Integer32()
3555 : Representation::Tagged();
3556 }
3557
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003558 HValue* string() { return OperandAt(0); }
3559 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003560
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003561 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003562
3563 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003564 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003565
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003566 virtual Range* InferRange() {
3567 return new Range(0, String::kMaxUC16CharCode);
3568 }
3569};
3570
3571
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003572class HStringCharFromCode: public HUnaryOperation {
3573 public:
3574 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3575 set_representation(Representation::Tagged());
3576 SetFlag(kUseGVN);
3577 }
3578
3579 virtual Representation RequiredInputRepresentation(int index) const {
3580 return Representation::Integer32();
3581 }
3582
3583 virtual bool DataEquals(HValue* other) { return true; }
3584
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003585 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003586};
3587
3588
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003589class HStringLength: public HUnaryOperation {
3590 public:
3591 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3592 set_representation(Representation::Tagged());
3593 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003594 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003595 }
3596
3597 virtual Representation RequiredInputRepresentation(int index) const {
3598 return Representation::Tagged();
3599 }
3600
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003601 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003602 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3603 return HType::Smi();
3604 }
3605
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003606 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003607
3608 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003609 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003610
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003611 virtual Range* InferRange() {
3612 return new Range(0, String::kMaxLength);
3613 }
3614};
3615
3616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617template <int V>
3618class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003620 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003621 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003622 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623 }
3624
3625 int literal_index() const { return literal_index_; }
3626 int depth() const { return depth_; }
3627
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628 private:
3629 int literal_index_;
3630 int depth_;
3631};
3632
3633
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003634class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635 public:
3636 HArrayLiteral(Handle<FixedArray> constant_elements,
3637 int length,
3638 int literal_index,
3639 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003640 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641 length_(length),
3642 constant_elements_(constant_elements) {}
3643
3644 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3645 int length() const { return length_; }
3646
3647 bool IsCopyOnWrite() const;
3648
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003649 virtual Representation RequiredInputRepresentation(int index) const {
3650 return Representation::None();
3651 }
3652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003653 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003654
3655 private:
3656 int length_;
3657 Handle<FixedArray> constant_elements_;
3658};
3659
3660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003661class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003663 HObjectLiteral(HValue* context,
3664 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003665 bool fast_elements,
3666 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003667 int depth,
3668 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003669 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003671 fast_elements_(fast_elements),
3672 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003673 SetOperandAt(0, context);
3674 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003675
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003676 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003677 Handle<FixedArray> constant_properties() const {
3678 return constant_properties_;
3679 }
3680 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003681 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003682
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003683 virtual Representation RequiredInputRepresentation(int index) const {
3684 return Representation::Tagged();
3685 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003686
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003687 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003688
3689 private:
3690 Handle<FixedArray> constant_properties_;
3691 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003692 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003693};
3694
3695
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003696class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003697 public:
3698 HRegExpLiteral(Handle<String> pattern,
3699 Handle<String> flags,
3700 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003701 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003702 pattern_(pattern),
3703 flags_(flags) { }
3704
3705 Handle<String> pattern() { return pattern_; }
3706 Handle<String> flags() { return flags_; }
3707
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003708 virtual Representation RequiredInputRepresentation(int index) const {
3709 return Representation::None();
3710 }
3711
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003712 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713
3714 private:
3715 Handle<String> pattern_;
3716 Handle<String> flags_;
3717};
3718
3719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003720class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003721 public:
3722 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3723 : shared_info_(shared), pretenure_(pretenure) {
3724 set_representation(Representation::Tagged());
3725 }
3726
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003727 virtual Representation RequiredInputRepresentation(int index) const {
3728 return Representation::None();
3729 }
3730
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003731 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003732
3733 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3734 bool pretenure() const { return pretenure_; }
3735
3736 private:
3737 Handle<SharedFunctionInfo> shared_info_;
3738 bool pretenure_;
3739};
3740
3741
3742class HTypeof: public HUnaryOperation {
3743 public:
3744 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3745 set_representation(Representation::Tagged());
3746 }
3747
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003748 virtual Representation RequiredInputRepresentation(int index) const {
3749 return Representation::Tagged();
3750 }
3751
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003752 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003753};
3754
3755
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003756class HToFastProperties: public HUnaryOperation {
3757 public:
3758 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3759 // This instruction is not marked as having side effects, but
3760 // changes the map of the input operand. Use it only when creating
3761 // object literals.
3762 ASSERT(value->IsObjectLiteral());
3763 set_representation(Representation::Tagged());
3764 }
3765
3766 virtual Representation RequiredInputRepresentation(int index) const {
3767 return Representation::Tagged();
3768 }
3769
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003770 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003771};
3772
3773
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003774class HValueOf: public HUnaryOperation {
3775 public:
3776 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3777 set_representation(Representation::Tagged());
3778 }
3779
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003780 virtual Representation RequiredInputRepresentation(int index) const {
3781 return Representation::Tagged();
3782 }
3783
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003784 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003785};
3786
3787
3788class HDeleteProperty: public HBinaryOperation {
3789 public:
3790 HDeleteProperty(HValue* obj, HValue* key)
3791 : HBinaryOperation(obj, key) {
3792 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003793 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003794 }
3795
3796 virtual Representation RequiredInputRepresentation(int index) const {
3797 return Representation::Tagged();
3798 }
3799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003800 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003802 HValue* object() { return left(); }
3803 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003804};
3805
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003806
3807class HIn: public HTemplateInstruction<2> {
3808 public:
3809 HIn(HValue* key, HValue* object) {
3810 SetOperandAt(0, key);
3811 SetOperandAt(1, object);
3812 set_representation(Representation::Tagged());
3813 SetAllSideEffects();
3814 }
3815
3816 HValue* key() { return OperandAt(0); }
3817 HValue* object() { return OperandAt(1); }
3818
3819 virtual Representation RequiredInputRepresentation(int index) const {
3820 return Representation::Tagged();
3821 }
3822
3823 virtual HType CalculateInferredType() {
3824 return HType::Boolean();
3825 }
3826
3827 virtual void PrintDataTo(StringStream* stream);
3828
3829 DECLARE_CONCRETE_INSTRUCTION(In)
3830};
3831
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003832#undef DECLARE_INSTRUCTION
3833#undef DECLARE_CONCRETE_INSTRUCTION
3834
3835} } // namespace v8::internal
3836
3837#endif // V8_HYDROGEN_INSTRUCTIONS_H_