blob: cc32b93831ebe2efebdb2b6cb6d6d3b39cb3b65a [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"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
48class HInstruction;
49class HLoopInformation;
50class HValue;
51class LInstruction;
52class LChunkBuilder;
53
54
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000055#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 V(ControlInstruction) \
58 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059
60
61#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000062 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000063 V(AccessArgumentsAt) \
64 V(Add) \
65 V(ApplyArguments) \
66 V(ArgumentsElements) \
67 V(ArgumentsLength) \
68 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ArrayLiteral) \
70 V(BitAnd) \
71 V(BitNot) \
72 V(BitOr) \
73 V(BitXor) \
74 V(BlockEntry) \
75 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000076 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000077 V(CallConstantFunction) \
78 V(CallFunction) \
79 V(CallGlobal) \
80 V(CallKeyed) \
81 V(CallKnownGlobal) \
82 V(CallNamed) \
83 V(CallNew) \
84 V(CallRuntime) \
85 V(CallStub) \
86 V(Change) \
87 V(CheckFunction) \
88 V(CheckInstanceType) \
89 V(CheckMap) \
90 V(CheckNonSmi) \
91 V(CheckPrototypeMaps) \
92 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000093 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000094 V(ClassOfTestAndBranch) \
95 V(CompareIDAndBranch) \
96 V(CompareGeneric) \
97 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000098 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000099 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000101 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000105 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000107 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000108 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000109 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000111 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(GlobalObject) \
113 V(GlobalReceiver) \
114 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000115 V(HasCachedArrayIndexAndBranch) \
116 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000117 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000119 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000120 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000121 V(IsConstructCallAndBranch) \
122 V(IsNullAndBranch) \
123 V(IsObjectAndBranch) \
124 V(IsSmiAndBranch) \
125 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000126 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000128 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000130 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000131 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000132 V(LoadGlobalCell) \
133 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadKeyedFastElement) \
135 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000136 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000138 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139 V(LoadNamedGeneric) \
140 V(Mod) \
141 V(Mul) \
142 V(ObjectLiteral) \
143 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000144 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000145 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000146 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(PushArgument) \
148 V(RegExpLiteral) \
149 V(Return) \
150 V(Sar) \
151 V(Shl) \
152 V(Shr) \
153 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000154 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000156 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000157 V(StoreGlobalCell) \
158 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159 V(StoreKeyedFastElement) \
160 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000161 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000162 V(StoreNamedField) \
163 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000164 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000165 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000166 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000167 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000168 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000169 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000171 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000172 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000173 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000174 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(UnaryMathOperation) \
176 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000177 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178 V(ValueOf)
179
180#define GVN_FLAG_LIST(V) \
181 V(Calls) \
182 V(InobjectFields) \
183 V(BackingStoreFields) \
184 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000185 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000186 V(GlobalVars) \
187 V(Maps) \
188 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000189 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000190 V(OsrEntries)
191
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000192#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193 virtual bool Is##type() const { return true; } \
194 static H##type* cast(HValue* value) { \
195 ASSERT(value->Is##type()); \
196 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000197 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198
199
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000200#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000202 static H##type* cast(HValue* value) { \
203 ASSERT(value->Is##type()); \
204 return reinterpret_cast<H##type*>(value); \
205 } \
206 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207
208
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209class Range: public ZoneObject {
210 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000211 Range()
212 : lower_(kMinInt),
213 upper_(kMaxInt),
214 next_(NULL),
215 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216
217 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000218 : lower_(lower),
219 upper_(upper),
220 next_(NULL),
221 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000223 int32_t upper() const { return upper_; }
224 int32_t lower() const { return lower_; }
225 Range* next() const { return next_; }
226 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
227 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 int32_t Mask() const;
230 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
231 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
232 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
233 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000234 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
235 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
236 bool IsInSmiRange() const {
237 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000239 void KeepOrder();
240 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000241
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000242 void StackUpon(Range* other) {
243 Intersect(other);
244 next_ = other;
245 }
246
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 void Intersect(Range* other);
248 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000249
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000250 void AddConstant(int32_t value);
251 void Sar(int32_t value);
252 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000253 bool AddAndCheckOverflow(Range* other);
254 bool SubAndCheckOverflow(Range* other);
255 bool MulAndCheckOverflow(Range* other);
256
257 private:
258 int32_t lower_;
259 int32_t upper_;
260 Range* next_;
261 bool can_be_minus_zero_;
262};
263
264
265class Representation {
266 public:
267 enum Kind {
268 kNone,
269 kTagged,
270 kDouble,
271 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000272 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 kNumRepresentations
274 };
275
276 Representation() : kind_(kNone) { }
277
278 static Representation None() { return Representation(kNone); }
279 static Representation Tagged() { return Representation(kTagged); }
280 static Representation Integer32() { return Representation(kInteger32); }
281 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000282 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000284 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000285 return kind_ == other.kind_;
286 }
287
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000288 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000289 bool IsNone() const { return kind_ == kNone; }
290 bool IsTagged() const { return kind_ == kTagged; }
291 bool IsInteger32() const { return kind_ == kInteger32; }
292 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000293 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000294 bool IsSpecialization() const {
295 return kind_ == kInteger32 || kind_ == kDouble;
296 }
297 const char* Mnemonic() const;
298
299 private:
300 explicit Representation(Kind k) : kind_(k) { }
301
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000302 // Make sure kind fits in int8.
303 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
304
305 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000306};
307
308
309class HType {
310 public:
311 HType() : type_(kUninitialized) { }
312
313 static HType Tagged() { return HType(kTagged); }
314 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
315 static HType TaggedNumber() { return HType(kTaggedNumber); }
316 static HType Smi() { return HType(kSmi); }
317 static HType HeapNumber() { return HType(kHeapNumber); }
318 static HType String() { return HType(kString); }
319 static HType Boolean() { return HType(kBoolean); }
320 static HType NonPrimitive() { return HType(kNonPrimitive); }
321 static HType JSArray() { return HType(kJSArray); }
322 static HType JSObject() { return HType(kJSObject); }
323 static HType Uninitialized() { return HType(kUninitialized); }
324
325 // Return the weakest (least precise) common type.
326 HType Combine(HType other) {
327 return HType(static_cast<Type>(type_ & other.type_));
328 }
329
330 bool Equals(const HType& other) {
331 return type_ == other.type_;
332 }
333
334 bool IsSubtypeOf(const HType& other) {
335 return Combine(other).Equals(other);
336 }
337
338 bool IsTagged() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kTagged) == kTagged);
341 }
342
343 bool IsTaggedPrimitive() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
346 }
347
348 bool IsTaggedNumber() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kTaggedNumber) == kTaggedNumber);
351 }
352
353 bool IsSmi() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kSmi) == kSmi);
356 }
357
358 bool IsHeapNumber() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kHeapNumber) == kHeapNumber);
361 }
362
363 bool IsString() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kString) == kString);
366 }
367
368 bool IsBoolean() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kBoolean) == kBoolean);
371 }
372
373 bool IsNonPrimitive() {
374 ASSERT(type_ != kUninitialized);
375 return ((type_ & kNonPrimitive) == kNonPrimitive);
376 }
377
378 bool IsJSArray() {
379 ASSERT(type_ != kUninitialized);
380 return ((type_ & kJSArray) == kJSArray);
381 }
382
383 bool IsJSObject() {
384 ASSERT(type_ != kUninitialized);
385 return ((type_ & kJSObject) == kJSObject);
386 }
387
388 bool IsUninitialized() {
389 return type_ == kUninitialized;
390 }
391
392 static HType TypeFromValue(Handle<Object> value);
393
394 const char* ToString();
395 const char* ToShortString();
396
397 private:
398 enum Type {
399 kTagged = 0x1, // 0000 0000 0000 0001
400 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
401 kTaggedNumber = 0xd, // 0000 0000 0000 1101
402 kSmi = 0x1d, // 0000 0000 0001 1101
403 kHeapNumber = 0x2d, // 0000 0000 0010 1101
404 kString = 0x45, // 0000 0000 0100 0101
405 kBoolean = 0x85, // 0000 0000 1000 0101
406 kNonPrimitive = 0x101, // 0000 0001 0000 0001
407 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000408 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000409 kUninitialized = 0x1fff // 0001 1111 1111 1111
410 };
411
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000412 // Make sure type fits in int16.
413 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
414
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000415 explicit HType(Type t) : type_(t) { }
416
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000417 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000418};
419
420
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000421class HUseListNode: public ZoneObject {
422 public:
423 HUseListNode(HValue* value, int index, HUseListNode* tail)
424 : tail_(tail), value_(value), index_(index) {
425 }
426
427 HUseListNode* tail() const { return tail_; }
428 HValue* value() const { return value_; }
429 int index() const { return index_; }
430
431 void set_tail(HUseListNode* list) { tail_ = list; }
432
433#ifdef DEBUG
434 void Zap() {
435 tail_ = reinterpret_cast<HUseListNode*>(1);
436 value_ = NULL;
437 index_ = -1;
438 }
439#endif
440
441 private:
442 HUseListNode* tail_;
443 HValue* value_;
444 int index_;
445};
446
447
448// We reuse use list nodes behind the scenes as uses are added and deleted.
449// This class is the safe way to iterate uses while deleting them.
450class HUseIterator BASE_EMBEDDED {
451 public:
452 bool Done() { return current_ == NULL; }
453 void Advance();
454
455 HValue* value() {
456 ASSERT(!Done());
457 return value_;
458 }
459
460 int index() {
461 ASSERT(!Done());
462 return index_;
463 }
464
465 private:
466 explicit HUseIterator(HUseListNode* head);
467
468 HUseListNode* current_;
469 HUseListNode* next_;
470 HValue* value_;
471 int index_;
472
473 friend class HValue;
474};
475
476
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000477class HValue: public ZoneObject {
478 public:
479 static const int kNoNumber = -1;
480
481 // There must be one corresponding kDepends flag for every kChanges flag and
482 // the order of the kChanges flags must be exactly the same as of the kDepends
483 // flags.
484 enum Flag {
485 // Declare global value numbering flags.
486 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
487 GVN_FLAG_LIST(DECLARE_DO)
488 #undef DECLARE_DO
489 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000490 // Participate in Global Value Numbering, i.e. elimination of
491 // unnecessary recomputations. If an instruction sets this flag, it must
492 // implement DataEquals(), which will be used to determine if other
493 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000494 kUseGVN,
495 kCanOverflow,
496 kBailoutOnMinusZero,
497 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000498 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000499 kIsArguments,
500 kTruncatingToInt32,
501 kLastFlag = kTruncatingToInt32
502 };
503
504 STATIC_ASSERT(kLastFlag < kBitsPerInt);
505
506 static const int kChangesToDependsFlagsLeftShift = 1;
507
508 static int ChangesFlagsMask() {
509 int result = 0;
510 // Create changes mask.
511#define DECLARE_DO(type) result |= (1 << kChanges##type);
512 GVN_FLAG_LIST(DECLARE_DO)
513#undef DECLARE_DO
514 return result;
515 }
516
517 static int DependsFlagsMask() {
518 return ConvertChangesToDependsFlags(ChangesFlagsMask());
519 }
520
521 static int ConvertChangesToDependsFlags(int flags) {
522 return flags << kChangesToDependsFlagsLeftShift;
523 }
524
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000525 static HValue* cast(HValue* value) { return value; }
526
527 enum Opcode {
528 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000529 #define DECLARE_OPCODE(type) k##type,
530 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
531 kPhi
532 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000534 virtual Opcode opcode() const = 0;
535
536 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
537 #define DECLARE_PREDICATE(type) \
538 bool Is##type() const { return opcode() == k##type; }
539 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
540 #undef DECLARE_PREDICATE
541 bool IsPhi() const { return opcode() == kPhi; }
542
543 // Declare virtual predicates for abstract HInstruction or HValue
544 #define DECLARE_PREDICATE(type) \
545 virtual bool Is##type() const { return false; }
546 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
547 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000548
549 HValue() : block_(NULL),
550 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000552 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553 range_(NULL),
554 flags_(0) {}
555 virtual ~HValue() {}
556
557 HBasicBlock* block() const { return block_; }
558 void SetBlock(HBasicBlock* block);
559
560 int id() const { return id_; }
561 void set_id(int id) { id_ = id; }
562
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000563 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000565 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566 Representation representation() const { return representation_; }
567 void ChangeRepresentation(Representation r) {
568 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569 ASSERT(!r.IsNone());
570 ASSERT(CheckFlag(kFlexibleRepresentation));
571 RepresentationChanged(r);
572 representation_ = r;
573 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000574 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000575
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000576 virtual bool IsConvertibleToInteger() const { return true; }
577
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578 HType type() const { return type_; }
579 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000580 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581 type_ = type;
582 }
583
584 // An operation needs to override this function iff:
585 // 1) it can produce an int32 output.
586 // 2) the true value of its output can potentially be minus zero.
587 // The implementation must set a flag so that it bails out in the case where
588 // it would otherwise output what should be a minus zero as an int32 zero.
589 // If the operation also exists in a form that takes int32 and outputs int32
590 // then the operation should return its input value so that we can propagate
591 // back. There are two operations that need to propagate back to more than
592 // one input. They are phi and binary add. They always return NULL and
593 // expect the caller to take care of things.
594 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
595 visited->Add(id());
596 return NULL;
597 }
598
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599 bool IsDefinedAfter(HBasicBlock* other) const;
600
601 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000602 virtual int OperandCount() = 0;
603 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000604 void SetOperandAt(int index, HValue* value);
605
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000606 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000607 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000608 bool HasNoUses() const { return use_list_ == NULL; }
609 bool HasMultipleUses() const {
610 return use_list_ != NULL && use_list_->tail() != NULL;
611 }
612 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000613 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000614
615 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000616 void SetFlag(Flag f) { flags_ |= (1 << f); }
617 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
618 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
619
620 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
621 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
622 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000623
624 Range* range() const { return range_; }
625 bool HasRange() const { return range_ != NULL; }
626 void AddNewRange(Range* r);
627 void RemoveLastAddedRange();
628 void ComputeInitialRange();
629
630 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000631 virtual Representation RequiredInputRepresentation(int index) const = 0;
632
633 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000634 return representation();
635 }
636
637 // This gives the instruction an opportunity to replace itself with an
638 // instruction that does the same in some better way. To replace an
639 // instruction with a new one, first add the new instruction to the graph,
640 // then return it. Return NULL to have the instruction deleted.
641 virtual HValue* Canonicalize() { return this; }
642
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000643 bool Equals(HValue* other);
644 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645
646 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000647 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000649 void PrintTypeTo(StringStream* stream);
650 void PrintRangeTo(StringStream* stream);
651 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000653 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654
655 // Updated the inferred type of this instruction and returns true if
656 // it has changed.
657 bool UpdateInferredType();
658
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000659 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000661#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000662 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663#endif
664
665 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000666 // This function must be overridden for instructions with flag kUseGVN, to
667 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000668 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000669 UNREACHABLE();
670 return false;
671 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000672 virtual void RepresentationChanged(Representation to) { }
673 virtual Range* InferRange();
674 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000675 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000676 void clear_block() {
677 ASSERT(block_ != NULL);
678 block_ = NULL;
679 }
680
681 void set_representation(Representation r) {
682 // Representation is set-once.
683 ASSERT(representation_.IsNone() && !r.IsNone());
684 representation_ = r;
685 }
686
687 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000688 // A flag mask to mark an instruction as having arbitrary side effects.
689 static int AllSideEffects() {
690 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
691 }
692
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000693 // Remove the matching use from the use list if present. Returns the
694 // removed list node or NULL.
695 HUseListNode* RemoveUse(HValue* value, int index);
696
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000697 void RegisterUse(int index, HValue* new_value);
698
699 HBasicBlock* block_;
700
701 // The id of this instruction in the hydrogen graph, assigned when first
702 // added to the graph. Reflects creation order.
703 int id_;
704
705 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000706 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000707 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000708 Range* range_;
709 int flags_;
710
711 DISALLOW_COPY_AND_ASSIGN(HValue);
712};
713
714
715class HInstruction: public HValue {
716 public:
717 HInstruction* next() const { return next_; }
718 HInstruction* previous() const { return previous_; }
719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000720 virtual void PrintTo(StringStream* stream);
721 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000722
723 bool IsLinked() const { return block() != NULL; }
724 void Unlink();
725 void InsertBefore(HInstruction* next);
726 void InsertAfter(HInstruction* previous);
727
728 int position() const { return position_; }
729 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
730 void set_position(int position) { position_ = position; }
731
732 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
733
734#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000735 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000736#endif
737
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000738 virtual bool IsCall() { return false; }
739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000740 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000741
742 protected:
743 HInstruction()
744 : next_(NULL),
745 previous_(NULL),
746 position_(RelocInfo::kNoPosition) {
747 SetFlag(kDependsOnOsrEntries);
748 }
749
750 virtual void DeleteFromGraph() { Unlink(); }
751
752 private:
753 void InitializeAsFirst(HBasicBlock* block) {
754 ASSERT(!IsLinked());
755 SetBlock(block);
756 }
757
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000758 void PrintMnemonicTo(StringStream* stream);
759
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000760 HInstruction* next_;
761 HInstruction* previous_;
762 int position_;
763
764 friend class HBasicBlock;
765};
766
767
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000768template<int V>
769class HTemplateInstruction : public HInstruction {
770 public:
771 int OperandCount() { return V; }
772 HValue* OperandAt(int i) { return inputs_[i]; }
773
774 protected:
775 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
776
777 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000778 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000779};
780
781
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000782class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000783 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000784 virtual HBasicBlock* SuccessorAt(int i) = 0;
785 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000786 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000787
788 virtual void PrintDataTo(StringStream* stream);
789
790 HBasicBlock* FirstSuccessor() {
791 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
792 }
793 HBasicBlock* SecondSuccessor() {
794 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
795 }
796
797 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
798};
799
800
801class HSuccessorIterator BASE_EMBEDDED {
802 public:
803 explicit HSuccessorIterator(HControlInstruction* instr)
804 : instr_(instr), current_(0) { }
805
806 bool Done() { return current_ >= instr_->SuccessorCount(); }
807 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
808 void Advance() { current_++; }
809
810 private:
811 HControlInstruction* instr_;
812 int current_;
813};
814
815
816template<int S, int V>
817class HTemplateControlInstruction: public HControlInstruction {
818 public:
819 int SuccessorCount() { return S; }
820 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000821 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000822
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000823 int OperandCount() { return V; }
824 HValue* OperandAt(int i) { return inputs_[i]; }
825
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000827 protected:
828 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
829
830 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000831 EmbeddedContainer<HBasicBlock*, S> successors_;
832 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000833};
834
835
836class HBlockEntry: public HTemplateInstruction<0> {
837 public:
838 virtual Representation RequiredInputRepresentation(int index) const {
839 return Representation::None();
840 }
841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000842 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000843};
844
845
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000846// We insert soft-deoptimize when we hit code with unknown typefeedback,
847// so that we get a chance of re-optimizing with useful typefeedback.
848// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
849class HSoftDeoptimize: public HTemplateInstruction<0> {
850 public:
851 virtual Representation RequiredInputRepresentation(int index) const {
852 return Representation::None();
853 }
854
855 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
856};
857
858
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000859class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000860 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000861 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000862
863 virtual Representation RequiredInputRepresentation(int index) const {
864 return Representation::None();
865 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000866
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000867 virtual int OperandCount() { return values_.length(); }
868 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000869 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000871 virtual int SuccessorCount() { return 0; }
872 virtual HBasicBlock* SuccessorAt(int i) {
873 UNREACHABLE();
874 return NULL;
875 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000876 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
877 UNREACHABLE();
878 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000879
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000880 void AddEnvironmentValue(HValue* value) {
881 values_.Add(NULL);
882 SetOperandAt(values_.length() - 1, value);
883 }
884
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000885 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000887 enum UseEnvironment {
888 kNoUses,
889 kUseAll
890 };
891
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000892 protected:
893 virtual void InternalSetOperandAt(int index, HValue* value) {
894 values_[index] = value;
895 }
896
897 private:
898 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899};
900
901
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000902class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000904 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000905 SetSuccessorAt(0, target);
906 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000908 virtual Representation RequiredInputRepresentation(int index) const {
909 return Representation::None();
910 }
911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000912 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913};
914
915
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000916class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918 HUnaryControlInstruction(HValue* value,
919 HBasicBlock* true_target,
920 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000922 SetSuccessorAt(0, true_target);
923 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000924 }
925
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000926 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000928 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000929};
930
931
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000932class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000933 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000934 HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000935 : HUnaryControlInstruction(value, true_target, false_target) {
936 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000937 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000938 explicit HBranch(HValue* value)
939 : HUnaryControlInstruction(value, NULL, NULL) { }
940
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941
942 virtual Representation RequiredInputRepresentation(int index) const {
943 return Representation::None();
944 }
945
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000946 DECLARE_CONCRETE_INSTRUCTION(Branch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947};
948
949
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000950class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000951 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000952 HCompareMap(HValue* value,
953 Handle<Map> map,
954 HBasicBlock* true_target,
955 HBasicBlock* false_target)
956 : HUnaryControlInstruction(value, true_target, false_target),
957 map_(map) {
958 ASSERT(true_target != NULL);
959 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960 ASSERT(!map.is_null());
961 }
962
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000963 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000964
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965 Handle<Map> map() const { return map_; }
966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000967 virtual Representation RequiredInputRepresentation(int index) const {
968 return Representation::Tagged();
969 }
970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000971 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000972
973 private:
974 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000975};
976
977
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000978class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000980 explicit HReturn(HValue* value) {
981 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000982 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000984 virtual Representation RequiredInputRepresentation(int index) const {
985 return Representation::Tagged();
986 }
987
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000988 virtual void PrintDataTo(StringStream* stream);
989
990 HValue* value() { return OperandAt(0); }
991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000992 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000993};
994
995
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000996class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000998 virtual Representation RequiredInputRepresentation(int index) const {
999 return Representation::None();
1000 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001001
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001002 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001003};
1004
1005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001006class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001007 public:
1008 explicit HUnaryOperation(HValue* value) {
1009 SetOperandAt(0, value);
1010 }
1011
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001012 static HUnaryOperation* cast(HValue* value) {
1013 return reinterpret_cast<HUnaryOperation*>(value);
1014 }
1015
1016 virtual bool CanTruncateToInt32() const {
1017 return CheckFlag(kTruncatingToInt32);
1018 }
1019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001020 HValue* value() { return OperandAt(0); }
1021 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022};
1023
1024
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001025class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001026 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001027 HThrow(HValue* context, HValue* value) {
1028 SetOperandAt(0, context);
1029 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001030 SetAllSideEffects();
1031 }
1032
1033 virtual Representation RequiredInputRepresentation(int index) const {
1034 return Representation::Tagged();
1035 }
1036
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001037 HValue* context() { return OperandAt(0); }
1038 HValue* value() { return OperandAt(1); }
1039
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001040 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001041};
1042
1043
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001044class HUseConst: public HUnaryOperation {
1045 public:
1046 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1047
1048 virtual Representation RequiredInputRepresentation(int index) const {
1049 return Representation::None();
1050 }
1051
1052 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1053};
1054
1055
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001056class HForceRepresentation: public HTemplateInstruction<1> {
1057 public:
1058 HForceRepresentation(HValue* value, Representation required_representation) {
1059 SetOperandAt(0, value);
1060 set_representation(required_representation);
1061 }
1062
1063 HValue* value() { return OperandAt(0); }
1064
1065 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1066
1067 virtual Representation RequiredInputRepresentation(int index) const {
1068 return representation(); // Same as the output representation.
1069 }
1070
1071 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1072};
1073
1074
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001075class HChange: public HUnaryOperation {
1076 public:
1077 HChange(HValue* value,
1078 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001079 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001080 bool is_truncating,
1081 bool deoptimize_on_undefined)
1082 : HUnaryOperation(value),
1083 from_(from),
1084 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085 ASSERT(!from.IsNone() && !to.IsNone());
1086 ASSERT(!from.Equals(to));
1087 set_representation(to);
1088 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001089 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001090 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1091 value->range()->IsInSmiRange()) {
1092 set_type(HType::Smi());
1093 }
1094 }
1095
1096 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1097
1098 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001099 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001100 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001101 virtual Representation RequiredInputRepresentation(int index) const {
1102 return from_;
1103 }
1104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001105 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001106
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001107 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108
1109 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001110 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001111 if (!other->IsChange()) return false;
1112 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001113 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001114 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115 }
1116
1117 private:
1118 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001119 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001120};
1121
1122
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001123class HClampToUint8: public HUnaryOperation {
1124 public:
1125 explicit HClampToUint8(HValue* value)
1126 : HUnaryOperation(value),
1127 input_rep_(Representation::None()) {
1128 SetFlag(kFlexibleRepresentation);
1129 set_representation(Representation::Tagged());
1130 SetFlag(kUseGVN);
1131 }
1132
1133 virtual Representation RequiredInputRepresentation(int index) const {
1134 return input_rep_;
1135 }
1136
1137 virtual Representation InferredRepresentation() {
1138 // TODO(danno): Inference on input types should happen separately from
1139 // return representation.
1140 Representation new_rep = value()->representation();
1141 if (input_rep_.IsNone()) {
1142 if (!new_rep.IsNone()) {
1143 input_rep_ = new_rep;
1144 return Representation::Integer32();
1145 } else {
1146 return Representation::None();
1147 }
1148 } else {
1149 return Representation::Integer32();
1150 }
1151 }
1152
1153 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1154
1155 protected:
1156 virtual bool DataEquals(HValue* other) { return true; }
1157
1158 private:
1159 Representation input_rep_;
1160};
1161
1162
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001163class HToInt32: public HUnaryOperation {
1164 public:
1165 explicit HToInt32(HValue* value)
1166 : HUnaryOperation(value) {
1167 set_representation(Representation::Integer32());
1168 SetFlag(kUseGVN);
1169 }
1170
1171 virtual Representation RequiredInputRepresentation(int index) const {
1172 return Representation::None();
1173 }
1174
1175 virtual bool CanTruncateToInt32() const {
1176 return true;
1177 }
1178
1179 virtual HValue* Canonicalize() {
1180 if (value()->representation().IsInteger32()) {
1181 return value();
1182 } else {
1183 return this;
1184 }
1185 }
1186
1187 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1188
1189 protected:
1190 virtual bool DataEquals(HValue* other) { return true; }
1191};
1192
1193
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194class HSimulate: public HInstruction {
1195 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001196 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001197 : ast_id_(ast_id),
1198 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001199 values_(2),
1200 assigned_indexes_(2) {}
1201 virtual ~HSimulate() {}
1202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001204
1205 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1206 int ast_id() const { return ast_id_; }
1207 void set_ast_id(int id) {
1208 ASSERT(!HasAstId());
1209 ast_id_ = id;
1210 }
1211
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001212 int pop_count() const { return pop_count_; }
1213 const ZoneList<HValue*>* values() const { return &values_; }
1214 int GetAssignedIndexAt(int index) const {
1215 ASSERT(HasAssignedIndexAt(index));
1216 return assigned_indexes_[index];
1217 }
1218 bool HasAssignedIndexAt(int index) const {
1219 return assigned_indexes_[index] != kNoIndex;
1220 }
1221 void AddAssignedValue(int index, HValue* value) {
1222 AddValue(index, value);
1223 }
1224 void AddPushedValue(HValue* value) {
1225 AddValue(kNoIndex, value);
1226 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227 virtual int OperandCount() { return values_.length(); }
1228 virtual HValue* OperandAt(int index) { return values_[index]; }
1229
1230 virtual Representation RequiredInputRepresentation(int index) const {
1231 return Representation::None();
1232 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001234 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001235
1236#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001237 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238#endif
1239
1240 protected:
1241 virtual void InternalSetOperandAt(int index, HValue* value) {
1242 values_[index] = value;
1243 }
1244
1245 private:
1246 static const int kNoIndex = -1;
1247 void AddValue(int index, HValue* value) {
1248 assigned_indexes_.Add(index);
1249 // Resize the list of pushed values.
1250 values_.Add(NULL);
1251 // Set the operand through the base method in HValue to make sure that the
1252 // use lists are correctly updated.
1253 SetOperandAt(values_.length() - 1, value);
1254 }
1255 int ast_id_;
1256 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257 ZoneList<HValue*> values_;
1258 ZoneList<int> assigned_indexes_;
1259};
1260
1261
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001262class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001264 enum Type {
1265 kFunctionEntry,
1266 kBackwardsBranch
1267 };
1268
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001269 HStackCheck(HValue* context, Type type) : type_(type) {
1270 SetOperandAt(0, context);
1271 }
1272
1273 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001275 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001276 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001277 }
1278
ager@chromium.org04921a82011-06-27 13:21:41 +00001279 void Eliminate() {
1280 // The stack check eliminator might try to eliminate the same stack
1281 // check instruction multiple times.
1282 if (IsLinked()) {
1283 DeleteFromGraph();
1284 }
1285 }
1286
1287 bool is_function_entry() { return type_ == kFunctionEntry; }
1288 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1289
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001290 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001291
1292 private:
1293 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294};
1295
1296
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001297class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001298 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001299 HEnterInlined(Handle<JSFunction> closure,
1300 FunctionLiteral* function,
1301 CallKind call_kind)
1302 : closure_(closure),
1303 function_(function),
1304 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305 }
1306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308
1309 Handle<JSFunction> closure() const { return closure_; }
1310 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001311 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001313 virtual Representation RequiredInputRepresentation(int index) const {
1314 return Representation::None();
1315 }
1316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001317 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318
1319 private:
1320 Handle<JSFunction> closure_;
1321 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001322 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323};
1324
1325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327 public:
1328 HLeaveInlined() {}
1329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001330 virtual Representation RequiredInputRepresentation(int index) const {
1331 return Representation::None();
1332 }
1333
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001334 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335};
1336
1337
1338class HPushArgument: public HUnaryOperation {
1339 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001340 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1341 set_representation(Representation::Tagged());
1342 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343
1344 virtual Representation RequiredInputRepresentation(int index) const {
1345 return Representation::Tagged();
1346 }
1347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001348 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001349
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001350 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001351};
1352
1353
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001354class HThisFunction: public HTemplateInstruction<0> {
1355 public:
1356 HThisFunction() {
1357 set_representation(Representation::Tagged());
1358 SetFlag(kUseGVN);
1359 }
1360
1361 virtual Representation RequiredInputRepresentation(int index) const {
1362 return Representation::None();
1363 }
1364
1365 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1366
1367 protected:
1368 virtual bool DataEquals(HValue* other) { return true; }
1369};
1370
1371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001374 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001375 set_representation(Representation::Tagged());
1376 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001377 }
1378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001379 virtual Representation RequiredInputRepresentation(int index) const {
1380 return Representation::None();
1381 }
1382
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001383 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001384
1385 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001386 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001387};
1388
1389
1390class HOuterContext: public HUnaryOperation {
1391 public:
1392 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1393 set_representation(Representation::Tagged());
1394 SetFlag(kUseGVN);
1395 }
1396
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001397 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001398
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001399 virtual Representation RequiredInputRepresentation(int index) const {
1400 return Representation::Tagged();
1401 }
1402
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001403 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001405};
1406
1407
1408class HGlobalObject: public HUnaryOperation {
1409 public:
1410 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1411 set_representation(Representation::Tagged());
1412 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413 }
1414
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001415 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001417 virtual Representation RequiredInputRepresentation(int index) const {
1418 return Representation::Tagged();
1419 }
1420
ager@chromium.org378b34e2011-01-28 08:04:38 +00001421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001422 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423};
1424
1425
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001426class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001428 explicit HGlobalReceiver(HValue* global_object)
1429 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430 set_representation(Representation::Tagged());
1431 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432 }
1433
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001434 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001436 virtual Representation RequiredInputRepresentation(int index) const {
1437 return Representation::Tagged();
1438 }
1439
ager@chromium.org378b34e2011-01-28 08:04:38 +00001440 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001442};
1443
1444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445template <int V>
1446class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001447 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001449 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1450 this->set_representation(Representation::Tagged());
1451 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001452 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001454 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001455
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001456 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001459
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001460 private:
1461 int argument_count_;
1462};
1463
1464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001466 public:
1467 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001468 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001469 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001470 }
1471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001472 virtual Representation RequiredInputRepresentation(int index) const {
1473 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001474 }
1475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476 virtual void PrintDataTo(StringStream* stream);
1477
1478 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001479};
1480
1481
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001482class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001483 public:
1484 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001485 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001486 SetOperandAt(0, first);
1487 SetOperandAt(1, second);
1488 }
1489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001490 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001492 virtual Representation RequiredInputRepresentation(int index) const {
1493 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001494 }
1495
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001496 HValue* first() { return OperandAt(0); }
1497 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498};
1499
1500
danno@chromium.org160a7b02011-04-18 15:51:38 +00001501class HInvokeFunction: public HBinaryCall {
1502 public:
1503 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1504 : HBinaryCall(context, function, argument_count) {
1505 }
1506
1507 virtual Representation RequiredInputRepresentation(int index) const {
1508 return Representation::Tagged();
1509 }
1510
1511 HValue* context() { return first(); }
1512 HValue* function() { return second(); }
1513
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001514 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001515};
1516
1517
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001518class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519 public:
1520 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001521 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522
1523 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001524
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001525 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001526 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001527 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 }
1529
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001530 virtual void PrintDataTo(StringStream* stream);
1531
1532 virtual Representation RequiredInputRepresentation(int index) const {
1533 return Representation::None();
1534 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001536 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537
1538 private:
1539 Handle<JSFunction> function_;
1540};
1541
1542
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001543class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001544 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001545 HCallKeyed(HValue* context, HValue* key, int argument_count)
1546 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547 }
1548
1549 virtual Representation RequiredInputRepresentation(int index) const {
1550 return Representation::Tagged();
1551 }
1552
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001553 HValue* context() { return first(); }
1554 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001556 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001557};
1558
1559
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001560class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001562 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1563 : HUnaryCall(context, argument_count), name_(name) {
1564 }
1565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001566 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001567
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001568 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001569 Handle<String> name() const { return name_; }
1570
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001571 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001573 virtual Representation RequiredInputRepresentation(int index) const {
1574 return Representation::Tagged();
1575 }
1576
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577 private:
1578 Handle<String> name_;
1579};
1580
1581
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001582class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001583 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001584 HCallFunction(HValue* context, int argument_count)
1585 : HUnaryCall(context, argument_count) {
1586 }
1587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001588 HValue* context() { return value(); }
1589
1590 virtual Representation RequiredInputRepresentation(int index) const {
1591 return Representation::Tagged();
1592 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001594 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595};
1596
1597
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001598class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001600 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1601 : HUnaryCall(context, argument_count), name_(name) {
1602 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001604 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001606 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607 Handle<String> name() const { return name_; }
1608
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001609 virtual Representation RequiredInputRepresentation(int index) const {
1610 return Representation::Tagged();
1611 }
1612
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001613 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614
1615 private:
1616 Handle<String> name_;
1617};
1618
1619
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001620class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001622 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001625 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001626
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001627 Handle<JSFunction> target() const { return target_; }
1628
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001629 virtual Representation RequiredInputRepresentation(int index) const {
1630 return Representation::None();
1631 }
1632
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001633 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634
1635 private:
1636 Handle<JSFunction> target_;
1637};
1638
1639
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001640class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001641 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001642 HCallNew(HValue* context, HValue* constructor, int argument_count)
1643 : HBinaryCall(context, constructor, argument_count) {
1644 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001645
1646 virtual Representation RequiredInputRepresentation(int index) const {
1647 return Representation::Tagged();
1648 }
1649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001650 HValue* context() { return first(); }
1651 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001653 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654};
1655
1656
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001657class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001658 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001659 HCallRuntime(HValue* context,
1660 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001661 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001662 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001663 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1664 SetOperandAt(0, context);
1665 }
1666
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001667 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001668
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001669 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001670 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671 Handle<String> name() const { return name_; }
1672
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001673 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001674 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001675 }
1676
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001677 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001678
1679 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001680 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001681 Handle<String> name_;
1682};
1683
1684
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001685class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001687 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001688 // The length of an array is stored as a tagged value in the array
1689 // object. It is guaranteed to be 32 bit integer, but it can be
1690 // represented as either a smi or heap number.
1691 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001692 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001693 SetFlag(kDependsOnArrayLengths);
1694 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695 }
1696
1697 virtual Representation RequiredInputRepresentation(int index) const {
1698 return Representation::Tagged();
1699 }
1700
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001701 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001702
1703 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001704 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001705};
1706
1707
1708class HFixedArrayLength: public HUnaryOperation {
1709 public:
1710 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1711 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001712 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001713 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001714 }
1715
1716 virtual Representation RequiredInputRepresentation(int index) const {
1717 return Representation::Tagged();
1718 }
1719
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001720 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001721
1722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001723 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001724};
1725
1726
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001727class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001728 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001729 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001730 set_representation(Representation::Integer32());
1731 // The result of this instruction is idempotent as long as its inputs don't
1732 // change. The length of a pixel array cannot change once set, so it's not
1733 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1734 SetFlag(kUseGVN);
1735 }
1736
1737 virtual Representation RequiredInputRepresentation(int index) const {
1738 return Representation::Tagged();
1739 }
1740
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001741 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001742
1743 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001744 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001745};
1746
1747
whesse@chromium.org7b260152011-06-20 15:33:18 +00001748class HElementsKind: public HUnaryOperation {
1749 public:
1750 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1751 set_representation(Representation::Integer32());
1752 SetFlag(kUseGVN);
1753 SetFlag(kDependsOnMaps);
1754 }
1755
1756 virtual Representation RequiredInputRepresentation(int index) const {
1757 return Representation::Tagged();
1758 }
1759
1760 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1761
1762 protected:
1763 virtual bool DataEquals(HValue* other) { return true; }
1764};
1765
1766
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767class HBitNot: public HUnaryOperation {
1768 public:
1769 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1770 set_representation(Representation::Integer32());
1771 SetFlag(kUseGVN);
1772 SetFlag(kTruncatingToInt32);
1773 }
1774
1775 virtual Representation RequiredInputRepresentation(int index) const {
1776 return Representation::Integer32();
1777 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001778 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001779
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001780 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001781
1782 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001783 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001784};
1785
1786
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001787class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001789 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1790 : op_(op) {
1791 SetOperandAt(0, context);
1792 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793 switch (op) {
1794 case kMathFloor:
1795 case kMathRound:
1796 case kMathCeil:
1797 set_representation(Representation::Integer32());
1798 break;
1799 case kMathAbs:
1800 set_representation(Representation::Tagged());
1801 SetFlag(kFlexibleRepresentation);
1802 break;
1803 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001804 case kMathPowHalf:
1805 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001806 case kMathSin:
1807 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001808 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001809 break;
1810 default:
1811 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001812 }
1813 SetFlag(kUseGVN);
1814 }
1815
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001816 HValue* context() { return OperandAt(0); }
1817 HValue* value() { return OperandAt(1); }
1818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001819 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001820
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001821 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001822
1823 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1824
1825 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001826 if (index == 0) {
1827 return Representation::Tagged();
1828 } else {
1829 switch (op_) {
1830 case kMathFloor:
1831 case kMathRound:
1832 case kMathCeil:
1833 case kMathSqrt:
1834 case kMathPowHalf:
1835 case kMathLog:
1836 case kMathSin:
1837 case kMathCos:
1838 return Representation::Double();
1839 case kMathAbs:
1840 return representation();
1841 default:
1842 UNREACHABLE();
1843 return Representation::None();
1844 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001845 }
1846 }
1847
1848 virtual HValue* Canonicalize() {
1849 // If the input is integer32 then we replace the floor instruction
1850 // with its inputs. This happens before the representation changes are
1851 // introduced.
1852 if (op() == kMathFloor) {
1853 if (value()->representation().IsInteger32()) return value();
1854 }
1855 return this;
1856 }
1857
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001858 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001859 const char* OpName() const;
1860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001861 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001863 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001864 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001865 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1866 return op_ == b->op();
1867 }
1868
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001870 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001871};
1872
1873
1874class HLoadElements: public HUnaryOperation {
1875 public:
1876 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1877 set_representation(Representation::Tagged());
1878 SetFlag(kUseGVN);
1879 SetFlag(kDependsOnMaps);
1880 }
1881
1882 virtual Representation RequiredInputRepresentation(int index) const {
1883 return Representation::Tagged();
1884 }
1885
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001886 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001887
1888 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001889 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001890};
1891
1892
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001893class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001894 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001895 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001896 : HUnaryOperation(value) {
1897 set_representation(Representation::External());
1898 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001899 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001900 // change once set, so it's no necessary to introduce any additional
1901 // dependencies on top of the inputs.
1902 SetFlag(kUseGVN);
1903 }
1904
1905 virtual Representation RequiredInputRepresentation(int index) const {
1906 return Representation::Tagged();
1907 }
1908
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001909 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001910
1911 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001912 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001913};
1914
1915
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916class HCheckMap: public HUnaryOperation {
1917 public:
1918 HCheckMap(HValue* value, Handle<Map> map)
1919 : HUnaryOperation(value), map_(map) {
1920 set_representation(Representation::Tagged());
1921 SetFlag(kUseGVN);
1922 SetFlag(kDependsOnMaps);
1923 }
1924
1925 virtual Representation RequiredInputRepresentation(int index) const {
1926 return Representation::Tagged();
1927 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001928 virtual void PrintDataTo(StringStream* stream);
1929 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930
1931#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001932 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001933#endif
1934
1935 Handle<Map> map() const { return map_; }
1936
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001937 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001938
1939 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001940 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001941 HCheckMap* b = HCheckMap::cast(other);
1942 return map_.is_identical_to(b->map());
1943 }
1944
1945 private:
1946 Handle<Map> map_;
1947};
1948
1949
1950class HCheckFunction: public HUnaryOperation {
1951 public:
1952 HCheckFunction(HValue* value, Handle<JSFunction> function)
1953 : HUnaryOperation(value), target_(function) {
1954 set_representation(Representation::Tagged());
1955 SetFlag(kUseGVN);
1956 }
1957
1958 virtual Representation RequiredInputRepresentation(int index) const {
1959 return Representation::Tagged();
1960 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001961 virtual void PrintDataTo(StringStream* stream);
1962 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963
1964#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001965 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966#endif
1967
1968 Handle<JSFunction> target() const { return target_; }
1969
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001970 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971
1972 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001973 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974 HCheckFunction* b = HCheckFunction::cast(other);
1975 return target_.is_identical_to(b->target());
1976 }
1977
1978 private:
1979 Handle<JSFunction> target_;
1980};
1981
1982
1983class HCheckInstanceType: public HUnaryOperation {
1984 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001985 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1986 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001987 }
1988 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1989 return new HCheckInstanceType(value, IS_JS_ARRAY);
1990 }
1991 static HCheckInstanceType* NewIsString(HValue* value) {
1992 return new HCheckInstanceType(value, IS_STRING);
1993 }
1994 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1995 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996 }
1997
1998 virtual Representation RequiredInputRepresentation(int index) const {
1999 return Representation::Tagged();
2000 }
2001
2002#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002003 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002004#endif
2005
danno@chromium.org160a7b02011-04-18 15:51:38 +00002006 virtual HValue* Canonicalize() {
2007 if (!value()->type().IsUninitialized() &&
2008 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002009 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00002010 return NULL;
2011 }
2012 return this;
2013 }
2014
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002015 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2016 void GetCheckInterval(InstanceType* first, InstanceType* last);
2017 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002018
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002019 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020
2021 protected:
2022 // TODO(ager): It could be nice to allow the ommision of instance
2023 // type checks if we have already performed an instance type check
2024 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002025 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002026 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002027 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002028 }
2029
2030 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002031 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002032 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002033 IS_JS_ARRAY,
2034 IS_STRING,
2035 IS_SYMBOL,
2036 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2037 };
2038
2039 HCheckInstanceType(HValue* value, Check check)
2040 : HUnaryOperation(value), check_(check) {
2041 set_representation(Representation::Tagged());
2042 SetFlag(kUseGVN);
2043 }
2044
2045 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002046};
2047
2048
2049class HCheckNonSmi: public HUnaryOperation {
2050 public:
2051 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2052 set_representation(Representation::Tagged());
2053 SetFlag(kUseGVN);
2054 }
2055
2056 virtual Representation RequiredInputRepresentation(int index) const {
2057 return Representation::Tagged();
2058 }
2059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002060 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002061
2062#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002063 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064#endif
2065
danno@chromium.org160a7b02011-04-18 15:51:38 +00002066 virtual HValue* Canonicalize() {
2067 HType value_type = value()->type();
2068 if (!value_type.IsUninitialized() &&
2069 (value_type.IsHeapNumber() ||
2070 value_type.IsString() ||
2071 value_type.IsBoolean() ||
2072 value_type.IsNonPrimitive())) {
2073 return NULL;
2074 }
2075 return this;
2076 }
2077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002078 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002079
2080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002081 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082};
2083
2084
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002085class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002086 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002087 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2088 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002089 SetFlag(kUseGVN);
2090 SetFlag(kDependsOnMaps);
2091 }
2092
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002093#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002094 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095#endif
2096
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002097 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002098 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002100 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002101
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002102 virtual Representation RequiredInputRepresentation(int index) const {
2103 return Representation::None();
2104 }
2105
2106 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002107 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002108 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2109 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2110 return hash;
2111 }
2112
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002113 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002114 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002116 return prototype_.is_identical_to(b->prototype()) &&
2117 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002118 }
2119
2120 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002121 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123};
2124
2125
2126class HCheckSmi: public HUnaryOperation {
2127 public:
2128 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2129 set_representation(Representation::Tagged());
2130 SetFlag(kUseGVN);
2131 }
2132
2133 virtual Representation RequiredInputRepresentation(int index) const {
2134 return Representation::Tagged();
2135 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002136 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002137
2138#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002139 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002140#endif
2141
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002142 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002143
2144 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002145 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002146};
2147
2148
2149class HPhi: public HValue {
2150 public:
2151 explicit HPhi(int merged_index)
2152 : inputs_(2),
2153 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002154 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002155 is_live_(false),
2156 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002157 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2158 non_phi_uses_[i] = 0;
2159 indirect_uses_[i] = 0;
2160 }
2161 ASSERT(merged_index >= 0);
2162 set_representation(Representation::Tagged());
2163 SetFlag(kFlexibleRepresentation);
2164 }
2165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002166 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167 bool double_occurred = false;
2168 bool int32_occurred = false;
2169 for (int i = 0; i < OperandCount(); ++i) {
2170 HValue* value = OperandAt(i);
2171 if (value->representation().IsDouble()) double_occurred = true;
2172 if (value->representation().IsInteger32()) int32_occurred = true;
2173 if (value->representation().IsTagged()) return Representation::Tagged();
2174 }
2175
2176 if (double_occurred) return Representation::Double();
2177 if (int32_occurred) return Representation::Integer32();
2178 return Representation::None();
2179 }
2180
2181 virtual Range* InferRange();
2182 virtual Representation RequiredInputRepresentation(int index) const {
2183 return representation();
2184 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002185 virtual HType CalculateInferredType();
2186 virtual int OperandCount() { return inputs_.length(); }
2187 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2188 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002189 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002190 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002192 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002193
2194 int merged_index() const { return merged_index_; }
2195
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002196 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002197
2198#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002199 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002200#endif
2201
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002202 void InitRealUses(int id);
2203 void AddNonPhiUsesFrom(HPhi* other);
2204 void AddIndirectUsesTo(int* use_count);
2205
2206 int tagged_non_phi_uses() const {
2207 return non_phi_uses_[Representation::kTagged];
2208 }
2209 int int32_non_phi_uses() const {
2210 return non_phi_uses_[Representation::kInteger32];
2211 }
2212 int double_non_phi_uses() const {
2213 return non_phi_uses_[Representation::kDouble];
2214 }
2215 int tagged_indirect_uses() const {
2216 return indirect_uses_[Representation::kTagged];
2217 }
2218 int int32_indirect_uses() const {
2219 return indirect_uses_[Representation::kInteger32];
2220 }
2221 int double_indirect_uses() const {
2222 return indirect_uses_[Representation::kDouble];
2223 }
2224 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002225 bool is_live() { return is_live_; }
2226 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002228 static HPhi* cast(HValue* value) {
2229 ASSERT(value->IsPhi());
2230 return reinterpret_cast<HPhi*>(value);
2231 }
2232 virtual Opcode opcode() const { return HValue::kPhi; }
2233
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002234 virtual bool IsConvertibleToInteger() const {
2235 return is_convertible_to_integer_;
2236 }
2237
2238 void set_is_convertible_to_integer(bool b) {
2239 is_convertible_to_integer_ = b;
2240 }
2241
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002242 protected:
2243 virtual void DeleteFromGraph();
2244 virtual void InternalSetOperandAt(int index, HValue* value) {
2245 inputs_[index] = value;
2246 }
2247
2248 private:
2249 ZoneList<HValue*> inputs_;
2250 int merged_index_;
2251
2252 int non_phi_uses_[Representation::kNumRepresentations];
2253 int indirect_uses_[Representation::kNumRepresentations];
2254 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002255 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002256 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002257};
2258
2259
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002260class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002261 public:
2262 HArgumentsObject() {
2263 set_representation(Representation::Tagged());
2264 SetFlag(kIsArguments);
2265 }
2266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002267 virtual Representation RequiredInputRepresentation(int index) const {
2268 return Representation::None();
2269 }
2270
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002271 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002272};
2273
2274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002275class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276 public:
2277 HConstant(Handle<Object> handle, Representation r);
2278
2279 Handle<Object> handle() const { return handle_; }
2280
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002281 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002282
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002283 virtual Representation RequiredInputRepresentation(int index) const {
2284 return Representation::None();
2285 }
2286
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002287 virtual bool IsConvertibleToInteger() const {
2288 if (handle_->IsSmi()) return true;
2289 if (handle_->IsHeapNumber() &&
2290 (HeapNumber::cast(*handle_)->value() ==
2291 static_cast<double>(NumberToInt32(*handle_)))) return true;
2292 return false;
2293 }
2294
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002295 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002296 virtual void PrintDataTo(StringStream* stream);
2297 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002298 bool IsInteger() const { return handle_->IsSmi(); }
2299 HConstant* CopyToRepresentation(Representation r) const;
2300 HConstant* CopyToTruncatedInt32() const;
2301 bool HasInteger32Value() const { return has_int32_value_; }
2302 int32_t Integer32Value() const {
2303 ASSERT(HasInteger32Value());
2304 return int32_value_;
2305 }
2306 bool HasDoubleValue() const { return has_double_value_; }
2307 double DoubleValue() const {
2308 ASSERT(HasDoubleValue());
2309 return double_value_;
2310 }
2311 bool HasStringValue() const { return handle_->IsString(); }
2312
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002313 bool ToBoolean() const;
2314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002315 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002316 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002317 return reinterpret_cast<intptr_t>(*handle());
2318 }
2319
2320#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002321 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002322#endif
2323
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002324 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002325
2326 protected:
2327 virtual Range* InferRange();
2328
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002329 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002330 HConstant* other_constant = HConstant::cast(other);
2331 return handle().is_identical_to(other_constant->handle());
2332 }
2333
2334 private:
2335 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336
2337 // The following two values represent the int32 and the double value of the
2338 // given constant if there is a lossless conversion between the constant
2339 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002340 bool has_int32_value_ : 1;
2341 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002342 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343 double double_value_;
2344};
2345
2346
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002347class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002348 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002349 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002350 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002351 SetOperandAt(0, context);
2352 SetOperandAt(1, left);
2353 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002354 }
2355
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002356 HValue* context() { return OperandAt(0); }
2357 HValue* left() { return OperandAt(1); }
2358 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002359
2360 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2361 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002362 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363 if (IsCommutative() && left()->IsConstant()) return right();
2364 return left();
2365 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002366 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002367 if (IsCommutative() && left()->IsConstant()) return left();
2368 return right();
2369 }
2370
2371 virtual bool IsCommutative() const { return false; }
2372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374};
2375
2376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002377class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002378 public:
2379 HApplyArguments(HValue* function,
2380 HValue* receiver,
2381 HValue* length,
2382 HValue* elements) {
2383 set_representation(Representation::Tagged());
2384 SetOperandAt(0, function);
2385 SetOperandAt(1, receiver);
2386 SetOperandAt(2, length);
2387 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002388 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002389 }
2390
2391 virtual Representation RequiredInputRepresentation(int index) const {
2392 // The length is untagged, all other inputs are tagged.
2393 return (index == 2)
2394 ? Representation::Integer32()
2395 : Representation::Tagged();
2396 }
2397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002398 HValue* function() { return OperandAt(0); }
2399 HValue* receiver() { return OperandAt(1); }
2400 HValue* length() { return OperandAt(2); }
2401 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002402
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002403 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002404};
2405
2406
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002407class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002408 public:
2409 HArgumentsElements() {
2410 // The value produced by this instruction is a pointer into the stack
2411 // that looks as if it was a smi because of alignment.
2412 set_representation(Representation::Tagged());
2413 SetFlag(kUseGVN);
2414 }
2415
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002416 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002418 virtual Representation RequiredInputRepresentation(int index) const {
2419 return Representation::None();
2420 }
2421
ager@chromium.org378b34e2011-01-28 08:04:38 +00002422 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002423 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002424};
2425
2426
2427class HArgumentsLength: public HUnaryOperation {
2428 public:
2429 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2430 set_representation(Representation::Integer32());
2431 SetFlag(kUseGVN);
2432 }
2433
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002434 virtual Representation RequiredInputRepresentation(int index) const {
2435 return Representation::Tagged();
2436 }
2437
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002438 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002439
2440 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002441 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002442};
2443
2444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002445class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002446 public:
2447 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2448 set_representation(Representation::Tagged());
2449 SetFlag(kUseGVN);
2450 SetOperandAt(0, arguments);
2451 SetOperandAt(1, length);
2452 SetOperandAt(2, index);
2453 }
2454
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002455 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002456
2457 virtual Representation RequiredInputRepresentation(int index) const {
2458 // The arguments elements is considered tagged.
2459 return index == 0
2460 ? Representation::Tagged()
2461 : Representation::Integer32();
2462 }
2463
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002464 HValue* arguments() { return OperandAt(0); }
2465 HValue* length() { return OperandAt(1); }
2466 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002467
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002468 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002469
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002470 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002471};
2472
2473
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002474class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002475 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002476 HBoundsCheck(HValue* index, HValue* length) {
2477 SetOperandAt(0, index);
2478 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002479 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480 SetFlag(kUseGVN);
2481 }
2482
2483 virtual Representation RequiredInputRepresentation(int index) const {
2484 return Representation::Integer32();
2485 }
2486
2487#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002488 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002489#endif
2490
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002491 HValue* index() { return OperandAt(0); }
2492 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002493
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002494 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002495
2496 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002497 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002498};
2499
2500
2501class HBitwiseBinaryOperation: public HBinaryOperation {
2502 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002503 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2504 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002505 set_representation(Representation::Tagged());
2506 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002507 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002508 }
2509
2510 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002511 return index == 0
2512 ? Representation::Tagged()
2513 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002514 }
2515
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002516 virtual void RepresentationChanged(Representation to) {
2517 if (!to.IsTagged()) {
2518 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002519 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002520 SetFlag(kTruncatingToInt32);
2521 SetFlag(kUseGVN);
2522 }
2523 }
2524
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002525 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002526
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002527 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002528};
2529
2530
2531class HArithmeticBinaryOperation: public HBinaryOperation {
2532 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002533 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2534 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002535 set_representation(Representation::Tagged());
2536 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002537 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 }
2539
2540 virtual void RepresentationChanged(Representation to) {
2541 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002542 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002543 SetFlag(kUseGVN);
2544 }
2545 }
2546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002547 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002549 return index == 0
2550 ? Representation::Tagged()
2551 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002552 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002554 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555 if (left()->representation().Equals(right()->representation())) {
2556 return left()->representation();
2557 }
2558 return HValue::InferredRepresentation();
2559 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560};
2561
2562
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002563class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002564 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002565 HCompareGeneric(HValue* context,
2566 HValue* left,
2567 HValue* right,
2568 Token::Value token)
2569 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002570 ASSERT(Token::IsCompareOp(token));
2571 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002572 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002573 }
2574
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002576 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002577 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002578
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002579 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002580 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002582
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002584 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002586 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002587
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002588 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2589
2590 private:
2591 Token::Value token_;
2592};
2593
2594
2595class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2596 public:
2597 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2598 : token_(token) {
2599 ASSERT(Token::IsCompareOp(token));
2600 SetOperandAt(0, left);
2601 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002602 }
2603
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002604 HValue* left() { return OperandAt(0); }
2605 HValue* right() { return OperandAt(1); }
2606 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002607
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002608 void SetInputRepresentation(Representation r);
2609 Representation GetInputRepresentation() const {
2610 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002611 }
2612
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002613 virtual Representation RequiredInputRepresentation(int index) const {
2614 return input_representation_;
2615 }
2616 virtual void PrintDataTo(StringStream* stream);
2617
2618 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620 private:
2621 Representation input_representation_;
2622 Token::Value token_;
2623};
2624
2625
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002626class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002627 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002628 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2629 SetOperandAt(0, left);
2630 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002631 }
2632
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002633 HValue* left() { return OperandAt(0); }
2634 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002635
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002636 virtual Representation RequiredInputRepresentation(int index) const {
2637 return Representation::Tagged();
2638 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002640 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641};
2642
2643
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002644class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002645 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002646 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2647 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002648 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002649 }
2650
2651 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002652 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002653 int right() const { return right_; }
2654
whesse@chromium.org7b260152011-06-20 15:33:18 +00002655 virtual Representation RequiredInputRepresentation(int index) const {
2656 return Representation::Integer32();
2657 }
2658
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002659 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002660
2661 private:
2662 const Token::Value op_;
2663 const int right_;
2664};
2665
2666
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002667class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002668 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002669 HIsNullAndBranch(HValue* value, bool is_strict)
2670 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002671
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002672 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002673
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002674 virtual Representation RequiredInputRepresentation(int index) const {
2675 return Representation::Tagged();
2676 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002677
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002678 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002679
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680 private:
2681 bool is_strict_;
2682};
2683
2684
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002685class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002686 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002687 explicit HIsObjectAndBranch(HValue* value)
2688 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002689
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002690 virtual Representation RequiredInputRepresentation(int index) const {
2691 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002692 }
2693
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002694 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2695};
2696
2697
2698class HIsSmiAndBranch: public HUnaryControlInstruction {
2699 public:
2700 explicit HIsSmiAndBranch(HValue* value)
2701 : HUnaryControlInstruction(value, NULL, NULL) { }
2702
2703 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2704
2705 virtual Representation RequiredInputRepresentation(int index) const {
2706 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002707 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002708
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002709 protected:
2710 virtual bool DataEquals(HValue* other) { return true; }
2711};
2712
2713
2714class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2715 public:
2716 explicit HIsUndetectableAndBranch(HValue* value)
2717 : HUnaryControlInstruction(value, NULL, NULL) { }
2718
2719 virtual Representation RequiredInputRepresentation(int index) const {
2720 return Representation::Tagged();
2721 }
2722
2723 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2724};
2725
2726
2727class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2728 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002729 virtual Representation RequiredInputRepresentation(int index) const {
2730 return Representation::None();
2731 }
2732
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002733 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002734};
2735
2736
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002737class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002739 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2740 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2741 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2742 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2744 }
2745
2746 InstanceType from() { return from_; }
2747 InstanceType to() { return to_; }
2748
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002749 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002751 virtual Representation RequiredInputRepresentation(int index) const {
2752 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002753 }
2754
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002755 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2756
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757 private:
2758 InstanceType from_;
2759 InstanceType to_; // Inclusive range, not all combinations work.
2760};
2761
2762
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002763class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002765 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2766 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002767
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002768 virtual Representation RequiredInputRepresentation(int index) const {
2769 return Representation::Tagged();
2770 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002771
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002772 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773};
2774
2775
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002776class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002777 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002778 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2779 set_representation(Representation::Tagged());
2780 SetFlag(kUseGVN);
2781 }
2782
2783 virtual Representation RequiredInputRepresentation(int index) const {
2784 return Representation::Tagged();
2785 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002786
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002787 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002788
2789 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002790 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002791};
2792
2793
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002794class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002795 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002796 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2797 : HUnaryControlInstruction(value, NULL, NULL),
2798 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002800 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2801
2802 virtual Representation RequiredInputRepresentation(int index) const {
2803 return Representation::Tagged();
2804 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002805
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002806 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807
2808 Handle<String> class_name() const { return class_name_; }
2809
2810 private:
2811 Handle<String> class_name_;
2812};
2813
2814
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002815class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002816 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002817 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2818 : HUnaryControlInstruction(value, NULL, NULL),
2819 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820
2821 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002822 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002823
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002824 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002826 virtual Representation RequiredInputRepresentation(int index) const {
2827 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002828 }
2829
2830 private:
2831 Handle<String> type_literal_;
2832};
2833
2834
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002835class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002837 HInstanceOf(HValue* context, HValue* left, HValue* right)
2838 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002839 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002840 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002841 }
2842
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002843 virtual Representation RequiredInputRepresentation(int index) const {
2844 return Representation::Tagged();
2845 }
2846
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002847 virtual HType CalculateInferredType();
2848
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002849 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002850
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002851 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002852};
2853
2854
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002855class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002856 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002857 HInstanceOfKnownGlobal(HValue* context,
2858 HValue* left,
2859 Handle<JSFunction> right)
2860 : function_(right) {
2861 SetOperandAt(0, context);
2862 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002863 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002864 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002865 }
2866
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002867 HValue* context() { return OperandAt(0); }
2868 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002869 Handle<JSFunction> function() { return function_; }
2870
2871 virtual Representation RequiredInputRepresentation(int index) const {
2872 return Representation::Tagged();
2873 }
2874
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002875 virtual HType CalculateInferredType();
2876
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002877 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002878
2879 private:
2880 Handle<JSFunction> function_;
2881};
2882
2883
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002884class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002885 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002886 HPower(HValue* left, HValue* right) {
2887 SetOperandAt(0, left);
2888 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002889 set_representation(Representation::Double());
2890 SetFlag(kUseGVN);
2891 }
2892
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002893 HValue* left() { return OperandAt(0); }
2894 HValue* right() { return OperandAt(1); }
2895
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002896 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002897 return index == 0
2898 ? Representation::Double()
2899 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002900 }
2901
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002902 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002903
2904 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002905 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002906};
2907
2908
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002909class HAdd: public HArithmeticBinaryOperation {
2910 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002911 HAdd(HValue* context, HValue* left, HValue* right)
2912 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913 SetFlag(kCanOverflow);
2914 }
2915
2916 // Add is only commutative if two integer values are added and not if two
2917 // tagged values are added (because it might be a String concatenation).
2918 virtual bool IsCommutative() const {
2919 return !representation().IsTagged();
2920 }
2921
2922 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2923
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002924 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002926 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927
2928 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002929 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002930
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 virtual Range* InferRange();
2932};
2933
2934
2935class HSub: public HArithmeticBinaryOperation {
2936 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002937 HSub(HValue* context, HValue* left, HValue* right)
2938 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002939 SetFlag(kCanOverflow);
2940 }
2941
2942 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2943
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002944 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945
2946 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002947 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002948
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002949 virtual Range* InferRange();
2950};
2951
2952
2953class HMul: public HArithmeticBinaryOperation {
2954 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002955 HMul(HValue* context, HValue* left, HValue* right)
2956 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002957 SetFlag(kCanOverflow);
2958 }
2959
2960 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2961
2962 // Only commutative if it is certain that not two objects are multiplicated.
2963 virtual bool IsCommutative() const {
2964 return !representation().IsTagged();
2965 }
2966
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002967 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002968
2969 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002970 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002971
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002972 virtual Range* InferRange();
2973};
2974
2975
2976class HMod: public HArithmeticBinaryOperation {
2977 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002978 HMod(HValue* context, HValue* left, HValue* right)
2979 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002980 SetFlag(kCanBeDivByZero);
2981 }
2982
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002983 bool HasPowerOf2Divisor() {
2984 if (right()->IsConstant() &&
2985 HConstant::cast(right())->HasInteger32Value()) {
2986 int32_t value = HConstant::cast(right())->Integer32Value();
2987 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2988 }
2989
2990 return false;
2991 }
2992
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2994
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002995 DECLARE_CONCRETE_INSTRUCTION(Mod)
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 HDiv: public HArithmeticBinaryOperation {
3005 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003006 HDiv(HValue* context, HValue* left, HValue* right)
3007 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008 SetFlag(kCanBeDivByZero);
3009 SetFlag(kCanOverflow);
3010 }
3011
3012 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3013
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003014 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015
3016 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003017 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003018
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019 virtual Range* InferRange();
3020};
3021
3022
3023class HBitAnd: public HBitwiseBinaryOperation {
3024 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003025 HBitAnd(HValue* context, HValue* left, HValue* right)
3026 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
3028 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003029 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003031 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032
3033 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003034 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003035
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003036 virtual Range* InferRange();
3037};
3038
3039
3040class HBitXor: public HBitwiseBinaryOperation {
3041 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003042 HBitXor(HValue* context, HValue* left, HValue* right)
3043 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044
3045 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003048 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003049
3050 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003051 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003052};
3053
3054
3055class HBitOr: public HBitwiseBinaryOperation {
3056 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003057 HBitOr(HValue* context, HValue* left, HValue* right)
3058 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
3060 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003061 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003063 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003064
3065 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003067
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003068 virtual Range* InferRange();
3069};
3070
3071
3072class HShl: public HBitwiseBinaryOperation {
3073 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003074 HShl(HValue* context, HValue* left, HValue* right)
3075 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003076
3077 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003078 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003080 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003081
3082 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003083 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003084};
3085
3086
3087class HShr: public HBitwiseBinaryOperation {
3088 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003089 HShr(HValue* context, HValue* left, HValue* right)
3090 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003092 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003093
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003094 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003095
3096 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003097 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098};
3099
3100
3101class HSar: public HBitwiseBinaryOperation {
3102 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003103 HSar(HValue* context, HValue* left, HValue* right)
3104 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105
3106 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003107 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003109 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003110
3111 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003112 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113};
3114
3115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003116class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117 public:
3118 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3119 SetFlag(kChangesOsrEntries);
3120 }
3121
3122 int ast_id() const { return ast_id_; }
3123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003124 virtual Representation RequiredInputRepresentation(int index) const {
3125 return Representation::None();
3126 }
3127
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003128 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129
3130 private:
3131 int ast_id_;
3132};
3133
3134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003135class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136 public:
3137 explicit HParameter(unsigned index) : index_(index) {
3138 set_representation(Representation::Tagged());
3139 }
3140
3141 unsigned index() const { return index_; }
3142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003143 virtual void PrintDataTo(StringStream* stream);
3144
3145 virtual Representation RequiredInputRepresentation(int index) const {
3146 return Representation::None();
3147 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003149 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003150
3151 private:
3152 unsigned index_;
3153};
3154
3155
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003156class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003158 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3159 : HUnaryCall(context, argument_count),
3160 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003161 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162 }
3163
3164 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003166 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167
3168 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3169 transcendental_type_ = transcendental_type;
3170 }
3171 TranscendentalCache::Type transcendental_type() {
3172 return transcendental_type_;
3173 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003174
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003175 virtual void PrintDataTo(StringStream* stream);
3176
3177 virtual Representation RequiredInputRepresentation(int index) const {
3178 return Representation::Tagged();
3179 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003181 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182
3183 private:
3184 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003185 TranscendentalCache::Type transcendental_type_;
3186};
3187
3188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003189class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190 public:
3191 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 virtual Representation RequiredInputRepresentation(int index) const {
3194 return Representation::None();
3195 }
3196
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003197 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198};
3199
3200
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003201class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003202 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003203 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003204 : cell_(cell), check_hole_value_(check_hole_value) {
3205 set_representation(Representation::Tagged());
3206 SetFlag(kUseGVN);
3207 SetFlag(kDependsOnGlobalVars);
3208 }
3209
3210 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3211 bool check_hole_value() const { return check_hole_value_; }
3212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003213 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003214
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003215 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003216 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003217 return reinterpret_cast<intptr_t>(*cell_);
3218 }
3219
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003220 virtual Representation RequiredInputRepresentation(int index) const {
3221 return Representation::None();
3222 }
3223
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003224 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003225
3226 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003227 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003228 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003229 return cell_.is_identical_to(b->cell());
3230 }
3231
3232 private:
3233 Handle<JSGlobalPropertyCell> cell_;
3234 bool check_hole_value_;
3235};
3236
3237
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003238class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003239 public:
3240 HLoadGlobalGeneric(HValue* context,
3241 HValue* global_object,
3242 Handle<Object> name,
3243 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003244 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003245 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003246 SetOperandAt(0, context);
3247 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003248 set_representation(Representation::Tagged());
3249 SetAllSideEffects();
3250 }
3251
3252 HValue* context() { return OperandAt(0); }
3253 HValue* global_object() { return OperandAt(1); }
3254 Handle<Object> name() const { return name_; }
3255 bool for_typeof() const { return for_typeof_; }
3256
3257 virtual void PrintDataTo(StringStream* stream);
3258
3259 virtual Representation RequiredInputRepresentation(int index) const {
3260 return Representation::Tagged();
3261 }
3262
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003263 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003264
3265 private:
3266 Handle<Object> name_;
3267 bool for_typeof_;
3268};
3269
3270
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003271class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003272 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003273 HStoreGlobalCell(HValue* value,
3274 Handle<JSGlobalPropertyCell> cell,
3275 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003276 : HUnaryOperation(value),
3277 cell_(cell),
3278 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003279 SetFlag(kChangesGlobalVars);
3280 }
3281
3282 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003283 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003284
3285 virtual Representation RequiredInputRepresentation(int index) const {
3286 return Representation::Tagged();
3287 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003288 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003289
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003290 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003291
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003292 private:
3293 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003294 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003295};
3296
3297
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003298class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3299 public:
3300 HStoreGlobalGeneric(HValue* context,
3301 HValue* global_object,
3302 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003303 HValue* value,
3304 bool strict_mode)
3305 : name_(name),
3306 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003307 SetOperandAt(0, context);
3308 SetOperandAt(1, global_object);
3309 SetOperandAt(2, value);
3310 set_representation(Representation::Tagged());
3311 SetAllSideEffects();
3312 }
3313
3314 HValue* context() { return OperandAt(0); }
3315 HValue* global_object() { return OperandAt(1); }
3316 Handle<Object> name() const { return name_; }
3317 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003318 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003319
3320 virtual void PrintDataTo(StringStream* stream);
3321
3322 virtual Representation RequiredInputRepresentation(int index) const {
3323 return Representation::Tagged();
3324 }
3325
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003326 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003327
3328 private:
3329 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003330 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003331};
3332
3333
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003334class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003335 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003336 HLoadContextSlot(HValue* context , int slot_index)
3337 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003338 set_representation(Representation::Tagged());
3339 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003340 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003341 }
3342
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003343 int slot_index() const { return slot_index_; }
3344
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003345 virtual Representation RequiredInputRepresentation(int index) const {
3346 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003347 }
3348
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003349 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003350
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003351 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003352
3353 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003354 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003355 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003356 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003357 }
3358
3359 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003360 int slot_index_;
3361};
3362
3363
3364static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3365 return !value->type().IsSmi() &&
3366 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3367}
3368
3369
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003370class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003371 public:
3372 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003373 : slot_index_(slot_index) {
3374 SetOperandAt(0, context);
3375 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003376 SetFlag(kChangesContextSlots);
3377 }
3378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003379 HValue* context() { return OperandAt(0); }
3380 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003381 int slot_index() const { return slot_index_; }
3382
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003383 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003384 return StoringValueNeedsWriteBarrier(value());
3385 }
3386
3387 virtual Representation RequiredInputRepresentation(int index) const {
3388 return Representation::Tagged();
3389 }
3390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003391 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003392
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003393 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003394
3395 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003396 int slot_index_;
3397};
3398
3399
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003400class HLoadNamedField: public HUnaryOperation {
3401 public:
3402 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3403 : HUnaryOperation(object),
3404 is_in_object_(is_in_object),
3405 offset_(offset) {
3406 set_representation(Representation::Tagged());
3407 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003408 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003409 if (is_in_object) {
3410 SetFlag(kDependsOnInobjectFields);
3411 } else {
3412 SetFlag(kDependsOnBackingStoreFields);
3413 }
3414 }
3415
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003416 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003417 bool is_in_object() const { return is_in_object_; }
3418 int offset() const { return offset_; }
3419
3420 virtual Representation RequiredInputRepresentation(int index) const {
3421 return Representation::Tagged();
3422 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003423 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003424
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003425 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003426
3427 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003428 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003429 HLoadNamedField* b = HLoadNamedField::cast(other);
3430 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3431 }
3432
3433 private:
3434 bool is_in_object_;
3435 int offset_;
3436};
3437
3438
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003439class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003440 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003441 HLoadNamedFieldPolymorphic(HValue* context,
3442 HValue* object,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003443 ZoneMapList* types,
3444 Handle<String> name);
3445
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003446 HValue* context() { return OperandAt(0); }
3447 HValue* object() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003448 ZoneMapList* types() { return &types_; }
3449 Handle<String> name() { return name_; }
3450 bool need_generic() { return need_generic_; }
3451
3452 virtual Representation RequiredInputRepresentation(int index) const {
3453 return Representation::Tagged();
3454 }
3455
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003456 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003457
3458 static const int kMaxLoadPolymorphism = 4;
3459
3460 protected:
3461 virtual bool DataEquals(HValue* value);
3462
3463 private:
3464 ZoneMapList types_;
3465 Handle<String> name_;
3466 bool need_generic_;
3467};
3468
3469
3470
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003471class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003472 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003473 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003474 : name_(name) {
3475 SetOperandAt(0, context);
3476 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003477 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003478 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003479 }
3480
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003481 HValue* context() { return OperandAt(0); }
3482 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003483 Handle<Object> name() const { return name_; }
3484
3485 virtual Representation RequiredInputRepresentation(int index) const {
3486 return Representation::Tagged();
3487 }
3488
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003489 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003490
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003491 private:
3492 Handle<Object> name_;
3493};
3494
3495
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003496class HLoadFunctionPrototype: public HUnaryOperation {
3497 public:
3498 explicit HLoadFunctionPrototype(HValue* function)
3499 : HUnaryOperation(function) {
3500 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003501 SetFlag(kUseGVN);
3502 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003503 }
3504
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003505 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003506
3507 virtual Representation RequiredInputRepresentation(int index) const {
3508 return Representation::Tagged();
3509 }
3510
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003511 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003512
3513 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003514 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003515};
3516
3517
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003518class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003520 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3521 SetOperandAt(0, obj);
3522 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003523 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003524 SetFlag(kDependsOnArrayElements);
3525 SetFlag(kUseGVN);
3526 }
3527
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003528 HValue* object() { return OperandAt(0); }
3529 HValue* key() { return OperandAt(1); }
3530
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003531 virtual Representation RequiredInputRepresentation(int index) const {
3532 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003533 return index == 0
3534 ? Representation::Tagged()
3535 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003536 }
3537
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003538 virtual void PrintDataTo(StringStream* stream);
3539
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003540 bool RequiresHoleCheck() const;
3541
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003542 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003543
3544 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003545 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003546};
3547
3548
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003549class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003550 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003551 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3552 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003553 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003554 : elements_kind_(elements_kind) {
3555 SetOperandAt(0, external_elements);
3556 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003557 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3558 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003559 set_representation(Representation::Double());
3560 } else {
3561 set_representation(Representation::Integer32());
3562 }
3563 SetFlag(kDependsOnSpecializedArrayElements);
3564 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003565 SetFlag(kDependsOnCalls);
3566 SetFlag(kUseGVN);
3567 }
3568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003569 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003570
3571 virtual Representation RequiredInputRepresentation(int index) const {
3572 // The key is supposed to be Integer32, but the base pointer
3573 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003574 return index == 0
3575 ? Representation::External()
3576 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003577 }
3578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 HValue* external_pointer() { return OperandAt(0); }
3580 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003581 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003582
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003583 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003584
3585 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003586 virtual bool DataEquals(HValue* other) {
3587 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3588 HLoadKeyedSpecializedArrayElement* cast_other =
3589 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003590 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003591 }
3592
3593 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003594 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003595};
3596
3597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003598class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003600 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003601 set_representation(Representation::Tagged());
3602 SetOperandAt(0, obj);
3603 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003604 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003605 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003606 }
3607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003608 HValue* object() { return OperandAt(0); }
3609 HValue* key() { return OperandAt(1); }
3610 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003612 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613
3614 virtual Representation RequiredInputRepresentation(int index) const {
3615 return Representation::Tagged();
3616 }
3617
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003618 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619};
3620
3621
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003622class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623 public:
3624 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003625 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003626 HValue* val,
3627 bool in_object,
3628 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003629 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 is_in_object_(in_object),
3631 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003632 SetOperandAt(0, obj);
3633 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634 if (is_in_object_) {
3635 SetFlag(kChangesInobjectFields);
3636 } else {
3637 SetFlag(kChangesBackingStoreFields);
3638 }
3639 }
3640
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003641 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003642
3643 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003644 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003645 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003646 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 HValue* object() { return OperandAt(0); }
3649 HValue* value() { return OperandAt(1); }
3650
3651 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003652 bool is_in_object() const { return is_in_object_; }
3653 int offset() const { return offset_; }
3654 Handle<Map> transition() const { return transition_; }
3655 void set_transition(Handle<Map> map) { transition_ = map; }
3656
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003657 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003658 return StoringValueNeedsWriteBarrier(value());
3659 }
3660
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003662 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003663 bool is_in_object_;
3664 int offset_;
3665 Handle<Map> transition_;
3666};
3667
3668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003669class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003671 HStoreNamedGeneric(HValue* context,
3672 HValue* object,
3673 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003674 HValue* value,
3675 bool strict_mode)
3676 : name_(name),
3677 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003678 SetOperandAt(0, object);
3679 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003680 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003681 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003682 }
3683
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003684 HValue* object() { return OperandAt(0); }
3685 HValue* value() { return OperandAt(1); }
3686 HValue* context() { return OperandAt(2); }
3687 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003688 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003689
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003690 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691
3692 virtual Representation RequiredInputRepresentation(int index) const {
3693 return Representation::Tagged();
3694 }
3695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003696 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003697
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003698 private:
3699 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003700 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701};
3702
3703
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003704class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003705 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003706 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3707 SetOperandAt(0, obj);
3708 SetOperandAt(1, key);
3709 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003710 SetFlag(kChangesArrayElements);
3711 }
3712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713 virtual Representation RequiredInputRepresentation(int index) const {
3714 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003715 return index == 1
3716 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003717 : Representation::Tagged();
3718 }
3719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003720 HValue* object() { return OperandAt(0); }
3721 HValue* key() { return OperandAt(1); }
3722 HValue* value() { return OperandAt(2); }
3723
3724 bool NeedsWriteBarrier() {
3725 return StoringValueNeedsWriteBarrier(value());
3726 }
3727
3728 virtual void PrintDataTo(StringStream* stream);
3729
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003730 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731};
3732
3733
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003734class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003735 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003736 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3737 HValue* key,
3738 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003739 JSObject::ElementsKind elements_kind)
3740 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003741 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003742 SetOperandAt(0, external_elements);
3743 SetOperandAt(1, key);
3744 SetOperandAt(2, val);
3745 }
3746
3747 virtual void PrintDataTo(StringStream* stream);
3748
3749 virtual Representation RequiredInputRepresentation(int index) const {
3750 if (index == 0) {
3751 return Representation::External();
3752 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003753 bool float_or_double_elements =
3754 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3755 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3756 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003757 return Representation::Double();
3758 } else {
3759 return Representation::Integer32();
3760 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003761 }
3762 }
3763
3764 HValue* external_pointer() { return OperandAt(0); }
3765 HValue* key() { return OperandAt(1); }
3766 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003767 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003768
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003769 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3770
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003771 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003772 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003773};
3774
3775
3776class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003777 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003778 HStoreKeyedGeneric(HValue* context,
3779 HValue* object,
3780 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003781 HValue* value,
3782 bool strict_mode)
3783 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003784 SetOperandAt(0, object);
3785 SetOperandAt(1, key);
3786 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003787 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003788 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003789 }
3790
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003791 HValue* object() { return OperandAt(0); }
3792 HValue* key() { return OperandAt(1); }
3793 HValue* value() { return OperandAt(2); }
3794 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003795 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003796
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003797 virtual Representation RequiredInputRepresentation(int index) const {
3798 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003799 }
3800
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003801 virtual void PrintDataTo(StringStream* stream);
3802
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003803 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003804
3805 private:
3806 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003807};
3808
3809
danno@chromium.org160a7b02011-04-18 15:51:38 +00003810class HStringAdd: public HBinaryOperation {
3811 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003812 HStringAdd(HValue* context, HValue* left, HValue* right)
3813 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003814 set_representation(Representation::Tagged());
3815 SetFlag(kUseGVN);
3816 SetFlag(kDependsOnMaps);
3817 }
3818
3819 virtual Representation RequiredInputRepresentation(int index) const {
3820 return Representation::Tagged();
3821 }
3822
3823 virtual HType CalculateInferredType() {
3824 return HType::String();
3825 }
3826
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003827 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003828
3829 protected:
3830 virtual bool DataEquals(HValue* other) { return true; }
3831};
3832
3833
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003834class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003835 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003836 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3837 SetOperandAt(0, context);
3838 SetOperandAt(1, string);
3839 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003840 set_representation(Representation::Integer32());
3841 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003842 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003843 }
3844
3845 virtual Representation RequiredInputRepresentation(int index) const {
3846 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003847 return index == 2
3848 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003849 : Representation::Tagged();
3850 }
3851
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003852 HValue* context() { return OperandAt(0); }
3853 HValue* string() { return OperandAt(1); }
3854 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003855
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003856 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003857
3858 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003859 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003860
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003861 virtual Range* InferRange() {
3862 return new Range(0, String::kMaxUC16CharCode);
3863 }
3864};
3865
3866
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003867class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003868 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003869 HStringCharFromCode(HValue* context, HValue* char_code) {
3870 SetOperandAt(0, context);
3871 SetOperandAt(1, char_code);
3872 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003873 SetFlag(kUseGVN);
3874 }
3875
3876 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003877 return index == 0
3878 ? Representation::Tagged()
3879 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003880 }
3881
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003882 HValue* context() { return OperandAt(0); }
3883 HValue* value() { return OperandAt(1); }
3884
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003885 virtual bool DataEquals(HValue* other) { return true; }
3886
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003887 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003888};
3889
3890
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003891class HStringLength: public HUnaryOperation {
3892 public:
3893 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3894 set_representation(Representation::Tagged());
3895 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003896 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003897 }
3898
3899 virtual Representation RequiredInputRepresentation(int index) const {
3900 return Representation::Tagged();
3901 }
3902
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003903 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003904 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3905 return HType::Smi();
3906 }
3907
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003908 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003909
3910 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003911 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003912
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003913 virtual Range* InferRange() {
3914 return new Range(0, String::kMaxLength);
3915 }
3916};
3917
3918
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003919template <int V>
3920class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003921 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003922 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003923 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003924 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003925 }
3926
3927 int literal_index() const { return literal_index_; }
3928 int depth() const { return depth_; }
3929
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003930 private:
3931 int literal_index_;
3932 int depth_;
3933};
3934
3935
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003936class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003937 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003938 HArrayLiteral(HValue* context,
3939 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003940 int length,
3941 int literal_index,
3942 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003943 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003944 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003945 constant_elements_(constant_elements) {
3946 SetOperandAt(0, context);
3947 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003948
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003949 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003950 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3951 int length() const { return length_; }
3952
3953 bool IsCopyOnWrite() const;
3954
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003955 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003956 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003957 }
3958
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003959 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003960
3961 private:
3962 int length_;
3963 Handle<FixedArray> constant_elements_;
3964};
3965
3966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003967class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003968 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003969 HObjectLiteral(HValue* context,
3970 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003971 bool fast_elements,
3972 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003973 int depth,
3974 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003975 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003976 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003977 fast_elements_(fast_elements),
3978 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003979 SetOperandAt(0, context);
3980 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003981
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003982 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003983 Handle<FixedArray> constant_properties() const {
3984 return constant_properties_;
3985 }
3986 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003987 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003989 virtual Representation RequiredInputRepresentation(int index) const {
3990 return Representation::Tagged();
3991 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003992
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003993 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003994
3995 private:
3996 Handle<FixedArray> constant_properties_;
3997 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003998 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003999};
4000
4001
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004002class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004003 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004004 HRegExpLiteral(HValue* context,
4005 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004006 Handle<String> flags,
4007 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004008 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004009 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004010 flags_(flags) {
4011 SetOperandAt(0, context);
4012 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004013
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004014 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004015 Handle<String> pattern() { return pattern_; }
4016 Handle<String> flags() { return flags_; }
4017
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004018 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004019 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004020 }
4021
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004022 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004023
4024 private:
4025 Handle<String> pattern_;
4026 Handle<String> flags_;
4027};
4028
4029
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004030class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004031 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004032 HFunctionLiteral(HValue* context,
4033 Handle<SharedFunctionInfo> shared,
4034 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004035 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004036 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004037 set_representation(Representation::Tagged());
4038 }
4039
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004040 HValue* context() { return OperandAt(0); }
4041
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004042 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004043 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004044 }
4045
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004046 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004047
4048 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4049 bool pretenure() const { return pretenure_; }
4050
4051 private:
4052 Handle<SharedFunctionInfo> shared_info_;
4053 bool pretenure_;
4054};
4055
4056
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004057class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004058 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004059 explicit HTypeof(HValue* context, HValue* value) {
4060 SetOperandAt(0, context);
4061 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004062 set_representation(Representation::Tagged());
4063 }
4064
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004065 HValue* context() { return OperandAt(0); }
4066 HValue* value() { return OperandAt(1); }
4067
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004068 virtual Representation RequiredInputRepresentation(int index) const {
4069 return Representation::Tagged();
4070 }
4071
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004072 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004073};
4074
4075
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004076class HToFastProperties: public HUnaryOperation {
4077 public:
4078 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4079 // This instruction is not marked as having side effects, but
4080 // changes the map of the input operand. Use it only when creating
4081 // object literals.
4082 ASSERT(value->IsObjectLiteral());
4083 set_representation(Representation::Tagged());
4084 }
4085
4086 virtual Representation RequiredInputRepresentation(int index) const {
4087 return Representation::Tagged();
4088 }
4089
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004090 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004091};
4092
4093
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004094class HValueOf: public HUnaryOperation {
4095 public:
4096 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4097 set_representation(Representation::Tagged());
4098 }
4099
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004100 virtual Representation RequiredInputRepresentation(int index) const {
4101 return Representation::Tagged();
4102 }
4103
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004104 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004105};
4106
4107
4108class HDeleteProperty: public HBinaryOperation {
4109 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004110 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4111 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004112 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004113 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004114 }
4115
4116 virtual Representation RequiredInputRepresentation(int index) const {
4117 return Representation::Tagged();
4118 }
4119
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004120 virtual HType CalculateInferredType();
4121
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004122 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004124 HValue* object() { return left(); }
4125 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004126};
4127
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004128
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004129class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004130 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004131 HIn(HValue* context, HValue* key, HValue* object) {
4132 SetOperandAt(0, context);
4133 SetOperandAt(1, key);
4134 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004135 set_representation(Representation::Tagged());
4136 SetAllSideEffects();
4137 }
4138
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004139 HValue* context() { return OperandAt(0); }
4140 HValue* key() { return OperandAt(1); }
4141 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004142
4143 virtual Representation RequiredInputRepresentation(int index) const {
4144 return Representation::Tagged();
4145 }
4146
4147 virtual HType CalculateInferredType() {
4148 return HType::Boolean();
4149 }
4150
4151 virtual void PrintDataTo(StringStream* stream);
4152
4153 DECLARE_CONCRETE_INSTRUCTION(In)
4154};
4155
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004156#undef DECLARE_INSTRUCTION
4157#undef DECLARE_CONCRETE_INSTRUCTION
4158
4159} } // namespace v8::internal
4160
4161#endif // V8_HYDROGEN_INSTRUCTIONS_H_