blob: 3ccf302e40fbe6bcef581523cace60ebe76285b2 [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) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000107 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000108 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000109 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000110 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(GlobalObject) \
112 V(GlobalReceiver) \
113 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000114 V(HasCachedArrayIndexAndBranch) \
115 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000116 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000118 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000119 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000120 V(IsConstructCallAndBranch) \
121 V(IsNullAndBranch) \
122 V(IsObjectAndBranch) \
123 V(IsSmiAndBranch) \
124 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000125 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000127 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000129 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000130 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000131 V(LoadGlobalCell) \
132 V(LoadGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000133 V(LoadKeyedFastDoubleElement) \
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) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000159 V(StoreKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(StoreKeyedFastElement) \
161 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000162 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 V(StoreNamedField) \
164 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000165 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000166 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000167 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000168 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000169 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000170 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000171 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000172 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000173 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000175 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(UnaryMathOperation) \
177 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000178 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 V(ValueOf)
180
181#define GVN_FLAG_LIST(V) \
182 V(Calls) \
183 V(InobjectFields) \
184 V(BackingStoreFields) \
185 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000186 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000187 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 V(GlobalVars) \
189 V(Maps) \
190 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000191 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192 V(OsrEntries)
193
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000194#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195 virtual bool Is##type() const { return true; } \
196 static H##type* cast(HValue* value) { \
197 ASSERT(value->Is##type()); \
198 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000199 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
201
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000202#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000204 static H##type* cast(HValue* value) { \
205 ASSERT(value->Is##type()); \
206 return reinterpret_cast<H##type*>(value); \
207 } \
208 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209
210
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211class Range: public ZoneObject {
212 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000213 Range()
214 : lower_(kMinInt),
215 upper_(kMaxInt),
216 next_(NULL),
217 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218
219 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000220 : lower_(lower),
221 upper_(upper),
222 next_(NULL),
223 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 int32_t upper() const { return upper_; }
226 int32_t lower() const { return lower_; }
227 Range* next() const { return next_; }
228 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
229 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000230 Range* Copy() const {
231 Range* result = new Range(lower_, upper_);
232 result->set_can_be_minus_zero(CanBeMinusZero());
233 return result;
234 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235 int32_t Mask() const;
236 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
237 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
238 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
239 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000240 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000241 bool IsMostGeneric() const {
242 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
243 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000244 bool IsInSmiRange() const {
245 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000246 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 void KeepOrder();
248 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000249
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000250 void StackUpon(Range* other) {
251 Intersect(other);
252 next_ = other;
253 }
254
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000255 void Intersect(Range* other);
256 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000257
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000258 void AddConstant(int32_t value);
259 void Sar(int32_t value);
260 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000261 bool AddAndCheckOverflow(Range* other);
262 bool SubAndCheckOverflow(Range* other);
263 bool MulAndCheckOverflow(Range* other);
264
265 private:
266 int32_t lower_;
267 int32_t upper_;
268 Range* next_;
269 bool can_be_minus_zero_;
270};
271
272
273class Representation {
274 public:
275 enum Kind {
276 kNone,
277 kTagged,
278 kDouble,
279 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000280 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000281 kNumRepresentations
282 };
283
284 Representation() : kind_(kNone) { }
285
286 static Representation None() { return Representation(kNone); }
287 static Representation Tagged() { return Representation(kTagged); }
288 static Representation Integer32() { return Representation(kInteger32); }
289 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000290 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000292 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000293 return kind_ == other.kind_;
294 }
295
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000296 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000297 bool IsNone() const { return kind_ == kNone; }
298 bool IsTagged() const { return kind_ == kTagged; }
299 bool IsInteger32() const { return kind_ == kInteger32; }
300 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000301 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302 bool IsSpecialization() const {
303 return kind_ == kInteger32 || kind_ == kDouble;
304 }
305 const char* Mnemonic() const;
306
307 private:
308 explicit Representation(Kind k) : kind_(k) { }
309
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000310 // Make sure kind fits in int8.
311 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
312
313 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000314};
315
316
317class HType {
318 public:
319 HType() : type_(kUninitialized) { }
320
321 static HType Tagged() { return HType(kTagged); }
322 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
323 static HType TaggedNumber() { return HType(kTaggedNumber); }
324 static HType Smi() { return HType(kSmi); }
325 static HType HeapNumber() { return HType(kHeapNumber); }
326 static HType String() { return HType(kString); }
327 static HType Boolean() { return HType(kBoolean); }
328 static HType NonPrimitive() { return HType(kNonPrimitive); }
329 static HType JSArray() { return HType(kJSArray); }
330 static HType JSObject() { return HType(kJSObject); }
331 static HType Uninitialized() { return HType(kUninitialized); }
332
333 // Return the weakest (least precise) common type.
334 HType Combine(HType other) {
335 return HType(static_cast<Type>(type_ & other.type_));
336 }
337
338 bool Equals(const HType& other) {
339 return type_ == other.type_;
340 }
341
342 bool IsSubtypeOf(const HType& other) {
343 return Combine(other).Equals(other);
344 }
345
346 bool IsTagged() {
347 ASSERT(type_ != kUninitialized);
348 return ((type_ & kTagged) == kTagged);
349 }
350
351 bool IsTaggedPrimitive() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
354 }
355
356 bool IsTaggedNumber() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kTaggedNumber) == kTaggedNumber);
359 }
360
361 bool IsSmi() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kSmi) == kSmi);
364 }
365
366 bool IsHeapNumber() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kHeapNumber) == kHeapNumber);
369 }
370
371 bool IsString() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kString) == kString);
374 }
375
376 bool IsBoolean() {
377 ASSERT(type_ != kUninitialized);
378 return ((type_ & kBoolean) == kBoolean);
379 }
380
381 bool IsNonPrimitive() {
382 ASSERT(type_ != kUninitialized);
383 return ((type_ & kNonPrimitive) == kNonPrimitive);
384 }
385
386 bool IsJSArray() {
387 ASSERT(type_ != kUninitialized);
388 return ((type_ & kJSArray) == kJSArray);
389 }
390
391 bool IsJSObject() {
392 ASSERT(type_ != kUninitialized);
393 return ((type_ & kJSObject) == kJSObject);
394 }
395
396 bool IsUninitialized() {
397 return type_ == kUninitialized;
398 }
399
400 static HType TypeFromValue(Handle<Object> value);
401
402 const char* ToString();
403 const char* ToShortString();
404
405 private:
406 enum Type {
407 kTagged = 0x1, // 0000 0000 0000 0001
408 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
409 kTaggedNumber = 0xd, // 0000 0000 0000 1101
410 kSmi = 0x1d, // 0000 0000 0001 1101
411 kHeapNumber = 0x2d, // 0000 0000 0010 1101
412 kString = 0x45, // 0000 0000 0100 0101
413 kBoolean = 0x85, // 0000 0000 1000 0101
414 kNonPrimitive = 0x101, // 0000 0001 0000 0001
415 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000416 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000417 kUninitialized = 0x1fff // 0001 1111 1111 1111
418 };
419
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000420 // Make sure type fits in int16.
421 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
422
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000423 explicit HType(Type t) : type_(t) { }
424
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000425 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000426};
427
428
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000429class HUseListNode: public ZoneObject {
430 public:
431 HUseListNode(HValue* value, int index, HUseListNode* tail)
432 : tail_(tail), value_(value), index_(index) {
433 }
434
435 HUseListNode* tail() const { return tail_; }
436 HValue* value() const { return value_; }
437 int index() const { return index_; }
438
439 void set_tail(HUseListNode* list) { tail_ = list; }
440
441#ifdef DEBUG
442 void Zap() {
443 tail_ = reinterpret_cast<HUseListNode*>(1);
444 value_ = NULL;
445 index_ = -1;
446 }
447#endif
448
449 private:
450 HUseListNode* tail_;
451 HValue* value_;
452 int index_;
453};
454
455
456// We reuse use list nodes behind the scenes as uses are added and deleted.
457// This class is the safe way to iterate uses while deleting them.
458class HUseIterator BASE_EMBEDDED {
459 public:
460 bool Done() { return current_ == NULL; }
461 void Advance();
462
463 HValue* value() {
464 ASSERT(!Done());
465 return value_;
466 }
467
468 int index() {
469 ASSERT(!Done());
470 return index_;
471 }
472
473 private:
474 explicit HUseIterator(HUseListNode* head);
475
476 HUseListNode* current_;
477 HUseListNode* next_;
478 HValue* value_;
479 int index_;
480
481 friend class HValue;
482};
483
484
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000485class HValue: public ZoneObject {
486 public:
487 static const int kNoNumber = -1;
488
489 // There must be one corresponding kDepends flag for every kChanges flag and
490 // the order of the kChanges flags must be exactly the same as of the kDepends
491 // flags.
492 enum Flag {
493 // Declare global value numbering flags.
494 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
495 GVN_FLAG_LIST(DECLARE_DO)
496 #undef DECLARE_DO
497 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000498 // Participate in Global Value Numbering, i.e. elimination of
499 // unnecessary recomputations. If an instruction sets this flag, it must
500 // implement DataEquals(), which will be used to determine if other
501 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000502 kUseGVN,
503 kCanOverflow,
504 kBailoutOnMinusZero,
505 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000506 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000507 kIsArguments,
508 kTruncatingToInt32,
509 kLastFlag = kTruncatingToInt32
510 };
511
512 STATIC_ASSERT(kLastFlag < kBitsPerInt);
513
514 static const int kChangesToDependsFlagsLeftShift = 1;
515
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000516 static int ConvertChangesToDependsFlags(int flags) {
517 return flags << kChangesToDependsFlagsLeftShift;
518 }
519
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000520 static HValue* cast(HValue* value) { return value; }
521
522 enum Opcode {
523 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000524 #define DECLARE_OPCODE(type) k##type,
525 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
526 kPhi
527 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000528 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000529 virtual Opcode opcode() const = 0;
530
531 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
532 #define DECLARE_PREDICATE(type) \
533 bool Is##type() const { return opcode() == k##type; }
534 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
535 #undef DECLARE_PREDICATE
536 bool IsPhi() const { return opcode() == kPhi; }
537
538 // Declare virtual predicates for abstract HInstruction or HValue
539 #define DECLARE_PREDICATE(type) \
540 virtual bool Is##type() const { return false; }
541 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
542 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000543
544 HValue() : block_(NULL),
545 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000546 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000547 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000548 range_(NULL),
549 flags_(0) {}
550 virtual ~HValue() {}
551
552 HBasicBlock* block() const { return block_; }
553 void SetBlock(HBasicBlock* block);
554
555 int id() const { return id_; }
556 void set_id(int id) { id_ = id; }
557
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000558 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000560 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000561 Representation representation() const { return representation_; }
562 void ChangeRepresentation(Representation r) {
563 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564 ASSERT(!r.IsNone());
565 ASSERT(CheckFlag(kFlexibleRepresentation));
566 RepresentationChanged(r);
567 representation_ = r;
568 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000569 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000570
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000571 virtual bool IsConvertibleToInteger() const { return true; }
572
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000573 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000574 void set_type(HType new_type) {
575 ASSERT(new_type.IsSubtypeOf(type_));
576 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577 }
578
579 // An operation needs to override this function iff:
580 // 1) it can produce an int32 output.
581 // 2) the true value of its output can potentially be minus zero.
582 // The implementation must set a flag so that it bails out in the case where
583 // it would otherwise output what should be a minus zero as an int32 zero.
584 // If the operation also exists in a form that takes int32 and outputs int32
585 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000586 // back. There are three operations that need to propagate back to more than
587 // one input. They are phi and binary div and mul. They always return NULL
588 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000589 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
590 visited->Add(id());
591 return NULL;
592 }
593
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000594 bool IsDefinedAfter(HBasicBlock* other) const;
595
596 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000597 virtual int OperandCount() = 0;
598 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599 void SetOperandAt(int index, HValue* value);
600
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000601 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000602 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000603 bool HasNoUses() const { return use_list_ == NULL; }
604 bool HasMultipleUses() const {
605 return use_list_ != NULL && use_list_->tail() != NULL;
606 }
607 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000608 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000609
610 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000611 void SetFlag(Flag f) { flags_ |= (1 << f); }
612 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
613 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
614
615 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
616 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
617 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000618
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000619 int ChangesFlags() const { return flags_ & ChangesFlagsMask(); }
620
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000621 Range* range() const { return range_; }
622 bool HasRange() const { return range_ != NULL; }
623 void AddNewRange(Range* r);
624 void RemoveLastAddedRange();
625 void ComputeInitialRange();
626
627 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000628 virtual Representation RequiredInputRepresentation(int index) const = 0;
629
630 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000631 return representation();
632 }
633
634 // This gives the instruction an opportunity to replace itself with an
635 // instruction that does the same in some better way. To replace an
636 // instruction with a new one, first add the new instruction to the graph,
637 // then return it. Return NULL to have the instruction deleted.
638 virtual HValue* Canonicalize() { return this; }
639
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000640 bool Equals(HValue* other);
641 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000642
643 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000644 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000646 void PrintTypeTo(StringStream* stream);
647 void PrintRangeTo(StringStream* stream);
648 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000649
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000650 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000651
652 // Updated the inferred type of this instruction and returns true if
653 // it has changed.
654 bool UpdateInferredType();
655
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000656 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000657
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000658#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000659 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660#endif
661
662 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000663 // This function must be overridden for instructions with flag kUseGVN, to
664 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000665 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000666 UNREACHABLE();
667 return false;
668 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000669 virtual void RepresentationChanged(Representation to) { }
670 virtual Range* InferRange();
671 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000672 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000673 void clear_block() {
674 ASSERT(block_ != NULL);
675 block_ = NULL;
676 }
677
678 void set_representation(Representation r) {
679 // Representation is set-once.
680 ASSERT(representation_.IsNone() && !r.IsNone());
681 representation_ = r;
682 }
683
684 private:
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000685 static int ChangesFlagsMask() {
686 int result = 0;
687 // Create changes mask.
688#define ADD_FLAG(type) result |= (1 << kChanges##type);
689 GVN_FLAG_LIST(ADD_FLAG)
690#undef ADD_FLAG
691 return result;
692 }
693
ager@chromium.org378b34e2011-01-28 08:04:38 +0000694 // A flag mask to mark an instruction as having arbitrary side effects.
695 static int AllSideEffects() {
696 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
697 }
698
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000699 // Remove the matching use from the use list if present. Returns the
700 // removed list node or NULL.
701 HUseListNode* RemoveUse(HValue* value, int index);
702
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000703 void RegisterUse(int index, HValue* new_value);
704
705 HBasicBlock* block_;
706
707 // The id of this instruction in the hydrogen graph, assigned when first
708 // added to the graph. Reflects creation order.
709 int id_;
710
711 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000712 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000713 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000714 Range* range_;
715 int flags_;
716
717 DISALLOW_COPY_AND_ASSIGN(HValue);
718};
719
720
721class HInstruction: public HValue {
722 public:
723 HInstruction* next() const { return next_; }
724 HInstruction* previous() const { return previous_; }
725
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000726 virtual void PrintTo(StringStream* stream);
727 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000728
729 bool IsLinked() const { return block() != NULL; }
730 void Unlink();
731 void InsertBefore(HInstruction* next);
732 void InsertAfter(HInstruction* previous);
733
734 int position() const { return position_; }
735 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
736 void set_position(int position) { position_ = position; }
737
738 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
739
740#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000741 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000742#endif
743
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000744 virtual bool IsCall() { return false; }
745
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000746 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000747
748 protected:
749 HInstruction()
750 : next_(NULL),
751 previous_(NULL),
752 position_(RelocInfo::kNoPosition) {
753 SetFlag(kDependsOnOsrEntries);
754 }
755
756 virtual void DeleteFromGraph() { Unlink(); }
757
758 private:
759 void InitializeAsFirst(HBasicBlock* block) {
760 ASSERT(!IsLinked());
761 SetBlock(block);
762 }
763
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000764 void PrintMnemonicTo(StringStream* stream);
765
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000766 HInstruction* next_;
767 HInstruction* previous_;
768 int position_;
769
770 friend class HBasicBlock;
771};
772
773
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000774template<int V>
775class HTemplateInstruction : public HInstruction {
776 public:
777 int OperandCount() { return V; }
778 HValue* OperandAt(int i) { return inputs_[i]; }
779
780 protected:
781 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
782
783 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000784 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000785};
786
787
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000788class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000789 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000790 virtual HBasicBlock* SuccessorAt(int i) = 0;
791 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000792 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000793
794 virtual void PrintDataTo(StringStream* stream);
795
796 HBasicBlock* FirstSuccessor() {
797 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
798 }
799 HBasicBlock* SecondSuccessor() {
800 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
801 }
802
803 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
804};
805
806
807class HSuccessorIterator BASE_EMBEDDED {
808 public:
809 explicit HSuccessorIterator(HControlInstruction* instr)
810 : instr_(instr), current_(0) { }
811
812 bool Done() { return current_ >= instr_->SuccessorCount(); }
813 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
814 void Advance() { current_++; }
815
816 private:
817 HControlInstruction* instr_;
818 int current_;
819};
820
821
822template<int S, int V>
823class HTemplateControlInstruction: public HControlInstruction {
824 public:
825 int SuccessorCount() { return S; }
826 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000827 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000829 int OperandCount() { return V; }
830 HValue* OperandAt(int i) { return inputs_[i]; }
831
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000832
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000833 protected:
834 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
835
836 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000837 EmbeddedContainer<HBasicBlock*, S> successors_;
838 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000839};
840
841
842class HBlockEntry: public HTemplateInstruction<0> {
843 public:
844 virtual Representation RequiredInputRepresentation(int index) const {
845 return Representation::None();
846 }
847
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000848 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000849};
850
851
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000852// We insert soft-deoptimize when we hit code with unknown typefeedback,
853// so that we get a chance of re-optimizing with useful typefeedback.
854// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
855class HSoftDeoptimize: public HTemplateInstruction<0> {
856 public:
857 virtual Representation RequiredInputRepresentation(int index) const {
858 return Representation::None();
859 }
860
861 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
862};
863
864
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000865class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000866 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000867 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868
869 virtual Representation RequiredInputRepresentation(int index) const {
870 return Representation::None();
871 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000872
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000873 virtual int OperandCount() { return values_.length(); }
874 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000875 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000876
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000877 virtual int SuccessorCount() { return 0; }
878 virtual HBasicBlock* SuccessorAt(int i) {
879 UNREACHABLE();
880 return NULL;
881 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000882 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
883 UNREACHABLE();
884 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000885
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886 void AddEnvironmentValue(HValue* value) {
887 values_.Add(NULL);
888 SetOperandAt(values_.length() - 1, value);
889 }
890
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000891 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000892
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000893 enum UseEnvironment {
894 kNoUses,
895 kUseAll
896 };
897
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000898 protected:
899 virtual void InternalSetOperandAt(int index, HValue* value) {
900 values_[index] = value;
901 }
902
903 private:
904 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000905};
906
907
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000908class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000910 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000911 SetSuccessorAt(0, target);
912 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000914 virtual Representation RequiredInputRepresentation(int index) const {
915 return Representation::None();
916 }
917
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000918 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919};
920
921
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000922class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000924 HUnaryControlInstruction(HValue* value,
925 HBasicBlock* true_target,
926 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000928 SetSuccessorAt(0, true_target);
929 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930 }
931
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000932 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000934 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935};
936
937
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000938class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000939 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000940 HBranch(HValue* value,
941 HBasicBlock* true_target,
942 HBasicBlock* false_target,
943 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
944 : HUnaryControlInstruction(value, true_target, false_target),
945 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000946 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000948 explicit HBranch(HValue* value)
949 : HUnaryControlInstruction(value, NULL, NULL) { }
950
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000951
952 virtual Representation RequiredInputRepresentation(int index) const {
953 return Representation::None();
954 }
955
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000956 ToBooleanStub::Types expected_input_types() const {
957 return expected_input_types_;
958 }
959
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000960 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000961
962 private:
963 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964};
965
966
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000967class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000968 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000969 HCompareMap(HValue* value,
970 Handle<Map> map,
971 HBasicBlock* true_target,
972 HBasicBlock* false_target)
973 : HUnaryControlInstruction(value, true_target, false_target),
974 map_(map) {
975 ASSERT(true_target != NULL);
976 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000977 ASSERT(!map.is_null());
978 }
979
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000980 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000981
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000982 Handle<Map> map() const { return map_; }
983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000984 virtual Representation RequiredInputRepresentation(int index) const {
985 return Representation::Tagged();
986 }
987
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000988 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000989
990 private:
991 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000992};
993
994
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000995class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000997 explicit HReturn(HValue* value) {
998 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000999 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001001 virtual Representation RequiredInputRepresentation(int index) const {
1002 return Representation::Tagged();
1003 }
1004
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001005 virtual void PrintDataTo(StringStream* stream);
1006
1007 HValue* value() { return OperandAt(0); }
1008
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001009 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001010};
1011
1012
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001013class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001014 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001015 virtual Representation RequiredInputRepresentation(int index) const {
1016 return Representation::None();
1017 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001018
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001019 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020};
1021
1022
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001023class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001024 public:
1025 explicit HUnaryOperation(HValue* value) {
1026 SetOperandAt(0, value);
1027 }
1028
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001029 static HUnaryOperation* cast(HValue* value) {
1030 return reinterpret_cast<HUnaryOperation*>(value);
1031 }
1032
1033 virtual bool CanTruncateToInt32() const {
1034 return CheckFlag(kTruncatingToInt32);
1035 }
1036
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001037 HValue* value() { return OperandAt(0); }
1038 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039};
1040
1041
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001042class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001043 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001044 HThrow(HValue* context, HValue* value) {
1045 SetOperandAt(0, context);
1046 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001047 SetAllSideEffects();
1048 }
1049
1050 virtual Representation RequiredInputRepresentation(int index) const {
1051 return Representation::Tagged();
1052 }
1053
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001054 HValue* context() { return OperandAt(0); }
1055 HValue* value() { return OperandAt(1); }
1056
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001057 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001058};
1059
1060
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001061class HUseConst: public HUnaryOperation {
1062 public:
1063 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1064
1065 virtual Representation RequiredInputRepresentation(int index) const {
1066 return Representation::None();
1067 }
1068
1069 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1070};
1071
1072
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001073class HForceRepresentation: public HTemplateInstruction<1> {
1074 public:
1075 HForceRepresentation(HValue* value, Representation required_representation) {
1076 SetOperandAt(0, value);
1077 set_representation(required_representation);
1078 }
1079
1080 HValue* value() { return OperandAt(0); }
1081
1082 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1083
1084 virtual Representation RequiredInputRepresentation(int index) const {
1085 return representation(); // Same as the output representation.
1086 }
1087
1088 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1089};
1090
1091
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001092class HChange: public HUnaryOperation {
1093 public:
1094 HChange(HValue* value,
1095 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001096 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001097 bool is_truncating,
1098 bool deoptimize_on_undefined)
1099 : HUnaryOperation(value),
1100 from_(from),
1101 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001102 ASSERT(!from.IsNone() && !to.IsNone());
1103 ASSERT(!from.Equals(to));
1104 set_representation(to);
1105 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001106 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001107 }
1108
1109 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1110
1111 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001112 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001113 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001114 virtual Representation RequiredInputRepresentation(int index) const {
1115 return from_;
1116 }
1117
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001118 virtual Range* InferRange();
1119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001120 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001121
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001122 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001123
1124 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001125 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126 if (!other->IsChange()) return false;
1127 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001128 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001129 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001130 }
1131
1132 private:
1133 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001134 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001135};
1136
1137
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001138class HClampToUint8: public HUnaryOperation {
1139 public:
1140 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001141 : HUnaryOperation(value) {
1142 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001143 SetFlag(kUseGVN);
1144 }
1145
1146 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001147 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001148 }
1149
1150 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1151
1152 protected:
1153 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001154};
1155
1156
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001157class HToInt32: public HUnaryOperation {
1158 public:
1159 explicit HToInt32(HValue* value)
1160 : HUnaryOperation(value) {
1161 set_representation(Representation::Integer32());
1162 SetFlag(kUseGVN);
1163 }
1164
1165 virtual Representation RequiredInputRepresentation(int index) const {
1166 return Representation::None();
1167 }
1168
1169 virtual bool CanTruncateToInt32() const {
1170 return true;
1171 }
1172
1173 virtual HValue* Canonicalize() {
1174 if (value()->representation().IsInteger32()) {
1175 return value();
1176 } else {
1177 return this;
1178 }
1179 }
1180
1181 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1182
1183 protected:
1184 virtual bool DataEquals(HValue* other) { return true; }
1185};
1186
1187
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001188class HSimulate: public HInstruction {
1189 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001190 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001191 : ast_id_(ast_id),
1192 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193 values_(2),
1194 assigned_indexes_(2) {}
1195 virtual ~HSimulate() {}
1196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001197 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001198
1199 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1200 int ast_id() const { return ast_id_; }
1201 void set_ast_id(int id) {
1202 ASSERT(!HasAstId());
1203 ast_id_ = id;
1204 }
1205
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001206 int pop_count() const { return pop_count_; }
1207 const ZoneList<HValue*>* values() const { return &values_; }
1208 int GetAssignedIndexAt(int index) const {
1209 ASSERT(HasAssignedIndexAt(index));
1210 return assigned_indexes_[index];
1211 }
1212 bool HasAssignedIndexAt(int index) const {
1213 return assigned_indexes_[index] != kNoIndex;
1214 }
1215 void AddAssignedValue(int index, HValue* value) {
1216 AddValue(index, value);
1217 }
1218 void AddPushedValue(HValue* value) {
1219 AddValue(kNoIndex, value);
1220 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001221 virtual int OperandCount() { return values_.length(); }
1222 virtual HValue* OperandAt(int index) { return values_[index]; }
1223
1224 virtual Representation RequiredInputRepresentation(int index) const {
1225 return Representation::None();
1226 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001227
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001228 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001229
1230#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001231 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001232#endif
1233
1234 protected:
1235 virtual void InternalSetOperandAt(int index, HValue* value) {
1236 values_[index] = value;
1237 }
1238
1239 private:
1240 static const int kNoIndex = -1;
1241 void AddValue(int index, HValue* value) {
1242 assigned_indexes_.Add(index);
1243 // Resize the list of pushed values.
1244 values_.Add(NULL);
1245 // Set the operand through the base method in HValue to make sure that the
1246 // use lists are correctly updated.
1247 SetOperandAt(values_.length() - 1, value);
1248 }
1249 int ast_id_;
1250 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001251 ZoneList<HValue*> values_;
1252 ZoneList<int> assigned_indexes_;
1253};
1254
1255
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001256class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001258 enum Type {
1259 kFunctionEntry,
1260 kBackwardsBranch
1261 };
1262
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001263 HStackCheck(HValue* context, Type type) : type_(type) {
1264 SetOperandAt(0, context);
1265 }
1266
1267 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001269 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001270 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001271 }
1272
ager@chromium.org04921a82011-06-27 13:21:41 +00001273 void Eliminate() {
1274 // The stack check eliminator might try to eliminate the same stack
1275 // check instruction multiple times.
1276 if (IsLinked()) {
1277 DeleteFromGraph();
1278 }
1279 }
1280
1281 bool is_function_entry() { return type_ == kFunctionEntry; }
1282 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1283
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001284 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001285
1286 private:
1287 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001288};
1289
1290
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001291class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001292 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001293 HEnterInlined(Handle<JSFunction> closure,
1294 FunctionLiteral* function,
1295 CallKind call_kind)
1296 : closure_(closure),
1297 function_(function),
1298 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001299 }
1300
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001301 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302
1303 Handle<JSFunction> closure() const { return closure_; }
1304 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001305 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307 virtual Representation RequiredInputRepresentation(int index) const {
1308 return Representation::None();
1309 }
1310
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001311 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312
1313 private:
1314 Handle<JSFunction> closure_;
1315 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001316 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001317};
1318
1319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001320class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001321 public:
1322 HLeaveInlined() {}
1323
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324 virtual Representation RequiredInputRepresentation(int index) const {
1325 return Representation::None();
1326 }
1327
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001328 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329};
1330
1331
1332class HPushArgument: public HUnaryOperation {
1333 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001334 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1335 set_representation(Representation::Tagged());
1336 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001337
1338 virtual Representation RequiredInputRepresentation(int index) const {
1339 return Representation::Tagged();
1340 }
1341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001342 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001344 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345};
1346
1347
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001348class HThisFunction: public HTemplateInstruction<0> {
1349 public:
1350 HThisFunction() {
1351 set_representation(Representation::Tagged());
1352 SetFlag(kUseGVN);
1353 }
1354
1355 virtual Representation RequiredInputRepresentation(int index) const {
1356 return Representation::None();
1357 }
1358
1359 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1360
1361 protected:
1362 virtual bool DataEquals(HValue* other) { return true; }
1363};
1364
1365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001366class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001368 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001369 set_representation(Representation::Tagged());
1370 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001371 }
1372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001373 virtual Representation RequiredInputRepresentation(int index) const {
1374 return Representation::None();
1375 }
1376
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001377 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001378
1379 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001380 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001381};
1382
1383
1384class HOuterContext: public HUnaryOperation {
1385 public:
1386 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1387 set_representation(Representation::Tagged());
1388 SetFlag(kUseGVN);
1389 }
1390
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001391 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001393 virtual Representation RequiredInputRepresentation(int index) const {
1394 return Representation::Tagged();
1395 }
1396
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001397 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001398 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001399};
1400
1401
1402class HGlobalObject: public HUnaryOperation {
1403 public:
1404 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1405 set_representation(Representation::Tagged());
1406 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407 }
1408
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001409 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001411 virtual Representation RequiredInputRepresentation(int index) const {
1412 return Representation::Tagged();
1413 }
1414
ager@chromium.org378b34e2011-01-28 08:04:38 +00001415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001416 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001417};
1418
1419
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001420class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001422 explicit HGlobalReceiver(HValue* global_object)
1423 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 set_representation(Representation::Tagged());
1425 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001426 }
1427
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001428 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001429
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001430 virtual Representation RequiredInputRepresentation(int index) const {
1431 return Representation::Tagged();
1432 }
1433
ager@chromium.org378b34e2011-01-28 08:04:38 +00001434 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001435 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001436};
1437
1438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439template <int V>
1440class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001442 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001443 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1444 this->set_representation(Representation::Tagged());
1445 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001446 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001448 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001450 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001451
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001452 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001454 private:
1455 int argument_count_;
1456};
1457
1458
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001459class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001460 public:
1461 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001462 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001463 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464 }
1465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 virtual Representation RequiredInputRepresentation(int index) const {
1467 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001468 }
1469
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001470 virtual void PrintDataTo(StringStream* stream);
1471
1472 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001473};
1474
1475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001477 public:
1478 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001479 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001480 SetOperandAt(0, first);
1481 SetOperandAt(1, second);
1482 }
1483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001484 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001485
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001486 virtual Representation RequiredInputRepresentation(int index) const {
1487 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001488 }
1489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001490 HValue* first() { return OperandAt(0); }
1491 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492};
1493
1494
danno@chromium.org160a7b02011-04-18 15:51:38 +00001495class HInvokeFunction: public HBinaryCall {
1496 public:
1497 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1498 : HBinaryCall(context, function, argument_count) {
1499 }
1500
1501 virtual Representation RequiredInputRepresentation(int index) const {
1502 return Representation::Tagged();
1503 }
1504
1505 HValue* context() { return first(); }
1506 HValue* function() { return second(); }
1507
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001508 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001509};
1510
1511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001512class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513 public:
1514 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001515 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516
1517 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001518
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001521 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522 }
1523
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001524 virtual void PrintDataTo(StringStream* stream);
1525
1526 virtual Representation RequiredInputRepresentation(int index) const {
1527 return Representation::None();
1528 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001530 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531
1532 private:
1533 Handle<JSFunction> function_;
1534};
1535
1536
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001537class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001539 HCallKeyed(HValue* context, HValue* key, int argument_count)
1540 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001541 }
1542
1543 virtual Representation RequiredInputRepresentation(int index) const {
1544 return Representation::Tagged();
1545 }
1546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001547 HValue* context() { return first(); }
1548 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001549
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001550 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551};
1552
1553
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001554class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001556 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1557 : HUnaryCall(context, argument_count), name_(name) {
1558 }
1559
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001560 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001562 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563 Handle<String> name() const { return name_; }
1564
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001565 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001567 virtual Representation RequiredInputRepresentation(int index) const {
1568 return Representation::Tagged();
1569 }
1570
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001571 private:
1572 Handle<String> name_;
1573};
1574
1575
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001576class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001578 HCallFunction(HValue* context, int argument_count)
1579 : HUnaryCall(context, argument_count) {
1580 }
1581
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001582 HValue* context() { return value(); }
1583
1584 virtual Representation RequiredInputRepresentation(int index) const {
1585 return Representation::Tagged();
1586 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001588 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001589};
1590
1591
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001592class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001594 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1595 : HUnaryCall(context, argument_count), name_(name) {
1596 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001598 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001600 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601 Handle<String> name() const { return name_; }
1602
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001603 virtual Representation RequiredInputRepresentation(int index) const {
1604 return Representation::Tagged();
1605 }
1606
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001607 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608
1609 private:
1610 Handle<String> name_;
1611};
1612
1613
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001614class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001616 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001617 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001619 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001620
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621 Handle<JSFunction> target() const { return target_; }
1622
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 virtual Representation RequiredInputRepresentation(int index) const {
1624 return Representation::None();
1625 }
1626
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001627 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628
1629 private:
1630 Handle<JSFunction> target_;
1631};
1632
1633
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001634class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001635 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001636 HCallNew(HValue* context, HValue* constructor, int argument_count)
1637 : HBinaryCall(context, constructor, argument_count) {
1638 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639
1640 virtual Representation RequiredInputRepresentation(int index) const {
1641 return Representation::Tagged();
1642 }
1643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001644 HValue* context() { return first(); }
1645 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001647 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001648};
1649
1650
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001651class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001653 HCallRuntime(HValue* context,
1654 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001655 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001656 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001657 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1658 SetOperandAt(0, context);
1659 }
1660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001661 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001662
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001663 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001664 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001665 Handle<String> name() const { return name_; }
1666
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001667 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001668 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001669 }
1670
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001671 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001672
1673 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001674 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001675 Handle<String> name_;
1676};
1677
1678
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001679class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001680 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001681 HJSArrayLength(HValue* value, HValue* typecheck) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682 // The length of an array is stored as a tagged value in the array
1683 // object. It is guaranteed to be 32 bit integer, but it can be
1684 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001685 SetOperandAt(0, value);
1686 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001687 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001688 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001689 SetFlag(kDependsOnArrayLengths);
1690 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001691 }
1692
1693 virtual Representation RequiredInputRepresentation(int index) const {
1694 return Representation::Tagged();
1695 }
1696
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001697 virtual void PrintDataTo(StringStream* stream);
1698
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001699 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001700 HValue* typecheck() { return OperandAt(1); }
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001701
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001702 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001703
1704 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001705 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001706};
1707
1708
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001709class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001710 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001711 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001712 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001713 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001714 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001715 }
1716
1717 virtual Representation RequiredInputRepresentation(int index) const {
1718 return Representation::Tagged();
1719 }
1720
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001721 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001722
1723 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001724 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001725};
1726
1727
whesse@chromium.org7b260152011-06-20 15:33:18 +00001728class HElementsKind: public HUnaryOperation {
1729 public:
1730 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1731 set_representation(Representation::Integer32());
1732 SetFlag(kUseGVN);
1733 SetFlag(kDependsOnMaps);
1734 }
1735
1736 virtual Representation RequiredInputRepresentation(int index) const {
1737 return Representation::Tagged();
1738 }
1739
1740 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1741
1742 protected:
1743 virtual bool DataEquals(HValue* other) { return true; }
1744};
1745
1746
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001747class HBitNot: public HUnaryOperation {
1748 public:
1749 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1750 set_representation(Representation::Integer32());
1751 SetFlag(kUseGVN);
1752 SetFlag(kTruncatingToInt32);
1753 }
1754
1755 virtual Representation RequiredInputRepresentation(int index) const {
1756 return Representation::Integer32();
1757 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001758 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001759
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001760 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001761
1762 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001763 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001764};
1765
1766
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001767class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001768 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001769 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1770 : op_(op) {
1771 SetOperandAt(0, context);
1772 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001773 switch (op) {
1774 case kMathFloor:
1775 case kMathRound:
1776 case kMathCeil:
1777 set_representation(Representation::Integer32());
1778 break;
1779 case kMathAbs:
1780 set_representation(Representation::Tagged());
1781 SetFlag(kFlexibleRepresentation);
1782 break;
1783 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001784 case kMathPowHalf:
1785 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001786 case kMathSin:
1787 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001789 break;
1790 default:
1791 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001792 }
1793 SetFlag(kUseGVN);
1794 }
1795
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001796 HValue* context() { return OperandAt(0); }
1797 HValue* value() { return OperandAt(1); }
1798
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001799 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001800
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001801 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001802
1803 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1804
1805 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001806 if (index == 0) {
1807 return Representation::Tagged();
1808 } else {
1809 switch (op_) {
1810 case kMathFloor:
1811 case kMathRound:
1812 case kMathCeil:
1813 case kMathSqrt:
1814 case kMathPowHalf:
1815 case kMathLog:
1816 case kMathSin:
1817 case kMathCos:
1818 return Representation::Double();
1819 case kMathAbs:
1820 return representation();
1821 default:
1822 UNREACHABLE();
1823 return Representation::None();
1824 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001825 }
1826 }
1827
1828 virtual HValue* Canonicalize() {
1829 // If the input is integer32 then we replace the floor instruction
1830 // with its inputs. This happens before the representation changes are
1831 // introduced.
1832 if (op() == kMathFloor) {
1833 if (value()->representation().IsInteger32()) return value();
1834 }
1835 return this;
1836 }
1837
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001838 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839 const char* OpName() const;
1840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001841 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001842
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001843 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001844 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001845 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1846 return op_ == b->op();
1847 }
1848
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001849 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001850 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851};
1852
1853
1854class HLoadElements: public HUnaryOperation {
1855 public:
1856 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1857 set_representation(Representation::Tagged());
1858 SetFlag(kUseGVN);
1859 SetFlag(kDependsOnMaps);
1860 }
1861
1862 virtual Representation RequiredInputRepresentation(int index) const {
1863 return Representation::Tagged();
1864 }
1865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001866 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001867
1868 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001869 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001870};
1871
1872
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001873class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001874 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001875 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001876 : HUnaryOperation(value) {
1877 set_representation(Representation::External());
1878 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001879 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001880 // change once set, so it's no necessary to introduce any additional
1881 // dependencies on top of the inputs.
1882 SetFlag(kUseGVN);
1883 }
1884
1885 virtual Representation RequiredInputRepresentation(int index) const {
1886 return Representation::Tagged();
1887 }
1888
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001889 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001890
1891 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001892 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001893};
1894
1895
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001896class HCheckMap: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001897 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001898 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
1899 : map_(map) {
1900 SetOperandAt(0, value);
1901 // If callers don't depend on a typecheck, they can pass in NULL. In that
1902 // case we use a copy of the |value| argument as a dummy value.
1903 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001904 set_representation(Representation::Tagged());
1905 SetFlag(kUseGVN);
1906 SetFlag(kDependsOnMaps);
1907 }
1908
1909 virtual Representation RequiredInputRepresentation(int index) const {
1910 return Representation::Tagged();
1911 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001912 virtual void PrintDataTo(StringStream* stream);
1913 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001914
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001915 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916 Handle<Map> map() const { return map_; }
1917
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001918 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919
1920 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001921 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001922 HCheckMap* b = HCheckMap::cast(other);
1923 return map_.is_identical_to(b->map());
1924 }
1925
1926 private:
1927 Handle<Map> map_;
1928};
1929
1930
1931class HCheckFunction: public HUnaryOperation {
1932 public:
1933 HCheckFunction(HValue* value, Handle<JSFunction> function)
1934 : HUnaryOperation(value), target_(function) {
1935 set_representation(Representation::Tagged());
1936 SetFlag(kUseGVN);
1937 }
1938
1939 virtual Representation RequiredInputRepresentation(int index) const {
1940 return Representation::Tagged();
1941 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001942 virtual void PrintDataTo(StringStream* stream);
1943 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944
1945#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001946 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001947#endif
1948
1949 Handle<JSFunction> target() const { return target_; }
1950
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001951 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952
1953 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001954 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001955 HCheckFunction* b = HCheckFunction::cast(other);
1956 return target_.is_identical_to(b->target());
1957 }
1958
1959 private:
1960 Handle<JSFunction> target_;
1961};
1962
1963
1964class HCheckInstanceType: public HUnaryOperation {
1965 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001966 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1967 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001968 }
1969 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1970 return new HCheckInstanceType(value, IS_JS_ARRAY);
1971 }
1972 static HCheckInstanceType* NewIsString(HValue* value) {
1973 return new HCheckInstanceType(value, IS_STRING);
1974 }
1975 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1976 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977 }
1978
1979 virtual Representation RequiredInputRepresentation(int index) const {
1980 return Representation::Tagged();
1981 }
1982
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00001983 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00001984
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001985 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1986 void GetCheckInterval(InstanceType* first, InstanceType* last);
1987 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001988
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001989 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001990
1991 protected:
1992 // TODO(ager): It could be nice to allow the ommision of instance
1993 // type checks if we have already performed an instance type check
1994 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001995 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001997 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998 }
1999
2000 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002001 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002002 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002003 IS_JS_ARRAY,
2004 IS_STRING,
2005 IS_SYMBOL,
2006 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2007 };
2008
2009 HCheckInstanceType(HValue* value, Check check)
2010 : HUnaryOperation(value), check_(check) {
2011 set_representation(Representation::Tagged());
2012 SetFlag(kUseGVN);
2013 }
2014
2015 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002016};
2017
2018
2019class HCheckNonSmi: public HUnaryOperation {
2020 public:
2021 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2022 set_representation(Representation::Tagged());
2023 SetFlag(kUseGVN);
2024 }
2025
2026 virtual Representation RequiredInputRepresentation(int index) const {
2027 return Representation::Tagged();
2028 }
2029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002030 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031
2032#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002033 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002034#endif
2035
danno@chromium.org160a7b02011-04-18 15:51:38 +00002036 virtual HValue* Canonicalize() {
2037 HType value_type = value()->type();
2038 if (!value_type.IsUninitialized() &&
2039 (value_type.IsHeapNumber() ||
2040 value_type.IsString() ||
2041 value_type.IsBoolean() ||
2042 value_type.IsNonPrimitive())) {
2043 return NULL;
2044 }
2045 return this;
2046 }
2047
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002048 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002049
2050 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002051 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052};
2053
2054
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002055class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002057 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2058 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002059 SetFlag(kUseGVN);
2060 SetFlag(kDependsOnMaps);
2061 }
2062
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002064 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002065#endif
2066
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002067 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002068 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002069
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002070 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002072 virtual Representation RequiredInputRepresentation(int index) const {
2073 return Representation::None();
2074 }
2075
2076 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002077 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002078 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2079 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2080 return hash;
2081 }
2082
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002083 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002084 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002085 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002086 return prototype_.is_identical_to(b->prototype()) &&
2087 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088 }
2089
2090 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002091 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002093};
2094
2095
2096class HCheckSmi: public HUnaryOperation {
2097 public:
2098 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2099 set_representation(Representation::Tagged());
2100 SetFlag(kUseGVN);
2101 }
2102
2103 virtual Representation RequiredInputRepresentation(int index) const {
2104 return Representation::Tagged();
2105 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002106 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002107
2108#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002109 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002110#endif
2111
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002112 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002113
2114 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002115 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116};
2117
2118
2119class HPhi: public HValue {
2120 public:
2121 explicit HPhi(int merged_index)
2122 : inputs_(2),
2123 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002124 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002125 is_live_(false),
2126 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002127 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2128 non_phi_uses_[i] = 0;
2129 indirect_uses_[i] = 0;
2130 }
2131 ASSERT(merged_index >= 0);
2132 set_representation(Representation::Tagged());
2133 SetFlag(kFlexibleRepresentation);
2134 }
2135
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002136 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002137 bool double_occurred = false;
2138 bool int32_occurred = false;
2139 for (int i = 0; i < OperandCount(); ++i) {
2140 HValue* value = OperandAt(i);
2141 if (value->representation().IsDouble()) double_occurred = true;
2142 if (value->representation().IsInteger32()) int32_occurred = true;
2143 if (value->representation().IsTagged()) return Representation::Tagged();
2144 }
2145
2146 if (double_occurred) return Representation::Double();
2147 if (int32_occurred) return Representation::Integer32();
2148 return Representation::None();
2149 }
2150
2151 virtual Range* InferRange();
2152 virtual Representation RequiredInputRepresentation(int index) const {
2153 return representation();
2154 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002155 virtual HType CalculateInferredType();
2156 virtual int OperandCount() { return inputs_.length(); }
2157 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2158 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002160 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002162 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002163
2164 int merged_index() const { return merged_index_; }
2165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002166 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167
2168#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002169 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002170#endif
2171
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002172 void InitRealUses(int id);
2173 void AddNonPhiUsesFrom(HPhi* other);
2174 void AddIndirectUsesTo(int* use_count);
2175
2176 int tagged_non_phi_uses() const {
2177 return non_phi_uses_[Representation::kTagged];
2178 }
2179 int int32_non_phi_uses() const {
2180 return non_phi_uses_[Representation::kInteger32];
2181 }
2182 int double_non_phi_uses() const {
2183 return non_phi_uses_[Representation::kDouble];
2184 }
2185 int tagged_indirect_uses() const {
2186 return indirect_uses_[Representation::kTagged];
2187 }
2188 int int32_indirect_uses() const {
2189 return indirect_uses_[Representation::kInteger32];
2190 }
2191 int double_indirect_uses() const {
2192 return indirect_uses_[Representation::kDouble];
2193 }
2194 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002195 bool is_live() { return is_live_; }
2196 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002197
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002198 static HPhi* cast(HValue* value) {
2199 ASSERT(value->IsPhi());
2200 return reinterpret_cast<HPhi*>(value);
2201 }
2202 virtual Opcode opcode() const { return HValue::kPhi; }
2203
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002204 virtual bool IsConvertibleToInteger() const {
2205 return is_convertible_to_integer_;
2206 }
2207
2208 void set_is_convertible_to_integer(bool b) {
2209 is_convertible_to_integer_ = b;
2210 }
2211
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002212 protected:
2213 virtual void DeleteFromGraph();
2214 virtual void InternalSetOperandAt(int index, HValue* value) {
2215 inputs_[index] = value;
2216 }
2217
2218 private:
2219 ZoneList<HValue*> inputs_;
2220 int merged_index_;
2221
2222 int non_phi_uses_[Representation::kNumRepresentations];
2223 int indirect_uses_[Representation::kNumRepresentations];
2224 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002225 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002226 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227};
2228
2229
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002230class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002231 public:
2232 HArgumentsObject() {
2233 set_representation(Representation::Tagged());
2234 SetFlag(kIsArguments);
2235 }
2236
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002237 virtual Representation RequiredInputRepresentation(int index) const {
2238 return Representation::None();
2239 }
2240
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002241 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002242};
2243
2244
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002245class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002246 public:
2247 HConstant(Handle<Object> handle, Representation r);
2248
2249 Handle<Object> handle() const { return handle_; }
2250
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002251 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002252
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002253 virtual Representation RequiredInputRepresentation(int index) const {
2254 return Representation::None();
2255 }
2256
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002257 virtual bool IsConvertibleToInteger() const {
2258 if (handle_->IsSmi()) return true;
2259 if (handle_->IsHeapNumber() &&
2260 (HeapNumber::cast(*handle_)->value() ==
2261 static_cast<double>(NumberToInt32(*handle_)))) return true;
2262 return false;
2263 }
2264
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002265 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002266 virtual void PrintDataTo(StringStream* stream);
2267 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002268 bool IsInteger() const { return handle_->IsSmi(); }
2269 HConstant* CopyToRepresentation(Representation r) const;
2270 HConstant* CopyToTruncatedInt32() const;
2271 bool HasInteger32Value() const { return has_int32_value_; }
2272 int32_t Integer32Value() const {
2273 ASSERT(HasInteger32Value());
2274 return int32_value_;
2275 }
2276 bool HasDoubleValue() const { return has_double_value_; }
2277 double DoubleValue() const {
2278 ASSERT(HasDoubleValue());
2279 return double_value_;
2280 }
2281 bool HasStringValue() const { return handle_->IsString(); }
2282
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002283 bool ToBoolean() const;
2284
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002285 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002286 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002287 return reinterpret_cast<intptr_t>(*handle());
2288 }
2289
2290#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002291 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292#endif
2293
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002294 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002295
2296 protected:
2297 virtual Range* InferRange();
2298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002299 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002300 HConstant* other_constant = HConstant::cast(other);
2301 return handle().is_identical_to(other_constant->handle());
2302 }
2303
2304 private:
2305 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002306
2307 // The following two values represent the int32 and the double value of the
2308 // given constant if there is a lossless conversion between the constant
2309 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002310 bool has_int32_value_ : 1;
2311 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002312 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002313 double double_value_;
2314};
2315
2316
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002317class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002318 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002319 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002320 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002321 SetOperandAt(0, context);
2322 SetOperandAt(1, left);
2323 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002324 }
2325
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002326 HValue* context() { return OperandAt(0); }
2327 HValue* left() { return OperandAt(1); }
2328 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002329
2330 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2331 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002332 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002333 if (IsCommutative() && left()->IsConstant()) return right();
2334 return left();
2335 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002336 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002337 if (IsCommutative() && left()->IsConstant()) return left();
2338 return right();
2339 }
2340
2341 virtual bool IsCommutative() const { return false; }
2342
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002343 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002344};
2345
2346
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002347class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002348 public:
2349 HApplyArguments(HValue* function,
2350 HValue* receiver,
2351 HValue* length,
2352 HValue* elements) {
2353 set_representation(Representation::Tagged());
2354 SetOperandAt(0, function);
2355 SetOperandAt(1, receiver);
2356 SetOperandAt(2, length);
2357 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002358 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002359 }
2360
2361 virtual Representation RequiredInputRepresentation(int index) const {
2362 // The length is untagged, all other inputs are tagged.
2363 return (index == 2)
2364 ? Representation::Integer32()
2365 : Representation::Tagged();
2366 }
2367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002368 HValue* function() { return OperandAt(0); }
2369 HValue* receiver() { return OperandAt(1); }
2370 HValue* length() { return OperandAt(2); }
2371 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002372
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002373 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374};
2375
2376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002377class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002378 public:
2379 HArgumentsElements() {
2380 // The value produced by this instruction is a pointer into the stack
2381 // that looks as if it was a smi because of alignment.
2382 set_representation(Representation::Tagged());
2383 SetFlag(kUseGVN);
2384 }
2385
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002386 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002387
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002388 virtual Representation RequiredInputRepresentation(int index) const {
2389 return Representation::None();
2390 }
2391
ager@chromium.org378b34e2011-01-28 08:04:38 +00002392 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002393 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002394};
2395
2396
2397class HArgumentsLength: public HUnaryOperation {
2398 public:
2399 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2400 set_representation(Representation::Integer32());
2401 SetFlag(kUseGVN);
2402 }
2403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002404 virtual Representation RequiredInputRepresentation(int index) const {
2405 return Representation::Tagged();
2406 }
2407
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002408 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002409
2410 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002411 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412};
2413
2414
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002415class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002416 public:
2417 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2418 set_representation(Representation::Tagged());
2419 SetFlag(kUseGVN);
2420 SetOperandAt(0, arguments);
2421 SetOperandAt(1, length);
2422 SetOperandAt(2, index);
2423 }
2424
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002425 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002426
2427 virtual Representation RequiredInputRepresentation(int index) const {
2428 // The arguments elements is considered tagged.
2429 return index == 0
2430 ? Representation::Tagged()
2431 : Representation::Integer32();
2432 }
2433
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002434 HValue* arguments() { return OperandAt(0); }
2435 HValue* length() { return OperandAt(1); }
2436 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002437
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002438 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002439
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002440 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002441};
2442
2443
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002444class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002446 HBoundsCheck(HValue* index, HValue* length) {
2447 SetOperandAt(0, index);
2448 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002449 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002450 SetFlag(kUseGVN);
2451 }
2452
2453 virtual Representation RequiredInputRepresentation(int index) const {
2454 return Representation::Integer32();
2455 }
2456
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002457 virtual void PrintDataTo(StringStream* stream);
2458
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002459 HValue* index() { return OperandAt(0); }
2460 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002461
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002462 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002463
2464 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002465 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002466};
2467
2468
2469class HBitwiseBinaryOperation: public HBinaryOperation {
2470 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002471 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2472 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002473 set_representation(Representation::Tagged());
2474 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002475 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002476 }
2477
2478 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002479 return index == 0
2480 ? Representation::Tagged()
2481 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002482 }
2483
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002484 virtual void RepresentationChanged(Representation to) {
2485 if (!to.IsTagged()) {
2486 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002487 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002488 SetFlag(kTruncatingToInt32);
2489 SetFlag(kUseGVN);
2490 }
2491 }
2492
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002493 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002494
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002495 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002496};
2497
2498
2499class HArithmeticBinaryOperation: public HBinaryOperation {
2500 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002501 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2502 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002503 set_representation(Representation::Tagged());
2504 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002505 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002506 }
2507
2508 virtual void RepresentationChanged(Representation to) {
2509 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002510 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511 SetFlag(kUseGVN);
2512 }
2513 }
2514
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002515 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002517 return index == 0
2518 ? Representation::Tagged()
2519 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002521
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002522 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002523 if (left()->representation().Equals(right()->representation())) {
2524 return left()->representation();
2525 }
2526 return HValue::InferredRepresentation();
2527 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002528};
2529
2530
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002531class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002532 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002533 HCompareGeneric(HValue* context,
2534 HValue* left,
2535 HValue* right,
2536 Token::Value token)
2537 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 ASSERT(Token::IsCompareOp(token));
2539 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002540 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002541 }
2542
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002543 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002544 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002545 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002548 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002549 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002550
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002551 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002552 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002554 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002556 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2557
2558 private:
2559 Token::Value token_;
2560};
2561
2562
2563class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2564 public:
2565 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2566 : token_(token) {
2567 ASSERT(Token::IsCompareOp(token));
2568 SetOperandAt(0, left);
2569 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002570 }
2571
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002572 HValue* left() { return OperandAt(0); }
2573 HValue* right() { return OperandAt(1); }
2574 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002576 void SetInputRepresentation(Representation r);
2577 Representation GetInputRepresentation() const {
2578 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002579 }
2580
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002581 virtual Representation RequiredInputRepresentation(int index) const {
2582 return input_representation_;
2583 }
2584 virtual void PrintDataTo(StringStream* stream);
2585
2586 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2587
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002588 private:
2589 Representation input_representation_;
2590 Token::Value token_;
2591};
2592
2593
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002594class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002595 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002596 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2597 SetOperandAt(0, left);
2598 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002599 }
2600
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002601 HValue* left() { return OperandAt(0); }
2602 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002603
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604 virtual Representation RequiredInputRepresentation(int index) const {
2605 return Representation::Tagged();
2606 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002607
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002608 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002609};
2610
2611
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002612class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002613 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002614 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2615 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002616 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002617 }
2618
2619 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002620 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002621 int right() const { return right_; }
2622
whesse@chromium.org7b260152011-06-20 15:33:18 +00002623 virtual Representation RequiredInputRepresentation(int index) const {
2624 return Representation::Integer32();
2625 }
2626
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002627 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002628
2629 private:
2630 const Token::Value op_;
2631 const int right_;
2632};
2633
2634
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002635class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002636 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002637 HIsNullAndBranch(HValue* value, bool is_strict)
2638 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002639
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002640 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002641
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002642 virtual Representation RequiredInputRepresentation(int index) const {
2643 return Representation::Tagged();
2644 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002645
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002646 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002647
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002648 private:
2649 bool is_strict_;
2650};
2651
2652
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002653class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002654 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002655 explicit HIsObjectAndBranch(HValue* value)
2656 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002657
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002658 virtual Representation RequiredInputRepresentation(int index) const {
2659 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002660 }
2661
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002662 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2663};
2664
2665
2666class HIsSmiAndBranch: public HUnaryControlInstruction {
2667 public:
2668 explicit HIsSmiAndBranch(HValue* value)
2669 : HUnaryControlInstruction(value, NULL, NULL) { }
2670
2671 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2672
2673 virtual Representation RequiredInputRepresentation(int index) const {
2674 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002675 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002676
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002677 protected:
2678 virtual bool DataEquals(HValue* other) { return true; }
2679};
2680
2681
2682class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2683 public:
2684 explicit HIsUndetectableAndBranch(HValue* value)
2685 : HUnaryControlInstruction(value, NULL, NULL) { }
2686
2687 virtual Representation RequiredInputRepresentation(int index) const {
2688 return Representation::Tagged();
2689 }
2690
2691 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2692};
2693
2694
2695class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2696 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002697 virtual Representation RequiredInputRepresentation(int index) const {
2698 return Representation::None();
2699 }
2700
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002701 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002702};
2703
2704
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002705class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002706 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002707 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2708 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2709 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2710 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002711 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2712 }
2713
2714 InstanceType from() { return from_; }
2715 InstanceType to() { return to_; }
2716
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002717 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002719 virtual Representation RequiredInputRepresentation(int index) const {
2720 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002721 }
2722
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002723 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2724
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725 private:
2726 InstanceType from_;
2727 InstanceType to_; // Inclusive range, not all combinations work.
2728};
2729
2730
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002731class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002732 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002733 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2734 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002735
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002736 virtual Representation RequiredInputRepresentation(int index) const {
2737 return Representation::Tagged();
2738 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002739
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002740 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741};
2742
2743
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002744class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002745 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002746 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2747 set_representation(Representation::Tagged());
2748 SetFlag(kUseGVN);
2749 }
2750
2751 virtual Representation RequiredInputRepresentation(int index) const {
2752 return Representation::Tagged();
2753 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002754
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002755 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002756
2757 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002758 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002759};
2760
2761
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002762class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002763 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002764 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2765 : HUnaryControlInstruction(value, NULL, NULL),
2766 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002767
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002768 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2769
2770 virtual Representation RequiredInputRepresentation(int index) const {
2771 return Representation::Tagged();
2772 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002774 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002775
2776 Handle<String> class_name() const { return class_name_; }
2777
2778 private:
2779 Handle<String> class_name_;
2780};
2781
2782
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002783class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002785 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2786 : HUnaryControlInstruction(value, NULL, NULL),
2787 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788
2789 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002790 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002792 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002793
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002794 virtual Representation RequiredInputRepresentation(int index) const {
2795 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002796 }
2797
2798 private:
2799 Handle<String> type_literal_;
2800};
2801
2802
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002803class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002804 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002805 HInstanceOf(HValue* context, HValue* left, HValue* right)
2806 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002808 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809 }
2810
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811 virtual Representation RequiredInputRepresentation(int index) const {
2812 return Representation::Tagged();
2813 }
2814
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002815 virtual HType CalculateInferredType();
2816
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002817 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002818
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002819 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820};
2821
2822
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002823class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002824 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002825 HInstanceOfKnownGlobal(HValue* context,
2826 HValue* left,
2827 Handle<JSFunction> right)
2828 : function_(right) {
2829 SetOperandAt(0, context);
2830 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002831 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002832 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002833 }
2834
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002835 HValue* context() { return OperandAt(0); }
2836 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002837 Handle<JSFunction> function() { return function_; }
2838
2839 virtual Representation RequiredInputRepresentation(int index) const {
2840 return Representation::Tagged();
2841 }
2842
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002843 virtual HType CalculateInferredType();
2844
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002845 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002846
2847 private:
2848 Handle<JSFunction> function_;
2849};
2850
2851
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002852class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002853 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002854 HPower(HValue* left, HValue* right) {
2855 SetOperandAt(0, left);
2856 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002857 set_representation(Representation::Double());
2858 SetFlag(kUseGVN);
2859 }
2860
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002861 HValue* left() { return OperandAt(0); }
2862 HValue* right() { return OperandAt(1); }
2863
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002864 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002865 return index == 0
2866 ? Representation::Double()
2867 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002868 }
2869
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002870 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002871
2872 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002873 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002874};
2875
2876
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002877class HAdd: public HArithmeticBinaryOperation {
2878 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002879 HAdd(HValue* context, HValue* left, HValue* right)
2880 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002881 SetFlag(kCanOverflow);
2882 }
2883
2884 // Add is only commutative if two integer values are added and not if two
2885 // tagged values are added (because it might be a String concatenation).
2886 virtual bool IsCommutative() const {
2887 return !representation().IsTagged();
2888 }
2889
2890 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2891
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002892 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002893
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002894 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895
2896 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002897 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002898
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899 virtual Range* InferRange();
2900};
2901
2902
2903class HSub: public HArithmeticBinaryOperation {
2904 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002905 HSub(HValue* context, HValue* left, HValue* right)
2906 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907 SetFlag(kCanOverflow);
2908 }
2909
2910 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002912 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913
2914 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002915 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002916
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917 virtual Range* InferRange();
2918};
2919
2920
2921class HMul: public HArithmeticBinaryOperation {
2922 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002923 HMul(HValue* context, HValue* left, HValue* right)
2924 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925 SetFlag(kCanOverflow);
2926 }
2927
2928 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2929
2930 // Only commutative if it is certain that not two objects are multiplicated.
2931 virtual bool IsCommutative() const {
2932 return !representation().IsTagged();
2933 }
2934
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002935 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002936
2937 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002938 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002939
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940 virtual Range* InferRange();
2941};
2942
2943
2944class HMod: public HArithmeticBinaryOperation {
2945 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002946 HMod(HValue* context, HValue* left, HValue* right)
2947 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002948 SetFlag(kCanBeDivByZero);
2949 }
2950
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002951 bool HasPowerOf2Divisor() {
2952 if (right()->IsConstant() &&
2953 HConstant::cast(right())->HasInteger32Value()) {
2954 int32_t value = HConstant::cast(right())->Integer32Value();
2955 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2956 }
2957
2958 return false;
2959 }
2960
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002961 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2962
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002963 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002964
2965 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002966 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002967
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002968 virtual Range* InferRange();
2969};
2970
2971
2972class HDiv: public HArithmeticBinaryOperation {
2973 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002974 HDiv(HValue* context, HValue* left, HValue* right)
2975 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002976 SetFlag(kCanBeDivByZero);
2977 SetFlag(kCanOverflow);
2978 }
2979
2980 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2981
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002982 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983
2984 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002985 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002986
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002987 virtual Range* InferRange();
2988};
2989
2990
2991class HBitAnd: public HBitwiseBinaryOperation {
2992 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002993 HBitAnd(HValue* context, HValue* left, HValue* right)
2994 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002995
2996 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002997 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002999 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000
3001 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003002 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003003
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003004 virtual Range* InferRange();
3005};
3006
3007
3008class HBitXor: public HBitwiseBinaryOperation {
3009 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003010 HBitXor(HValue* context, HValue* left, HValue* right)
3011 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012
3013 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003016 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003017
3018 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003019 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003020};
3021
3022
3023class HBitOr: public HBitwiseBinaryOperation {
3024 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003025 HBitOr(HValue* context, HValue* left, HValue* right)
3026 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
3028 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003029 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003031 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032
3033 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003034 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003035
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003036 virtual Range* InferRange();
3037};
3038
3039
3040class HShl: public HBitwiseBinaryOperation {
3041 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003042 HShl(HValue* context, HValue* left, HValue* right)
3043 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044
3045 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003048 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003049
3050 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003051 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003052};
3053
3054
3055class HShr: public HBitwiseBinaryOperation {
3056 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003057 HShr(HValue* context, HValue* left, HValue* right)
3058 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003060 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003061 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003063 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003064
3065 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067};
3068
3069
3070class HSar: public HBitwiseBinaryOperation {
3071 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003072 HSar(HValue* context, HValue* left, HValue* right)
3073 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074
3075 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003076 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003078 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003079
3080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082};
3083
3084
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003085class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003086 public:
3087 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3088 SetFlag(kChangesOsrEntries);
3089 }
3090
3091 int ast_id() const { return ast_id_; }
3092
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003093 virtual Representation RequiredInputRepresentation(int index) const {
3094 return Representation::None();
3095 }
3096
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003097 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098
3099 private:
3100 int ast_id_;
3101};
3102
3103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105 public:
3106 explicit HParameter(unsigned index) : index_(index) {
3107 set_representation(Representation::Tagged());
3108 }
3109
3110 unsigned index() const { return index_; }
3111
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003112 virtual void PrintDataTo(StringStream* stream);
3113
3114 virtual Representation RequiredInputRepresentation(int index) const {
3115 return Representation::None();
3116 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003118 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003119
3120 private:
3121 unsigned index_;
3122};
3123
3124
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003125class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003126 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003127 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3128 : HUnaryCall(context, argument_count),
3129 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003131 }
3132
3133 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003135 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136
3137 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3138 transcendental_type_ = transcendental_type;
3139 }
3140 TranscendentalCache::Type transcendental_type() {
3141 return transcendental_type_;
3142 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003143
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003144 virtual void PrintDataTo(StringStream* stream);
3145
3146 virtual Representation RequiredInputRepresentation(int index) const {
3147 return Representation::Tagged();
3148 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003150 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151
3152 private:
3153 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154 TranscendentalCache::Type transcendental_type_;
3155};
3156
3157
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003158class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159 public:
3160 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003162 virtual Representation RequiredInputRepresentation(int index) const {
3163 return Representation::None();
3164 }
3165
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003166 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167};
3168
3169
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003170class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003171 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003172 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173 : cell_(cell), check_hole_value_(check_hole_value) {
3174 set_representation(Representation::Tagged());
3175 SetFlag(kUseGVN);
3176 SetFlag(kDependsOnGlobalVars);
3177 }
3178
3179 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3180 bool check_hole_value() const { return check_hole_value_; }
3181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003182 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003183
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003184 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003185 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186 return reinterpret_cast<intptr_t>(*cell_);
3187 }
3188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003189 virtual Representation RequiredInputRepresentation(int index) const {
3190 return Representation::None();
3191 }
3192
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003193 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194
3195 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003196 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003197 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198 return cell_.is_identical_to(b->cell());
3199 }
3200
3201 private:
3202 Handle<JSGlobalPropertyCell> cell_;
3203 bool check_hole_value_;
3204};
3205
3206
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003207class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003208 public:
3209 HLoadGlobalGeneric(HValue* context,
3210 HValue* global_object,
3211 Handle<Object> name,
3212 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003213 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003214 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003215 SetOperandAt(0, context);
3216 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003217 set_representation(Representation::Tagged());
3218 SetAllSideEffects();
3219 }
3220
3221 HValue* context() { return OperandAt(0); }
3222 HValue* global_object() { return OperandAt(1); }
3223 Handle<Object> name() const { return name_; }
3224 bool for_typeof() const { return for_typeof_; }
3225
3226 virtual void PrintDataTo(StringStream* stream);
3227
3228 virtual Representation RequiredInputRepresentation(int index) const {
3229 return Representation::Tagged();
3230 }
3231
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003232 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003233
3234 private:
3235 Handle<Object> name_;
3236 bool for_typeof_;
3237};
3238
3239
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003240class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003241 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003242 HStoreGlobalCell(HValue* value,
3243 Handle<JSGlobalPropertyCell> cell,
3244 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003245 : HUnaryOperation(value),
3246 cell_(cell),
3247 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003248 SetFlag(kChangesGlobalVars);
3249 }
3250
3251 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003252 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003253
3254 virtual Representation RequiredInputRepresentation(int index) const {
3255 return Representation::Tagged();
3256 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003257 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003258
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003259 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003260
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261 private:
3262 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003263 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264};
3265
3266
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003267class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3268 public:
3269 HStoreGlobalGeneric(HValue* context,
3270 HValue* global_object,
3271 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003272 HValue* value,
3273 bool strict_mode)
3274 : name_(name),
3275 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003276 SetOperandAt(0, context);
3277 SetOperandAt(1, global_object);
3278 SetOperandAt(2, value);
3279 set_representation(Representation::Tagged());
3280 SetAllSideEffects();
3281 }
3282
3283 HValue* context() { return OperandAt(0); }
3284 HValue* global_object() { return OperandAt(1); }
3285 Handle<Object> name() const { return name_; }
3286 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003287 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003288
3289 virtual void PrintDataTo(StringStream* stream);
3290
3291 virtual Representation RequiredInputRepresentation(int index) const {
3292 return Representation::Tagged();
3293 }
3294
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003295 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003296
3297 private:
3298 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003299 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003300};
3301
3302
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003303class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003304 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003305 HLoadContextSlot(HValue* context , int slot_index)
3306 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003307 set_representation(Representation::Tagged());
3308 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003309 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003310 }
3311
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003312 int slot_index() const { return slot_index_; }
3313
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003314 virtual Representation RequiredInputRepresentation(int index) const {
3315 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003316 }
3317
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003318 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003319
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003320 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003321
3322 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003323 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003324 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003325 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003326 }
3327
3328 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003329 int slot_index_;
3330};
3331
3332
3333static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003334 return !value->type().IsBoolean()
3335 && !value->type().IsSmi()
3336 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003337}
3338
3339
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003340class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003341 public:
3342 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003343 : slot_index_(slot_index) {
3344 SetOperandAt(0, context);
3345 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003346 SetFlag(kChangesContextSlots);
3347 }
3348
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003349 HValue* context() { return OperandAt(0); }
3350 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003351 int slot_index() const { return slot_index_; }
3352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003353 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003354 return StoringValueNeedsWriteBarrier(value());
3355 }
3356
3357 virtual Representation RequiredInputRepresentation(int index) const {
3358 return Representation::Tagged();
3359 }
3360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003361 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003362
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003363 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003364
3365 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003366 int slot_index_;
3367};
3368
3369
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003370class HLoadNamedField: public HUnaryOperation {
3371 public:
3372 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3373 : HUnaryOperation(object),
3374 is_in_object_(is_in_object),
3375 offset_(offset) {
3376 set_representation(Representation::Tagged());
3377 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003378 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379 if (is_in_object) {
3380 SetFlag(kDependsOnInobjectFields);
3381 } else {
3382 SetFlag(kDependsOnBackingStoreFields);
3383 }
3384 }
3385
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003386 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003387 bool is_in_object() const { return is_in_object_; }
3388 int offset() const { return offset_; }
3389
3390 virtual Representation RequiredInputRepresentation(int index) const {
3391 return Representation::Tagged();
3392 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003393 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003395 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003396
3397 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003398 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399 HLoadNamedField* b = HLoadNamedField::cast(other);
3400 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3401 }
3402
3403 private:
3404 bool is_in_object_;
3405 int offset_;
3406};
3407
3408
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003409class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003410 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003411 HLoadNamedFieldPolymorphic(HValue* context,
3412 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003413 SmallMapList* types,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003414 Handle<String> name);
3415
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003416 HValue* context() { return OperandAt(0); }
3417 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003418 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003419 Handle<String> name() { return name_; }
3420 bool need_generic() { return need_generic_; }
3421
3422 virtual Representation RequiredInputRepresentation(int index) const {
3423 return Representation::Tagged();
3424 }
3425
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003426 virtual void PrintDataTo(StringStream* stream);
3427
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003428 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003429
3430 static const int kMaxLoadPolymorphism = 4;
3431
3432 protected:
3433 virtual bool DataEquals(HValue* value);
3434
3435 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003436 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003437 Handle<String> name_;
3438 bool need_generic_;
3439};
3440
3441
3442
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003443class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003444 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003445 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003446 : name_(name) {
3447 SetOperandAt(0, context);
3448 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003449 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003450 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003451 }
3452
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003453 HValue* context() { return OperandAt(0); }
3454 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003455 Handle<Object> name() const { return name_; }
3456
3457 virtual Representation RequiredInputRepresentation(int index) const {
3458 return Representation::Tagged();
3459 }
3460
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003461 virtual void PrintDataTo(StringStream* stream);
3462
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003463 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003464
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465 private:
3466 Handle<Object> name_;
3467};
3468
3469
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003470class HLoadFunctionPrototype: public HUnaryOperation {
3471 public:
3472 explicit HLoadFunctionPrototype(HValue* function)
3473 : HUnaryOperation(function) {
3474 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003475 SetFlag(kUseGVN);
3476 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003477 }
3478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003479 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003480
3481 virtual Representation RequiredInputRepresentation(int index) const {
3482 return Representation::Tagged();
3483 }
3484
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003485 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003486
3487 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003488 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003489};
3490
3491
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003492class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003493 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003494 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3495 SetOperandAt(0, obj);
3496 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003497 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003498 SetFlag(kDependsOnArrayElements);
3499 SetFlag(kUseGVN);
3500 }
3501
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003502 HValue* object() { return OperandAt(0); }
3503 HValue* key() { return OperandAt(1); }
3504
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003505 virtual Representation RequiredInputRepresentation(int index) const {
3506 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003507 return index == 0
3508 ? Representation::Tagged()
3509 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003510 }
3511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003512 virtual void PrintDataTo(StringStream* stream);
3513
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003514 bool RequiresHoleCheck() const;
3515
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003516 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003517
3518 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003519 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003520};
3521
3522
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003523class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3524 public:
3525 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3526 SetOperandAt(0, elements);
3527 SetOperandAt(1, key);
3528 set_representation(Representation::Double());
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003529 SetFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003530 SetFlag(kUseGVN);
3531 }
3532
3533 HValue* elements() { return OperandAt(0); }
3534 HValue* key() { return OperandAt(1); }
3535
3536 virtual Representation RequiredInputRepresentation(int index) const {
3537 // The key is supposed to be Integer32.
3538 return index == 0
3539 ? Representation::Tagged()
3540 : Representation::Integer32();
3541 }
3542
3543 virtual void PrintDataTo(StringStream* stream);
3544
3545 bool RequiresHoleCheck() const;
3546
3547 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3548
3549 protected:
3550 virtual bool DataEquals(HValue* other) { return true; }
3551};
3552
3553
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003554class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003555 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003556 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3557 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003558 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003559 : elements_kind_(elements_kind) {
3560 SetOperandAt(0, external_elements);
3561 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003562 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3563 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003564 set_representation(Representation::Double());
3565 } else {
3566 set_representation(Representation::Integer32());
3567 }
3568 SetFlag(kDependsOnSpecializedArrayElements);
3569 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003570 SetFlag(kDependsOnCalls);
3571 SetFlag(kUseGVN);
3572 }
3573
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003574 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003575
3576 virtual Representation RequiredInputRepresentation(int index) const {
3577 // The key is supposed to be Integer32, but the base pointer
3578 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003579 return index == 0
3580 ? Representation::External()
3581 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003582 }
3583
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003584 HValue* external_pointer() { return OperandAt(0); }
3585 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003586 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003587
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003588 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003589
3590 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003591 virtual bool DataEquals(HValue* other) {
3592 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3593 HLoadKeyedSpecializedArrayElement* cast_other =
3594 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003595 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003596 }
3597
3598 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003599 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003600};
3601
3602
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003603class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003604 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003605 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003606 set_representation(Representation::Tagged());
3607 SetOperandAt(0, obj);
3608 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003609 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003610 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003611 }
3612
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003613 HValue* object() { return OperandAt(0); }
3614 HValue* key() { return OperandAt(1); }
3615 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618
3619 virtual Representation RequiredInputRepresentation(int index) const {
3620 return Representation::Tagged();
3621 }
3622
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003623 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003624};
3625
3626
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003627class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628 public:
3629 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003630 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003631 HValue* val,
3632 bool in_object,
3633 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003634 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635 is_in_object_(in_object),
3636 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003637 SetOperandAt(0, obj);
3638 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003639 if (is_in_object_) {
3640 SetFlag(kChangesInobjectFields);
3641 } else {
3642 SetFlag(kChangesBackingStoreFields);
3643 }
3644 }
3645
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003646 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647
3648 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003649 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003650 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003651 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003652
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003653 HValue* object() { return OperandAt(0); }
3654 HValue* value() { return OperandAt(1); }
3655
3656 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003657 bool is_in_object() const { return is_in_object_; }
3658 int offset() const { return offset_; }
3659 Handle<Map> transition() const { return transition_; }
3660 void set_transition(Handle<Map> map) { transition_ = map; }
3661
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003662 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003663 return StoringValueNeedsWriteBarrier(value());
3664 }
3665
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003666 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003667 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668 bool is_in_object_;
3669 int offset_;
3670 Handle<Map> transition_;
3671};
3672
3673
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003674class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003675 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003676 HStoreNamedGeneric(HValue* context,
3677 HValue* object,
3678 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003679 HValue* value,
3680 bool strict_mode)
3681 : name_(name),
3682 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003683 SetOperandAt(0, object);
3684 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003685 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003686 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003687 }
3688
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003689 HValue* object() { return OperandAt(0); }
3690 HValue* value() { return OperandAt(1); }
3691 HValue* context() { return OperandAt(2); }
3692 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003693 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003694
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003695 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003696
3697 virtual Representation RequiredInputRepresentation(int index) const {
3698 return Representation::Tagged();
3699 }
3700
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003701 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003702
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003703 private:
3704 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003705 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003706};
3707
3708
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003709class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003710 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003711 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3712 SetOperandAt(0, obj);
3713 SetOperandAt(1, key);
3714 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003715 SetFlag(kChangesArrayElements);
3716 }
3717
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003718 virtual Representation RequiredInputRepresentation(int index) const {
3719 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003720 return index == 1
3721 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003722 : Representation::Tagged();
3723 }
3724
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003725 HValue* object() { return OperandAt(0); }
3726 HValue* key() { return OperandAt(1); }
3727 HValue* value() { return OperandAt(2); }
3728
3729 bool NeedsWriteBarrier() {
3730 return StoringValueNeedsWriteBarrier(value());
3731 }
3732
3733 virtual void PrintDataTo(StringStream* stream);
3734
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003735 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003736};
3737
3738
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003739class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3740 public:
3741 HStoreKeyedFastDoubleElement(HValue* elements,
3742 HValue* key,
3743 HValue* val) {
3744 SetOperandAt(0, elements);
3745 SetOperandAt(1, key);
3746 SetOperandAt(2, val);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003747 SetFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003748 }
3749
3750 virtual Representation RequiredInputRepresentation(int index) const {
3751 if (index == 1) {
3752 return Representation::Integer32();
3753 } else if (index == 2) {
3754 return Representation::Double();
3755 } else {
3756 return Representation::Tagged();
3757 }
3758 }
3759
3760 HValue* elements() { return OperandAt(0); }
3761 HValue* key() { return OperandAt(1); }
3762 HValue* value() { return OperandAt(2); }
3763
3764 bool NeedsWriteBarrier() {
3765 return StoringValueNeedsWriteBarrier(value());
3766 }
3767
3768 virtual void PrintDataTo(StringStream* stream);
3769
3770 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3771};
3772
3773
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003774class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003775 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003776 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3777 HValue* key,
3778 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003779 JSObject::ElementsKind elements_kind)
3780 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003781 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003782 SetOperandAt(0, external_elements);
3783 SetOperandAt(1, key);
3784 SetOperandAt(2, val);
3785 }
3786
3787 virtual void PrintDataTo(StringStream* stream);
3788
3789 virtual Representation RequiredInputRepresentation(int index) const {
3790 if (index == 0) {
3791 return Representation::External();
3792 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003793 bool float_or_double_elements =
3794 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3795 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3796 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003797 return Representation::Double();
3798 } else {
3799 return Representation::Integer32();
3800 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003801 }
3802 }
3803
3804 HValue* external_pointer() { return OperandAt(0); }
3805 HValue* key() { return OperandAt(1); }
3806 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003807 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003808
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003809 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3810
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003811 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003812 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003813};
3814
3815
3816class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003817 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003818 HStoreKeyedGeneric(HValue* context,
3819 HValue* object,
3820 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003821 HValue* value,
3822 bool strict_mode)
3823 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003824 SetOperandAt(0, object);
3825 SetOperandAt(1, key);
3826 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003827 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003828 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003829 }
3830
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003831 HValue* object() { return OperandAt(0); }
3832 HValue* key() { return OperandAt(1); }
3833 HValue* value() { return OperandAt(2); }
3834 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003835 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003836
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003837 virtual Representation RequiredInputRepresentation(int index) const {
3838 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003839 }
3840
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003841 virtual void PrintDataTo(StringStream* stream);
3842
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003843 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003844
3845 private:
3846 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003847};
3848
3849
danno@chromium.org160a7b02011-04-18 15:51:38 +00003850class HStringAdd: public HBinaryOperation {
3851 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003852 HStringAdd(HValue* context, HValue* left, HValue* right)
3853 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003854 set_representation(Representation::Tagged());
3855 SetFlag(kUseGVN);
3856 SetFlag(kDependsOnMaps);
3857 }
3858
3859 virtual Representation RequiredInputRepresentation(int index) const {
3860 return Representation::Tagged();
3861 }
3862
3863 virtual HType CalculateInferredType() {
3864 return HType::String();
3865 }
3866
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003867 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003868
3869 protected:
3870 virtual bool DataEquals(HValue* other) { return true; }
3871};
3872
3873
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003874class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003875 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003876 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3877 SetOperandAt(0, context);
3878 SetOperandAt(1, string);
3879 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003880 set_representation(Representation::Integer32());
3881 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003882 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003883 }
3884
3885 virtual Representation RequiredInputRepresentation(int index) const {
3886 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003887 return index == 2
3888 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003889 : Representation::Tagged();
3890 }
3891
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003892 HValue* context() { return OperandAt(0); }
3893 HValue* string() { return OperandAt(1); }
3894 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003895
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003896 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003897
3898 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003899 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003900
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003901 virtual Range* InferRange() {
3902 return new Range(0, String::kMaxUC16CharCode);
3903 }
3904};
3905
3906
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003907class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003908 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003909 HStringCharFromCode(HValue* context, HValue* char_code) {
3910 SetOperandAt(0, context);
3911 SetOperandAt(1, char_code);
3912 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003913 SetFlag(kUseGVN);
3914 }
3915
3916 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003917 return index == 0
3918 ? Representation::Tagged()
3919 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003920 }
3921
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003922 HValue* context() { return OperandAt(0); }
3923 HValue* value() { return OperandAt(1); }
3924
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003925 virtual bool DataEquals(HValue* other) { return true; }
3926
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003927 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003928};
3929
3930
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003931class HStringLength: public HUnaryOperation {
3932 public:
3933 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3934 set_representation(Representation::Tagged());
3935 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003936 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003937 }
3938
3939 virtual Representation RequiredInputRepresentation(int index) const {
3940 return Representation::Tagged();
3941 }
3942
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003943 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003944 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3945 return HType::Smi();
3946 }
3947
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003948 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003949
3950 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003951 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003952
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003953 virtual Range* InferRange() {
3954 return new Range(0, String::kMaxLength);
3955 }
3956};
3957
3958
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003959template <int V>
3960class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003961 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003962 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003963 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003964 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003965 }
3966
3967 int literal_index() const { return literal_index_; }
3968 int depth() const { return depth_; }
3969
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003970 private:
3971 int literal_index_;
3972 int depth_;
3973};
3974
3975
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003976class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003977 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003978 HArrayLiteral(HValue* context,
3979 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003980 int length,
3981 int literal_index,
3982 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003983 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003984 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003985 constant_elements_(constant_elements) {
3986 SetOperandAt(0, context);
3987 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003989 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003990 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3991 int length() const { return length_; }
3992
3993 bool IsCopyOnWrite() const;
3994
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003995 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003996 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003997 }
3998
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003999 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004000
4001 private:
4002 int length_;
4003 Handle<FixedArray> constant_elements_;
4004};
4005
4006
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004007class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004008 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004009 HObjectLiteral(HValue* context,
4010 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004011 bool fast_elements,
4012 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004013 int depth,
4014 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004015 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004016 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004017 fast_elements_(fast_elements),
4018 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004019 SetOperandAt(0, context);
4020 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004021
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004022 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004023 Handle<FixedArray> constant_properties() const {
4024 return constant_properties_;
4025 }
4026 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004027 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004028
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004029 virtual Representation RequiredInputRepresentation(int index) const {
4030 return Representation::Tagged();
4031 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004032
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004033 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004034
4035 private:
4036 Handle<FixedArray> constant_properties_;
4037 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004038 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004039};
4040
4041
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004042class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004043 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004044 HRegExpLiteral(HValue* context,
4045 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004046 Handle<String> flags,
4047 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004048 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004049 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004050 flags_(flags) {
4051 SetOperandAt(0, context);
4052 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004053
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004054 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004055 Handle<String> pattern() { return pattern_; }
4056 Handle<String> flags() { return flags_; }
4057
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004058 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004059 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004060 }
4061
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004062 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004063
4064 private:
4065 Handle<String> pattern_;
4066 Handle<String> flags_;
4067};
4068
4069
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004070class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004071 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004072 HFunctionLiteral(HValue* context,
4073 Handle<SharedFunctionInfo> shared,
4074 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004075 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004076 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004077 set_representation(Representation::Tagged());
4078 }
4079
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004080 HValue* context() { return OperandAt(0); }
4081
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004082 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004083 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004084 }
4085
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004086 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004087
4088 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4089 bool pretenure() const { return pretenure_; }
4090
4091 private:
4092 Handle<SharedFunctionInfo> shared_info_;
4093 bool pretenure_;
4094};
4095
4096
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004097class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004098 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004099 explicit HTypeof(HValue* context, HValue* value) {
4100 SetOperandAt(0, context);
4101 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004102 set_representation(Representation::Tagged());
4103 }
4104
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004105 HValue* context() { return OperandAt(0); }
4106 HValue* value() { return OperandAt(1); }
4107
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004108 virtual Representation RequiredInputRepresentation(int index) const {
4109 return Representation::Tagged();
4110 }
4111
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004112 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004113};
4114
4115
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004116class HToFastProperties: public HUnaryOperation {
4117 public:
4118 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4119 // This instruction is not marked as having side effects, but
4120 // changes the map of the input operand. Use it only when creating
4121 // object literals.
4122 ASSERT(value->IsObjectLiteral());
4123 set_representation(Representation::Tagged());
4124 }
4125
4126 virtual Representation RequiredInputRepresentation(int index) const {
4127 return Representation::Tagged();
4128 }
4129
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004130 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004131};
4132
4133
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004134class HValueOf: public HUnaryOperation {
4135 public:
4136 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4137 set_representation(Representation::Tagged());
4138 }
4139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004140 virtual Representation RequiredInputRepresentation(int index) const {
4141 return Representation::Tagged();
4142 }
4143
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004144 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004145};
4146
4147
4148class HDeleteProperty: public HBinaryOperation {
4149 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004150 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4151 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004152 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004153 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004154 }
4155
4156 virtual Representation RequiredInputRepresentation(int index) const {
4157 return Representation::Tagged();
4158 }
4159
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004160 virtual HType CalculateInferredType();
4161
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004162 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004163
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004164 HValue* object() { return left(); }
4165 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004166};
4167
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004168
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004169class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004170 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004171 HIn(HValue* context, HValue* key, HValue* object) {
4172 SetOperandAt(0, context);
4173 SetOperandAt(1, key);
4174 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004175 set_representation(Representation::Tagged());
4176 SetAllSideEffects();
4177 }
4178
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004179 HValue* context() { return OperandAt(0); }
4180 HValue* key() { return OperandAt(1); }
4181 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004182
4183 virtual Representation RequiredInputRepresentation(int index) const {
4184 return Representation::Tagged();
4185 }
4186
4187 virtual HType CalculateInferredType() {
4188 return HType::Boolean();
4189 }
4190
4191 virtual void PrintDataTo(StringStream* stream);
4192
4193 DECLARE_CONCRETE_INSTRUCTION(In)
4194};
4195
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004196#undef DECLARE_INSTRUCTION
4197#undef DECLARE_CONCRETE_INSTRUCTION
4198
4199} } // namespace v8::internal
4200
4201#endif // V8_HYDROGEN_INSTRUCTIONS_H_