blob: 93a7073b6ad14a1b3f16c4d481eeb5f4328a1ad4 [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
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000591 // back. There are three operations that need to propagate back to more than
592 // one input. They are phi and binary div and mul. They always return NULL
593 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000594 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)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001126 : HUnaryOperation(value) {
1127 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001128 SetFlag(kUseGVN);
1129 }
1130
1131 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001132 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001133 }
1134
1135 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1136
1137 protected:
1138 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001139};
1140
1141
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001142class HToInt32: public HUnaryOperation {
1143 public:
1144 explicit HToInt32(HValue* value)
1145 : HUnaryOperation(value) {
1146 set_representation(Representation::Integer32());
1147 SetFlag(kUseGVN);
1148 }
1149
1150 virtual Representation RequiredInputRepresentation(int index) const {
1151 return Representation::None();
1152 }
1153
1154 virtual bool CanTruncateToInt32() const {
1155 return true;
1156 }
1157
1158 virtual HValue* Canonicalize() {
1159 if (value()->representation().IsInteger32()) {
1160 return value();
1161 } else {
1162 return this;
1163 }
1164 }
1165
1166 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1167
1168 protected:
1169 virtual bool DataEquals(HValue* other) { return true; }
1170};
1171
1172
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173class HSimulate: public HInstruction {
1174 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001175 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001176 : ast_id_(ast_id),
1177 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001178 values_(2),
1179 assigned_indexes_(2) {}
1180 virtual ~HSimulate() {}
1181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001182 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001183
1184 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1185 int ast_id() const { return ast_id_; }
1186 void set_ast_id(int id) {
1187 ASSERT(!HasAstId());
1188 ast_id_ = id;
1189 }
1190
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001191 int pop_count() const { return pop_count_; }
1192 const ZoneList<HValue*>* values() const { return &values_; }
1193 int GetAssignedIndexAt(int index) const {
1194 ASSERT(HasAssignedIndexAt(index));
1195 return assigned_indexes_[index];
1196 }
1197 bool HasAssignedIndexAt(int index) const {
1198 return assigned_indexes_[index] != kNoIndex;
1199 }
1200 void AddAssignedValue(int index, HValue* value) {
1201 AddValue(index, value);
1202 }
1203 void AddPushedValue(HValue* value) {
1204 AddValue(kNoIndex, value);
1205 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001206 virtual int OperandCount() { return values_.length(); }
1207 virtual HValue* OperandAt(int index) { return values_[index]; }
1208
1209 virtual Representation RequiredInputRepresentation(int index) const {
1210 return Representation::None();
1211 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001212
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001213 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001214
1215#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001216 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001217#endif
1218
1219 protected:
1220 virtual void InternalSetOperandAt(int index, HValue* value) {
1221 values_[index] = value;
1222 }
1223
1224 private:
1225 static const int kNoIndex = -1;
1226 void AddValue(int index, HValue* value) {
1227 assigned_indexes_.Add(index);
1228 // Resize the list of pushed values.
1229 values_.Add(NULL);
1230 // Set the operand through the base method in HValue to make sure that the
1231 // use lists are correctly updated.
1232 SetOperandAt(values_.length() - 1, value);
1233 }
1234 int ast_id_;
1235 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001236 ZoneList<HValue*> values_;
1237 ZoneList<int> assigned_indexes_;
1238};
1239
1240
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001241class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001242 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001243 enum Type {
1244 kFunctionEntry,
1245 kBackwardsBranch
1246 };
1247
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001248 HStackCheck(HValue* context, Type type) : type_(type) {
1249 SetOperandAt(0, context);
1250 }
1251
1252 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001254 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001255 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001256 }
1257
ager@chromium.org04921a82011-06-27 13:21:41 +00001258 void Eliminate() {
1259 // The stack check eliminator might try to eliminate the same stack
1260 // check instruction multiple times.
1261 if (IsLinked()) {
1262 DeleteFromGraph();
1263 }
1264 }
1265
1266 bool is_function_entry() { return type_ == kFunctionEntry; }
1267 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1268
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001269 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001270
1271 private:
1272 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001273};
1274
1275
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001276class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001277 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001278 HEnterInlined(Handle<JSFunction> closure,
1279 FunctionLiteral* function,
1280 CallKind call_kind)
1281 : closure_(closure),
1282 function_(function),
1283 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001284 }
1285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001286 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287
1288 Handle<JSFunction> closure() const { return closure_; }
1289 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001290 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001292 virtual Representation RequiredInputRepresentation(int index) const {
1293 return Representation::None();
1294 }
1295
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001296 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001297
1298 private:
1299 Handle<JSFunction> closure_;
1300 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001301 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302};
1303
1304
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001305class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306 public:
1307 HLeaveInlined() {}
1308
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001309 virtual Representation RequiredInputRepresentation(int index) const {
1310 return Representation::None();
1311 }
1312
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001313 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314};
1315
1316
1317class HPushArgument: public HUnaryOperation {
1318 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001319 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1320 set_representation(Representation::Tagged());
1321 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001322
1323 virtual Representation RequiredInputRepresentation(int index) const {
1324 return Representation::Tagged();
1325 }
1326
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001327 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001329 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001330};
1331
1332
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001333class HThisFunction: public HTemplateInstruction<0> {
1334 public:
1335 HThisFunction() {
1336 set_representation(Representation::Tagged());
1337 SetFlag(kUseGVN);
1338 }
1339
1340 virtual Representation RequiredInputRepresentation(int index) const {
1341 return Representation::None();
1342 }
1343
1344 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1345
1346 protected:
1347 virtual bool DataEquals(HValue* other) { return true; }
1348};
1349
1350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001352 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001353 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001354 set_representation(Representation::Tagged());
1355 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001356 }
1357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001358 virtual Representation RequiredInputRepresentation(int index) const {
1359 return Representation::None();
1360 }
1361
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001362 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001363
1364 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001365 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001366};
1367
1368
1369class HOuterContext: public HUnaryOperation {
1370 public:
1371 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1372 set_representation(Representation::Tagged());
1373 SetFlag(kUseGVN);
1374 }
1375
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001376 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001377
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001378 virtual Representation RequiredInputRepresentation(int index) const {
1379 return Representation::Tagged();
1380 }
1381
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001382 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001383 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001384};
1385
1386
1387class HGlobalObject: public HUnaryOperation {
1388 public:
1389 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1390 set_representation(Representation::Tagged());
1391 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001392 }
1393
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001394 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001396 virtual Representation RequiredInputRepresentation(int index) const {
1397 return Representation::Tagged();
1398 }
1399
ager@chromium.org378b34e2011-01-28 08:04:38 +00001400 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001401 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001402};
1403
1404
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001405class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001407 explicit HGlobalReceiver(HValue* global_object)
1408 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409 set_representation(Representation::Tagged());
1410 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411 }
1412
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001413 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001414
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001415 virtual Representation RequiredInputRepresentation(int index) const {
1416 return Representation::Tagged();
1417 }
1418
ager@chromium.org378b34e2011-01-28 08:04:38 +00001419 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001420 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421};
1422
1423
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001424template <int V>
1425class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001426 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001427 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001428 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1429 this->set_representation(Representation::Tagged());
1430 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001431 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001433 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001434
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001435 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001436
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001437 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001439 private:
1440 int argument_count_;
1441};
1442
1443
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001444class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001445 public:
1446 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001447 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449 }
1450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001451 virtual Representation RequiredInputRepresentation(int index) const {
1452 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001453 }
1454
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001455 virtual void PrintDataTo(StringStream* stream);
1456
1457 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001458};
1459
1460
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001461class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001462 public:
1463 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001464 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465 SetOperandAt(0, first);
1466 SetOperandAt(1, second);
1467 }
1468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001469 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001470
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001471 virtual Representation RequiredInputRepresentation(int index) const {
1472 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001473 }
1474
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001475 HValue* first() { return OperandAt(0); }
1476 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477};
1478
1479
danno@chromium.org160a7b02011-04-18 15:51:38 +00001480class HInvokeFunction: public HBinaryCall {
1481 public:
1482 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1483 : HBinaryCall(context, function, argument_count) {
1484 }
1485
1486 virtual Representation RequiredInputRepresentation(int index) const {
1487 return Representation::Tagged();
1488 }
1489
1490 HValue* context() { return first(); }
1491 HValue* function() { return second(); }
1492
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001493 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001494};
1495
1496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001497class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498 public:
1499 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001500 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001501
1502 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001503
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001504 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001505 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001506 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507 }
1508
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001509 virtual void PrintDataTo(StringStream* stream);
1510
1511 virtual Representation RequiredInputRepresentation(int index) const {
1512 return Representation::None();
1513 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001515 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516
1517 private:
1518 Handle<JSFunction> function_;
1519};
1520
1521
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001522class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001523 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001524 HCallKeyed(HValue* context, HValue* key, int argument_count)
1525 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526 }
1527
1528 virtual Representation RequiredInputRepresentation(int index) const {
1529 return Representation::Tagged();
1530 }
1531
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001532 HValue* context() { return first(); }
1533 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001535 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536};
1537
1538
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001539class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001540 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001541 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1542 : HUnaryCall(context, argument_count), name_(name) {
1543 }
1544
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001545 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001547 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001548 Handle<String> name() const { return name_; }
1549
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001550 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001552 virtual Representation RequiredInputRepresentation(int index) const {
1553 return Representation::Tagged();
1554 }
1555
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001556 private:
1557 Handle<String> name_;
1558};
1559
1560
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001561class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001562 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001563 HCallFunction(HValue* context, int argument_count)
1564 : HUnaryCall(context, argument_count) {
1565 }
1566
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001567 HValue* context() { return value(); }
1568
1569 virtual Representation RequiredInputRepresentation(int index) const {
1570 return Representation::Tagged();
1571 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001573 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574};
1575
1576
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001577class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001579 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1580 : HUnaryCall(context, argument_count), name_(name) {
1581 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001582
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001583 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001584
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001585 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 Handle<String> name() const { return name_; }
1587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001588 virtual Representation RequiredInputRepresentation(int index) const {
1589 return Representation::Tagged();
1590 }
1591
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001592 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593
1594 private:
1595 Handle<String> name_;
1596};
1597
1598
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001599class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001600 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001601 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001604 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606 Handle<JSFunction> target() const { return target_; }
1607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001608 virtual Representation RequiredInputRepresentation(int index) const {
1609 return Representation::None();
1610 }
1611
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001612 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001613
1614 private:
1615 Handle<JSFunction> target_;
1616};
1617
1618
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001619class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001620 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001621 HCallNew(HValue* context, HValue* constructor, int argument_count)
1622 : HBinaryCall(context, constructor, argument_count) {
1623 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624
1625 virtual Representation RequiredInputRepresentation(int index) const {
1626 return Representation::Tagged();
1627 }
1628
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001629 HValue* context() { return first(); }
1630 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001631
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001632 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633};
1634
1635
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001636class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001637 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001638 HCallRuntime(HValue* context,
1639 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001640 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001641 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001642 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1643 SetOperandAt(0, context);
1644 }
1645
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001646 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001647
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001648 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001649 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001650 Handle<String> name() const { return name_; }
1651
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001652 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001653 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001654 }
1655
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001656 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001657
1658 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001659 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660 Handle<String> name_;
1661};
1662
1663
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001664class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001665 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001666 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667 // The length of an array is stored as a tagged value in the array
1668 // object. It is guaranteed to be 32 bit integer, but it can be
1669 // represented as either a smi or heap number.
1670 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001672 SetFlag(kDependsOnArrayLengths);
1673 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674 }
1675
1676 virtual Representation RequiredInputRepresentation(int index) const {
1677 return Representation::Tagged();
1678 }
1679
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001680 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001681
1682 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001683 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001684};
1685
1686
1687class HFixedArrayLength: public HUnaryOperation {
1688 public:
1689 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1690 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001691 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001692 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001693 }
1694
1695 virtual Representation RequiredInputRepresentation(int index) const {
1696 return Representation::Tagged();
1697 }
1698
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001699 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001700
1701 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001702 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001703};
1704
1705
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001706class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001707 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001708 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001709 set_representation(Representation::Integer32());
1710 // The result of this instruction is idempotent as long as its inputs don't
1711 // change. The length of a pixel array cannot change once set, so it's not
1712 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1713 SetFlag(kUseGVN);
1714 }
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(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001721
1722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001723 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001724};
1725
1726
whesse@chromium.org7b260152011-06-20 15:33:18 +00001727class HElementsKind: public HUnaryOperation {
1728 public:
1729 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1730 set_representation(Representation::Integer32());
1731 SetFlag(kUseGVN);
1732 SetFlag(kDependsOnMaps);
1733 }
1734
1735 virtual Representation RequiredInputRepresentation(int index) const {
1736 return Representation::Tagged();
1737 }
1738
1739 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1740
1741 protected:
1742 virtual bool DataEquals(HValue* other) { return true; }
1743};
1744
1745
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746class HBitNot: public HUnaryOperation {
1747 public:
1748 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1749 set_representation(Representation::Integer32());
1750 SetFlag(kUseGVN);
1751 SetFlag(kTruncatingToInt32);
1752 }
1753
1754 virtual Representation RequiredInputRepresentation(int index) const {
1755 return Representation::Integer32();
1756 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001757 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001759 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001760
1761 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001762 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763};
1764
1765
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001766class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001768 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1769 : op_(op) {
1770 SetOperandAt(0, context);
1771 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001772 switch (op) {
1773 case kMathFloor:
1774 case kMathRound:
1775 case kMathCeil:
1776 set_representation(Representation::Integer32());
1777 break;
1778 case kMathAbs:
1779 set_representation(Representation::Tagged());
1780 SetFlag(kFlexibleRepresentation);
1781 break;
1782 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001783 case kMathPowHalf:
1784 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001785 case kMathSin:
1786 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001788 break;
1789 default:
1790 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001791 }
1792 SetFlag(kUseGVN);
1793 }
1794
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001795 HValue* context() { return OperandAt(0); }
1796 HValue* value() { return OperandAt(1); }
1797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001798 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001800 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801
1802 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1803
1804 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001805 if (index == 0) {
1806 return Representation::Tagged();
1807 } else {
1808 switch (op_) {
1809 case kMathFloor:
1810 case kMathRound:
1811 case kMathCeil:
1812 case kMathSqrt:
1813 case kMathPowHalf:
1814 case kMathLog:
1815 case kMathSin:
1816 case kMathCos:
1817 return Representation::Double();
1818 case kMathAbs:
1819 return representation();
1820 default:
1821 UNREACHABLE();
1822 return Representation::None();
1823 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001824 }
1825 }
1826
1827 virtual HValue* Canonicalize() {
1828 // If the input is integer32 then we replace the floor instruction
1829 // with its inputs. This happens before the representation changes are
1830 // introduced.
1831 if (op() == kMathFloor) {
1832 if (value()->representation().IsInteger32()) return value();
1833 }
1834 return this;
1835 }
1836
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001837 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001838 const char* OpName() const;
1839
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001840 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001841
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001842 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001843 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001844 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1845 return op_ == b->op();
1846 }
1847
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001849 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850};
1851
1852
1853class HLoadElements: public HUnaryOperation {
1854 public:
1855 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1856 set_representation(Representation::Tagged());
1857 SetFlag(kUseGVN);
1858 SetFlag(kDependsOnMaps);
1859 }
1860
1861 virtual Representation RequiredInputRepresentation(int index) const {
1862 return Representation::Tagged();
1863 }
1864
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001865 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001866
1867 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001868 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869};
1870
1871
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001872class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001873 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001874 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001875 : HUnaryOperation(value) {
1876 set_representation(Representation::External());
1877 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001878 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001879 // change once set, so it's no necessary to introduce any additional
1880 // dependencies on top of the inputs.
1881 SetFlag(kUseGVN);
1882 }
1883
1884 virtual Representation RequiredInputRepresentation(int index) const {
1885 return Representation::Tagged();
1886 }
1887
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001888 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001889
1890 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001891 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001892};
1893
1894
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001895class HCheckMap: public HUnaryOperation {
1896 public:
1897 HCheckMap(HValue* value, Handle<Map> map)
1898 : HUnaryOperation(value), map_(map) {
1899 set_representation(Representation::Tagged());
1900 SetFlag(kUseGVN);
1901 SetFlag(kDependsOnMaps);
1902 }
1903
1904 virtual Representation RequiredInputRepresentation(int index) const {
1905 return Representation::Tagged();
1906 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001907 virtual void PrintDataTo(StringStream* stream);
1908 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001909
1910#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001911 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001912#endif
1913
1914 Handle<Map> map() const { return map_; }
1915
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001916 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001917
1918 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001919 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001920 HCheckMap* b = HCheckMap::cast(other);
1921 return map_.is_identical_to(b->map());
1922 }
1923
1924 private:
1925 Handle<Map> map_;
1926};
1927
1928
1929class HCheckFunction: public HUnaryOperation {
1930 public:
1931 HCheckFunction(HValue* value, Handle<JSFunction> function)
1932 : HUnaryOperation(value), target_(function) {
1933 set_representation(Representation::Tagged());
1934 SetFlag(kUseGVN);
1935 }
1936
1937 virtual Representation RequiredInputRepresentation(int index) const {
1938 return Representation::Tagged();
1939 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001940 virtual void PrintDataTo(StringStream* stream);
1941 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001942
1943#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001944 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001945#endif
1946
1947 Handle<JSFunction> target() const { return target_; }
1948
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001949 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001950
1951 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001952 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001953 HCheckFunction* b = HCheckFunction::cast(other);
1954 return target_.is_identical_to(b->target());
1955 }
1956
1957 private:
1958 Handle<JSFunction> target_;
1959};
1960
1961
1962class HCheckInstanceType: public HUnaryOperation {
1963 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001964 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1965 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001966 }
1967 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1968 return new HCheckInstanceType(value, IS_JS_ARRAY);
1969 }
1970 static HCheckInstanceType* NewIsString(HValue* value) {
1971 return new HCheckInstanceType(value, IS_STRING);
1972 }
1973 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1974 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001975 }
1976
1977 virtual Representation RequiredInputRepresentation(int index) const {
1978 return Representation::Tagged();
1979 }
1980
1981#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001982 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001983#endif
1984
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00001985 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00001986
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001987 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1988 void GetCheckInterval(InstanceType* first, InstanceType* last);
1989 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001990
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001991 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001992
1993 protected:
1994 // TODO(ager): It could be nice to allow the ommision of instance
1995 // type checks if we have already performed an instance type check
1996 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001997 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001999 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000 }
2001
2002 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002003 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002004 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002005 IS_JS_ARRAY,
2006 IS_STRING,
2007 IS_SYMBOL,
2008 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2009 };
2010
2011 HCheckInstanceType(HValue* value, Check check)
2012 : HUnaryOperation(value), check_(check) {
2013 set_representation(Representation::Tagged());
2014 SetFlag(kUseGVN);
2015 }
2016
2017 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002018};
2019
2020
2021class HCheckNonSmi: public HUnaryOperation {
2022 public:
2023 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2024 set_representation(Representation::Tagged());
2025 SetFlag(kUseGVN);
2026 }
2027
2028 virtual Representation RequiredInputRepresentation(int index) const {
2029 return Representation::Tagged();
2030 }
2031
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002032 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033
2034#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002035 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002036#endif
2037
danno@chromium.org160a7b02011-04-18 15:51:38 +00002038 virtual HValue* Canonicalize() {
2039 HType value_type = value()->type();
2040 if (!value_type.IsUninitialized() &&
2041 (value_type.IsHeapNumber() ||
2042 value_type.IsString() ||
2043 value_type.IsBoolean() ||
2044 value_type.IsNonPrimitive())) {
2045 return NULL;
2046 }
2047 return this;
2048 }
2049
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002050 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002051
2052 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002053 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054};
2055
2056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002057class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002058 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002059 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2060 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002061 SetFlag(kUseGVN);
2062 SetFlag(kDependsOnMaps);
2063 }
2064
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002065#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002066 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002067#endif
2068
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002069 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002070 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002072 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002073
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002074 virtual Representation RequiredInputRepresentation(int index) const {
2075 return Representation::None();
2076 }
2077
2078 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002079 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002080 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2081 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2082 return hash;
2083 }
2084
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002085 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002086 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002087 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002088 return prototype_.is_identical_to(b->prototype()) &&
2089 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090 }
2091
2092 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002093 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002094 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095};
2096
2097
2098class HCheckSmi: public HUnaryOperation {
2099 public:
2100 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2101 set_representation(Representation::Tagged());
2102 SetFlag(kUseGVN);
2103 }
2104
2105 virtual Representation RequiredInputRepresentation(int index) const {
2106 return Representation::Tagged();
2107 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002108 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109
2110#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002111 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002112#endif
2113
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002114 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002115
2116 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002117 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002118};
2119
2120
2121class HPhi: public HValue {
2122 public:
2123 explicit HPhi(int merged_index)
2124 : inputs_(2),
2125 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002126 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002127 is_live_(false),
2128 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002129 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2130 non_phi_uses_[i] = 0;
2131 indirect_uses_[i] = 0;
2132 }
2133 ASSERT(merged_index >= 0);
2134 set_representation(Representation::Tagged());
2135 SetFlag(kFlexibleRepresentation);
2136 }
2137
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002138 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002139 bool double_occurred = false;
2140 bool int32_occurred = false;
2141 for (int i = 0; i < OperandCount(); ++i) {
2142 HValue* value = OperandAt(i);
2143 if (value->representation().IsDouble()) double_occurred = true;
2144 if (value->representation().IsInteger32()) int32_occurred = true;
2145 if (value->representation().IsTagged()) return Representation::Tagged();
2146 }
2147
2148 if (double_occurred) return Representation::Double();
2149 if (int32_occurred) return Representation::Integer32();
2150 return Representation::None();
2151 }
2152
2153 virtual Range* InferRange();
2154 virtual Representation RequiredInputRepresentation(int index) const {
2155 return representation();
2156 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002157 virtual HType CalculateInferredType();
2158 virtual int OperandCount() { return inputs_.length(); }
2159 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2160 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002162 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002163
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002164 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165
2166 int merged_index() const { return merged_index_; }
2167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002168 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002169
2170#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002171 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002172#endif
2173
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174 void InitRealUses(int id);
2175 void AddNonPhiUsesFrom(HPhi* other);
2176 void AddIndirectUsesTo(int* use_count);
2177
2178 int tagged_non_phi_uses() const {
2179 return non_phi_uses_[Representation::kTagged];
2180 }
2181 int int32_non_phi_uses() const {
2182 return non_phi_uses_[Representation::kInteger32];
2183 }
2184 int double_non_phi_uses() const {
2185 return non_phi_uses_[Representation::kDouble];
2186 }
2187 int tagged_indirect_uses() const {
2188 return indirect_uses_[Representation::kTagged];
2189 }
2190 int int32_indirect_uses() const {
2191 return indirect_uses_[Representation::kInteger32];
2192 }
2193 int double_indirect_uses() const {
2194 return indirect_uses_[Representation::kDouble];
2195 }
2196 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002197 bool is_live() { return is_live_; }
2198 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002199
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002200 static HPhi* cast(HValue* value) {
2201 ASSERT(value->IsPhi());
2202 return reinterpret_cast<HPhi*>(value);
2203 }
2204 virtual Opcode opcode() const { return HValue::kPhi; }
2205
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002206 virtual bool IsConvertibleToInteger() const {
2207 return is_convertible_to_integer_;
2208 }
2209
2210 void set_is_convertible_to_integer(bool b) {
2211 is_convertible_to_integer_ = b;
2212 }
2213
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002214 protected:
2215 virtual void DeleteFromGraph();
2216 virtual void InternalSetOperandAt(int index, HValue* value) {
2217 inputs_[index] = value;
2218 }
2219
2220 private:
2221 ZoneList<HValue*> inputs_;
2222 int merged_index_;
2223
2224 int non_phi_uses_[Representation::kNumRepresentations];
2225 int indirect_uses_[Representation::kNumRepresentations];
2226 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002227 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002228 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002229};
2230
2231
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002232class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002233 public:
2234 HArgumentsObject() {
2235 set_representation(Representation::Tagged());
2236 SetFlag(kIsArguments);
2237 }
2238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002239 virtual Representation RequiredInputRepresentation(int index) const {
2240 return Representation::None();
2241 }
2242
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002243 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244};
2245
2246
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002247class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248 public:
2249 HConstant(Handle<Object> handle, Representation r);
2250
2251 Handle<Object> handle() const { return handle_; }
2252
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002253 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002254
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002255 virtual Representation RequiredInputRepresentation(int index) const {
2256 return Representation::None();
2257 }
2258
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002259 virtual bool IsConvertibleToInteger() const {
2260 if (handle_->IsSmi()) return true;
2261 if (handle_->IsHeapNumber() &&
2262 (HeapNumber::cast(*handle_)->value() ==
2263 static_cast<double>(NumberToInt32(*handle_)))) return true;
2264 return false;
2265 }
2266
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002267 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002268 virtual void PrintDataTo(StringStream* stream);
2269 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002270 bool IsInteger() const { return handle_->IsSmi(); }
2271 HConstant* CopyToRepresentation(Representation r) const;
2272 HConstant* CopyToTruncatedInt32() const;
2273 bool HasInteger32Value() const { return has_int32_value_; }
2274 int32_t Integer32Value() const {
2275 ASSERT(HasInteger32Value());
2276 return int32_value_;
2277 }
2278 bool HasDoubleValue() const { return has_double_value_; }
2279 double DoubleValue() const {
2280 ASSERT(HasDoubleValue());
2281 return double_value_;
2282 }
2283 bool HasStringValue() const { return handle_->IsString(); }
2284
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002285 bool ToBoolean() const;
2286
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002287 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002288 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002289 return reinterpret_cast<intptr_t>(*handle());
2290 }
2291
2292#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002293 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002294#endif
2295
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002296 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002297
2298 protected:
2299 virtual Range* InferRange();
2300
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002301 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002302 HConstant* other_constant = HConstant::cast(other);
2303 return handle().is_identical_to(other_constant->handle());
2304 }
2305
2306 private:
2307 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002308
2309 // The following two values represent the int32 and the double value of the
2310 // given constant if there is a lossless conversion between the constant
2311 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002312 bool has_int32_value_ : 1;
2313 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002314 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315 double double_value_;
2316};
2317
2318
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002319class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002320 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002321 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002322 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002323 SetOperandAt(0, context);
2324 SetOperandAt(1, left);
2325 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002326 }
2327
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002328 HValue* context() { return OperandAt(0); }
2329 HValue* left() { return OperandAt(1); }
2330 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331
2332 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2333 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002334 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002335 if (IsCommutative() && left()->IsConstant()) return right();
2336 return left();
2337 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002338 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339 if (IsCommutative() && left()->IsConstant()) return left();
2340 return right();
2341 }
2342
2343 virtual bool IsCommutative() const { return false; }
2344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002345 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002346};
2347
2348
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002349class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002350 public:
2351 HApplyArguments(HValue* function,
2352 HValue* receiver,
2353 HValue* length,
2354 HValue* elements) {
2355 set_representation(Representation::Tagged());
2356 SetOperandAt(0, function);
2357 SetOperandAt(1, receiver);
2358 SetOperandAt(2, length);
2359 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002360 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361 }
2362
2363 virtual Representation RequiredInputRepresentation(int index) const {
2364 // The length is untagged, all other inputs are tagged.
2365 return (index == 2)
2366 ? Representation::Integer32()
2367 : Representation::Tagged();
2368 }
2369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002370 HValue* function() { return OperandAt(0); }
2371 HValue* receiver() { return OperandAt(1); }
2372 HValue* length() { return OperandAt(2); }
2373 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002375 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376};
2377
2378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002379class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002380 public:
2381 HArgumentsElements() {
2382 // The value produced by this instruction is a pointer into the stack
2383 // that looks as if it was a smi because of alignment.
2384 set_representation(Representation::Tagged());
2385 SetFlag(kUseGVN);
2386 }
2387
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002388 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002390 virtual Representation RequiredInputRepresentation(int index) const {
2391 return Representation::None();
2392 }
2393
ager@chromium.org378b34e2011-01-28 08:04:38 +00002394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002395 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002396};
2397
2398
2399class HArgumentsLength: public HUnaryOperation {
2400 public:
2401 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2402 set_representation(Representation::Integer32());
2403 SetFlag(kUseGVN);
2404 }
2405
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002406 virtual Representation RequiredInputRepresentation(int index) const {
2407 return Representation::Tagged();
2408 }
2409
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002410 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002411
2412 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002413 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002414};
2415
2416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002417class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002418 public:
2419 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2420 set_representation(Representation::Tagged());
2421 SetFlag(kUseGVN);
2422 SetOperandAt(0, arguments);
2423 SetOperandAt(1, length);
2424 SetOperandAt(2, index);
2425 }
2426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002427 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002428
2429 virtual Representation RequiredInputRepresentation(int index) const {
2430 // The arguments elements is considered tagged.
2431 return index == 0
2432 ? Representation::Tagged()
2433 : Representation::Integer32();
2434 }
2435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002436 HValue* arguments() { return OperandAt(0); }
2437 HValue* length() { return OperandAt(1); }
2438 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002439
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002440 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002441
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002442 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443};
2444
2445
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002446class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002447 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002448 HBoundsCheck(HValue* index, HValue* length) {
2449 SetOperandAt(0, index);
2450 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002451 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002452 SetFlag(kUseGVN);
2453 }
2454
2455 virtual Representation RequiredInputRepresentation(int index) const {
2456 return Representation::Integer32();
2457 }
2458
2459#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002460 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002461#endif
2462
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002463 HValue* index() { return OperandAt(0); }
2464 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002465
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002466 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002467
2468 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002469 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002470};
2471
2472
2473class HBitwiseBinaryOperation: public HBinaryOperation {
2474 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002475 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2476 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002477 set_representation(Representation::Tagged());
2478 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002479 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480 }
2481
2482 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002483 return index == 0
2484 ? Representation::Tagged()
2485 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486 }
2487
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002488 virtual void RepresentationChanged(Representation to) {
2489 if (!to.IsTagged()) {
2490 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002491 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002492 SetFlag(kTruncatingToInt32);
2493 SetFlag(kUseGVN);
2494 }
2495 }
2496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002497 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002498
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002499 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002500};
2501
2502
2503class HArithmeticBinaryOperation: public HBinaryOperation {
2504 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002505 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2506 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002507 set_representation(Representation::Tagged());
2508 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002509 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002510 }
2511
2512 virtual void RepresentationChanged(Representation to) {
2513 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002514 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515 SetFlag(kUseGVN);
2516 }
2517 }
2518
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002519 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002521 return index == 0
2522 ? Representation::Tagged()
2523 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002524 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002526 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002527 if (left()->representation().Equals(right()->representation())) {
2528 return left()->representation();
2529 }
2530 return HValue::InferredRepresentation();
2531 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002532};
2533
2534
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002535class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002537 HCompareGeneric(HValue* context,
2538 HValue* left,
2539 HValue* right,
2540 Token::Value token)
2541 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002542 ASSERT(Token::IsCompareOp(token));
2543 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002544 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002545 }
2546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002548 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002549 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002550
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002551 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002552 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002554
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002556 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002557
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002558 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002559
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002560 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2561
2562 private:
2563 Token::Value token_;
2564};
2565
2566
2567class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2568 public:
2569 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2570 : token_(token) {
2571 ASSERT(Token::IsCompareOp(token));
2572 SetOperandAt(0, left);
2573 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002574 }
2575
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002576 HValue* left() { return OperandAt(0); }
2577 HValue* right() { return OperandAt(1); }
2578 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002579
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002580 void SetInputRepresentation(Representation r);
2581 Representation GetInputRepresentation() const {
2582 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 }
2584
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002585 virtual Representation RequiredInputRepresentation(int index) const {
2586 return input_representation_;
2587 }
2588 virtual void PrintDataTo(StringStream* stream);
2589
2590 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2591
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002592 private:
2593 Representation input_representation_;
2594 Token::Value token_;
2595};
2596
2597
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002598class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002599 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002600 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2601 SetOperandAt(0, left);
2602 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603 }
2604
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002605 HValue* left() { return OperandAt(0); }
2606 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002607
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002608 virtual Representation RequiredInputRepresentation(int index) const {
2609 return Representation::Tagged();
2610 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002611
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002612 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002613};
2614
2615
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002616class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002617 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002618 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2619 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002620 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002621 }
2622
2623 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002624 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002625 int right() const { return right_; }
2626
whesse@chromium.org7b260152011-06-20 15:33:18 +00002627 virtual Representation RequiredInputRepresentation(int index) const {
2628 return Representation::Integer32();
2629 }
2630
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002631 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002632
2633 private:
2634 const Token::Value op_;
2635 const int right_;
2636};
2637
2638
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002639class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002640 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002641 HIsNullAndBranch(HValue* value, bool is_strict)
2642 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002643
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002644 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002645
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002646 virtual Representation RequiredInputRepresentation(int index) const {
2647 return Representation::Tagged();
2648 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002649
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002650 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002651
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002652 private:
2653 bool is_strict_;
2654};
2655
2656
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002657class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002658 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002659 explicit HIsObjectAndBranch(HValue* value)
2660 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002661
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002662 virtual Representation RequiredInputRepresentation(int index) const {
2663 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002664 }
2665
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002666 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2667};
2668
2669
2670class HIsSmiAndBranch: public HUnaryControlInstruction {
2671 public:
2672 explicit HIsSmiAndBranch(HValue* value)
2673 : HUnaryControlInstruction(value, NULL, NULL) { }
2674
2675 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2676
2677 virtual Representation RequiredInputRepresentation(int index) const {
2678 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002679 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002680
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002681 protected:
2682 virtual bool DataEquals(HValue* other) { return true; }
2683};
2684
2685
2686class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2687 public:
2688 explicit HIsUndetectableAndBranch(HValue* value)
2689 : HUnaryControlInstruction(value, NULL, NULL) { }
2690
2691 virtual Representation RequiredInputRepresentation(int index) const {
2692 return Representation::Tagged();
2693 }
2694
2695 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2696};
2697
2698
2699class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2700 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002701 virtual Representation RequiredInputRepresentation(int index) const {
2702 return Representation::None();
2703 }
2704
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002705 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002706};
2707
2708
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002709class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002710 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002711 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2712 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2713 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2714 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2716 }
2717
2718 InstanceType from() { return from_; }
2719 InstanceType to() { return to_; }
2720
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002721 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002723 virtual Representation RequiredInputRepresentation(int index) const {
2724 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002725 }
2726
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002727 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002729 private:
2730 InstanceType from_;
2731 InstanceType to_; // Inclusive range, not all combinations work.
2732};
2733
2734
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002735class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002737 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2738 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002740 virtual Representation RequiredInputRepresentation(int index) const {
2741 return Representation::Tagged();
2742 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002743
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002744 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002745};
2746
2747
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002748class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002749 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002750 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2751 set_representation(Representation::Tagged());
2752 SetFlag(kUseGVN);
2753 }
2754
2755 virtual Representation RequiredInputRepresentation(int index) const {
2756 return Representation::Tagged();
2757 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002758
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002759 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002760
2761 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002762 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002763};
2764
2765
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002766class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002767 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002768 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2769 : HUnaryControlInstruction(value, NULL, NULL),
2770 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002771
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002772 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2773
2774 virtual Representation RequiredInputRepresentation(int index) const {
2775 return Representation::Tagged();
2776 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002777
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002778 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779
2780 Handle<String> class_name() const { return class_name_; }
2781
2782 private:
2783 Handle<String> class_name_;
2784};
2785
2786
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002787class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002789 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2790 : HUnaryControlInstruction(value, NULL, NULL),
2791 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792
2793 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002794 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002795
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002796 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002797
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002798 virtual Representation RequiredInputRepresentation(int index) const {
2799 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002800 }
2801
2802 private:
2803 Handle<String> type_literal_;
2804};
2805
2806
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002807class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002809 HInstanceOf(HValue* context, HValue* left, HValue* right)
2810 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002812 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813 }
2814
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815 virtual Representation RequiredInputRepresentation(int index) const {
2816 return Representation::Tagged();
2817 }
2818
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002819 virtual HType CalculateInferredType();
2820
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002821 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002822
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002823 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824};
2825
2826
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002827class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002828 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002829 HInstanceOfKnownGlobal(HValue* context,
2830 HValue* left,
2831 Handle<JSFunction> right)
2832 : function_(right) {
2833 SetOperandAt(0, context);
2834 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002835 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002836 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002837 }
2838
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002839 HValue* context() { return OperandAt(0); }
2840 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002841 Handle<JSFunction> function() { return function_; }
2842
2843 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
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002849 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002850
2851 private:
2852 Handle<JSFunction> function_;
2853};
2854
2855
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002856class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002857 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002858 HPower(HValue* left, HValue* right) {
2859 SetOperandAt(0, left);
2860 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002861 set_representation(Representation::Double());
2862 SetFlag(kUseGVN);
2863 }
2864
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002865 HValue* left() { return OperandAt(0); }
2866 HValue* right() { return OperandAt(1); }
2867
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002868 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002869 return index == 0
2870 ? Representation::Double()
2871 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002872 }
2873
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002874 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002875
2876 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002877 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002878};
2879
2880
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002881class HAdd: public HArithmeticBinaryOperation {
2882 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002883 HAdd(HValue* context, HValue* left, HValue* right)
2884 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002885 SetFlag(kCanOverflow);
2886 }
2887
2888 // Add is only commutative if two integer values are added and not if two
2889 // tagged values are added (because it might be a String concatenation).
2890 virtual bool IsCommutative() const {
2891 return !representation().IsTagged();
2892 }
2893
2894 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2895
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002896 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002897
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002898 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899
2900 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002901 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002902
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903 virtual Range* InferRange();
2904};
2905
2906
2907class HSub: public HArithmeticBinaryOperation {
2908 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002909 HSub(HValue* context, HValue* left, HValue* right)
2910 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002911 SetFlag(kCanOverflow);
2912 }
2913
2914 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2915
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002916 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917
2918 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002919 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002920
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002921 virtual Range* InferRange();
2922};
2923
2924
2925class HMul: public HArithmeticBinaryOperation {
2926 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002927 HMul(HValue* context, HValue* left, HValue* right)
2928 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002929 SetFlag(kCanOverflow);
2930 }
2931
2932 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2933
2934 // Only commutative if it is certain that not two objects are multiplicated.
2935 virtual bool IsCommutative() const {
2936 return !representation().IsTagged();
2937 }
2938
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002939 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940
2941 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002942 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002943
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944 virtual Range* InferRange();
2945};
2946
2947
2948class HMod: public HArithmeticBinaryOperation {
2949 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002950 HMod(HValue* context, HValue* left, HValue* right)
2951 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002952 SetFlag(kCanBeDivByZero);
2953 }
2954
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002955 bool HasPowerOf2Divisor() {
2956 if (right()->IsConstant() &&
2957 HConstant::cast(right())->HasInteger32Value()) {
2958 int32_t value = HConstant::cast(right())->Integer32Value();
2959 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2960 }
2961
2962 return false;
2963 }
2964
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002965 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2966
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002967 DECLARE_CONCRETE_INSTRUCTION(Mod)
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 HDiv: public HArithmeticBinaryOperation {
2977 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002978 HDiv(HValue* context, HValue* left, HValue* right)
2979 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002980 SetFlag(kCanBeDivByZero);
2981 SetFlag(kCanOverflow);
2982 }
2983
2984 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2985
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002986 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002987
2988 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002989 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002990
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 virtual Range* InferRange();
2992};
2993
2994
2995class HBitAnd: public HBitwiseBinaryOperation {
2996 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002997 HBitAnd(HValue* context, HValue* left, HValue* right)
2998 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999
3000 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003001 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003003 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003004
3005 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003006 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003007
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008 virtual Range* InferRange();
3009};
3010
3011
3012class HBitXor: public HBitwiseBinaryOperation {
3013 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003014 HBitXor(HValue* context, HValue* left, HValue* right)
3015 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016
3017 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003018 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003020 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003021
3022 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003023 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024};
3025
3026
3027class HBitOr: public HBitwiseBinaryOperation {
3028 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003029 HBitOr(HValue* context, HValue* left, HValue* right)
3030 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003031
3032 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003033 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003034
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003035 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003036
3037 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003038 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003039
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003040 virtual Range* InferRange();
3041};
3042
3043
3044class HShl: public HBitwiseBinaryOperation {
3045 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003046 HShl(HValue* context, HValue* left, HValue* right)
3047 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003048
3049 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003050 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003052 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003053
3054 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003055 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003056};
3057
3058
3059class HShr: public HBitwiseBinaryOperation {
3060 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003061 HShr(HValue* context, HValue* left, HValue* right)
3062 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003063
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003064 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003066 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003067
3068 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003069 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003070};
3071
3072
3073class HSar: public HBitwiseBinaryOperation {
3074 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003075 HSar(HValue* context, HValue* left, HValue* right)
3076 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077
3078 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003079 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003081 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003082
3083 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003084 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085};
3086
3087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003088class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089 public:
3090 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3091 SetFlag(kChangesOsrEntries);
3092 }
3093
3094 int ast_id() const { return ast_id_; }
3095
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003096 virtual Representation RequiredInputRepresentation(int index) const {
3097 return Representation::None();
3098 }
3099
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003100 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101
3102 private:
3103 int ast_id_;
3104};
3105
3106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003107class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108 public:
3109 explicit HParameter(unsigned index) : index_(index) {
3110 set_representation(Representation::Tagged());
3111 }
3112
3113 unsigned index() const { return index_; }
3114
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003115 virtual void PrintDataTo(StringStream* stream);
3116
3117 virtual Representation RequiredInputRepresentation(int index) const {
3118 return Representation::None();
3119 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003121 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122
3123 private:
3124 unsigned index_;
3125};
3126
3127
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003128class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003130 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3131 : HUnaryCall(context, argument_count),
3132 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 }
3135
3136 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003137
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003138 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003139
3140 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3141 transcendental_type_ = transcendental_type;
3142 }
3143 TranscendentalCache::Type transcendental_type() {
3144 return transcendental_type_;
3145 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003146
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003147 virtual void PrintDataTo(StringStream* stream);
3148
3149 virtual Representation RequiredInputRepresentation(int index) const {
3150 return Representation::Tagged();
3151 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003152
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003153 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154
3155 private:
3156 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157 TranscendentalCache::Type transcendental_type_;
3158};
3159
3160
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003161class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162 public:
3163 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3164
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003165 virtual Representation RequiredInputRepresentation(int index) const {
3166 return Representation::None();
3167 }
3168
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003169 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170};
3171
3172
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003173class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003174 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003175 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 : cell_(cell), check_hole_value_(check_hole_value) {
3177 set_representation(Representation::Tagged());
3178 SetFlag(kUseGVN);
3179 SetFlag(kDependsOnGlobalVars);
3180 }
3181
3182 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3183 bool check_hole_value() const { return check_hole_value_; }
3184
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003185 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003187 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003188 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003189 return reinterpret_cast<intptr_t>(*cell_);
3190 }
3191
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003192 virtual Representation RequiredInputRepresentation(int index) const {
3193 return Representation::None();
3194 }
3195
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003196 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197
3198 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003199 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003200 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 return cell_.is_identical_to(b->cell());
3202 }
3203
3204 private:
3205 Handle<JSGlobalPropertyCell> cell_;
3206 bool check_hole_value_;
3207};
3208
3209
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003210class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003211 public:
3212 HLoadGlobalGeneric(HValue* context,
3213 HValue* global_object,
3214 Handle<Object> name,
3215 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003216 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003217 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003218 SetOperandAt(0, context);
3219 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003220 set_representation(Representation::Tagged());
3221 SetAllSideEffects();
3222 }
3223
3224 HValue* context() { return OperandAt(0); }
3225 HValue* global_object() { return OperandAt(1); }
3226 Handle<Object> name() const { return name_; }
3227 bool for_typeof() const { return for_typeof_; }
3228
3229 virtual void PrintDataTo(StringStream* stream);
3230
3231 virtual Representation RequiredInputRepresentation(int index) const {
3232 return Representation::Tagged();
3233 }
3234
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003235 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003236
3237 private:
3238 Handle<Object> name_;
3239 bool for_typeof_;
3240};
3241
3242
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003243class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003244 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003245 HStoreGlobalCell(HValue* value,
3246 Handle<JSGlobalPropertyCell> cell,
3247 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003248 : HUnaryOperation(value),
3249 cell_(cell),
3250 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251 SetFlag(kChangesGlobalVars);
3252 }
3253
3254 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003255 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003256
3257 virtual Representation RequiredInputRepresentation(int index) const {
3258 return Representation::Tagged();
3259 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003260 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003262 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264 private:
3265 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003266 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003267};
3268
3269
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003270class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3271 public:
3272 HStoreGlobalGeneric(HValue* context,
3273 HValue* global_object,
3274 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003275 HValue* value,
3276 bool strict_mode)
3277 : name_(name),
3278 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003279 SetOperandAt(0, context);
3280 SetOperandAt(1, global_object);
3281 SetOperandAt(2, value);
3282 set_representation(Representation::Tagged());
3283 SetAllSideEffects();
3284 }
3285
3286 HValue* context() { return OperandAt(0); }
3287 HValue* global_object() { return OperandAt(1); }
3288 Handle<Object> name() const { return name_; }
3289 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003290 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003291
3292 virtual void PrintDataTo(StringStream* stream);
3293
3294 virtual Representation RequiredInputRepresentation(int index) const {
3295 return Representation::Tagged();
3296 }
3297
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003298 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003299
3300 private:
3301 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003302 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003303};
3304
3305
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003306class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003307 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003308 HLoadContextSlot(HValue* context , int slot_index)
3309 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003310 set_representation(Representation::Tagged());
3311 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003312 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003313 }
3314
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003315 int slot_index() const { return slot_index_; }
3316
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003317 virtual Representation RequiredInputRepresentation(int index) const {
3318 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003319 }
3320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003321 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003322
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003323 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003324
3325 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003326 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003327 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003328 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003329 }
3330
3331 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003332 int slot_index_;
3333};
3334
3335
3336static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003337 return !value->type().IsBoolean()
3338 && !value->type().IsSmi()
3339 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003340}
3341
3342
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003343class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003344 public:
3345 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003346 : slot_index_(slot_index) {
3347 SetOperandAt(0, context);
3348 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003349 SetFlag(kChangesContextSlots);
3350 }
3351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003352 HValue* context() { return OperandAt(0); }
3353 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003354 int slot_index() const { return slot_index_; }
3355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003356 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003357 return StoringValueNeedsWriteBarrier(value());
3358 }
3359
3360 virtual Representation RequiredInputRepresentation(int index) const {
3361 return Representation::Tagged();
3362 }
3363
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003364 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003365
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003366 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003367
3368 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003369 int slot_index_;
3370};
3371
3372
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003373class HLoadNamedField: public HUnaryOperation {
3374 public:
3375 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3376 : HUnaryOperation(object),
3377 is_in_object_(is_in_object),
3378 offset_(offset) {
3379 set_representation(Representation::Tagged());
3380 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003381 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003382 if (is_in_object) {
3383 SetFlag(kDependsOnInobjectFields);
3384 } else {
3385 SetFlag(kDependsOnBackingStoreFields);
3386 }
3387 }
3388
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003389 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003390 bool is_in_object() const { return is_in_object_; }
3391 int offset() const { return offset_; }
3392
3393 virtual Representation RequiredInputRepresentation(int index) const {
3394 return Representation::Tagged();
3395 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003396 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003397
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003398 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399
3400 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003401 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003402 HLoadNamedField* b = HLoadNamedField::cast(other);
3403 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3404 }
3405
3406 private:
3407 bool is_in_object_;
3408 int offset_;
3409};
3410
3411
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003412class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003413 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003414 HLoadNamedFieldPolymorphic(HValue* context,
3415 HValue* object,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003416 ZoneMapList* types,
3417 Handle<String> name);
3418
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003419 HValue* context() { return OperandAt(0); }
3420 HValue* object() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003421 ZoneMapList* types() { return &types_; }
3422 Handle<String> name() { return name_; }
3423 bool need_generic() { return need_generic_; }
3424
3425 virtual Representation RequiredInputRepresentation(int index) const {
3426 return Representation::Tagged();
3427 }
3428
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003429 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003430
3431 static const int kMaxLoadPolymorphism = 4;
3432
3433 protected:
3434 virtual bool DataEquals(HValue* value);
3435
3436 private:
3437 ZoneMapList types_;
3438 Handle<String> name_;
3439 bool need_generic_;
3440};
3441
3442
3443
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003444class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003446 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003447 : name_(name) {
3448 SetOperandAt(0, context);
3449 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003451 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003452 }
3453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003454 HValue* context() { return OperandAt(0); }
3455 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003456 Handle<Object> name() const { return name_; }
3457
3458 virtual Representation RequiredInputRepresentation(int index) const {
3459 return Representation::Tagged();
3460 }
3461
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003462 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003463
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003464 private:
3465 Handle<Object> name_;
3466};
3467
3468
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003469class HLoadFunctionPrototype: public HUnaryOperation {
3470 public:
3471 explicit HLoadFunctionPrototype(HValue* function)
3472 : HUnaryOperation(function) {
3473 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003474 SetFlag(kUseGVN);
3475 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003476 }
3477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003478 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003479
3480 virtual Representation RequiredInputRepresentation(int index) const {
3481 return Representation::Tagged();
3482 }
3483
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003484 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003485
3486 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003488};
3489
3490
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003491class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003492 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003493 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3494 SetOperandAt(0, obj);
3495 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003496 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003497 SetFlag(kDependsOnArrayElements);
3498 SetFlag(kUseGVN);
3499 }
3500
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003501 HValue* object() { return OperandAt(0); }
3502 HValue* key() { return OperandAt(1); }
3503
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003504 virtual Representation RequiredInputRepresentation(int index) const {
3505 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003506 return index == 0
3507 ? Representation::Tagged()
3508 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509 }
3510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003511 virtual void PrintDataTo(StringStream* stream);
3512
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003513 bool RequiresHoleCheck() const;
3514
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003515 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003516
3517 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003518 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519};
3520
3521
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003522class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003523 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003524 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3525 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003526 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003527 : elements_kind_(elements_kind) {
3528 SetOperandAt(0, external_elements);
3529 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003530 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3531 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003532 set_representation(Representation::Double());
3533 } else {
3534 set_representation(Representation::Integer32());
3535 }
3536 SetFlag(kDependsOnSpecializedArrayElements);
3537 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003538 SetFlag(kDependsOnCalls);
3539 SetFlag(kUseGVN);
3540 }
3541
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003542 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003543
3544 virtual Representation RequiredInputRepresentation(int index) const {
3545 // The key is supposed to be Integer32, but the base pointer
3546 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003547 return index == 0
3548 ? Representation::External()
3549 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003550 }
3551
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003552 HValue* external_pointer() { return OperandAt(0); }
3553 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003554 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003555
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003556 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003557
3558 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003559 virtual bool DataEquals(HValue* other) {
3560 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3561 HLoadKeyedSpecializedArrayElement* cast_other =
3562 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003563 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003564 }
3565
3566 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003567 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003568};
3569
3570
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003571class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003572 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003573 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003574 set_representation(Representation::Tagged());
3575 SetOperandAt(0, obj);
3576 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003577 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003578 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003579 }
3580
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003581 HValue* object() { return OperandAt(0); }
3582 HValue* key() { return OperandAt(1); }
3583 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003584
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003585 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003586
3587 virtual Representation RequiredInputRepresentation(int index) const {
3588 return Representation::Tagged();
3589 }
3590
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003591 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592};
3593
3594
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003595class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003596 public:
3597 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003598 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 HValue* val,
3600 bool in_object,
3601 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003602 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603 is_in_object_(in_object),
3604 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003605 SetOperandAt(0, obj);
3606 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003607 if (is_in_object_) {
3608 SetFlag(kChangesInobjectFields);
3609 } else {
3610 SetFlag(kChangesBackingStoreFields);
3611 }
3612 }
3613
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003614 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003615
3616 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003617 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003619 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003621 HValue* object() { return OperandAt(0); }
3622 HValue* value() { return OperandAt(1); }
3623
3624 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625 bool is_in_object() const { return is_in_object_; }
3626 int offset() const { return offset_; }
3627 Handle<Map> transition() const { return transition_; }
3628 void set_transition(Handle<Map> map) { transition_ = map; }
3629
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003630 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003631 return StoringValueNeedsWriteBarrier(value());
3632 }
3633
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003635 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636 bool is_in_object_;
3637 int offset_;
3638 Handle<Map> transition_;
3639};
3640
3641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003642class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003644 HStoreNamedGeneric(HValue* context,
3645 HValue* object,
3646 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003647 HValue* value,
3648 bool strict_mode)
3649 : name_(name),
3650 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003651 SetOperandAt(0, object);
3652 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003653 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003654 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003655 }
3656
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003657 HValue* object() { return OperandAt(0); }
3658 HValue* value() { return OperandAt(1); }
3659 HValue* context() { return OperandAt(2); }
3660 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003661 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003663 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003664
3665 virtual Representation RequiredInputRepresentation(int index) const {
3666 return Representation::Tagged();
3667 }
3668
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003669 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003671 private:
3672 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003673 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003674};
3675
3676
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003677class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003678 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003679 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3680 SetOperandAt(0, obj);
3681 SetOperandAt(1, key);
3682 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003683 SetFlag(kChangesArrayElements);
3684 }
3685
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003686 virtual Representation RequiredInputRepresentation(int index) const {
3687 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003688 return index == 1
3689 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690 : Representation::Tagged();
3691 }
3692
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003693 HValue* object() { return OperandAt(0); }
3694 HValue* key() { return OperandAt(1); }
3695 HValue* value() { return OperandAt(2); }
3696
3697 bool NeedsWriteBarrier() {
3698 return StoringValueNeedsWriteBarrier(value());
3699 }
3700
3701 virtual void PrintDataTo(StringStream* stream);
3702
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003703 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003704};
3705
3706
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003707class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003708 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003709 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3710 HValue* key,
3711 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003712 JSObject::ElementsKind elements_kind)
3713 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003714 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003715 SetOperandAt(0, external_elements);
3716 SetOperandAt(1, key);
3717 SetOperandAt(2, val);
3718 }
3719
3720 virtual void PrintDataTo(StringStream* stream);
3721
3722 virtual Representation RequiredInputRepresentation(int index) const {
3723 if (index == 0) {
3724 return Representation::External();
3725 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003726 bool float_or_double_elements =
3727 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3728 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3729 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003730 return Representation::Double();
3731 } else {
3732 return Representation::Integer32();
3733 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003734 }
3735 }
3736
3737 HValue* external_pointer() { return OperandAt(0); }
3738 HValue* key() { return OperandAt(1); }
3739 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003740 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003741
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003742 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3743
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003744 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003745 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003746};
3747
3748
3749class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003750 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003751 HStoreKeyedGeneric(HValue* context,
3752 HValue* object,
3753 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003754 HValue* value,
3755 bool strict_mode)
3756 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003757 SetOperandAt(0, object);
3758 SetOperandAt(1, key);
3759 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003760 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003761 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003762 }
3763
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003764 HValue* object() { return OperandAt(0); }
3765 HValue* key() { return OperandAt(1); }
3766 HValue* value() { return OperandAt(2); }
3767 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003768 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003770 virtual Representation RequiredInputRepresentation(int index) const {
3771 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003772 }
3773
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003774 virtual void PrintDataTo(StringStream* stream);
3775
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003776 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003777
3778 private:
3779 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003780};
3781
3782
danno@chromium.org160a7b02011-04-18 15:51:38 +00003783class HStringAdd: public HBinaryOperation {
3784 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003785 HStringAdd(HValue* context, HValue* left, HValue* right)
3786 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003787 set_representation(Representation::Tagged());
3788 SetFlag(kUseGVN);
3789 SetFlag(kDependsOnMaps);
3790 }
3791
3792 virtual Representation RequiredInputRepresentation(int index) const {
3793 return Representation::Tagged();
3794 }
3795
3796 virtual HType CalculateInferredType() {
3797 return HType::String();
3798 }
3799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003800 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003801
3802 protected:
3803 virtual bool DataEquals(HValue* other) { return true; }
3804};
3805
3806
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003807class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003808 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003809 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3810 SetOperandAt(0, context);
3811 SetOperandAt(1, string);
3812 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003813 set_representation(Representation::Integer32());
3814 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003815 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003816 }
3817
3818 virtual Representation RequiredInputRepresentation(int index) const {
3819 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003820 return index == 2
3821 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003822 : Representation::Tagged();
3823 }
3824
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003825 HValue* context() { return OperandAt(0); }
3826 HValue* string() { return OperandAt(1); }
3827 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003828
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003829 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003830
3831 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003832 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003833
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003834 virtual Range* InferRange() {
3835 return new Range(0, String::kMaxUC16CharCode);
3836 }
3837};
3838
3839
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003840class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003841 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003842 HStringCharFromCode(HValue* context, HValue* char_code) {
3843 SetOperandAt(0, context);
3844 SetOperandAt(1, char_code);
3845 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003846 SetFlag(kUseGVN);
3847 }
3848
3849 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003850 return index == 0
3851 ? Representation::Tagged()
3852 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003853 }
3854
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003855 HValue* context() { return OperandAt(0); }
3856 HValue* value() { return OperandAt(1); }
3857
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003858 virtual bool DataEquals(HValue* other) { return true; }
3859
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003860 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003861};
3862
3863
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003864class HStringLength: public HUnaryOperation {
3865 public:
3866 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3867 set_representation(Representation::Tagged());
3868 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003869 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003870 }
3871
3872 virtual Representation RequiredInputRepresentation(int index) const {
3873 return Representation::Tagged();
3874 }
3875
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003876 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003877 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3878 return HType::Smi();
3879 }
3880
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003881 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003882
3883 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003884 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003885
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003886 virtual Range* InferRange() {
3887 return new Range(0, String::kMaxLength);
3888 }
3889};
3890
3891
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003892template <int V>
3893class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003894 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003895 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003896 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003897 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003898 }
3899
3900 int literal_index() const { return literal_index_; }
3901 int depth() const { return depth_; }
3902
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003903 private:
3904 int literal_index_;
3905 int depth_;
3906};
3907
3908
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003909class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003910 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003911 HArrayLiteral(HValue* context,
3912 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003913 int length,
3914 int literal_index,
3915 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003916 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003917 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003918 constant_elements_(constant_elements) {
3919 SetOperandAt(0, context);
3920 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003921
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003922 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003923 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3924 int length() const { return length_; }
3925
3926 bool IsCopyOnWrite() const;
3927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003928 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003929 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003930 }
3931
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003932 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003933
3934 private:
3935 int length_;
3936 Handle<FixedArray> constant_elements_;
3937};
3938
3939
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003940class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003941 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003942 HObjectLiteral(HValue* context,
3943 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003944 bool fast_elements,
3945 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003946 int depth,
3947 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003948 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003949 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003950 fast_elements_(fast_elements),
3951 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003952 SetOperandAt(0, context);
3953 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003954
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003955 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003956 Handle<FixedArray> constant_properties() const {
3957 return constant_properties_;
3958 }
3959 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003960 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003961
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003962 virtual Representation RequiredInputRepresentation(int index) const {
3963 return Representation::Tagged();
3964 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003965
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003966 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003967
3968 private:
3969 Handle<FixedArray> constant_properties_;
3970 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003971 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003972};
3973
3974
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003975class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003976 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003977 HRegExpLiteral(HValue* context,
3978 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003979 Handle<String> flags,
3980 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003981 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003982 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003983 flags_(flags) {
3984 SetOperandAt(0, context);
3985 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003986
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003987 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988 Handle<String> pattern() { return pattern_; }
3989 Handle<String> flags() { return flags_; }
3990
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003991 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003992 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003993 }
3994
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003995 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003996
3997 private:
3998 Handle<String> pattern_;
3999 Handle<String> flags_;
4000};
4001
4002
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004003class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004004 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004005 HFunctionLiteral(HValue* context,
4006 Handle<SharedFunctionInfo> shared,
4007 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004008 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004009 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004010 set_representation(Representation::Tagged());
4011 }
4012
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004013 HValue* context() { return OperandAt(0); }
4014
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004015 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004016 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004017 }
4018
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004019 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004020
4021 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4022 bool pretenure() const { return pretenure_; }
4023
4024 private:
4025 Handle<SharedFunctionInfo> shared_info_;
4026 bool pretenure_;
4027};
4028
4029
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004030class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004031 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004032 explicit HTypeof(HValue* context, HValue* value) {
4033 SetOperandAt(0, context);
4034 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004035 set_representation(Representation::Tagged());
4036 }
4037
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004038 HValue* context() { return OperandAt(0); }
4039 HValue* value() { return OperandAt(1); }
4040
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004041 virtual Representation RequiredInputRepresentation(int index) const {
4042 return Representation::Tagged();
4043 }
4044
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004045 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004046};
4047
4048
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004049class HToFastProperties: public HUnaryOperation {
4050 public:
4051 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4052 // This instruction is not marked as having side effects, but
4053 // changes the map of the input operand. Use it only when creating
4054 // object literals.
4055 ASSERT(value->IsObjectLiteral());
4056 set_representation(Representation::Tagged());
4057 }
4058
4059 virtual Representation RequiredInputRepresentation(int index) const {
4060 return Representation::Tagged();
4061 }
4062
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004063 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004064};
4065
4066
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004067class HValueOf: public HUnaryOperation {
4068 public:
4069 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4070 set_representation(Representation::Tagged());
4071 }
4072
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004073 virtual Representation RequiredInputRepresentation(int index) const {
4074 return Representation::Tagged();
4075 }
4076
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004077 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004078};
4079
4080
4081class HDeleteProperty: public HBinaryOperation {
4082 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004083 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4084 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004085 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004086 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004087 }
4088
4089 virtual Representation RequiredInputRepresentation(int index) const {
4090 return Representation::Tagged();
4091 }
4092
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004093 virtual HType CalculateInferredType();
4094
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004095 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004096
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004097 HValue* object() { return left(); }
4098 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004099};
4100
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004101
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004102class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004103 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004104 HIn(HValue* context, HValue* key, HValue* object) {
4105 SetOperandAt(0, context);
4106 SetOperandAt(1, key);
4107 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004108 set_representation(Representation::Tagged());
4109 SetAllSideEffects();
4110 }
4111
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004112 HValue* context() { return OperandAt(0); }
4113 HValue* key() { return OperandAt(1); }
4114 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004115
4116 virtual Representation RequiredInputRepresentation(int index) const {
4117 return Representation::Tagged();
4118 }
4119
4120 virtual HType CalculateInferredType() {
4121 return HType::Boolean();
4122 }
4123
4124 virtual void PrintDataTo(StringStream* stream);
4125
4126 DECLARE_CONCRETE_INSTRUCTION(In)
4127};
4128
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004129#undef DECLARE_INSTRUCTION
4130#undef DECLARE_CONCRETE_INSTRUCTION
4131
4132} } // namespace v8::internal
4133
4134#endif // V8_HYDROGEN_INSTRUCTIONS_H_