blob: 561dbc1d0f826cac6b63ab556f60b84fd9146b49 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "code-stubs.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000034#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "string-stream.h"
36#include "zone.h"
37
38namespace v8 {
39namespace internal {
40
41// Forward declarations.
42class HBasicBlock;
43class HEnvironment;
44class HInstruction;
45class HLoopInformation;
46class HValue;
47class LInstruction;
48class LChunkBuilder;
49
50
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000051#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000052 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000053 V(ControlInstruction) \
54 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055
56
57#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000058 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059 V(AccessArgumentsAt) \
60 V(Add) \
61 V(ApplyArguments) \
62 V(ArgumentsElements) \
63 V(ArgumentsLength) \
64 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065 V(ArrayLiteral) \
66 V(BitAnd) \
67 V(BitNot) \
68 V(BitOr) \
69 V(BitXor) \
70 V(BlockEntry) \
71 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000072 V(CallConstantFunction) \
73 V(CallFunction) \
74 V(CallGlobal) \
75 V(CallKeyed) \
76 V(CallKnownGlobal) \
77 V(CallNamed) \
78 V(CallNew) \
79 V(CallRuntime) \
80 V(CallStub) \
81 V(Change) \
82 V(CheckFunction) \
83 V(CheckInstanceType) \
84 V(CheckMap) \
85 V(CheckNonSmi) \
86 V(CheckPrototypeMaps) \
87 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000088 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000089 V(Compare) \
90 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000091 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000092 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000093 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000094 V(DeleteProperty) \
95 V(Deoptimize) \
96 V(Div) \
97 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000098 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +000099 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000101 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(GlobalObject) \
103 V(GlobalReceiver) \
104 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000105 V(HasInstanceType) \
106 V(HasCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000107 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000108 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000109 V(InvokeFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000111 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000113 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000114 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000116 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000118 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000119 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000120 V(LoadGlobalCell) \
121 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LoadKeyedFastElement) \
123 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000124 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000126 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LoadNamedGeneric) \
128 V(Mod) \
129 V(Mul) \
130 V(ObjectLiteral) \
131 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000132 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000133 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000134 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(PushArgument) \
136 V(RegExpLiteral) \
137 V(Return) \
138 V(Sar) \
139 V(Shl) \
140 V(Shr) \
141 V(Simulate) \
142 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000143 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000144 V(StoreGlobalCell) \
145 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000146 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000147 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000148 V(StoreKeyedGeneric) \
149 V(StoreNamedField) \
150 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000151 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000152 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000153 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000154 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000156 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000158 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159 V(Typeof) \
160 V(TypeofIs) \
161 V(UnaryMathOperation) \
162 V(UnknownOSRValue) \
163 V(ValueOf)
164
165#define GVN_FLAG_LIST(V) \
166 V(Calls) \
167 V(InobjectFields) \
168 V(BackingStoreFields) \
169 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000170 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000171 V(GlobalVars) \
172 V(Maps) \
173 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000174 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(OsrEntries)
176
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000177#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178 virtual bool Is##type() const { return true; } \
179 static H##type* cast(HValue* value) { \
180 ASSERT(value->Is##type()); \
181 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000182 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000183
184
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000185#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000186 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000187 static H##type* cast(HValue* value) { \
188 ASSERT(value->Is##type()); \
189 return reinterpret_cast<H##type*>(value); \
190 } \
191 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192
193
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000194class Range: public ZoneObject {
195 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000196 Range()
197 : lower_(kMinInt),
198 upper_(kMaxInt),
199 next_(NULL),
200 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201
202 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000203 : lower_(lower),
204 upper_(upper),
205 next_(NULL),
206 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000208 int32_t upper() const { return upper_; }
209 int32_t lower() const { return lower_; }
210 Range* next() const { return next_; }
211 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
212 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214 int32_t Mask() const;
215 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
216 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
217 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
218 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000219 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
220 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
221 bool IsInSmiRange() const {
222 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000223 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000224 void KeepOrder();
225 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000226
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227 void StackUpon(Range* other) {
228 Intersect(other);
229 next_ = other;
230 }
231
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000232 void Intersect(Range* other);
233 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000234
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000235 void AddConstant(int32_t value);
236 void Sar(int32_t value);
237 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238 bool AddAndCheckOverflow(Range* other);
239 bool SubAndCheckOverflow(Range* other);
240 bool MulAndCheckOverflow(Range* other);
241
242 private:
243 int32_t lower_;
244 int32_t upper_;
245 Range* next_;
246 bool can_be_minus_zero_;
247};
248
249
250class Representation {
251 public:
252 enum Kind {
253 kNone,
254 kTagged,
255 kDouble,
256 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000257 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000258 kNumRepresentations
259 };
260
261 Representation() : kind_(kNone) { }
262
263 static Representation None() { return Representation(kNone); }
264 static Representation Tagged() { return Representation(kTagged); }
265 static Representation Integer32() { return Representation(kInteger32); }
266 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000267 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000269 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000270 return kind_ == other.kind_;
271 }
272
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000273 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000274 bool IsNone() const { return kind_ == kNone; }
275 bool IsTagged() const { return kind_ == kTagged; }
276 bool IsInteger32() const { return kind_ == kInteger32; }
277 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000278 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000279 bool IsSpecialization() const {
280 return kind_ == kInteger32 || kind_ == kDouble;
281 }
282 const char* Mnemonic() const;
283
284 private:
285 explicit Representation(Kind k) : kind_(k) { }
286
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000287 // Make sure kind fits in int8.
288 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
289
290 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291};
292
293
294class HType {
295 public:
296 HType() : type_(kUninitialized) { }
297
298 static HType Tagged() { return HType(kTagged); }
299 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
300 static HType TaggedNumber() { return HType(kTaggedNumber); }
301 static HType Smi() { return HType(kSmi); }
302 static HType HeapNumber() { return HType(kHeapNumber); }
303 static HType String() { return HType(kString); }
304 static HType Boolean() { return HType(kBoolean); }
305 static HType NonPrimitive() { return HType(kNonPrimitive); }
306 static HType JSArray() { return HType(kJSArray); }
307 static HType JSObject() { return HType(kJSObject); }
308 static HType Uninitialized() { return HType(kUninitialized); }
309
310 // Return the weakest (least precise) common type.
311 HType Combine(HType other) {
312 return HType(static_cast<Type>(type_ & other.type_));
313 }
314
315 bool Equals(const HType& other) {
316 return type_ == other.type_;
317 }
318
319 bool IsSubtypeOf(const HType& other) {
320 return Combine(other).Equals(other);
321 }
322
323 bool IsTagged() {
324 ASSERT(type_ != kUninitialized);
325 return ((type_ & kTagged) == kTagged);
326 }
327
328 bool IsTaggedPrimitive() {
329 ASSERT(type_ != kUninitialized);
330 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
331 }
332
333 bool IsTaggedNumber() {
334 ASSERT(type_ != kUninitialized);
335 return ((type_ & kTaggedNumber) == kTaggedNumber);
336 }
337
338 bool IsSmi() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kSmi) == kSmi);
341 }
342
343 bool IsHeapNumber() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kHeapNumber) == kHeapNumber);
346 }
347
348 bool IsString() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kString) == kString);
351 }
352
353 bool IsBoolean() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kBoolean) == kBoolean);
356 }
357
358 bool IsNonPrimitive() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kNonPrimitive) == kNonPrimitive);
361 }
362
363 bool IsJSArray() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kJSArray) == kJSArray);
366 }
367
368 bool IsJSObject() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kJSObject) == kJSObject);
371 }
372
373 bool IsUninitialized() {
374 return type_ == kUninitialized;
375 }
376
377 static HType TypeFromValue(Handle<Object> value);
378
379 const char* ToString();
380 const char* ToShortString();
381
382 private:
383 enum Type {
384 kTagged = 0x1, // 0000 0000 0000 0001
385 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
386 kTaggedNumber = 0xd, // 0000 0000 0000 1101
387 kSmi = 0x1d, // 0000 0000 0001 1101
388 kHeapNumber = 0x2d, // 0000 0000 0010 1101
389 kString = 0x45, // 0000 0000 0100 0101
390 kBoolean = 0x85, // 0000 0000 1000 0101
391 kNonPrimitive = 0x101, // 0000 0001 0000 0001
392 kJSObject = 0x301, // 0000 0011 0000 0001
393 kJSArray = 0x701, // 0000 0111 1000 0001
394 kUninitialized = 0x1fff // 0001 1111 1111 1111
395 };
396
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000397 // Make sure type fits in int16.
398 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
399
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000400 explicit HType(Type t) : type_(t) { }
401
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000402 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000403};
404
405
406class HValue: public ZoneObject {
407 public:
408 static const int kNoNumber = -1;
409
410 // There must be one corresponding kDepends flag for every kChanges flag and
411 // the order of the kChanges flags must be exactly the same as of the kDepends
412 // flags.
413 enum Flag {
414 // Declare global value numbering flags.
415 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
416 GVN_FLAG_LIST(DECLARE_DO)
417 #undef DECLARE_DO
418 kFlexibleRepresentation,
419 kUseGVN,
420 kCanOverflow,
421 kBailoutOnMinusZero,
422 kCanBeDivByZero,
423 kIsArguments,
424 kTruncatingToInt32,
425 kLastFlag = kTruncatingToInt32
426 };
427
428 STATIC_ASSERT(kLastFlag < kBitsPerInt);
429
430 static const int kChangesToDependsFlagsLeftShift = 1;
431
432 static int ChangesFlagsMask() {
433 int result = 0;
434 // Create changes mask.
435#define DECLARE_DO(type) result |= (1 << kChanges##type);
436 GVN_FLAG_LIST(DECLARE_DO)
437#undef DECLARE_DO
438 return result;
439 }
440
441 static int DependsFlagsMask() {
442 return ConvertChangesToDependsFlags(ChangesFlagsMask());
443 }
444
445 static int ConvertChangesToDependsFlags(int flags) {
446 return flags << kChangesToDependsFlagsLeftShift;
447 }
448
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000449 static HValue* cast(HValue* value) { return value; }
450
451 enum Opcode {
452 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000453 #define DECLARE_OPCODE(type) k##type,
454 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
455 kPhi
456 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000457 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000458 virtual Opcode opcode() const = 0;
459
460 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
461 #define DECLARE_PREDICATE(type) \
462 bool Is##type() const { return opcode() == k##type; }
463 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
464 #undef DECLARE_PREDICATE
465 bool IsPhi() const { return opcode() == kPhi; }
466
467 // Declare virtual predicates for abstract HInstruction or HValue
468 #define DECLARE_PREDICATE(type) \
469 virtual bool Is##type() const { return false; }
470 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
471 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000472
473 HValue() : block_(NULL),
474 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000475 type_(HType::Tagged()),
476 range_(NULL),
477 flags_(0) {}
478 virtual ~HValue() {}
479
480 HBasicBlock* block() const { return block_; }
481 void SetBlock(HBasicBlock* block);
482
483 int id() const { return id_; }
484 void set_id(int id) { id_ = id; }
485
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000486 SmallPointerList<HValue>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000487
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000488 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000489 Representation representation() const { return representation_; }
490 void ChangeRepresentation(Representation r) {
491 // Representation was already set and is allowed to be changed.
492 ASSERT(!representation_.IsNone());
493 ASSERT(!r.IsNone());
494 ASSERT(CheckFlag(kFlexibleRepresentation));
495 RepresentationChanged(r);
496 representation_ = r;
497 }
498
499 HType type() const { return type_; }
500 void set_type(HType type) {
501 ASSERT(uses_.length() == 0);
502 type_ = type;
503 }
504
505 // An operation needs to override this function iff:
506 // 1) it can produce an int32 output.
507 // 2) the true value of its output can potentially be minus zero.
508 // The implementation must set a flag so that it bails out in the case where
509 // it would otherwise output what should be a minus zero as an int32 zero.
510 // If the operation also exists in a form that takes int32 and outputs int32
511 // then the operation should return its input value so that we can propagate
512 // back. There are two operations that need to propagate back to more than
513 // one input. They are phi and binary add. They always return NULL and
514 // expect the caller to take care of things.
515 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
516 visited->Add(id());
517 return NULL;
518 }
519
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000520 bool IsDefinedAfter(HBasicBlock* other) const;
521
522 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000523 virtual int OperandCount() = 0;
524 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000525 void SetOperandAt(int index, HValue* value);
526
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000527 int LookupOperandIndex(int occurrence_index, HValue* op);
528 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000529
530 void ReplaceAndDelete(HValue* other);
531 void ReplaceValue(HValue* other);
532 void ReplaceAtUse(HValue* use, HValue* other);
533 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
534 bool HasNoUses() const { return uses_.is_empty(); }
535 void ClearOperands();
536 void Delete();
537
538 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000539 void SetFlag(Flag f) { flags_ |= (1 << f); }
540 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
541 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
542
543 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
544 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
545 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000546
547 Range* range() const { return range_; }
548 bool HasRange() const { return range_ != NULL; }
549 void AddNewRange(Range* r);
550 void RemoveLastAddedRange();
551 void ComputeInitialRange();
552
553 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000554 virtual Representation RequiredInputRepresentation(int index) const = 0;
555
556 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557 return representation();
558 }
559
560 // This gives the instruction an opportunity to replace itself with an
561 // instruction that does the same in some better way. To replace an
562 // instruction with a new one, first add the new instruction to the graph,
563 // then return it. Return NULL to have the instruction deleted.
564 virtual HValue* Canonicalize() { return this; }
565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000566 bool Equals(HValue* other);
567 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568
569 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000570 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571 void PrintNameTo(StringStream* stream);
572 static void PrintTypeTo(HType type, StringStream* stream);
573
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000574 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000575
576 // Updated the inferred type of this instruction and returns true if
577 // it has changed.
578 bool UpdateInferredType();
579
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000580 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000583 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000584#endif
585
586 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000587 // This function must be overridden for instructions with flag kUseGVN, to
588 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000589 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000590 UNREACHABLE();
591 return false;
592 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000593 virtual void RepresentationChanged(Representation to) { }
594 virtual Range* InferRange();
595 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000596 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000597 void clear_block() {
598 ASSERT(block_ != NULL);
599 block_ = NULL;
600 }
601
602 void set_representation(Representation r) {
603 // Representation is set-once.
604 ASSERT(representation_.IsNone() && !r.IsNone());
605 representation_ = r;
606 }
607
608 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000609 // A flag mask to mark an instruction as having arbitrary side effects.
610 static int AllSideEffects() {
611 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
612 }
613
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000614 void InternalReplaceAtUse(HValue* use, HValue* other);
615 void RegisterUse(int index, HValue* new_value);
616
617 HBasicBlock* block_;
618
619 // The id of this instruction in the hydrogen graph, assigned when first
620 // added to the graph. Reflects creation order.
621 int id_;
622
623 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000624 HType type_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000625 SmallPointerList<HValue> uses_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000626 Range* range_;
627 int flags_;
628
629 DISALLOW_COPY_AND_ASSIGN(HValue);
630};
631
632
633class HInstruction: public HValue {
634 public:
635 HInstruction* next() const { return next_; }
636 HInstruction* previous() const { return previous_; }
637
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000638 virtual void PrintTo(StringStream* stream);
639 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000640
641 bool IsLinked() const { return block() != NULL; }
642 void Unlink();
643 void InsertBefore(HInstruction* next);
644 void InsertAfter(HInstruction* previous);
645
646 int position() const { return position_; }
647 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
648 void set_position(int position) { position_ = position; }
649
650 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
651
652#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000653 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654#endif
655
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000656 // Returns whether this is some kind of deoptimizing check
657 // instruction.
658 virtual bool IsCheckInstruction() const { return false; }
659
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000660 virtual bool IsCall() { return false; }
661
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000662 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663
664 protected:
665 HInstruction()
666 : next_(NULL),
667 previous_(NULL),
668 position_(RelocInfo::kNoPosition) {
669 SetFlag(kDependsOnOsrEntries);
670 }
671
672 virtual void DeleteFromGraph() { Unlink(); }
673
674 private:
675 void InitializeAsFirst(HBasicBlock* block) {
676 ASSERT(!IsLinked());
677 SetBlock(block);
678 }
679
680 HInstruction* next_;
681 HInstruction* previous_;
682 int position_;
683
684 friend class HBasicBlock;
685};
686
687
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688class HControlInstruction: public HInstruction {
689 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000690 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
691 : first_successor_(first), second_successor_(second) {
692 }
693
694 HBasicBlock* FirstSuccessor() const { return first_successor_; }
695 HBasicBlock* SecondSuccessor() const { return second_successor_; }
696
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000697 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000698
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000699 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000700
701 private:
702 HBasicBlock* first_successor_;
703 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000704};
705
706
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000707template<int NumElements>
708class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000709 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000710 HOperandContainer() : elems_() { }
711
712 int length() { return NumElements; }
713 HValue*& operator[](int i) {
714 ASSERT(i < length());
715 return elems_[i];
716 }
717
718 private:
719 HValue* elems_[NumElements];
720};
721
722
723template<>
724class HOperandContainer<0> {
725 public:
726 int length() { return 0; }
727 HValue*& operator[](int i) {
728 UNREACHABLE();
729 static HValue* t = 0;
730 return t;
731 }
732};
733
734
735template<int V>
736class HTemplateInstruction : public HInstruction {
737 public:
738 int OperandCount() { return V; }
739 HValue* OperandAt(int i) { return inputs_[i]; }
740
741 protected:
742 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
743
744 private:
745 HOperandContainer<V> inputs_;
746};
747
748
749template<int V>
750class HTemplateControlInstruction : public HControlInstruction {
751 public:
752 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
753 : HControlInstruction(first, second) { }
754 int OperandCount() { return V; }
755 HValue* OperandAt(int i) { return inputs_[i]; }
756
757 protected:
758 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
759
760 private:
761 HOperandContainer<V> inputs_;
762};
763
764
765class HBlockEntry: public HTemplateInstruction<0> {
766 public:
767 virtual Representation RequiredInputRepresentation(int index) const {
768 return Representation::None();
769 }
770
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000771 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000772};
773
774
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000775class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000776 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000777 explicit HDeoptimize(int environment_length)
778 : HControlInstruction(NULL, NULL),
779 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000780
781 virtual Representation RequiredInputRepresentation(int index) const {
782 return Representation::None();
783 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000784
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000785 virtual int OperandCount() { return values_.length(); }
786 virtual HValue* OperandAt(int index) { return values_[index]; }
787
788 void AddEnvironmentValue(HValue* value) {
789 values_.Add(NULL);
790 SetOperandAt(values_.length() - 1, value);
791 }
792
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000793 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000794
795 protected:
796 virtual void InternalSetOperandAt(int index, HValue* value) {
797 values_[index] = value;
798 }
799
800 private:
801 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000802};
803
804
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000805class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000806 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000807 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000808 : HTemplateControlInstruction<0>(target, NULL),
809 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000810
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000811 void set_include_stack_check(bool include_stack_check) {
812 include_stack_check_ = include_stack_check;
813 }
814 bool include_stack_check() const { return include_stack_check_; }
815
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000816 virtual Representation RequiredInputRepresentation(int index) const {
817 return Representation::None();
818 }
819
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000820 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000821
822 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000823 bool include_stack_check_;
824};
825
826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000827class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000828 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000829 explicit HUnaryControlInstruction(HValue* value,
830 HBasicBlock* true_target,
831 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000832 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000833 SetOperandAt(0, value);
834 }
835
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000836 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000837
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000838 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000839};
840
841
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000842class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000843 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000844 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
845 : HUnaryControlInstruction(value, true_target, false_target) {
846 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000847 }
848
849 virtual Representation RequiredInputRepresentation(int index) const {
850 return Representation::None();
851 }
852
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000853 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000854};
855
856
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000857class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000858 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000859 HCompareMap(HValue* value,
860 Handle<Map> map,
861 HBasicBlock* true_target,
862 HBasicBlock* false_target)
863 : HUnaryControlInstruction(value, true_target, false_target),
864 map_(map) {
865 ASSERT(true_target != NULL);
866 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000867 ASSERT(!map.is_null());
868 }
869
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000870 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000871
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000872 Handle<Map> map() const { return map_; }
873
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000874 virtual Representation RequiredInputRepresentation(int index) const {
875 return Representation::Tagged();
876 }
877
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000878 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000879
880 private:
881 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000882};
883
884
885class HReturn: public HUnaryControlInstruction {
886 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000887 explicit HReturn(HValue* value)
888 : HUnaryControlInstruction(value, NULL, NULL) {
889 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000891 virtual Representation RequiredInputRepresentation(int index) const {
892 return Representation::Tagged();
893 }
894
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000895 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896};
897
898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000899class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000901 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
902
903 virtual Representation RequiredInputRepresentation(int index) const {
904 return Representation::None();
905 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000907 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000908};
909
910
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000911class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000912 public:
913 explicit HUnaryOperation(HValue* value) {
914 SetOperandAt(0, value);
915 }
916
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000917 HValue* value() { return OperandAt(0); }
918 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919};
920
921
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000922class HThrow: public HUnaryOperation {
923 public:
924 explicit HThrow(HValue* value) : HUnaryOperation(value) {
925 SetAllSideEffects();
926 }
927
928 virtual Representation RequiredInputRepresentation(int index) const {
929 return Representation::Tagged();
930 }
931
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000932 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000933};
934
935
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936class HChange: public HUnaryOperation {
937 public:
938 HChange(HValue* value,
939 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000940 Representation to,
941 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000942 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943 ASSERT(!from.IsNone() && !to.IsNone());
944 ASSERT(!from.Equals(to));
945 set_representation(to);
946 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000947 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000948 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
949 value->range()->IsInSmiRange()) {
950 set_type(HType::Smi());
951 }
952 }
953
954 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
955
956 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000957 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958 virtual Representation RequiredInputRepresentation(int index) const {
959 return from_;
960 }
961
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000962 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000963
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000964 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000966 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000967
968 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000969 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000970 if (!other->IsChange()) return false;
971 HChange* change = HChange::cast(other);
972 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000973 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974 }
975
976 private:
977 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000978};
979
980
981class HSimulate: public HInstruction {
982 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000983 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000984 : ast_id_(ast_id),
985 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000986 values_(2),
987 assigned_indexes_(2) {}
988 virtual ~HSimulate() {}
989
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000990 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000991
992 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
993 int ast_id() const { return ast_id_; }
994 void set_ast_id(int id) {
995 ASSERT(!HasAstId());
996 ast_id_ = id;
997 }
998
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000999 int pop_count() const { return pop_count_; }
1000 const ZoneList<HValue*>* values() const { return &values_; }
1001 int GetAssignedIndexAt(int index) const {
1002 ASSERT(HasAssignedIndexAt(index));
1003 return assigned_indexes_[index];
1004 }
1005 bool HasAssignedIndexAt(int index) const {
1006 return assigned_indexes_[index] != kNoIndex;
1007 }
1008 void AddAssignedValue(int index, HValue* value) {
1009 AddValue(index, value);
1010 }
1011 void AddPushedValue(HValue* value) {
1012 AddValue(kNoIndex, value);
1013 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001014 virtual int OperandCount() { return values_.length(); }
1015 virtual HValue* OperandAt(int index) { return values_[index]; }
1016
1017 virtual Representation RequiredInputRepresentation(int index) const {
1018 return Representation::None();
1019 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001021 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022
1023#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001024 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001025#endif
1026
1027 protected:
1028 virtual void InternalSetOperandAt(int index, HValue* value) {
1029 values_[index] = value;
1030 }
1031
1032 private:
1033 static const int kNoIndex = -1;
1034 void AddValue(int index, HValue* value) {
1035 assigned_indexes_.Add(index);
1036 // Resize the list of pushed values.
1037 values_.Add(NULL);
1038 // Set the operand through the base method in HValue to make sure that the
1039 // use lists are correctly updated.
1040 SetOperandAt(values_.length() - 1, value);
1041 }
1042 int ast_id_;
1043 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001044 ZoneList<HValue*> values_;
1045 ZoneList<int> assigned_indexes_;
1046};
1047
1048
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001049class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001050 public:
1051 HStackCheck() { }
1052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001053 virtual Representation RequiredInputRepresentation(int index) const {
1054 return Representation::None();
1055 }
1056
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001057 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001058};
1059
1060
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001061class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001062 public:
1063 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1064 : closure_(closure), function_(function) {
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
1069 Handle<JSFunction> closure() const { return closure_; }
1070 FunctionLiteral* function() const { return function_; }
1071
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001072 virtual Representation RequiredInputRepresentation(int index) const {
1073 return Representation::None();
1074 }
1075
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001076 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001077
1078 private:
1079 Handle<JSFunction> closure_;
1080 FunctionLiteral* function_;
1081};
1082
1083
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001084class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085 public:
1086 HLeaveInlined() {}
1087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001088 virtual Representation RequiredInputRepresentation(int index) const {
1089 return Representation::None();
1090 }
1091
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001092 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001093};
1094
1095
1096class HPushArgument: public HUnaryOperation {
1097 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001098 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1099 set_representation(Representation::Tagged());
1100 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001101
1102 virtual Representation RequiredInputRepresentation(int index) const {
1103 return Representation::Tagged();
1104 }
1105
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001106 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001107
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001108 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001109};
1110
1111
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001112class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001113 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001114 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115 set_representation(Representation::Tagged());
1116 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001117 }
1118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001119 virtual Representation RequiredInputRepresentation(int index) const {
1120 return Representation::None();
1121 }
1122
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001123 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001124
1125 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001126 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001127};
1128
1129
1130class HOuterContext: public HUnaryOperation {
1131 public:
1132 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1133 set_representation(Representation::Tagged());
1134 SetFlag(kUseGVN);
1135 }
1136
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001137 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001138
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001139 virtual Representation RequiredInputRepresentation(int index) const {
1140 return Representation::Tagged();
1141 }
1142
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001143 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001144 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001145};
1146
1147
1148class HGlobalObject: public HUnaryOperation {
1149 public:
1150 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1151 set_representation(Representation::Tagged());
1152 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001153 }
1154
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001155 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001156
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001157 virtual Representation RequiredInputRepresentation(int index) const {
1158 return Representation::Tagged();
1159 }
1160
ager@chromium.org378b34e2011-01-28 08:04:38 +00001161 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001162 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001163};
1164
1165
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001166class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001167 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001168 explicit HGlobalReceiver(HValue* global_object)
1169 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001170 set_representation(Representation::Tagged());
1171 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001172 }
1173
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001174 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001175
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001176 virtual Representation RequiredInputRepresentation(int index) const {
1177 return Representation::Tagged();
1178 }
1179
ager@chromium.org378b34e2011-01-28 08:04:38 +00001180 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001181 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001182};
1183
1184
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001185template <int V>
1186class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001187 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001188 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001189 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1190 this->set_representation(Representation::Tagged());
1191 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001192 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001194 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001195
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001196 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001197
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001198 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001199
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001200 private:
1201 int argument_count_;
1202};
1203
1204
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001205class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001206 public:
1207 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001208 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001209 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001210 }
1211
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001212 virtual Representation RequiredInputRepresentation(int index) const {
1213 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001214 }
1215
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001216 virtual void PrintDataTo(StringStream* stream);
1217
1218 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001219};
1220
1221
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001222class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001223 public:
1224 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001225 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001226 SetOperandAt(0, first);
1227 SetOperandAt(1, second);
1228 }
1229
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001230 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001231
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001232 virtual Representation RequiredInputRepresentation(int index) const {
1233 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001234 }
1235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001236 HValue* first() { return OperandAt(0); }
1237 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238};
1239
1240
danno@chromium.org160a7b02011-04-18 15:51:38 +00001241class HInvokeFunction: public HBinaryCall {
1242 public:
1243 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1244 : HBinaryCall(context, function, argument_count) {
1245 }
1246
1247 virtual Representation RequiredInputRepresentation(int index) const {
1248 return Representation::Tagged();
1249 }
1250
1251 HValue* context() { return first(); }
1252 HValue* function() { return second(); }
1253
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001254 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001255};
1256
1257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001258class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001259 public:
1260 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001261 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001262
1263 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001264
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001265 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001266 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001267 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001268 }
1269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001270 virtual void PrintDataTo(StringStream* stream);
1271
1272 virtual Representation RequiredInputRepresentation(int index) const {
1273 return Representation::None();
1274 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001276 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001277
1278 private:
1279 Handle<JSFunction> function_;
1280};
1281
1282
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001283class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001284 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001285 HCallKeyed(HValue* context, HValue* key, int argument_count)
1286 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287 }
1288
1289 virtual Representation RequiredInputRepresentation(int index) const {
1290 return Representation::Tagged();
1291 }
1292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001293 HValue* context() { return first(); }
1294 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001295
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001296 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001297};
1298
1299
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001300class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001301 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001302 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1303 : HUnaryCall(context, argument_count), name_(name) {
1304 }
1305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001306 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001308 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001309 Handle<String> name() const { return name_; }
1310
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001311 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001313 virtual Representation RequiredInputRepresentation(int index) const {
1314 return Representation::Tagged();
1315 }
1316
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001317 private:
1318 Handle<String> name_;
1319};
1320
1321
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001322class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001324 HCallFunction(HValue* context, int argument_count)
1325 : HUnaryCall(context, argument_count) {
1326 }
1327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001328 HValue* context() { return value(); }
1329
1330 virtual Representation RequiredInputRepresentation(int index) const {
1331 return Representation::Tagged();
1332 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001333
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001334 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335};
1336
1337
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001338class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001339 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001340 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1341 : HUnaryCall(context, argument_count), name_(name) {
1342 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001344 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001346 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001347 Handle<String> name() const { return name_; }
1348
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001349 virtual Representation RequiredInputRepresentation(int index) const {
1350 return Representation::Tagged();
1351 }
1352
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001353 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001354
1355 private:
1356 Handle<String> name_;
1357};
1358
1359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001360class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001361 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001362 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001363 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001364
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001365 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001366
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367 Handle<JSFunction> target() const { return target_; }
1368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001369 virtual Representation RequiredInputRepresentation(int index) const {
1370 return Representation::None();
1371 }
1372
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001373 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001374
1375 private:
1376 Handle<JSFunction> target_;
1377};
1378
1379
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001380class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001381 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001382 HCallNew(HValue* context, HValue* constructor, int argument_count)
1383 : HBinaryCall(context, constructor, argument_count) {
1384 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001385
1386 virtual Representation RequiredInputRepresentation(int index) const {
1387 return Representation::Tagged();
1388 }
1389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390 HValue* context() { return first(); }
1391 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001392
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001393 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394};
1395
1396
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001397class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001398 public:
1399 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001400 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001401 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001402 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1403 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001404
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001405 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406 Handle<String> name() const { return name_; }
1407
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001408 virtual Representation RequiredInputRepresentation(int index) const {
1409 return Representation::None();
1410 }
1411
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001412 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413
1414 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001415 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001416 Handle<String> name_;
1417};
1418
1419
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001420class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001422 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 // The length of an array is stored as a tagged value in the array
1424 // object. It is guaranteed to be 32 bit integer, but it can be
1425 // represented as either a smi or heap number.
1426 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001428 SetFlag(kDependsOnArrayLengths);
1429 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430 }
1431
1432 virtual Representation RequiredInputRepresentation(int index) const {
1433 return Representation::Tagged();
1434 }
1435
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001436 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001437
1438 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001440};
1441
1442
1443class HFixedArrayLength: public HUnaryOperation {
1444 public:
1445 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1446 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001447 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001448 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001449 }
1450
1451 virtual Representation RequiredInputRepresentation(int index) const {
1452 return Representation::Tagged();
1453 }
1454
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001455 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001456
1457 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001459};
1460
1461
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001462class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001463 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001464 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465 set_representation(Representation::Integer32());
1466 // The result of this instruction is idempotent as long as its inputs don't
1467 // change. The length of a pixel array cannot change once set, so it's not
1468 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1469 SetFlag(kUseGVN);
1470 }
1471
1472 virtual Representation RequiredInputRepresentation(int index) const {
1473 return Representation::Tagged();
1474 }
1475
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001476 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001477
1478 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001479 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001480};
1481
1482
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001483class HBitNot: public HUnaryOperation {
1484 public:
1485 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1486 set_representation(Representation::Integer32());
1487 SetFlag(kUseGVN);
1488 SetFlag(kTruncatingToInt32);
1489 }
1490
1491 virtual Representation RequiredInputRepresentation(int index) const {
1492 return Representation::Integer32();
1493 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001494 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001495
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001496 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001497
1498 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001499 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001500};
1501
1502
1503class HUnaryMathOperation: public HUnaryOperation {
1504 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001505 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001506 : HUnaryOperation(value), op_(op) {
1507 switch (op) {
1508 case kMathFloor:
1509 case kMathRound:
1510 case kMathCeil:
1511 set_representation(Representation::Integer32());
1512 break;
1513 case kMathAbs:
1514 set_representation(Representation::Tagged());
1515 SetFlag(kFlexibleRepresentation);
1516 break;
1517 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001518 case kMathPowHalf:
1519 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001520 case kMathSin:
1521 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001523 break;
1524 default:
1525 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526 }
1527 SetFlag(kUseGVN);
1528 }
1529
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001530 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001532 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001533
1534 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1535
1536 virtual Representation RequiredInputRepresentation(int index) const {
1537 switch (op_) {
1538 case kMathFloor:
1539 case kMathRound:
1540 case kMathCeil:
1541 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001542 case kMathPowHalf:
1543 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001544 case kMathSin:
1545 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001546 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547 case kMathAbs:
1548 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001549 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001550 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551 return Representation::None();
1552 }
1553 }
1554
1555 virtual HValue* Canonicalize() {
1556 // If the input is integer32 then we replace the floor instruction
1557 // with its inputs. This happens before the representation changes are
1558 // introduced.
1559 if (op() == kMathFloor) {
1560 if (value()->representation().IsInteger32()) return value();
1561 }
1562 return this;
1563 }
1564
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001565 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566 const char* OpName() const;
1567
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001568 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001569
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001570 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001571 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001572 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1573 return op_ == b->op();
1574 }
1575
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001577 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578};
1579
1580
1581class HLoadElements: public HUnaryOperation {
1582 public:
1583 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1584 set_representation(Representation::Tagged());
1585 SetFlag(kUseGVN);
1586 SetFlag(kDependsOnMaps);
1587 }
1588
1589 virtual Representation RequiredInputRepresentation(int index) const {
1590 return Representation::Tagged();
1591 }
1592
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001593 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001594
1595 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001596 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597};
1598
1599
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001600class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001601 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001602 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001603 : HUnaryOperation(value) {
1604 set_representation(Representation::External());
1605 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001606 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001607 // change once set, so it's no necessary to introduce any additional
1608 // dependencies on top of the inputs.
1609 SetFlag(kUseGVN);
1610 }
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(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001617
1618 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001619 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001620};
1621
1622
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001623class HCheckMap: public HUnaryOperation {
1624 public:
1625 HCheckMap(HValue* value, Handle<Map> map)
1626 : HUnaryOperation(value), map_(map) {
1627 set_representation(Representation::Tagged());
1628 SetFlag(kUseGVN);
1629 SetFlag(kDependsOnMaps);
1630 }
1631
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001632 virtual bool IsCheckInstruction() const { return true; }
1633
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634 virtual Representation RequiredInputRepresentation(int index) const {
1635 return Representation::Tagged();
1636 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001637 virtual void PrintDataTo(StringStream* stream);
1638 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639
1640#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001641 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001642#endif
1643
1644 Handle<Map> map() const { return map_; }
1645
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001646 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001647
1648 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001649 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001650 HCheckMap* b = HCheckMap::cast(other);
1651 return map_.is_identical_to(b->map());
1652 }
1653
1654 private:
1655 Handle<Map> map_;
1656};
1657
1658
1659class HCheckFunction: public HUnaryOperation {
1660 public:
1661 HCheckFunction(HValue* value, Handle<JSFunction> function)
1662 : HUnaryOperation(value), target_(function) {
1663 set_representation(Representation::Tagged());
1664 SetFlag(kUseGVN);
1665 }
1666
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001667 virtual bool IsCheckInstruction() const { return true; }
1668
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001669 virtual Representation RequiredInputRepresentation(int index) const {
1670 return Representation::Tagged();
1671 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001672 virtual void PrintDataTo(StringStream* stream);
1673 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674
1675#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001676 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001677#endif
1678
1679 Handle<JSFunction> target() const { return target_; }
1680
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001681 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682
1683 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001684 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001685 HCheckFunction* b = HCheckFunction::cast(other);
1686 return target_.is_identical_to(b->target());
1687 }
1688
1689 private:
1690 Handle<JSFunction> target_;
1691};
1692
1693
1694class HCheckInstanceType: public HUnaryOperation {
1695 public:
1696 // Check that the instance type is in the range [first, last] where
1697 // both first and last are included.
1698 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1699 : HUnaryOperation(value), first_(first), last_(last) {
1700 ASSERT(first <= last);
1701 set_representation(Representation::Tagged());
1702 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001703 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1704 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1705 // A particular string instance type can change because of GC or
1706 // externalization, but the value still remains a string.
1707 SetFlag(kDependsOnMaps);
1708 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001709 }
1710
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001711 virtual bool IsCheckInstruction() const { return true; }
1712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713 virtual Representation RequiredInputRepresentation(int index) const {
1714 return Representation::Tagged();
1715 }
1716
1717#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001718 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001719#endif
1720
danno@chromium.org160a7b02011-04-18 15:51:38 +00001721 virtual HValue* Canonicalize() {
1722 if (!value()->type().IsUninitialized() &&
1723 value()->type().IsString() &&
1724 first() == FIRST_STRING_TYPE &&
1725 last() == LAST_STRING_TYPE) {
1726 return NULL;
1727 }
1728 return this;
1729 }
1730
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001731 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1732
1733 InstanceType first() const { return first_; }
1734 InstanceType last() const { return last_; }
1735
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001736 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001737
1738 protected:
1739 // TODO(ager): It could be nice to allow the ommision of instance
1740 // type checks if we have already performed an instance type check
1741 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001742 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001743 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1744 return (first_ == b->first()) && (last_ == b->last());
1745 }
1746
1747 private:
1748 InstanceType first_;
1749 InstanceType last_;
1750};
1751
1752
1753class HCheckNonSmi: public HUnaryOperation {
1754 public:
1755 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1756 set_representation(Representation::Tagged());
1757 SetFlag(kUseGVN);
1758 }
1759
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001760 virtual bool IsCheckInstruction() const { return true; }
1761
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001762 virtual Representation RequiredInputRepresentation(int index) const {
1763 return Representation::Tagged();
1764 }
1765
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001766 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767
1768#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001769 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770#endif
1771
danno@chromium.org160a7b02011-04-18 15:51:38 +00001772 virtual HValue* Canonicalize() {
1773 HType value_type = value()->type();
1774 if (!value_type.IsUninitialized() &&
1775 (value_type.IsHeapNumber() ||
1776 value_type.IsString() ||
1777 value_type.IsBoolean() ||
1778 value_type.IsNonPrimitive())) {
1779 return NULL;
1780 }
1781 return this;
1782 }
1783
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001784 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001785
1786 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001787 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788};
1789
1790
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001791class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001792 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001793 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1794 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795 SetFlag(kUseGVN);
1796 SetFlag(kDependsOnMaps);
1797 }
1798
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001799 virtual bool IsCheckInstruction() const { return true; }
1800
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001802 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803#endif
1804
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001805 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001806 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001807
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001808 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001810 virtual Representation RequiredInputRepresentation(int index) const {
1811 return Representation::None();
1812 }
1813
1814 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001816 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1817 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1818 return hash;
1819 }
1820
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001821 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001822 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001823 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001824 return prototype_.is_identical_to(b->prototype()) &&
1825 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001826 }
1827
1828 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001829 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001831};
1832
1833
1834class HCheckSmi: public HUnaryOperation {
1835 public:
1836 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1837 set_representation(Representation::Tagged());
1838 SetFlag(kUseGVN);
1839 }
1840
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001841 virtual bool IsCheckInstruction() const { return true; }
1842
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001843 virtual Representation RequiredInputRepresentation(int index) const {
1844 return Representation::Tagged();
1845 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001846 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001847
1848#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001849 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850#endif
1851
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001852 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001853
1854 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001855 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001856};
1857
1858
1859class HPhi: public HValue {
1860 public:
1861 explicit HPhi(int merged_index)
1862 : inputs_(2),
1863 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001864 phi_id_(-1),
1865 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001866 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1867 non_phi_uses_[i] = 0;
1868 indirect_uses_[i] = 0;
1869 }
1870 ASSERT(merged_index >= 0);
1871 set_representation(Representation::Tagged());
1872 SetFlag(kFlexibleRepresentation);
1873 }
1874
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001875 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001876 bool double_occurred = false;
1877 bool int32_occurred = false;
1878 for (int i = 0; i < OperandCount(); ++i) {
1879 HValue* value = OperandAt(i);
1880 if (value->representation().IsDouble()) double_occurred = true;
1881 if (value->representation().IsInteger32()) int32_occurred = true;
1882 if (value->representation().IsTagged()) return Representation::Tagged();
1883 }
1884
1885 if (double_occurred) return Representation::Double();
1886 if (int32_occurred) return Representation::Integer32();
1887 return Representation::None();
1888 }
1889
1890 virtual Range* InferRange();
1891 virtual Representation RequiredInputRepresentation(int index) const {
1892 return representation();
1893 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001894 virtual HType CalculateInferredType();
1895 virtual int OperandCount() { return inputs_.length(); }
1896 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1897 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001898 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001899 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001900
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001901 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001902
1903 int merged_index() const { return merged_index_; }
1904
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001905 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001906
1907#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001908 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001909#endif
1910
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911 void InitRealUses(int id);
1912 void AddNonPhiUsesFrom(HPhi* other);
1913 void AddIndirectUsesTo(int* use_count);
1914
1915 int tagged_non_phi_uses() const {
1916 return non_phi_uses_[Representation::kTagged];
1917 }
1918 int int32_non_phi_uses() const {
1919 return non_phi_uses_[Representation::kInteger32];
1920 }
1921 int double_non_phi_uses() const {
1922 return non_phi_uses_[Representation::kDouble];
1923 }
1924 int tagged_indirect_uses() const {
1925 return indirect_uses_[Representation::kTagged];
1926 }
1927 int int32_indirect_uses() const {
1928 return indirect_uses_[Representation::kInteger32];
1929 }
1930 int double_indirect_uses() const {
1931 return indirect_uses_[Representation::kDouble];
1932 }
1933 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001934 bool is_live() { return is_live_; }
1935 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001936
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001937 static HPhi* cast(HValue* value) {
1938 ASSERT(value->IsPhi());
1939 return reinterpret_cast<HPhi*>(value);
1940 }
1941 virtual Opcode opcode() const { return HValue::kPhi; }
1942
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001943 protected:
1944 virtual void DeleteFromGraph();
1945 virtual void InternalSetOperandAt(int index, HValue* value) {
1946 inputs_[index] = value;
1947 }
1948
1949 private:
1950 ZoneList<HValue*> inputs_;
1951 int merged_index_;
1952
1953 int non_phi_uses_[Representation::kNumRepresentations];
1954 int indirect_uses_[Representation::kNumRepresentations];
1955 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001956 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001957};
1958
1959
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001960class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001961 public:
1962 HArgumentsObject() {
1963 set_representation(Representation::Tagged());
1964 SetFlag(kIsArguments);
1965 }
1966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001967 virtual Representation RequiredInputRepresentation(int index) const {
1968 return Representation::None();
1969 }
1970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001971 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001972};
1973
1974
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001975class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001976 public:
1977 HConstant(Handle<Object> handle, Representation r);
1978
1979 Handle<Object> handle() const { return handle_; }
1980
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001981 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001983 virtual Representation RequiredInputRepresentation(int index) const {
1984 return Representation::None();
1985 }
1986
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001987 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001988 virtual void PrintDataTo(StringStream* stream);
1989 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001990 bool IsInteger() const { return handle_->IsSmi(); }
1991 HConstant* CopyToRepresentation(Representation r) const;
1992 HConstant* CopyToTruncatedInt32() const;
1993 bool HasInteger32Value() const { return has_int32_value_; }
1994 int32_t Integer32Value() const {
1995 ASSERT(HasInteger32Value());
1996 return int32_value_;
1997 }
1998 bool HasDoubleValue() const { return has_double_value_; }
1999 double DoubleValue() const {
2000 ASSERT(HasDoubleValue());
2001 return double_value_;
2002 }
2003 bool HasStringValue() const { return handle_->IsString(); }
2004
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002005 bool ToBoolean() const;
2006
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002007 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002008 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002009 return reinterpret_cast<intptr_t>(*handle());
2010 }
2011
2012#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002013 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014#endif
2015
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002016 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002017
2018 protected:
2019 virtual Range* InferRange();
2020
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002021 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002022 HConstant* other_constant = HConstant::cast(other);
2023 return handle().is_identical_to(other_constant->handle());
2024 }
2025
2026 private:
2027 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002028
2029 // The following two values represent the int32 and the double value of the
2030 // given constant if there is a lossless conversion between the constant
2031 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002032 bool has_int32_value_ : 1;
2033 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002034 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002035 double double_value_;
2036};
2037
2038
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002039class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002040 public:
2041 HBinaryOperation(HValue* left, HValue* right) {
2042 ASSERT(left != NULL && right != NULL);
2043 SetOperandAt(0, left);
2044 SetOperandAt(1, right);
2045 }
2046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002047 HValue* left() { return OperandAt(0); }
2048 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002049
2050 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2051 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002052 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002053 if (IsCommutative() && left()->IsConstant()) return right();
2054 return left();
2055 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002056 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057 if (IsCommutative() && left()->IsConstant()) return left();
2058 return right();
2059 }
2060
2061 virtual bool IsCommutative() const { return false; }
2062
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002063 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064};
2065
2066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002067class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002068 public:
2069 HApplyArguments(HValue* function,
2070 HValue* receiver,
2071 HValue* length,
2072 HValue* elements) {
2073 set_representation(Representation::Tagged());
2074 SetOperandAt(0, function);
2075 SetOperandAt(1, receiver);
2076 SetOperandAt(2, length);
2077 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002078 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002079 }
2080
2081 virtual Representation RequiredInputRepresentation(int index) const {
2082 // The length is untagged, all other inputs are tagged.
2083 return (index == 2)
2084 ? Representation::Integer32()
2085 : Representation::Tagged();
2086 }
2087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002088 HValue* function() { return OperandAt(0); }
2089 HValue* receiver() { return OperandAt(1); }
2090 HValue* length() { return OperandAt(2); }
2091 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002093 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002094};
2095
2096
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002097class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002098 public:
2099 HArgumentsElements() {
2100 // The value produced by this instruction is a pointer into the stack
2101 // that looks as if it was a smi because of alignment.
2102 set_representation(Representation::Tagged());
2103 SetFlag(kUseGVN);
2104 }
2105
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002106 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002107
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002108 virtual Representation RequiredInputRepresentation(int index) const {
2109 return Representation::None();
2110 }
2111
ager@chromium.org378b34e2011-01-28 08:04:38 +00002112 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002113 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002114};
2115
2116
2117class HArgumentsLength: public HUnaryOperation {
2118 public:
2119 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2120 set_representation(Representation::Integer32());
2121 SetFlag(kUseGVN);
2122 }
2123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002124 virtual Representation RequiredInputRepresentation(int index) const {
2125 return Representation::Tagged();
2126 }
2127
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002128 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002129
2130 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002131 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002132};
2133
2134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002135class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136 public:
2137 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2138 set_representation(Representation::Tagged());
2139 SetFlag(kUseGVN);
2140 SetOperandAt(0, arguments);
2141 SetOperandAt(1, length);
2142 SetOperandAt(2, index);
2143 }
2144
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002145 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002146
2147 virtual Representation RequiredInputRepresentation(int index) const {
2148 // The arguments elements is considered tagged.
2149 return index == 0
2150 ? Representation::Tagged()
2151 : Representation::Integer32();
2152 }
2153
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002154 HValue* arguments() { return OperandAt(0); }
2155 HValue* length() { return OperandAt(1); }
2156 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002157
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002158 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002160 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161};
2162
2163
2164class HBoundsCheck: public HBinaryOperation {
2165 public:
2166 HBoundsCheck(HValue* index, HValue* length)
2167 : HBinaryOperation(index, length) {
2168 SetFlag(kUseGVN);
2169 }
2170
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002171 virtual bool IsCheckInstruction() const { return true; }
2172
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002173 virtual Representation RequiredInputRepresentation(int index) const {
2174 return Representation::Integer32();
2175 }
2176
2177#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002178 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002179#endif
2180
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002181 HValue* index() { return left(); }
2182 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002183
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002184 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002185
2186 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002187 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002188};
2189
2190
2191class HBitwiseBinaryOperation: public HBinaryOperation {
2192 public:
2193 HBitwiseBinaryOperation(HValue* left, HValue* right)
2194 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002195 set_representation(Representation::Tagged());
2196 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002197 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002198 }
2199
2200 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002201 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002202 }
2203
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002204 virtual void RepresentationChanged(Representation to) {
2205 if (!to.IsTagged()) {
2206 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002207 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002208 SetFlag(kTruncatingToInt32);
2209 SetFlag(kUseGVN);
2210 }
2211 }
2212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002213 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002214
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002215 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002216};
2217
2218
2219class HArithmeticBinaryOperation: public HBinaryOperation {
2220 public:
2221 HArithmeticBinaryOperation(HValue* left, HValue* right)
2222 : HBinaryOperation(left, right) {
2223 set_representation(Representation::Tagged());
2224 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002225 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002226 }
2227
2228 virtual void RepresentationChanged(Representation to) {
2229 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002230 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002231 SetFlag(kUseGVN);
2232 }
2233 }
2234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002235 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002236 virtual Representation RequiredInputRepresentation(int index) const {
2237 return representation();
2238 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002239 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002240 if (left()->representation().Equals(right()->representation())) {
2241 return left()->representation();
2242 }
2243 return HValue::InferredRepresentation();
2244 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002245};
2246
2247
2248class HCompare: public HBinaryOperation {
2249 public:
2250 HCompare(HValue* left, HValue* right, Token::Value token)
2251 : HBinaryOperation(left, right), token_(token) {
2252 ASSERT(Token::IsCompareOp(token));
2253 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002254 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002255 }
2256
2257 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002258
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002259 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002260 return !HasSideEffects() && (uses()->length() <= 1);
2261 }
2262
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002263 virtual Representation RequiredInputRepresentation(int index) const {
2264 return input_representation_;
2265 }
2266 Representation GetInputRepresentation() const {
2267 return input_representation_;
2268 }
2269 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002270 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002271
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002272 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002274 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002275 return HValue::Hashcode() * 7 + token_;
2276 }
2277
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002278 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002279
2280 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002281 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002282 HCompare* comp = HCompare::cast(other);
2283 return token_ == comp->token();
2284 }
2285
2286 private:
2287 Representation input_representation_;
2288 Token::Value token_;
2289};
2290
2291
2292class HCompareJSObjectEq: public HBinaryOperation {
2293 public:
2294 HCompareJSObjectEq(HValue* left, HValue* right)
2295 : HBinaryOperation(left, right) {
2296 set_representation(Representation::Tagged());
2297 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002298 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002299 }
2300
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002301 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002302 return !HasSideEffects() && (uses()->length() <= 1);
2303 }
2304
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002305 virtual Representation RequiredInputRepresentation(int index) const {
2306 return Representation::Tagged();
2307 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002308 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002309
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002310 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002311
2312 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002313 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002314};
2315
2316
2317class HUnaryPredicate: public HUnaryOperation {
2318 public:
2319 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2320 set_representation(Representation::Tagged());
2321 SetFlag(kUseGVN);
2322 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002323
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002324 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002325 return !HasSideEffects() && (uses()->length() <= 1);
2326 }
2327
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002328 virtual Representation RequiredInputRepresentation(int index) const {
2329 return Representation::Tagged();
2330 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002331 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002332};
2333
2334
2335class HIsNull: public HUnaryPredicate {
2336 public:
2337 HIsNull(HValue* value, bool is_strict)
2338 : HUnaryPredicate(value), is_strict_(is_strict) { }
2339
2340 bool is_strict() const { return is_strict_; }
2341
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002342 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002344 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002345 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002346 HIsNull* b = HIsNull::cast(other);
2347 return is_strict_ == b->is_strict();
2348 }
2349
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002350 private:
2351 bool is_strict_;
2352};
2353
2354
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002355class HIsObject: public HUnaryPredicate {
2356 public:
2357 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2358
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002359 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002360
2361 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002362 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002363};
2364
2365
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002366class HIsSmi: public HUnaryPredicate {
2367 public:
2368 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2369
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002370 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002371
2372 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374};
2375
2376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002377class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002378 public:
2379 HIsConstructCall() {
2380 set_representation(Representation::Tagged());
2381 SetFlag(kUseGVN);
2382 }
2383
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002384 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002385 return !HasSideEffects() && (uses()->length() <= 1);
2386 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002387
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002388 virtual Representation RequiredInputRepresentation(int index) const {
2389 return Representation::None();
2390 }
2391
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002392 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002393
2394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002395 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002396};
2397
2398
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002399class HHasInstanceType: public HUnaryPredicate {
2400 public:
2401 HHasInstanceType(HValue* value, InstanceType type)
2402 : HUnaryPredicate(value), from_(type), to_(type) { }
2403 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2404 : HUnaryPredicate(value), from_(from), to_(to) {
2405 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2406 }
2407
2408 InstanceType from() { return from_; }
2409 InstanceType to() { return to_; }
2410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002411 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002413 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002414
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002417 HHasInstanceType* b = HHasInstanceType::cast(other);
2418 return (from_ == b->from()) && (to_ == b->to());
2419 }
2420
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002421 private:
2422 InstanceType from_;
2423 InstanceType to_; // Inclusive range, not all combinations work.
2424};
2425
2426
2427class HHasCachedArrayIndex: public HUnaryPredicate {
2428 public:
2429 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2430
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002431 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002432
2433 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002434 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002435};
2436
2437
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002438class HGetCachedArrayIndex: public HUnaryPredicate {
2439 public:
2440 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2441
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002442 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002443
2444 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002445 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002446};
2447
2448
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002449class HClassOfTest: public HUnaryPredicate {
2450 public:
2451 HClassOfTest(HValue* value, Handle<String> class_name)
2452 : HUnaryPredicate(value), class_name_(class_name) { }
2453
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002454 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002456 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002457
2458 Handle<String> class_name() const { return class_name_; }
2459
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002460 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002461 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002462 HClassOfTest* b = HClassOfTest::cast(other);
2463 return class_name_.is_identical_to(b->class_name_);
2464 }
2465
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002466 private:
2467 Handle<String> class_name_;
2468};
2469
2470
2471class HTypeofIs: public HUnaryPredicate {
2472 public:
2473 HTypeofIs(HValue* value, Handle<String> type_literal)
2474 : HUnaryPredicate(value), type_literal_(type_literal) { }
2475
2476 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002477 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002478
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002479 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480
2481 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002482 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002483 HTypeofIs* b = HTypeofIs::cast(other);
2484 return type_literal_.is_identical_to(b->type_literal_);
2485 }
2486
2487 private:
2488 Handle<String> type_literal_;
2489};
2490
2491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002492class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002493 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002494 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2495 SetOperandAt(0, context);
2496 SetOperandAt(1, left);
2497 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002498 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002499 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002500 }
2501
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002502 HValue* context() { return OperandAt(0); }
2503 HValue* left() { return OperandAt(1); }
2504 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002505
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002506 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002507 return !HasSideEffects() && (uses()->length() <= 1);
2508 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002509
2510 virtual Representation RequiredInputRepresentation(int index) const {
2511 return Representation::Tagged();
2512 }
2513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002514 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002515
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002516 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002517};
2518
2519
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002520class HInstanceOfKnownGlobal: public HUnaryOperation {
2521 public:
2522 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2523 : HUnaryOperation(left), function_(right) {
2524 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002525 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002526 }
2527
2528 Handle<JSFunction> function() { return function_; }
2529
2530 virtual Representation RequiredInputRepresentation(int index) const {
2531 return Representation::Tagged();
2532 }
2533
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002534 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002535
2536 private:
2537 Handle<JSFunction> function_;
2538};
2539
2540
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002541class HPower: public HBinaryOperation {
2542 public:
2543 HPower(HValue* left, HValue* right)
2544 : HBinaryOperation(left, right) {
2545 set_representation(Representation::Double());
2546 SetFlag(kUseGVN);
2547 }
2548
2549 virtual Representation RequiredInputRepresentation(int index) const {
2550 return (index == 1) ? Representation::None() : Representation::Double();
2551 }
2552
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002553 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002554
2555 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002556 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002557};
2558
2559
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560class HAdd: public HArithmeticBinaryOperation {
2561 public:
2562 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2563 SetFlag(kCanOverflow);
2564 }
2565
2566 // Add is only commutative if two integer values are added and not if two
2567 // tagged values are added (because it might be a String concatenation).
2568 virtual bool IsCommutative() const {
2569 return !representation().IsTagged();
2570 }
2571
2572 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2573
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002574 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002576 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002577
2578 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002579 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002580
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581 virtual Range* InferRange();
2582};
2583
2584
2585class HSub: public HArithmeticBinaryOperation {
2586 public:
2587 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2588 SetFlag(kCanOverflow);
2589 }
2590
2591 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2592
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002593 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002594
2595 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002596 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002597
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002598 virtual Range* InferRange();
2599};
2600
2601
2602class HMul: public HArithmeticBinaryOperation {
2603 public:
2604 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2605 SetFlag(kCanOverflow);
2606 }
2607
2608 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2609
2610 // Only commutative if it is certain that not two objects are multiplicated.
2611 virtual bool IsCommutative() const {
2612 return !representation().IsTagged();
2613 }
2614
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002615 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002616
2617 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002618 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620 virtual Range* InferRange();
2621};
2622
2623
2624class HMod: public HArithmeticBinaryOperation {
2625 public:
2626 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2627 SetFlag(kCanBeDivByZero);
2628 }
2629
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002630 bool HasPowerOf2Divisor() {
2631 if (right()->IsConstant() &&
2632 HConstant::cast(right())->HasInteger32Value()) {
2633 int32_t value = HConstant::cast(right())->Integer32Value();
2634 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2635 }
2636
2637 return false;
2638 }
2639
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002640 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2641
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002642 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002643
2644 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002645 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002646
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647 virtual Range* InferRange();
2648};
2649
2650
2651class HDiv: public HArithmeticBinaryOperation {
2652 public:
2653 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2654 SetFlag(kCanBeDivByZero);
2655 SetFlag(kCanOverflow);
2656 }
2657
2658 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2659
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002660 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002661
2662 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002663 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002664
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002665 virtual Range* InferRange();
2666};
2667
2668
2669class HBitAnd: public HBitwiseBinaryOperation {
2670 public:
2671 HBitAnd(HValue* left, HValue* right)
2672 : HBitwiseBinaryOperation(left, right) { }
2673
2674 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002675 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002677 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002678
2679 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002680 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002681
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002682 virtual Range* InferRange();
2683};
2684
2685
2686class HBitXor: public HBitwiseBinaryOperation {
2687 public:
2688 HBitXor(HValue* left, HValue* right)
2689 : HBitwiseBinaryOperation(left, right) { }
2690
2691 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002692 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002693
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002694 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002695
2696 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002697 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002698};
2699
2700
2701class HBitOr: public HBitwiseBinaryOperation {
2702 public:
2703 HBitOr(HValue* left, HValue* right)
2704 : HBitwiseBinaryOperation(left, right) { }
2705
2706 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002707 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002708
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002709 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002710
2711 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002712 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002713
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002714 virtual Range* InferRange();
2715};
2716
2717
2718class HShl: public HBitwiseBinaryOperation {
2719 public:
2720 HShl(HValue* left, HValue* right)
2721 : HBitwiseBinaryOperation(left, right) { }
2722
2723 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002724 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002726 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002727
2728 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002729 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002730};
2731
2732
2733class HShr: public HBitwiseBinaryOperation {
2734 public:
2735 HShr(HValue* left, HValue* right)
2736 : HBitwiseBinaryOperation(left, right) { }
2737
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002738 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002740 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002741
2742 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002743 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002744};
2745
2746
2747class HSar: public HBitwiseBinaryOperation {
2748 public:
2749 HSar(HValue* left, HValue* right)
2750 : HBitwiseBinaryOperation(left, right) { }
2751
2752 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002753 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002754
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002755 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002756
2757 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002758 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002759};
2760
2761
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002762class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002763 public:
2764 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2765 SetFlag(kChangesOsrEntries);
2766 }
2767
2768 int ast_id() const { return ast_id_; }
2769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002770 virtual Representation RequiredInputRepresentation(int index) const {
2771 return Representation::None();
2772 }
2773
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002774 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002775
2776 private:
2777 int ast_id_;
2778};
2779
2780
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002781class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002782 public:
2783 explicit HParameter(unsigned index) : index_(index) {
2784 set_representation(Representation::Tagged());
2785 }
2786
2787 unsigned index() const { return index_; }
2788
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual void PrintDataTo(StringStream* stream);
2790
2791 virtual Representation RequiredInputRepresentation(int index) const {
2792 return Representation::None();
2793 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002794
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002795 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002796
2797 private:
2798 unsigned index_;
2799};
2800
2801
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002802class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002803 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002804 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2805 : HUnaryCall(context, argument_count),
2806 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 }
2809
2810 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002811
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002812 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813
2814 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2815 transcendental_type_ = transcendental_type;
2816 }
2817 TranscendentalCache::Type transcendental_type() {
2818 return transcendental_type_;
2819 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002820
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002821 virtual void PrintDataTo(StringStream* stream);
2822
2823 virtual Representation RequiredInputRepresentation(int index) const {
2824 return Representation::Tagged();
2825 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002827 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002828
2829 private:
2830 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002831 TranscendentalCache::Type transcendental_type_;
2832};
2833
2834
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002835class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836 public:
2837 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2838
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002839 virtual Representation RequiredInputRepresentation(int index) const {
2840 return Representation::None();
2841 }
2842
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002843 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002844};
2845
2846
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002847class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002848 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002849 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002850 : cell_(cell), check_hole_value_(check_hole_value) {
2851 set_representation(Representation::Tagged());
2852 SetFlag(kUseGVN);
2853 SetFlag(kDependsOnGlobalVars);
2854 }
2855
2856 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2857 bool check_hole_value() const { return check_hole_value_; }
2858
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002859 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002860
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002861 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002862 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863 return reinterpret_cast<intptr_t>(*cell_);
2864 }
2865
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002866 virtual Representation RequiredInputRepresentation(int index) const {
2867 return Representation::None();
2868 }
2869
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002870 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002871
2872 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002873 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002874 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002875 return cell_.is_identical_to(b->cell());
2876 }
2877
2878 private:
2879 Handle<JSGlobalPropertyCell> cell_;
2880 bool check_hole_value_;
2881};
2882
2883
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002884class HLoadGlobalGeneric: public HBinaryOperation {
2885 public:
2886 HLoadGlobalGeneric(HValue* context,
2887 HValue* global_object,
2888 Handle<Object> name,
2889 bool for_typeof)
2890 : HBinaryOperation(context, global_object),
2891 name_(name),
2892 for_typeof_(for_typeof) {
2893 set_representation(Representation::Tagged());
2894 SetAllSideEffects();
2895 }
2896
2897 HValue* context() { return OperandAt(0); }
2898 HValue* global_object() { return OperandAt(1); }
2899 Handle<Object> name() const { return name_; }
2900 bool for_typeof() const { return for_typeof_; }
2901
2902 virtual void PrintDataTo(StringStream* stream);
2903
2904 virtual Representation RequiredInputRepresentation(int index) const {
2905 return Representation::Tagged();
2906 }
2907
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002908 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002909
2910 private:
2911 Handle<Object> name_;
2912 bool for_typeof_;
2913};
2914
2915
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002916class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002918 HStoreGlobalCell(HValue* value,
2919 Handle<JSGlobalPropertyCell> cell,
2920 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002921 : HUnaryOperation(value),
2922 cell_(cell),
2923 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 SetFlag(kChangesGlobalVars);
2925 }
2926
2927 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002928 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002929
2930 virtual Representation RequiredInputRepresentation(int index) const {
2931 return Representation::Tagged();
2932 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002933 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002934
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002935 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002936
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002937 private:
2938 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002939 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940};
2941
2942
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002943class HStoreGlobalGeneric: public HTemplateInstruction<3> {
2944 public:
2945 HStoreGlobalGeneric(HValue* context,
2946 HValue* global_object,
2947 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002948 HValue* value,
2949 bool strict_mode)
2950 : name_(name),
2951 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002952 SetOperandAt(0, context);
2953 SetOperandAt(1, global_object);
2954 SetOperandAt(2, value);
2955 set_representation(Representation::Tagged());
2956 SetAllSideEffects();
2957 }
2958
2959 HValue* context() { return OperandAt(0); }
2960 HValue* global_object() { return OperandAt(1); }
2961 Handle<Object> name() const { return name_; }
2962 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002963 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002964
2965 virtual void PrintDataTo(StringStream* stream);
2966
2967 virtual Representation RequiredInputRepresentation(int index) const {
2968 return Representation::Tagged();
2969 }
2970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002971 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002972
2973 private:
2974 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002975 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002976};
2977
2978
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002979class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002980 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002981 HLoadContextSlot(HValue* context , int slot_index)
2982 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002983 set_representation(Representation::Tagged());
2984 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002985 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002986 }
2987
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002988 int slot_index() const { return slot_index_; }
2989
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002990 virtual Representation RequiredInputRepresentation(int index) const {
2991 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002992 }
2993
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002994 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002995
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002996 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002997
2998 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002999 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003000 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003001 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003002 }
3003
3004 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003005 int slot_index_;
3006};
3007
3008
3009static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3010 return !value->type().IsSmi() &&
3011 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3012}
3013
3014
3015class HStoreContextSlot: public HBinaryOperation {
3016 public:
3017 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3018 : HBinaryOperation(context, value), slot_index_(slot_index) {
3019 SetFlag(kChangesContextSlots);
3020 }
3021
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003022 HValue* context() { return OperandAt(0); }
3023 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003024 int slot_index() const { return slot_index_; }
3025
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003026 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003027 return StoringValueNeedsWriteBarrier(value());
3028 }
3029
3030 virtual Representation RequiredInputRepresentation(int index) const {
3031 return Representation::Tagged();
3032 }
3033
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003034 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003035
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003036 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003037
3038 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003039 int slot_index_;
3040};
3041
3042
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043class HLoadNamedField: public HUnaryOperation {
3044 public:
3045 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3046 : HUnaryOperation(object),
3047 is_in_object_(is_in_object),
3048 offset_(offset) {
3049 set_representation(Representation::Tagged());
3050 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003051 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003052 if (is_in_object) {
3053 SetFlag(kDependsOnInobjectFields);
3054 } else {
3055 SetFlag(kDependsOnBackingStoreFields);
3056 }
3057 }
3058
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003059 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060 bool is_in_object() const { return is_in_object_; }
3061 int offset() const { return offset_; }
3062
3063 virtual Representation RequiredInputRepresentation(int index) const {
3064 return Representation::Tagged();
3065 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003068 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003069
3070 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003071 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072 HLoadNamedField* b = HLoadNamedField::cast(other);
3073 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3074 }
3075
3076 private:
3077 bool is_in_object_;
3078 int offset_;
3079};
3080
3081
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003082class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3083 public:
3084 HLoadNamedFieldPolymorphic(HValue* object,
3085 ZoneMapList* types,
3086 Handle<String> name);
3087
3088 HValue* object() { return OperandAt(0); }
3089 ZoneMapList* types() { return &types_; }
3090 Handle<String> name() { return name_; }
3091 bool need_generic() { return need_generic_; }
3092
3093 virtual Representation RequiredInputRepresentation(int index) const {
3094 return Representation::Tagged();
3095 }
3096
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003097 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003098
3099 static const int kMaxLoadPolymorphism = 4;
3100
3101 protected:
3102 virtual bool DataEquals(HValue* value);
3103
3104 private:
3105 ZoneMapList types_;
3106 Handle<String> name_;
3107 bool need_generic_;
3108};
3109
3110
3111
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003112class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003114 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3115 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003117 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118 }
3119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003120 HValue* context() { return OperandAt(0); }
3121 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122 Handle<Object> name() const { return name_; }
3123
3124 virtual Representation RequiredInputRepresentation(int index) const {
3125 return Representation::Tagged();
3126 }
3127
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003128 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 private:
3131 Handle<Object> name_;
3132};
3133
3134
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003135class HLoadFunctionPrototype: public HUnaryOperation {
3136 public:
3137 explicit HLoadFunctionPrototype(HValue* function)
3138 : HUnaryOperation(function) {
3139 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003140 SetFlag(kUseGVN);
3141 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003142 }
3143
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003144 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003145
3146 virtual Representation RequiredInputRepresentation(int index) const {
3147 return Representation::Tagged();
3148 }
3149
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003150 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003151
3152 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003153 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003154};
3155
3156
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003157class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003158 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003159 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003161 SetFlag(kDependsOnArrayElements);
3162 SetFlag(kUseGVN);
3163 }
3164
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003165 HValue* object() { return OperandAt(0); }
3166 HValue* key() { return OperandAt(1); }
3167
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003168 virtual Representation RequiredInputRepresentation(int index) const {
3169 // The key is supposed to be Integer32.
3170 return (index == 1) ? Representation::Integer32()
3171 : Representation::Tagged();
3172 }
3173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003174 virtual void PrintDataTo(StringStream* stream);
3175
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003176 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003177
3178 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003179 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180};
3181
3182
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003183class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003184 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003185 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3186 HValue* key,
3187 ExternalArrayType array_type)
3188 : HBinaryOperation(external_elements, key),
3189 array_type_(array_type) {
3190 if (array_type == kExternalFloatArray) {
3191 set_representation(Representation::Double());
3192 } else {
3193 set_representation(Representation::Integer32());
3194 }
3195 SetFlag(kDependsOnSpecializedArrayElements);
3196 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003197 SetFlag(kDependsOnCalls);
3198 SetFlag(kUseGVN);
3199 }
3200
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003201 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003202
3203 virtual Representation RequiredInputRepresentation(int index) const {
3204 // The key is supposed to be Integer32, but the base pointer
3205 // for the element load is a naked pointer.
3206 return (index == 1) ? Representation::Integer32()
3207 : Representation::External();
3208 }
3209
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003210 HValue* external_pointer() { return OperandAt(0); }
3211 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003212 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003213
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003214 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003215
3216 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003217 virtual bool DataEquals(HValue* other) {
3218 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3219 HLoadKeyedSpecializedArrayElement* cast_other =
3220 HLoadKeyedSpecializedArrayElement::cast(other);
3221 return array_type_ == cast_other->array_type();
3222 }
3223
3224 private:
3225 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003226};
3227
3228
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003229class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003230 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003231 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3232 set_representation(Representation::Tagged());
3233 SetOperandAt(0, obj);
3234 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003235 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003236 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003237 }
3238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003239 HValue* object() { return OperandAt(0); }
3240 HValue* key() { return OperandAt(1); }
3241 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003243 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003244
3245 virtual Representation RequiredInputRepresentation(int index) const {
3246 return Representation::Tagged();
3247 }
3248
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003249 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003250};
3251
3252
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003253class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003254 public:
3255 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003256 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003257 HValue* val,
3258 bool in_object,
3259 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003260 : HBinaryOperation(obj, val),
3261 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003262 is_in_object_(in_object),
3263 offset_(offset) {
3264 if (is_in_object_) {
3265 SetFlag(kChangesInobjectFields);
3266 } else {
3267 SetFlag(kChangesBackingStoreFields);
3268 }
3269 }
3270
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003271 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003272
3273 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003274 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003275 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003276 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003278 HValue* object() { return OperandAt(0); }
3279 HValue* value() { return OperandAt(1); }
3280
3281 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003282 bool is_in_object() const { return is_in_object_; }
3283 int offset() const { return offset_; }
3284 Handle<Map> transition() const { return transition_; }
3285 void set_transition(Handle<Map> map) { transition_ = map; }
3286
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003287 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003288 return StoringValueNeedsWriteBarrier(value());
3289 }
3290
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003291 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003292 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003293 bool is_in_object_;
3294 int offset_;
3295 Handle<Map> transition_;
3296};
3297
3298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003299class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003300 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003301 HStoreNamedGeneric(HValue* context,
3302 HValue* object,
3303 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003304 HValue* value,
3305 bool strict_mode)
3306 : name_(name),
3307 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003308 SetOperandAt(0, object);
3309 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003310 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003311 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003312 }
3313
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003314 HValue* object() { return OperandAt(0); }
3315 HValue* value() { return OperandAt(1); }
3316 HValue* context() { return OperandAt(2); }
3317 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003318 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003320 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003321
3322 virtual Representation RequiredInputRepresentation(int index) const {
3323 return Representation::Tagged();
3324 }
3325
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003326 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003328 private:
3329 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003330 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003331};
3332
3333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003334class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003335 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003336 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3337 SetOperandAt(0, obj);
3338 SetOperandAt(1, key);
3339 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003340 SetFlag(kChangesArrayElements);
3341 }
3342
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003343 virtual Representation RequiredInputRepresentation(int index) const {
3344 // The key is supposed to be Integer32.
3345 return (index == 1) ? Representation::Integer32()
3346 : Representation::Tagged();
3347 }
3348
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003349 HValue* object() { return OperandAt(0); }
3350 HValue* key() { return OperandAt(1); }
3351 HValue* value() { return OperandAt(2); }
3352
3353 bool NeedsWriteBarrier() {
3354 return StoringValueNeedsWriteBarrier(value());
3355 }
3356
3357 virtual void PrintDataTo(StringStream* stream);
3358
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003359 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003360};
3361
3362
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003363class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003364 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003365 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3366 HValue* key,
3367 HValue* val,
3368 ExternalArrayType array_type)
3369 : array_type_(array_type) {
3370 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003371 SetOperandAt(0, external_elements);
3372 SetOperandAt(1, key);
3373 SetOperandAt(2, val);
3374 }
3375
3376 virtual void PrintDataTo(StringStream* stream);
3377
3378 virtual Representation RequiredInputRepresentation(int index) const {
3379 if (index == 0) {
3380 return Representation::External();
3381 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003382 if (index == 2 && array_type() == kExternalFloatArray) {
3383 return Representation::Double();
3384 } else {
3385 return Representation::Integer32();
3386 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003387 }
3388 }
3389
3390 HValue* external_pointer() { return OperandAt(0); }
3391 HValue* key() { return OperandAt(1); }
3392 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003393 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003394
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003395 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3396
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003397 private:
3398 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003399};
3400
3401
3402class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003404 HStoreKeyedGeneric(HValue* context,
3405 HValue* object,
3406 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003407 HValue* value,
3408 bool strict_mode)
3409 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003410 SetOperandAt(0, object);
3411 SetOperandAt(1, key);
3412 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003413 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003414 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003415 }
3416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003417 HValue* object() { return OperandAt(0); }
3418 HValue* key() { return OperandAt(1); }
3419 HValue* value() { return OperandAt(2); }
3420 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003421 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003422
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003423 virtual Representation RequiredInputRepresentation(int index) const {
3424 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003425 }
3426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003427 virtual void PrintDataTo(StringStream* stream);
3428
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003429 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003430
3431 private:
3432 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003433};
3434
3435
danno@chromium.org160a7b02011-04-18 15:51:38 +00003436class HStringAdd: public HBinaryOperation {
3437 public:
3438 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3439 set_representation(Representation::Tagged());
3440 SetFlag(kUseGVN);
3441 SetFlag(kDependsOnMaps);
3442 }
3443
3444 virtual Representation RequiredInputRepresentation(int index) const {
3445 return Representation::Tagged();
3446 }
3447
3448 virtual HType CalculateInferredType() {
3449 return HType::String();
3450 }
3451
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003452 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003453
3454 protected:
3455 virtual bool DataEquals(HValue* other) { return true; }
3456};
3457
3458
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003459class HStringCharCodeAt: public HBinaryOperation {
3460 public:
3461 HStringCharCodeAt(HValue* string, HValue* index)
3462 : HBinaryOperation(string, index) {
3463 set_representation(Representation::Integer32());
3464 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003465 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003466 }
3467
3468 virtual Representation RequiredInputRepresentation(int index) const {
3469 // The index is supposed to be Integer32.
3470 return (index == 1) ? Representation::Integer32()
3471 : Representation::Tagged();
3472 }
3473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003474 HValue* string() { return OperandAt(0); }
3475 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003476
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003477 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003478
3479 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003480 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003481
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003482 virtual Range* InferRange() {
3483 return new Range(0, String::kMaxUC16CharCode);
3484 }
3485};
3486
3487
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003488class HStringCharFromCode: public HUnaryOperation {
3489 public:
3490 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3491 set_representation(Representation::Tagged());
3492 SetFlag(kUseGVN);
3493 }
3494
3495 virtual Representation RequiredInputRepresentation(int index) const {
3496 return Representation::Integer32();
3497 }
3498
3499 virtual bool DataEquals(HValue* other) { return true; }
3500
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003501 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003502};
3503
3504
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003505class HStringLength: public HUnaryOperation {
3506 public:
3507 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3508 set_representation(Representation::Tagged());
3509 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003510 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003511 }
3512
3513 virtual Representation RequiredInputRepresentation(int index) const {
3514 return Representation::Tagged();
3515 }
3516
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003517 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003518 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3519 return HType::Smi();
3520 }
3521
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003522 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003523
3524 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003525 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003526
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003527 virtual Range* InferRange() {
3528 return new Range(0, String::kMaxLength);
3529 }
3530};
3531
3532
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003533template <int V>
3534class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003535 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003536 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003537 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003538 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003539 }
3540
3541 int literal_index() const { return literal_index_; }
3542 int depth() const { return depth_; }
3543
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003544 private:
3545 int literal_index_;
3546 int depth_;
3547};
3548
3549
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003550class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003551 public:
3552 HArrayLiteral(Handle<FixedArray> constant_elements,
3553 int length,
3554 int literal_index,
3555 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003556 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003557 length_(length),
3558 constant_elements_(constant_elements) {}
3559
3560 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3561 int length() const { return length_; }
3562
3563 bool IsCopyOnWrite() const;
3564
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003565 virtual Representation RequiredInputRepresentation(int index) const {
3566 return Representation::None();
3567 }
3568
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003569 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003570
3571 private:
3572 int length_;
3573 Handle<FixedArray> constant_elements_;
3574};
3575
3576
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003577class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003578 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003579 HObjectLiteral(HValue* context,
3580 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003581 bool fast_elements,
3582 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003583 int depth,
3584 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003585 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003586 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003587 fast_elements_(fast_elements),
3588 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003589 SetOperandAt(0, context);
3590 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003591
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003592 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003593 Handle<FixedArray> constant_properties() const {
3594 return constant_properties_;
3595 }
3596 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003597 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003598
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003599 virtual Representation RequiredInputRepresentation(int index) const {
3600 return Representation::Tagged();
3601 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003602
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003603 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003604
3605 private:
3606 Handle<FixedArray> constant_properties_;
3607 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003608 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003609};
3610
3611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003612class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613 public:
3614 HRegExpLiteral(Handle<String> pattern,
3615 Handle<String> flags,
3616 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618 pattern_(pattern),
3619 flags_(flags) { }
3620
3621 Handle<String> pattern() { return pattern_; }
3622 Handle<String> flags() { return flags_; }
3623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003624 virtual Representation RequiredInputRepresentation(int index) const {
3625 return Representation::None();
3626 }
3627
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003628 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003629
3630 private:
3631 Handle<String> pattern_;
3632 Handle<String> flags_;
3633};
3634
3635
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003636class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003637 public:
3638 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3639 : shared_info_(shared), pretenure_(pretenure) {
3640 set_representation(Representation::Tagged());
3641 }
3642
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003643 virtual Representation RequiredInputRepresentation(int index) const {
3644 return Representation::None();
3645 }
3646
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003647 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003648
3649 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3650 bool pretenure() const { return pretenure_; }
3651
3652 private:
3653 Handle<SharedFunctionInfo> shared_info_;
3654 bool pretenure_;
3655};
3656
3657
3658class HTypeof: public HUnaryOperation {
3659 public:
3660 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3661 set_representation(Representation::Tagged());
3662 }
3663
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003664 virtual Representation RequiredInputRepresentation(int index) const {
3665 return Representation::Tagged();
3666 }
3667
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003668 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003669};
3670
3671
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003672class HToFastProperties: public HUnaryOperation {
3673 public:
3674 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3675 // This instruction is not marked as having side effects, but
3676 // changes the map of the input operand. Use it only when creating
3677 // object literals.
3678 ASSERT(value->IsObjectLiteral());
3679 set_representation(Representation::Tagged());
3680 }
3681
3682 virtual Representation RequiredInputRepresentation(int index) const {
3683 return Representation::Tagged();
3684 }
3685
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003686 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003687};
3688
3689
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690class HValueOf: public HUnaryOperation {
3691 public:
3692 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3693 set_representation(Representation::Tagged());
3694 }
3695
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003696 virtual Representation RequiredInputRepresentation(int index) const {
3697 return Representation::Tagged();
3698 }
3699
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003700 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701};
3702
3703
3704class HDeleteProperty: public HBinaryOperation {
3705 public:
3706 HDeleteProperty(HValue* obj, HValue* key)
3707 : HBinaryOperation(obj, key) {
3708 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003709 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003710 }
3711
3712 virtual Representation RequiredInputRepresentation(int index) const {
3713 return Representation::Tagged();
3714 }
3715
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003716 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003717
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003718 HValue* object() { return left(); }
3719 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003720};
3721
3722#undef DECLARE_INSTRUCTION
3723#undef DECLARE_CONCRETE_INSTRUCTION
3724
3725} } // namespace v8::internal
3726
3727#endif // V8_HYDROGEN_INSTRUCTIONS_H_