blob: 00e9bd63efdf1a1af54ff144cd8b14c6151edb80 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000038#include "utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000039#include "zone.h"
40
41namespace v8 {
42namespace internal {
43
44// Forward declarations.
45class HBasicBlock;
46class HEnvironment;
47class HInstruction;
48class HLoopInformation;
49class HValue;
50class LInstruction;
51class LChunkBuilder;
52
53
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000054#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(ControlInstruction) \
57 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058
59
60#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000061 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000062 V(AccessArgumentsAt) \
63 V(Add) \
64 V(ApplyArguments) \
65 V(ArgumentsElements) \
66 V(ArgumentsLength) \
67 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000068 V(ArrayLiteral) \
69 V(BitAnd) \
70 V(BitNot) \
71 V(BitOr) \
72 V(BitXor) \
73 V(BlockEntry) \
74 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000075 V(CallConstantFunction) \
76 V(CallFunction) \
77 V(CallGlobal) \
78 V(CallKeyed) \
79 V(CallKnownGlobal) \
80 V(CallNamed) \
81 V(CallNew) \
82 V(CallRuntime) \
83 V(CallStub) \
84 V(Change) \
85 V(CheckFunction) \
86 V(CheckInstanceType) \
87 V(CheckMap) \
88 V(CheckNonSmi) \
89 V(CheckPrototypeMaps) \
90 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000091 V(ClampToUint8) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000092 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000093 V(Compare) \
94 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000095 V(CompareMap) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +000096 V(CompareSymbolEq) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000097 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000098 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000099 V(DeleteProperty) \
100 V(Deoptimize) \
101 V(Div) \
102 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000103 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000104 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000105 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000107 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(GlobalObject) \
109 V(GlobalReceiver) \
110 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000111 V(HasCachedArrayIndex) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000112 V(HasInstanceType) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000113 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000114 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000115 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000116 V(InvokeFunction) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000117 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000119 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(IsSmi) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000121 V(IsUndetectable) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000122 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000123 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000124 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000126 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000127 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000128 V(LoadGlobalCell) \
129 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130 V(LoadKeyedFastElement) \
131 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000132 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000133 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000134 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(LoadNamedGeneric) \
136 V(Mod) \
137 V(Mul) \
138 V(ObjectLiteral) \
139 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000140 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000141 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000142 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143 V(PushArgument) \
144 V(RegExpLiteral) \
145 V(Return) \
146 V(Sar) \
147 V(Shl) \
148 V(Shr) \
149 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000150 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000151 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000152 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000153 V(StoreGlobalCell) \
154 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(StoreKeyedFastElement) \
156 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000157 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(StoreNamedField) \
159 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000160 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000161 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000162 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000163 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000164 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000165 V(Test) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000166 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000167 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000168 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000169 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(Typeof) \
171 V(TypeofIs) \
172 V(UnaryMathOperation) \
173 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000174 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(ValueOf)
176
177#define GVN_FLAG_LIST(V) \
178 V(Calls) \
179 V(InobjectFields) \
180 V(BackingStoreFields) \
181 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000182 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000183 V(GlobalVars) \
184 V(Maps) \
185 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000186 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000187 V(OsrEntries)
188
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000189#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000190 virtual bool Is##type() const { return true; } \
191 static H##type* cast(HValue* value) { \
192 ASSERT(value->Is##type()); \
193 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000194 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195
196
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000197#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000199 static H##type* cast(HValue* value) { \
200 ASSERT(value->Is##type()); \
201 return reinterpret_cast<H##type*>(value); \
202 } \
203 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204
205
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206class Range: public ZoneObject {
207 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000208 Range()
209 : lower_(kMinInt),
210 upper_(kMaxInt),
211 next_(NULL),
212 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213
214 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000215 : lower_(lower),
216 upper_(upper),
217 next_(NULL),
218 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000219
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000220 int32_t upper() const { return upper_; }
221 int32_t lower() const { return lower_; }
222 Range* next() const { return next_; }
223 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
224 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 int32_t Mask() const;
227 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
228 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
229 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
230 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000231 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
232 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
233 bool IsInSmiRange() const {
234 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000236 void KeepOrder();
237 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000238
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000239 void StackUpon(Range* other) {
240 Intersect(other);
241 next_ = other;
242 }
243
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000244 void Intersect(Range* other);
245 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000246
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 void AddConstant(int32_t value);
248 void Sar(int32_t value);
249 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000250 bool AddAndCheckOverflow(Range* other);
251 bool SubAndCheckOverflow(Range* other);
252 bool MulAndCheckOverflow(Range* other);
253
254 private:
255 int32_t lower_;
256 int32_t upper_;
257 Range* next_;
258 bool can_be_minus_zero_;
259};
260
261
262class Representation {
263 public:
264 enum Kind {
265 kNone,
266 kTagged,
267 kDouble,
268 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000269 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000270 kNumRepresentations
271 };
272
273 Representation() : kind_(kNone) { }
274
275 static Representation None() { return Representation(kNone); }
276 static Representation Tagged() { return Representation(kTagged); }
277 static Representation Integer32() { return Representation(kInteger32); }
278 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000279 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000280
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000281 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282 return kind_ == other.kind_;
283 }
284
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000285 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000286 bool IsNone() const { return kind_ == kNone; }
287 bool IsTagged() const { return kind_ == kTagged; }
288 bool IsInteger32() const { return kind_ == kInteger32; }
289 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000290 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291 bool IsSpecialization() const {
292 return kind_ == kInteger32 || kind_ == kDouble;
293 }
294 const char* Mnemonic() const;
295
296 private:
297 explicit Representation(Kind k) : kind_(k) { }
298
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000299 // Make sure kind fits in int8.
300 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
301
302 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000303};
304
305
306class HType {
307 public:
308 HType() : type_(kUninitialized) { }
309
310 static HType Tagged() { return HType(kTagged); }
311 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
312 static HType TaggedNumber() { return HType(kTaggedNumber); }
313 static HType Smi() { return HType(kSmi); }
314 static HType HeapNumber() { return HType(kHeapNumber); }
315 static HType String() { return HType(kString); }
316 static HType Boolean() { return HType(kBoolean); }
317 static HType NonPrimitive() { return HType(kNonPrimitive); }
318 static HType JSArray() { return HType(kJSArray); }
319 static HType JSObject() { return HType(kJSObject); }
320 static HType Uninitialized() { return HType(kUninitialized); }
321
322 // Return the weakest (least precise) common type.
323 HType Combine(HType other) {
324 return HType(static_cast<Type>(type_ & other.type_));
325 }
326
327 bool Equals(const HType& other) {
328 return type_ == other.type_;
329 }
330
331 bool IsSubtypeOf(const HType& other) {
332 return Combine(other).Equals(other);
333 }
334
335 bool IsTagged() {
336 ASSERT(type_ != kUninitialized);
337 return ((type_ & kTagged) == kTagged);
338 }
339
340 bool IsTaggedPrimitive() {
341 ASSERT(type_ != kUninitialized);
342 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
343 }
344
345 bool IsTaggedNumber() {
346 ASSERT(type_ != kUninitialized);
347 return ((type_ & kTaggedNumber) == kTaggedNumber);
348 }
349
350 bool IsSmi() {
351 ASSERT(type_ != kUninitialized);
352 return ((type_ & kSmi) == kSmi);
353 }
354
355 bool IsHeapNumber() {
356 ASSERT(type_ != kUninitialized);
357 return ((type_ & kHeapNumber) == kHeapNumber);
358 }
359
360 bool IsString() {
361 ASSERT(type_ != kUninitialized);
362 return ((type_ & kString) == kString);
363 }
364
365 bool IsBoolean() {
366 ASSERT(type_ != kUninitialized);
367 return ((type_ & kBoolean) == kBoolean);
368 }
369
370 bool IsNonPrimitive() {
371 ASSERT(type_ != kUninitialized);
372 return ((type_ & kNonPrimitive) == kNonPrimitive);
373 }
374
375 bool IsJSArray() {
376 ASSERT(type_ != kUninitialized);
377 return ((type_ & kJSArray) == kJSArray);
378 }
379
380 bool IsJSObject() {
381 ASSERT(type_ != kUninitialized);
382 return ((type_ & kJSObject) == kJSObject);
383 }
384
385 bool IsUninitialized() {
386 return type_ == kUninitialized;
387 }
388
389 static HType TypeFromValue(Handle<Object> value);
390
391 const char* ToString();
392 const char* ToShortString();
393
394 private:
395 enum Type {
396 kTagged = 0x1, // 0000 0000 0000 0001
397 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
398 kTaggedNumber = 0xd, // 0000 0000 0000 1101
399 kSmi = 0x1d, // 0000 0000 0001 1101
400 kHeapNumber = 0x2d, // 0000 0000 0010 1101
401 kString = 0x45, // 0000 0000 0100 0101
402 kBoolean = 0x85, // 0000 0000 1000 0101
403 kNonPrimitive = 0x101, // 0000 0001 0000 0001
404 kJSObject = 0x301, // 0000 0011 0000 0001
405 kJSArray = 0x701, // 0000 0111 1000 0001
406 kUninitialized = 0x1fff // 0001 1111 1111 1111
407 };
408
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000409 // Make sure type fits in int16.
410 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
411
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000412 explicit HType(Type t) : type_(t) { }
413
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000414 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000415};
416
417
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000418class HUseListNode: public ZoneObject {
419 public:
420 HUseListNode(HValue* value, int index, HUseListNode* tail)
421 : tail_(tail), value_(value), index_(index) {
422 }
423
424 HUseListNode* tail() const { return tail_; }
425 HValue* value() const { return value_; }
426 int index() const { return index_; }
427
428 void set_tail(HUseListNode* list) { tail_ = list; }
429
430#ifdef DEBUG
431 void Zap() {
432 tail_ = reinterpret_cast<HUseListNode*>(1);
433 value_ = NULL;
434 index_ = -1;
435 }
436#endif
437
438 private:
439 HUseListNode* tail_;
440 HValue* value_;
441 int index_;
442};
443
444
445// We reuse use list nodes behind the scenes as uses are added and deleted.
446// This class is the safe way to iterate uses while deleting them.
447class HUseIterator BASE_EMBEDDED {
448 public:
449 bool Done() { return current_ == NULL; }
450 void Advance();
451
452 HValue* value() {
453 ASSERT(!Done());
454 return value_;
455 }
456
457 int index() {
458 ASSERT(!Done());
459 return index_;
460 }
461
462 private:
463 explicit HUseIterator(HUseListNode* head);
464
465 HUseListNode* current_;
466 HUseListNode* next_;
467 HValue* value_;
468 int index_;
469
470 friend class HValue;
471};
472
473
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000474class HValue: public ZoneObject {
475 public:
476 static const int kNoNumber = -1;
477
478 // There must be one corresponding kDepends flag for every kChanges flag and
479 // the order of the kChanges flags must be exactly the same as of the kDepends
480 // flags.
481 enum Flag {
482 // Declare global value numbering flags.
483 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
484 GVN_FLAG_LIST(DECLARE_DO)
485 #undef DECLARE_DO
486 kFlexibleRepresentation,
487 kUseGVN,
488 kCanOverflow,
489 kBailoutOnMinusZero,
490 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000491 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000492 kIsArguments,
493 kTruncatingToInt32,
494 kLastFlag = kTruncatingToInt32
495 };
496
497 STATIC_ASSERT(kLastFlag < kBitsPerInt);
498
499 static const int kChangesToDependsFlagsLeftShift = 1;
500
501 static int ChangesFlagsMask() {
502 int result = 0;
503 // Create changes mask.
504#define DECLARE_DO(type) result |= (1 << kChanges##type);
505 GVN_FLAG_LIST(DECLARE_DO)
506#undef DECLARE_DO
507 return result;
508 }
509
510 static int DependsFlagsMask() {
511 return ConvertChangesToDependsFlags(ChangesFlagsMask());
512 }
513
514 static int ConvertChangesToDependsFlags(int flags) {
515 return flags << kChangesToDependsFlagsLeftShift;
516 }
517
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000518 static HValue* cast(HValue* value) { return value; }
519
520 enum Opcode {
521 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000522 #define DECLARE_OPCODE(type) k##type,
523 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
524 kPhi
525 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000526 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000527 virtual Opcode opcode() const = 0;
528
529 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
530 #define DECLARE_PREDICATE(type) \
531 bool Is##type() const { return opcode() == k##type; }
532 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
533 #undef DECLARE_PREDICATE
534 bool IsPhi() const { return opcode() == kPhi; }
535
536 // Declare virtual predicates for abstract HInstruction or HValue
537 #define DECLARE_PREDICATE(type) \
538 virtual bool Is##type() const { return false; }
539 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
540 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000541
542 HValue() : block_(NULL),
543 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000544 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000545 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000546 range_(NULL),
547 flags_(0) {}
548 virtual ~HValue() {}
549
550 HBasicBlock* block() const { return block_; }
551 void SetBlock(HBasicBlock* block);
552
553 int id() const { return id_; }
554 void set_id(int id) { id_ = id; }
555
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000556 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000558 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559 Representation representation() const { return representation_; }
560 void ChangeRepresentation(Representation r) {
561 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000562 ASSERT(!r.IsNone());
563 ASSERT(CheckFlag(kFlexibleRepresentation));
564 RepresentationChanged(r);
565 representation_ = r;
566 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000567 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000569 virtual bool IsConvertibleToInteger() const { return true; }
570
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571 HType type() const { return type_; }
572 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000573 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000574 type_ = type;
575 }
576
577 // An operation needs to override this function iff:
578 // 1) it can produce an int32 output.
579 // 2) the true value of its output can potentially be minus zero.
580 // The implementation must set a flag so that it bails out in the case where
581 // it would otherwise output what should be a minus zero as an int32 zero.
582 // If the operation also exists in a form that takes int32 and outputs int32
583 // then the operation should return its input value so that we can propagate
584 // back. There are two operations that need to propagate back to more than
585 // one input. They are phi and binary add. They always return NULL and
586 // expect the caller to take care of things.
587 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
588 visited->Add(id());
589 return NULL;
590 }
591
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000592 bool IsDefinedAfter(HBasicBlock* other) const;
593
594 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000595 virtual int OperandCount() = 0;
596 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000597 void SetOperandAt(int index, HValue* value);
598
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000599 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000600 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000601 bool HasNoUses() const { return use_list_ == NULL; }
602 bool HasMultipleUses() const {
603 return use_list_ != NULL && use_list_->tail() != NULL;
604 }
605 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000606 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000607
608 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000609 void SetFlag(Flag f) { flags_ |= (1 << f); }
610 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
611 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
612
613 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
614 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
615 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000616
617 Range* range() const { return range_; }
618 bool HasRange() const { return range_ != NULL; }
619 void AddNewRange(Range* r);
620 void RemoveLastAddedRange();
621 void ComputeInitialRange();
622
623 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000624 virtual Representation RequiredInputRepresentation(int index) const = 0;
625
626 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000627 return representation();
628 }
629
630 // This gives the instruction an opportunity to replace itself with an
631 // instruction that does the same in some better way. To replace an
632 // instruction with a new one, first add the new instruction to the graph,
633 // then return it. Return NULL to have the instruction deleted.
634 virtual HValue* Canonicalize() { return this; }
635
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000636 bool Equals(HValue* other);
637 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000638
639 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000640 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000641 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000642 void PrintTypeTo(StringStream* stream);
643 void PrintRangeTo(StringStream* stream);
644 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000646 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000647
648 // Updated the inferred type of this instruction and returns true if
649 // it has changed.
650 bool UpdateInferredType();
651
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000652 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000653
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000655 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000656#endif
657
658 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000659 // This function must be overridden for instructions with flag kUseGVN, to
660 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000661 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000662 UNREACHABLE();
663 return false;
664 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000665 virtual void RepresentationChanged(Representation to) { }
666 virtual Range* InferRange();
667 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000668 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000669 void clear_block() {
670 ASSERT(block_ != NULL);
671 block_ = NULL;
672 }
673
674 void set_representation(Representation r) {
675 // Representation is set-once.
676 ASSERT(representation_.IsNone() && !r.IsNone());
677 representation_ = r;
678 }
679
680 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000681 // A flag mask to mark an instruction as having arbitrary side effects.
682 static int AllSideEffects() {
683 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
684 }
685
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000686 // Remove the matching use from the use list if present. Returns the
687 // removed list node or NULL.
688 HUseListNode* RemoveUse(HValue* value, int index);
689
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000690 void RegisterUse(int index, HValue* new_value);
691
692 HBasicBlock* block_;
693
694 // The id of this instruction in the hydrogen graph, assigned when first
695 // added to the graph. Reflects creation order.
696 int id_;
697
698 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000699 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000700 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000701 Range* range_;
702 int flags_;
703
704 DISALLOW_COPY_AND_ASSIGN(HValue);
705};
706
707
708class HInstruction: public HValue {
709 public:
710 HInstruction* next() const { return next_; }
711 HInstruction* previous() const { return previous_; }
712
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000713 virtual void PrintTo(StringStream* stream);
714 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000715
716 bool IsLinked() const { return block() != NULL; }
717 void Unlink();
718 void InsertBefore(HInstruction* next);
719 void InsertAfter(HInstruction* previous);
720
721 int position() const { return position_; }
722 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
723 void set_position(int position) { position_ = position; }
724
725 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
726
727#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000728 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000729#endif
730
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000731 virtual bool IsCall() { return false; }
732
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000733 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000734
735 protected:
736 HInstruction()
737 : next_(NULL),
738 previous_(NULL),
739 position_(RelocInfo::kNoPosition) {
740 SetFlag(kDependsOnOsrEntries);
741 }
742
743 virtual void DeleteFromGraph() { Unlink(); }
744
745 private:
746 void InitializeAsFirst(HBasicBlock* block) {
747 ASSERT(!IsLinked());
748 SetBlock(block);
749 }
750
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000751 void PrintMnemonicTo(StringStream* stream);
752
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000753 HInstruction* next_;
754 HInstruction* previous_;
755 int position_;
756
757 friend class HBasicBlock;
758};
759
760
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000761template<int V>
762class HTemplateInstruction : public HInstruction {
763 public:
764 int OperandCount() { return V; }
765 HValue* OperandAt(int i) { return inputs_[i]; }
766
767 protected:
768 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
769
770 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000771 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000772};
773
774
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000775class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000776 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000777 virtual HBasicBlock* SuccessorAt(int i) = 0;
778 virtual int SuccessorCount() = 0;
779
780 virtual void PrintDataTo(StringStream* stream);
781
782 HBasicBlock* FirstSuccessor() {
783 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
784 }
785 HBasicBlock* SecondSuccessor() {
786 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
787 }
788
789 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
790};
791
792
793class HSuccessorIterator BASE_EMBEDDED {
794 public:
795 explicit HSuccessorIterator(HControlInstruction* instr)
796 : instr_(instr), current_(0) { }
797
798 bool Done() { return current_ >= instr_->SuccessorCount(); }
799 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
800 void Advance() { current_++; }
801
802 private:
803 HControlInstruction* instr_;
804 int current_;
805};
806
807
808template<int S, int V>
809class HTemplateControlInstruction: public HControlInstruction {
810 public:
811 int SuccessorCount() { return S; }
812 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
813
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000814 int OperandCount() { return V; }
815 HValue* OperandAt(int i) { return inputs_[i]; }
816
817 protected:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000818 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000819 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
820
821 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000822 EmbeddedContainer<HBasicBlock*, S> successors_;
823 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000824};
825
826
827class HBlockEntry: public HTemplateInstruction<0> {
828 public:
829 virtual Representation RequiredInputRepresentation(int index) const {
830 return Representation::None();
831 }
832
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000833 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000834};
835
836
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000837// We insert soft-deoptimize when we hit code with unknown typefeedback,
838// so that we get a chance of re-optimizing with useful typefeedback.
839// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
840class HSoftDeoptimize: public HTemplateInstruction<0> {
841 public:
842 virtual Representation RequiredInputRepresentation(int index) const {
843 return Representation::None();
844 }
845
846 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
847};
848
849
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000850class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000851 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000852 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000853
854 virtual Representation RequiredInputRepresentation(int index) const {
855 return Representation::None();
856 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000857
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000858 virtual int OperandCount() { return values_.length(); }
859 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000860 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000861
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000862 virtual int SuccessorCount() { return 0; }
863 virtual HBasicBlock* SuccessorAt(int i) {
864 UNREACHABLE();
865 return NULL;
866 }
867
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000868 void AddEnvironmentValue(HValue* value) {
869 values_.Add(NULL);
870 SetOperandAt(values_.length() - 1, value);
871 }
872
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000873 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000874
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000875 enum UseEnvironment {
876 kNoUses,
877 kUseAll
878 };
879
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000880 protected:
881 virtual void InternalSetOperandAt(int index, HValue* value) {
882 values_[index] = value;
883 }
884
885 private:
886 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887};
888
889
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000890class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000892 explicit HGoto(HBasicBlock* target)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000893 : include_stack_check_(false) {
894 SetSuccessorAt(0, target);
895 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000897 void set_include_stack_check(bool include_stack_check) {
898 include_stack_check_ = include_stack_check;
899 }
900 bool include_stack_check() const { return include_stack_check_; }
901
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000902 virtual Representation RequiredInputRepresentation(int index) const {
903 return Representation::None();
904 }
905
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000906 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907
908 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909 bool include_stack_check_;
910};
911
912
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000913class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000914 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000915 HUnaryControlInstruction(HValue* value,
916 HBasicBlock* true_target,
917 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000918 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000919 SetSuccessorAt(0, true_target);
920 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921 }
922
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000923 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000924
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000925 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926};
927
928
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000929class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000931 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
932 : HUnaryControlInstruction(value, true_target, false_target) {
933 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934 }
935
936 virtual Representation RequiredInputRepresentation(int index) const {
937 return Representation::None();
938 }
939
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000940 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941};
942
943
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000944class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000945 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000946 HCompareMap(HValue* value,
947 Handle<Map> map,
948 HBasicBlock* true_target,
949 HBasicBlock* false_target)
950 : HUnaryControlInstruction(value, true_target, false_target),
951 map_(map) {
952 ASSERT(true_target != NULL);
953 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000954 ASSERT(!map.is_null());
955 }
956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000957 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000958
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959 Handle<Map> map() const { return map_; }
960
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000961 virtual Representation RequiredInputRepresentation(int index) const {
962 return Representation::Tagged();
963 }
964
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000965 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000966
967 private:
968 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000969};
970
971
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000972class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000973 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000974 explicit HReturn(HValue* value) {
975 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000976 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000977
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000978 virtual Representation RequiredInputRepresentation(int index) const {
979 return Representation::Tagged();
980 }
981
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000982 virtual void PrintDataTo(StringStream* stream);
983
984 HValue* value() { return OperandAt(0); }
985
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000986 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987};
988
989
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000990class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000991 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000992 virtual Representation RequiredInputRepresentation(int index) const {
993 return Representation::None();
994 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000995
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000996 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997};
998
999
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001000class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001001 public:
1002 explicit HUnaryOperation(HValue* value) {
1003 SetOperandAt(0, value);
1004 }
1005
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001006 static HUnaryOperation* cast(HValue* value) {
1007 return reinterpret_cast<HUnaryOperation*>(value);
1008 }
1009
1010 virtual bool CanTruncateToInt32() const {
1011 return CheckFlag(kTruncatingToInt32);
1012 }
1013
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001014 HValue* value() { return OperandAt(0); }
1015 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001016};
1017
1018
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001019class HThrow: public HUnaryOperation {
1020 public:
1021 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1022 SetAllSideEffects();
1023 }
1024
1025 virtual Representation RequiredInputRepresentation(int index) const {
1026 return Representation::Tagged();
1027 }
1028
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001029 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001030};
1031
1032
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001033class HUseConst: public HUnaryOperation {
1034 public:
1035 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1036
1037 virtual Representation RequiredInputRepresentation(int index) const {
1038 return Representation::None();
1039 }
1040
1041 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1042};
1043
1044
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001045class HForceRepresentation: public HTemplateInstruction<1> {
1046 public:
1047 HForceRepresentation(HValue* value, Representation required_representation) {
1048 SetOperandAt(0, value);
1049 set_representation(required_representation);
1050 }
1051
1052 HValue* value() { return OperandAt(0); }
1053
1054 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1055
1056 virtual Representation RequiredInputRepresentation(int index) const {
1057 return representation(); // Same as the output representation.
1058 }
1059
1060 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1061};
1062
1063
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001064class HChange: public HUnaryOperation {
1065 public:
1066 HChange(HValue* value,
1067 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001068 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001069 bool is_truncating,
1070 bool deoptimize_on_undefined)
1071 : HUnaryOperation(value),
1072 from_(from),
1073 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001074 ASSERT(!from.IsNone() && !to.IsNone());
1075 ASSERT(!from.Equals(to));
1076 set_representation(to);
1077 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001078 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001079 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1080 value->range()->IsInSmiRange()) {
1081 set_type(HType::Smi());
1082 }
1083 }
1084
1085 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1086
1087 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001088 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001089 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001090 virtual Representation RequiredInputRepresentation(int index) const {
1091 return from_;
1092 }
1093
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001094 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001095
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001096 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001097
1098 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001099 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001100 if (!other->IsChange()) return false;
1101 HChange* change = HChange::cast(other);
1102 return value() == change->value()
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001103 && to().Equals(change->to())
1104 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001105 }
1106
1107 private:
1108 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001109 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110};
1111
1112
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001113class HClampToUint8: public HUnaryOperation {
1114 public:
1115 explicit HClampToUint8(HValue* value)
1116 : HUnaryOperation(value),
1117 input_rep_(Representation::None()) {
1118 SetFlag(kFlexibleRepresentation);
1119 set_representation(Representation::Tagged());
1120 SetFlag(kUseGVN);
1121 }
1122
1123 virtual Representation RequiredInputRepresentation(int index) const {
1124 return input_rep_;
1125 }
1126
1127 virtual Representation InferredRepresentation() {
1128 // TODO(danno): Inference on input types should happen separately from
1129 // return representation.
1130 Representation new_rep = value()->representation();
1131 if (input_rep_.IsNone()) {
1132 if (!new_rep.IsNone()) {
1133 input_rep_ = new_rep;
1134 return Representation::Integer32();
1135 } else {
1136 return Representation::None();
1137 }
1138 } else {
1139 return Representation::Integer32();
1140 }
1141 }
1142
1143 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1144
1145 protected:
1146 virtual bool DataEquals(HValue* other) { return true; }
1147
1148 private:
1149 Representation input_rep_;
1150};
1151
1152
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001153class HToInt32: public HUnaryOperation {
1154 public:
1155 explicit HToInt32(HValue* value)
1156 : HUnaryOperation(value) {
1157 set_representation(Representation::Integer32());
1158 SetFlag(kUseGVN);
1159 }
1160
1161 virtual Representation RequiredInputRepresentation(int index) const {
1162 return Representation::None();
1163 }
1164
1165 virtual bool CanTruncateToInt32() const {
1166 return true;
1167 }
1168
1169 virtual HValue* Canonicalize() {
1170 if (value()->representation().IsInteger32()) {
1171 return value();
1172 } else {
1173 return this;
1174 }
1175 }
1176
1177 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1178
1179 protected:
1180 virtual bool DataEquals(HValue* other) { return true; }
1181};
1182
1183
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001184class HSimulate: public HInstruction {
1185 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001186 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001187 : ast_id_(ast_id),
1188 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001189 values_(2),
1190 assigned_indexes_(2) {}
1191 virtual ~HSimulate() {}
1192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001193 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194
1195 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1196 int ast_id() const { return ast_id_; }
1197 void set_ast_id(int id) {
1198 ASSERT(!HasAstId());
1199 ast_id_ = id;
1200 }
1201
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001202 int pop_count() const { return pop_count_; }
1203 const ZoneList<HValue*>* values() const { return &values_; }
1204 int GetAssignedIndexAt(int index) const {
1205 ASSERT(HasAssignedIndexAt(index));
1206 return assigned_indexes_[index];
1207 }
1208 bool HasAssignedIndexAt(int index) const {
1209 return assigned_indexes_[index] != kNoIndex;
1210 }
1211 void AddAssignedValue(int index, HValue* value) {
1212 AddValue(index, value);
1213 }
1214 void AddPushedValue(HValue* value) {
1215 AddValue(kNoIndex, value);
1216 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001217 virtual int OperandCount() { return values_.length(); }
1218 virtual HValue* OperandAt(int index) { return values_[index]; }
1219
1220 virtual Representation RequiredInputRepresentation(int index) const {
1221 return Representation::None();
1222 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001223
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001224 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001225
1226#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001227 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001228#endif
1229
1230 protected:
1231 virtual void InternalSetOperandAt(int index, HValue* value) {
1232 values_[index] = value;
1233 }
1234
1235 private:
1236 static const int kNoIndex = -1;
1237 void AddValue(int index, HValue* value) {
1238 assigned_indexes_.Add(index);
1239 // Resize the list of pushed values.
1240 values_.Add(NULL);
1241 // Set the operand through the base method in HValue to make sure that the
1242 // use lists are correctly updated.
1243 SetOperandAt(values_.length() - 1, value);
1244 }
1245 int ast_id_;
1246 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001247 ZoneList<HValue*> values_;
1248 ZoneList<int> assigned_indexes_;
1249};
1250
1251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001252class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253 public:
1254 HStackCheck() { }
1255
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001256 virtual Representation RequiredInputRepresentation(int index) const {
1257 return Representation::None();
1258 }
1259
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001260 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001261};
1262
1263
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001264class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001265 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001266 HEnterInlined(Handle<JSFunction> closure,
1267 FunctionLiteral* function,
1268 CallKind call_kind)
1269 : closure_(closure),
1270 function_(function),
1271 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001272 }
1273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001274 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275
1276 Handle<JSFunction> closure() const { return closure_; }
1277 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001278 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001279
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001280 virtual Representation RequiredInputRepresentation(int index) const {
1281 return Representation::None();
1282 }
1283
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001284 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001285
1286 private:
1287 Handle<JSFunction> closure_;
1288 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001289 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001290};
1291
1292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001293class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294 public:
1295 HLeaveInlined() {}
1296
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001297 virtual Representation RequiredInputRepresentation(int index) const {
1298 return Representation::None();
1299 }
1300
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001301 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302};
1303
1304
1305class HPushArgument: public HUnaryOperation {
1306 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1308 set_representation(Representation::Tagged());
1309 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001310
1311 virtual Representation RequiredInputRepresentation(int index) const {
1312 return Representation::Tagged();
1313 }
1314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001315 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001317 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318};
1319
1320
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001321class HThisFunction: public HTemplateInstruction<0> {
1322 public:
1323 HThisFunction() {
1324 set_representation(Representation::Tagged());
1325 SetFlag(kUseGVN);
1326 }
1327
1328 virtual Representation RequiredInputRepresentation(int index) const {
1329 return Representation::None();
1330 }
1331
1332 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1333
1334 protected:
1335 virtual bool DataEquals(HValue* other) { return true; }
1336};
1337
1338
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001339class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001340 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001341 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001342 set_representation(Representation::Tagged());
1343 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001344 }
1345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001346 virtual Representation RequiredInputRepresentation(int index) const {
1347 return Representation::None();
1348 }
1349
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001350 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001351
1352 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001353 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001354};
1355
1356
1357class HOuterContext: public HUnaryOperation {
1358 public:
1359 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1360 set_representation(Representation::Tagged());
1361 SetFlag(kUseGVN);
1362 }
1363
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001364 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001366 virtual Representation RequiredInputRepresentation(int index) const {
1367 return Representation::Tagged();
1368 }
1369
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001370 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001371 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001372};
1373
1374
1375class HGlobalObject: public HUnaryOperation {
1376 public:
1377 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1378 set_representation(Representation::Tagged());
1379 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380 }
1381
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001382 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001383
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001384 virtual Representation RequiredInputRepresentation(int index) const {
1385 return Representation::Tagged();
1386 }
1387
ager@chromium.org378b34e2011-01-28 08:04:38 +00001388 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001389 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001390};
1391
1392
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001393class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001395 explicit HGlobalReceiver(HValue* global_object)
1396 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001397 set_representation(Representation::Tagged());
1398 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001399 }
1400
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001401 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001402
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001403 virtual Representation RequiredInputRepresentation(int index) const {
1404 return Representation::Tagged();
1405 }
1406
ager@chromium.org378b34e2011-01-28 08:04:38 +00001407 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001408 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409};
1410
1411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001412template <int V>
1413class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001414 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001415 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001416 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1417 this->set_representation(Representation::Tagged());
1418 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001419 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001420
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001421 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001422
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001423 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001425 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001426
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001427 private:
1428 int argument_count_;
1429};
1430
1431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001432class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001433 public:
1434 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001435 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001436 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001437 }
1438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439 virtual Representation RequiredInputRepresentation(int index) const {
1440 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001441 }
1442
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001443 virtual void PrintDataTo(StringStream* stream);
1444
1445 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001446};
1447
1448
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001449class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001450 public:
1451 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001452 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001453 SetOperandAt(0, first);
1454 SetOperandAt(1, second);
1455 }
1456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001457 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001458
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001459 virtual Representation RequiredInputRepresentation(int index) const {
1460 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001461 }
1462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001463 HValue* first() { return OperandAt(0); }
1464 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001465};
1466
1467
danno@chromium.org160a7b02011-04-18 15:51:38 +00001468class HInvokeFunction: public HBinaryCall {
1469 public:
1470 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1471 : HBinaryCall(context, function, argument_count) {
1472 }
1473
1474 virtual Representation RequiredInputRepresentation(int index) const {
1475 return Representation::Tagged();
1476 }
1477
1478 HValue* context() { return first(); }
1479 HValue* function() { return second(); }
1480
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001481 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001482};
1483
1484
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001485class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001486 public:
1487 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001488 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001489
1490 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001491
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001493 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001494 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001495 }
1496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001497 virtual void PrintDataTo(StringStream* stream);
1498
1499 virtual Representation RequiredInputRepresentation(int index) const {
1500 return Representation::None();
1501 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001502
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001503 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001504
1505 private:
1506 Handle<JSFunction> function_;
1507};
1508
1509
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001510class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001511 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001512 HCallKeyed(HValue* context, HValue* key, int argument_count)
1513 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514 }
1515
1516 virtual Representation RequiredInputRepresentation(int index) const {
1517 return Representation::Tagged();
1518 }
1519
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001520 HValue* context() { return first(); }
1521 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001523 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001524};
1525
1526
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001527class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001529 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1530 : HUnaryCall(context, argument_count), name_(name) {
1531 }
1532
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001533 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001535 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536 Handle<String> name() const { return name_; }
1537
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001538 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001540 virtual Representation RequiredInputRepresentation(int index) const {
1541 return Representation::Tagged();
1542 }
1543
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001544 private:
1545 Handle<String> name_;
1546};
1547
1548
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001549class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001550 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001551 HCallFunction(HValue* context, int argument_count)
1552 : HUnaryCall(context, argument_count) {
1553 }
1554
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001555 HValue* context() { return value(); }
1556
1557 virtual Representation RequiredInputRepresentation(int index) const {
1558 return Representation::Tagged();
1559 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001560
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001561 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001562};
1563
1564
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001565class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001567 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1568 : HUnaryCall(context, argument_count), name_(name) {
1569 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001570
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001571 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001573 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574 Handle<String> name() const { return name_; }
1575
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001576 virtual Representation RequiredInputRepresentation(int index) const {
1577 return Representation::Tagged();
1578 }
1579
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001580 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001581
1582 private:
1583 Handle<String> name_;
1584};
1585
1586
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001587class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001589 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001590 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001591
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001592 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001593
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001594 Handle<JSFunction> target() const { return target_; }
1595
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001596 virtual Representation RequiredInputRepresentation(int index) const {
1597 return Representation::None();
1598 }
1599
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001600 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601
1602 private:
1603 Handle<JSFunction> target_;
1604};
1605
1606
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001607class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001609 HCallNew(HValue* context, HValue* constructor, int argument_count)
1610 : HBinaryCall(context, constructor, argument_count) {
1611 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612
1613 virtual Representation RequiredInputRepresentation(int index) const {
1614 return Representation::Tagged();
1615 }
1616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001617 HValue* context() { return first(); }
1618 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001619
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001620 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621};
1622
1623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001624class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625 public:
1626 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001627 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001629 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1630 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001631
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001632 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633 Handle<String> name() const { return name_; }
1634
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001635 virtual Representation RequiredInputRepresentation(int index) const {
1636 return Representation::None();
1637 }
1638
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001639 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001640
1641 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001642 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001643 Handle<String> name_;
1644};
1645
1646
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001647class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001648 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001649 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001650 // The length of an array is stored as a tagged value in the array
1651 // object. It is guaranteed to be 32 bit integer, but it can be
1652 // represented as either a smi or heap number.
1653 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001655 SetFlag(kDependsOnArrayLengths);
1656 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001657 }
1658
1659 virtual Representation RequiredInputRepresentation(int index) const {
1660 return Representation::Tagged();
1661 }
1662
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001663 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001664
1665 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001666 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001667};
1668
1669
1670class HFixedArrayLength: public HUnaryOperation {
1671 public:
1672 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1673 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001674 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001675 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001676 }
1677
1678 virtual Representation RequiredInputRepresentation(int index) const {
1679 return Representation::Tagged();
1680 }
1681
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001682 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001683
1684 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001685 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686};
1687
1688
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001689class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001690 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001691 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001692 set_representation(Representation::Integer32());
1693 // The result of this instruction is idempotent as long as its inputs don't
1694 // change. The length of a pixel array cannot change once set, so it's not
1695 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1696 SetFlag(kUseGVN);
1697 }
1698
1699 virtual Representation RequiredInputRepresentation(int index) const {
1700 return Representation::Tagged();
1701 }
1702
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001703 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001704
1705 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001706 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001707};
1708
1709
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710class HBitNot: public HUnaryOperation {
1711 public:
1712 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1713 set_representation(Representation::Integer32());
1714 SetFlag(kUseGVN);
1715 SetFlag(kTruncatingToInt32);
1716 }
1717
1718 virtual Representation RequiredInputRepresentation(int index) const {
1719 return Representation::Integer32();
1720 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001721 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001722
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001723 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001724
1725 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001726 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001727};
1728
1729
1730class HUnaryMathOperation: public HUnaryOperation {
1731 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001732 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001733 : HUnaryOperation(value), op_(op) {
1734 switch (op) {
1735 case kMathFloor:
1736 case kMathRound:
1737 case kMathCeil:
1738 set_representation(Representation::Integer32());
1739 break;
1740 case kMathAbs:
1741 set_representation(Representation::Tagged());
1742 SetFlag(kFlexibleRepresentation);
1743 break;
1744 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001745 case kMathPowHalf:
1746 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001747 case kMathSin:
1748 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001749 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001750 break;
1751 default:
1752 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001753 }
1754 SetFlag(kUseGVN);
1755 }
1756
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001757 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001759 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001760
1761 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1762
1763 virtual Representation RequiredInputRepresentation(int index) const {
1764 switch (op_) {
1765 case kMathFloor:
1766 case kMathRound:
1767 case kMathCeil:
1768 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001769 case kMathPowHalf:
1770 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001771 case kMathSin:
1772 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001773 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001774 case kMathAbs:
1775 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001776 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001777 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001778 return Representation::None();
1779 }
1780 }
1781
1782 virtual HValue* Canonicalize() {
1783 // If the input is integer32 then we replace the floor instruction
1784 // with its inputs. This happens before the representation changes are
1785 // introduced.
1786 if (op() == kMathFloor) {
1787 if (value()->representation().IsInteger32()) return value();
1788 }
1789 return this;
1790 }
1791
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001792 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793 const char* OpName() const;
1794
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001795 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001796
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001797 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001798 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001799 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1800 return op_ == b->op();
1801 }
1802
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001804 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001805};
1806
1807
1808class HLoadElements: public HUnaryOperation {
1809 public:
1810 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1811 set_representation(Representation::Tagged());
1812 SetFlag(kUseGVN);
1813 SetFlag(kDependsOnMaps);
1814 }
1815
1816 virtual Representation RequiredInputRepresentation(int index) const {
1817 return Representation::Tagged();
1818 }
1819
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001820 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001821
1822 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001823 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001824};
1825
1826
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001827class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001828 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001829 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001830 : HUnaryOperation(value) {
1831 set_representation(Representation::External());
1832 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001833 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001834 // change once set, so it's no necessary to introduce any additional
1835 // dependencies on top of the inputs.
1836 SetFlag(kUseGVN);
1837 }
1838
1839 virtual Representation RequiredInputRepresentation(int index) const {
1840 return Representation::Tagged();
1841 }
1842
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001843 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001844
1845 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001846 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001847};
1848
1849
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850class HCheckMap: public HUnaryOperation {
1851 public:
1852 HCheckMap(HValue* value, Handle<Map> map)
1853 : HUnaryOperation(value), map_(map) {
1854 set_representation(Representation::Tagged());
1855 SetFlag(kUseGVN);
1856 SetFlag(kDependsOnMaps);
1857 }
1858
1859 virtual Representation RequiredInputRepresentation(int index) const {
1860 return Representation::Tagged();
1861 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001862 virtual void PrintDataTo(StringStream* stream);
1863 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001864
1865#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001866 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867#endif
1868
1869 Handle<Map> map() const { return map_; }
1870
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001871 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001872
1873 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001874 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875 HCheckMap* b = HCheckMap::cast(other);
1876 return map_.is_identical_to(b->map());
1877 }
1878
1879 private:
1880 Handle<Map> map_;
1881};
1882
1883
1884class HCheckFunction: public HUnaryOperation {
1885 public:
1886 HCheckFunction(HValue* value, Handle<JSFunction> function)
1887 : HUnaryOperation(value), target_(function) {
1888 set_representation(Representation::Tagged());
1889 SetFlag(kUseGVN);
1890 }
1891
1892 virtual Representation RequiredInputRepresentation(int index) const {
1893 return Representation::Tagged();
1894 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001895 virtual void PrintDataTo(StringStream* stream);
1896 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001897
1898#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001899 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001900#endif
1901
1902 Handle<JSFunction> target() const { return target_; }
1903
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001904 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001905
1906 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001907 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001908 HCheckFunction* b = HCheckFunction::cast(other);
1909 return target_.is_identical_to(b->target());
1910 }
1911
1912 private:
1913 Handle<JSFunction> target_;
1914};
1915
1916
1917class HCheckInstanceType: public HUnaryOperation {
1918 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001919 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1920 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001921 }
1922 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1923 return new HCheckInstanceType(value, IS_JS_ARRAY);
1924 }
1925 static HCheckInstanceType* NewIsString(HValue* value) {
1926 return new HCheckInstanceType(value, IS_STRING);
1927 }
1928 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1929 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930 }
1931
1932 virtual Representation RequiredInputRepresentation(int index) const {
1933 return Representation::Tagged();
1934 }
1935
1936#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001937 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001938#endif
1939
danno@chromium.org160a7b02011-04-18 15:51:38 +00001940 virtual HValue* Canonicalize() {
1941 if (!value()->type().IsUninitialized() &&
1942 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001943 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001944 return NULL;
1945 }
1946 return this;
1947 }
1948
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001949 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1950 void GetCheckInterval(InstanceType* first, InstanceType* last);
1951 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001953 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001954
1955 protected:
1956 // TODO(ager): It could be nice to allow the ommision of instance
1957 // type checks if we have already performed an instance type check
1958 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001959 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001960 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001961 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001962 }
1963
1964 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001965 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001966 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001967 IS_JS_ARRAY,
1968 IS_STRING,
1969 IS_SYMBOL,
1970 LAST_INTERVAL_CHECK = IS_JS_ARRAY
1971 };
1972
1973 HCheckInstanceType(HValue* value, Check check)
1974 : HUnaryOperation(value), check_(check) {
1975 set_representation(Representation::Tagged());
1976 SetFlag(kUseGVN);
1977 }
1978
1979 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001980};
1981
1982
1983class HCheckNonSmi: public HUnaryOperation {
1984 public:
1985 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1986 set_representation(Representation::Tagged());
1987 SetFlag(kUseGVN);
1988 }
1989
1990 virtual Representation RequiredInputRepresentation(int index) const {
1991 return Representation::Tagged();
1992 }
1993
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001994 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995
1996#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001997 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998#endif
1999
danno@chromium.org160a7b02011-04-18 15:51:38 +00002000 virtual HValue* Canonicalize() {
2001 HType value_type = value()->type();
2002 if (!value_type.IsUninitialized() &&
2003 (value_type.IsHeapNumber() ||
2004 value_type.IsString() ||
2005 value_type.IsBoolean() ||
2006 value_type.IsNonPrimitive())) {
2007 return NULL;
2008 }
2009 return this;
2010 }
2011
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002012 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002013
2014 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002015 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002016};
2017
2018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002019class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002021 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2022 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002023 SetFlag(kUseGVN);
2024 SetFlag(kDependsOnMaps);
2025 }
2026
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002027#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002028 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002029#endif
2030
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002031 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002032 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002034 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002035
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002036 virtual Representation RequiredInputRepresentation(int index) const {
2037 return Representation::None();
2038 }
2039
2040 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002041 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002042 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2043 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2044 return hash;
2045 }
2046
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002047 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002048 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002049 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002050 return prototype_.is_identical_to(b->prototype()) &&
2051 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052 }
2053
2054 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002055 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057};
2058
2059
2060class HCheckSmi: public HUnaryOperation {
2061 public:
2062 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2063 set_representation(Representation::Tagged());
2064 SetFlag(kUseGVN);
2065 }
2066
2067 virtual Representation RequiredInputRepresentation(int index) const {
2068 return Representation::Tagged();
2069 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071
2072#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002073 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002074#endif
2075
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002076 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002077
2078 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002079 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002080};
2081
2082
2083class HPhi: public HValue {
2084 public:
2085 explicit HPhi(int merged_index)
2086 : inputs_(2),
2087 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002088 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002089 is_live_(false),
2090 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2092 non_phi_uses_[i] = 0;
2093 indirect_uses_[i] = 0;
2094 }
2095 ASSERT(merged_index >= 0);
2096 set_representation(Representation::Tagged());
2097 SetFlag(kFlexibleRepresentation);
2098 }
2099
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002100 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002101 bool double_occurred = false;
2102 bool int32_occurred = false;
2103 for (int i = 0; i < OperandCount(); ++i) {
2104 HValue* value = OperandAt(i);
2105 if (value->representation().IsDouble()) double_occurred = true;
2106 if (value->representation().IsInteger32()) int32_occurred = true;
2107 if (value->representation().IsTagged()) return Representation::Tagged();
2108 }
2109
2110 if (double_occurred) return Representation::Double();
2111 if (int32_occurred) return Representation::Integer32();
2112 return Representation::None();
2113 }
2114
2115 virtual Range* InferRange();
2116 virtual Representation RequiredInputRepresentation(int index) const {
2117 return representation();
2118 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002119 virtual HType CalculateInferredType();
2120 virtual int OperandCount() { return inputs_.length(); }
2121 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2122 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002124 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002125
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002126 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002127
2128 int merged_index() const { return merged_index_; }
2129
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002130 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002131
2132#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002133 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002134#endif
2135
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136 void InitRealUses(int id);
2137 void AddNonPhiUsesFrom(HPhi* other);
2138 void AddIndirectUsesTo(int* use_count);
2139
2140 int tagged_non_phi_uses() const {
2141 return non_phi_uses_[Representation::kTagged];
2142 }
2143 int int32_non_phi_uses() const {
2144 return non_phi_uses_[Representation::kInteger32];
2145 }
2146 int double_non_phi_uses() const {
2147 return non_phi_uses_[Representation::kDouble];
2148 }
2149 int tagged_indirect_uses() const {
2150 return indirect_uses_[Representation::kTagged];
2151 }
2152 int int32_indirect_uses() const {
2153 return indirect_uses_[Representation::kInteger32];
2154 }
2155 int double_indirect_uses() const {
2156 return indirect_uses_[Representation::kDouble];
2157 }
2158 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002159 bool is_live() { return is_live_; }
2160 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002162 static HPhi* cast(HValue* value) {
2163 ASSERT(value->IsPhi());
2164 return reinterpret_cast<HPhi*>(value);
2165 }
2166 virtual Opcode opcode() const { return HValue::kPhi; }
2167
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002168 virtual bool IsConvertibleToInteger() const {
2169 return is_convertible_to_integer_;
2170 }
2171
2172 void set_is_convertible_to_integer(bool b) {
2173 is_convertible_to_integer_ = b;
2174 }
2175
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002176 protected:
2177 virtual void DeleteFromGraph();
2178 virtual void InternalSetOperandAt(int index, HValue* value) {
2179 inputs_[index] = value;
2180 }
2181
2182 private:
2183 ZoneList<HValue*> inputs_;
2184 int merged_index_;
2185
2186 int non_phi_uses_[Representation::kNumRepresentations];
2187 int indirect_uses_[Representation::kNumRepresentations];
2188 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002189 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002190 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191};
2192
2193
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002194class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195 public:
2196 HArgumentsObject() {
2197 set_representation(Representation::Tagged());
2198 SetFlag(kIsArguments);
2199 }
2200
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002201 virtual Representation RequiredInputRepresentation(int index) const {
2202 return Representation::None();
2203 }
2204
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002205 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002206};
2207
2208
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002209class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002210 public:
2211 HConstant(Handle<Object> handle, Representation r);
2212
2213 Handle<Object> handle() const { return handle_; }
2214
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002215 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002217 virtual Representation RequiredInputRepresentation(int index) const {
2218 return Representation::None();
2219 }
2220
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002221 virtual bool IsConvertibleToInteger() const {
2222 if (handle_->IsSmi()) return true;
2223 if (handle_->IsHeapNumber() &&
2224 (HeapNumber::cast(*handle_)->value() ==
2225 static_cast<double>(NumberToInt32(*handle_)))) return true;
2226 return false;
2227 }
2228
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002229 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002230 virtual void PrintDataTo(StringStream* stream);
2231 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002232 bool IsInteger() const { return handle_->IsSmi(); }
2233 HConstant* CopyToRepresentation(Representation r) const;
2234 HConstant* CopyToTruncatedInt32() const;
2235 bool HasInteger32Value() const { return has_int32_value_; }
2236 int32_t Integer32Value() const {
2237 ASSERT(HasInteger32Value());
2238 return int32_value_;
2239 }
2240 bool HasDoubleValue() const { return has_double_value_; }
2241 double DoubleValue() const {
2242 ASSERT(HasDoubleValue());
2243 return double_value_;
2244 }
2245 bool HasStringValue() const { return handle_->IsString(); }
2246
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002247 bool ToBoolean() const;
2248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002249 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002250 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002251 return reinterpret_cast<intptr_t>(*handle());
2252 }
2253
2254#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002255 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002256#endif
2257
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002258 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002259
2260 protected:
2261 virtual Range* InferRange();
2262
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002263 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002264 HConstant* other_constant = HConstant::cast(other);
2265 return handle().is_identical_to(other_constant->handle());
2266 }
2267
2268 private:
2269 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002270
2271 // The following two values represent the int32 and the double value of the
2272 // given constant if there is a lossless conversion between the constant
2273 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002274 bool has_int32_value_ : 1;
2275 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002277 double double_value_;
2278};
2279
2280
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002281class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002282 public:
2283 HBinaryOperation(HValue* left, HValue* right) {
2284 ASSERT(left != NULL && right != NULL);
2285 SetOperandAt(0, left);
2286 SetOperandAt(1, right);
2287 }
2288
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002289 HValue* left() { return OperandAt(0); }
2290 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002291
2292 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2293 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002294 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002295 if (IsCommutative() && left()->IsConstant()) return right();
2296 return left();
2297 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002298 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002299 if (IsCommutative() && left()->IsConstant()) return left();
2300 return right();
2301 }
2302
2303 virtual bool IsCommutative() const { return false; }
2304
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002305 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002306};
2307
2308
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002309class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310 public:
2311 HApplyArguments(HValue* function,
2312 HValue* receiver,
2313 HValue* length,
2314 HValue* elements) {
2315 set_representation(Representation::Tagged());
2316 SetOperandAt(0, function);
2317 SetOperandAt(1, receiver);
2318 SetOperandAt(2, length);
2319 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002320 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002321 }
2322
2323 virtual Representation RequiredInputRepresentation(int index) const {
2324 // The length is untagged, all other inputs are tagged.
2325 return (index == 2)
2326 ? Representation::Integer32()
2327 : Representation::Tagged();
2328 }
2329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002330 HValue* function() { return OperandAt(0); }
2331 HValue* receiver() { return OperandAt(1); }
2332 HValue* length() { return OperandAt(2); }
2333 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002334
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002335 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336};
2337
2338
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002339class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002340 public:
2341 HArgumentsElements() {
2342 // The value produced by this instruction is a pointer into the stack
2343 // that looks as if it was a smi because of alignment.
2344 set_representation(Representation::Tagged());
2345 SetFlag(kUseGVN);
2346 }
2347
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002348 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002349
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002350 virtual Representation RequiredInputRepresentation(int index) const {
2351 return Representation::None();
2352 }
2353
ager@chromium.org378b34e2011-01-28 08:04:38 +00002354 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002356};
2357
2358
2359class HArgumentsLength: public HUnaryOperation {
2360 public:
2361 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2362 set_representation(Representation::Integer32());
2363 SetFlag(kUseGVN);
2364 }
2365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002366 virtual Representation RequiredInputRepresentation(int index) const {
2367 return Representation::Tagged();
2368 }
2369
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002370 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
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 HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002378 public:
2379 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2380 set_representation(Representation::Tagged());
2381 SetFlag(kUseGVN);
2382 SetOperandAt(0, arguments);
2383 SetOperandAt(1, length);
2384 SetOperandAt(2, index);
2385 }
2386
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002387 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002388
2389 virtual Representation RequiredInputRepresentation(int index) const {
2390 // The arguments elements is considered tagged.
2391 return index == 0
2392 ? Representation::Tagged()
2393 : Representation::Integer32();
2394 }
2395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002396 HValue* arguments() { return OperandAt(0); }
2397 HValue* length() { return OperandAt(1); }
2398 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002399
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002400 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002401
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002402 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002403};
2404
2405
2406class HBoundsCheck: public HBinaryOperation {
2407 public:
2408 HBoundsCheck(HValue* index, HValue* length)
2409 : HBinaryOperation(index, length) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002410 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002411 SetFlag(kUseGVN);
2412 }
2413
2414 virtual Representation RequiredInputRepresentation(int index) const {
2415 return Representation::Integer32();
2416 }
2417
2418#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002419 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002420#endif
2421
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002422 HValue* index() { return left(); }
2423 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002424
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002425 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002426
2427 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002428 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002429};
2430
2431
2432class HBitwiseBinaryOperation: public HBinaryOperation {
2433 public:
2434 HBitwiseBinaryOperation(HValue* left, HValue* right)
2435 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002436 set_representation(Representation::Tagged());
2437 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002438 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002439 }
2440
2441 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002442 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443 }
2444
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002445 virtual void RepresentationChanged(Representation to) {
2446 if (!to.IsTagged()) {
2447 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002448 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002449 SetFlag(kTruncatingToInt32);
2450 SetFlag(kUseGVN);
2451 }
2452 }
2453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002454 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002455
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002456 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002457};
2458
2459
2460class HArithmeticBinaryOperation: public HBinaryOperation {
2461 public:
2462 HArithmeticBinaryOperation(HValue* left, HValue* right)
2463 : HBinaryOperation(left, right) {
2464 set_representation(Representation::Tagged());
2465 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002466 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002467 }
2468
2469 virtual void RepresentationChanged(Representation to) {
2470 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002471 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002472 SetFlag(kUseGVN);
2473 }
2474 }
2475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002476 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002477 virtual Representation RequiredInputRepresentation(int index) const {
2478 return representation();
2479 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002480 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002481 if (left()->representation().Equals(right()->representation())) {
2482 return left()->representation();
2483 }
2484 return HValue::InferredRepresentation();
2485 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486};
2487
2488
2489class HCompare: public HBinaryOperation {
2490 public:
2491 HCompare(HValue* left, HValue* right, Token::Value token)
2492 : HBinaryOperation(left, right), token_(token) {
2493 ASSERT(Token::IsCompareOp(token));
2494 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002495 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002496 }
2497
2498 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002499
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002500 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002501 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002502 }
2503
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002504 virtual Representation RequiredInputRepresentation(int index) const {
2505 return input_representation_;
2506 }
2507 Representation GetInputRepresentation() const {
2508 return input_representation_;
2509 }
2510 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002511 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002512
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002513 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002514
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002515 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516 return HValue::Hashcode() * 7 + token_;
2517 }
2518
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002519 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520
2521 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002522 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002523 HCompare* comp = HCompare::cast(other);
2524 return token_ == comp->token();
2525 }
2526
2527 private:
2528 Representation input_representation_;
2529 Token::Value token_;
2530};
2531
2532
2533class HCompareJSObjectEq: public HBinaryOperation {
2534 public:
2535 HCompareJSObjectEq(HValue* left, HValue* right)
2536 : HBinaryOperation(left, right) {
2537 set_representation(Representation::Tagged());
2538 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002539 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540 }
2541
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002542 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002543 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002544 }
2545
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546 virtual Representation RequiredInputRepresentation(int index) const {
2547 return Representation::Tagged();
2548 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002549 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002551 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002552
2553 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002554 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555};
2556
2557
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002558class HCompareSymbolEq: public HBinaryOperation {
2559 public:
2560 HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
2561 : HBinaryOperation(left, right), op_(op) {
2562 ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
2563 set_representation(Representation::Tagged());
2564 SetFlag(kUseGVN);
2565 SetFlag(kDependsOnMaps);
2566 }
2567
2568 Token::Value op() const { return op_; }
2569
2570 virtual bool EmitAtUses() {
2571 return !HasSideEffects() && !HasMultipleUses();
2572 }
2573
2574 virtual Representation RequiredInputRepresentation(int index) const {
2575 return Representation::Tagged();
2576 }
2577
2578 virtual HType CalculateInferredType() { return HType::Boolean(); }
2579
2580 DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
2581
2582 protected:
2583 virtual bool DataEquals(HValue* other) {
2584 return op_ == HCompareSymbolEq::cast(other)->op_;
2585 }
2586
2587 private:
2588 const Token::Value op_;
2589};
2590
2591
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002592class HUnaryPredicate: public HUnaryOperation {
2593 public:
2594 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2595 set_representation(Representation::Tagged());
2596 SetFlag(kUseGVN);
2597 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002598
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002599 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002600 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002601 }
2602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603 virtual Representation RequiredInputRepresentation(int index) const {
2604 return Representation::Tagged();
2605 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002606 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002607};
2608
2609
2610class HIsNull: public HUnaryPredicate {
2611 public:
2612 HIsNull(HValue* value, bool is_strict)
2613 : HUnaryPredicate(value), is_strict_(is_strict) { }
2614
2615 bool is_strict() const { return is_strict_; }
2616
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002617 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002618
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002619 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002620 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002621 HIsNull* b = HIsNull::cast(other);
2622 return is_strict_ == b->is_strict();
2623 }
2624
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002625 private:
2626 bool is_strict_;
2627};
2628
2629
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002630class HIsObject: public HUnaryPredicate {
2631 public:
2632 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2633
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002634 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002635
2636 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002637 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002638};
2639
2640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641class HIsSmi: public HUnaryPredicate {
2642 public:
2643 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2644
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002645 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002646
2647 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002648 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002649};
2650
2651
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002652class HIsUndetectable: public HUnaryPredicate {
2653 public:
2654 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2655
2656 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2657
2658 protected:
2659 virtual bool DataEquals(HValue* other) { return true; }
2660};
2661
2662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002663class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002664 public:
2665 HIsConstructCall() {
2666 set_representation(Representation::Tagged());
2667 SetFlag(kUseGVN);
2668 }
2669
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002670 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002671 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002672 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002673
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002674 virtual Representation RequiredInputRepresentation(int index) const {
2675 return Representation::None();
2676 }
2677
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002678 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002679
2680 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002681 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002682};
2683
2684
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002685class HHasInstanceType: public HUnaryPredicate {
2686 public:
2687 HHasInstanceType(HValue* value, InstanceType type)
2688 : HUnaryPredicate(value), from_(type), to_(type) { }
2689 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2690 : HUnaryPredicate(value), from_(from), to_(to) {
2691 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2692 }
2693
2694 InstanceType from() { return from_; }
2695 InstanceType to() { return to_; }
2696
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002697 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002698
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002699 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002700
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002701 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002702 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002703 HHasInstanceType* b = HHasInstanceType::cast(other);
2704 return (from_ == b->from()) && (to_ == b->to());
2705 }
2706
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707 private:
2708 InstanceType from_;
2709 InstanceType to_; // Inclusive range, not all combinations work.
2710};
2711
2712
2713class HHasCachedArrayIndex: public HUnaryPredicate {
2714 public:
2715 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2716
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002717 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002718
2719 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002720 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721};
2722
2723
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002724class HGetCachedArrayIndex: public HUnaryPredicate {
2725 public:
2726 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2727
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002728 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002729
2730 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002731 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002732};
2733
2734
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002735class HClassOfTest: public HUnaryPredicate {
2736 public:
2737 HClassOfTest(HValue* value, Handle<String> class_name)
2738 : HUnaryPredicate(value), class_name_(class_name) { }
2739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002740 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002742 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743
2744 Handle<String> class_name() const { return class_name_; }
2745
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002746 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002747 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002748 HClassOfTest* b = HClassOfTest::cast(other);
2749 return class_name_.is_identical_to(b->class_name_);
2750 }
2751
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002752 private:
2753 Handle<String> class_name_;
2754};
2755
2756
2757class HTypeofIs: public HUnaryPredicate {
2758 public:
2759 HTypeofIs(HValue* value, Handle<String> type_literal)
2760 : HUnaryPredicate(value), type_literal_(type_literal) { }
2761
2762 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002763 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002765 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766
2767 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002768 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769 HTypeofIs* b = HTypeofIs::cast(other);
2770 return type_literal_.is_identical_to(b->type_literal_);
2771 }
2772
2773 private:
2774 Handle<String> type_literal_;
2775};
2776
2777
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002778class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002780 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2781 SetOperandAt(0, context);
2782 SetOperandAt(1, left);
2783 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002785 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002786 }
2787
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002788 HValue* context() { return OperandAt(0); }
2789 HValue* left() { return OperandAt(1); }
2790 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002791
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792 virtual Representation RequiredInputRepresentation(int index) const {
2793 return Representation::Tagged();
2794 }
2795
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002796 virtual HType CalculateInferredType();
2797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002798 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002800 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801};
2802
2803
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002804class HInstanceOfKnownGlobal: public HUnaryOperation {
2805 public:
2806 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2807 : HUnaryOperation(left), function_(right) {
2808 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002809 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002810 }
2811
2812 Handle<JSFunction> function() { return function_; }
2813
2814 virtual Representation RequiredInputRepresentation(int index) const {
2815 return Representation::Tagged();
2816 }
2817
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002818 virtual HType CalculateInferredType();
2819
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002820 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002821
2822 private:
2823 Handle<JSFunction> function_;
2824};
2825
2826
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002827class HPower: public HBinaryOperation {
2828 public:
2829 HPower(HValue* left, HValue* right)
2830 : HBinaryOperation(left, right) {
2831 set_representation(Representation::Double());
2832 SetFlag(kUseGVN);
2833 }
2834
2835 virtual Representation RequiredInputRepresentation(int index) const {
2836 return (index == 1) ? Representation::None() : Representation::Double();
2837 }
2838
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002839 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002840
2841 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002842 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002843};
2844
2845
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846class HAdd: public HArithmeticBinaryOperation {
2847 public:
2848 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2849 SetFlag(kCanOverflow);
2850 }
2851
2852 // Add is only commutative if two integer values are added and not if two
2853 // tagged values are added (because it might be a String concatenation).
2854 virtual bool IsCommutative() const {
2855 return !representation().IsTagged();
2856 }
2857
2858 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2859
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002860 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002861
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002862 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863
2864 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002865 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002866
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002867 virtual Range* InferRange();
2868};
2869
2870
2871class HSub: public HArithmeticBinaryOperation {
2872 public:
2873 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2874 SetFlag(kCanOverflow);
2875 }
2876
2877 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2878
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002879 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002880
2881 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002882 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002883
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002884 virtual Range* InferRange();
2885};
2886
2887
2888class HMul: public HArithmeticBinaryOperation {
2889 public:
2890 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2891 SetFlag(kCanOverflow);
2892 }
2893
2894 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2895
2896 // Only commutative if it is certain that not two objects are multiplicated.
2897 virtual bool IsCommutative() const {
2898 return !representation().IsTagged();
2899 }
2900
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002901 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902
2903 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002904 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002905
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002906 virtual Range* InferRange();
2907};
2908
2909
2910class HMod: public HArithmeticBinaryOperation {
2911 public:
2912 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2913 SetFlag(kCanBeDivByZero);
2914 }
2915
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002916 bool HasPowerOf2Divisor() {
2917 if (right()->IsConstant() &&
2918 HConstant::cast(right())->HasInteger32Value()) {
2919 int32_t value = HConstant::cast(right())->Integer32Value();
2920 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2921 }
2922
2923 return false;
2924 }
2925
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002926 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2927
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002928 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002929
2930 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002931 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002932
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933 virtual Range* InferRange();
2934};
2935
2936
2937class HDiv: public HArithmeticBinaryOperation {
2938 public:
2939 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2940 SetFlag(kCanBeDivByZero);
2941 SetFlag(kCanOverflow);
2942 }
2943
2944 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2945
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002946 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947
2948 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002949 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002950
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002951 virtual Range* InferRange();
2952};
2953
2954
2955class HBitAnd: public HBitwiseBinaryOperation {
2956 public:
2957 HBitAnd(HValue* left, HValue* right)
2958 : HBitwiseBinaryOperation(left, right) { }
2959
2960 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002961 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002962
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002963 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002964
2965 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002966 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002967
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002968 virtual Range* InferRange();
2969};
2970
2971
2972class HBitXor: public HBitwiseBinaryOperation {
2973 public:
2974 HBitXor(HValue* left, HValue* right)
2975 : HBitwiseBinaryOperation(left, right) { }
2976
2977 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002978 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002980 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002981
2982 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002983 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984};
2985
2986
2987class HBitOr: public HBitwiseBinaryOperation {
2988 public:
2989 HBitOr(HValue* left, HValue* right)
2990 : HBitwiseBinaryOperation(left, right) { }
2991
2992 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002993 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002995 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996
2997 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002998 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002999
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000 virtual Range* InferRange();
3001};
3002
3003
3004class HShl: public HBitwiseBinaryOperation {
3005 public:
3006 HShl(HValue* left, HValue* right)
3007 : HBitwiseBinaryOperation(left, right) { }
3008
3009 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003010 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003012 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003013
3014 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003015 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016};
3017
3018
3019class HShr: public HBitwiseBinaryOperation {
3020 public:
3021 HShr(HValue* left, HValue* right)
3022 : HBitwiseBinaryOperation(left, right) { }
3023
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003024 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003026 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003027
3028 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003029 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030};
3031
3032
3033class HSar: public HBitwiseBinaryOperation {
3034 public:
3035 HSar(HValue* left, HValue* right)
3036 : HBitwiseBinaryOperation(left, right) { }
3037
3038 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003039 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003040
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003041 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003042
3043 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003044 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003045};
3046
3047
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003048class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003049 public:
3050 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3051 SetFlag(kChangesOsrEntries);
3052 }
3053
3054 int ast_id() const { return ast_id_; }
3055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003056 virtual Representation RequiredInputRepresentation(int index) const {
3057 return Representation::None();
3058 }
3059
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003060 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061
3062 private:
3063 int ast_id_;
3064};
3065
3066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003067class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003068 public:
3069 explicit HParameter(unsigned index) : index_(index) {
3070 set_representation(Representation::Tagged());
3071 }
3072
3073 unsigned index() const { return index_; }
3074
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003075 virtual void PrintDataTo(StringStream* stream);
3076
3077 virtual Representation RequiredInputRepresentation(int index) const {
3078 return Representation::None();
3079 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003081 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082
3083 private:
3084 unsigned index_;
3085};
3086
3087
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003088class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003090 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3091 : HUnaryCall(context, argument_count),
3092 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003093 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094 }
3095
3096 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003097
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003098 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099
3100 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3101 transcendental_type_ = transcendental_type;
3102 }
3103 TranscendentalCache::Type transcendental_type() {
3104 return transcendental_type_;
3105 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003107 virtual void PrintDataTo(StringStream* stream);
3108
3109 virtual Representation RequiredInputRepresentation(int index) const {
3110 return Representation::Tagged();
3111 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003113 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114
3115 private:
3116 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117 TranscendentalCache::Type transcendental_type_;
3118};
3119
3120
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003121class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122 public:
3123 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3124
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003125 virtual Representation RequiredInputRepresentation(int index) const {
3126 return Representation::None();
3127 }
3128
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003129 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130};
3131
3132
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003133class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003135 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136 : cell_(cell), check_hole_value_(check_hole_value) {
3137 set_representation(Representation::Tagged());
3138 SetFlag(kUseGVN);
3139 SetFlag(kDependsOnGlobalVars);
3140 }
3141
3142 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3143 bool check_hole_value() const { return check_hole_value_; }
3144
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003145 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003147 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003148 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149 return reinterpret_cast<intptr_t>(*cell_);
3150 }
3151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003152 virtual Representation RequiredInputRepresentation(int index) const {
3153 return Representation::None();
3154 }
3155
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003156 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157
3158 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003159 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003160 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003161 return cell_.is_identical_to(b->cell());
3162 }
3163
3164 private:
3165 Handle<JSGlobalPropertyCell> cell_;
3166 bool check_hole_value_;
3167};
3168
3169
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003170class HLoadGlobalGeneric: public HBinaryOperation {
3171 public:
3172 HLoadGlobalGeneric(HValue* context,
3173 HValue* global_object,
3174 Handle<Object> name,
3175 bool for_typeof)
3176 : HBinaryOperation(context, global_object),
3177 name_(name),
3178 for_typeof_(for_typeof) {
3179 set_representation(Representation::Tagged());
3180 SetAllSideEffects();
3181 }
3182
3183 HValue* context() { return OperandAt(0); }
3184 HValue* global_object() { return OperandAt(1); }
3185 Handle<Object> name() const { return name_; }
3186 bool for_typeof() const { return for_typeof_; }
3187
3188 virtual void PrintDataTo(StringStream* stream);
3189
3190 virtual Representation RequiredInputRepresentation(int index) const {
3191 return Representation::Tagged();
3192 }
3193
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003194 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003195
3196 private:
3197 Handle<Object> name_;
3198 bool for_typeof_;
3199};
3200
3201
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003202class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003204 HStoreGlobalCell(HValue* value,
3205 Handle<JSGlobalPropertyCell> cell,
3206 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003207 : HUnaryOperation(value),
3208 cell_(cell),
3209 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003210 SetFlag(kChangesGlobalVars);
3211 }
3212
3213 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003214 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215
3216 virtual Representation RequiredInputRepresentation(int index) const {
3217 return Representation::Tagged();
3218 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003219 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003220
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003221 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003222
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003223 private:
3224 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003225 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003226};
3227
3228
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003229class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3230 public:
3231 HStoreGlobalGeneric(HValue* context,
3232 HValue* global_object,
3233 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003234 HValue* value,
3235 bool strict_mode)
3236 : name_(name),
3237 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003238 SetOperandAt(0, context);
3239 SetOperandAt(1, global_object);
3240 SetOperandAt(2, value);
3241 set_representation(Representation::Tagged());
3242 SetAllSideEffects();
3243 }
3244
3245 HValue* context() { return OperandAt(0); }
3246 HValue* global_object() { return OperandAt(1); }
3247 Handle<Object> name() const { return name_; }
3248 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003249 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003250
3251 virtual void PrintDataTo(StringStream* stream);
3252
3253 virtual Representation RequiredInputRepresentation(int index) const {
3254 return Representation::Tagged();
3255 }
3256
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003257 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003258
3259 private:
3260 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003261 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003262};
3263
3264
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003265class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003266 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003267 HLoadContextSlot(HValue* context , int slot_index)
3268 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003269 set_representation(Representation::Tagged());
3270 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003271 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003272 }
3273
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003274 int slot_index() const { return slot_index_; }
3275
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003276 virtual Representation RequiredInputRepresentation(int index) const {
3277 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003278 }
3279
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003280 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003281
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003282 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003283
3284 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003285 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003286 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003287 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003288 }
3289
3290 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003291 int slot_index_;
3292};
3293
3294
3295static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3296 return !value->type().IsSmi() &&
3297 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3298}
3299
3300
3301class HStoreContextSlot: public HBinaryOperation {
3302 public:
3303 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3304 : HBinaryOperation(context, value), slot_index_(slot_index) {
3305 SetFlag(kChangesContextSlots);
3306 }
3307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003308 HValue* context() { return OperandAt(0); }
3309 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003310 int slot_index() const { return slot_index_; }
3311
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003312 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003313 return StoringValueNeedsWriteBarrier(value());
3314 }
3315
3316 virtual Representation RequiredInputRepresentation(int index) const {
3317 return Representation::Tagged();
3318 }
3319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003320 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003321
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003322 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003323
3324 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003325 int slot_index_;
3326};
3327
3328
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003329class HLoadNamedField: public HUnaryOperation {
3330 public:
3331 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3332 : HUnaryOperation(object),
3333 is_in_object_(is_in_object),
3334 offset_(offset) {
3335 set_representation(Representation::Tagged());
3336 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003337 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003338 if (is_in_object) {
3339 SetFlag(kDependsOnInobjectFields);
3340 } else {
3341 SetFlag(kDependsOnBackingStoreFields);
3342 }
3343 }
3344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003345 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003346 bool is_in_object() const { return is_in_object_; }
3347 int offset() const { return offset_; }
3348
3349 virtual Representation RequiredInputRepresentation(int index) const {
3350 return Representation::Tagged();
3351 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003352 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003353
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003354 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003355
3356 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003357 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003358 HLoadNamedField* b = HLoadNamedField::cast(other);
3359 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3360 }
3361
3362 private:
3363 bool is_in_object_;
3364 int offset_;
3365};
3366
3367
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003368class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3369 public:
3370 HLoadNamedFieldPolymorphic(HValue* object,
3371 ZoneMapList* types,
3372 Handle<String> name);
3373
3374 HValue* object() { return OperandAt(0); }
3375 ZoneMapList* types() { return &types_; }
3376 Handle<String> name() { return name_; }
3377 bool need_generic() { return need_generic_; }
3378
3379 virtual Representation RequiredInputRepresentation(int index) const {
3380 return Representation::Tagged();
3381 }
3382
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003383 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003384
3385 static const int kMaxLoadPolymorphism = 4;
3386
3387 protected:
3388 virtual bool DataEquals(HValue* value);
3389
3390 private:
3391 ZoneMapList types_;
3392 Handle<String> name_;
3393 bool need_generic_;
3394};
3395
3396
3397
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003398class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003400 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3401 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003402 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003403 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003404 }
3405
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003406 HValue* context() { return OperandAt(0); }
3407 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003408 Handle<Object> name() const { return name_; }
3409
3410 virtual Representation RequiredInputRepresentation(int index) const {
3411 return Representation::Tagged();
3412 }
3413
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003414 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003415
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003416 private:
3417 Handle<Object> name_;
3418};
3419
3420
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003421class HLoadFunctionPrototype: public HUnaryOperation {
3422 public:
3423 explicit HLoadFunctionPrototype(HValue* function)
3424 : HUnaryOperation(function) {
3425 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003426 SetFlag(kUseGVN);
3427 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003428 }
3429
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003430 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003431
3432 virtual Representation RequiredInputRepresentation(int index) const {
3433 return Representation::Tagged();
3434 }
3435
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003436 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003437
3438 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003439 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003440};
3441
3442
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003443class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003444 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003445 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003446 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003447 SetFlag(kDependsOnArrayElements);
3448 SetFlag(kUseGVN);
3449 }
3450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003451 HValue* object() { return OperandAt(0); }
3452 HValue* key() { return OperandAt(1); }
3453
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003454 virtual Representation RequiredInputRepresentation(int index) const {
3455 // The key is supposed to be Integer32.
3456 return (index == 1) ? Representation::Integer32()
3457 : Representation::Tagged();
3458 }
3459
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003460 virtual void PrintDataTo(StringStream* stream);
3461
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003462 bool RequiresHoleCheck() const;
3463
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003464 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003465
3466 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003467 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003468};
3469
3470
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003471class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003472 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003473 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3474 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003475 JSObject::ElementsKind elements_kind)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003476 : HBinaryOperation(external_elements, key),
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003477 elements_kind_(elements_kind) {
3478 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3479 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003480 set_representation(Representation::Double());
3481 } else {
3482 set_representation(Representation::Integer32());
3483 }
3484 SetFlag(kDependsOnSpecializedArrayElements);
3485 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003486 SetFlag(kDependsOnCalls);
3487 SetFlag(kUseGVN);
3488 }
3489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003490 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003491
3492 virtual Representation RequiredInputRepresentation(int index) const {
3493 // The key is supposed to be Integer32, but the base pointer
3494 // for the element load is a naked pointer.
3495 return (index == 1) ? Representation::Integer32()
3496 : Representation::External();
3497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 HValue* external_pointer() { return OperandAt(0); }
3500 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003501 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003502
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003503 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003504
3505 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003506 virtual bool DataEquals(HValue* other) {
3507 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3508 HLoadKeyedSpecializedArrayElement* cast_other =
3509 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003510 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003511 }
3512
3513 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003514 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003515};
3516
3517
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003518class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003520 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003521 set_representation(Representation::Tagged());
3522 SetOperandAt(0, obj);
3523 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003524 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003525 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003526 }
3527
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003528 HValue* object() { return OperandAt(0); }
3529 HValue* key() { return OperandAt(1); }
3530 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003531
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003532 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003533
3534 virtual Representation RequiredInputRepresentation(int index) const {
3535 return Representation::Tagged();
3536 }
3537
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003538 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003539};
3540
3541
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003542class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003543 public:
3544 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003545 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003546 HValue* val,
3547 bool in_object,
3548 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003549 : HBinaryOperation(obj, val),
3550 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003551 is_in_object_(in_object),
3552 offset_(offset) {
3553 if (is_in_object_) {
3554 SetFlag(kChangesInobjectFields);
3555 } else {
3556 SetFlag(kChangesBackingStoreFields);
3557 }
3558 }
3559
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003560 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003561
3562 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003563 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003564 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003565 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003566
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003567 HValue* object() { return OperandAt(0); }
3568 HValue* value() { return OperandAt(1); }
3569
3570 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003571 bool is_in_object() const { return is_in_object_; }
3572 int offset() const { return offset_; }
3573 Handle<Map> transition() const { return transition_; }
3574 void set_transition(Handle<Map> map) { transition_ = map; }
3575
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003576 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003577 return StoringValueNeedsWriteBarrier(value());
3578 }
3579
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003580 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003581 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003582 bool is_in_object_;
3583 int offset_;
3584 Handle<Map> transition_;
3585};
3586
3587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003588class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003589 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003590 HStoreNamedGeneric(HValue* context,
3591 HValue* object,
3592 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003593 HValue* value,
3594 bool strict_mode)
3595 : name_(name),
3596 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003597 SetOperandAt(0, object);
3598 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003599 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003600 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003601 }
3602
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003603 HValue* object() { return OperandAt(0); }
3604 HValue* value() { return OperandAt(1); }
3605 HValue* context() { return OperandAt(2); }
3606 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003607 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003608
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003609 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003610
3611 virtual Representation RequiredInputRepresentation(int index) const {
3612 return Representation::Tagged();
3613 }
3614
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003615 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617 private:
3618 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003619 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620};
3621
3622
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003623class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003624 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003625 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3626 SetOperandAt(0, obj);
3627 SetOperandAt(1, key);
3628 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003629 SetFlag(kChangesArrayElements);
3630 }
3631
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632 virtual Representation RequiredInputRepresentation(int index) const {
3633 // The key is supposed to be Integer32.
3634 return (index == 1) ? Representation::Integer32()
3635 : Representation::Tagged();
3636 }
3637
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003638 HValue* object() { return OperandAt(0); }
3639 HValue* key() { return OperandAt(1); }
3640 HValue* value() { return OperandAt(2); }
3641
3642 bool NeedsWriteBarrier() {
3643 return StoringValueNeedsWriteBarrier(value());
3644 }
3645
3646 virtual void PrintDataTo(StringStream* stream);
3647
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003648 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649};
3650
3651
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003652class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003653 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003654 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3655 HValue* key,
3656 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003657 JSObject::ElementsKind elements_kind)
3658 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003659 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003660 SetOperandAt(0, external_elements);
3661 SetOperandAt(1, key);
3662 SetOperandAt(2, val);
3663 }
3664
3665 virtual void PrintDataTo(StringStream* stream);
3666
3667 virtual Representation RequiredInputRepresentation(int index) const {
3668 if (index == 0) {
3669 return Representation::External();
3670 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003671 bool float_or_double_elements =
3672 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3673 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3674 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003675 return Representation::Double();
3676 } else {
3677 return Representation::Integer32();
3678 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003679 }
3680 }
3681
3682 HValue* external_pointer() { return OperandAt(0); }
3683 HValue* key() { return OperandAt(1); }
3684 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003685 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003686
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003687 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3688
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003689 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003690 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003691};
3692
3693
3694class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003696 HStoreKeyedGeneric(HValue* context,
3697 HValue* object,
3698 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003699 HValue* value,
3700 bool strict_mode)
3701 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003702 SetOperandAt(0, object);
3703 SetOperandAt(1, key);
3704 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003705 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003706 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003707 }
3708
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003709 HValue* object() { return OperandAt(0); }
3710 HValue* key() { return OperandAt(1); }
3711 HValue* value() { return OperandAt(2); }
3712 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003713 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003714
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003715 virtual Representation RequiredInputRepresentation(int index) const {
3716 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003717 }
3718
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003719 virtual void PrintDataTo(StringStream* stream);
3720
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003721 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003722
3723 private:
3724 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003725};
3726
3727
danno@chromium.org160a7b02011-04-18 15:51:38 +00003728class HStringAdd: public HBinaryOperation {
3729 public:
3730 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3731 set_representation(Representation::Tagged());
3732 SetFlag(kUseGVN);
3733 SetFlag(kDependsOnMaps);
3734 }
3735
3736 virtual Representation RequiredInputRepresentation(int index) const {
3737 return Representation::Tagged();
3738 }
3739
3740 virtual HType CalculateInferredType() {
3741 return HType::String();
3742 }
3743
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003744 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003745
3746 protected:
3747 virtual bool DataEquals(HValue* other) { return true; }
3748};
3749
3750
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003751class HStringCharCodeAt: public HBinaryOperation {
3752 public:
3753 HStringCharCodeAt(HValue* string, HValue* index)
3754 : HBinaryOperation(string, index) {
3755 set_representation(Representation::Integer32());
3756 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003757 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003758 }
3759
3760 virtual Representation RequiredInputRepresentation(int index) const {
3761 // The index is supposed to be Integer32.
3762 return (index == 1) ? Representation::Integer32()
3763 : Representation::Tagged();
3764 }
3765
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003766 HValue* string() { return OperandAt(0); }
3767 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003768
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003769 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003770
3771 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003772 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003773
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003774 virtual Range* InferRange() {
3775 return new Range(0, String::kMaxUC16CharCode);
3776 }
3777};
3778
3779
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003780class HStringCharFromCode: public HUnaryOperation {
3781 public:
3782 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3783 set_representation(Representation::Tagged());
3784 SetFlag(kUseGVN);
3785 }
3786
3787 virtual Representation RequiredInputRepresentation(int index) const {
3788 return Representation::Integer32();
3789 }
3790
3791 virtual bool DataEquals(HValue* other) { return true; }
3792
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003793 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003794};
3795
3796
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003797class HStringLength: public HUnaryOperation {
3798 public:
3799 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3800 set_representation(Representation::Tagged());
3801 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003802 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003803 }
3804
3805 virtual Representation RequiredInputRepresentation(int index) const {
3806 return Representation::Tagged();
3807 }
3808
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003809 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003810 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3811 return HType::Smi();
3812 }
3813
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003814 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003815
3816 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003817 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003818
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003819 virtual Range* InferRange() {
3820 return new Range(0, String::kMaxLength);
3821 }
3822};
3823
3824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003825template <int V>
3826class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003827 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003828 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003829 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003830 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831 }
3832
3833 int literal_index() const { return literal_index_; }
3834 int depth() const { return depth_; }
3835
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003836 private:
3837 int literal_index_;
3838 int depth_;
3839};
3840
3841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003842class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003843 public:
3844 HArrayLiteral(Handle<FixedArray> constant_elements,
3845 int length,
3846 int literal_index,
3847 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003848 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003849 length_(length),
3850 constant_elements_(constant_elements) {}
3851
3852 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3853 int length() const { return length_; }
3854
3855 bool IsCopyOnWrite() const;
3856
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003857 virtual Representation RequiredInputRepresentation(int index) const {
3858 return Representation::None();
3859 }
3860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003861 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003862
3863 private:
3864 int length_;
3865 Handle<FixedArray> constant_elements_;
3866};
3867
3868
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003869class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003870 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003871 HObjectLiteral(HValue* context,
3872 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003873 bool fast_elements,
3874 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003875 int depth,
3876 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003877 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003878 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003879 fast_elements_(fast_elements),
3880 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003881 SetOperandAt(0, context);
3882 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003883
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003884 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003885 Handle<FixedArray> constant_properties() const {
3886 return constant_properties_;
3887 }
3888 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003889 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003891 virtual Representation RequiredInputRepresentation(int index) const {
3892 return Representation::Tagged();
3893 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003894
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003895 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003896
3897 private:
3898 Handle<FixedArray> constant_properties_;
3899 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003900 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003901};
3902
3903
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003904class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003905 public:
3906 HRegExpLiteral(Handle<String> pattern,
3907 Handle<String> flags,
3908 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003909 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003910 pattern_(pattern),
3911 flags_(flags) { }
3912
3913 Handle<String> pattern() { return pattern_; }
3914 Handle<String> flags() { return flags_; }
3915
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003916 virtual Representation RequiredInputRepresentation(int index) const {
3917 return Representation::None();
3918 }
3919
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003920 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003921
3922 private:
3923 Handle<String> pattern_;
3924 Handle<String> flags_;
3925};
3926
3927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003928class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003929 public:
3930 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3931 : shared_info_(shared), pretenure_(pretenure) {
3932 set_representation(Representation::Tagged());
3933 }
3934
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003935 virtual Representation RequiredInputRepresentation(int index) const {
3936 return Representation::None();
3937 }
3938
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003939 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003940
3941 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3942 bool pretenure() const { return pretenure_; }
3943
3944 private:
3945 Handle<SharedFunctionInfo> shared_info_;
3946 bool pretenure_;
3947};
3948
3949
3950class HTypeof: public HUnaryOperation {
3951 public:
3952 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3953 set_representation(Representation::Tagged());
3954 }
3955
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003956 virtual Representation RequiredInputRepresentation(int index) const {
3957 return Representation::Tagged();
3958 }
3959
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003960 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003961};
3962
3963
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003964class HToFastProperties: public HUnaryOperation {
3965 public:
3966 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3967 // This instruction is not marked as having side effects, but
3968 // changes the map of the input operand. Use it only when creating
3969 // object literals.
3970 ASSERT(value->IsObjectLiteral());
3971 set_representation(Representation::Tagged());
3972 }
3973
3974 virtual Representation RequiredInputRepresentation(int index) const {
3975 return Representation::Tagged();
3976 }
3977
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003978 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003979};
3980
3981
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003982class HValueOf: public HUnaryOperation {
3983 public:
3984 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3985 set_representation(Representation::Tagged());
3986 }
3987
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003988 virtual Representation RequiredInputRepresentation(int index) const {
3989 return Representation::Tagged();
3990 }
3991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003992 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003993};
3994
3995
3996class HDeleteProperty: public HBinaryOperation {
3997 public:
3998 HDeleteProperty(HValue* obj, HValue* key)
3999 : HBinaryOperation(obj, key) {
4000 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004001 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004002 }
4003
4004 virtual Representation RequiredInputRepresentation(int index) const {
4005 return Representation::Tagged();
4006 }
4007
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004008 virtual HType CalculateInferredType();
4009
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004010 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004011
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004012 HValue* object() { return left(); }
4013 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004014};
4015
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004016
4017class HIn: public HTemplateInstruction<2> {
4018 public:
4019 HIn(HValue* key, HValue* object) {
4020 SetOperandAt(0, key);
4021 SetOperandAt(1, object);
4022 set_representation(Representation::Tagged());
4023 SetAllSideEffects();
4024 }
4025
4026 HValue* key() { return OperandAt(0); }
4027 HValue* object() { return OperandAt(1); }
4028
4029 virtual Representation RequiredInputRepresentation(int index) const {
4030 return Representation::Tagged();
4031 }
4032
4033 virtual HType CalculateInferredType() {
4034 return HType::Boolean();
4035 }
4036
4037 virtual void PrintDataTo(StringStream* stream);
4038
4039 DECLARE_CONCRETE_INSTRUCTION(In)
4040};
4041
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004042#undef DECLARE_INSTRUCTION
4043#undef DECLARE_CONCRETE_INSTRUCTION
4044
4045} } // namespace v8::internal
4046
4047#endif // V8_HYDROGEN_INSTRUCTIONS_H_