blob: 85a06fcbb7b56a87a9fec6b574ea21e98273a8f2 [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);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000631 void PrintTypeTo(StringStream* stream);
632 void PrintRangeTo(StringStream* stream);
633 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000634
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000635 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000636
637 // Updated the inferred type of this instruction and returns true if
638 // it has changed.
639 bool UpdateInferredType();
640
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000641 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000642
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000643#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000644 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645#endif
646
647 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000648 // This function must be overridden for instructions with flag kUseGVN, to
649 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000650 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000651 UNREACHABLE();
652 return false;
653 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654 virtual void RepresentationChanged(Representation to) { }
655 virtual Range* InferRange();
656 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000657 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000658 void clear_block() {
659 ASSERT(block_ != NULL);
660 block_ = NULL;
661 }
662
663 void set_representation(Representation r) {
664 // Representation is set-once.
665 ASSERT(representation_.IsNone() && !r.IsNone());
666 representation_ = r;
667 }
668
669 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000670 // A flag mask to mark an instruction as having arbitrary side effects.
671 static int AllSideEffects() {
672 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
673 }
674
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000675 // Remove the matching use from the use list if present. Returns the
676 // removed list node or NULL.
677 HUseListNode* RemoveUse(HValue* value, int index);
678
679 void ReplaceAllUsesWith(HValue* other);
680
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000681 void RegisterUse(int index, HValue* new_value);
682
683 HBasicBlock* block_;
684
685 // The id of this instruction in the hydrogen graph, assigned when first
686 // added to the graph. Reflects creation order.
687 int id_;
688
689 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000690 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000691 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000692 Range* range_;
693 int flags_;
694
695 DISALLOW_COPY_AND_ASSIGN(HValue);
696};
697
698
699class HInstruction: public HValue {
700 public:
701 HInstruction* next() const { return next_; }
702 HInstruction* previous() const { return previous_; }
703
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000704 virtual void PrintTo(StringStream* stream);
705 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000706
707 bool IsLinked() const { return block() != NULL; }
708 void Unlink();
709 void InsertBefore(HInstruction* next);
710 void InsertAfter(HInstruction* previous);
711
712 int position() const { return position_; }
713 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
714 void set_position(int position) { position_ = position; }
715
716 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
717
718#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000719 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000720#endif
721
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000722 // Returns whether this is some kind of deoptimizing check
723 // instruction.
724 virtual bool IsCheckInstruction() const { return false; }
725
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000726 virtual bool IsCall() { return false; }
727
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000728 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000729
730 protected:
731 HInstruction()
732 : next_(NULL),
733 previous_(NULL),
734 position_(RelocInfo::kNoPosition) {
735 SetFlag(kDependsOnOsrEntries);
736 }
737
738 virtual void DeleteFromGraph() { Unlink(); }
739
740 private:
741 void InitializeAsFirst(HBasicBlock* block) {
742 ASSERT(!IsLinked());
743 SetBlock(block);
744 }
745
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000746 void PrintMnemonicTo(StringStream* stream);
747
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000748 HInstruction* next_;
749 HInstruction* previous_;
750 int position_;
751
752 friend class HBasicBlock;
753};
754
755
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000756class HControlInstruction: public HInstruction {
757 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000758 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
759 : first_successor_(first), second_successor_(second) {
760 }
761
762 HBasicBlock* FirstSuccessor() const { return first_successor_; }
763 HBasicBlock* SecondSuccessor() const { return second_successor_; }
764
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000765 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000766
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000767 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000768
769 private:
770 HBasicBlock* first_successor_;
771 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000772};
773
774
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000775template<int NumElements>
776class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000777 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000778 HOperandContainer() : elems_() { }
779
780 int length() { return NumElements; }
781 HValue*& operator[](int i) {
782 ASSERT(i < length());
783 return elems_[i];
784 }
785
786 private:
787 HValue* elems_[NumElements];
788};
789
790
791template<>
792class HOperandContainer<0> {
793 public:
794 int length() { return 0; }
795 HValue*& operator[](int i) {
796 UNREACHABLE();
797 static HValue* t = 0;
798 return t;
799 }
800};
801
802
803template<int V>
804class HTemplateInstruction : public HInstruction {
805 public:
806 int OperandCount() { return V; }
807 HValue* OperandAt(int i) { return inputs_[i]; }
808
809 protected:
810 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
811
812 private:
813 HOperandContainer<V> inputs_;
814};
815
816
817template<int V>
818class HTemplateControlInstruction : public HControlInstruction {
819 public:
820 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
821 : HControlInstruction(first, second) { }
822 int OperandCount() { return V; }
823 HValue* OperandAt(int i) { return inputs_[i]; }
824
825 protected:
826 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
827
828 private:
829 HOperandContainer<V> inputs_;
830};
831
832
833class HBlockEntry: public HTemplateInstruction<0> {
834 public:
835 virtual Representation RequiredInputRepresentation(int index) const {
836 return Representation::None();
837 }
838
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000839 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000840};
841
842
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000843class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000844 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000845 explicit HDeoptimize(int environment_length)
846 : HControlInstruction(NULL, NULL),
847 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000848
849 virtual Representation RequiredInputRepresentation(int index) const {
850 return Representation::None();
851 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000852
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000853 virtual int OperandCount() { return values_.length(); }
854 virtual HValue* OperandAt(int index) { return values_[index]; }
855
856 void AddEnvironmentValue(HValue* value) {
857 values_.Add(NULL);
858 SetOperandAt(values_.length() - 1, value);
859 }
860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000861 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000862
863 protected:
864 virtual void InternalSetOperandAt(int index, HValue* value) {
865 values_[index] = value;
866 }
867
868 private:
869 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870};
871
872
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000873class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000874 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000875 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000876 : HTemplateControlInstruction<0>(target, NULL),
877 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000878
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000879 void set_include_stack_check(bool include_stack_check) {
880 include_stack_check_ = include_stack_check;
881 }
882 bool include_stack_check() const { return include_stack_check_; }
883
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000884 virtual Representation RequiredInputRepresentation(int index) const {
885 return Representation::None();
886 }
887
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000888 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000889
890 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891 bool include_stack_check_;
892};
893
894
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000895class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000897 explicit HUnaryControlInstruction(HValue* value,
898 HBasicBlock* true_target,
899 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000900 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000901 SetOperandAt(0, value);
902 }
903
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000904 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000905
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000906 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907};
908
909
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000910class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000912 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
913 : HUnaryControlInstruction(value, true_target, false_target) {
914 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915 }
916
917 virtual Representation RequiredInputRepresentation(int index) const {
918 return Representation::None();
919 }
920
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000921 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000922};
923
924
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000925class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000927 HCompareMap(HValue* value,
928 Handle<Map> map,
929 HBasicBlock* true_target,
930 HBasicBlock* false_target)
931 : HUnaryControlInstruction(value, true_target, false_target),
932 map_(map) {
933 ASSERT(true_target != NULL);
934 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935 ASSERT(!map.is_null());
936 }
937
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000938 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000939
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000940 Handle<Map> map() const { return map_; }
941
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000942 virtual Representation RequiredInputRepresentation(int index) const {
943 return Representation::Tagged();
944 }
945
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000946 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947
948 private:
949 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950};
951
952
953class HReturn: public HUnaryControlInstruction {
954 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000955 explicit HReturn(HValue* value)
956 : HUnaryControlInstruction(value, NULL, NULL) {
957 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000959 virtual Representation RequiredInputRepresentation(int index) const {
960 return Representation::Tagged();
961 }
962
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000963 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964};
965
966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000967class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000968 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000969 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
970
971 virtual Representation RequiredInputRepresentation(int index) const {
972 return Representation::None();
973 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000975 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976};
977
978
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000979class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000980 public:
981 explicit HUnaryOperation(HValue* value) {
982 SetOperandAt(0, value);
983 }
984
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000985 HValue* value() { return OperandAt(0); }
986 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987};
988
989
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000990class HThrow: public HUnaryOperation {
991 public:
992 explicit HThrow(HValue* value) : HUnaryOperation(value) {
993 SetAllSideEffects();
994 }
995
996 virtual Representation RequiredInputRepresentation(int index) const {
997 return Representation::Tagged();
998 }
999
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001000 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001001};
1002
1003
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001004class HChange: public HUnaryOperation {
1005 public:
1006 HChange(HValue* value,
1007 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001008 Representation to,
1009 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001010 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001011 ASSERT(!from.IsNone() && !to.IsNone());
1012 ASSERT(!from.Equals(to));
1013 set_representation(to);
1014 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001015 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001016 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1017 value->range()->IsInSmiRange()) {
1018 set_type(HType::Smi());
1019 }
1020 }
1021
1022 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1023
1024 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001025 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001026 virtual Representation RequiredInputRepresentation(int index) const {
1027 return from_;
1028 }
1029
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001030 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001031
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001032 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001033
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001034 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001035
1036 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001037 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001038 if (!other->IsChange()) return false;
1039 HChange* change = HChange::cast(other);
1040 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001041 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001042 }
1043
1044 private:
1045 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001046};
1047
1048
1049class HSimulate: public HInstruction {
1050 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001051 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001052 : ast_id_(ast_id),
1053 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001054 values_(2),
1055 assigned_indexes_(2) {}
1056 virtual ~HSimulate() {}
1057
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001058 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001059
1060 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1061 int ast_id() const { return ast_id_; }
1062 void set_ast_id(int id) {
1063 ASSERT(!HasAstId());
1064 ast_id_ = id;
1065 }
1066
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001067 int pop_count() const { return pop_count_; }
1068 const ZoneList<HValue*>* values() const { return &values_; }
1069 int GetAssignedIndexAt(int index) const {
1070 ASSERT(HasAssignedIndexAt(index));
1071 return assigned_indexes_[index];
1072 }
1073 bool HasAssignedIndexAt(int index) const {
1074 return assigned_indexes_[index] != kNoIndex;
1075 }
1076 void AddAssignedValue(int index, HValue* value) {
1077 AddValue(index, value);
1078 }
1079 void AddPushedValue(HValue* value) {
1080 AddValue(kNoIndex, value);
1081 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001082 virtual int OperandCount() { return values_.length(); }
1083 virtual HValue* OperandAt(int index) { return values_[index]; }
1084
1085 virtual Representation RequiredInputRepresentation(int index) const {
1086 return Representation::None();
1087 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001088
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001089 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001090
1091#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001092 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001093#endif
1094
1095 protected:
1096 virtual void InternalSetOperandAt(int index, HValue* value) {
1097 values_[index] = value;
1098 }
1099
1100 private:
1101 static const int kNoIndex = -1;
1102 void AddValue(int index, HValue* value) {
1103 assigned_indexes_.Add(index);
1104 // Resize the list of pushed values.
1105 values_.Add(NULL);
1106 // Set the operand through the base method in HValue to make sure that the
1107 // use lists are correctly updated.
1108 SetOperandAt(values_.length() - 1, value);
1109 }
1110 int ast_id_;
1111 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001112 ZoneList<HValue*> values_;
1113 ZoneList<int> assigned_indexes_;
1114};
1115
1116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001117class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001118 public:
1119 HStackCheck() { }
1120
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001121 virtual Representation RequiredInputRepresentation(int index) const {
1122 return Representation::None();
1123 }
1124
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001125 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126};
1127
1128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001129class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001130 public:
1131 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1132 : closure_(closure), function_(function) {
1133 }
1134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001135 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001136
1137 Handle<JSFunction> closure() const { return closure_; }
1138 FunctionLiteral* function() const { return function_; }
1139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001140 virtual Representation RequiredInputRepresentation(int index) const {
1141 return Representation::None();
1142 }
1143
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001144 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001145
1146 private:
1147 Handle<JSFunction> closure_;
1148 FunctionLiteral* function_;
1149};
1150
1151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001152class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001153 public:
1154 HLeaveInlined() {}
1155
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001156 virtual Representation RequiredInputRepresentation(int index) const {
1157 return Representation::None();
1158 }
1159
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001160 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001161};
1162
1163
1164class HPushArgument: public HUnaryOperation {
1165 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001166 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1167 set_representation(Representation::Tagged());
1168 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169
1170 virtual Representation RequiredInputRepresentation(int index) const {
1171 return Representation::Tagged();
1172 }
1173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001174 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001175
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001176 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001177};
1178
1179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001180class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001181 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001182 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001183 set_representation(Representation::Tagged());
1184 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001185 }
1186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001187 virtual Representation RequiredInputRepresentation(int index) const {
1188 return Representation::None();
1189 }
1190
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001191 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001192
1193 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001194 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001195};
1196
1197
1198class HOuterContext: public HUnaryOperation {
1199 public:
1200 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1201 set_representation(Representation::Tagged());
1202 SetFlag(kUseGVN);
1203 }
1204
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001205 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001207 virtual Representation RequiredInputRepresentation(int index) const {
1208 return Representation::Tagged();
1209 }
1210
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001211 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001212 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001213};
1214
1215
1216class HGlobalObject: public HUnaryOperation {
1217 public:
1218 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1219 set_representation(Representation::Tagged());
1220 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001221 }
1222
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001223 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001224
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001225 virtual Representation RequiredInputRepresentation(int index) const {
1226 return Representation::Tagged();
1227 }
1228
ager@chromium.org378b34e2011-01-28 08:04:38 +00001229 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001230 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001231};
1232
1233
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001234class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001235 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001236 explicit HGlobalReceiver(HValue* global_object)
1237 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238 set_representation(Representation::Tagged());
1239 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001240 }
1241
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001242 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001243
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001244 virtual Representation RequiredInputRepresentation(int index) const {
1245 return Representation::Tagged();
1246 }
1247
ager@chromium.org378b34e2011-01-28 08:04:38 +00001248 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001249 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250};
1251
1252
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001253template <int V>
1254class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001255 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001256 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001257 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1258 this->set_representation(Representation::Tagged());
1259 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001260 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001261
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001262 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001264 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001265
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001266 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001267
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001268 private:
1269 int argument_count_;
1270};
1271
1272
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001273class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001274 public:
1275 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001276 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001277 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001278 }
1279
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001280 virtual Representation RequiredInputRepresentation(int index) const {
1281 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001282 }
1283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001284 virtual void PrintDataTo(StringStream* stream);
1285
1286 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001287};
1288
1289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001290class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001291 public:
1292 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001293 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001294 SetOperandAt(0, first);
1295 SetOperandAt(1, second);
1296 }
1297
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001298 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001300 virtual Representation RequiredInputRepresentation(int index) const {
1301 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001302 }
1303
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001304 HValue* first() { return OperandAt(0); }
1305 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306};
1307
1308
danno@chromium.org160a7b02011-04-18 15:51:38 +00001309class HInvokeFunction: public HBinaryCall {
1310 public:
1311 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1312 : HBinaryCall(context, function, argument_count) {
1313 }
1314
1315 virtual Representation RequiredInputRepresentation(int index) const {
1316 return Representation::Tagged();
1317 }
1318
1319 HValue* context() { return first(); }
1320 HValue* function() { return second(); }
1321
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001322 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001323};
1324
1325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327 public:
1328 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001329 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001330
1331 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001332
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001333 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001334 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001335 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001336 }
1337
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001338 virtual void PrintDataTo(StringStream* stream);
1339
1340 virtual Representation RequiredInputRepresentation(int index) const {
1341 return Representation::None();
1342 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001344 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345
1346 private:
1347 Handle<JSFunction> function_;
1348};
1349
1350
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001351class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001352 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001353 HCallKeyed(HValue* context, HValue* key, int argument_count)
1354 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 }
1356
1357 virtual Representation RequiredInputRepresentation(int index) const {
1358 return Representation::Tagged();
1359 }
1360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001361 HValue* context() { return first(); }
1362 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001363
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001364 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001365};
1366
1367
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001368class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001369 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001370 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1371 : HUnaryCall(context, argument_count), name_(name) {
1372 }
1373
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001374 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001376 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377 Handle<String> name() const { return name_; }
1378
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001379 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001381 virtual Representation RequiredInputRepresentation(int index) const {
1382 return Representation::Tagged();
1383 }
1384
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001385 private:
1386 Handle<String> name_;
1387};
1388
1389
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001390class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001391 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001392 HCallFunction(HValue* context, int argument_count)
1393 : HUnaryCall(context, argument_count) {
1394 }
1395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001396 HValue* context() { return value(); }
1397
1398 virtual Representation RequiredInputRepresentation(int index) const {
1399 return Representation::Tagged();
1400 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001401
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001402 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403};
1404
1405
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001406class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001408 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1409 : HUnaryCall(context, argument_count), name_(name) {
1410 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001412 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001414 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415 Handle<String> name() const { return name_; }
1416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001417 virtual Representation RequiredInputRepresentation(int index) const {
1418 return Representation::Tagged();
1419 }
1420
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001421 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001422
1423 private:
1424 Handle<String> name_;
1425};
1426
1427
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001428class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001429 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001430 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001431 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001433 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001434
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001435 Handle<JSFunction> target() const { return target_; }
1436
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001437 virtual Representation RequiredInputRepresentation(int index) const {
1438 return Representation::None();
1439 }
1440
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001441 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001442
1443 private:
1444 Handle<JSFunction> target_;
1445};
1446
1447
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001450 HCallNew(HValue* context, HValue* constructor, int argument_count)
1451 : HBinaryCall(context, constructor, argument_count) {
1452 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453
1454 virtual Representation RequiredInputRepresentation(int index) const {
1455 return Representation::Tagged();
1456 }
1457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458 HValue* context() { return first(); }
1459 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001460
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001461 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001462};
1463
1464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001466 public:
1467 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001468 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001469 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001470 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1471 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001472
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001473 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001474 Handle<String> name() const { return name_; }
1475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476 virtual Representation RequiredInputRepresentation(int index) const {
1477 return Representation::None();
1478 }
1479
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001480 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001481
1482 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001483 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001484 Handle<String> name_;
1485};
1486
1487
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001488class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001489 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001490 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001491 // The length of an array is stored as a tagged value in the array
1492 // object. It is guaranteed to be 32 bit integer, but it can be
1493 // represented as either a smi or heap number.
1494 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001495 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001496 SetFlag(kDependsOnArrayLengths);
1497 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498 }
1499
1500 virtual Representation RequiredInputRepresentation(int index) const {
1501 return Representation::Tagged();
1502 }
1503
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001504 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001505
1506 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001507 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001508};
1509
1510
1511class HFixedArrayLength: public HUnaryOperation {
1512 public:
1513 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1514 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001515 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001516 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001517 }
1518
1519 virtual Representation RequiredInputRepresentation(int index) const {
1520 return Representation::Tagged();
1521 }
1522
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001523 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001524
1525 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001526 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001527};
1528
1529
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001530class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001531 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001532 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001533 set_representation(Representation::Integer32());
1534 // The result of this instruction is idempotent as long as its inputs don't
1535 // change. The length of a pixel array cannot change once set, so it's not
1536 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1537 SetFlag(kUseGVN);
1538 }
1539
1540 virtual Representation RequiredInputRepresentation(int index) const {
1541 return Representation::Tagged();
1542 }
1543
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001544 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001545
1546 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001547 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001548};
1549
1550
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551class HBitNot: public HUnaryOperation {
1552 public:
1553 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1554 set_representation(Representation::Integer32());
1555 SetFlag(kUseGVN);
1556 SetFlag(kTruncatingToInt32);
1557 }
1558
1559 virtual Representation RequiredInputRepresentation(int index) const {
1560 return Representation::Integer32();
1561 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001562 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001564 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001565
1566 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001567 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001568};
1569
1570
1571class HUnaryMathOperation: public HUnaryOperation {
1572 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001573 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574 : HUnaryOperation(value), op_(op) {
1575 switch (op) {
1576 case kMathFloor:
1577 case kMathRound:
1578 case kMathCeil:
1579 set_representation(Representation::Integer32());
1580 break;
1581 case kMathAbs:
1582 set_representation(Representation::Tagged());
1583 SetFlag(kFlexibleRepresentation);
1584 break;
1585 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001586 case kMathPowHalf:
1587 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001588 case kMathSin:
1589 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001590 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001591 break;
1592 default:
1593 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001594 }
1595 SetFlag(kUseGVN);
1596 }
1597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001598 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001600 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601
1602 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1603
1604 virtual Representation RequiredInputRepresentation(int index) const {
1605 switch (op_) {
1606 case kMathFloor:
1607 case kMathRound:
1608 case kMathCeil:
1609 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001610 case kMathPowHalf:
1611 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001612 case kMathSin:
1613 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615 case kMathAbs:
1616 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001617 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001618 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001619 return Representation::None();
1620 }
1621 }
1622
1623 virtual HValue* Canonicalize() {
1624 // If the input is integer32 then we replace the floor instruction
1625 // with its inputs. This happens before the representation changes are
1626 // introduced.
1627 if (op() == kMathFloor) {
1628 if (value()->representation().IsInteger32()) return value();
1629 }
1630 return this;
1631 }
1632
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001633 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634 const char* OpName() const;
1635
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001636 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001637
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001638 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001639 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001640 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1641 return op_ == b->op();
1642 }
1643
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001644 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001645 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646};
1647
1648
1649class HLoadElements: public HUnaryOperation {
1650 public:
1651 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1652 set_representation(Representation::Tagged());
1653 SetFlag(kUseGVN);
1654 SetFlag(kDependsOnMaps);
1655 }
1656
1657 virtual Representation RequiredInputRepresentation(int index) const {
1658 return Representation::Tagged();
1659 }
1660
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001661 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001662
1663 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001664 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001665};
1666
1667
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001668class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001669 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001670 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001671 : HUnaryOperation(value) {
1672 set_representation(Representation::External());
1673 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001674 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001675 // change once set, so it's no necessary to introduce any additional
1676 // dependencies on top of the inputs.
1677 SetFlag(kUseGVN);
1678 }
1679
1680 virtual Representation RequiredInputRepresentation(int index) const {
1681 return Representation::Tagged();
1682 }
1683
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001684 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001685
1686 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001687 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001688};
1689
1690
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001691class HCheckMap: public HUnaryOperation {
1692 public:
1693 HCheckMap(HValue* value, Handle<Map> map)
1694 : HUnaryOperation(value), map_(map) {
1695 set_representation(Representation::Tagged());
1696 SetFlag(kUseGVN);
1697 SetFlag(kDependsOnMaps);
1698 }
1699
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001700 virtual bool IsCheckInstruction() const { return true; }
1701
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001702 virtual Representation RequiredInputRepresentation(int index) const {
1703 return Representation::Tagged();
1704 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001705 virtual void PrintDataTo(StringStream* stream);
1706 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707
1708#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001709 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710#endif
1711
1712 Handle<Map> map() const { return map_; }
1713
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001714 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001715
1716 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001717 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001718 HCheckMap* b = HCheckMap::cast(other);
1719 return map_.is_identical_to(b->map());
1720 }
1721
1722 private:
1723 Handle<Map> map_;
1724};
1725
1726
1727class HCheckFunction: public HUnaryOperation {
1728 public:
1729 HCheckFunction(HValue* value, Handle<JSFunction> function)
1730 : HUnaryOperation(value), target_(function) {
1731 set_representation(Representation::Tagged());
1732 SetFlag(kUseGVN);
1733 }
1734
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001735 virtual bool IsCheckInstruction() const { return true; }
1736
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001737 virtual Representation RequiredInputRepresentation(int index) const {
1738 return Representation::Tagged();
1739 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001740 virtual void PrintDataTo(StringStream* stream);
1741 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001742
1743#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001744 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745#endif
1746
1747 Handle<JSFunction> target() const { return target_; }
1748
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001749 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001750
1751 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001752 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001753 HCheckFunction* b = HCheckFunction::cast(other);
1754 return target_.is_identical_to(b->target());
1755 }
1756
1757 private:
1758 Handle<JSFunction> target_;
1759};
1760
1761
1762class HCheckInstanceType: public HUnaryOperation {
1763 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001764 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) {
1765 return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION);
1766 }
1767 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1768 return new HCheckInstanceType(value, IS_JS_ARRAY);
1769 }
1770 static HCheckInstanceType* NewIsString(HValue* value) {
1771 return new HCheckInstanceType(value, IS_STRING);
1772 }
1773 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1774 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001775 }
1776
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001777 virtual bool IsCheckInstruction() const { return true; }
1778
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001779 virtual Representation RequiredInputRepresentation(int index) const {
1780 return Representation::Tagged();
1781 }
1782
1783#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001784 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785#endif
1786
danno@chromium.org160a7b02011-04-18 15:51:38 +00001787 virtual HValue* Canonicalize() {
1788 if (!value()->type().IsUninitialized() &&
1789 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001790 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001791 return NULL;
1792 }
1793 return this;
1794 }
1795
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001796 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1797 void GetCheckInterval(InstanceType* first, InstanceType* last);
1798 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001799
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);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001808 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809 }
1810
1811 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001812 enum Check {
1813 IS_JS_OBJECT_OR_JS_FUNCTION,
1814 IS_JS_ARRAY,
1815 IS_STRING,
1816 IS_SYMBOL,
1817 LAST_INTERVAL_CHECK = IS_JS_ARRAY
1818 };
1819
1820 HCheckInstanceType(HValue* value, Check check)
1821 : HUnaryOperation(value), check_(check) {
1822 set_representation(Representation::Tagged());
1823 SetFlag(kUseGVN);
1824 }
1825
1826 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001827};
1828
1829
1830class HCheckNonSmi: public HUnaryOperation {
1831 public:
1832 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1833 set_representation(Representation::Tagged());
1834 SetFlag(kUseGVN);
1835 }
1836
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001837 virtual bool IsCheckInstruction() const { return true; }
1838
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839 virtual Representation RequiredInputRepresentation(int index) const {
1840 return Representation::Tagged();
1841 }
1842
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001843 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001844
1845#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001846 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001847#endif
1848
danno@chromium.org160a7b02011-04-18 15:51:38 +00001849 virtual HValue* Canonicalize() {
1850 HType value_type = value()->type();
1851 if (!value_type.IsUninitialized() &&
1852 (value_type.IsHeapNumber() ||
1853 value_type.IsString() ||
1854 value_type.IsBoolean() ||
1855 value_type.IsNonPrimitive())) {
1856 return NULL;
1857 }
1858 return this;
1859 }
1860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001861 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001862
1863 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001864 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001865};
1866
1867
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001868class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001870 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1871 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001872 SetFlag(kUseGVN);
1873 SetFlag(kDependsOnMaps);
1874 }
1875
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001876 virtual bool IsCheckInstruction() const { return true; }
1877
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001878#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001879 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001880#endif
1881
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001882 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001883 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001884
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001885 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001887 virtual Representation RequiredInputRepresentation(int index) const {
1888 return Representation::None();
1889 }
1890
1891 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001892 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001893 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1894 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1895 return hash;
1896 }
1897
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001898 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001899 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001900 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001901 return prototype_.is_identical_to(b->prototype()) &&
1902 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001903 }
1904
1905 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001906 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001907 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001908};
1909
1910
1911class HCheckSmi: public HUnaryOperation {
1912 public:
1913 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1914 set_representation(Representation::Tagged());
1915 SetFlag(kUseGVN);
1916 }
1917
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001918 virtual bool IsCheckInstruction() const { return true; }
1919
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001920 virtual Representation RequiredInputRepresentation(int index) const {
1921 return Representation::Tagged();
1922 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001923 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001924
1925#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001926 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001927#endif
1928
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001929 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001930
1931 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001932 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001933};
1934
1935
1936class HPhi: public HValue {
1937 public:
1938 explicit HPhi(int merged_index)
1939 : inputs_(2),
1940 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001941 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001942 is_live_(false),
1943 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1945 non_phi_uses_[i] = 0;
1946 indirect_uses_[i] = 0;
1947 }
1948 ASSERT(merged_index >= 0);
1949 set_representation(Representation::Tagged());
1950 SetFlag(kFlexibleRepresentation);
1951 }
1952
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001953 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001954 bool double_occurred = false;
1955 bool int32_occurred = false;
1956 for (int i = 0; i < OperandCount(); ++i) {
1957 HValue* value = OperandAt(i);
1958 if (value->representation().IsDouble()) double_occurred = true;
1959 if (value->representation().IsInteger32()) int32_occurred = true;
1960 if (value->representation().IsTagged()) return Representation::Tagged();
1961 }
1962
1963 if (double_occurred) return Representation::Double();
1964 if (int32_occurred) return Representation::Integer32();
1965 return Representation::None();
1966 }
1967
1968 virtual Range* InferRange();
1969 virtual Representation RequiredInputRepresentation(int index) const {
1970 return representation();
1971 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001972 virtual HType CalculateInferredType();
1973 virtual int OperandCount() { return inputs_.length(); }
1974 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1975 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001976 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001977 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001978
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001979 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001980
1981 int merged_index() const { return merged_index_; }
1982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001983 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001984
1985#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001986 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001987#endif
1988
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001989 void InitRealUses(int id);
1990 void AddNonPhiUsesFrom(HPhi* other);
1991 void AddIndirectUsesTo(int* use_count);
1992
1993 int tagged_non_phi_uses() const {
1994 return non_phi_uses_[Representation::kTagged];
1995 }
1996 int int32_non_phi_uses() const {
1997 return non_phi_uses_[Representation::kInteger32];
1998 }
1999 int double_non_phi_uses() const {
2000 return non_phi_uses_[Representation::kDouble];
2001 }
2002 int tagged_indirect_uses() const {
2003 return indirect_uses_[Representation::kTagged];
2004 }
2005 int int32_indirect_uses() const {
2006 return indirect_uses_[Representation::kInteger32];
2007 }
2008 int double_indirect_uses() const {
2009 return indirect_uses_[Representation::kDouble];
2010 }
2011 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002012 bool is_live() { return is_live_; }
2013 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002015 static HPhi* cast(HValue* value) {
2016 ASSERT(value->IsPhi());
2017 return reinterpret_cast<HPhi*>(value);
2018 }
2019 virtual Opcode opcode() const { return HValue::kPhi; }
2020
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002021 virtual bool IsConvertibleToInteger() const {
2022 return is_convertible_to_integer_;
2023 }
2024
2025 void set_is_convertible_to_integer(bool b) {
2026 is_convertible_to_integer_ = b;
2027 }
2028
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002029 protected:
2030 virtual void DeleteFromGraph();
2031 virtual void InternalSetOperandAt(int index, HValue* value) {
2032 inputs_[index] = value;
2033 }
2034
2035 private:
2036 ZoneList<HValue*> inputs_;
2037 int merged_index_;
2038
2039 int non_phi_uses_[Representation::kNumRepresentations];
2040 int indirect_uses_[Representation::kNumRepresentations];
2041 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002042 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002043 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002044};
2045
2046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002047class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002048 public:
2049 HArgumentsObject() {
2050 set_representation(Representation::Tagged());
2051 SetFlag(kIsArguments);
2052 }
2053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002054 virtual Representation RequiredInputRepresentation(int index) const {
2055 return Representation::None();
2056 }
2057
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002058 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002059};
2060
2061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002062class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063 public:
2064 HConstant(Handle<Object> handle, Representation r);
2065
2066 Handle<Object> handle() const { return handle_; }
2067
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002068 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070 virtual Representation RequiredInputRepresentation(int index) const {
2071 return Representation::None();
2072 }
2073
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002074 virtual bool IsConvertibleToInteger() const {
2075 if (handle_->IsSmi()) return true;
2076 if (handle_->IsHeapNumber() &&
2077 (HeapNumber::cast(*handle_)->value() ==
2078 static_cast<double>(NumberToInt32(*handle_)))) return true;
2079 return false;
2080 }
2081
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002082 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002083 virtual void PrintDataTo(StringStream* stream);
2084 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002085 bool IsInteger() const { return handle_->IsSmi(); }
2086 HConstant* CopyToRepresentation(Representation r) const;
2087 HConstant* CopyToTruncatedInt32() const;
2088 bool HasInteger32Value() const { return has_int32_value_; }
2089 int32_t Integer32Value() const {
2090 ASSERT(HasInteger32Value());
2091 return int32_value_;
2092 }
2093 bool HasDoubleValue() const { return has_double_value_; }
2094 double DoubleValue() const {
2095 ASSERT(HasDoubleValue());
2096 return double_value_;
2097 }
2098 bool HasStringValue() const { return handle_->IsString(); }
2099
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002100 bool ToBoolean() const;
2101
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002102 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002103 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002104 return reinterpret_cast<intptr_t>(*handle());
2105 }
2106
2107#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002108 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109#endif
2110
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002111 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002112
2113 protected:
2114 virtual Range* InferRange();
2115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002116 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117 HConstant* other_constant = HConstant::cast(other);
2118 return handle().is_identical_to(other_constant->handle());
2119 }
2120
2121 private:
2122 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123
2124 // The following two values represent the int32 and the double value of the
2125 // given constant if there is a lossless conversion between the constant
2126 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002127 bool has_int32_value_ : 1;
2128 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002129 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002130 double double_value_;
2131};
2132
2133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002134class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002135 public:
2136 HBinaryOperation(HValue* left, HValue* right) {
2137 ASSERT(left != NULL && right != NULL);
2138 SetOperandAt(0, left);
2139 SetOperandAt(1, right);
2140 }
2141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002142 HValue* left() { return OperandAt(0); }
2143 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002144
2145 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2146 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002147 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002148 if (IsCommutative() && left()->IsConstant()) return right();
2149 return left();
2150 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002151 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002152 if (IsCommutative() && left()->IsConstant()) return left();
2153 return right();
2154 }
2155
2156 virtual bool IsCommutative() const { return false; }
2157
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002158 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159};
2160
2161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002162class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002163 public:
2164 HApplyArguments(HValue* function,
2165 HValue* receiver,
2166 HValue* length,
2167 HValue* elements) {
2168 set_representation(Representation::Tagged());
2169 SetOperandAt(0, function);
2170 SetOperandAt(1, receiver);
2171 SetOperandAt(2, length);
2172 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002173 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174 }
2175
2176 virtual Representation RequiredInputRepresentation(int index) const {
2177 // The length is untagged, all other inputs are tagged.
2178 return (index == 2)
2179 ? Representation::Integer32()
2180 : Representation::Tagged();
2181 }
2182
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002183 HValue* function() { return OperandAt(0); }
2184 HValue* receiver() { return OperandAt(1); }
2185 HValue* length() { return OperandAt(2); }
2186 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002187
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002188 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002189};
2190
2191
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002192class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002193 public:
2194 HArgumentsElements() {
2195 // The value produced by this instruction is a pointer into the stack
2196 // that looks as if it was a smi because of alignment.
2197 set_representation(Representation::Tagged());
2198 SetFlag(kUseGVN);
2199 }
2200
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002201 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002203 virtual Representation RequiredInputRepresentation(int index) const {
2204 return Representation::None();
2205 }
2206
ager@chromium.org378b34e2011-01-28 08:04:38 +00002207 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002208 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002209};
2210
2211
2212class HArgumentsLength: public HUnaryOperation {
2213 public:
2214 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2215 set_representation(Representation::Integer32());
2216 SetFlag(kUseGVN);
2217 }
2218
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002219 virtual Representation RequiredInputRepresentation(int index) const {
2220 return Representation::Tagged();
2221 }
2222
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002223 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002224
2225 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002226 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227};
2228
2229
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002230class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002231 public:
2232 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2233 set_representation(Representation::Tagged());
2234 SetFlag(kUseGVN);
2235 SetOperandAt(0, arguments);
2236 SetOperandAt(1, length);
2237 SetOperandAt(2, index);
2238 }
2239
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002240 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002241
2242 virtual Representation RequiredInputRepresentation(int index) const {
2243 // The arguments elements is considered tagged.
2244 return index == 0
2245 ? Representation::Tagged()
2246 : Representation::Integer32();
2247 }
2248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002249 HValue* arguments() { return OperandAt(0); }
2250 HValue* length() { return OperandAt(1); }
2251 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002252
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002253 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002254
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002255 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002256};
2257
2258
2259class HBoundsCheck: public HBinaryOperation {
2260 public:
2261 HBoundsCheck(HValue* index, HValue* length)
2262 : HBinaryOperation(index, length) {
2263 SetFlag(kUseGVN);
2264 }
2265
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002266 virtual bool IsCheckInstruction() const { return true; }
2267
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002268 virtual Representation RequiredInputRepresentation(int index) const {
2269 return Representation::Integer32();
2270 }
2271
2272#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002273 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002274#endif
2275
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002276 HValue* index() { return left(); }
2277 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002278
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002279 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002280
2281 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002282 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002283};
2284
2285
2286class HBitwiseBinaryOperation: public HBinaryOperation {
2287 public:
2288 HBitwiseBinaryOperation(HValue* left, HValue* right)
2289 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002290 set_representation(Representation::Tagged());
2291 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002292 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002293 }
2294
2295 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002296 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002297 }
2298
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002299 virtual void RepresentationChanged(Representation to) {
2300 if (!to.IsTagged()) {
2301 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002302 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002303 SetFlag(kTruncatingToInt32);
2304 SetFlag(kUseGVN);
2305 }
2306 }
2307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002308 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002309
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002310 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002311};
2312
2313
2314class HArithmeticBinaryOperation: public HBinaryOperation {
2315 public:
2316 HArithmeticBinaryOperation(HValue* left, HValue* right)
2317 : HBinaryOperation(left, right) {
2318 set_representation(Representation::Tagged());
2319 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002320 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002321 }
2322
2323 virtual void RepresentationChanged(Representation to) {
2324 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002325 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002326 SetFlag(kUseGVN);
2327 }
2328 }
2329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002330 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331 virtual Representation RequiredInputRepresentation(int index) const {
2332 return representation();
2333 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002334 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002335 if (left()->representation().Equals(right()->representation())) {
2336 return left()->representation();
2337 }
2338 return HValue::InferredRepresentation();
2339 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002340};
2341
2342
2343class HCompare: public HBinaryOperation {
2344 public:
2345 HCompare(HValue* left, HValue* right, Token::Value token)
2346 : HBinaryOperation(left, right), token_(token) {
2347 ASSERT(Token::IsCompareOp(token));
2348 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002349 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002350 }
2351
2352 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002353
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002354 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002355 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002356 }
2357
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002358 virtual Representation RequiredInputRepresentation(int index) const {
2359 return input_representation_;
2360 }
2361 Representation GetInputRepresentation() const {
2362 return input_representation_;
2363 }
2364 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002365 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002366
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002367 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002369 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002370 return HValue::Hashcode() * 7 + token_;
2371 }
2372
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002373 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374
2375 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002376 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377 HCompare* comp = HCompare::cast(other);
2378 return token_ == comp->token();
2379 }
2380
2381 private:
2382 Representation input_representation_;
2383 Token::Value token_;
2384};
2385
2386
2387class HCompareJSObjectEq: public HBinaryOperation {
2388 public:
2389 HCompareJSObjectEq(HValue* left, HValue* right)
2390 : HBinaryOperation(left, right) {
2391 set_representation(Representation::Tagged());
2392 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002393 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002394 }
2395
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002396 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002397 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002398 }
2399
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002400 virtual Representation RequiredInputRepresentation(int index) const {
2401 return Representation::Tagged();
2402 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002403 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002404
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002405 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002406
2407 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002408 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409};
2410
2411
2412class HUnaryPredicate: public HUnaryOperation {
2413 public:
2414 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2415 set_representation(Representation::Tagged());
2416 SetFlag(kUseGVN);
2417 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002418
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002419 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002420 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002421 }
2422
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002423 virtual Representation RequiredInputRepresentation(int index) const {
2424 return Representation::Tagged();
2425 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002427};
2428
2429
2430class HIsNull: public HUnaryPredicate {
2431 public:
2432 HIsNull(HValue* value, bool is_strict)
2433 : HUnaryPredicate(value), is_strict_(is_strict) { }
2434
2435 bool is_strict() const { return is_strict_; }
2436
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002437 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002439 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002440 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002441 HIsNull* b = HIsNull::cast(other);
2442 return is_strict_ == b->is_strict();
2443 }
2444
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445 private:
2446 bool is_strict_;
2447};
2448
2449
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002450class HIsObject: public HUnaryPredicate {
2451 public:
2452 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2453
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002454 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002455
2456 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002457 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002458};
2459
2460
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002461class HIsSmi: public HUnaryPredicate {
2462 public:
2463 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2464
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002465 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002466
2467 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002468 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002469};
2470
2471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002472class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002473 public:
2474 HIsConstructCall() {
2475 set_representation(Representation::Tagged());
2476 SetFlag(kUseGVN);
2477 }
2478
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002479 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002480 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002481 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002482
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002483 virtual Representation RequiredInputRepresentation(int index) const {
2484 return Representation::None();
2485 }
2486
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002487 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002488
2489 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002490 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002491};
2492
2493
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002494class HHasInstanceType: public HUnaryPredicate {
2495 public:
2496 HHasInstanceType(HValue* value, InstanceType type)
2497 : HUnaryPredicate(value), from_(type), to_(type) { }
2498 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2499 : HUnaryPredicate(value), from_(from), to_(to) {
2500 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2501 }
2502
2503 InstanceType from() { return from_; }
2504 InstanceType to() { return to_; }
2505
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002506 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002507
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002508 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002509
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002510 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002511 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002512 HHasInstanceType* b = HHasInstanceType::cast(other);
2513 return (from_ == b->from()) && (to_ == b->to());
2514 }
2515
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516 private:
2517 InstanceType from_;
2518 InstanceType to_; // Inclusive range, not all combinations work.
2519};
2520
2521
2522class HHasCachedArrayIndex: public HUnaryPredicate {
2523 public:
2524 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2525
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002526 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002527
2528 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002529 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002530};
2531
2532
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002533class HGetCachedArrayIndex: public HUnaryPredicate {
2534 public:
2535 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2536
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002537 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002538
2539 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002540 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002541};
2542
2543
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544class HClassOfTest: public HUnaryPredicate {
2545 public:
2546 HClassOfTest(HValue* value, Handle<String> class_name)
2547 : HUnaryPredicate(value), class_name_(class_name) { }
2548
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002549 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002551 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002552
2553 Handle<String> class_name() const { return class_name_; }
2554
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002555 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002556 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002557 HClassOfTest* b = HClassOfTest::cast(other);
2558 return class_name_.is_identical_to(b->class_name_);
2559 }
2560
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002561 private:
2562 Handle<String> class_name_;
2563};
2564
2565
2566class HTypeofIs: public HUnaryPredicate {
2567 public:
2568 HTypeofIs(HValue* value, Handle<String> type_literal)
2569 : HUnaryPredicate(value), type_literal_(type_literal) { }
2570
2571 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002572 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002573
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002574 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575
2576 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002577 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002578 HTypeofIs* b = HTypeofIs::cast(other);
2579 return type_literal_.is_identical_to(b->type_literal_);
2580 }
2581
2582 private:
2583 Handle<String> type_literal_;
2584};
2585
2586
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002587class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002588 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002589 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2590 SetOperandAt(0, context);
2591 SetOperandAt(1, left);
2592 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002593 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002594 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002595 }
2596
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002597 HValue* context() { return OperandAt(0); }
2598 HValue* left() { return OperandAt(1); }
2599 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002600
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002601 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002602 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002603 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604
2605 virtual Representation RequiredInputRepresentation(int index) const {
2606 return Representation::Tagged();
2607 }
2608
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002609 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002610
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002611 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002612};
2613
2614
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002615class HInstanceOfKnownGlobal: public HUnaryOperation {
2616 public:
2617 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2618 : HUnaryOperation(left), function_(right) {
2619 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002620 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002621 }
2622
2623 Handle<JSFunction> function() { return function_; }
2624
2625 virtual Representation RequiredInputRepresentation(int index) const {
2626 return Representation::Tagged();
2627 }
2628
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002629 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002630
2631 private:
2632 Handle<JSFunction> function_;
2633};
2634
2635
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002636class HPower: public HBinaryOperation {
2637 public:
2638 HPower(HValue* left, HValue* right)
2639 : HBinaryOperation(left, right) {
2640 set_representation(Representation::Double());
2641 SetFlag(kUseGVN);
2642 }
2643
2644 virtual Representation RequiredInputRepresentation(int index) const {
2645 return (index == 1) ? Representation::None() : Representation::Double();
2646 }
2647
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002648 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002649
2650 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002651 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002652};
2653
2654
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002655class HAdd: public HArithmeticBinaryOperation {
2656 public:
2657 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2658 SetFlag(kCanOverflow);
2659 }
2660
2661 // Add is only commutative if two integer values are added and not if two
2662 // tagged values are added (because it might be a String concatenation).
2663 virtual bool IsCommutative() const {
2664 return !representation().IsTagged();
2665 }
2666
2667 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002669 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002670
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002671 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002672
2673 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002674 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002675
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676 virtual Range* InferRange();
2677};
2678
2679
2680class HSub: public HArithmeticBinaryOperation {
2681 public:
2682 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2683 SetFlag(kCanOverflow);
2684 }
2685
2686 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2687
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002688 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002689
2690 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002691 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002692
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002693 virtual Range* InferRange();
2694};
2695
2696
2697class HMul: public HArithmeticBinaryOperation {
2698 public:
2699 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2700 SetFlag(kCanOverflow);
2701 }
2702
2703 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2704
2705 // Only commutative if it is certain that not two objects are multiplicated.
2706 virtual bool IsCommutative() const {
2707 return !representation().IsTagged();
2708 }
2709
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002710 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002711
2712 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002713 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002714
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715 virtual Range* InferRange();
2716};
2717
2718
2719class HMod: public HArithmeticBinaryOperation {
2720 public:
2721 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2722 SetFlag(kCanBeDivByZero);
2723 }
2724
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002725 bool HasPowerOf2Divisor() {
2726 if (right()->IsConstant() &&
2727 HConstant::cast(right())->HasInteger32Value()) {
2728 int32_t value = HConstant::cast(right())->Integer32Value();
2729 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2730 }
2731
2732 return false;
2733 }
2734
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002735 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2736
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002737 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738
2739 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002740 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002741
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002742 virtual Range* InferRange();
2743};
2744
2745
2746class HDiv: public HArithmeticBinaryOperation {
2747 public:
2748 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2749 SetFlag(kCanBeDivByZero);
2750 SetFlag(kCanOverflow);
2751 }
2752
2753 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2754
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002755 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002756
2757 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002758 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002759
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760 virtual Range* InferRange();
2761};
2762
2763
2764class HBitAnd: public HBitwiseBinaryOperation {
2765 public:
2766 HBitAnd(HValue* left, HValue* right)
2767 : HBitwiseBinaryOperation(left, right) { }
2768
2769 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002770 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002771
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002772 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773
2774 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002775 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002776
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002777 virtual Range* InferRange();
2778};
2779
2780
2781class HBitXor: public HBitwiseBinaryOperation {
2782 public:
2783 HBitXor(HValue* left, HValue* right)
2784 : HBitwiseBinaryOperation(left, right) { }
2785
2786 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002787 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002789 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002790
2791 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002792 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002793};
2794
2795
2796class HBitOr: public HBitwiseBinaryOperation {
2797 public:
2798 HBitOr(HValue* left, HValue* right)
2799 : HBitwiseBinaryOperation(left, right) { }
2800
2801 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002802 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002803
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002804 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002805
2806 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002807 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002808
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809 virtual Range* InferRange();
2810};
2811
2812
2813class HShl: public HBitwiseBinaryOperation {
2814 public:
2815 HShl(HValue* left, HValue* right)
2816 : HBitwiseBinaryOperation(left, right) { }
2817
2818 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002819 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002821 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002822
2823 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002824 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825};
2826
2827
2828class HShr: public HBitwiseBinaryOperation {
2829 public:
2830 HShr(HValue* left, HValue* right)
2831 : HBitwiseBinaryOperation(left, right) { }
2832
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002833 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002834
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002835 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002836
2837 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002838 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002839};
2840
2841
2842class HSar: public HBitwiseBinaryOperation {
2843 public:
2844 HSar(HValue* left, HValue* right)
2845 : HBitwiseBinaryOperation(left, right) { }
2846
2847 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002848 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002849
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002850 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002851
2852 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002853 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002854};
2855
2856
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002857class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858 public:
2859 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2860 SetFlag(kChangesOsrEntries);
2861 }
2862
2863 int ast_id() const { return ast_id_; }
2864
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002865 virtual Representation RequiredInputRepresentation(int index) const {
2866 return Representation::None();
2867 }
2868
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002869 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002870
2871 private:
2872 int ast_id_;
2873};
2874
2875
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002876class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002877 public:
2878 explicit HParameter(unsigned index) : index_(index) {
2879 set_representation(Representation::Tagged());
2880 }
2881
2882 unsigned index() const { return index_; }
2883
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002884 virtual void PrintDataTo(StringStream* stream);
2885
2886 virtual Representation RequiredInputRepresentation(int index) const {
2887 return Representation::None();
2888 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002889
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002890 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002891
2892 private:
2893 unsigned index_;
2894};
2895
2896
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002897class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002898 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002899 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2900 : HUnaryCall(context, argument_count),
2901 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903 }
2904
2905 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002907 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908
2909 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2910 transcendental_type_ = transcendental_type;
2911 }
2912 TranscendentalCache::Type transcendental_type() {
2913 return transcendental_type_;
2914 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002915
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002916 virtual void PrintDataTo(StringStream* stream);
2917
2918 virtual Representation RequiredInputRepresentation(int index) const {
2919 return Representation::Tagged();
2920 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002921
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002922 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923
2924 private:
2925 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002926 TranscendentalCache::Type transcendental_type_;
2927};
2928
2929
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002930class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 public:
2932 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002934 virtual Representation RequiredInputRepresentation(int index) const {
2935 return Representation::None();
2936 }
2937
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002938 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002939};
2940
2941
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002942class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002943 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002944 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945 : cell_(cell), check_hole_value_(check_hole_value) {
2946 set_representation(Representation::Tagged());
2947 SetFlag(kUseGVN);
2948 SetFlag(kDependsOnGlobalVars);
2949 }
2950
2951 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2952 bool check_hole_value() const { return check_hole_value_; }
2953
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002954 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002955
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002956 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002957 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002958 return reinterpret_cast<intptr_t>(*cell_);
2959 }
2960
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002961 virtual Representation RequiredInputRepresentation(int index) const {
2962 return Representation::None();
2963 }
2964
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002965 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966
2967 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002968 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002969 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002970 return cell_.is_identical_to(b->cell());
2971 }
2972
2973 private:
2974 Handle<JSGlobalPropertyCell> cell_;
2975 bool check_hole_value_;
2976};
2977
2978
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002979class HLoadGlobalGeneric: public HBinaryOperation {
2980 public:
2981 HLoadGlobalGeneric(HValue* context,
2982 HValue* global_object,
2983 Handle<Object> name,
2984 bool for_typeof)
2985 : HBinaryOperation(context, global_object),
2986 name_(name),
2987 for_typeof_(for_typeof) {
2988 set_representation(Representation::Tagged());
2989 SetAllSideEffects();
2990 }
2991
2992 HValue* context() { return OperandAt(0); }
2993 HValue* global_object() { return OperandAt(1); }
2994 Handle<Object> name() const { return name_; }
2995 bool for_typeof() const { return for_typeof_; }
2996
2997 virtual void PrintDataTo(StringStream* stream);
2998
2999 virtual Representation RequiredInputRepresentation(int index) const {
3000 return Representation::Tagged();
3001 }
3002
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003003 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003004
3005 private:
3006 Handle<Object> name_;
3007 bool for_typeof_;
3008};
3009
3010
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003011class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003013 HStoreGlobalCell(HValue* value,
3014 Handle<JSGlobalPropertyCell> cell,
3015 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003016 : HUnaryOperation(value),
3017 cell_(cell),
3018 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019 SetFlag(kChangesGlobalVars);
3020 }
3021
3022 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003023 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024
3025 virtual Representation RequiredInputRepresentation(int index) const {
3026 return Representation::Tagged();
3027 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003028 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003029
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003030 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003031
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032 private:
3033 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003034 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003035};
3036
3037
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003038class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3039 public:
3040 HStoreGlobalGeneric(HValue* context,
3041 HValue* global_object,
3042 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003043 HValue* value,
3044 bool strict_mode)
3045 : name_(name),
3046 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003047 SetOperandAt(0, context);
3048 SetOperandAt(1, global_object);
3049 SetOperandAt(2, value);
3050 set_representation(Representation::Tagged());
3051 SetAllSideEffects();
3052 }
3053
3054 HValue* context() { return OperandAt(0); }
3055 HValue* global_object() { return OperandAt(1); }
3056 Handle<Object> name() const { return name_; }
3057 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003058 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003059
3060 virtual void PrintDataTo(StringStream* stream);
3061
3062 virtual Representation RequiredInputRepresentation(int index) const {
3063 return Representation::Tagged();
3064 }
3065
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003066 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003067
3068 private:
3069 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003070 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003071};
3072
3073
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003074class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003075 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003076 HLoadContextSlot(HValue* context , int slot_index)
3077 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003078 set_representation(Representation::Tagged());
3079 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003080 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003081 }
3082
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003083 int slot_index() const { return slot_index_; }
3084
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003085 virtual Representation RequiredInputRepresentation(int index) const {
3086 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003087 }
3088
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003089 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003090
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003091 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003092
3093 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003094 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003095 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003096 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003097 }
3098
3099 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003100 int slot_index_;
3101};
3102
3103
3104static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3105 return !value->type().IsSmi() &&
3106 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3107}
3108
3109
3110class HStoreContextSlot: public HBinaryOperation {
3111 public:
3112 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3113 : HBinaryOperation(context, value), slot_index_(slot_index) {
3114 SetFlag(kChangesContextSlots);
3115 }
3116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003117 HValue* context() { return OperandAt(0); }
3118 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003119 int slot_index() const { return slot_index_; }
3120
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003121 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003122 return StoringValueNeedsWriteBarrier(value());
3123 }
3124
3125 virtual Representation RequiredInputRepresentation(int index) const {
3126 return Representation::Tagged();
3127 }
3128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003129 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003130
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003131 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003132
3133 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003134 int slot_index_;
3135};
3136
3137
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138class HLoadNamedField: public HUnaryOperation {
3139 public:
3140 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3141 : HUnaryOperation(object),
3142 is_in_object_(is_in_object),
3143 offset_(offset) {
3144 set_representation(Representation::Tagged());
3145 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003146 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003147 if (is_in_object) {
3148 SetFlag(kDependsOnInobjectFields);
3149 } else {
3150 SetFlag(kDependsOnBackingStoreFields);
3151 }
3152 }
3153
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003154 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155 bool is_in_object() const { return is_in_object_; }
3156 int offset() const { return offset_; }
3157
3158 virtual Representation RequiredInputRepresentation(int index) const {
3159 return Representation::Tagged();
3160 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003161 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003163 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164
3165 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003166 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167 HLoadNamedField* b = HLoadNamedField::cast(other);
3168 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3169 }
3170
3171 private:
3172 bool is_in_object_;
3173 int offset_;
3174};
3175
3176
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003177class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3178 public:
3179 HLoadNamedFieldPolymorphic(HValue* object,
3180 ZoneMapList* types,
3181 Handle<String> name);
3182
3183 HValue* object() { return OperandAt(0); }
3184 ZoneMapList* types() { return &types_; }
3185 Handle<String> name() { return name_; }
3186 bool need_generic() { return need_generic_; }
3187
3188 virtual Representation RequiredInputRepresentation(int index) const {
3189 return Representation::Tagged();
3190 }
3191
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003192 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003193
3194 static const int kMaxLoadPolymorphism = 4;
3195
3196 protected:
3197 virtual bool DataEquals(HValue* value);
3198
3199 private:
3200 ZoneMapList types_;
3201 Handle<String> name_;
3202 bool need_generic_;
3203};
3204
3205
3206
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003207class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003208 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003209 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3210 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003212 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003213 }
3214
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003215 HValue* context() { return OperandAt(0); }
3216 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003217 Handle<Object> name() const { return name_; }
3218
3219 virtual Representation RequiredInputRepresentation(int index) const {
3220 return Representation::Tagged();
3221 }
3222
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003223 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003225 private:
3226 Handle<Object> name_;
3227};
3228
3229
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003230class HLoadFunctionPrototype: public HUnaryOperation {
3231 public:
3232 explicit HLoadFunctionPrototype(HValue* function)
3233 : HUnaryOperation(function) {
3234 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003235 SetFlag(kUseGVN);
3236 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003237 }
3238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003239 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003240
3241 virtual Representation RequiredInputRepresentation(int index) const {
3242 return Representation::Tagged();
3243 }
3244
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003245 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003246
3247 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003248 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003249};
3250
3251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003252class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003253 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003254 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003255 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003256 SetFlag(kDependsOnArrayElements);
3257 SetFlag(kUseGVN);
3258 }
3259
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003260 HValue* object() { return OperandAt(0); }
3261 HValue* key() { return OperandAt(1); }
3262
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263 virtual Representation RequiredInputRepresentation(int index) const {
3264 // The key is supposed to be Integer32.
3265 return (index == 1) ? Representation::Integer32()
3266 : Representation::Tagged();
3267 }
3268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003269 virtual void PrintDataTo(StringStream* stream);
3270
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003271 bool RequiresHoleCheck() const;
3272
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003273 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003274
3275 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003276 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003277};
3278
3279
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003280class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003281 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003282 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3283 HValue* key,
3284 ExternalArrayType array_type)
3285 : HBinaryOperation(external_elements, key),
3286 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003287 if (array_type == kExternalFloatArray ||
3288 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003289 set_representation(Representation::Double());
3290 } else {
3291 set_representation(Representation::Integer32());
3292 }
3293 SetFlag(kDependsOnSpecializedArrayElements);
3294 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003295 SetFlag(kDependsOnCalls);
3296 SetFlag(kUseGVN);
3297 }
3298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003299 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003300
3301 virtual Representation RequiredInputRepresentation(int index) const {
3302 // The key is supposed to be Integer32, but the base pointer
3303 // for the element load is a naked pointer.
3304 return (index == 1) ? Representation::Integer32()
3305 : Representation::External();
3306 }
3307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003308 HValue* external_pointer() { return OperandAt(0); }
3309 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003310 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003311
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003312 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003313
3314 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003315 virtual bool DataEquals(HValue* other) {
3316 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3317 HLoadKeyedSpecializedArrayElement* cast_other =
3318 HLoadKeyedSpecializedArrayElement::cast(other);
3319 return array_type_ == cast_other->array_type();
3320 }
3321
3322 private:
3323 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003324};
3325
3326
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003327class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003328 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003329 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003330 set_representation(Representation::Tagged());
3331 SetOperandAt(0, obj);
3332 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003333 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003334 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003335 }
3336
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003337 HValue* object() { return OperandAt(0); }
3338 HValue* key() { return OperandAt(1); }
3339 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003340
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003341 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003342
3343 virtual Representation RequiredInputRepresentation(int index) const {
3344 return Representation::Tagged();
3345 }
3346
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003347 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003348};
3349
3350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003351class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003352 public:
3353 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003354 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003355 HValue* val,
3356 bool in_object,
3357 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358 : HBinaryOperation(obj, val),
3359 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003360 is_in_object_(in_object),
3361 offset_(offset) {
3362 if (is_in_object_) {
3363 SetFlag(kChangesInobjectFields);
3364 } else {
3365 SetFlag(kChangesBackingStoreFields);
3366 }
3367 }
3368
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003369 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003370
3371 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003372 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003373 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003374 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003376 HValue* object() { return OperandAt(0); }
3377 HValue* value() { return OperandAt(1); }
3378
3379 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003380 bool is_in_object() const { return is_in_object_; }
3381 int offset() const { return offset_; }
3382 Handle<Map> transition() const { return transition_; }
3383 void set_transition(Handle<Map> map) { transition_ = map; }
3384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003385 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003386 return StoringValueNeedsWriteBarrier(value());
3387 }
3388
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003389 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003390 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003391 bool is_in_object_;
3392 int offset_;
3393 Handle<Map> transition_;
3394};
3395
3396
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003397class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003398 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003399 HStoreNamedGeneric(HValue* context,
3400 HValue* object,
3401 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003402 HValue* value,
3403 bool strict_mode)
3404 : name_(name),
3405 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003406 SetOperandAt(0, object);
3407 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003408 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003409 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003410 }
3411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003412 HValue* object() { return OperandAt(0); }
3413 HValue* value() { return OperandAt(1); }
3414 HValue* context() { return OperandAt(2); }
3415 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003416 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003418 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003419
3420 virtual Representation RequiredInputRepresentation(int index) const {
3421 return Representation::Tagged();
3422 }
3423
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003424 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003425
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003426 private:
3427 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003428 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003429};
3430
3431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003432class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003433 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003434 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3435 SetOperandAt(0, obj);
3436 SetOperandAt(1, key);
3437 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003438 SetFlag(kChangesArrayElements);
3439 }
3440
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003441 virtual Representation RequiredInputRepresentation(int index) const {
3442 // The key is supposed to be Integer32.
3443 return (index == 1) ? Representation::Integer32()
3444 : Representation::Tagged();
3445 }
3446
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003447 HValue* object() { return OperandAt(0); }
3448 HValue* key() { return OperandAt(1); }
3449 HValue* value() { return OperandAt(2); }
3450
3451 bool NeedsWriteBarrier() {
3452 return StoringValueNeedsWriteBarrier(value());
3453 }
3454
3455 virtual void PrintDataTo(StringStream* stream);
3456
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003457 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003458};
3459
3460
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003461class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003462 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003463 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3464 HValue* key,
3465 HValue* val,
3466 ExternalArrayType array_type)
3467 : array_type_(array_type) {
3468 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003469 SetOperandAt(0, external_elements);
3470 SetOperandAt(1, key);
3471 SetOperandAt(2, val);
3472 }
3473
3474 virtual void PrintDataTo(StringStream* stream);
3475
3476 virtual Representation RequiredInputRepresentation(int index) const {
3477 if (index == 0) {
3478 return Representation::External();
3479 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003480 if (index == 2 && (array_type() == kExternalFloatArray ||
3481 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003482 return Representation::Double();
3483 } else {
3484 return Representation::Integer32();
3485 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003486 }
3487 }
3488
3489 HValue* external_pointer() { return OperandAt(0); }
3490 HValue* key() { return OperandAt(1); }
3491 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003492 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003493
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003494 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3495
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003496 private:
3497 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003498};
3499
3500
3501class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003502 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003503 HStoreKeyedGeneric(HValue* context,
3504 HValue* object,
3505 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003506 HValue* value,
3507 bool strict_mode)
3508 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003509 SetOperandAt(0, object);
3510 SetOperandAt(1, key);
3511 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003512 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003513 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003514 }
3515
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003516 HValue* object() { return OperandAt(0); }
3517 HValue* key() { return OperandAt(1); }
3518 HValue* value() { return OperandAt(2); }
3519 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003520 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003521
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003522 virtual Representation RequiredInputRepresentation(int index) const {
3523 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003524 }
3525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003526 virtual void PrintDataTo(StringStream* stream);
3527
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003528 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003529
3530 private:
3531 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003532};
3533
3534
danno@chromium.org160a7b02011-04-18 15:51:38 +00003535class HStringAdd: public HBinaryOperation {
3536 public:
3537 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3538 set_representation(Representation::Tagged());
3539 SetFlag(kUseGVN);
3540 SetFlag(kDependsOnMaps);
3541 }
3542
3543 virtual Representation RequiredInputRepresentation(int index) const {
3544 return Representation::Tagged();
3545 }
3546
3547 virtual HType CalculateInferredType() {
3548 return HType::String();
3549 }
3550
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003551 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003552
3553 protected:
3554 virtual bool DataEquals(HValue* other) { return true; }
3555};
3556
3557
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003558class HStringCharCodeAt: public HBinaryOperation {
3559 public:
3560 HStringCharCodeAt(HValue* string, HValue* index)
3561 : HBinaryOperation(string, index) {
3562 set_representation(Representation::Integer32());
3563 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003564 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003565 }
3566
3567 virtual Representation RequiredInputRepresentation(int index) const {
3568 // The index is supposed to be Integer32.
3569 return (index == 1) ? Representation::Integer32()
3570 : Representation::Tagged();
3571 }
3572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003573 HValue* string() { return OperandAt(0); }
3574 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003575
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003576 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003577
3578 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003580
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003581 virtual Range* InferRange() {
3582 return new Range(0, String::kMaxUC16CharCode);
3583 }
3584};
3585
3586
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003587class HStringCharFromCode: public HUnaryOperation {
3588 public:
3589 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3590 set_representation(Representation::Tagged());
3591 SetFlag(kUseGVN);
3592 }
3593
3594 virtual Representation RequiredInputRepresentation(int index) const {
3595 return Representation::Integer32();
3596 }
3597
3598 virtual bool DataEquals(HValue* other) { return true; }
3599
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003600 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003601};
3602
3603
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003604class HStringLength: public HUnaryOperation {
3605 public:
3606 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3607 set_representation(Representation::Tagged());
3608 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003609 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003610 }
3611
3612 virtual Representation RequiredInputRepresentation(int index) const {
3613 return Representation::Tagged();
3614 }
3615
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003616 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003617 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3618 return HType::Smi();
3619 }
3620
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003621 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003622
3623 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003624 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003625
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003626 virtual Range* InferRange() {
3627 return new Range(0, String::kMaxLength);
3628 }
3629};
3630
3631
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003632template <int V>
3633class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003635 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003637 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003638 }
3639
3640 int literal_index() const { return literal_index_; }
3641 int depth() const { return depth_; }
3642
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643 private:
3644 int literal_index_;
3645 int depth_;
3646};
3647
3648
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003649class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003650 public:
3651 HArrayLiteral(Handle<FixedArray> constant_elements,
3652 int length,
3653 int literal_index,
3654 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003655 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003656 length_(length),
3657 constant_elements_(constant_elements) {}
3658
3659 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3660 int length() const { return length_; }
3661
3662 bool IsCopyOnWrite() const;
3663
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003664 virtual Representation RequiredInputRepresentation(int index) const {
3665 return Representation::None();
3666 }
3667
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003668 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003669
3670 private:
3671 int length_;
3672 Handle<FixedArray> constant_elements_;
3673};
3674
3675
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003676class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003677 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003678 HObjectLiteral(HValue* context,
3679 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680 bool fast_elements,
3681 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003682 int depth,
3683 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003684 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003685 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003686 fast_elements_(fast_elements),
3687 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003688 SetOperandAt(0, context);
3689 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003691 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003692 Handle<FixedArray> constant_properties() const {
3693 return constant_properties_;
3694 }
3695 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003696 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003697
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003698 virtual Representation RequiredInputRepresentation(int index) const {
3699 return Representation::Tagged();
3700 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003701
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003702 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003703
3704 private:
3705 Handle<FixedArray> constant_properties_;
3706 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003707 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003708};
3709
3710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003711class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003712 public:
3713 HRegExpLiteral(Handle<String> pattern,
3714 Handle<String> flags,
3715 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003716 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003717 pattern_(pattern),
3718 flags_(flags) { }
3719
3720 Handle<String> pattern() { return pattern_; }
3721 Handle<String> flags() { return flags_; }
3722
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003723 virtual Representation RequiredInputRepresentation(int index) const {
3724 return Representation::None();
3725 }
3726
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003727 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003728
3729 private:
3730 Handle<String> pattern_;
3731 Handle<String> flags_;
3732};
3733
3734
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003735class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003736 public:
3737 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3738 : shared_info_(shared), pretenure_(pretenure) {
3739 set_representation(Representation::Tagged());
3740 }
3741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003742 virtual Representation RequiredInputRepresentation(int index) const {
3743 return Representation::None();
3744 }
3745
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003746 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003747
3748 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3749 bool pretenure() const { return pretenure_; }
3750
3751 private:
3752 Handle<SharedFunctionInfo> shared_info_;
3753 bool pretenure_;
3754};
3755
3756
3757class HTypeof: public HUnaryOperation {
3758 public:
3759 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3760 set_representation(Representation::Tagged());
3761 }
3762
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003763 virtual Representation RequiredInputRepresentation(int index) const {
3764 return Representation::Tagged();
3765 }
3766
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003767 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003768};
3769
3770
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003771class HToFastProperties: public HUnaryOperation {
3772 public:
3773 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3774 // This instruction is not marked as having side effects, but
3775 // changes the map of the input operand. Use it only when creating
3776 // object literals.
3777 ASSERT(value->IsObjectLiteral());
3778 set_representation(Representation::Tagged());
3779 }
3780
3781 virtual Representation RequiredInputRepresentation(int index) const {
3782 return Representation::Tagged();
3783 }
3784
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003785 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003786};
3787
3788
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003789class HValueOf: public HUnaryOperation {
3790 public:
3791 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3792 set_representation(Representation::Tagged());
3793 }
3794
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003795 virtual Representation RequiredInputRepresentation(int index) const {
3796 return Representation::Tagged();
3797 }
3798
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003799 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800};
3801
3802
3803class HDeleteProperty: public HBinaryOperation {
3804 public:
3805 HDeleteProperty(HValue* obj, HValue* key)
3806 : HBinaryOperation(obj, key) {
3807 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003808 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003809 }
3810
3811 virtual Representation RequiredInputRepresentation(int index) const {
3812 return Representation::Tagged();
3813 }
3814
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003815 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003816
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003817 HValue* object() { return left(); }
3818 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003819};
3820
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003821
3822class HIn: public HTemplateInstruction<2> {
3823 public:
3824 HIn(HValue* key, HValue* object) {
3825 SetOperandAt(0, key);
3826 SetOperandAt(1, object);
3827 set_representation(Representation::Tagged());
3828 SetAllSideEffects();
3829 }
3830
3831 HValue* key() { return OperandAt(0); }
3832 HValue* object() { return OperandAt(1); }
3833
3834 virtual Representation RequiredInputRepresentation(int index) const {
3835 return Representation::Tagged();
3836 }
3837
3838 virtual HType CalculateInferredType() {
3839 return HType::Boolean();
3840 }
3841
3842 virtual void PrintDataTo(StringStream* stream);
3843
3844 DECLARE_CONCRETE_INSTRUCTION(In)
3845};
3846
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003847#undef DECLARE_INSTRUCTION
3848#undef DECLARE_CONCRETE_INSTRUCTION
3849
3850} } // namespace v8::internal
3851
3852#endif // V8_HYDROGEN_INSTRUCTIONS_H_