blob: 88ce87dbc264b2411a9d3711d7d95fd0db9759a3 [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) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +000094 V(CompareSymbolEq) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000095 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000096 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000097 V(DeleteProperty) \
98 V(Deoptimize) \
99 V(Div) \
100 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000101 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000102 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000103 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000104 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000105 V(GlobalObject) \
106 V(GlobalReceiver) \
107 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000108 V(HasInstanceType) \
109 V(HasCachedArrayIndex) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000110 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000112 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000113 V(InvokeFunction) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000114 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000116 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(IsSmi) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000118 V(IsUndetectable) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000119 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000121 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000123 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000124 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000125 V(LoadGlobalCell) \
126 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LoadKeyedFastElement) \
128 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000129 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000131 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132 V(LoadNamedGeneric) \
133 V(Mod) \
134 V(Mul) \
135 V(ObjectLiteral) \
136 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000137 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000139 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000140 V(PushArgument) \
141 V(RegExpLiteral) \
142 V(Return) \
143 V(Sar) \
144 V(Shl) \
145 V(Shr) \
146 V(Simulate) \
147 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000148 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000149 V(StoreGlobalCell) \
150 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000151 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000152 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 V(StoreKeyedGeneric) \
154 V(StoreNamedField) \
155 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000156 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000157 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000158 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000159 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000161 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000162 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000163 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000164 V(Typeof) \
165 V(TypeofIs) \
166 V(UnaryMathOperation) \
167 V(UnknownOSRValue) \
168 V(ValueOf)
169
170#define GVN_FLAG_LIST(V) \
171 V(Calls) \
172 V(InobjectFields) \
173 V(BackingStoreFields) \
174 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000175 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(GlobalVars) \
177 V(Maps) \
178 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000179 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000180 V(OsrEntries)
181
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000182#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000183 virtual bool Is##type() const { return true; } \
184 static H##type* cast(HValue* value) { \
185 ASSERT(value->Is##type()); \
186 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000187 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188
189
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000190#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000192 static H##type* cast(HValue* value) { \
193 ASSERT(value->Is##type()); \
194 return reinterpret_cast<H##type*>(value); \
195 } \
196 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197
198
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000199class Range: public ZoneObject {
200 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000201 Range()
202 : lower_(kMinInt),
203 upper_(kMaxInt),
204 next_(NULL),
205 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206
207 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000208 : lower_(lower),
209 upper_(upper),
210 next_(NULL),
211 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213 int32_t upper() const { return upper_; }
214 int32_t lower() const { return lower_; }
215 Range* next() const { return next_; }
216 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
217 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000219 int32_t Mask() const;
220 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
221 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
222 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
223 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000224 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
225 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
226 bool IsInSmiRange() const {
227 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000229 void KeepOrder();
230 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000231
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000232 void StackUpon(Range* other) {
233 Intersect(other);
234 next_ = other;
235 }
236
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000237 void Intersect(Range* other);
238 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000239
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000240 void AddConstant(int32_t value);
241 void Sar(int32_t value);
242 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000243 bool AddAndCheckOverflow(Range* other);
244 bool SubAndCheckOverflow(Range* other);
245 bool MulAndCheckOverflow(Range* other);
246
247 private:
248 int32_t lower_;
249 int32_t upper_;
250 Range* next_;
251 bool can_be_minus_zero_;
252};
253
254
255class Representation {
256 public:
257 enum Kind {
258 kNone,
259 kTagged,
260 kDouble,
261 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000262 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000263 kNumRepresentations
264 };
265
266 Representation() : kind_(kNone) { }
267
268 static Representation None() { return Representation(kNone); }
269 static Representation Tagged() { return Representation(kTagged); }
270 static Representation Integer32() { return Representation(kInteger32); }
271 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000272 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000274 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000275 return kind_ == other.kind_;
276 }
277
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000278 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000279 bool IsNone() const { return kind_ == kNone; }
280 bool IsTagged() const { return kind_ == kTagged; }
281 bool IsInteger32() const { return kind_ == kInteger32; }
282 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000283 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000284 bool IsSpecialization() const {
285 return kind_ == kInteger32 || kind_ == kDouble;
286 }
287 const char* Mnemonic() const;
288
289 private:
290 explicit Representation(Kind k) : kind_(k) { }
291
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000292 // Make sure kind fits in int8.
293 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
294
295 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000296};
297
298
299class HType {
300 public:
301 HType() : type_(kUninitialized) { }
302
303 static HType Tagged() { return HType(kTagged); }
304 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
305 static HType TaggedNumber() { return HType(kTaggedNumber); }
306 static HType Smi() { return HType(kSmi); }
307 static HType HeapNumber() { return HType(kHeapNumber); }
308 static HType String() { return HType(kString); }
309 static HType Boolean() { return HType(kBoolean); }
310 static HType NonPrimitive() { return HType(kNonPrimitive); }
311 static HType JSArray() { return HType(kJSArray); }
312 static HType JSObject() { return HType(kJSObject); }
313 static HType Uninitialized() { return HType(kUninitialized); }
314
315 // Return the weakest (least precise) common type.
316 HType Combine(HType other) {
317 return HType(static_cast<Type>(type_ & other.type_));
318 }
319
320 bool Equals(const HType& other) {
321 return type_ == other.type_;
322 }
323
324 bool IsSubtypeOf(const HType& other) {
325 return Combine(other).Equals(other);
326 }
327
328 bool IsTagged() {
329 ASSERT(type_ != kUninitialized);
330 return ((type_ & kTagged) == kTagged);
331 }
332
333 bool IsTaggedPrimitive() {
334 ASSERT(type_ != kUninitialized);
335 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
336 }
337
338 bool IsTaggedNumber() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kTaggedNumber) == kTaggedNumber);
341 }
342
343 bool IsSmi() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kSmi) == kSmi);
346 }
347
348 bool IsHeapNumber() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kHeapNumber) == kHeapNumber);
351 }
352
353 bool IsString() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kString) == kString);
356 }
357
358 bool IsBoolean() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kBoolean) == kBoolean);
361 }
362
363 bool IsNonPrimitive() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kNonPrimitive) == kNonPrimitive);
366 }
367
368 bool IsJSArray() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kJSArray) == kJSArray);
371 }
372
373 bool IsJSObject() {
374 ASSERT(type_ != kUninitialized);
375 return ((type_ & kJSObject) == kJSObject);
376 }
377
378 bool IsUninitialized() {
379 return type_ == kUninitialized;
380 }
381
382 static HType TypeFromValue(Handle<Object> value);
383
384 const char* ToString();
385 const char* ToShortString();
386
387 private:
388 enum Type {
389 kTagged = 0x1, // 0000 0000 0000 0001
390 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
391 kTaggedNumber = 0xd, // 0000 0000 0000 1101
392 kSmi = 0x1d, // 0000 0000 0001 1101
393 kHeapNumber = 0x2d, // 0000 0000 0010 1101
394 kString = 0x45, // 0000 0000 0100 0101
395 kBoolean = 0x85, // 0000 0000 1000 0101
396 kNonPrimitive = 0x101, // 0000 0001 0000 0001
397 kJSObject = 0x301, // 0000 0011 0000 0001
398 kJSArray = 0x701, // 0000 0111 1000 0001
399 kUninitialized = 0x1fff // 0001 1111 1111 1111
400 };
401
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000402 // Make sure type fits in int16.
403 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
404
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000405 explicit HType(Type t) : type_(t) { }
406
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000407 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000408};
409
410
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000411class HUseListNode: public ZoneObject {
412 public:
413 HUseListNode(HValue* value, int index, HUseListNode* tail)
414 : tail_(tail), value_(value), index_(index) {
415 }
416
417 HUseListNode* tail() const { return tail_; }
418 HValue* value() const { return value_; }
419 int index() const { return index_; }
420
421 void set_tail(HUseListNode* list) { tail_ = list; }
422
423#ifdef DEBUG
424 void Zap() {
425 tail_ = reinterpret_cast<HUseListNode*>(1);
426 value_ = NULL;
427 index_ = -1;
428 }
429#endif
430
431 private:
432 HUseListNode* tail_;
433 HValue* value_;
434 int index_;
435};
436
437
438// We reuse use list nodes behind the scenes as uses are added and deleted.
439// This class is the safe way to iterate uses while deleting them.
440class HUseIterator BASE_EMBEDDED {
441 public:
442 bool Done() { return current_ == NULL; }
443 void Advance();
444
445 HValue* value() {
446 ASSERT(!Done());
447 return value_;
448 }
449
450 int index() {
451 ASSERT(!Done());
452 return index_;
453 }
454
455 private:
456 explicit HUseIterator(HUseListNode* head);
457
458 HUseListNode* current_;
459 HUseListNode* next_;
460 HValue* value_;
461 int index_;
462
463 friend class HValue;
464};
465
466
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000467class HValue: public ZoneObject {
468 public:
469 static const int kNoNumber = -1;
470
471 // There must be one corresponding kDepends flag for every kChanges flag and
472 // the order of the kChanges flags must be exactly the same as of the kDepends
473 // flags.
474 enum Flag {
475 // Declare global value numbering flags.
476 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
477 GVN_FLAG_LIST(DECLARE_DO)
478 #undef DECLARE_DO
479 kFlexibleRepresentation,
480 kUseGVN,
481 kCanOverflow,
482 kBailoutOnMinusZero,
483 kCanBeDivByZero,
484 kIsArguments,
485 kTruncatingToInt32,
486 kLastFlag = kTruncatingToInt32
487 };
488
489 STATIC_ASSERT(kLastFlag < kBitsPerInt);
490
491 static const int kChangesToDependsFlagsLeftShift = 1;
492
493 static int ChangesFlagsMask() {
494 int result = 0;
495 // Create changes mask.
496#define DECLARE_DO(type) result |= (1 << kChanges##type);
497 GVN_FLAG_LIST(DECLARE_DO)
498#undef DECLARE_DO
499 return result;
500 }
501
502 static int DependsFlagsMask() {
503 return ConvertChangesToDependsFlags(ChangesFlagsMask());
504 }
505
506 static int ConvertChangesToDependsFlags(int flags) {
507 return flags << kChangesToDependsFlagsLeftShift;
508 }
509
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000510 static HValue* cast(HValue* value) { return value; }
511
512 enum Opcode {
513 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000514 #define DECLARE_OPCODE(type) k##type,
515 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
516 kPhi
517 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000518 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000519 virtual Opcode opcode() const = 0;
520
521 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
522 #define DECLARE_PREDICATE(type) \
523 bool Is##type() const { return opcode() == k##type; }
524 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
525 #undef DECLARE_PREDICATE
526 bool IsPhi() const { return opcode() == kPhi; }
527
528 // Declare virtual predicates for abstract HInstruction or HValue
529 #define DECLARE_PREDICATE(type) \
530 virtual bool Is##type() const { return false; }
531 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
532 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533
534 HValue() : block_(NULL),
535 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000536 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000537 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000538 range_(NULL),
539 flags_(0) {}
540 virtual ~HValue() {}
541
542 HBasicBlock* block() const { return block_; }
543 void SetBlock(HBasicBlock* block);
544
545 int id() const { return id_; }
546 void set_id(int id) { id_ = id; }
547
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000548 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000549
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000550 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551 Representation representation() const { return representation_; }
552 void ChangeRepresentation(Representation r) {
553 // Representation was already set and is allowed to be changed.
554 ASSERT(!representation_.IsNone());
555 ASSERT(!r.IsNone());
556 ASSERT(CheckFlag(kFlexibleRepresentation));
557 RepresentationChanged(r);
558 representation_ = r;
559 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000560 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000561
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000562 virtual bool IsConvertibleToInteger() const { return true; }
563
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564 HType type() const { return type_; }
565 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000566 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000567 type_ = type;
568 }
569
570 // An operation needs to override this function iff:
571 // 1) it can produce an int32 output.
572 // 2) the true value of its output can potentially be minus zero.
573 // The implementation must set a flag so that it bails out in the case where
574 // it would otherwise output what should be a minus zero as an int32 zero.
575 // If the operation also exists in a form that takes int32 and outputs int32
576 // then the operation should return its input value so that we can propagate
577 // back. There are two operations that need to propagate back to more than
578 // one input. They are phi and binary add. They always return NULL and
579 // expect the caller to take care of things.
580 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
581 visited->Add(id());
582 return NULL;
583 }
584
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000585 bool IsDefinedAfter(HBasicBlock* other) const;
586
587 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000588 virtual int OperandCount() = 0;
589 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000590 void SetOperandAt(int index, HValue* value);
591
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000592 void DeleteAndReplaceWith(HValue* other);
593 bool HasNoUses() const { return use_list_ == NULL; }
594 bool HasMultipleUses() const {
595 return use_list_ != NULL && use_list_->tail() != NULL;
596 }
597 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000598 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599
600 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000601 void SetFlag(Flag f) { flags_ |= (1 << f); }
602 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
603 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
604
605 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
606 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
607 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000608
609 Range* range() const { return range_; }
610 bool HasRange() const { return range_ != NULL; }
611 void AddNewRange(Range* r);
612 void RemoveLastAddedRange();
613 void ComputeInitialRange();
614
615 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000616 virtual Representation RequiredInputRepresentation(int index) const = 0;
617
618 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000619 return representation();
620 }
621
622 // This gives the instruction an opportunity to replace itself with an
623 // instruction that does the same in some better way. To replace an
624 // instruction with a new one, first add the new instruction to the graph,
625 // then return it. Return NULL to have the instruction deleted.
626 virtual HValue* Canonicalize() { return this; }
627
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000628 bool Equals(HValue* other);
629 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000630
631 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000632 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000633 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000634 void PrintTypeTo(StringStream* stream);
635 void PrintRangeTo(StringStream* stream);
636 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000637
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000638 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000639
640 // Updated the inferred type of this instruction and returns true if
641 // it has changed.
642 bool UpdateInferredType();
643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000644 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000646#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000647 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648#endif
649
650 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000651 // This function must be overridden for instructions with flag kUseGVN, to
652 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000653 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000654 UNREACHABLE();
655 return false;
656 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000657 virtual void RepresentationChanged(Representation to) { }
658 virtual Range* InferRange();
659 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000660 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000661 void clear_block() {
662 ASSERT(block_ != NULL);
663 block_ = NULL;
664 }
665
666 void set_representation(Representation r) {
667 // Representation is set-once.
668 ASSERT(representation_.IsNone() && !r.IsNone());
669 representation_ = r;
670 }
671
672 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000673 // A flag mask to mark an instruction as having arbitrary side effects.
674 static int AllSideEffects() {
675 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
676 }
677
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000678 // Remove the matching use from the use list if present. Returns the
679 // removed list node or NULL.
680 HUseListNode* RemoveUse(HValue* value, int index);
681
682 void ReplaceAllUsesWith(HValue* other);
683
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684 void RegisterUse(int index, HValue* new_value);
685
686 HBasicBlock* block_;
687
688 // The id of this instruction in the hydrogen graph, assigned when first
689 // added to the graph. Reflects creation order.
690 int id_;
691
692 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000693 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000694 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000695 Range* range_;
696 int flags_;
697
698 DISALLOW_COPY_AND_ASSIGN(HValue);
699};
700
701
702class HInstruction: public HValue {
703 public:
704 HInstruction* next() const { return next_; }
705 HInstruction* previous() const { return previous_; }
706
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000707 virtual void PrintTo(StringStream* stream);
708 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000709
710 bool IsLinked() const { return block() != NULL; }
711 void Unlink();
712 void InsertBefore(HInstruction* next);
713 void InsertAfter(HInstruction* previous);
714
715 int position() const { return position_; }
716 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
717 void set_position(int position) { position_ = position; }
718
719 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
720
721#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000722 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000723#endif
724
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000725 // Returns whether this is some kind of deoptimizing check
726 // instruction.
727 virtual bool IsCheckInstruction() const { return false; }
728
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000729 virtual bool IsCall() { return false; }
730
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000731 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000732
733 protected:
734 HInstruction()
735 : next_(NULL),
736 previous_(NULL),
737 position_(RelocInfo::kNoPosition) {
738 SetFlag(kDependsOnOsrEntries);
739 }
740
741 virtual void DeleteFromGraph() { Unlink(); }
742
743 private:
744 void InitializeAsFirst(HBasicBlock* block) {
745 ASSERT(!IsLinked());
746 SetBlock(block);
747 }
748
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000749 void PrintMnemonicTo(StringStream* stream);
750
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000751 HInstruction* next_;
752 HInstruction* previous_;
753 int position_;
754
755 friend class HBasicBlock;
756};
757
758
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000759class HControlInstruction: public HInstruction {
760 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000761 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
762 : first_successor_(first), second_successor_(second) {
763 }
764
765 HBasicBlock* FirstSuccessor() const { return first_successor_; }
766 HBasicBlock* SecondSuccessor() const { return second_successor_; }
767
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000768 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000769
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000770 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000771
772 private:
773 HBasicBlock* first_successor_;
774 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000775};
776
777
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000778template<int NumElements>
779class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000780 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000781 HOperandContainer() : elems_() { }
782
783 int length() { return NumElements; }
784 HValue*& operator[](int i) {
785 ASSERT(i < length());
786 return elems_[i];
787 }
788
789 private:
790 HValue* elems_[NumElements];
791};
792
793
794template<>
795class HOperandContainer<0> {
796 public:
797 int length() { return 0; }
798 HValue*& operator[](int i) {
799 UNREACHABLE();
800 static HValue* t = 0;
801 return t;
802 }
803};
804
805
806template<int V>
807class HTemplateInstruction : public HInstruction {
808 public:
809 int OperandCount() { return V; }
810 HValue* OperandAt(int i) { return inputs_[i]; }
811
812 protected:
813 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
814
815 private:
816 HOperandContainer<V> inputs_;
817};
818
819
820template<int V>
821class HTemplateControlInstruction : public HControlInstruction {
822 public:
823 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
824 : HControlInstruction(first, second) { }
825 int OperandCount() { return V; }
826 HValue* OperandAt(int i) { return inputs_[i]; }
827
828 protected:
829 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
830
831 private:
832 HOperandContainer<V> inputs_;
833};
834
835
836class HBlockEntry: public HTemplateInstruction<0> {
837 public:
838 virtual Representation RequiredInputRepresentation(int index) const {
839 return Representation::None();
840 }
841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000842 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000843};
844
845
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000846class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000847 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000848 explicit HDeoptimize(int environment_length)
849 : HControlInstruction(NULL, NULL),
850 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000851
852 virtual Representation RequiredInputRepresentation(int index) const {
853 return Representation::None();
854 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000855
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000856 virtual int OperandCount() { return values_.length(); }
857 virtual HValue* OperandAt(int index) { return values_[index]; }
858
859 void AddEnvironmentValue(HValue* value) {
860 values_.Add(NULL);
861 SetOperandAt(values_.length() - 1, value);
862 }
863
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000864 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000865
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000866 enum UseEnvironment {
867 kNoUses,
868 kUseAll
869 };
870
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000871 protected:
872 virtual void InternalSetOperandAt(int index, HValue* value) {
873 values_[index] = value;
874 }
875
876 private:
877 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000878};
879
880
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000881class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000882 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000883 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000884 : HTemplateControlInstruction<0>(target, NULL),
885 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000886
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887 void set_include_stack_check(bool include_stack_check) {
888 include_stack_check_ = include_stack_check;
889 }
890 bool include_stack_check() const { return include_stack_check_; }
891
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000892 virtual Representation RequiredInputRepresentation(int index) const {
893 return Representation::None();
894 }
895
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000896 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000897
898 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899 bool include_stack_check_;
900};
901
902
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000903class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000904 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000905 explicit HUnaryControlInstruction(HValue* value,
906 HBasicBlock* true_target,
907 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000908 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909 SetOperandAt(0, value);
910 }
911
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000912 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000914 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915};
916
917
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000918class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000920 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
921 : HUnaryControlInstruction(value, true_target, false_target) {
922 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 }
924
925 virtual Representation RequiredInputRepresentation(int index) const {
926 return Representation::None();
927 }
928
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000929 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930};
931
932
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000933class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000935 HCompareMap(HValue* value,
936 Handle<Map> map,
937 HBasicBlock* true_target,
938 HBasicBlock* false_target)
939 : HUnaryControlInstruction(value, true_target, false_target),
940 map_(map) {
941 ASSERT(true_target != NULL);
942 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943 ASSERT(!map.is_null());
944 }
945
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000946 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000947
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000948 Handle<Map> map() const { return map_; }
949
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000950 virtual Representation RequiredInputRepresentation(int index) const {
951 return Representation::Tagged();
952 }
953
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000954 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000955
956 private:
957 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958};
959
960
961class HReturn: public HUnaryControlInstruction {
962 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000963 explicit HReturn(HValue* value)
964 : HUnaryControlInstruction(value, NULL, NULL) {
965 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000967 virtual Representation RequiredInputRepresentation(int index) const {
968 return Representation::Tagged();
969 }
970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000971 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000972};
973
974
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000975class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000977 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
978
979 virtual Representation RequiredInputRepresentation(int index) const {
980 return Representation::None();
981 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000982
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000983 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000984};
985
986
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000987class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000988 public:
989 explicit HUnaryOperation(HValue* value) {
990 SetOperandAt(0, value);
991 }
992
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000993 HValue* value() { return OperandAt(0); }
994 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000995};
996
997
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000998class HThrow: public HUnaryOperation {
999 public:
1000 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1001 SetAllSideEffects();
1002 }
1003
1004 virtual Representation RequiredInputRepresentation(int index) const {
1005 return Representation::Tagged();
1006 }
1007
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001008 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001009};
1010
1011
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001012class HChange: public HUnaryOperation {
1013 public:
1014 HChange(HValue* value,
1015 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001016 Representation to,
1017 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001018 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001019 ASSERT(!from.IsNone() && !to.IsNone());
1020 ASSERT(!from.Equals(to));
1021 set_representation(to);
1022 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001023 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001024 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1025 value->range()->IsInSmiRange()) {
1026 set_type(HType::Smi());
1027 }
1028 }
1029
1030 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1031
1032 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001033 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001034 virtual Representation RequiredInputRepresentation(int index) const {
1035 return from_;
1036 }
1037
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001038 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001040 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001041
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001042 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001043
1044 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001045 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001046 if (!other->IsChange()) return false;
1047 HChange* change = HChange::cast(other);
1048 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001049 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001050 }
1051
1052 private:
1053 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001054};
1055
1056
1057class HSimulate: public HInstruction {
1058 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001059 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001060 : ast_id_(ast_id),
1061 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001062 values_(2),
1063 assigned_indexes_(2) {}
1064 virtual ~HSimulate() {}
1065
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001066 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001067
1068 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1069 int ast_id() const { return ast_id_; }
1070 void set_ast_id(int id) {
1071 ASSERT(!HasAstId());
1072 ast_id_ = id;
1073 }
1074
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001075 int pop_count() const { return pop_count_; }
1076 const ZoneList<HValue*>* values() const { return &values_; }
1077 int GetAssignedIndexAt(int index) const {
1078 ASSERT(HasAssignedIndexAt(index));
1079 return assigned_indexes_[index];
1080 }
1081 bool HasAssignedIndexAt(int index) const {
1082 return assigned_indexes_[index] != kNoIndex;
1083 }
1084 void AddAssignedValue(int index, HValue* value) {
1085 AddValue(index, value);
1086 }
1087 void AddPushedValue(HValue* value) {
1088 AddValue(kNoIndex, value);
1089 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001090 virtual int OperandCount() { return values_.length(); }
1091 virtual HValue* OperandAt(int index) { return values_[index]; }
1092
1093 virtual Representation RequiredInputRepresentation(int index) const {
1094 return Representation::None();
1095 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001096
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001097 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001098
1099#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001100 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001101#endif
1102
1103 protected:
1104 virtual void InternalSetOperandAt(int index, HValue* value) {
1105 values_[index] = value;
1106 }
1107
1108 private:
1109 static const int kNoIndex = -1;
1110 void AddValue(int index, HValue* value) {
1111 assigned_indexes_.Add(index);
1112 // Resize the list of pushed values.
1113 values_.Add(NULL);
1114 // Set the operand through the base method in HValue to make sure that the
1115 // use lists are correctly updated.
1116 SetOperandAt(values_.length() - 1, value);
1117 }
1118 int ast_id_;
1119 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001120 ZoneList<HValue*> values_;
1121 ZoneList<int> assigned_indexes_;
1122};
1123
1124
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001125class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126 public:
1127 HStackCheck() { }
1128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001129 virtual Representation RequiredInputRepresentation(int index) const {
1130 return Representation::None();
1131 }
1132
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001133 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001134};
1135
1136
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001137class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001138 public:
1139 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1140 : closure_(closure), function_(function) {
1141 }
1142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001143 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001144
1145 Handle<JSFunction> closure() const { return closure_; }
1146 FunctionLiteral* function() const { return function_; }
1147
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001148 virtual Representation RequiredInputRepresentation(int index) const {
1149 return Representation::None();
1150 }
1151
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001152 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001153
1154 private:
1155 Handle<JSFunction> closure_;
1156 FunctionLiteral* function_;
1157};
1158
1159
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001160class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001161 public:
1162 HLeaveInlined() {}
1163
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001164 virtual Representation RequiredInputRepresentation(int index) const {
1165 return Representation::None();
1166 }
1167
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001168 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169};
1170
1171
1172class HPushArgument: public HUnaryOperation {
1173 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001174 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1175 set_representation(Representation::Tagged());
1176 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001177
1178 virtual Representation RequiredInputRepresentation(int index) const {
1179 return Representation::Tagged();
1180 }
1181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001182 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001183
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001184 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001185};
1186
1187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001188class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001189 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001190 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001191 set_representation(Representation::Tagged());
1192 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001193 }
1194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001195 virtual Representation RequiredInputRepresentation(int index) const {
1196 return Representation::None();
1197 }
1198
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001199 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001200
1201 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001202 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001203};
1204
1205
1206class HOuterContext: public HUnaryOperation {
1207 public:
1208 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1209 set_representation(Representation::Tagged());
1210 SetFlag(kUseGVN);
1211 }
1212
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001213 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001214
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001215 virtual Representation RequiredInputRepresentation(int index) const {
1216 return Representation::Tagged();
1217 }
1218
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001219 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001220 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001221};
1222
1223
1224class HGlobalObject: public HUnaryOperation {
1225 public:
1226 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1227 set_representation(Representation::Tagged());
1228 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001229 }
1230
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001231 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001232
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001233 virtual Representation RequiredInputRepresentation(int index) const {
1234 return Representation::Tagged();
1235 }
1236
ager@chromium.org378b34e2011-01-28 08:04:38 +00001237 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001238 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001239};
1240
1241
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001242class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001243 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001244 explicit HGlobalReceiver(HValue* global_object)
1245 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001246 set_representation(Representation::Tagged());
1247 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001248 }
1249
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001250 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001252 virtual Representation RequiredInputRepresentation(int index) const {
1253 return Representation::Tagged();
1254 }
1255
ager@chromium.org378b34e2011-01-28 08:04:38 +00001256 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001257 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001258};
1259
1260
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001261template <int V>
1262class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001264 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001265 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1266 this->set_representation(Representation::Tagged());
1267 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001268 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001270 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001271
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001272 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001274 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001276 private:
1277 int argument_count_;
1278};
1279
1280
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001281class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001282 public:
1283 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001284 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001285 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001286 }
1287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001288 virtual Representation RequiredInputRepresentation(int index) const {
1289 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001290 }
1291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001292 virtual void PrintDataTo(StringStream* stream);
1293
1294 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001295};
1296
1297
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001298class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001299 public:
1300 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001301 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001302 SetOperandAt(0, first);
1303 SetOperandAt(1, second);
1304 }
1305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001306 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001308 virtual Representation RequiredInputRepresentation(int index) const {
1309 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001310 }
1311
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001312 HValue* first() { return OperandAt(0); }
1313 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314};
1315
1316
danno@chromium.org160a7b02011-04-18 15:51:38 +00001317class HInvokeFunction: public HBinaryCall {
1318 public:
1319 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1320 : HBinaryCall(context, function, argument_count) {
1321 }
1322
1323 virtual Representation RequiredInputRepresentation(int index) const {
1324 return Representation::Tagged();
1325 }
1326
1327 HValue* context() { return first(); }
1328 HValue* function() { return second(); }
1329
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001330 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001331};
1332
1333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001334class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335 public:
1336 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001337 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001338
1339 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001340
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001341 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001342 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001343 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001344 }
1345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001346 virtual void PrintDataTo(StringStream* stream);
1347
1348 virtual Representation RequiredInputRepresentation(int index) const {
1349 return Representation::None();
1350 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001351
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001352 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001353
1354 private:
1355 Handle<JSFunction> function_;
1356};
1357
1358
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001359class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001360 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001361 HCallKeyed(HValue* context, HValue* key, int argument_count)
1362 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001363 }
1364
1365 virtual Representation RequiredInputRepresentation(int index) const {
1366 return Representation::Tagged();
1367 }
1368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001369 HValue* context() { return first(); }
1370 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001371
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001372 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373};
1374
1375
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001376class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001378 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1379 : HUnaryCall(context, argument_count), name_(name) {
1380 }
1381
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001382 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001384 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001385 Handle<String> name() const { return name_; }
1386
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001387 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001388
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001389 virtual Representation RequiredInputRepresentation(int index) const {
1390 return Representation::Tagged();
1391 }
1392
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001393 private:
1394 Handle<String> name_;
1395};
1396
1397
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001398class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001399 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001400 HCallFunction(HValue* context, int argument_count)
1401 : HUnaryCall(context, argument_count) {
1402 }
1403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404 HValue* context() { return value(); }
1405
1406 virtual Representation RequiredInputRepresentation(int index) const {
1407 return Representation::Tagged();
1408 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001410 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411};
1412
1413
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001414class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001416 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1417 : HUnaryCall(context, argument_count), name_(name) {
1418 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001420 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001422 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 Handle<String> name() const { return name_; }
1424
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001425 virtual Representation RequiredInputRepresentation(int index) const {
1426 return Representation::Tagged();
1427 }
1428
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001429 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430
1431 private:
1432 Handle<String> name_;
1433};
1434
1435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001436class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001437 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001438 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001440
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001442
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001443 Handle<JSFunction> target() const { return target_; }
1444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445 virtual Representation RequiredInputRepresentation(int index) const {
1446 return Representation::None();
1447 }
1448
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001449 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450
1451 private:
1452 Handle<JSFunction> target_;
1453};
1454
1455
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001456class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001457 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001458 HCallNew(HValue* context, HValue* constructor, int argument_count)
1459 : HBinaryCall(context, constructor, argument_count) {
1460 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001461
1462 virtual Representation RequiredInputRepresentation(int index) const {
1463 return Representation::Tagged();
1464 }
1465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 HValue* context() { return first(); }
1467 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001468
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001469 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001470};
1471
1472
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001473class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001474 public:
1475 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001476 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001478 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1479 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001480
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001481 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001482 Handle<String> name() const { return name_; }
1483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001484 virtual Representation RequiredInputRepresentation(int index) const {
1485 return Representation::None();
1486 }
1487
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001488 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001489
1490 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001491 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492 Handle<String> name_;
1493};
1494
1495
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001496class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001497 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001498 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001499 // The length of an array is stored as a tagged value in the array
1500 // object. It is guaranteed to be 32 bit integer, but it can be
1501 // represented as either a smi or heap number.
1502 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001503 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001504 SetFlag(kDependsOnArrayLengths);
1505 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001506 }
1507
1508 virtual Representation RequiredInputRepresentation(int index) const {
1509 return Representation::Tagged();
1510 }
1511
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001512 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001513
1514 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001515 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001516};
1517
1518
1519class HFixedArrayLength: public HUnaryOperation {
1520 public:
1521 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1522 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001523 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001524 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001525 }
1526
1527 virtual Representation RequiredInputRepresentation(int index) const {
1528 return Representation::Tagged();
1529 }
1530
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001531 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001532
1533 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001534 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001535};
1536
1537
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001538class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001539 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001540 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001541 set_representation(Representation::Integer32());
1542 // The result of this instruction is idempotent as long as its inputs don't
1543 // change. The length of a pixel array cannot change once set, so it's not
1544 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1545 SetFlag(kUseGVN);
1546 }
1547
1548 virtual Representation RequiredInputRepresentation(int index) const {
1549 return Representation::Tagged();
1550 }
1551
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001552 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001553
1554 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001555 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001556};
1557
1558
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559class HBitNot: public HUnaryOperation {
1560 public:
1561 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1562 set_representation(Representation::Integer32());
1563 SetFlag(kUseGVN);
1564 SetFlag(kTruncatingToInt32);
1565 }
1566
1567 virtual Representation RequiredInputRepresentation(int index) const {
1568 return Representation::Integer32();
1569 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001570 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001571
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001572 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001573
1574 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001575 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576};
1577
1578
1579class HUnaryMathOperation: public HUnaryOperation {
1580 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001581 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001582 : HUnaryOperation(value), op_(op) {
1583 switch (op) {
1584 case kMathFloor:
1585 case kMathRound:
1586 case kMathCeil:
1587 set_representation(Representation::Integer32());
1588 break;
1589 case kMathAbs:
1590 set_representation(Representation::Tagged());
1591 SetFlag(kFlexibleRepresentation);
1592 break;
1593 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001594 case kMathPowHalf:
1595 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001596 case kMathSin:
1597 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001598 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001599 break;
1600 default:
1601 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001602 }
1603 SetFlag(kUseGVN);
1604 }
1605
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001606 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001608 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001609
1610 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1611
1612 virtual Representation RequiredInputRepresentation(int index) const {
1613 switch (op_) {
1614 case kMathFloor:
1615 case kMathRound:
1616 case kMathCeil:
1617 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001618 case kMathPowHalf:
1619 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001620 case kMathSin:
1621 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001622 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001623 case kMathAbs:
1624 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001626 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001627 return Representation::None();
1628 }
1629 }
1630
1631 virtual HValue* Canonicalize() {
1632 // If the input is integer32 then we replace the floor instruction
1633 // with its inputs. This happens before the representation changes are
1634 // introduced.
1635 if (op() == kMathFloor) {
1636 if (value()->representation().IsInteger32()) return value();
1637 }
1638 return this;
1639 }
1640
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001641 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001642 const char* OpName() const;
1643
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001644 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001645
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001646 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001647 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001648 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1649 return op_ == b->op();
1650 }
1651
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001653 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654};
1655
1656
1657class HLoadElements: public HUnaryOperation {
1658 public:
1659 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1660 set_representation(Representation::Tagged());
1661 SetFlag(kUseGVN);
1662 SetFlag(kDependsOnMaps);
1663 }
1664
1665 virtual Representation RequiredInputRepresentation(int index) const {
1666 return Representation::Tagged();
1667 }
1668
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001669 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001670
1671 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001672 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001673};
1674
1675
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001676class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001677 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001678 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001679 : HUnaryOperation(value) {
1680 set_representation(Representation::External());
1681 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001682 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001683 // change once set, so it's no necessary to introduce any additional
1684 // dependencies on top of the inputs.
1685 SetFlag(kUseGVN);
1686 }
1687
1688 virtual Representation RequiredInputRepresentation(int index) const {
1689 return Representation::Tagged();
1690 }
1691
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001692 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001693
1694 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001695 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001696};
1697
1698
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001699class HCheckMap: public HUnaryOperation {
1700 public:
1701 HCheckMap(HValue* value, Handle<Map> map)
1702 : HUnaryOperation(value), map_(map) {
1703 set_representation(Representation::Tagged());
1704 SetFlag(kUseGVN);
1705 SetFlag(kDependsOnMaps);
1706 }
1707
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001708 virtual bool IsCheckInstruction() const { return true; }
1709
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710 virtual Representation RequiredInputRepresentation(int index) const {
1711 return Representation::Tagged();
1712 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001713 virtual void PrintDataTo(StringStream* stream);
1714 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001715
1716#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001717 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001718#endif
1719
1720 Handle<Map> map() const { return map_; }
1721
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001722 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001723
1724 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001725 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001726 HCheckMap* b = HCheckMap::cast(other);
1727 return map_.is_identical_to(b->map());
1728 }
1729
1730 private:
1731 Handle<Map> map_;
1732};
1733
1734
1735class HCheckFunction: public HUnaryOperation {
1736 public:
1737 HCheckFunction(HValue* value, Handle<JSFunction> function)
1738 : HUnaryOperation(value), target_(function) {
1739 set_representation(Representation::Tagged());
1740 SetFlag(kUseGVN);
1741 }
1742
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001743 virtual bool IsCheckInstruction() const { return true; }
1744
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745 virtual Representation RequiredInputRepresentation(int index) const {
1746 return Representation::Tagged();
1747 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001748 virtual void PrintDataTo(StringStream* stream);
1749 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001750
1751#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001752 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001753#endif
1754
1755 Handle<JSFunction> target() const { return target_; }
1756
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001757 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758
1759 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001760 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761 HCheckFunction* b = HCheckFunction::cast(other);
1762 return target_.is_identical_to(b->target());
1763 }
1764
1765 private:
1766 Handle<JSFunction> target_;
1767};
1768
1769
1770class HCheckInstanceType: public HUnaryOperation {
1771 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001772 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) {
1773 return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION);
1774 }
1775 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1776 return new HCheckInstanceType(value, IS_JS_ARRAY);
1777 }
1778 static HCheckInstanceType* NewIsString(HValue* value) {
1779 return new HCheckInstanceType(value, IS_STRING);
1780 }
1781 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1782 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001783 }
1784
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001785 virtual bool IsCheckInstruction() const { return true; }
1786
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787 virtual Representation RequiredInputRepresentation(int index) const {
1788 return Representation::Tagged();
1789 }
1790
1791#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001792 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793#endif
1794
danno@chromium.org160a7b02011-04-18 15:51:38 +00001795 virtual HValue* Canonicalize() {
1796 if (!value()->type().IsUninitialized() &&
1797 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001798 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001799 return NULL;
1800 }
1801 return this;
1802 }
1803
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001804 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1805 void GetCheckInterval(InstanceType* first, InstanceType* last);
1806 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001807
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001808 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809
1810 protected:
1811 // TODO(ager): It could be nice to allow the ommision of instance
1812 // type checks if we have already performed an instance type check
1813 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001814 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001815 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001816 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817 }
1818
1819 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001820 enum Check {
1821 IS_JS_OBJECT_OR_JS_FUNCTION,
1822 IS_JS_ARRAY,
1823 IS_STRING,
1824 IS_SYMBOL,
1825 LAST_INTERVAL_CHECK = IS_JS_ARRAY
1826 };
1827
1828 HCheckInstanceType(HValue* value, Check check)
1829 : HUnaryOperation(value), check_(check) {
1830 set_representation(Representation::Tagged());
1831 SetFlag(kUseGVN);
1832 }
1833
1834 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001835};
1836
1837
1838class HCheckNonSmi: public HUnaryOperation {
1839 public:
1840 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1841 set_representation(Representation::Tagged());
1842 SetFlag(kUseGVN);
1843 }
1844
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001845 virtual bool IsCheckInstruction() const { return true; }
1846
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001847 virtual Representation RequiredInputRepresentation(int index) const {
1848 return Representation::Tagged();
1849 }
1850
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001851 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001852
1853#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001854 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001855#endif
1856
danno@chromium.org160a7b02011-04-18 15:51:38 +00001857 virtual HValue* Canonicalize() {
1858 HType value_type = value()->type();
1859 if (!value_type.IsUninitialized() &&
1860 (value_type.IsHeapNumber() ||
1861 value_type.IsString() ||
1862 value_type.IsBoolean() ||
1863 value_type.IsNonPrimitive())) {
1864 return NULL;
1865 }
1866 return this;
1867 }
1868
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001869 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001870
1871 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001872 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001873};
1874
1875
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001876class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001877 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001878 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1879 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001880 SetFlag(kUseGVN);
1881 SetFlag(kDependsOnMaps);
1882 }
1883
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001884 virtual bool IsCheckInstruction() const { return true; }
1885
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001886#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001887 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001888#endif
1889
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001890 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001891 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001892
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001893 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001894
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001895 virtual Representation RequiredInputRepresentation(int index) const {
1896 return Representation::None();
1897 }
1898
1899 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001900 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001901 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1902 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1903 return hash;
1904 }
1905
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001906 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001907 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001908 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001909 return prototype_.is_identical_to(b->prototype()) &&
1910 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911 }
1912
1913 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001914 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001915 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916};
1917
1918
1919class HCheckSmi: public HUnaryOperation {
1920 public:
1921 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1922 set_representation(Representation::Tagged());
1923 SetFlag(kUseGVN);
1924 }
1925
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001926 virtual bool IsCheckInstruction() const { return true; }
1927
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001928 virtual Representation RequiredInputRepresentation(int index) const {
1929 return Representation::Tagged();
1930 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001931 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001932
1933#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001934 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001935#endif
1936
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001937 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001938
1939 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001940 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001941};
1942
1943
1944class HPhi: public HValue {
1945 public:
1946 explicit HPhi(int merged_index)
1947 : inputs_(2),
1948 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001949 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001950 is_live_(false),
1951 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1953 non_phi_uses_[i] = 0;
1954 indirect_uses_[i] = 0;
1955 }
1956 ASSERT(merged_index >= 0);
1957 set_representation(Representation::Tagged());
1958 SetFlag(kFlexibleRepresentation);
1959 }
1960
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001961 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001962 bool double_occurred = false;
1963 bool int32_occurred = false;
1964 for (int i = 0; i < OperandCount(); ++i) {
1965 HValue* value = OperandAt(i);
1966 if (value->representation().IsDouble()) double_occurred = true;
1967 if (value->representation().IsInteger32()) int32_occurred = true;
1968 if (value->representation().IsTagged()) return Representation::Tagged();
1969 }
1970
1971 if (double_occurred) return Representation::Double();
1972 if (int32_occurred) return Representation::Integer32();
1973 return Representation::None();
1974 }
1975
1976 virtual Range* InferRange();
1977 virtual Representation RequiredInputRepresentation(int index) const {
1978 return representation();
1979 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001980 virtual HType CalculateInferredType();
1981 virtual int OperandCount() { return inputs_.length(); }
1982 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1983 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001984 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001985 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001986
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001987 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001988
1989 int merged_index() const { return merged_index_; }
1990
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001991 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001992
1993#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001994 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995#endif
1996
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997 void InitRealUses(int id);
1998 void AddNonPhiUsesFrom(HPhi* other);
1999 void AddIndirectUsesTo(int* use_count);
2000
2001 int tagged_non_phi_uses() const {
2002 return non_phi_uses_[Representation::kTagged];
2003 }
2004 int int32_non_phi_uses() const {
2005 return non_phi_uses_[Representation::kInteger32];
2006 }
2007 int double_non_phi_uses() const {
2008 return non_phi_uses_[Representation::kDouble];
2009 }
2010 int tagged_indirect_uses() const {
2011 return indirect_uses_[Representation::kTagged];
2012 }
2013 int int32_indirect_uses() const {
2014 return indirect_uses_[Representation::kInteger32];
2015 }
2016 int double_indirect_uses() const {
2017 return indirect_uses_[Representation::kDouble];
2018 }
2019 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002020 bool is_live() { return is_live_; }
2021 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002022
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002023 static HPhi* cast(HValue* value) {
2024 ASSERT(value->IsPhi());
2025 return reinterpret_cast<HPhi*>(value);
2026 }
2027 virtual Opcode opcode() const { return HValue::kPhi; }
2028
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002029 virtual bool IsConvertibleToInteger() const {
2030 return is_convertible_to_integer_;
2031 }
2032
2033 void set_is_convertible_to_integer(bool b) {
2034 is_convertible_to_integer_ = b;
2035 }
2036
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002037 protected:
2038 virtual void DeleteFromGraph();
2039 virtual void InternalSetOperandAt(int index, HValue* value) {
2040 inputs_[index] = value;
2041 }
2042
2043 private:
2044 ZoneList<HValue*> inputs_;
2045 int merged_index_;
2046
2047 int non_phi_uses_[Representation::kNumRepresentations];
2048 int indirect_uses_[Representation::kNumRepresentations];
2049 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002050 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002051 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052};
2053
2054
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002055class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056 public:
2057 HArgumentsObject() {
2058 set_representation(Representation::Tagged());
2059 SetFlag(kIsArguments);
2060 }
2061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002062 virtual Representation RequiredInputRepresentation(int index) const {
2063 return Representation::None();
2064 }
2065
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002066 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002067};
2068
2069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071 public:
2072 HConstant(Handle<Object> handle, Representation r);
2073
2074 Handle<Object> handle() const { return handle_; }
2075
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002076 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002077
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002078 virtual Representation RequiredInputRepresentation(int index) const {
2079 return Representation::None();
2080 }
2081
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002082 virtual bool IsConvertibleToInteger() const {
2083 if (handle_->IsSmi()) return true;
2084 if (handle_->IsHeapNumber() &&
2085 (HeapNumber::cast(*handle_)->value() ==
2086 static_cast<double>(NumberToInt32(*handle_)))) return true;
2087 return false;
2088 }
2089
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002090 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002091 virtual void PrintDataTo(StringStream* stream);
2092 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002093 bool IsInteger() const { return handle_->IsSmi(); }
2094 HConstant* CopyToRepresentation(Representation r) const;
2095 HConstant* CopyToTruncatedInt32() const;
2096 bool HasInteger32Value() const { return has_int32_value_; }
2097 int32_t Integer32Value() const {
2098 ASSERT(HasInteger32Value());
2099 return int32_value_;
2100 }
2101 bool HasDoubleValue() const { return has_double_value_; }
2102 double DoubleValue() const {
2103 ASSERT(HasDoubleValue());
2104 return double_value_;
2105 }
2106 bool HasStringValue() const { return handle_->IsString(); }
2107
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002108 bool ToBoolean() const;
2109
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002110 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002111 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002112 return reinterpret_cast<intptr_t>(*handle());
2113 }
2114
2115#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002116 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117#endif
2118
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002119 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002120
2121 protected:
2122 virtual Range* InferRange();
2123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002124 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002125 HConstant* other_constant = HConstant::cast(other);
2126 return handle().is_identical_to(other_constant->handle());
2127 }
2128
2129 private:
2130 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002131
2132 // The following two values represent the int32 and the double value of the
2133 // given constant if there is a lossless conversion between the constant
2134 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002135 bool has_int32_value_ : 1;
2136 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002137 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002138 double double_value_;
2139};
2140
2141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002142class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002143 public:
2144 HBinaryOperation(HValue* left, HValue* right) {
2145 ASSERT(left != NULL && right != NULL);
2146 SetOperandAt(0, left);
2147 SetOperandAt(1, right);
2148 }
2149
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002150 HValue* left() { return OperandAt(0); }
2151 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002152
2153 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2154 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002155 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156 if (IsCommutative() && left()->IsConstant()) return right();
2157 return left();
2158 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002159 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160 if (IsCommutative() && left()->IsConstant()) return left();
2161 return right();
2162 }
2163
2164 virtual bool IsCommutative() const { return false; }
2165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002166 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167};
2168
2169
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002170class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002171 public:
2172 HApplyArguments(HValue* function,
2173 HValue* receiver,
2174 HValue* length,
2175 HValue* elements) {
2176 set_representation(Representation::Tagged());
2177 SetOperandAt(0, function);
2178 SetOperandAt(1, receiver);
2179 SetOperandAt(2, length);
2180 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002181 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002182 }
2183
2184 virtual Representation RequiredInputRepresentation(int index) const {
2185 // The length is untagged, all other inputs are tagged.
2186 return (index == 2)
2187 ? Representation::Integer32()
2188 : Representation::Tagged();
2189 }
2190
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002191 HValue* function() { return OperandAt(0); }
2192 HValue* receiver() { return OperandAt(1); }
2193 HValue* length() { return OperandAt(2); }
2194 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002196 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002197};
2198
2199
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002200class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002201 public:
2202 HArgumentsElements() {
2203 // The value produced by this instruction is a pointer into the stack
2204 // that looks as if it was a smi because of alignment.
2205 set_representation(Representation::Tagged());
2206 SetFlag(kUseGVN);
2207 }
2208
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002209 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002211 virtual Representation RequiredInputRepresentation(int index) const {
2212 return Representation::None();
2213 }
2214
ager@chromium.org378b34e2011-01-28 08:04:38 +00002215 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002216 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002217};
2218
2219
2220class HArgumentsLength: public HUnaryOperation {
2221 public:
2222 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2223 set_representation(Representation::Integer32());
2224 SetFlag(kUseGVN);
2225 }
2226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002227 virtual Representation RequiredInputRepresentation(int index) const {
2228 return Representation::Tagged();
2229 }
2230
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002231 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002232
2233 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002234 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235};
2236
2237
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002238class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239 public:
2240 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2241 set_representation(Representation::Tagged());
2242 SetFlag(kUseGVN);
2243 SetOperandAt(0, arguments);
2244 SetOperandAt(1, length);
2245 SetOperandAt(2, index);
2246 }
2247
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002248 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002249
2250 virtual Representation RequiredInputRepresentation(int index) const {
2251 // The arguments elements is considered tagged.
2252 return index == 0
2253 ? Representation::Tagged()
2254 : Representation::Integer32();
2255 }
2256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002257 HValue* arguments() { return OperandAt(0); }
2258 HValue* length() { return OperandAt(1); }
2259 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002260
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002261 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002262
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002263 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002264};
2265
2266
2267class HBoundsCheck: public HBinaryOperation {
2268 public:
2269 HBoundsCheck(HValue* index, HValue* length)
2270 : HBinaryOperation(index, length) {
2271 SetFlag(kUseGVN);
2272 }
2273
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002274 virtual bool IsCheckInstruction() const { return true; }
2275
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276 virtual Representation RequiredInputRepresentation(int index) const {
2277 return Representation::Integer32();
2278 }
2279
2280#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002281 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002282#endif
2283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002284 HValue* index() { return left(); }
2285 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002286
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002287 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002288
2289 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002290 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002291};
2292
2293
2294class HBitwiseBinaryOperation: public HBinaryOperation {
2295 public:
2296 HBitwiseBinaryOperation(HValue* left, HValue* right)
2297 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002298 set_representation(Representation::Tagged());
2299 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002300 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002301 }
2302
2303 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002304 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002305 }
2306
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002307 virtual void RepresentationChanged(Representation to) {
2308 if (!to.IsTagged()) {
2309 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002310 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002311 SetFlag(kTruncatingToInt32);
2312 SetFlag(kUseGVN);
2313 }
2314 }
2315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002316 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002317
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002318 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319};
2320
2321
2322class HArithmeticBinaryOperation: public HBinaryOperation {
2323 public:
2324 HArithmeticBinaryOperation(HValue* left, HValue* right)
2325 : HBinaryOperation(left, right) {
2326 set_representation(Representation::Tagged());
2327 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002328 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002329 }
2330
2331 virtual void RepresentationChanged(Representation to) {
2332 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002333 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002334 SetFlag(kUseGVN);
2335 }
2336 }
2337
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002338 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339 virtual Representation RequiredInputRepresentation(int index) const {
2340 return representation();
2341 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002342 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343 if (left()->representation().Equals(right()->representation())) {
2344 return left()->representation();
2345 }
2346 return HValue::InferredRepresentation();
2347 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002348};
2349
2350
2351class HCompare: public HBinaryOperation {
2352 public:
2353 HCompare(HValue* left, HValue* right, Token::Value token)
2354 : HBinaryOperation(left, right), token_(token) {
2355 ASSERT(Token::IsCompareOp(token));
2356 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002357 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002358 }
2359
2360 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002361
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002362 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002363 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002364 }
2365
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002366 virtual Representation RequiredInputRepresentation(int index) const {
2367 return input_representation_;
2368 }
2369 Representation GetInputRepresentation() const {
2370 return input_representation_;
2371 }
2372 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002375 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002377 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002378 return HValue::Hashcode() * 7 + token_;
2379 }
2380
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002381 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002382
2383 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002384 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002385 HCompare* comp = HCompare::cast(other);
2386 return token_ == comp->token();
2387 }
2388
2389 private:
2390 Representation input_representation_;
2391 Token::Value token_;
2392};
2393
2394
2395class HCompareJSObjectEq: public HBinaryOperation {
2396 public:
2397 HCompareJSObjectEq(HValue* left, HValue* right)
2398 : HBinaryOperation(left, right) {
2399 set_representation(Representation::Tagged());
2400 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002401 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002402 }
2403
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002404 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002405 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002406 }
2407
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002408 virtual Representation RequiredInputRepresentation(int index) const {
2409 return Representation::Tagged();
2410 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002411 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002413 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002414
2415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002417};
2418
2419
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002420class HCompareSymbolEq: public HBinaryOperation {
2421 public:
2422 HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
2423 : HBinaryOperation(left, right), op_(op) {
2424 ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
2425 set_representation(Representation::Tagged());
2426 SetFlag(kUseGVN);
2427 SetFlag(kDependsOnMaps);
2428 }
2429
2430 Token::Value op() const { return op_; }
2431
2432 virtual bool EmitAtUses() {
2433 return !HasSideEffects() && !HasMultipleUses();
2434 }
2435
2436 virtual Representation RequiredInputRepresentation(int index) const {
2437 return Representation::Tagged();
2438 }
2439
2440 virtual HType CalculateInferredType() { return HType::Boolean(); }
2441
2442 DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
2443
2444 protected:
2445 virtual bool DataEquals(HValue* other) {
2446 return op_ == HCompareSymbolEq::cast(other)->op_;
2447 }
2448
2449 private:
2450 const Token::Value op_;
2451};
2452
2453
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454class HUnaryPredicate: public HUnaryOperation {
2455 public:
2456 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2457 set_representation(Representation::Tagged());
2458 SetFlag(kUseGVN);
2459 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002460
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002461 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002462 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002463 }
2464
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002465 virtual Representation RequiredInputRepresentation(int index) const {
2466 return Representation::Tagged();
2467 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002468 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002469};
2470
2471
2472class HIsNull: public HUnaryPredicate {
2473 public:
2474 HIsNull(HValue* value, bool is_strict)
2475 : HUnaryPredicate(value), is_strict_(is_strict) { }
2476
2477 bool is_strict() const { return is_strict_; }
2478
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002479 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002481 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002482 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002483 HIsNull* b = HIsNull::cast(other);
2484 return is_strict_ == b->is_strict();
2485 }
2486
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002487 private:
2488 bool is_strict_;
2489};
2490
2491
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002492class HIsObject: public HUnaryPredicate {
2493 public:
2494 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2495
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002496 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002497
2498 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002499 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002500};
2501
2502
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002503class HIsSmi: public HUnaryPredicate {
2504 public:
2505 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2506
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002507 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002508
2509 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002510 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511};
2512
2513
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002514class HIsUndetectable: public HUnaryPredicate {
2515 public:
2516 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2517
2518 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2519
2520 protected:
2521 virtual bool DataEquals(HValue* other) { return true; }
2522};
2523
2524
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002525class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002526 public:
2527 HIsConstructCall() {
2528 set_representation(Representation::Tagged());
2529 SetFlag(kUseGVN);
2530 }
2531
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002532 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002533 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002534 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002535
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002536 virtual Representation RequiredInputRepresentation(int index) const {
2537 return Representation::None();
2538 }
2539
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002540 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002541
2542 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002543 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002544};
2545
2546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547class HHasInstanceType: public HUnaryPredicate {
2548 public:
2549 HHasInstanceType(HValue* value, InstanceType type)
2550 : HUnaryPredicate(value), from_(type), to_(type) { }
2551 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2552 : HUnaryPredicate(value), from_(from), to_(to) {
2553 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2554 }
2555
2556 InstanceType from() { return from_; }
2557 InstanceType to() { return to_; }
2558
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002559 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002561 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002562
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002563 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002564 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002565 HHasInstanceType* b = HHasInstanceType::cast(other);
2566 return (from_ == b->from()) && (to_ == b->to());
2567 }
2568
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002569 private:
2570 InstanceType from_;
2571 InstanceType to_; // Inclusive range, not all combinations work.
2572};
2573
2574
2575class HHasCachedArrayIndex: public HUnaryPredicate {
2576 public:
2577 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2578
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002579 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002580
2581 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002582 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583};
2584
2585
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002586class HGetCachedArrayIndex: public HUnaryPredicate {
2587 public:
2588 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2589
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002590 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002591
2592 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002593 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002594};
2595
2596
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002597class HClassOfTest: public HUnaryPredicate {
2598 public:
2599 HClassOfTest(HValue* value, Handle<String> class_name)
2600 : HUnaryPredicate(value), class_name_(class_name) { }
2601
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002602 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002604 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002605
2606 Handle<String> class_name() const { return class_name_; }
2607
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002608 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002609 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002610 HClassOfTest* b = HClassOfTest::cast(other);
2611 return class_name_.is_identical_to(b->class_name_);
2612 }
2613
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002614 private:
2615 Handle<String> class_name_;
2616};
2617
2618
2619class HTypeofIs: public HUnaryPredicate {
2620 public:
2621 HTypeofIs(HValue* value, Handle<String> type_literal)
2622 : HUnaryPredicate(value), type_literal_(type_literal) { }
2623
2624 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002625 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002626
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002627 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002628
2629 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002630 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002631 HTypeofIs* b = HTypeofIs::cast(other);
2632 return type_literal_.is_identical_to(b->type_literal_);
2633 }
2634
2635 private:
2636 Handle<String> type_literal_;
2637};
2638
2639
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002640class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002642 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2643 SetOperandAt(0, context);
2644 SetOperandAt(1, left);
2645 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002646 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002647 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002648 }
2649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002650 HValue* context() { return OperandAt(0); }
2651 HValue* left() { return OperandAt(1); }
2652 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002653
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002654 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002655 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002656 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002657
2658 virtual Representation RequiredInputRepresentation(int index) const {
2659 return Representation::Tagged();
2660 }
2661
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002662 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002663
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002664 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002665};
2666
2667
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002668class HInstanceOfKnownGlobal: public HUnaryOperation {
2669 public:
2670 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2671 : HUnaryOperation(left), function_(right) {
2672 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002673 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002674 }
2675
2676 Handle<JSFunction> function() { return function_; }
2677
2678 virtual Representation RequiredInputRepresentation(int index) const {
2679 return Representation::Tagged();
2680 }
2681
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002682 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002683
2684 private:
2685 Handle<JSFunction> function_;
2686};
2687
2688
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002689class HPower: public HBinaryOperation {
2690 public:
2691 HPower(HValue* left, HValue* right)
2692 : HBinaryOperation(left, right) {
2693 set_representation(Representation::Double());
2694 SetFlag(kUseGVN);
2695 }
2696
2697 virtual Representation RequiredInputRepresentation(int index) const {
2698 return (index == 1) ? Representation::None() : Representation::Double();
2699 }
2700
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002701 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002702
2703 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002704 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002705};
2706
2707
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002708class HAdd: public HArithmeticBinaryOperation {
2709 public:
2710 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2711 SetFlag(kCanOverflow);
2712 }
2713
2714 // Add is only commutative if two integer values are added and not if two
2715 // tagged values are added (because it might be a String concatenation).
2716 virtual bool IsCommutative() const {
2717 return !representation().IsTagged();
2718 }
2719
2720 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2721
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002722 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002723
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002724 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725
2726 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002727 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002729 virtual Range* InferRange();
2730};
2731
2732
2733class HSub: public HArithmeticBinaryOperation {
2734 public:
2735 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2736 SetFlag(kCanOverflow);
2737 }
2738
2739 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2740
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002741 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002742
2743 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002744 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002745
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002746 virtual Range* InferRange();
2747};
2748
2749
2750class HMul: public HArithmeticBinaryOperation {
2751 public:
2752 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2753 SetFlag(kCanOverflow);
2754 }
2755
2756 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2757
2758 // Only commutative if it is certain that not two objects are multiplicated.
2759 virtual bool IsCommutative() const {
2760 return !representation().IsTagged();
2761 }
2762
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002763 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764
2765 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002766 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002767
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768 virtual Range* InferRange();
2769};
2770
2771
2772class HMod: public HArithmeticBinaryOperation {
2773 public:
2774 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2775 SetFlag(kCanBeDivByZero);
2776 }
2777
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002778 bool HasPowerOf2Divisor() {
2779 if (right()->IsConstant() &&
2780 HConstant::cast(right())->HasInteger32Value()) {
2781 int32_t value = HConstant::cast(right())->Integer32Value();
2782 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2783 }
2784
2785 return false;
2786 }
2787
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2789
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002790 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791
2792 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002793 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002794
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002795 virtual Range* InferRange();
2796};
2797
2798
2799class HDiv: public HArithmeticBinaryOperation {
2800 public:
2801 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2802 SetFlag(kCanBeDivByZero);
2803 SetFlag(kCanOverflow);
2804 }
2805
2806 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2807
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002808 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809
2810 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002811 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002812
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813 virtual Range* InferRange();
2814};
2815
2816
2817class HBitAnd: public HBitwiseBinaryOperation {
2818 public:
2819 HBitAnd(HValue* left, HValue* right)
2820 : HBitwiseBinaryOperation(left, right) { }
2821
2822 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002823 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002825 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826
2827 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002828 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002829
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002830 virtual Range* InferRange();
2831};
2832
2833
2834class HBitXor: public HBitwiseBinaryOperation {
2835 public:
2836 HBitXor(HValue* left, HValue* right)
2837 : HBitwiseBinaryOperation(left, right) { }
2838
2839 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002840 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002842 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002843
2844 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002845 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846};
2847
2848
2849class HBitOr: public HBitwiseBinaryOperation {
2850 public:
2851 HBitOr(HValue* left, HValue* right)
2852 : HBitwiseBinaryOperation(left, right) { }
2853
2854 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002855 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002856
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002857 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858
2859 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002860 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002861
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002862 virtual Range* InferRange();
2863};
2864
2865
2866class HShl: public HBitwiseBinaryOperation {
2867 public:
2868 HShl(HValue* left, HValue* right)
2869 : HBitwiseBinaryOperation(left, right) { }
2870
2871 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002872 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002873
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002874 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002875
2876 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002877 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002878};
2879
2880
2881class HShr: public HBitwiseBinaryOperation {
2882 public:
2883 HShr(HValue* left, HValue* right)
2884 : HBitwiseBinaryOperation(left, right) { }
2885
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002886 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002888 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002889
2890 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002891 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892};
2893
2894
2895class HSar: public HBitwiseBinaryOperation {
2896 public:
2897 HSar(HValue* left, HValue* right)
2898 : HBitwiseBinaryOperation(left, right) { }
2899
2900 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002901 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002903 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002904
2905 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002906 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907};
2908
2909
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002910class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002911 public:
2912 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2913 SetFlag(kChangesOsrEntries);
2914 }
2915
2916 int ast_id() const { return ast_id_; }
2917
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002918 virtual Representation RequiredInputRepresentation(int index) const {
2919 return Representation::None();
2920 }
2921
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002922 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923
2924 private:
2925 int ast_id_;
2926};
2927
2928
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002929class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930 public:
2931 explicit HParameter(unsigned index) : index_(index) {
2932 set_representation(Representation::Tagged());
2933 }
2934
2935 unsigned index() const { return index_; }
2936
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002937 virtual void PrintDataTo(StringStream* stream);
2938
2939 virtual Representation RequiredInputRepresentation(int index) const {
2940 return Representation::None();
2941 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002942
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002943 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944
2945 private:
2946 unsigned index_;
2947};
2948
2949
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002950class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002951 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002952 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2953 : HUnaryCall(context, argument_count),
2954 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002955 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956 }
2957
2958 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002959
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002960 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002961
2962 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2963 transcendental_type_ = transcendental_type;
2964 }
2965 TranscendentalCache::Type transcendental_type() {
2966 return transcendental_type_;
2967 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002968
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002969 virtual void PrintDataTo(StringStream* stream);
2970
2971 virtual Representation RequiredInputRepresentation(int index) const {
2972 return Representation::Tagged();
2973 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002974
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002975 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002976
2977 private:
2978 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979 TranscendentalCache::Type transcendental_type_;
2980};
2981
2982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002983class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984 public:
2985 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2986
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002987 virtual Representation RequiredInputRepresentation(int index) const {
2988 return Representation::None();
2989 }
2990
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002991 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992};
2993
2994
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002995class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002997 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998 : cell_(cell), check_hole_value_(check_hole_value) {
2999 set_representation(Representation::Tagged());
3000 SetFlag(kUseGVN);
3001 SetFlag(kDependsOnGlobalVars);
3002 }
3003
3004 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3005 bool check_hole_value() const { return check_hole_value_; }
3006
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003007 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003009 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003010 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 return reinterpret_cast<intptr_t>(*cell_);
3012 }
3013
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014 virtual Representation RequiredInputRepresentation(int index) const {
3015 return Representation::None();
3016 }
3017
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003018 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019
3020 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003021 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003022 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023 return cell_.is_identical_to(b->cell());
3024 }
3025
3026 private:
3027 Handle<JSGlobalPropertyCell> cell_;
3028 bool check_hole_value_;
3029};
3030
3031
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003032class HLoadGlobalGeneric: public HBinaryOperation {
3033 public:
3034 HLoadGlobalGeneric(HValue* context,
3035 HValue* global_object,
3036 Handle<Object> name,
3037 bool for_typeof)
3038 : HBinaryOperation(context, global_object),
3039 name_(name),
3040 for_typeof_(for_typeof) {
3041 set_representation(Representation::Tagged());
3042 SetAllSideEffects();
3043 }
3044
3045 HValue* context() { return OperandAt(0); }
3046 HValue* global_object() { return OperandAt(1); }
3047 Handle<Object> name() const { return name_; }
3048 bool for_typeof() const { return for_typeof_; }
3049
3050 virtual void PrintDataTo(StringStream* stream);
3051
3052 virtual Representation RequiredInputRepresentation(int index) const {
3053 return Representation::Tagged();
3054 }
3055
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003056 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003057
3058 private:
3059 Handle<Object> name_;
3060 bool for_typeof_;
3061};
3062
3063
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003064class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003066 HStoreGlobalCell(HValue* value,
3067 Handle<JSGlobalPropertyCell> cell,
3068 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003069 : HUnaryOperation(value),
3070 cell_(cell),
3071 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072 SetFlag(kChangesGlobalVars);
3073 }
3074
3075 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003076 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077
3078 virtual Representation RequiredInputRepresentation(int index) const {
3079 return Representation::Tagged();
3080 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003083 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003084
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 private:
3086 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003087 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003088};
3089
3090
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003091class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3092 public:
3093 HStoreGlobalGeneric(HValue* context,
3094 HValue* global_object,
3095 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003096 HValue* value,
3097 bool strict_mode)
3098 : name_(name),
3099 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003100 SetOperandAt(0, context);
3101 SetOperandAt(1, global_object);
3102 SetOperandAt(2, value);
3103 set_representation(Representation::Tagged());
3104 SetAllSideEffects();
3105 }
3106
3107 HValue* context() { return OperandAt(0); }
3108 HValue* global_object() { return OperandAt(1); }
3109 Handle<Object> name() const { return name_; }
3110 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003111 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003112
3113 virtual void PrintDataTo(StringStream* stream);
3114
3115 virtual Representation RequiredInputRepresentation(int index) const {
3116 return Representation::Tagged();
3117 }
3118
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003119 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003120
3121 private:
3122 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003123 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003124};
3125
3126
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003127class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003128 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003129 HLoadContextSlot(HValue* context , int slot_index)
3130 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003131 set_representation(Representation::Tagged());
3132 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003133 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003134 }
3135
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003136 int slot_index() const { return slot_index_; }
3137
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003138 virtual Representation RequiredInputRepresentation(int index) const {
3139 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003140 }
3141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003142 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003143
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003144 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003145
3146 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003147 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003148 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003149 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003150 }
3151
3152 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003153 int slot_index_;
3154};
3155
3156
3157static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3158 return !value->type().IsSmi() &&
3159 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3160}
3161
3162
3163class HStoreContextSlot: public HBinaryOperation {
3164 public:
3165 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3166 : HBinaryOperation(context, value), slot_index_(slot_index) {
3167 SetFlag(kChangesContextSlots);
3168 }
3169
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003170 HValue* context() { return OperandAt(0); }
3171 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003172 int slot_index() const { return slot_index_; }
3173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003174 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003175 return StoringValueNeedsWriteBarrier(value());
3176 }
3177
3178 virtual Representation RequiredInputRepresentation(int index) const {
3179 return Representation::Tagged();
3180 }
3181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003182 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003183
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003184 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003185
3186 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003187 int slot_index_;
3188};
3189
3190
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191class HLoadNamedField: public HUnaryOperation {
3192 public:
3193 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3194 : HUnaryOperation(object),
3195 is_in_object_(is_in_object),
3196 offset_(offset) {
3197 set_representation(Representation::Tagged());
3198 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003199 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003200 if (is_in_object) {
3201 SetFlag(kDependsOnInobjectFields);
3202 } else {
3203 SetFlag(kDependsOnBackingStoreFields);
3204 }
3205 }
3206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003207 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003208 bool is_in_object() const { return is_in_object_; }
3209 int offset() const { return offset_; }
3210
3211 virtual Representation RequiredInputRepresentation(int index) const {
3212 return Representation::Tagged();
3213 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003214 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003216 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003217
3218 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003219 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003220 HLoadNamedField* b = HLoadNamedField::cast(other);
3221 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3222 }
3223
3224 private:
3225 bool is_in_object_;
3226 int offset_;
3227};
3228
3229
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003230class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3231 public:
3232 HLoadNamedFieldPolymorphic(HValue* object,
3233 ZoneMapList* types,
3234 Handle<String> name);
3235
3236 HValue* object() { return OperandAt(0); }
3237 ZoneMapList* types() { return &types_; }
3238 Handle<String> name() { return name_; }
3239 bool need_generic() { return need_generic_; }
3240
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(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003246
3247 static const int kMaxLoadPolymorphism = 4;
3248
3249 protected:
3250 virtual bool DataEquals(HValue* value);
3251
3252 private:
3253 ZoneMapList types_;
3254 Handle<String> name_;
3255 bool need_generic_;
3256};
3257
3258
3259
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003260class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003262 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3263 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003265 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003266 }
3267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003268 HValue* context() { return OperandAt(0); }
3269 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003270 Handle<Object> name() const { return name_; }
3271
3272 virtual Representation RequiredInputRepresentation(int index) const {
3273 return Representation::Tagged();
3274 }
3275
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003276 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003277
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003278 private:
3279 Handle<Object> name_;
3280};
3281
3282
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003283class HLoadFunctionPrototype: public HUnaryOperation {
3284 public:
3285 explicit HLoadFunctionPrototype(HValue* function)
3286 : HUnaryOperation(function) {
3287 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003288 SetFlag(kUseGVN);
3289 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003290 }
3291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003292 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003293
3294 virtual Representation RequiredInputRepresentation(int index) const {
3295 return Representation::Tagged();
3296 }
3297
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003298 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003299
3300 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003301 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003302};
3303
3304
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003305class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003306 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003307 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003308 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003309 SetFlag(kDependsOnArrayElements);
3310 SetFlag(kUseGVN);
3311 }
3312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003313 HValue* object() { return OperandAt(0); }
3314 HValue* key() { return OperandAt(1); }
3315
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003316 virtual Representation RequiredInputRepresentation(int index) const {
3317 // The key is supposed to be Integer32.
3318 return (index == 1) ? Representation::Integer32()
3319 : Representation::Tagged();
3320 }
3321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003322 virtual void PrintDataTo(StringStream* stream);
3323
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003324 bool RequiresHoleCheck() const;
3325
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003326 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003327
3328 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003329 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003330};
3331
3332
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003333class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003334 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003335 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3336 HValue* key,
3337 ExternalArrayType array_type)
3338 : HBinaryOperation(external_elements, key),
3339 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003340 if (array_type == kExternalFloatArray ||
3341 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003342 set_representation(Representation::Double());
3343 } else {
3344 set_representation(Representation::Integer32());
3345 }
3346 SetFlag(kDependsOnSpecializedArrayElements);
3347 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003348 SetFlag(kDependsOnCalls);
3349 SetFlag(kUseGVN);
3350 }
3351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003352 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003353
3354 virtual Representation RequiredInputRepresentation(int index) const {
3355 // The key is supposed to be Integer32, but the base pointer
3356 // for the element load is a naked pointer.
3357 return (index == 1) ? Representation::Integer32()
3358 : Representation::External();
3359 }
3360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003361 HValue* external_pointer() { return OperandAt(0); }
3362 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003363 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003364
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003365 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003366
3367 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003368 virtual bool DataEquals(HValue* other) {
3369 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3370 HLoadKeyedSpecializedArrayElement* cast_other =
3371 HLoadKeyedSpecializedArrayElement::cast(other);
3372 return array_type_ == cast_other->array_type();
3373 }
3374
3375 private:
3376 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003377};
3378
3379
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003380class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003381 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003382 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003383 set_representation(Representation::Tagged());
3384 SetOperandAt(0, obj);
3385 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003386 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003387 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003388 }
3389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003390 HValue* object() { return OperandAt(0); }
3391 HValue* key() { return OperandAt(1); }
3392 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003393
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003394 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003395
3396 virtual Representation RequiredInputRepresentation(int index) const {
3397 return Representation::Tagged();
3398 }
3399
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003400 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401};
3402
3403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003404class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003405 public:
3406 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003407 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003408 HValue* val,
3409 bool in_object,
3410 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003411 : HBinaryOperation(obj, val),
3412 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003413 is_in_object_(in_object),
3414 offset_(offset) {
3415 if (is_in_object_) {
3416 SetFlag(kChangesInobjectFields);
3417 } else {
3418 SetFlag(kChangesBackingStoreFields);
3419 }
3420 }
3421
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003422 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003423
3424 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003425 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003426 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003427 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003429 HValue* object() { return OperandAt(0); }
3430 HValue* value() { return OperandAt(1); }
3431
3432 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003433 bool is_in_object() const { return is_in_object_; }
3434 int offset() const { return offset_; }
3435 Handle<Map> transition() const { return transition_; }
3436 void set_transition(Handle<Map> map) { transition_ = map; }
3437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003438 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003439 return StoringValueNeedsWriteBarrier(value());
3440 }
3441
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003442 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003443 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003444 bool is_in_object_;
3445 int offset_;
3446 Handle<Map> transition_;
3447};
3448
3449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003450class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003451 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003452 HStoreNamedGeneric(HValue* context,
3453 HValue* object,
3454 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003455 HValue* value,
3456 bool strict_mode)
3457 : name_(name),
3458 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003459 SetOperandAt(0, object);
3460 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003461 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003462 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003463 }
3464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003465 HValue* object() { return OperandAt(0); }
3466 HValue* value() { return OperandAt(1); }
3467 HValue* context() { return OperandAt(2); }
3468 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003469 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003470
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003471 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003472
3473 virtual Representation RequiredInputRepresentation(int index) const {
3474 return Representation::Tagged();
3475 }
3476
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003477 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003479 private:
3480 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003481 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003482};
3483
3484
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003485class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003486 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3488 SetOperandAt(0, obj);
3489 SetOperandAt(1, key);
3490 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003491 SetFlag(kChangesArrayElements);
3492 }
3493
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003494 virtual Representation RequiredInputRepresentation(int index) const {
3495 // The key is supposed to be Integer32.
3496 return (index == 1) ? Representation::Integer32()
3497 : Representation::Tagged();
3498 }
3499
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003500 HValue* object() { return OperandAt(0); }
3501 HValue* key() { return OperandAt(1); }
3502 HValue* value() { return OperandAt(2); }
3503
3504 bool NeedsWriteBarrier() {
3505 return StoringValueNeedsWriteBarrier(value());
3506 }
3507
3508 virtual void PrintDataTo(StringStream* stream);
3509
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003510 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003511};
3512
3513
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003514class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003515 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003516 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3517 HValue* key,
3518 HValue* val,
3519 ExternalArrayType array_type)
3520 : array_type_(array_type) {
3521 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003522 SetOperandAt(0, external_elements);
3523 SetOperandAt(1, key);
3524 SetOperandAt(2, val);
3525 }
3526
3527 virtual void PrintDataTo(StringStream* stream);
3528
3529 virtual Representation RequiredInputRepresentation(int index) const {
3530 if (index == 0) {
3531 return Representation::External();
3532 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003533 if (index == 2 && (array_type() == kExternalFloatArray ||
3534 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003535 return Representation::Double();
3536 } else {
3537 return Representation::Integer32();
3538 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003539 }
3540 }
3541
3542 HValue* external_pointer() { return OperandAt(0); }
3543 HValue* key() { return OperandAt(1); }
3544 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003545 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003546
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003547 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3548
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003549 private:
3550 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003551};
3552
3553
3554class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003555 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003556 HStoreKeyedGeneric(HValue* context,
3557 HValue* object,
3558 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003559 HValue* value,
3560 bool strict_mode)
3561 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003562 SetOperandAt(0, object);
3563 SetOperandAt(1, key);
3564 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003565 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003566 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567 }
3568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003569 HValue* object() { return OperandAt(0); }
3570 HValue* key() { return OperandAt(1); }
3571 HValue* value() { return OperandAt(2); }
3572 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003573 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003574
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003575 virtual Representation RequiredInputRepresentation(int index) const {
3576 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003577 }
3578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 virtual void PrintDataTo(StringStream* stream);
3580
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003581 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003582
3583 private:
3584 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003585};
3586
3587
danno@chromium.org160a7b02011-04-18 15:51:38 +00003588class HStringAdd: public HBinaryOperation {
3589 public:
3590 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3591 set_representation(Representation::Tagged());
3592 SetFlag(kUseGVN);
3593 SetFlag(kDependsOnMaps);
3594 }
3595
3596 virtual Representation RequiredInputRepresentation(int index) const {
3597 return Representation::Tagged();
3598 }
3599
3600 virtual HType CalculateInferredType() {
3601 return HType::String();
3602 }
3603
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003604 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003605
3606 protected:
3607 virtual bool DataEquals(HValue* other) { return true; }
3608};
3609
3610
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003611class HStringCharCodeAt: public HBinaryOperation {
3612 public:
3613 HStringCharCodeAt(HValue* string, HValue* index)
3614 : HBinaryOperation(string, index) {
3615 set_representation(Representation::Integer32());
3616 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003617 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003618 }
3619
3620 virtual Representation RequiredInputRepresentation(int index) const {
3621 // The index is supposed to be Integer32.
3622 return (index == 1) ? Representation::Integer32()
3623 : Representation::Tagged();
3624 }
3625
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003626 HValue* string() { return OperandAt(0); }
3627 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003628
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003629 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003630
3631 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003632 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003633
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003634 virtual Range* InferRange() {
3635 return new Range(0, String::kMaxUC16CharCode);
3636 }
3637};
3638
3639
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003640class HStringCharFromCode: public HUnaryOperation {
3641 public:
3642 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3643 set_representation(Representation::Tagged());
3644 SetFlag(kUseGVN);
3645 }
3646
3647 virtual Representation RequiredInputRepresentation(int index) const {
3648 return Representation::Integer32();
3649 }
3650
3651 virtual bool DataEquals(HValue* other) { return true; }
3652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003653 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003654};
3655
3656
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003657class HStringLength: public HUnaryOperation {
3658 public:
3659 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3660 set_representation(Representation::Tagged());
3661 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003662 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003663 }
3664
3665 virtual Representation RequiredInputRepresentation(int index) const {
3666 return Representation::Tagged();
3667 }
3668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003669 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003670 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3671 return HType::Smi();
3672 }
3673
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003674 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003675
3676 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003677 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003678
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003679 virtual Range* InferRange() {
3680 return new Range(0, String::kMaxLength);
3681 }
3682};
3683
3684
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003685template <int V>
3686class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003687 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003688 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003689 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003690 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691 }
3692
3693 int literal_index() const { return literal_index_; }
3694 int depth() const { return depth_; }
3695
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003696 private:
3697 int literal_index_;
3698 int depth_;
3699};
3700
3701
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003702class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003703 public:
3704 HArrayLiteral(Handle<FixedArray> constant_elements,
3705 int length,
3706 int literal_index,
3707 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003708 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003709 length_(length),
3710 constant_elements_(constant_elements) {}
3711
3712 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3713 int length() const { return length_; }
3714
3715 bool IsCopyOnWrite() const;
3716
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003717 virtual Representation RequiredInputRepresentation(int index) const {
3718 return Representation::None();
3719 }
3720
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003721 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003722
3723 private:
3724 int length_;
3725 Handle<FixedArray> constant_elements_;
3726};
3727
3728
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003729class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003730 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003731 HObjectLiteral(HValue* context,
3732 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003733 bool fast_elements,
3734 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003735 int depth,
3736 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003737 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003738 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003739 fast_elements_(fast_elements),
3740 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003741 SetOperandAt(0, context);
3742 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003743
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003744 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003745 Handle<FixedArray> constant_properties() const {
3746 return constant_properties_;
3747 }
3748 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003749 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003750
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003751 virtual Representation RequiredInputRepresentation(int index) const {
3752 return Representation::Tagged();
3753 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003754
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003755 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003756
3757 private:
3758 Handle<FixedArray> constant_properties_;
3759 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003760 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003761};
3762
3763
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003764class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003765 public:
3766 HRegExpLiteral(Handle<String> pattern,
3767 Handle<String> flags,
3768 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003769 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003770 pattern_(pattern),
3771 flags_(flags) { }
3772
3773 Handle<String> pattern() { return pattern_; }
3774 Handle<String> flags() { return flags_; }
3775
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003776 virtual Representation RequiredInputRepresentation(int index) const {
3777 return Representation::None();
3778 }
3779
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003780 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003781
3782 private:
3783 Handle<String> pattern_;
3784 Handle<String> flags_;
3785};
3786
3787
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003788class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003789 public:
3790 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3791 : shared_info_(shared), pretenure_(pretenure) {
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::None();
3797 }
3798
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003799 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800
3801 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3802 bool pretenure() const { return pretenure_; }
3803
3804 private:
3805 Handle<SharedFunctionInfo> shared_info_;
3806 bool pretenure_;
3807};
3808
3809
3810class HTypeof: public HUnaryOperation {
3811 public:
3812 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3813 set_representation(Representation::Tagged());
3814 }
3815
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003816 virtual Representation RequiredInputRepresentation(int index) const {
3817 return Representation::Tagged();
3818 }
3819
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003820 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003821};
3822
3823
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003824class HToFastProperties: public HUnaryOperation {
3825 public:
3826 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3827 // This instruction is not marked as having side effects, but
3828 // changes the map of the input operand. Use it only when creating
3829 // object literals.
3830 ASSERT(value->IsObjectLiteral());
3831 set_representation(Representation::Tagged());
3832 }
3833
3834 virtual Representation RequiredInputRepresentation(int index) const {
3835 return Representation::Tagged();
3836 }
3837
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003838 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003839};
3840
3841
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003842class HValueOf: public HUnaryOperation {
3843 public:
3844 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3845 set_representation(Representation::Tagged());
3846 }
3847
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003848 virtual Representation RequiredInputRepresentation(int index) const {
3849 return Representation::Tagged();
3850 }
3851
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003852 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003853};
3854
3855
3856class HDeleteProperty: public HBinaryOperation {
3857 public:
3858 HDeleteProperty(HValue* obj, HValue* key)
3859 : HBinaryOperation(obj, key) {
3860 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003861 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003862 }
3863
3864 virtual Representation RequiredInputRepresentation(int index) const {
3865 return Representation::Tagged();
3866 }
3867
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003868 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003869
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003870 HValue* object() { return left(); }
3871 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003872};
3873
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003874
3875class HIn: public HTemplateInstruction<2> {
3876 public:
3877 HIn(HValue* key, HValue* object) {
3878 SetOperandAt(0, key);
3879 SetOperandAt(1, object);
3880 set_representation(Representation::Tagged());
3881 SetAllSideEffects();
3882 }
3883
3884 HValue* key() { return OperandAt(0); }
3885 HValue* object() { return OperandAt(1); }
3886
3887 virtual Representation RequiredInputRepresentation(int index) const {
3888 return Representation::Tagged();
3889 }
3890
3891 virtual HType CalculateInferredType() {
3892 return HType::Boolean();
3893 }
3894
3895 virtual void PrintDataTo(StringStream* stream);
3896
3897 DECLARE_CONCRETE_INSTRUCTION(In)
3898};
3899
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003900#undef DECLARE_INSTRUCTION
3901#undef DECLARE_CONCRETE_INSTRUCTION
3902
3903} } // namespace v8::internal
3904
3905#endif // V8_HYDROGEN_INSTRUCTIONS_H_