blob: fce11a111fa04a5885c51d83fdc4a08c0f5d7255 [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) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000090 V(ClampToUint8) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000091 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000092 V(Compare) \
93 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000094 V(CompareMap) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +000095 V(CompareSymbolEq) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000096 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000097 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 V(DeleteProperty) \
99 V(Deoptimize) \
100 V(Div) \
101 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000102 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000103 V(FixedArrayLength) \
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000104 V(ToInt32) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000105 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000107 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(GlobalObject) \
109 V(GlobalReceiver) \
110 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000111 V(HasInstanceType) \
112 V(HasCachedArrayIndex) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000113 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000114 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000115 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000116 V(InvokeFunction) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000117 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000119 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(IsSmi) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000121 V(IsUndetectable) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000122 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000123 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000124 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000126 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000127 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000128 V(LoadGlobalCell) \
129 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130 V(LoadKeyedFastElement) \
131 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000132 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000133 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000134 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(LoadNamedGeneric) \
136 V(Mod) \
137 V(Mul) \
138 V(ObjectLiteral) \
139 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000140 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000141 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000142 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143 V(PushArgument) \
144 V(RegExpLiteral) \
145 V(Return) \
146 V(Sar) \
147 V(Shl) \
148 V(Shr) \
149 V(Simulate) \
150 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000151 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000152 V(StoreGlobalCell) \
153 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000154 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000155 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(StoreKeyedGeneric) \
157 V(StoreNamedField) \
158 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000159 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000160 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000161 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000162 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000164 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000166 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000167 V(Typeof) \
168 V(TypeofIs) \
169 V(UnaryMathOperation) \
170 V(UnknownOSRValue) \
171 V(ValueOf)
172
173#define GVN_FLAG_LIST(V) \
174 V(Calls) \
175 V(InobjectFields) \
176 V(BackingStoreFields) \
177 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000178 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 V(GlobalVars) \
180 V(Maps) \
181 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000182 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000183 V(OsrEntries)
184
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000185#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000186 virtual bool Is##type() const { return true; } \
187 static H##type* cast(HValue* value) { \
188 ASSERT(value->Is##type()); \
189 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000190 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191
192
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000193#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000194 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000195 static H##type* cast(HValue* value) { \
196 ASSERT(value->Is##type()); \
197 return reinterpret_cast<H##type*>(value); \
198 } \
199 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
201
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000202class Range: public ZoneObject {
203 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000204 Range()
205 : lower_(kMinInt),
206 upper_(kMaxInt),
207 next_(NULL),
208 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209
210 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000211 : lower_(lower),
212 upper_(upper),
213 next_(NULL),
214 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 int32_t upper() const { return upper_; }
217 int32_t lower() const { return lower_; }
218 Range* next() const { return next_; }
219 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
220 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222 int32_t Mask() const;
223 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
224 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
225 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
226 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000227 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
228 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
229 bool IsInSmiRange() const {
230 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000232 void KeepOrder();
233 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000234
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235 void StackUpon(Range* other) {
236 Intersect(other);
237 next_ = other;
238 }
239
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000240 void Intersect(Range* other);
241 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000242
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000243 void AddConstant(int32_t value);
244 void Sar(int32_t value);
245 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000246 bool AddAndCheckOverflow(Range* other);
247 bool SubAndCheckOverflow(Range* other);
248 bool MulAndCheckOverflow(Range* other);
249
250 private:
251 int32_t lower_;
252 int32_t upper_;
253 Range* next_;
254 bool can_be_minus_zero_;
255};
256
257
258class Representation {
259 public:
260 enum Kind {
261 kNone,
262 kTagged,
263 kDouble,
264 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000265 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000266 kNumRepresentations
267 };
268
269 Representation() : kind_(kNone) { }
270
271 static Representation None() { return Representation(kNone); }
272 static Representation Tagged() { return Representation(kTagged); }
273 static Representation Integer32() { return Representation(kInteger32); }
274 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000275 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000277 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000278 return kind_ == other.kind_;
279 }
280
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000281 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282 bool IsNone() const { return kind_ == kNone; }
283 bool IsTagged() const { return kind_ == kTagged; }
284 bool IsInteger32() const { return kind_ == kInteger32; }
285 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000286 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000287 bool IsSpecialization() const {
288 return kind_ == kInteger32 || kind_ == kDouble;
289 }
290 const char* Mnemonic() const;
291
292 private:
293 explicit Representation(Kind k) : kind_(k) { }
294
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000295 // Make sure kind fits in int8.
296 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
297
298 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000299};
300
301
302class HType {
303 public:
304 HType() : type_(kUninitialized) { }
305
306 static HType Tagged() { return HType(kTagged); }
307 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
308 static HType TaggedNumber() { return HType(kTaggedNumber); }
309 static HType Smi() { return HType(kSmi); }
310 static HType HeapNumber() { return HType(kHeapNumber); }
311 static HType String() { return HType(kString); }
312 static HType Boolean() { return HType(kBoolean); }
313 static HType NonPrimitive() { return HType(kNonPrimitive); }
314 static HType JSArray() { return HType(kJSArray); }
315 static HType JSObject() { return HType(kJSObject); }
316 static HType Uninitialized() { return HType(kUninitialized); }
317
318 // Return the weakest (least precise) common type.
319 HType Combine(HType other) {
320 return HType(static_cast<Type>(type_ & other.type_));
321 }
322
323 bool Equals(const HType& other) {
324 return type_ == other.type_;
325 }
326
327 bool IsSubtypeOf(const HType& other) {
328 return Combine(other).Equals(other);
329 }
330
331 bool IsTagged() {
332 ASSERT(type_ != kUninitialized);
333 return ((type_ & kTagged) == kTagged);
334 }
335
336 bool IsTaggedPrimitive() {
337 ASSERT(type_ != kUninitialized);
338 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
339 }
340
341 bool IsTaggedNumber() {
342 ASSERT(type_ != kUninitialized);
343 return ((type_ & kTaggedNumber) == kTaggedNumber);
344 }
345
346 bool IsSmi() {
347 ASSERT(type_ != kUninitialized);
348 return ((type_ & kSmi) == kSmi);
349 }
350
351 bool IsHeapNumber() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kHeapNumber) == kHeapNumber);
354 }
355
356 bool IsString() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kString) == kString);
359 }
360
361 bool IsBoolean() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kBoolean) == kBoolean);
364 }
365
366 bool IsNonPrimitive() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kNonPrimitive) == kNonPrimitive);
369 }
370
371 bool IsJSArray() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kJSArray) == kJSArray);
374 }
375
376 bool IsJSObject() {
377 ASSERT(type_ != kUninitialized);
378 return ((type_ & kJSObject) == kJSObject);
379 }
380
381 bool IsUninitialized() {
382 return type_ == kUninitialized;
383 }
384
385 static HType TypeFromValue(Handle<Object> value);
386
387 const char* ToString();
388 const char* ToShortString();
389
390 private:
391 enum Type {
392 kTagged = 0x1, // 0000 0000 0000 0001
393 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
394 kTaggedNumber = 0xd, // 0000 0000 0000 1101
395 kSmi = 0x1d, // 0000 0000 0001 1101
396 kHeapNumber = 0x2d, // 0000 0000 0010 1101
397 kString = 0x45, // 0000 0000 0100 0101
398 kBoolean = 0x85, // 0000 0000 1000 0101
399 kNonPrimitive = 0x101, // 0000 0001 0000 0001
400 kJSObject = 0x301, // 0000 0011 0000 0001
401 kJSArray = 0x701, // 0000 0111 1000 0001
402 kUninitialized = 0x1fff // 0001 1111 1111 1111
403 };
404
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000405 // Make sure type fits in int16.
406 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
407
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000408 explicit HType(Type t) : type_(t) { }
409
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000410 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000411};
412
413
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000414class HUseListNode: public ZoneObject {
415 public:
416 HUseListNode(HValue* value, int index, HUseListNode* tail)
417 : tail_(tail), value_(value), index_(index) {
418 }
419
420 HUseListNode* tail() const { return tail_; }
421 HValue* value() const { return value_; }
422 int index() const { return index_; }
423
424 void set_tail(HUseListNode* list) { tail_ = list; }
425
426#ifdef DEBUG
427 void Zap() {
428 tail_ = reinterpret_cast<HUseListNode*>(1);
429 value_ = NULL;
430 index_ = -1;
431 }
432#endif
433
434 private:
435 HUseListNode* tail_;
436 HValue* value_;
437 int index_;
438};
439
440
441// We reuse use list nodes behind the scenes as uses are added and deleted.
442// This class is the safe way to iterate uses while deleting them.
443class HUseIterator BASE_EMBEDDED {
444 public:
445 bool Done() { return current_ == NULL; }
446 void Advance();
447
448 HValue* value() {
449 ASSERT(!Done());
450 return value_;
451 }
452
453 int index() {
454 ASSERT(!Done());
455 return index_;
456 }
457
458 private:
459 explicit HUseIterator(HUseListNode* head);
460
461 HUseListNode* current_;
462 HUseListNode* next_;
463 HValue* value_;
464 int index_;
465
466 friend class HValue;
467};
468
469
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000470class HValue: public ZoneObject {
471 public:
472 static const int kNoNumber = -1;
473
474 // There must be one corresponding kDepends flag for every kChanges flag and
475 // the order of the kChanges flags must be exactly the same as of the kDepends
476 // flags.
477 enum Flag {
478 // Declare global value numbering flags.
479 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
480 GVN_FLAG_LIST(DECLARE_DO)
481 #undef DECLARE_DO
482 kFlexibleRepresentation,
483 kUseGVN,
484 kCanOverflow,
485 kBailoutOnMinusZero,
486 kCanBeDivByZero,
487 kIsArguments,
488 kTruncatingToInt32,
489 kLastFlag = kTruncatingToInt32
490 };
491
492 STATIC_ASSERT(kLastFlag < kBitsPerInt);
493
494 static const int kChangesToDependsFlagsLeftShift = 1;
495
496 static int ChangesFlagsMask() {
497 int result = 0;
498 // Create changes mask.
499#define DECLARE_DO(type) result |= (1 << kChanges##type);
500 GVN_FLAG_LIST(DECLARE_DO)
501#undef DECLARE_DO
502 return result;
503 }
504
505 static int DependsFlagsMask() {
506 return ConvertChangesToDependsFlags(ChangesFlagsMask());
507 }
508
509 static int ConvertChangesToDependsFlags(int flags) {
510 return flags << kChangesToDependsFlagsLeftShift;
511 }
512
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000513 static HValue* cast(HValue* value) { return value; }
514
515 enum Opcode {
516 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000517 #define DECLARE_OPCODE(type) k##type,
518 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
519 kPhi
520 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000521 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000522 virtual Opcode opcode() const = 0;
523
524 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
525 #define DECLARE_PREDICATE(type) \
526 bool Is##type() const { return opcode() == k##type; }
527 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
528 #undef DECLARE_PREDICATE
529 bool IsPhi() const { return opcode() == kPhi; }
530
531 // Declare virtual predicates for abstract HInstruction or HValue
532 #define DECLARE_PREDICATE(type) \
533 virtual bool Is##type() const { return false; }
534 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
535 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000536
537 HValue() : block_(NULL),
538 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000539 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000540 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000541 range_(NULL),
542 flags_(0) {}
543 virtual ~HValue() {}
544
545 HBasicBlock* block() const { return block_; }
546 void SetBlock(HBasicBlock* block);
547
548 int id() const { return id_; }
549 void set_id(int id) { id_ = id; }
550
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000551 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000552
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000553 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000554 Representation representation() const { return representation_; }
555 void ChangeRepresentation(Representation r) {
556 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557 ASSERT(!r.IsNone());
558 ASSERT(CheckFlag(kFlexibleRepresentation));
559 RepresentationChanged(r);
560 representation_ = r;
561 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000562 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000563
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000564 virtual bool IsConvertibleToInteger() const { return true; }
565
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566 HType type() const { return type_; }
567 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000568 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569 type_ = type;
570 }
571
572 // An operation needs to override this function iff:
573 // 1) it can produce an int32 output.
574 // 2) the true value of its output can potentially be minus zero.
575 // The implementation must set a flag so that it bails out in the case where
576 // it would otherwise output what should be a minus zero as an int32 zero.
577 // If the operation also exists in a form that takes int32 and outputs int32
578 // then the operation should return its input value so that we can propagate
579 // back. There are two operations that need to propagate back to more than
580 // one input. They are phi and binary add. They always return NULL and
581 // expect the caller to take care of things.
582 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
583 visited->Add(id());
584 return NULL;
585 }
586
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000587 bool IsDefinedAfter(HBasicBlock* other) const;
588
589 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000590 virtual int OperandCount() = 0;
591 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000592 void SetOperandAt(int index, HValue* value);
593
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000594 void DeleteAndReplaceWith(HValue* other);
595 bool HasNoUses() const { return use_list_ == NULL; }
596 bool HasMultipleUses() const {
597 return use_list_ != NULL && use_list_->tail() != NULL;
598 }
599 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000600 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000601
602 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000603 void SetFlag(Flag f) { flags_ |= (1 << f); }
604 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
605 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
606
607 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
608 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
609 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000610
611 Range* range() const { return range_; }
612 bool HasRange() const { return range_ != NULL; }
613 void AddNewRange(Range* r);
614 void RemoveLastAddedRange();
615 void ComputeInitialRange();
616
617 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000618 virtual Representation RequiredInputRepresentation(int index) const = 0;
619
620 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000621 return representation();
622 }
623
624 // This gives the instruction an opportunity to replace itself with an
625 // instruction that does the same in some better way. To replace an
626 // instruction with a new one, first add the new instruction to the graph,
627 // then return it. Return NULL to have the instruction deleted.
628 virtual HValue* Canonicalize() { return this; }
629
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000630 bool Equals(HValue* other);
631 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000632
633 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000634 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000635 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000636 void PrintTypeTo(StringStream* stream);
637 void PrintRangeTo(StringStream* stream);
638 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000639
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000640 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000641
642 // Updated the inferred type of this instruction and returns true if
643 // it has changed.
644 bool UpdateInferredType();
645
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000646 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000647
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000649 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000650#endif
651
652 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000653 // This function must be overridden for instructions with flag kUseGVN, to
654 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000655 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000656 UNREACHABLE();
657 return false;
658 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000659 virtual void RepresentationChanged(Representation to) { }
660 virtual Range* InferRange();
661 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000662 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663 void clear_block() {
664 ASSERT(block_ != NULL);
665 block_ = NULL;
666 }
667
668 void set_representation(Representation r) {
669 // Representation is set-once.
670 ASSERT(representation_.IsNone() && !r.IsNone());
671 representation_ = r;
672 }
673
674 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000675 // A flag mask to mark an instruction as having arbitrary side effects.
676 static int AllSideEffects() {
677 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
678 }
679
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000680 // Remove the matching use from the use list if present. Returns the
681 // removed list node or NULL.
682 HUseListNode* RemoveUse(HValue* value, int index);
683
684 void ReplaceAllUsesWith(HValue* other);
685
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000686 void RegisterUse(int index, HValue* new_value);
687
688 HBasicBlock* block_;
689
690 // The id of this instruction in the hydrogen graph, assigned when first
691 // added to the graph. Reflects creation order.
692 int id_;
693
694 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000695 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000696 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000697 Range* range_;
698 int flags_;
699
700 DISALLOW_COPY_AND_ASSIGN(HValue);
701};
702
703
704class HInstruction: public HValue {
705 public:
706 HInstruction* next() const { return next_; }
707 HInstruction* previous() const { return previous_; }
708
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000709 virtual void PrintTo(StringStream* stream);
710 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000711
712 bool IsLinked() const { return block() != NULL; }
713 void Unlink();
714 void InsertBefore(HInstruction* next);
715 void InsertAfter(HInstruction* previous);
716
717 int position() const { return position_; }
718 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
719 void set_position(int position) { position_ = position; }
720
721 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
722
723#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000724 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000725#endif
726
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000727 // Returns whether this is some kind of deoptimizing check
728 // instruction.
729 virtual bool IsCheckInstruction() const { return false; }
730
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000731 virtual bool IsCall() { return false; }
732
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000733 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000734
735 protected:
736 HInstruction()
737 : next_(NULL),
738 previous_(NULL),
739 position_(RelocInfo::kNoPosition) {
740 SetFlag(kDependsOnOsrEntries);
741 }
742
743 virtual void DeleteFromGraph() { Unlink(); }
744
745 private:
746 void InitializeAsFirst(HBasicBlock* block) {
747 ASSERT(!IsLinked());
748 SetBlock(block);
749 }
750
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000751 void PrintMnemonicTo(StringStream* stream);
752
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000753 HInstruction* next_;
754 HInstruction* previous_;
755 int position_;
756
757 friend class HBasicBlock;
758};
759
760
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000761class HControlInstruction: public HInstruction {
762 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000763 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
764 : first_successor_(first), second_successor_(second) {
765 }
766
767 HBasicBlock* FirstSuccessor() const { return first_successor_; }
768 HBasicBlock* SecondSuccessor() const { return second_successor_; }
769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000770 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000771
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000772 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000773
774 private:
775 HBasicBlock* first_successor_;
776 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000777};
778
779
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000780template<int NumElements>
781class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000782 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000783 HOperandContainer() : elems_() { }
784
785 int length() { return NumElements; }
786 HValue*& operator[](int i) {
787 ASSERT(i < length());
788 return elems_[i];
789 }
790
791 private:
792 HValue* elems_[NumElements];
793};
794
795
796template<>
797class HOperandContainer<0> {
798 public:
799 int length() { return 0; }
800 HValue*& operator[](int i) {
801 UNREACHABLE();
802 static HValue* t = 0;
803 return t;
804 }
805};
806
807
808template<int V>
809class HTemplateInstruction : public HInstruction {
810 public:
811 int OperandCount() { return V; }
812 HValue* OperandAt(int i) { return inputs_[i]; }
813
814 protected:
815 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
816
817 private:
818 HOperandContainer<V> inputs_;
819};
820
821
822template<int V>
823class HTemplateControlInstruction : public HControlInstruction {
824 public:
825 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
826 : HControlInstruction(first, second) { }
827 int OperandCount() { return V; }
828 HValue* OperandAt(int i) { return inputs_[i]; }
829
830 protected:
831 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
832
833 private:
834 HOperandContainer<V> inputs_;
835};
836
837
838class HBlockEntry: public HTemplateInstruction<0> {
839 public:
840 virtual Representation RequiredInputRepresentation(int index) const {
841 return Representation::None();
842 }
843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000844 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000845};
846
847
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000848class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000849 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000850 explicit HDeoptimize(int environment_length)
851 : HControlInstruction(NULL, NULL),
852 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000853
854 virtual Representation RequiredInputRepresentation(int index) const {
855 return Representation::None();
856 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000857
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000858 virtual int OperandCount() { return values_.length(); }
859 virtual HValue* OperandAt(int index) { return values_[index]; }
860
861 void AddEnvironmentValue(HValue* value) {
862 values_.Add(NULL);
863 SetOperandAt(values_.length() - 1, value);
864 }
865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000866 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000867
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000868 enum UseEnvironment {
869 kNoUses,
870 kUseAll
871 };
872
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000873 protected:
874 virtual void InternalSetOperandAt(int index, HValue* value) {
875 values_[index] = value;
876 }
877
878 private:
879 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000880};
881
882
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000883class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000884 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000885 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000886 : HTemplateControlInstruction<0>(target, NULL),
887 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000888
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000889 void set_include_stack_check(bool include_stack_check) {
890 include_stack_check_ = include_stack_check;
891 }
892 bool include_stack_check() const { return include_stack_check_; }
893
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000894 virtual Representation RequiredInputRepresentation(int index) const {
895 return Representation::None();
896 }
897
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000898 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899
900 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000901 bool include_stack_check_;
902};
903
904
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000905class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000907 explicit HUnaryControlInstruction(HValue* value,
908 HBasicBlock* true_target,
909 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000910 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911 SetOperandAt(0, value);
912 }
913
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000914 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000916 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917};
918
919
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000920class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000922 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
923 : HUnaryControlInstruction(value, true_target, false_target) {
924 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000925 }
926
927 virtual Representation RequiredInputRepresentation(int index) const {
928 return Representation::None();
929 }
930
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000931 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932};
933
934
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000935class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000937 HCompareMap(HValue* value,
938 Handle<Map> map,
939 HBasicBlock* true_target,
940 HBasicBlock* false_target)
941 : HUnaryControlInstruction(value, true_target, false_target),
942 map_(map) {
943 ASSERT(true_target != NULL);
944 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000945 ASSERT(!map.is_null());
946 }
947
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000948 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000949
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950 Handle<Map> map() const { return map_; }
951
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000952 virtual Representation RequiredInputRepresentation(int index) const {
953 return Representation::Tagged();
954 }
955
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000956 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000957
958 private:
959 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960};
961
962
963class HReturn: public HUnaryControlInstruction {
964 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000965 explicit HReturn(HValue* value)
966 : HUnaryControlInstruction(value, NULL, NULL) {
967 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000968
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000969 virtual Representation RequiredInputRepresentation(int index) const {
970 return Representation::Tagged();
971 }
972
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000973 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974};
975
976
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000977class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000978 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000979 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
980
981 virtual Representation RequiredInputRepresentation(int index) const {
982 return Representation::None();
983 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000984
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000985 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000986};
987
988
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000989class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000990 public:
991 explicit HUnaryOperation(HValue* value) {
992 SetOperandAt(0, value);
993 }
994
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000995 static HUnaryOperation* cast(HValue* value) {
996 return reinterpret_cast<HUnaryOperation*>(value);
997 }
998
999 virtual bool CanTruncateToInt32() const {
1000 return CheckFlag(kTruncatingToInt32);
1001 }
1002
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001003 HValue* value() { return OperandAt(0); }
1004 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001005};
1006
1007
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001008class HThrow: public HUnaryOperation {
1009 public:
1010 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1011 SetAllSideEffects();
1012 }
1013
1014 virtual Representation RequiredInputRepresentation(int index) const {
1015 return Representation::Tagged();
1016 }
1017
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001018 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001019};
1020
1021
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001022class HForceRepresentation: public HTemplateInstruction<1> {
1023 public:
1024 HForceRepresentation(HValue* value, Representation required_representation) {
1025 SetOperandAt(0, value);
1026 set_representation(required_representation);
1027 }
1028
1029 HValue* value() { return OperandAt(0); }
1030
1031 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1032
1033 virtual Representation RequiredInputRepresentation(int index) const {
1034 return representation(); // Same as the output representation.
1035 }
1036
1037 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1038};
1039
1040
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001041class HChange: public HUnaryOperation {
1042 public:
1043 HChange(HValue* value,
1044 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001045 Representation to,
1046 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001047 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001048 ASSERT(!from.IsNone() && !to.IsNone());
1049 ASSERT(!from.Equals(to));
1050 set_representation(to);
1051 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001052 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001053 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1054 value->range()->IsInSmiRange()) {
1055 set_type(HType::Smi());
1056 }
1057 }
1058
1059 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1060
1061 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001062 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063 virtual Representation RequiredInputRepresentation(int index) const {
1064 return from_;
1065 }
1066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001067 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001068
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001069 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001070
1071 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001072 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001073 if (!other->IsChange()) return false;
1074 HChange* change = HChange::cast(other);
1075 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001076 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001077 }
1078
1079 private:
1080 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001081};
1082
1083
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001084class HClampToUint8: public HUnaryOperation {
1085 public:
1086 explicit HClampToUint8(HValue* value)
1087 : HUnaryOperation(value),
1088 input_rep_(Representation::None()) {
1089 SetFlag(kFlexibleRepresentation);
1090 set_representation(Representation::Tagged());
1091 SetFlag(kUseGVN);
1092 }
1093
1094 virtual Representation RequiredInputRepresentation(int index) const {
1095 return input_rep_;
1096 }
1097
1098 virtual Representation InferredRepresentation() {
1099 // TODO(danno): Inference on input types should happen separately from
1100 // return representation.
1101 Representation new_rep = value()->representation();
1102 if (input_rep_.IsNone()) {
1103 if (!new_rep.IsNone()) {
1104 input_rep_ = new_rep;
1105 return Representation::Integer32();
1106 } else {
1107 return Representation::None();
1108 }
1109 } else {
1110 return Representation::Integer32();
1111 }
1112 }
1113
1114 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1115
1116 protected:
1117 virtual bool DataEquals(HValue* other) { return true; }
1118
1119 private:
1120 Representation input_rep_;
1121};
1122
1123
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001124class HToInt32: public HUnaryOperation {
1125 public:
1126 explicit HToInt32(HValue* value)
1127 : HUnaryOperation(value) {
1128 set_representation(Representation::Integer32());
1129 SetFlag(kUseGVN);
1130 }
1131
1132 virtual Representation RequiredInputRepresentation(int index) const {
1133 return Representation::None();
1134 }
1135
1136 virtual bool CanTruncateToInt32() const {
1137 return true;
1138 }
1139
1140 virtual HValue* Canonicalize() {
1141 if (value()->representation().IsInteger32()) {
1142 return value();
1143 } else {
1144 return this;
1145 }
1146 }
1147
1148 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1149
1150 protected:
1151 virtual bool DataEquals(HValue* other) { return true; }
1152};
1153
1154
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001155class HSimulate: public HInstruction {
1156 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001157 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001158 : ast_id_(ast_id),
1159 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001160 values_(2),
1161 assigned_indexes_(2) {}
1162 virtual ~HSimulate() {}
1163
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001164 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001165
1166 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1167 int ast_id() const { return ast_id_; }
1168 void set_ast_id(int id) {
1169 ASSERT(!HasAstId());
1170 ast_id_ = id;
1171 }
1172
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173 int pop_count() const { return pop_count_; }
1174 const ZoneList<HValue*>* values() const { return &values_; }
1175 int GetAssignedIndexAt(int index) const {
1176 ASSERT(HasAssignedIndexAt(index));
1177 return assigned_indexes_[index];
1178 }
1179 bool HasAssignedIndexAt(int index) const {
1180 return assigned_indexes_[index] != kNoIndex;
1181 }
1182 void AddAssignedValue(int index, HValue* value) {
1183 AddValue(index, value);
1184 }
1185 void AddPushedValue(HValue* value) {
1186 AddValue(kNoIndex, value);
1187 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001188 virtual int OperandCount() { return values_.length(); }
1189 virtual HValue* OperandAt(int index) { return values_[index]; }
1190
1191 virtual Representation RequiredInputRepresentation(int index) const {
1192 return Representation::None();
1193 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001195 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001196
1197#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001198 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001199#endif
1200
1201 protected:
1202 virtual void InternalSetOperandAt(int index, HValue* value) {
1203 values_[index] = value;
1204 }
1205
1206 private:
1207 static const int kNoIndex = -1;
1208 void AddValue(int index, HValue* value) {
1209 assigned_indexes_.Add(index);
1210 // Resize the list of pushed values.
1211 values_.Add(NULL);
1212 // Set the operand through the base method in HValue to make sure that the
1213 // use lists are correctly updated.
1214 SetOperandAt(values_.length() - 1, value);
1215 }
1216 int ast_id_;
1217 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001218 ZoneList<HValue*> values_;
1219 ZoneList<int> assigned_indexes_;
1220};
1221
1222
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001223class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001224 public:
1225 HStackCheck() { }
1226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227 virtual Representation RequiredInputRepresentation(int index) const {
1228 return Representation::None();
1229 }
1230
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001231 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001232};
1233
1234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001235class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001236 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001237 HEnterInlined(Handle<JSFunction> closure,
1238 FunctionLiteral* function,
1239 CallKind call_kind)
1240 : closure_(closure),
1241 function_(function),
1242 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001243 }
1244
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001245 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001246
1247 Handle<JSFunction> closure() const { return closure_; }
1248 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001249 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001251 virtual Representation RequiredInputRepresentation(int index) const {
1252 return Representation::None();
1253 }
1254
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001255 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001256
1257 private:
1258 Handle<JSFunction> closure_;
1259 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001260 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001261};
1262
1263
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001264class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001265 public:
1266 HLeaveInlined() {}
1267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001268 virtual Representation RequiredInputRepresentation(int index) const {
1269 return Representation::None();
1270 }
1271
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001272 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001273};
1274
1275
1276class HPushArgument: public HUnaryOperation {
1277 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001278 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1279 set_representation(Representation::Tagged());
1280 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001281
1282 virtual Representation RequiredInputRepresentation(int index) const {
1283 return Representation::Tagged();
1284 }
1285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001286 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001288 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289};
1290
1291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001292class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001293 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001294 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001295 set_representation(Representation::Tagged());
1296 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001297 }
1298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001299 virtual Representation RequiredInputRepresentation(int index) const {
1300 return Representation::None();
1301 }
1302
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001303 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001304
1305 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001306 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001307};
1308
1309
1310class HOuterContext: public HUnaryOperation {
1311 public:
1312 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1313 set_representation(Representation::Tagged());
1314 SetFlag(kUseGVN);
1315 }
1316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001317 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001318
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001319 virtual Representation RequiredInputRepresentation(int index) const {
1320 return Representation::Tagged();
1321 }
1322
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001323 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001325};
1326
1327
1328class HGlobalObject: public HUnaryOperation {
1329 public:
1330 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1331 set_representation(Representation::Tagged());
1332 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001333 }
1334
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001335 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001336
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001337 virtual Representation RequiredInputRepresentation(int index) const {
1338 return Representation::Tagged();
1339 }
1340
ager@chromium.org378b34e2011-01-28 08:04:38 +00001341 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001342 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343};
1344
1345
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001346class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001347 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001348 explicit HGlobalReceiver(HValue* global_object)
1349 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001350 set_representation(Representation::Tagged());
1351 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001352 }
1353
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001354 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001356 virtual Representation RequiredInputRepresentation(int index) const {
1357 return Representation::Tagged();
1358 }
1359
ager@chromium.org378b34e2011-01-28 08:04:38 +00001360 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001361 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001362};
1363
1364
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001365template <int V>
1366class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001368 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001369 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1370 this->set_representation(Representation::Tagged());
1371 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001372 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001374 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001375
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001376 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001378 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001379
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001380 private:
1381 int argument_count_;
1382};
1383
1384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001385class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001386 public:
1387 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001388 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001389 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001390 }
1391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001392 virtual Representation RequiredInputRepresentation(int index) const {
1393 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001394 }
1395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001396 virtual void PrintDataTo(StringStream* stream);
1397
1398 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001399};
1400
1401
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001402class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001403 public:
1404 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001405 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001406 SetOperandAt(0, first);
1407 SetOperandAt(1, second);
1408 }
1409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001410 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001412 virtual Representation RequiredInputRepresentation(int index) const {
1413 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001414 }
1415
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001416 HValue* first() { return OperandAt(0); }
1417 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001418};
1419
1420
danno@chromium.org160a7b02011-04-18 15:51:38 +00001421class HInvokeFunction: public HBinaryCall {
1422 public:
1423 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1424 : HBinaryCall(context, function, argument_count) {
1425 }
1426
1427 virtual Representation RequiredInputRepresentation(int index) const {
1428 return Representation::Tagged();
1429 }
1430
1431 HValue* context() { return first(); }
1432 HValue* function() { return second(); }
1433
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001434 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001435};
1436
1437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001438class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001439 public:
1440 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001442
1443 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001444
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001445 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001446 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001447 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001448 }
1449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001450 virtual void PrintDataTo(StringStream* stream);
1451
1452 virtual Representation RequiredInputRepresentation(int index) const {
1453 return Representation::None();
1454 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001455
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001456 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001457
1458 private:
1459 Handle<JSFunction> function_;
1460};
1461
1462
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001463class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465 HCallKeyed(HValue* context, HValue* key, int argument_count)
1466 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001467 }
1468
1469 virtual Representation RequiredInputRepresentation(int index) const {
1470 return Representation::Tagged();
1471 }
1472
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001473 HValue* context() { return first(); }
1474 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001475
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001476 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477};
1478
1479
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001480class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001481 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001482 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1483 : HUnaryCall(context, argument_count), name_(name) {
1484 }
1485
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001486 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001488 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001489 Handle<String> name() const { return name_; }
1490
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001491 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001493 virtual Representation RequiredInputRepresentation(int index) const {
1494 return Representation::Tagged();
1495 }
1496
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001497 private:
1498 Handle<String> name_;
1499};
1500
1501
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001502class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001503 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001504 HCallFunction(HValue* context, int argument_count)
1505 : HUnaryCall(context, argument_count) {
1506 }
1507
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001508 HValue* context() { return value(); }
1509
1510 virtual Representation RequiredInputRepresentation(int index) const {
1511 return Representation::Tagged();
1512 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001514 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001515};
1516
1517
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001518class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001520 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1521 : HUnaryCall(context, argument_count), name_(name) {
1522 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001523
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001524 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001526 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001527 Handle<String> name() const { return name_; }
1528
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001529 virtual Representation RequiredInputRepresentation(int index) const {
1530 return Representation::Tagged();
1531 }
1532
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001533 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534
1535 private:
1536 Handle<String> name_;
1537};
1538
1539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001540class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001541 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001542 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001543 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001544
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001545 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547 Handle<JSFunction> target() const { return target_; }
1548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001549 virtual Representation RequiredInputRepresentation(int index) const {
1550 return Representation::None();
1551 }
1552
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001553 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554
1555 private:
1556 Handle<JSFunction> target_;
1557};
1558
1559
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001560class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001562 HCallNew(HValue* context, HValue* constructor, int argument_count)
1563 : HBinaryCall(context, constructor, argument_count) {
1564 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001565
1566 virtual Representation RequiredInputRepresentation(int index) const {
1567 return Representation::Tagged();
1568 }
1569
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001570 HValue* context() { return first(); }
1571 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001573 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574};
1575
1576
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001577class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578 public:
1579 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001580 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001581 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001582 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1583 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001584
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001585 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 Handle<String> name() const { return name_; }
1587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001588 virtual Representation RequiredInputRepresentation(int index) const {
1589 return Representation::None();
1590 }
1591
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001592 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593
1594 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001595 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596 Handle<String> name_;
1597};
1598
1599
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001600class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001602 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603 // The length of an array is stored as a tagged value in the array
1604 // object. It is guaranteed to be 32 bit integer, but it can be
1605 // represented as either a smi or heap number.
1606 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001608 SetFlag(kDependsOnArrayLengths);
1609 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001610 }
1611
1612 virtual Representation RequiredInputRepresentation(int index) const {
1613 return Representation::Tagged();
1614 }
1615
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001616 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001617
1618 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001619 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001620};
1621
1622
1623class HFixedArrayLength: public HUnaryOperation {
1624 public:
1625 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1626 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001627 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001628 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001629 }
1630
1631 virtual Representation RequiredInputRepresentation(int index) const {
1632 return Representation::Tagged();
1633 }
1634
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001635 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001636
1637 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001638 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639};
1640
1641
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001642class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001643 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001644 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001645 set_representation(Representation::Integer32());
1646 // The result of this instruction is idempotent as long as its inputs don't
1647 // change. The length of a pixel array cannot change once set, so it's not
1648 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1649 SetFlag(kUseGVN);
1650 }
1651
1652 virtual Representation RequiredInputRepresentation(int index) const {
1653 return Representation::Tagged();
1654 }
1655
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001656 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001657
1658 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001659 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001660};
1661
1662
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663class HBitNot: public HUnaryOperation {
1664 public:
1665 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1666 set_representation(Representation::Integer32());
1667 SetFlag(kUseGVN);
1668 SetFlag(kTruncatingToInt32);
1669 }
1670
1671 virtual Representation RequiredInputRepresentation(int index) const {
1672 return Representation::Integer32();
1673 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001674 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001675
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001676 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001677
1678 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001679 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001680};
1681
1682
1683class HUnaryMathOperation: public HUnaryOperation {
1684 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001685 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686 : HUnaryOperation(value), op_(op) {
1687 switch (op) {
1688 case kMathFloor:
1689 case kMathRound:
1690 case kMathCeil:
1691 set_representation(Representation::Integer32());
1692 break;
1693 case kMathAbs:
1694 set_representation(Representation::Tagged());
1695 SetFlag(kFlexibleRepresentation);
1696 break;
1697 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001698 case kMathPowHalf:
1699 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001700 case kMathSin:
1701 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001702 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001703 break;
1704 default:
1705 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001706 }
1707 SetFlag(kUseGVN);
1708 }
1709
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001710 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001711
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001712 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713
1714 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1715
1716 virtual Representation RequiredInputRepresentation(int index) const {
1717 switch (op_) {
1718 case kMathFloor:
1719 case kMathRound:
1720 case kMathCeil:
1721 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001722 case kMathPowHalf:
1723 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001724 case kMathSin:
1725 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001726 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001727 case kMathAbs:
1728 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001729 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001730 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001731 return Representation::None();
1732 }
1733 }
1734
1735 virtual HValue* Canonicalize() {
1736 // If the input is integer32 then we replace the floor instruction
1737 // with its inputs. This happens before the representation changes are
1738 // introduced.
1739 if (op() == kMathFloor) {
1740 if (value()->representation().IsInteger32()) return value();
1741 }
1742 return this;
1743 }
1744
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001745 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746 const char* OpName() const;
1747
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001748 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001749
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001750 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001751 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001752 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1753 return op_ == b->op();
1754 }
1755
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001756 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001757 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758};
1759
1760
1761class HLoadElements: public HUnaryOperation {
1762 public:
1763 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1764 set_representation(Representation::Tagged());
1765 SetFlag(kUseGVN);
1766 SetFlag(kDependsOnMaps);
1767 }
1768
1769 virtual Representation RequiredInputRepresentation(int index) const {
1770 return Representation::Tagged();
1771 }
1772
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001773 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001774
1775 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001776 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001777};
1778
1779
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001780class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001781 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001782 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001783 : HUnaryOperation(value) {
1784 set_representation(Representation::External());
1785 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001786 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001787 // change once set, so it's no necessary to introduce any additional
1788 // dependencies on top of the inputs.
1789 SetFlag(kUseGVN);
1790 }
1791
1792 virtual Representation RequiredInputRepresentation(int index) const {
1793 return Representation::Tagged();
1794 }
1795
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001796 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001797
1798 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001799 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001800};
1801
1802
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803class HCheckMap: public HUnaryOperation {
1804 public:
1805 HCheckMap(HValue* value, Handle<Map> map)
1806 : HUnaryOperation(value), map_(map) {
1807 set_representation(Representation::Tagged());
1808 SetFlag(kUseGVN);
1809 SetFlag(kDependsOnMaps);
1810 }
1811
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001812 virtual bool IsCheckInstruction() const { return true; }
1813
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001814 virtual Representation RequiredInputRepresentation(int index) const {
1815 return Representation::Tagged();
1816 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001817 virtual void PrintDataTo(StringStream* stream);
1818 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001819
1820#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001821 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001822#endif
1823
1824 Handle<Map> map() const { return map_; }
1825
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001826 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001827
1828 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001829 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830 HCheckMap* b = HCheckMap::cast(other);
1831 return map_.is_identical_to(b->map());
1832 }
1833
1834 private:
1835 Handle<Map> map_;
1836};
1837
1838
1839class HCheckFunction: public HUnaryOperation {
1840 public:
1841 HCheckFunction(HValue* value, Handle<JSFunction> function)
1842 : HUnaryOperation(value), target_(function) {
1843 set_representation(Representation::Tagged());
1844 SetFlag(kUseGVN);
1845 }
1846
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001847 virtual bool IsCheckInstruction() const { return true; }
1848
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001849 virtual Representation RequiredInputRepresentation(int index) const {
1850 return Representation::Tagged();
1851 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001852 virtual void PrintDataTo(StringStream* stream);
1853 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001854
1855#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001856 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001857#endif
1858
1859 Handle<JSFunction> target() const { return target_; }
1860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001861 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862
1863 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001864 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001865 HCheckFunction* b = HCheckFunction::cast(other);
1866 return target_.is_identical_to(b->target());
1867 }
1868
1869 private:
1870 Handle<JSFunction> target_;
1871};
1872
1873
1874class HCheckInstanceType: public HUnaryOperation {
1875 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001876 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) {
1877 return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION);
1878 }
1879 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1880 return new HCheckInstanceType(value, IS_JS_ARRAY);
1881 }
1882 static HCheckInstanceType* NewIsString(HValue* value) {
1883 return new HCheckInstanceType(value, IS_STRING);
1884 }
1885 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1886 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001887 }
1888
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001889 virtual bool IsCheckInstruction() const { return true; }
1890
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001891 virtual Representation RequiredInputRepresentation(int index) const {
1892 return Representation::Tagged();
1893 }
1894
1895#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001896 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001897#endif
1898
danno@chromium.org160a7b02011-04-18 15:51:38 +00001899 virtual HValue* Canonicalize() {
1900 if (!value()->type().IsUninitialized() &&
1901 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001902 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001903 return NULL;
1904 }
1905 return this;
1906 }
1907
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001908 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1909 void GetCheckInterval(InstanceType* first, InstanceType* last);
1910 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001912 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001913
1914 protected:
1915 // TODO(ager): It could be nice to allow the ommision of instance
1916 // type checks if we have already performed an instance type check
1917 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001918 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001920 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001921 }
1922
1923 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001924 enum Check {
1925 IS_JS_OBJECT_OR_JS_FUNCTION,
1926 IS_JS_ARRAY,
1927 IS_STRING,
1928 IS_SYMBOL,
1929 LAST_INTERVAL_CHECK = IS_JS_ARRAY
1930 };
1931
1932 HCheckInstanceType(HValue* value, Check check)
1933 : HUnaryOperation(value), check_(check) {
1934 set_representation(Representation::Tagged());
1935 SetFlag(kUseGVN);
1936 }
1937
1938 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001939};
1940
1941
1942class HCheckNonSmi: public HUnaryOperation {
1943 public:
1944 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1945 set_representation(Representation::Tagged());
1946 SetFlag(kUseGVN);
1947 }
1948
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001949 virtual bool IsCheckInstruction() const { return true; }
1950
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001951 virtual Representation RequiredInputRepresentation(int index) const {
1952 return Representation::Tagged();
1953 }
1954
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001955 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001956
1957#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001958 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001959#endif
1960
danno@chromium.org160a7b02011-04-18 15:51:38 +00001961 virtual HValue* Canonicalize() {
1962 HType value_type = value()->type();
1963 if (!value_type.IsUninitialized() &&
1964 (value_type.IsHeapNumber() ||
1965 value_type.IsString() ||
1966 value_type.IsBoolean() ||
1967 value_type.IsNonPrimitive())) {
1968 return NULL;
1969 }
1970 return this;
1971 }
1972
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001973 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001974
1975 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001976 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977};
1978
1979
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001980class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001981 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001982 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1983 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001984 SetFlag(kUseGVN);
1985 SetFlag(kDependsOnMaps);
1986 }
1987
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001988 virtual bool IsCheckInstruction() const { return true; }
1989
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001990#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001991 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001992#endif
1993
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001994 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001997 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001999 virtual Representation RequiredInputRepresentation(int index) const {
2000 return Representation::None();
2001 }
2002
2003 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002004 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002005 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2006 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2007 return hash;
2008 }
2009
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002010 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002011 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002012 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002013 return prototype_.is_identical_to(b->prototype()) &&
2014 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015 }
2016
2017 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002018 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002019 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020};
2021
2022
2023class HCheckSmi: public HUnaryOperation {
2024 public:
2025 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2026 set_representation(Representation::Tagged());
2027 SetFlag(kUseGVN);
2028 }
2029
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002030 virtual bool IsCheckInstruction() const { return true; }
2031
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002032 virtual Representation RequiredInputRepresentation(int index) const {
2033 return Representation::Tagged();
2034 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002035 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002036
2037#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002038 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002039#endif
2040
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002041 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002042
2043 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002044 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002045};
2046
2047
2048class HPhi: public HValue {
2049 public:
2050 explicit HPhi(int merged_index)
2051 : inputs_(2),
2052 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002053 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002054 is_live_(false),
2055 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2057 non_phi_uses_[i] = 0;
2058 indirect_uses_[i] = 0;
2059 }
2060 ASSERT(merged_index >= 0);
2061 set_representation(Representation::Tagged());
2062 SetFlag(kFlexibleRepresentation);
2063 }
2064
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002065 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066 bool double_occurred = false;
2067 bool int32_occurred = false;
2068 for (int i = 0; i < OperandCount(); ++i) {
2069 HValue* value = OperandAt(i);
2070 if (value->representation().IsDouble()) double_occurred = true;
2071 if (value->representation().IsInteger32()) int32_occurred = true;
2072 if (value->representation().IsTagged()) return Representation::Tagged();
2073 }
2074
2075 if (double_occurred) return Representation::Double();
2076 if (int32_occurred) return Representation::Integer32();
2077 return Representation::None();
2078 }
2079
2080 virtual Range* InferRange();
2081 virtual Representation RequiredInputRepresentation(int index) const {
2082 return representation();
2083 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002084 virtual HType CalculateInferredType();
2085 virtual int OperandCount() { return inputs_.length(); }
2086 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2087 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002089 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002091 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092
2093 int merged_index() const { return merged_index_; }
2094
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002095 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096
2097#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002098 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099#endif
2100
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002101 void InitRealUses(int id);
2102 void AddNonPhiUsesFrom(HPhi* other);
2103 void AddIndirectUsesTo(int* use_count);
2104
2105 int tagged_non_phi_uses() const {
2106 return non_phi_uses_[Representation::kTagged];
2107 }
2108 int int32_non_phi_uses() const {
2109 return non_phi_uses_[Representation::kInteger32];
2110 }
2111 int double_non_phi_uses() const {
2112 return non_phi_uses_[Representation::kDouble];
2113 }
2114 int tagged_indirect_uses() const {
2115 return indirect_uses_[Representation::kTagged];
2116 }
2117 int int32_indirect_uses() const {
2118 return indirect_uses_[Representation::kInteger32];
2119 }
2120 int double_indirect_uses() const {
2121 return indirect_uses_[Representation::kDouble];
2122 }
2123 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002124 bool is_live() { return is_live_; }
2125 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002126
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002127 static HPhi* cast(HValue* value) {
2128 ASSERT(value->IsPhi());
2129 return reinterpret_cast<HPhi*>(value);
2130 }
2131 virtual Opcode opcode() const { return HValue::kPhi; }
2132
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002133 virtual bool IsConvertibleToInteger() const {
2134 return is_convertible_to_integer_;
2135 }
2136
2137 void set_is_convertible_to_integer(bool b) {
2138 is_convertible_to_integer_ = b;
2139 }
2140
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002141 protected:
2142 virtual void DeleteFromGraph();
2143 virtual void InternalSetOperandAt(int index, HValue* value) {
2144 inputs_[index] = value;
2145 }
2146
2147 private:
2148 ZoneList<HValue*> inputs_;
2149 int merged_index_;
2150
2151 int non_phi_uses_[Representation::kNumRepresentations];
2152 int indirect_uses_[Representation::kNumRepresentations];
2153 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002154 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002155 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156};
2157
2158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002159class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160 public:
2161 HArgumentsObject() {
2162 set_representation(Representation::Tagged());
2163 SetFlag(kIsArguments);
2164 }
2165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002166 virtual Representation RequiredInputRepresentation(int index) const {
2167 return Representation::None();
2168 }
2169
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002170 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002171};
2172
2173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002174class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002175 public:
2176 HConstant(Handle<Object> handle, Representation r);
2177
2178 Handle<Object> handle() const { return handle_; }
2179
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002180 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002182 virtual Representation RequiredInputRepresentation(int index) const {
2183 return Representation::None();
2184 }
2185
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002186 virtual bool IsConvertibleToInteger() const {
2187 if (handle_->IsSmi()) return true;
2188 if (handle_->IsHeapNumber() &&
2189 (HeapNumber::cast(*handle_)->value() ==
2190 static_cast<double>(NumberToInt32(*handle_)))) return true;
2191 return false;
2192 }
2193
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002194 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002195 virtual void PrintDataTo(StringStream* stream);
2196 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002197 bool IsInteger() const { return handle_->IsSmi(); }
2198 HConstant* CopyToRepresentation(Representation r) const;
2199 HConstant* CopyToTruncatedInt32() const;
2200 bool HasInteger32Value() const { return has_int32_value_; }
2201 int32_t Integer32Value() const {
2202 ASSERT(HasInteger32Value());
2203 return int32_value_;
2204 }
2205 bool HasDoubleValue() const { return has_double_value_; }
2206 double DoubleValue() const {
2207 ASSERT(HasDoubleValue());
2208 return double_value_;
2209 }
2210 bool HasStringValue() const { return handle_->IsString(); }
2211
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002212 bool ToBoolean() const;
2213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002214 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002215 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002216 return reinterpret_cast<intptr_t>(*handle());
2217 }
2218
2219#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002220 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002221#endif
2222
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002223 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002224
2225 protected:
2226 virtual Range* InferRange();
2227
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002228 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002229 HConstant* other_constant = HConstant::cast(other);
2230 return handle().is_identical_to(other_constant->handle());
2231 }
2232
2233 private:
2234 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235
2236 // The following two values represent the int32 and the double value of the
2237 // given constant if there is a lossless conversion between the constant
2238 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002239 bool has_int32_value_ : 1;
2240 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002241 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002242 double double_value_;
2243};
2244
2245
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002246class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002247 public:
2248 HBinaryOperation(HValue* left, HValue* right) {
2249 ASSERT(left != NULL && right != NULL);
2250 SetOperandAt(0, left);
2251 SetOperandAt(1, right);
2252 }
2253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002254 HValue* left() { return OperandAt(0); }
2255 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002256
2257 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2258 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002259 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002260 if (IsCommutative() && left()->IsConstant()) return right();
2261 return left();
2262 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002263 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002264 if (IsCommutative() && left()->IsConstant()) return left();
2265 return right();
2266 }
2267
2268 virtual bool IsCommutative() const { return false; }
2269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002270 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002271};
2272
2273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002274class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002275 public:
2276 HApplyArguments(HValue* function,
2277 HValue* receiver,
2278 HValue* length,
2279 HValue* elements) {
2280 set_representation(Representation::Tagged());
2281 SetOperandAt(0, function);
2282 SetOperandAt(1, receiver);
2283 SetOperandAt(2, length);
2284 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002285 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002286 }
2287
2288 virtual Representation RequiredInputRepresentation(int index) const {
2289 // The length is untagged, all other inputs are tagged.
2290 return (index == 2)
2291 ? Representation::Integer32()
2292 : Representation::Tagged();
2293 }
2294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002295 HValue* function() { return OperandAt(0); }
2296 HValue* receiver() { return OperandAt(1); }
2297 HValue* length() { return OperandAt(2); }
2298 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002299
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002300 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002301};
2302
2303
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002304class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002305 public:
2306 HArgumentsElements() {
2307 // The value produced by this instruction is a pointer into the stack
2308 // that looks as if it was a smi because of alignment.
2309 set_representation(Representation::Tagged());
2310 SetFlag(kUseGVN);
2311 }
2312
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002313 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002315 virtual Representation RequiredInputRepresentation(int index) const {
2316 return Representation::None();
2317 }
2318
ager@chromium.org378b34e2011-01-28 08:04:38 +00002319 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002320 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002321};
2322
2323
2324class HArgumentsLength: public HUnaryOperation {
2325 public:
2326 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2327 set_representation(Representation::Integer32());
2328 SetFlag(kUseGVN);
2329 }
2330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002331 virtual Representation RequiredInputRepresentation(int index) const {
2332 return Representation::Tagged();
2333 }
2334
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002335 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002336
2337 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002338 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339};
2340
2341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002342class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343 public:
2344 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2345 set_representation(Representation::Tagged());
2346 SetFlag(kUseGVN);
2347 SetOperandAt(0, arguments);
2348 SetOperandAt(1, length);
2349 SetOperandAt(2, index);
2350 }
2351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002352 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002353
2354 virtual Representation RequiredInputRepresentation(int index) const {
2355 // The arguments elements is considered tagged.
2356 return index == 0
2357 ? Representation::Tagged()
2358 : Representation::Integer32();
2359 }
2360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002361 HValue* arguments() { return OperandAt(0); }
2362 HValue* length() { return OperandAt(1); }
2363 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002364
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002365 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002366
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002367 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002368};
2369
2370
2371class HBoundsCheck: public HBinaryOperation {
2372 public:
2373 HBoundsCheck(HValue* index, HValue* length)
2374 : HBinaryOperation(index, length) {
2375 SetFlag(kUseGVN);
2376 }
2377
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002378 virtual bool IsCheckInstruction() const { return true; }
2379
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002380 virtual Representation RequiredInputRepresentation(int index) const {
2381 return Representation::Integer32();
2382 }
2383
2384#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002385 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002386#endif
2387
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002388 HValue* index() { return left(); }
2389 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002390
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002391 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002392
2393 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002394 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002395};
2396
2397
2398class HBitwiseBinaryOperation: public HBinaryOperation {
2399 public:
2400 HBitwiseBinaryOperation(HValue* left, HValue* right)
2401 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002402 set_representation(Representation::Tagged());
2403 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002404 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002405 }
2406
2407 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002408 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409 }
2410
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002411 virtual void RepresentationChanged(Representation to) {
2412 if (!to.IsTagged()) {
2413 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002414 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002415 SetFlag(kTruncatingToInt32);
2416 SetFlag(kUseGVN);
2417 }
2418 }
2419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002420 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002421
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002422 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002423};
2424
2425
2426class HArithmeticBinaryOperation: public HBinaryOperation {
2427 public:
2428 HArithmeticBinaryOperation(HValue* left, HValue* right)
2429 : HBinaryOperation(left, right) {
2430 set_representation(Representation::Tagged());
2431 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002432 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002433 }
2434
2435 virtual void RepresentationChanged(Representation to) {
2436 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002437 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438 SetFlag(kUseGVN);
2439 }
2440 }
2441
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002442 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443 virtual Representation RequiredInputRepresentation(int index) const {
2444 return representation();
2445 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002446 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002447 if (left()->representation().Equals(right()->representation())) {
2448 return left()->representation();
2449 }
2450 return HValue::InferredRepresentation();
2451 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002452};
2453
2454
2455class HCompare: public HBinaryOperation {
2456 public:
2457 HCompare(HValue* left, HValue* right, Token::Value token)
2458 : HBinaryOperation(left, right), token_(token) {
2459 ASSERT(Token::IsCompareOp(token));
2460 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002461 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002462 }
2463
2464 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002465
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002466 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002467 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002468 }
2469
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002470 virtual Representation RequiredInputRepresentation(int index) const {
2471 return input_representation_;
2472 }
2473 Representation GetInputRepresentation() const {
2474 return input_representation_;
2475 }
2476 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002477 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002479 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002481 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002482 return HValue::Hashcode() * 7 + token_;
2483 }
2484
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002485 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486
2487 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002488 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002489 HCompare* comp = HCompare::cast(other);
2490 return token_ == comp->token();
2491 }
2492
2493 private:
2494 Representation input_representation_;
2495 Token::Value token_;
2496};
2497
2498
2499class HCompareJSObjectEq: public HBinaryOperation {
2500 public:
2501 HCompareJSObjectEq(HValue* left, HValue* right)
2502 : HBinaryOperation(left, right) {
2503 set_representation(Representation::Tagged());
2504 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002505 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002506 }
2507
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002508 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002509 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002510 }
2511
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002512 virtual Representation RequiredInputRepresentation(int index) const {
2513 return Representation::Tagged();
2514 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002515 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002517 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002518
2519 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002520 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521};
2522
2523
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002524class HCompareSymbolEq: public HBinaryOperation {
2525 public:
2526 HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
2527 : HBinaryOperation(left, right), op_(op) {
2528 ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
2529 set_representation(Representation::Tagged());
2530 SetFlag(kUseGVN);
2531 SetFlag(kDependsOnMaps);
2532 }
2533
2534 Token::Value op() const { return op_; }
2535
2536 virtual bool EmitAtUses() {
2537 return !HasSideEffects() && !HasMultipleUses();
2538 }
2539
2540 virtual Representation RequiredInputRepresentation(int index) const {
2541 return Representation::Tagged();
2542 }
2543
2544 virtual HType CalculateInferredType() { return HType::Boolean(); }
2545
2546 DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
2547
2548 protected:
2549 virtual bool DataEquals(HValue* other) {
2550 return op_ == HCompareSymbolEq::cast(other)->op_;
2551 }
2552
2553 private:
2554 const Token::Value op_;
2555};
2556
2557
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002558class HUnaryPredicate: public HUnaryOperation {
2559 public:
2560 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2561 set_representation(Representation::Tagged());
2562 SetFlag(kUseGVN);
2563 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002564
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002565 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002566 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002567 }
2568
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002569 virtual Representation RequiredInputRepresentation(int index) const {
2570 return Representation::Tagged();
2571 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002572 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002573};
2574
2575
2576class HIsNull: public HUnaryPredicate {
2577 public:
2578 HIsNull(HValue* value, bool is_strict)
2579 : HUnaryPredicate(value), is_strict_(is_strict) { }
2580
2581 bool is_strict() const { return is_strict_; }
2582
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002583 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002584
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002585 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002586 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002587 HIsNull* b = HIsNull::cast(other);
2588 return is_strict_ == b->is_strict();
2589 }
2590
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002591 private:
2592 bool is_strict_;
2593};
2594
2595
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002596class HIsObject: public HUnaryPredicate {
2597 public:
2598 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2599
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002600 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002601
2602 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002603 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002604};
2605
2606
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002607class HIsSmi: public HUnaryPredicate {
2608 public:
2609 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2610
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002611 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002612
2613 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002614 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002615};
2616
2617
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002618class HIsUndetectable: public HUnaryPredicate {
2619 public:
2620 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2621
2622 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2623
2624 protected:
2625 virtual bool DataEquals(HValue* other) { return true; }
2626};
2627
2628
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002629class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002630 public:
2631 HIsConstructCall() {
2632 set_representation(Representation::Tagged());
2633 SetFlag(kUseGVN);
2634 }
2635
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002636 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002637 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002638 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002639
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002640 virtual Representation RequiredInputRepresentation(int index) const {
2641 return Representation::None();
2642 }
2643
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002644 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002645
2646 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002647 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002648};
2649
2650
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002651class HHasInstanceType: public HUnaryPredicate {
2652 public:
2653 HHasInstanceType(HValue* value, InstanceType type)
2654 : HUnaryPredicate(value), from_(type), to_(type) { }
2655 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2656 : HUnaryPredicate(value), from_(from), to_(to) {
2657 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2658 }
2659
2660 InstanceType from() { return from_; }
2661 InstanceType to() { return to_; }
2662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002663 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002664
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002665 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002666
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002667 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002668 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002669 HHasInstanceType* b = HHasInstanceType::cast(other);
2670 return (from_ == b->from()) && (to_ == b->to());
2671 }
2672
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002673 private:
2674 InstanceType from_;
2675 InstanceType to_; // Inclusive range, not all combinations work.
2676};
2677
2678
2679class HHasCachedArrayIndex: public HUnaryPredicate {
2680 public:
2681 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2682
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002683 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002684
2685 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002686 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002687};
2688
2689
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002690class HGetCachedArrayIndex: public HUnaryPredicate {
2691 public:
2692 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2693
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002694 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002695
2696 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002697 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002698};
2699
2700
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002701class HClassOfTest: public HUnaryPredicate {
2702 public:
2703 HClassOfTest(HValue* value, Handle<String> class_name)
2704 : HUnaryPredicate(value), class_name_(class_name) { }
2705
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002706 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002708 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002709
2710 Handle<String> class_name() const { return class_name_; }
2711
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002712 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002713 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002714 HClassOfTest* b = HClassOfTest::cast(other);
2715 return class_name_.is_identical_to(b->class_name_);
2716 }
2717
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718 private:
2719 Handle<String> class_name_;
2720};
2721
2722
2723class HTypeofIs: public HUnaryPredicate {
2724 public:
2725 HTypeofIs(HValue* value, Handle<String> type_literal)
2726 : HUnaryPredicate(value), type_literal_(type_literal) { }
2727
2728 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002729 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002730
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002731 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002732
2733 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002734 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002735 HTypeofIs* b = HTypeofIs::cast(other);
2736 return type_literal_.is_identical_to(b->type_literal_);
2737 }
2738
2739 private:
2740 Handle<String> type_literal_;
2741};
2742
2743
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002744class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002745 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002746 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2747 SetOperandAt(0, context);
2748 SetOperandAt(1, left);
2749 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002751 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002752 }
2753
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002754 HValue* context() { return OperandAt(0); }
2755 HValue* left() { return OperandAt(1); }
2756 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002757
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002758 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002759 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002760 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002761
2762 virtual Representation RequiredInputRepresentation(int index) const {
2763 return Representation::Tagged();
2764 }
2765
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002766 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002767
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002768 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769};
2770
2771
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002772class HInstanceOfKnownGlobal: public HUnaryOperation {
2773 public:
2774 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2775 : HUnaryOperation(left), function_(right) {
2776 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002777 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002778 }
2779
2780 Handle<JSFunction> function() { return function_; }
2781
2782 virtual Representation RequiredInputRepresentation(int index) const {
2783 return Representation::Tagged();
2784 }
2785
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002786 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002787
2788 private:
2789 Handle<JSFunction> function_;
2790};
2791
2792
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002793class HPower: public HBinaryOperation {
2794 public:
2795 HPower(HValue* left, HValue* right)
2796 : HBinaryOperation(left, right) {
2797 set_representation(Representation::Double());
2798 SetFlag(kUseGVN);
2799 }
2800
2801 virtual Representation RequiredInputRepresentation(int index) const {
2802 return (index == 1) ? Representation::None() : Representation::Double();
2803 }
2804
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002805 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002806
2807 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002808 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002809};
2810
2811
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002812class HAdd: public HArithmeticBinaryOperation {
2813 public:
2814 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2815 SetFlag(kCanOverflow);
2816 }
2817
2818 // Add is only commutative if two integer values are added and not if two
2819 // tagged values are added (because it might be a String concatenation).
2820 virtual bool IsCommutative() const {
2821 return !representation().IsTagged();
2822 }
2823
2824 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002826 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002828 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002829
2830 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002831 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002832
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002833 virtual Range* InferRange();
2834};
2835
2836
2837class HSub: public HArithmeticBinaryOperation {
2838 public:
2839 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2840 SetFlag(kCanOverflow);
2841 }
2842
2843 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2844
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002845 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846
2847 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002848 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002849
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002850 virtual Range* InferRange();
2851};
2852
2853
2854class HMul: public HArithmeticBinaryOperation {
2855 public:
2856 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2857 SetFlag(kCanOverflow);
2858 }
2859
2860 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2861
2862 // Only commutative if it is certain that not two objects are multiplicated.
2863 virtual bool IsCommutative() const {
2864 return !representation().IsTagged();
2865 }
2866
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002867 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002868
2869 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002870 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002871
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002872 virtual Range* InferRange();
2873};
2874
2875
2876class HMod: public HArithmeticBinaryOperation {
2877 public:
2878 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2879 SetFlag(kCanBeDivByZero);
2880 }
2881
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002882 bool HasPowerOf2Divisor() {
2883 if (right()->IsConstant() &&
2884 HConstant::cast(right())->HasInteger32Value()) {
2885 int32_t value = HConstant::cast(right())->Integer32Value();
2886 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2887 }
2888
2889 return false;
2890 }
2891
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2893
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002894 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895
2896 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002897 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002898
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899 virtual Range* InferRange();
2900};
2901
2902
2903class HDiv: public HArithmeticBinaryOperation {
2904 public:
2905 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2906 SetFlag(kCanBeDivByZero);
2907 SetFlag(kCanOverflow);
2908 }
2909
2910 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002912 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913
2914 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002915 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002916
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917 virtual Range* InferRange();
2918};
2919
2920
2921class HBitAnd: public HBitwiseBinaryOperation {
2922 public:
2923 HBitAnd(HValue* left, HValue* right)
2924 : HBitwiseBinaryOperation(left, right) { }
2925
2926 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002927 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002929 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930
2931 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002932 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002933
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002934 virtual Range* InferRange();
2935};
2936
2937
2938class HBitXor: public HBitwiseBinaryOperation {
2939 public:
2940 HBitXor(HValue* left, HValue* right)
2941 : HBitwiseBinaryOperation(left, right) { }
2942
2943 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002944 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002946 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002947
2948 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002949 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950};
2951
2952
2953class HBitOr: public HBitwiseBinaryOperation {
2954 public:
2955 HBitOr(HValue* left, HValue* right)
2956 : HBitwiseBinaryOperation(left, right) { }
2957
2958 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002959 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002960
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002961 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002962
2963 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002964 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002965
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966 virtual Range* InferRange();
2967};
2968
2969
2970class HShl: public HBitwiseBinaryOperation {
2971 public:
2972 HShl(HValue* left, HValue* right)
2973 : HBitwiseBinaryOperation(left, right) { }
2974
2975 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002976 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002977
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002978 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002979
2980 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002981 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982};
2983
2984
2985class HShr: public HBitwiseBinaryOperation {
2986 public:
2987 HShr(HValue* left, HValue* right)
2988 : HBitwiseBinaryOperation(left, right) { }
2989
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002990 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002992 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002993
2994 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002995 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996};
2997
2998
2999class HSar: public HBitwiseBinaryOperation {
3000 public:
3001 HSar(HValue* left, HValue* right)
3002 : HBitwiseBinaryOperation(left, right) { }
3003
3004 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003005 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003006
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003007 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003008
3009 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003010 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011};
3012
3013
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015 public:
3016 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3017 SetFlag(kChangesOsrEntries);
3018 }
3019
3020 int ast_id() const { return ast_id_; }
3021
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003022 virtual Representation RequiredInputRepresentation(int index) const {
3023 return Representation::None();
3024 }
3025
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003026 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
3028 private:
3029 int ast_id_;
3030};
3031
3032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003033class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003034 public:
3035 explicit HParameter(unsigned index) : index_(index) {
3036 set_representation(Representation::Tagged());
3037 }
3038
3039 unsigned index() const { return index_; }
3040
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003041 virtual void PrintDataTo(StringStream* stream);
3042
3043 virtual Representation RequiredInputRepresentation(int index) const {
3044 return Representation::None();
3045 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003046
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003047 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003048
3049 private:
3050 unsigned index_;
3051};
3052
3053
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003054class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003055 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003056 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3057 : HUnaryCall(context, argument_count),
3058 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060 }
3061
3062 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003063
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003064 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065
3066 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3067 transcendental_type_ = transcendental_type;
3068 }
3069 TranscendentalCache::Type transcendental_type() {
3070 return transcendental_type_;
3071 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003072
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003073 virtual void PrintDataTo(StringStream* stream);
3074
3075 virtual Representation RequiredInputRepresentation(int index) const {
3076 return Representation::Tagged();
3077 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003079 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080
3081 private:
3082 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003083 TranscendentalCache::Type transcendental_type_;
3084};
3085
3086
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003087class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003088 public:
3089 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3090
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003091 virtual Representation RequiredInputRepresentation(int index) const {
3092 return Representation::None();
3093 }
3094
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003095 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003096};
3097
3098
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003099class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003100 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003101 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102 : cell_(cell), check_hole_value_(check_hole_value) {
3103 set_representation(Representation::Tagged());
3104 SetFlag(kUseGVN);
3105 SetFlag(kDependsOnGlobalVars);
3106 }
3107
3108 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3109 bool check_hole_value() const { return check_hole_value_; }
3110
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003111 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003113 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003114 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115 return reinterpret_cast<intptr_t>(*cell_);
3116 }
3117
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003118 virtual Representation RequiredInputRepresentation(int index) const {
3119 return Representation::None();
3120 }
3121
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003122 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123
3124 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003125 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003126 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127 return cell_.is_identical_to(b->cell());
3128 }
3129
3130 private:
3131 Handle<JSGlobalPropertyCell> cell_;
3132 bool check_hole_value_;
3133};
3134
3135
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003136class HLoadGlobalGeneric: public HBinaryOperation {
3137 public:
3138 HLoadGlobalGeneric(HValue* context,
3139 HValue* global_object,
3140 Handle<Object> name,
3141 bool for_typeof)
3142 : HBinaryOperation(context, global_object),
3143 name_(name),
3144 for_typeof_(for_typeof) {
3145 set_representation(Representation::Tagged());
3146 SetAllSideEffects();
3147 }
3148
3149 HValue* context() { return OperandAt(0); }
3150 HValue* global_object() { return OperandAt(1); }
3151 Handle<Object> name() const { return name_; }
3152 bool for_typeof() const { return for_typeof_; }
3153
3154 virtual void PrintDataTo(StringStream* stream);
3155
3156 virtual Representation RequiredInputRepresentation(int index) const {
3157 return Representation::Tagged();
3158 }
3159
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003160 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003161
3162 private:
3163 Handle<Object> name_;
3164 bool for_typeof_;
3165};
3166
3167
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003168class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003169 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003170 HStoreGlobalCell(HValue* value,
3171 Handle<JSGlobalPropertyCell> cell,
3172 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003173 : HUnaryOperation(value),
3174 cell_(cell),
3175 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 SetFlag(kChangesGlobalVars);
3177 }
3178
3179 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003180 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003181
3182 virtual Representation RequiredInputRepresentation(int index) const {
3183 return Representation::Tagged();
3184 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003185 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003187 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003189 private:
3190 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003191 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003192};
3193
3194
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003195class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3196 public:
3197 HStoreGlobalGeneric(HValue* context,
3198 HValue* global_object,
3199 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003200 HValue* value,
3201 bool strict_mode)
3202 : name_(name),
3203 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003204 SetOperandAt(0, context);
3205 SetOperandAt(1, global_object);
3206 SetOperandAt(2, value);
3207 set_representation(Representation::Tagged());
3208 SetAllSideEffects();
3209 }
3210
3211 HValue* context() { return OperandAt(0); }
3212 HValue* global_object() { return OperandAt(1); }
3213 Handle<Object> name() const { return name_; }
3214 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003215 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003216
3217 virtual void PrintDataTo(StringStream* stream);
3218
3219 virtual Representation RequiredInputRepresentation(int index) const {
3220 return Representation::Tagged();
3221 }
3222
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003223 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003224
3225 private:
3226 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003227 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003228};
3229
3230
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003231class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003232 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003233 HLoadContextSlot(HValue* context , int slot_index)
3234 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003235 set_representation(Representation::Tagged());
3236 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003237 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003238 }
3239
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003240 int slot_index() const { return slot_index_; }
3241
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003242 virtual Representation RequiredInputRepresentation(int index) const {
3243 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003244 }
3245
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003246 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003247
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003248 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003249
3250 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003251 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003252 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003253 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003254 }
3255
3256 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003257 int slot_index_;
3258};
3259
3260
3261static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3262 return !value->type().IsSmi() &&
3263 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3264}
3265
3266
3267class HStoreContextSlot: public HBinaryOperation {
3268 public:
3269 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3270 : HBinaryOperation(context, value), slot_index_(slot_index) {
3271 SetFlag(kChangesContextSlots);
3272 }
3273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003274 HValue* context() { return OperandAt(0); }
3275 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003276 int slot_index() const { return slot_index_; }
3277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003278 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003279 return StoringValueNeedsWriteBarrier(value());
3280 }
3281
3282 virtual Representation RequiredInputRepresentation(int index) const {
3283 return Representation::Tagged();
3284 }
3285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003286 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003287
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003288 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003289
3290 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003291 int slot_index_;
3292};
3293
3294
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003295class HLoadNamedField: public HUnaryOperation {
3296 public:
3297 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3298 : HUnaryOperation(object),
3299 is_in_object_(is_in_object),
3300 offset_(offset) {
3301 set_representation(Representation::Tagged());
3302 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003303 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003304 if (is_in_object) {
3305 SetFlag(kDependsOnInobjectFields);
3306 } else {
3307 SetFlag(kDependsOnBackingStoreFields);
3308 }
3309 }
3310
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003311 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003312 bool is_in_object() const { return is_in_object_; }
3313 int offset() const { return offset_; }
3314
3315 virtual Representation RequiredInputRepresentation(int index) const {
3316 return Representation::Tagged();
3317 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003318 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003320 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003321
3322 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003323 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003324 HLoadNamedField* b = HLoadNamedField::cast(other);
3325 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3326 }
3327
3328 private:
3329 bool is_in_object_;
3330 int offset_;
3331};
3332
3333
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003334class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3335 public:
3336 HLoadNamedFieldPolymorphic(HValue* object,
3337 ZoneMapList* types,
3338 Handle<String> name);
3339
3340 HValue* object() { return OperandAt(0); }
3341 ZoneMapList* types() { return &types_; }
3342 Handle<String> name() { return name_; }
3343 bool need_generic() { return need_generic_; }
3344
3345 virtual Representation RequiredInputRepresentation(int index) const {
3346 return Representation::Tagged();
3347 }
3348
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003349 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003350
3351 static const int kMaxLoadPolymorphism = 4;
3352
3353 protected:
3354 virtual bool DataEquals(HValue* value);
3355
3356 private:
3357 ZoneMapList types_;
3358 Handle<String> name_;
3359 bool need_generic_;
3360};
3361
3362
3363
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003364class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003365 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003366 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3367 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003368 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003369 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003370 }
3371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003372 HValue* context() { return OperandAt(0); }
3373 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003374 Handle<Object> name() const { return name_; }
3375
3376 virtual Representation RequiredInputRepresentation(int index) const {
3377 return Representation::Tagged();
3378 }
3379
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003380 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003381
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003382 private:
3383 Handle<Object> name_;
3384};
3385
3386
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003387class HLoadFunctionPrototype: public HUnaryOperation {
3388 public:
3389 explicit HLoadFunctionPrototype(HValue* function)
3390 : HUnaryOperation(function) {
3391 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003392 SetFlag(kUseGVN);
3393 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003394 }
3395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003396 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003397
3398 virtual Representation RequiredInputRepresentation(int index) const {
3399 return Representation::Tagged();
3400 }
3401
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003402 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003403
3404 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003405 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003406};
3407
3408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003409class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003410 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003411 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003412 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003413 SetFlag(kDependsOnArrayElements);
3414 SetFlag(kUseGVN);
3415 }
3416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003417 HValue* object() { return OperandAt(0); }
3418 HValue* key() { return OperandAt(1); }
3419
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003420 virtual Representation RequiredInputRepresentation(int index) const {
3421 // The key is supposed to be Integer32.
3422 return (index == 1) ? Representation::Integer32()
3423 : Representation::Tagged();
3424 }
3425
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003426 virtual void PrintDataTo(StringStream* stream);
3427
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003428 bool RequiresHoleCheck() const;
3429
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003430 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003431
3432 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003433 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003434};
3435
3436
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003437class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003438 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003439 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3440 HValue* key,
3441 ExternalArrayType array_type)
3442 : HBinaryOperation(external_elements, key),
3443 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003444 if (array_type == kExternalFloatArray ||
3445 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003446 set_representation(Representation::Double());
3447 } else {
3448 set_representation(Representation::Integer32());
3449 }
3450 SetFlag(kDependsOnSpecializedArrayElements);
3451 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003452 SetFlag(kDependsOnCalls);
3453 SetFlag(kUseGVN);
3454 }
3455
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003456 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003457
3458 virtual Representation RequiredInputRepresentation(int index) const {
3459 // The key is supposed to be Integer32, but the base pointer
3460 // for the element load is a naked pointer.
3461 return (index == 1) ? Representation::Integer32()
3462 : Representation::External();
3463 }
3464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003465 HValue* external_pointer() { return OperandAt(0); }
3466 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003467 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003468
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003469 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003470
3471 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003472 virtual bool DataEquals(HValue* other) {
3473 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3474 HLoadKeyedSpecializedArrayElement* cast_other =
3475 HLoadKeyedSpecializedArrayElement::cast(other);
3476 return array_type_ == cast_other->array_type();
3477 }
3478
3479 private:
3480 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003481};
3482
3483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003484class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003485 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003486 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 set_representation(Representation::Tagged());
3488 SetOperandAt(0, obj);
3489 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003490 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003491 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003492 }
3493
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003494 HValue* object() { return OperandAt(0); }
3495 HValue* key() { return OperandAt(1); }
3496 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003497
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003498 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003499
3500 virtual Representation RequiredInputRepresentation(int index) const {
3501 return Representation::Tagged();
3502 }
3503
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003504 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003505};
3506
3507
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003508class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509 public:
3510 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003511 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003512 HValue* val,
3513 bool in_object,
3514 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003515 : HBinaryOperation(obj, val),
3516 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003517 is_in_object_(in_object),
3518 offset_(offset) {
3519 if (is_in_object_) {
3520 SetFlag(kChangesInobjectFields);
3521 } else {
3522 SetFlag(kChangesBackingStoreFields);
3523 }
3524 }
3525
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003526 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003527
3528 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003529 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003530 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003531 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003532
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003533 HValue* object() { return OperandAt(0); }
3534 HValue* value() { return OperandAt(1); }
3535
3536 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003537 bool is_in_object() const { return is_in_object_; }
3538 int offset() const { return offset_; }
3539 Handle<Map> transition() const { return transition_; }
3540 void set_transition(Handle<Map> map) { transition_ = map; }
3541
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003542 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003543 return StoringValueNeedsWriteBarrier(value());
3544 }
3545
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003546 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003547 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003548 bool is_in_object_;
3549 int offset_;
3550 Handle<Map> transition_;
3551};
3552
3553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003554class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003555 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003556 HStoreNamedGeneric(HValue* context,
3557 HValue* object,
3558 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003559 HValue* value,
3560 bool strict_mode)
3561 : name_(name),
3562 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003563 SetOperandAt(0, object);
3564 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003565 SetOperandAt(2, 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* value() { return OperandAt(1); }
3571 HValue* context() { return OperandAt(2); }
3572 Handle<String> name() { return name_; }
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 void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003576
3577 virtual Representation RequiredInputRepresentation(int index) const {
3578 return Representation::Tagged();
3579 }
3580
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003581 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003582
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003583 private:
3584 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003585 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003586};
3587
3588
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003589class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003590 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003591 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3592 SetOperandAt(0, obj);
3593 SetOperandAt(1, key);
3594 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003595 SetFlag(kChangesArrayElements);
3596 }
3597
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003598 virtual Representation RequiredInputRepresentation(int index) const {
3599 // The key is supposed to be Integer32.
3600 return (index == 1) ? Representation::Integer32()
3601 : Representation::Tagged();
3602 }
3603
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003604 HValue* object() { return OperandAt(0); }
3605 HValue* key() { return OperandAt(1); }
3606 HValue* value() { return OperandAt(2); }
3607
3608 bool NeedsWriteBarrier() {
3609 return StoringValueNeedsWriteBarrier(value());
3610 }
3611
3612 virtual void PrintDataTo(StringStream* stream);
3613
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003614 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003615};
3616
3617
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003618class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003619 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003620 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3621 HValue* key,
3622 HValue* val,
3623 ExternalArrayType array_type)
3624 : array_type_(array_type) {
3625 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003626 SetOperandAt(0, external_elements);
3627 SetOperandAt(1, key);
3628 SetOperandAt(2, val);
3629 }
3630
3631 virtual void PrintDataTo(StringStream* stream);
3632
3633 virtual Representation RequiredInputRepresentation(int index) const {
3634 if (index == 0) {
3635 return Representation::External();
3636 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003637 if (index == 2 && (array_type() == kExternalFloatArray ||
3638 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003639 return Representation::Double();
3640 } else {
3641 return Representation::Integer32();
3642 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003643 }
3644 }
3645
3646 HValue* external_pointer() { return OperandAt(0); }
3647 HValue* key() { return OperandAt(1); }
3648 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003649 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003650
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003651 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3652
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003653 private:
3654 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003655};
3656
3657
3658class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003659 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003660 HStoreKeyedGeneric(HValue* context,
3661 HValue* object,
3662 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003663 HValue* value,
3664 bool strict_mode)
3665 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003666 SetOperandAt(0, object);
3667 SetOperandAt(1, key);
3668 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003669 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003670 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003671 }
3672
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003673 HValue* object() { return OperandAt(0); }
3674 HValue* key() { return OperandAt(1); }
3675 HValue* value() { return OperandAt(2); }
3676 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003677 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003678
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003679 virtual Representation RequiredInputRepresentation(int index) const {
3680 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003681 }
3682
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003683 virtual void PrintDataTo(StringStream* stream);
3684
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003685 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003686
3687 private:
3688 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003689};
3690
3691
danno@chromium.org160a7b02011-04-18 15:51:38 +00003692class HStringAdd: public HBinaryOperation {
3693 public:
3694 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3695 set_representation(Representation::Tagged());
3696 SetFlag(kUseGVN);
3697 SetFlag(kDependsOnMaps);
3698 }
3699
3700 virtual Representation RequiredInputRepresentation(int index) const {
3701 return Representation::Tagged();
3702 }
3703
3704 virtual HType CalculateInferredType() {
3705 return HType::String();
3706 }
3707
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003708 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003709
3710 protected:
3711 virtual bool DataEquals(HValue* other) { return true; }
3712};
3713
3714
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003715class HStringCharCodeAt: public HBinaryOperation {
3716 public:
3717 HStringCharCodeAt(HValue* string, HValue* index)
3718 : HBinaryOperation(string, index) {
3719 set_representation(Representation::Integer32());
3720 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003721 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003722 }
3723
3724 virtual Representation RequiredInputRepresentation(int index) const {
3725 // The index is supposed to be Integer32.
3726 return (index == 1) ? Representation::Integer32()
3727 : Representation::Tagged();
3728 }
3729
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003730 HValue* string() { return OperandAt(0); }
3731 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003732
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003733 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003734
3735 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003736 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003737
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003738 virtual Range* InferRange() {
3739 return new Range(0, String::kMaxUC16CharCode);
3740 }
3741};
3742
3743
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003744class HStringCharFromCode: public HUnaryOperation {
3745 public:
3746 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3747 set_representation(Representation::Tagged());
3748 SetFlag(kUseGVN);
3749 }
3750
3751 virtual Representation RequiredInputRepresentation(int index) const {
3752 return Representation::Integer32();
3753 }
3754
3755 virtual bool DataEquals(HValue* other) { return true; }
3756
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003757 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003758};
3759
3760
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003761class HStringLength: public HUnaryOperation {
3762 public:
3763 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3764 set_representation(Representation::Tagged());
3765 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003766 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003767 }
3768
3769 virtual Representation RequiredInputRepresentation(int index) const {
3770 return Representation::Tagged();
3771 }
3772
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003773 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003774 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3775 return HType::Smi();
3776 }
3777
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003778 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003779
3780 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003781 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003782
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003783 virtual Range* InferRange() {
3784 return new Range(0, String::kMaxLength);
3785 }
3786};
3787
3788
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003789template <int V>
3790class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003791 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003792 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003793 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003794 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003795 }
3796
3797 int literal_index() const { return literal_index_; }
3798 int depth() const { return depth_; }
3799
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800 private:
3801 int literal_index_;
3802 int depth_;
3803};
3804
3805
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003806class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003807 public:
3808 HArrayLiteral(Handle<FixedArray> constant_elements,
3809 int length,
3810 int literal_index,
3811 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003812 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003813 length_(length),
3814 constant_elements_(constant_elements) {}
3815
3816 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3817 int length() const { return length_; }
3818
3819 bool IsCopyOnWrite() const;
3820
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003821 virtual Representation RequiredInputRepresentation(int index) const {
3822 return Representation::None();
3823 }
3824
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003825 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003826
3827 private:
3828 int length_;
3829 Handle<FixedArray> constant_elements_;
3830};
3831
3832
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003833class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003834 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003835 HObjectLiteral(HValue* context,
3836 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003837 bool fast_elements,
3838 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003839 int depth,
3840 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003841 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003842 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003843 fast_elements_(fast_elements),
3844 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003845 SetOperandAt(0, context);
3846 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003847
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003848 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003849 Handle<FixedArray> constant_properties() const {
3850 return constant_properties_;
3851 }
3852 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003853 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003854
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003855 virtual Representation RequiredInputRepresentation(int index) const {
3856 return Representation::Tagged();
3857 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003858
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003859 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003860
3861 private:
3862 Handle<FixedArray> constant_properties_;
3863 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003864 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003865};
3866
3867
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003868class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003869 public:
3870 HRegExpLiteral(Handle<String> pattern,
3871 Handle<String> flags,
3872 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003873 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003874 pattern_(pattern),
3875 flags_(flags) { }
3876
3877 Handle<String> pattern() { return pattern_; }
3878 Handle<String> flags() { return flags_; }
3879
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003880 virtual Representation RequiredInputRepresentation(int index) const {
3881 return Representation::None();
3882 }
3883
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003884 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003885
3886 private:
3887 Handle<String> pattern_;
3888 Handle<String> flags_;
3889};
3890
3891
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003892class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003893 public:
3894 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3895 : shared_info_(shared), pretenure_(pretenure) {
3896 set_representation(Representation::Tagged());
3897 }
3898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003899 virtual Representation RequiredInputRepresentation(int index) const {
3900 return Representation::None();
3901 }
3902
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003903 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003904
3905 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3906 bool pretenure() const { return pretenure_; }
3907
3908 private:
3909 Handle<SharedFunctionInfo> shared_info_;
3910 bool pretenure_;
3911};
3912
3913
3914class HTypeof: public HUnaryOperation {
3915 public:
3916 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3917 set_representation(Representation::Tagged());
3918 }
3919
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003920 virtual Representation RequiredInputRepresentation(int index) const {
3921 return Representation::Tagged();
3922 }
3923
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003924 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003925};
3926
3927
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003928class HToFastProperties: public HUnaryOperation {
3929 public:
3930 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3931 // This instruction is not marked as having side effects, but
3932 // changes the map of the input operand. Use it only when creating
3933 // object literals.
3934 ASSERT(value->IsObjectLiteral());
3935 set_representation(Representation::Tagged());
3936 }
3937
3938 virtual Representation RequiredInputRepresentation(int index) const {
3939 return Representation::Tagged();
3940 }
3941
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003942 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003943};
3944
3945
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003946class HValueOf: public HUnaryOperation {
3947 public:
3948 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3949 set_representation(Representation::Tagged());
3950 }
3951
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003952 virtual Representation RequiredInputRepresentation(int index) const {
3953 return Representation::Tagged();
3954 }
3955
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003956 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003957};
3958
3959
3960class HDeleteProperty: public HBinaryOperation {
3961 public:
3962 HDeleteProperty(HValue* obj, HValue* key)
3963 : HBinaryOperation(obj, key) {
3964 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003965 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003966 }
3967
3968 virtual Representation RequiredInputRepresentation(int index) const {
3969 return Representation::Tagged();
3970 }
3971
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003972 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003973
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003974 HValue* object() { return left(); }
3975 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003976};
3977
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003978
3979class HIn: public HTemplateInstruction<2> {
3980 public:
3981 HIn(HValue* key, HValue* object) {
3982 SetOperandAt(0, key);
3983 SetOperandAt(1, object);
3984 set_representation(Representation::Tagged());
3985 SetAllSideEffects();
3986 }
3987
3988 HValue* key() { return OperandAt(0); }
3989 HValue* object() { return OperandAt(1); }
3990
3991 virtual Representation RequiredInputRepresentation(int index) const {
3992 return Representation::Tagged();
3993 }
3994
3995 virtual HType CalculateInferredType() {
3996 return HType::Boolean();
3997 }
3998
3999 virtual void PrintDataTo(StringStream* stream);
4000
4001 DECLARE_CONCRETE_INSTRUCTION(In)
4002};
4003
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004004#undef DECLARE_INSTRUCTION
4005#undef DECLARE_CONCRETE_INSTRUCTION
4006
4007} } // namespace v8::internal
4008
4009#endif // V8_HYDROGEN_INSTRUCTIONS_H_