blob: 76007d764e6564db26abc9520ddf1b4100eaddf3 [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
516 static int ChangesFlagsMask() {
517 int result = 0;
518 // Create changes mask.
519#define DECLARE_DO(type) result |= (1 << kChanges##type);
520 GVN_FLAG_LIST(DECLARE_DO)
521#undef DECLARE_DO
522 return result;
523 }
524
525 static int DependsFlagsMask() {
526 return ConvertChangesToDependsFlags(ChangesFlagsMask());
527 }
528
529 static int ConvertChangesToDependsFlags(int flags) {
530 return flags << kChangesToDependsFlagsLeftShift;
531 }
532
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533 static HValue* cast(HValue* value) { return value; }
534
535 enum Opcode {
536 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000537 #define DECLARE_OPCODE(type) k##type,
538 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
539 kPhi
540 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000541 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000542 virtual Opcode opcode() const = 0;
543
544 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
545 #define DECLARE_PREDICATE(type) \
546 bool Is##type() const { return opcode() == k##type; }
547 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
548 #undef DECLARE_PREDICATE
549 bool IsPhi() const { return opcode() == kPhi; }
550
551 // Declare virtual predicates for abstract HInstruction or HValue
552 #define DECLARE_PREDICATE(type) \
553 virtual bool Is##type() const { return false; }
554 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
555 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000556
557 HValue() : block_(NULL),
558 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000560 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000561 range_(NULL),
562 flags_(0) {}
563 virtual ~HValue() {}
564
565 HBasicBlock* block() const { return block_; }
566 void SetBlock(HBasicBlock* block);
567
568 int id() const { return id_; }
569 void set_id(int id) { id_ = id; }
570
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000571 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000572
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000573 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000574 Representation representation() const { return representation_; }
575 void ChangeRepresentation(Representation r) {
576 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577 ASSERT(!r.IsNone());
578 ASSERT(CheckFlag(kFlexibleRepresentation));
579 RepresentationChanged(r);
580 representation_ = r;
581 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000582 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000583
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000584 virtual bool IsConvertibleToInteger() const { return true; }
585
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000586 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000587 void set_type(HType new_type) {
588 ASSERT(new_type.IsSubtypeOf(type_));
589 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000590 }
591
592 // An operation needs to override this function iff:
593 // 1) it can produce an int32 output.
594 // 2) the true value of its output can potentially be minus zero.
595 // The implementation must set a flag so that it bails out in the case where
596 // it would otherwise output what should be a minus zero as an int32 zero.
597 // If the operation also exists in a form that takes int32 and outputs int32
598 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000599 // back. There are three operations that need to propagate back to more than
600 // one input. They are phi and binary div and mul. They always return NULL
601 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000602 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
603 visited->Add(id());
604 return NULL;
605 }
606
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000607 bool IsDefinedAfter(HBasicBlock* other) const;
608
609 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000610 virtual int OperandCount() = 0;
611 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612 void SetOperandAt(int index, HValue* value);
613
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000614 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000615 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000616 bool HasNoUses() const { return use_list_ == NULL; }
617 bool HasMultipleUses() const {
618 return use_list_ != NULL && use_list_->tail() != NULL;
619 }
620 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000621 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622
623 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000624 void SetFlag(Flag f) { flags_ |= (1 << f); }
625 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
626 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
627
628 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
629 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
630 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000631
632 Range* range() const { return range_; }
633 bool HasRange() const { return range_ != NULL; }
634 void AddNewRange(Range* r);
635 void RemoveLastAddedRange();
636 void ComputeInitialRange();
637
638 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000639 virtual Representation RequiredInputRepresentation(int index) const = 0;
640
641 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000642 return representation();
643 }
644
645 // This gives the instruction an opportunity to replace itself with an
646 // instruction that does the same in some better way. To replace an
647 // instruction with a new one, first add the new instruction to the graph,
648 // then return it. Return NULL to have the instruction deleted.
649 virtual HValue* Canonicalize() { return this; }
650
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000651 bool Equals(HValue* other);
652 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000653
654 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000655 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000656 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000657 void PrintTypeTo(StringStream* stream);
658 void PrintRangeTo(StringStream* stream);
659 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000661 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000662
663 // Updated the inferred type of this instruction and returns true if
664 // it has changed.
665 bool UpdateInferredType();
666
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000667 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000668
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000669#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000670 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000671#endif
672
673 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000674 // This function must be overridden for instructions with flag kUseGVN, to
675 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000676 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000677 UNREACHABLE();
678 return false;
679 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000680 virtual void RepresentationChanged(Representation to) { }
681 virtual Range* InferRange();
682 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000683 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684 void clear_block() {
685 ASSERT(block_ != NULL);
686 block_ = NULL;
687 }
688
689 void set_representation(Representation r) {
690 // Representation is set-once.
691 ASSERT(representation_.IsNone() && !r.IsNone());
692 representation_ = r;
693 }
694
695 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000696 // A flag mask to mark an instruction as having arbitrary side effects.
697 static int AllSideEffects() {
698 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
699 }
700
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000701 // Remove the matching use from the use list if present. Returns the
702 // removed list node or NULL.
703 HUseListNode* RemoveUse(HValue* value, int index);
704
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000705 void RegisterUse(int index, HValue* new_value);
706
707 HBasicBlock* block_;
708
709 // The id of this instruction in the hydrogen graph, assigned when first
710 // added to the graph. Reflects creation order.
711 int id_;
712
713 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000714 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000715 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000716 Range* range_;
717 int flags_;
718
719 DISALLOW_COPY_AND_ASSIGN(HValue);
720};
721
722
723class HInstruction: public HValue {
724 public:
725 HInstruction* next() const { return next_; }
726 HInstruction* previous() const { return previous_; }
727
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000728 virtual void PrintTo(StringStream* stream);
729 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000730
731 bool IsLinked() const { return block() != NULL; }
732 void Unlink();
733 void InsertBefore(HInstruction* next);
734 void InsertAfter(HInstruction* previous);
735
736 int position() const { return position_; }
737 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
738 void set_position(int position) { position_ = position; }
739
740 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
741
742#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000743 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000744#endif
745
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000746 virtual bool IsCall() { return false; }
747
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000748 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000749
750 protected:
751 HInstruction()
752 : next_(NULL),
753 previous_(NULL),
754 position_(RelocInfo::kNoPosition) {
755 SetFlag(kDependsOnOsrEntries);
756 }
757
758 virtual void DeleteFromGraph() { Unlink(); }
759
760 private:
761 void InitializeAsFirst(HBasicBlock* block) {
762 ASSERT(!IsLinked());
763 SetBlock(block);
764 }
765
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000766 void PrintMnemonicTo(StringStream* stream);
767
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000768 HInstruction* next_;
769 HInstruction* previous_;
770 int position_;
771
772 friend class HBasicBlock;
773};
774
775
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000776template<int V>
777class HTemplateInstruction : public HInstruction {
778 public:
779 int OperandCount() { return V; }
780 HValue* OperandAt(int i) { return inputs_[i]; }
781
782 protected:
783 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
784
785 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000786 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000787};
788
789
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000790class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000791 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000792 virtual HBasicBlock* SuccessorAt(int i) = 0;
793 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000794 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000795
796 virtual void PrintDataTo(StringStream* stream);
797
798 HBasicBlock* FirstSuccessor() {
799 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
800 }
801 HBasicBlock* SecondSuccessor() {
802 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
803 }
804
805 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
806};
807
808
809class HSuccessorIterator BASE_EMBEDDED {
810 public:
811 explicit HSuccessorIterator(HControlInstruction* instr)
812 : instr_(instr), current_(0) { }
813
814 bool Done() { return current_ >= instr_->SuccessorCount(); }
815 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
816 void Advance() { current_++; }
817
818 private:
819 HControlInstruction* instr_;
820 int current_;
821};
822
823
824template<int S, int V>
825class HTemplateControlInstruction: public HControlInstruction {
826 public:
827 int SuccessorCount() { return S; }
828 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000829 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000830
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000831 int OperandCount() { return V; }
832 HValue* OperandAt(int i) { return inputs_[i]; }
833
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000834
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000835 protected:
836 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
837
838 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000839 EmbeddedContainer<HBasicBlock*, S> successors_;
840 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000841};
842
843
844class HBlockEntry: public HTemplateInstruction<0> {
845 public:
846 virtual Representation RequiredInputRepresentation(int index) const {
847 return Representation::None();
848 }
849
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000850 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000851};
852
853
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000854// We insert soft-deoptimize when we hit code with unknown typefeedback,
855// so that we get a chance of re-optimizing with useful typefeedback.
856// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
857class HSoftDeoptimize: public HTemplateInstruction<0> {
858 public:
859 virtual Representation RequiredInputRepresentation(int index) const {
860 return Representation::None();
861 }
862
863 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
864};
865
866
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000867class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000869 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000870
871 virtual Representation RequiredInputRepresentation(int index) const {
872 return Representation::None();
873 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000874
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000875 virtual int OperandCount() { return values_.length(); }
876 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000877 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000878
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000879 virtual int SuccessorCount() { return 0; }
880 virtual HBasicBlock* SuccessorAt(int i) {
881 UNREACHABLE();
882 return NULL;
883 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000884 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
885 UNREACHABLE();
886 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000887
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000888 void AddEnvironmentValue(HValue* value) {
889 values_.Add(NULL);
890 SetOperandAt(values_.length() - 1, value);
891 }
892
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000893 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000894
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000895 enum UseEnvironment {
896 kNoUses,
897 kUseAll
898 };
899
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000900 protected:
901 virtual void InternalSetOperandAt(int index, HValue* value) {
902 values_[index] = value;
903 }
904
905 private:
906 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907};
908
909
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000910class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000912 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000913 SetSuccessorAt(0, target);
914 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000916 virtual Representation RequiredInputRepresentation(int index) const {
917 return Representation::None();
918 }
919
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000920 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921};
922
923
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000924class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000925 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000926 HUnaryControlInstruction(HValue* value,
927 HBasicBlock* true_target,
928 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000929 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000930 SetSuccessorAt(0, true_target);
931 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932 }
933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000934 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000936 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000937};
938
939
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000940class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000942 HBranch(HValue* value,
943 HBasicBlock* true_target,
944 HBasicBlock* false_target,
945 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
946 : HUnaryControlInstruction(value, true_target, false_target),
947 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000948 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000949 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000950 explicit HBranch(HValue* value)
951 : HUnaryControlInstruction(value, NULL, NULL) { }
952
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000953
954 virtual Representation RequiredInputRepresentation(int index) const {
955 return Representation::None();
956 }
957
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000958 ToBooleanStub::Types expected_input_types() const {
959 return expected_input_types_;
960 }
961
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000962 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000963
964 private:
965 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000966};
967
968
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000969class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000970 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000971 HCompareMap(HValue* value,
972 Handle<Map> map,
973 HBasicBlock* true_target,
974 HBasicBlock* false_target)
975 : HUnaryControlInstruction(value, true_target, false_target),
976 map_(map) {
977 ASSERT(true_target != NULL);
978 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 ASSERT(!map.is_null());
980 }
981
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000982 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000983
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000984 Handle<Map> map() const { return map_; }
985
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000986 virtual Representation RequiredInputRepresentation(int index) const {
987 return Representation::Tagged();
988 }
989
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000990 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000991
992 private:
993 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000994};
995
996
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000997class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000998 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000999 explicit HReturn(HValue* value) {
1000 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001001 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001002
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001003 virtual Representation RequiredInputRepresentation(int index) const {
1004 return Representation::Tagged();
1005 }
1006
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001007 virtual void PrintDataTo(StringStream* stream);
1008
1009 HValue* value() { return OperandAt(0); }
1010
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001011 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001012};
1013
1014
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001015class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001016 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001017 virtual Representation RequiredInputRepresentation(int index) const {
1018 return Representation::None();
1019 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001021 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022};
1023
1024
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001025class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001026 public:
1027 explicit HUnaryOperation(HValue* value) {
1028 SetOperandAt(0, value);
1029 }
1030
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001031 static HUnaryOperation* cast(HValue* value) {
1032 return reinterpret_cast<HUnaryOperation*>(value);
1033 }
1034
1035 virtual bool CanTruncateToInt32() const {
1036 return CheckFlag(kTruncatingToInt32);
1037 }
1038
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001039 HValue* value() { return OperandAt(0); }
1040 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001041};
1042
1043
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001044class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001045 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001046 HThrow(HValue* context, HValue* value) {
1047 SetOperandAt(0, context);
1048 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001049 SetAllSideEffects();
1050 }
1051
1052 virtual Representation RequiredInputRepresentation(int index) const {
1053 return Representation::Tagged();
1054 }
1055
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001056 HValue* context() { return OperandAt(0); }
1057 HValue* value() { return OperandAt(1); }
1058
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001059 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001060};
1061
1062
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001063class HUseConst: public HUnaryOperation {
1064 public:
1065 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1066
1067 virtual Representation RequiredInputRepresentation(int index) const {
1068 return Representation::None();
1069 }
1070
1071 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1072};
1073
1074
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001075class HForceRepresentation: public HTemplateInstruction<1> {
1076 public:
1077 HForceRepresentation(HValue* value, Representation required_representation) {
1078 SetOperandAt(0, value);
1079 set_representation(required_representation);
1080 }
1081
1082 HValue* value() { return OperandAt(0); }
1083
1084 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1085
1086 virtual Representation RequiredInputRepresentation(int index) const {
1087 return representation(); // Same as the output representation.
1088 }
1089
1090 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1091};
1092
1093
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001094class HChange: public HUnaryOperation {
1095 public:
1096 HChange(HValue* value,
1097 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001098 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001099 bool is_truncating,
1100 bool deoptimize_on_undefined)
1101 : HUnaryOperation(value),
1102 from_(from),
1103 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104 ASSERT(!from.IsNone() && !to.IsNone());
1105 ASSERT(!from.Equals(to));
1106 set_representation(to);
1107 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001108 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001109 }
1110
1111 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1112
1113 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001114 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001115 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001116 virtual Representation RequiredInputRepresentation(int index) const {
1117 return from_;
1118 }
1119
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001120 virtual Range* InferRange();
1121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001122 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001123
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001124 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001125
1126 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001127 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001128 if (!other->IsChange()) return false;
1129 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001130 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001131 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001132 }
1133
1134 private:
1135 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001136 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001137};
1138
1139
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001140class HClampToUint8: public HUnaryOperation {
1141 public:
1142 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001143 : HUnaryOperation(value) {
1144 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001145 SetFlag(kUseGVN);
1146 }
1147
1148 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001149 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001150 }
1151
1152 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1153
1154 protected:
1155 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001156};
1157
1158
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001159class HToInt32: public HUnaryOperation {
1160 public:
1161 explicit HToInt32(HValue* value)
1162 : HUnaryOperation(value) {
1163 set_representation(Representation::Integer32());
1164 SetFlag(kUseGVN);
1165 }
1166
1167 virtual Representation RequiredInputRepresentation(int index) const {
1168 return Representation::None();
1169 }
1170
1171 virtual bool CanTruncateToInt32() const {
1172 return true;
1173 }
1174
1175 virtual HValue* Canonicalize() {
1176 if (value()->representation().IsInteger32()) {
1177 return value();
1178 } else {
1179 return this;
1180 }
1181 }
1182
1183 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1184
1185 protected:
1186 virtual bool DataEquals(HValue* other) { return true; }
1187};
1188
1189
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190class HSimulate: public HInstruction {
1191 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001192 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193 : ast_id_(ast_id),
1194 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001195 values_(2),
1196 assigned_indexes_(2) {}
1197 virtual ~HSimulate() {}
1198
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001199 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001200
1201 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1202 int ast_id() const { return ast_id_; }
1203 void set_ast_id(int id) {
1204 ASSERT(!HasAstId());
1205 ast_id_ = id;
1206 }
1207
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001208 int pop_count() const { return pop_count_; }
1209 const ZoneList<HValue*>* values() const { return &values_; }
1210 int GetAssignedIndexAt(int index) const {
1211 ASSERT(HasAssignedIndexAt(index));
1212 return assigned_indexes_[index];
1213 }
1214 bool HasAssignedIndexAt(int index) const {
1215 return assigned_indexes_[index] != kNoIndex;
1216 }
1217 void AddAssignedValue(int index, HValue* value) {
1218 AddValue(index, value);
1219 }
1220 void AddPushedValue(HValue* value) {
1221 AddValue(kNoIndex, value);
1222 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001223 virtual int OperandCount() { return values_.length(); }
1224 virtual HValue* OperandAt(int index) { return values_[index]; }
1225
1226 virtual Representation RequiredInputRepresentation(int index) const {
1227 return Representation::None();
1228 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001229
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001230 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001231
1232#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001233 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001234#endif
1235
1236 protected:
1237 virtual void InternalSetOperandAt(int index, HValue* value) {
1238 values_[index] = value;
1239 }
1240
1241 private:
1242 static const int kNoIndex = -1;
1243 void AddValue(int index, HValue* value) {
1244 assigned_indexes_.Add(index);
1245 // Resize the list of pushed values.
1246 values_.Add(NULL);
1247 // Set the operand through the base method in HValue to make sure that the
1248 // use lists are correctly updated.
1249 SetOperandAt(values_.length() - 1, value);
1250 }
1251 int ast_id_;
1252 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253 ZoneList<HValue*> values_;
1254 ZoneList<int> assigned_indexes_;
1255};
1256
1257
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001258class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001259 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001260 enum Type {
1261 kFunctionEntry,
1262 kBackwardsBranch
1263 };
1264
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001265 HStackCheck(HValue* context, Type type) : type_(type) {
1266 SetOperandAt(0, context);
1267 }
1268
1269 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001270
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001271 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001272 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001273 }
1274
ager@chromium.org04921a82011-06-27 13:21:41 +00001275 void Eliminate() {
1276 // The stack check eliminator might try to eliminate the same stack
1277 // check instruction multiple times.
1278 if (IsLinked()) {
1279 DeleteFromGraph();
1280 }
1281 }
1282
1283 bool is_function_entry() { return type_ == kFunctionEntry; }
1284 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1285
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001286 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001287
1288 private:
1289 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001290};
1291
1292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001293class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001295 HEnterInlined(Handle<JSFunction> closure,
1296 FunctionLiteral* function,
1297 CallKind call_kind)
1298 : closure_(closure),
1299 function_(function),
1300 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001301 }
1302
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001303 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001304
1305 Handle<JSFunction> closure() const { return closure_; }
1306 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001307 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001309 virtual Representation RequiredInputRepresentation(int index) const {
1310 return Representation::None();
1311 }
1312
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001313 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314
1315 private:
1316 Handle<JSFunction> closure_;
1317 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001318 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001319};
1320
1321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001322class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323 public:
1324 HLeaveInlined() {}
1325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326 virtual Representation RequiredInputRepresentation(int index) const {
1327 return Representation::None();
1328 }
1329
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001330 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001331};
1332
1333
1334class HPushArgument: public HUnaryOperation {
1335 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001336 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1337 set_representation(Representation::Tagged());
1338 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001339
1340 virtual Representation RequiredInputRepresentation(int index) const {
1341 return Representation::Tagged();
1342 }
1343
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001344 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001346 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001347};
1348
1349
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001350class HThisFunction: public HTemplateInstruction<0> {
1351 public:
1352 HThisFunction() {
1353 set_representation(Representation::Tagged());
1354 SetFlag(kUseGVN);
1355 }
1356
1357 virtual Representation RequiredInputRepresentation(int index) const {
1358 return Representation::None();
1359 }
1360
1361 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1362
1363 protected:
1364 virtual bool DataEquals(HValue* other) { return true; }
1365};
1366
1367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001368class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001369 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001370 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001371 set_representation(Representation::Tagged());
1372 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001373 }
1374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001375 virtual Representation RequiredInputRepresentation(int index) const {
1376 return Representation::None();
1377 }
1378
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001379 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001380
1381 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001382 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001383};
1384
1385
1386class HOuterContext: public HUnaryOperation {
1387 public:
1388 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1389 set_representation(Representation::Tagged());
1390 SetFlag(kUseGVN);
1391 }
1392
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001393 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001394
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001395 virtual Representation RequiredInputRepresentation(int index) const {
1396 return Representation::Tagged();
1397 }
1398
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001399 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001400 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001401};
1402
1403
1404class HGlobalObject: public HUnaryOperation {
1405 public:
1406 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1407 set_representation(Representation::Tagged());
1408 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409 }
1410
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001411 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001412
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001413 virtual Representation RequiredInputRepresentation(int index) const {
1414 return Representation::Tagged();
1415 }
1416
ager@chromium.org378b34e2011-01-28 08:04:38 +00001417 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001418 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001419};
1420
1421
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001422class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001424 explicit HGlobalReceiver(HValue* global_object)
1425 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001426 set_representation(Representation::Tagged());
1427 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001428 }
1429
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001430 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001432 virtual Representation RequiredInputRepresentation(int index) const {
1433 return Representation::Tagged();
1434 }
1435
ager@chromium.org378b34e2011-01-28 08:04:38 +00001436 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001437 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438};
1439
1440
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441template <int V>
1442class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001443 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001444 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1446 this->set_representation(Representation::Tagged());
1447 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001450 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001451
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001452 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001454 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001455
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001456 private:
1457 int argument_count_;
1458};
1459
1460
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001461class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001462 public:
1463 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001464 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001466 }
1467
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001468 virtual Representation RequiredInputRepresentation(int index) const {
1469 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001470 }
1471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001472 virtual void PrintDataTo(StringStream* stream);
1473
1474 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001475};
1476
1477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001478class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001479 public:
1480 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001481 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001482 SetOperandAt(0, first);
1483 SetOperandAt(1, second);
1484 }
1485
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001486 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001487
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001488 virtual Representation RequiredInputRepresentation(int index) const {
1489 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001490 }
1491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001492 HValue* first() { return OperandAt(0); }
1493 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001494};
1495
1496
danno@chromium.org160a7b02011-04-18 15:51:38 +00001497class HInvokeFunction: public HBinaryCall {
1498 public:
1499 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1500 : HBinaryCall(context, function, argument_count) {
1501 }
1502
1503 virtual Representation RequiredInputRepresentation(int index) const {
1504 return Representation::Tagged();
1505 }
1506
1507 HValue* context() { return first(); }
1508 HValue* function() { return second(); }
1509
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001510 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001511};
1512
1513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001514class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001515 public:
1516 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001517 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001518
1519 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001520
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001521 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001522 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001523 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001524 }
1525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001526 virtual void PrintDataTo(StringStream* stream);
1527
1528 virtual Representation RequiredInputRepresentation(int index) const {
1529 return Representation::None();
1530 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001532 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001533
1534 private:
1535 Handle<JSFunction> function_;
1536};
1537
1538
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001539class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001540 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001541 HCallKeyed(HValue* context, HValue* key, int argument_count)
1542 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001543 }
1544
1545 virtual Representation RequiredInputRepresentation(int index) const {
1546 return Representation::Tagged();
1547 }
1548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001549 HValue* context() { return first(); }
1550 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001552 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001553};
1554
1555
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001556class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001557 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001558 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1559 : HUnaryCall(context, argument_count), name_(name) {
1560 }
1561
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001562 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001564 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001565 Handle<String> name() const { return name_; }
1566
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001567 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001569 virtual Representation RequiredInputRepresentation(int index) const {
1570 return Representation::Tagged();
1571 }
1572
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001573 private:
1574 Handle<String> name_;
1575};
1576
1577
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001578class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001579 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001580 HCallFunction(HValue* context, int argument_count)
1581 : HUnaryCall(context, argument_count) {
1582 }
1583
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001584 HValue* context() { return value(); }
1585
1586 virtual Representation RequiredInputRepresentation(int index) const {
1587 return Representation::Tagged();
1588 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001589
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001590 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001591};
1592
1593
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001594class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001596 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1597 : HUnaryCall(context, argument_count), name_(name) {
1598 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001600 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603 Handle<String> name() const { return name_; }
1604
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001605 virtual Representation RequiredInputRepresentation(int index) const {
1606 return Representation::Tagged();
1607 }
1608
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001609 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001610
1611 private:
1612 Handle<String> name_;
1613};
1614
1615
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001616class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001617 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001618 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001619 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001620
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001621 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001622
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001623 Handle<JSFunction> target() const { return target_; }
1624
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001625 virtual Representation RequiredInputRepresentation(int index) const {
1626 return Representation::None();
1627 }
1628
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001629 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001630
1631 private:
1632 Handle<JSFunction> target_;
1633};
1634
1635
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001636class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001637 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001638 HCallNew(HValue* context, HValue* constructor, int argument_count)
1639 : HBinaryCall(context, constructor, argument_count) {
1640 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001641
1642 virtual Representation RequiredInputRepresentation(int index) const {
1643 return Representation::Tagged();
1644 }
1645
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001646 HValue* context() { return first(); }
1647 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001648
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001649 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001650};
1651
1652
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001653class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001655 HCallRuntime(HValue* context,
1656 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001657 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001658 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001659 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1660 SetOperandAt(0, context);
1661 }
1662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001663 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001664
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001665 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001666 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667 Handle<String> name() const { return name_; }
1668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001669 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001670 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001671 }
1672
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001673 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674
1675 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001676 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001677 Handle<String> name_;
1678};
1679
1680
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001681class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001683 HJSArrayLength(HValue* value, HValue* typecheck) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001684 // The length of an array is stored as a tagged value in the array
1685 // object. It is guaranteed to be 32 bit integer, but it can be
1686 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001687 SetOperandAt(0, value);
1688 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001689 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001690 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001691 SetFlag(kDependsOnArrayLengths);
1692 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001693 }
1694
1695 virtual Representation RequiredInputRepresentation(int index) const {
1696 return Representation::Tagged();
1697 }
1698
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001699 HValue* value() { return OperandAt(0); }
1700
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001701 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001702
1703 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001704 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001705};
1706
1707
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001708class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001709 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001710 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001711 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001712 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001713 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001714 }
1715
1716 virtual Representation RequiredInputRepresentation(int index) const {
1717 return Representation::Tagged();
1718 }
1719
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001720 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001721
1722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001723 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001724};
1725
1726
whesse@chromium.org7b260152011-06-20 15:33:18 +00001727class HElementsKind: public HUnaryOperation {
1728 public:
1729 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1730 set_representation(Representation::Integer32());
1731 SetFlag(kUseGVN);
1732 SetFlag(kDependsOnMaps);
1733 }
1734
1735 virtual Representation RequiredInputRepresentation(int index) const {
1736 return Representation::Tagged();
1737 }
1738
1739 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1740
1741 protected:
1742 virtual bool DataEquals(HValue* other) { return true; }
1743};
1744
1745
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746class HBitNot: public HUnaryOperation {
1747 public:
1748 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1749 set_representation(Representation::Integer32());
1750 SetFlag(kUseGVN);
1751 SetFlag(kTruncatingToInt32);
1752 }
1753
1754 virtual Representation RequiredInputRepresentation(int index) const {
1755 return Representation::Integer32();
1756 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001757 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001759 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001760
1761 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001762 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763};
1764
1765
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001766class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001768 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1769 : op_(op) {
1770 SetOperandAt(0, context);
1771 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001772 switch (op) {
1773 case kMathFloor:
1774 case kMathRound:
1775 case kMathCeil:
1776 set_representation(Representation::Integer32());
1777 break;
1778 case kMathAbs:
1779 set_representation(Representation::Tagged());
1780 SetFlag(kFlexibleRepresentation);
1781 break;
1782 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001783 case kMathPowHalf:
1784 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001785 case kMathSin:
1786 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001788 break;
1789 default:
1790 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001791 }
1792 SetFlag(kUseGVN);
1793 }
1794
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001795 HValue* context() { return OperandAt(0); }
1796 HValue* value() { return OperandAt(1); }
1797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001798 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001800 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801
1802 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1803
1804 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001805 if (index == 0) {
1806 return Representation::Tagged();
1807 } else {
1808 switch (op_) {
1809 case kMathFloor:
1810 case kMathRound:
1811 case kMathCeil:
1812 case kMathSqrt:
1813 case kMathPowHalf:
1814 case kMathLog:
1815 case kMathSin:
1816 case kMathCos:
1817 return Representation::Double();
1818 case kMathAbs:
1819 return representation();
1820 default:
1821 UNREACHABLE();
1822 return Representation::None();
1823 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001824 }
1825 }
1826
1827 virtual HValue* Canonicalize() {
1828 // If the input is integer32 then we replace the floor instruction
1829 // with its inputs. This happens before the representation changes are
1830 // introduced.
1831 if (op() == kMathFloor) {
1832 if (value()->representation().IsInteger32()) return value();
1833 }
1834 return this;
1835 }
1836
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001837 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001838 const char* OpName() const;
1839
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001840 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001841
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001842 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001843 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001844 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1845 return op_ == b->op();
1846 }
1847
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001849 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850};
1851
1852
1853class HLoadElements: public HUnaryOperation {
1854 public:
1855 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1856 set_representation(Representation::Tagged());
1857 SetFlag(kUseGVN);
1858 SetFlag(kDependsOnMaps);
1859 }
1860
1861 virtual Representation RequiredInputRepresentation(int index) const {
1862 return Representation::Tagged();
1863 }
1864
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001865 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001866
1867 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001868 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869};
1870
1871
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001872class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001873 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001874 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001875 : HUnaryOperation(value) {
1876 set_representation(Representation::External());
1877 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001878 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001879 // change once set, so it's no necessary to introduce any additional
1880 // dependencies on top of the inputs.
1881 SetFlag(kUseGVN);
1882 }
1883
1884 virtual Representation RequiredInputRepresentation(int index) const {
1885 return Representation::Tagged();
1886 }
1887
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001888 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001889
1890 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001891 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001892};
1893
1894
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001895class HCheckMap: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001896 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001897 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
1898 : map_(map) {
1899 SetOperandAt(0, value);
1900 // If callers don't depend on a typecheck, they can pass in NULL. In that
1901 // case we use a copy of the |value| argument as a dummy value.
1902 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001903 set_representation(Representation::Tagged());
1904 SetFlag(kUseGVN);
1905 SetFlag(kDependsOnMaps);
1906 }
1907
1908 virtual Representation RequiredInputRepresentation(int index) const {
1909 return Representation::Tagged();
1910 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001911 virtual void PrintDataTo(StringStream* stream);
1912 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001913
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001914 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001915 Handle<Map> map() const { return map_; }
1916
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001917 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001918
1919 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001920 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001921 HCheckMap* b = HCheckMap::cast(other);
1922 return map_.is_identical_to(b->map());
1923 }
1924
1925 private:
1926 Handle<Map> map_;
1927};
1928
1929
1930class HCheckFunction: public HUnaryOperation {
1931 public:
1932 HCheckFunction(HValue* value, Handle<JSFunction> function)
1933 : HUnaryOperation(value), target_(function) {
1934 set_representation(Representation::Tagged());
1935 SetFlag(kUseGVN);
1936 }
1937
1938 virtual Representation RequiredInputRepresentation(int index) const {
1939 return Representation::Tagged();
1940 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001941 virtual void PrintDataTo(StringStream* stream);
1942 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001943
1944#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001945 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001946#endif
1947
1948 Handle<JSFunction> target() const { return target_; }
1949
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001950 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001951
1952 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001953 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001954 HCheckFunction* b = HCheckFunction::cast(other);
1955 return target_.is_identical_to(b->target());
1956 }
1957
1958 private:
1959 Handle<JSFunction> target_;
1960};
1961
1962
1963class HCheckInstanceType: public HUnaryOperation {
1964 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001965 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1966 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001967 }
1968 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1969 return new HCheckInstanceType(value, IS_JS_ARRAY);
1970 }
1971 static HCheckInstanceType* NewIsString(HValue* value) {
1972 return new HCheckInstanceType(value, IS_STRING);
1973 }
1974 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1975 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001976 }
1977
1978 virtual Representation RequiredInputRepresentation(int index) const {
1979 return Representation::Tagged();
1980 }
1981
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00001982 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00001983
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001984 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1985 void GetCheckInterval(InstanceType* first, InstanceType* last);
1986 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001987
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001988 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001989
1990 protected:
1991 // TODO(ager): It could be nice to allow the ommision of instance
1992 // type checks if we have already performed an instance type check
1993 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001994 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001996 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997 }
1998
1999 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002000 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002001 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002002 IS_JS_ARRAY,
2003 IS_STRING,
2004 IS_SYMBOL,
2005 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2006 };
2007
2008 HCheckInstanceType(HValue* value, Check check)
2009 : HUnaryOperation(value), check_(check) {
2010 set_representation(Representation::Tagged());
2011 SetFlag(kUseGVN);
2012 }
2013
2014 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015};
2016
2017
2018class HCheckNonSmi: public HUnaryOperation {
2019 public:
2020 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2021 set_representation(Representation::Tagged());
2022 SetFlag(kUseGVN);
2023 }
2024
2025 virtual Representation RequiredInputRepresentation(int index) const {
2026 return Representation::Tagged();
2027 }
2028
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002029 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030
2031#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002032 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033#endif
2034
danno@chromium.org160a7b02011-04-18 15:51:38 +00002035 virtual HValue* Canonicalize() {
2036 HType value_type = value()->type();
2037 if (!value_type.IsUninitialized() &&
2038 (value_type.IsHeapNumber() ||
2039 value_type.IsString() ||
2040 value_type.IsBoolean() ||
2041 value_type.IsNonPrimitive())) {
2042 return NULL;
2043 }
2044 return this;
2045 }
2046
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002047 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002048
2049 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002050 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002051};
2052
2053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002054class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002055 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002056 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2057 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002058 SetFlag(kUseGVN);
2059 SetFlag(kDependsOnMaps);
2060 }
2061
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002062#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002063 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064#endif
2065
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002066 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002067 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002068
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002069 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002070
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002071 virtual Representation RequiredInputRepresentation(int index) const {
2072 return Representation::None();
2073 }
2074
2075 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002076 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002077 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2078 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2079 return hash;
2080 }
2081
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002083 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002084 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002085 return prototype_.is_identical_to(b->prototype()) &&
2086 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002087 }
2088
2089 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002090 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092};
2093
2094
2095class HCheckSmi: public HUnaryOperation {
2096 public:
2097 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2098 set_representation(Representation::Tagged());
2099 SetFlag(kUseGVN);
2100 }
2101
2102 virtual Representation RequiredInputRepresentation(int index) const {
2103 return Representation::Tagged();
2104 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002105 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106
2107#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002108 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109#endif
2110
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002111 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002112
2113 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002114 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115};
2116
2117
2118class HPhi: public HValue {
2119 public:
2120 explicit HPhi(int merged_index)
2121 : inputs_(2),
2122 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002123 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002124 is_live_(false),
2125 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002126 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2127 non_phi_uses_[i] = 0;
2128 indirect_uses_[i] = 0;
2129 }
2130 ASSERT(merged_index >= 0);
2131 set_representation(Representation::Tagged());
2132 SetFlag(kFlexibleRepresentation);
2133 }
2134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002135 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136 bool double_occurred = false;
2137 bool int32_occurred = false;
2138 for (int i = 0; i < OperandCount(); ++i) {
2139 HValue* value = OperandAt(i);
2140 if (value->representation().IsDouble()) double_occurred = true;
2141 if (value->representation().IsInteger32()) int32_occurred = true;
2142 if (value->representation().IsTagged()) return Representation::Tagged();
2143 }
2144
2145 if (double_occurred) return Representation::Double();
2146 if (int32_occurred) return Representation::Integer32();
2147 return Representation::None();
2148 }
2149
2150 virtual Range* InferRange();
2151 virtual Representation RequiredInputRepresentation(int index) const {
2152 return representation();
2153 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002154 virtual HType CalculateInferredType();
2155 virtual int OperandCount() { return inputs_.length(); }
2156 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2157 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002158 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002159 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002161 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002162
2163 int merged_index() const { return merged_index_; }
2164
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002165 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002166
2167#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002168 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002169#endif
2170
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002171 void InitRealUses(int id);
2172 void AddNonPhiUsesFrom(HPhi* other);
2173 void AddIndirectUsesTo(int* use_count);
2174
2175 int tagged_non_phi_uses() const {
2176 return non_phi_uses_[Representation::kTagged];
2177 }
2178 int int32_non_phi_uses() const {
2179 return non_phi_uses_[Representation::kInteger32];
2180 }
2181 int double_non_phi_uses() const {
2182 return non_phi_uses_[Representation::kDouble];
2183 }
2184 int tagged_indirect_uses() const {
2185 return indirect_uses_[Representation::kTagged];
2186 }
2187 int int32_indirect_uses() const {
2188 return indirect_uses_[Representation::kInteger32];
2189 }
2190 int double_indirect_uses() const {
2191 return indirect_uses_[Representation::kDouble];
2192 }
2193 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002194 bool is_live() { return is_live_; }
2195 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002196
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002197 static HPhi* cast(HValue* value) {
2198 ASSERT(value->IsPhi());
2199 return reinterpret_cast<HPhi*>(value);
2200 }
2201 virtual Opcode opcode() const { return HValue::kPhi; }
2202
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002203 virtual bool IsConvertibleToInteger() const {
2204 return is_convertible_to_integer_;
2205 }
2206
2207 void set_is_convertible_to_integer(bool b) {
2208 is_convertible_to_integer_ = b;
2209 }
2210
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002211 protected:
2212 virtual void DeleteFromGraph();
2213 virtual void InternalSetOperandAt(int index, HValue* value) {
2214 inputs_[index] = value;
2215 }
2216
2217 private:
2218 ZoneList<HValue*> inputs_;
2219 int merged_index_;
2220
2221 int non_phi_uses_[Representation::kNumRepresentations];
2222 int indirect_uses_[Representation::kNumRepresentations];
2223 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002224 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002225 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002226};
2227
2228
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002229class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002230 public:
2231 HArgumentsObject() {
2232 set_representation(Representation::Tagged());
2233 SetFlag(kIsArguments);
2234 }
2235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002236 virtual Representation RequiredInputRepresentation(int index) const {
2237 return Representation::None();
2238 }
2239
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002240 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002241};
2242
2243
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002244class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002245 public:
2246 HConstant(Handle<Object> handle, Representation r);
2247
2248 Handle<Object> handle() const { return handle_; }
2249
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002250 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002252 virtual Representation RequiredInputRepresentation(int index) const {
2253 return Representation::None();
2254 }
2255
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002256 virtual bool IsConvertibleToInteger() const {
2257 if (handle_->IsSmi()) return true;
2258 if (handle_->IsHeapNumber() &&
2259 (HeapNumber::cast(*handle_)->value() ==
2260 static_cast<double>(NumberToInt32(*handle_)))) return true;
2261 return false;
2262 }
2263
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002264 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002265 virtual void PrintDataTo(StringStream* stream);
2266 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002267 bool IsInteger() const { return handle_->IsSmi(); }
2268 HConstant* CopyToRepresentation(Representation r) const;
2269 HConstant* CopyToTruncatedInt32() const;
2270 bool HasInteger32Value() const { return has_int32_value_; }
2271 int32_t Integer32Value() const {
2272 ASSERT(HasInteger32Value());
2273 return int32_value_;
2274 }
2275 bool HasDoubleValue() const { return has_double_value_; }
2276 double DoubleValue() const {
2277 ASSERT(HasDoubleValue());
2278 return double_value_;
2279 }
2280 bool HasStringValue() const { return handle_->IsString(); }
2281
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002282 bool ToBoolean() const;
2283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002284 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002285 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002286 return reinterpret_cast<intptr_t>(*handle());
2287 }
2288
2289#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002290 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002291#endif
2292
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002293 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002294
2295 protected:
2296 virtual Range* InferRange();
2297
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002298 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002299 HConstant* other_constant = HConstant::cast(other);
2300 return handle().is_identical_to(other_constant->handle());
2301 }
2302
2303 private:
2304 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002305
2306 // The following two values represent the int32 and the double value of the
2307 // given constant if there is a lossless conversion between the constant
2308 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002309 bool has_int32_value_ : 1;
2310 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002311 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002312 double double_value_;
2313};
2314
2315
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002316class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002317 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002318 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002320 SetOperandAt(0, context);
2321 SetOperandAt(1, left);
2322 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002323 }
2324
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002325 HValue* context() { return OperandAt(0); }
2326 HValue* left() { return OperandAt(1); }
2327 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002328
2329 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2330 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002331 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002332 if (IsCommutative() && left()->IsConstant()) return right();
2333 return left();
2334 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002335 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336 if (IsCommutative() && left()->IsConstant()) return left();
2337 return right();
2338 }
2339
2340 virtual bool IsCommutative() const { return false; }
2341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002342 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343};
2344
2345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002346class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002347 public:
2348 HApplyArguments(HValue* function,
2349 HValue* receiver,
2350 HValue* length,
2351 HValue* elements) {
2352 set_representation(Representation::Tagged());
2353 SetOperandAt(0, function);
2354 SetOperandAt(1, receiver);
2355 SetOperandAt(2, length);
2356 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002357 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002358 }
2359
2360 virtual Representation RequiredInputRepresentation(int index) const {
2361 // The length is untagged, all other inputs are tagged.
2362 return (index == 2)
2363 ? Representation::Integer32()
2364 : Representation::Tagged();
2365 }
2366
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002367 HValue* function() { return OperandAt(0); }
2368 HValue* receiver() { return OperandAt(1); }
2369 HValue* length() { return OperandAt(2); }
2370 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002371
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002372 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002373};
2374
2375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002376class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377 public:
2378 HArgumentsElements() {
2379 // The value produced by this instruction is a pointer into the stack
2380 // that looks as if it was a smi because of alignment.
2381 set_representation(Representation::Tagged());
2382 SetFlag(kUseGVN);
2383 }
2384
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002385 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002386
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002387 virtual Representation RequiredInputRepresentation(int index) const {
2388 return Representation::None();
2389 }
2390
ager@chromium.org378b34e2011-01-28 08:04:38 +00002391 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002392 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002393};
2394
2395
2396class HArgumentsLength: public HUnaryOperation {
2397 public:
2398 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2399 set_representation(Representation::Integer32());
2400 SetFlag(kUseGVN);
2401 }
2402
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002403 virtual Representation RequiredInputRepresentation(int index) const {
2404 return Representation::Tagged();
2405 }
2406
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002407 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002408
2409 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002410 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002411};
2412
2413
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002414class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002415 public:
2416 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2417 set_representation(Representation::Tagged());
2418 SetFlag(kUseGVN);
2419 SetOperandAt(0, arguments);
2420 SetOperandAt(1, length);
2421 SetOperandAt(2, index);
2422 }
2423
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002424 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002425
2426 virtual Representation RequiredInputRepresentation(int index) const {
2427 // The arguments elements is considered tagged.
2428 return index == 0
2429 ? Representation::Tagged()
2430 : Representation::Integer32();
2431 }
2432
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002433 HValue* arguments() { return OperandAt(0); }
2434 HValue* length() { return OperandAt(1); }
2435 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002436
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002437 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002439 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002440};
2441
2442
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002443class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002444 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002445 HBoundsCheck(HValue* index, HValue* length) {
2446 SetOperandAt(0, index);
2447 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002448 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002449 SetFlag(kUseGVN);
2450 }
2451
2452 virtual Representation RequiredInputRepresentation(int index) const {
2453 return Representation::Integer32();
2454 }
2455
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002456 virtual void PrintDataTo(StringStream* stream);
2457
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002458 HValue* index() { return OperandAt(0); }
2459 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002460
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002461 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002462
2463 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002464 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002465};
2466
2467
2468class HBitwiseBinaryOperation: public HBinaryOperation {
2469 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002470 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2471 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002472 set_representation(Representation::Tagged());
2473 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002474 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002475 }
2476
2477 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002478 return index == 0
2479 ? Representation::Tagged()
2480 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002481 }
2482
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002483 virtual void RepresentationChanged(Representation to) {
2484 if (!to.IsTagged()) {
2485 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002486 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002487 SetFlag(kTruncatingToInt32);
2488 SetFlag(kUseGVN);
2489 }
2490 }
2491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002492 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002493
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002494 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002495};
2496
2497
2498class HArithmeticBinaryOperation: public HBinaryOperation {
2499 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002500 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2501 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002502 set_representation(Representation::Tagged());
2503 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002504 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002505 }
2506
2507 virtual void RepresentationChanged(Representation to) {
2508 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002509 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002510 SetFlag(kUseGVN);
2511 }
2512 }
2513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002514 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002516 return index == 0
2517 ? Representation::Tagged()
2518 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002519 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002520
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002521 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002522 if (left()->representation().Equals(right()->representation())) {
2523 return left()->representation();
2524 }
2525 return HValue::InferredRepresentation();
2526 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002527};
2528
2529
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002530class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002532 HCompareGeneric(HValue* context,
2533 HValue* left,
2534 HValue* right,
2535 Token::Value token)
2536 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002537 ASSERT(Token::IsCompareOp(token));
2538 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002539 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540 }
2541
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002542 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002543 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002545
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002547 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002549
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002551 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002552
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002553 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002554
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002555 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2556
2557 private:
2558 Token::Value token_;
2559};
2560
2561
2562class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2563 public:
2564 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2565 : token_(token) {
2566 ASSERT(Token::IsCompareOp(token));
2567 SetOperandAt(0, left);
2568 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002569 }
2570
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002571 HValue* left() { return OperandAt(0); }
2572 HValue* right() { return OperandAt(1); }
2573 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002574
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002575 void SetInputRepresentation(Representation r);
2576 Representation GetInputRepresentation() const {
2577 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002578 }
2579
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002580 virtual Representation RequiredInputRepresentation(int index) const {
2581 return input_representation_;
2582 }
2583 virtual void PrintDataTo(StringStream* stream);
2584
2585 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2586
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002587 private:
2588 Representation input_representation_;
2589 Token::Value token_;
2590};
2591
2592
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002593class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002594 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002595 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2596 SetOperandAt(0, left);
2597 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002598 }
2599
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002600 HValue* left() { return OperandAt(0); }
2601 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603 virtual Representation RequiredInputRepresentation(int index) const {
2604 return Representation::Tagged();
2605 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002607 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002608};
2609
2610
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002611class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002612 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002613 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2614 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002615 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002616 }
2617
2618 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002619 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002620 int right() const { return right_; }
2621
whesse@chromium.org7b260152011-06-20 15:33:18 +00002622 virtual Representation RequiredInputRepresentation(int index) const {
2623 return Representation::Integer32();
2624 }
2625
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002626 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002627
2628 private:
2629 const Token::Value op_;
2630 const int right_;
2631};
2632
2633
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002634class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002635 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002636 HIsNullAndBranch(HValue* value, bool is_strict)
2637 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002638
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002639 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641 virtual Representation RequiredInputRepresentation(int index) const {
2642 return Representation::Tagged();
2643 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002644
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002645 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002646
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647 private:
2648 bool is_strict_;
2649};
2650
2651
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002652class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002653 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002654 explicit HIsObjectAndBranch(HValue* value)
2655 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002656
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002657 virtual Representation RequiredInputRepresentation(int index) const {
2658 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002659 }
2660
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002661 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2662};
2663
2664
2665class HIsSmiAndBranch: public HUnaryControlInstruction {
2666 public:
2667 explicit HIsSmiAndBranch(HValue* value)
2668 : HUnaryControlInstruction(value, NULL, NULL) { }
2669
2670 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2671
2672 virtual Representation RequiredInputRepresentation(int index) const {
2673 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002674 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002675
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002676 protected:
2677 virtual bool DataEquals(HValue* other) { return true; }
2678};
2679
2680
2681class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2682 public:
2683 explicit HIsUndetectableAndBranch(HValue* value)
2684 : HUnaryControlInstruction(value, NULL, NULL) { }
2685
2686 virtual Representation RequiredInputRepresentation(int index) const {
2687 return Representation::Tagged();
2688 }
2689
2690 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2691};
2692
2693
2694class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2695 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002696 virtual Representation RequiredInputRepresentation(int index) const {
2697 return Representation::None();
2698 }
2699
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002700 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002701};
2702
2703
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002704class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002705 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002706 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2707 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2708 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2709 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002710 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2711 }
2712
2713 InstanceType from() { return from_; }
2714 InstanceType to() { return to_; }
2715
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002716 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002717
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002718 virtual Representation RequiredInputRepresentation(int index) const {
2719 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002720 }
2721
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002722 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2723
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724 private:
2725 InstanceType from_;
2726 InstanceType to_; // Inclusive range, not all combinations work.
2727};
2728
2729
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002730class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002731 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002732 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2733 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002734
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002735 virtual Representation RequiredInputRepresentation(int index) const {
2736 return Representation::Tagged();
2737 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002738
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002739 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002740};
2741
2742
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002743class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002744 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002745 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2746 set_representation(Representation::Tagged());
2747 SetFlag(kUseGVN);
2748 }
2749
2750 virtual Representation RequiredInputRepresentation(int index) const {
2751 return Representation::Tagged();
2752 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002753
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002754 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002755
2756 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002757 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002758};
2759
2760
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002761class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002762 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002763 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2764 : HUnaryControlInstruction(value, NULL, NULL),
2765 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002767 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2768
2769 virtual Representation RequiredInputRepresentation(int index) const {
2770 return Representation::Tagged();
2771 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002772
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002773 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774
2775 Handle<String> class_name() const { return class_name_; }
2776
2777 private:
2778 Handle<String> class_name_;
2779};
2780
2781
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002782class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002783 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002784 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2785 : HUnaryControlInstruction(value, NULL, NULL),
2786 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787
2788 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002791 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002793 virtual Representation RequiredInputRepresentation(int index) const {
2794 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002795 }
2796
2797 private:
2798 Handle<String> type_literal_;
2799};
2800
2801
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002802class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002803 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002804 HInstanceOf(HValue* context, HValue* left, HValue* right)
2805 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002807 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 }
2809
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002810 virtual Representation RequiredInputRepresentation(int index) const {
2811 return Representation::Tagged();
2812 }
2813
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002814 virtual HType CalculateInferredType();
2815
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002816 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002817
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002818 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002819};
2820
2821
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002822class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002823 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002824 HInstanceOfKnownGlobal(HValue* context,
2825 HValue* left,
2826 Handle<JSFunction> right)
2827 : function_(right) {
2828 SetOperandAt(0, context);
2829 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002830 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002831 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002832 }
2833
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002834 HValue* context() { return OperandAt(0); }
2835 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002836 Handle<JSFunction> function() { return function_; }
2837
2838 virtual Representation RequiredInputRepresentation(int index) const {
2839 return Representation::Tagged();
2840 }
2841
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002842 virtual HType CalculateInferredType();
2843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002844 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002845
2846 private:
2847 Handle<JSFunction> function_;
2848};
2849
2850
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002851class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002852 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002853 HPower(HValue* left, HValue* right) {
2854 SetOperandAt(0, left);
2855 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002856 set_representation(Representation::Double());
2857 SetFlag(kUseGVN);
2858 }
2859
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002860 HValue* left() { return OperandAt(0); }
2861 HValue* right() { return OperandAt(1); }
2862
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002863 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002864 return index == 0
2865 ? Representation::Double()
2866 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002867 }
2868
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002869 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002870
2871 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002872 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002873};
2874
2875
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002876class HAdd: public HArithmeticBinaryOperation {
2877 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002878 HAdd(HValue* context, HValue* left, HValue* right)
2879 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002880 SetFlag(kCanOverflow);
2881 }
2882
2883 // Add is only commutative if two integer values are added and not if two
2884 // tagged values are added (because it might be a String concatenation).
2885 virtual bool IsCommutative() const {
2886 return !representation().IsTagged();
2887 }
2888
2889 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002891 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002893 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002894
2895 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002896 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002897
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002898 virtual Range* InferRange();
2899};
2900
2901
2902class HSub: public HArithmeticBinaryOperation {
2903 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002904 HSub(HValue* context, HValue* left, HValue* right)
2905 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002906 SetFlag(kCanOverflow);
2907 }
2908
2909 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2910
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002911 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002912
2913 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002914 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002915
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002916 virtual Range* InferRange();
2917};
2918
2919
2920class HMul: public HArithmeticBinaryOperation {
2921 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002922 HMul(HValue* context, HValue* left, HValue* right)
2923 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 SetFlag(kCanOverflow);
2925 }
2926
2927 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2928
2929 // Only commutative if it is certain that not two objects are multiplicated.
2930 virtual bool IsCommutative() const {
2931 return !representation().IsTagged();
2932 }
2933
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002934 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002935
2936 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002937 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002938
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002939 virtual Range* InferRange();
2940};
2941
2942
2943class HMod: public HArithmeticBinaryOperation {
2944 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002945 HMod(HValue* context, HValue* left, HValue* right)
2946 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947 SetFlag(kCanBeDivByZero);
2948 }
2949
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002950 bool HasPowerOf2Divisor() {
2951 if (right()->IsConstant() &&
2952 HConstant::cast(right())->HasInteger32Value()) {
2953 int32_t value = HConstant::cast(right())->Integer32Value();
2954 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2955 }
2956
2957 return false;
2958 }
2959
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002960 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2961
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002962 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002963
2964 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002965 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002966
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002967 virtual Range* InferRange();
2968};
2969
2970
2971class HDiv: public HArithmeticBinaryOperation {
2972 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002973 HDiv(HValue* context, HValue* left, HValue* right)
2974 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002975 SetFlag(kCanBeDivByZero);
2976 SetFlag(kCanOverflow);
2977 }
2978
2979 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2980
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002981 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982
2983 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002984 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002985
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002986 virtual Range* InferRange();
2987};
2988
2989
2990class HBitAnd: public HBitwiseBinaryOperation {
2991 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002992 HBitAnd(HValue* context, HValue* left, HValue* right)
2993 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994
2995 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002996 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002997
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002998 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999
3000 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003001 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003002
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 virtual Range* InferRange();
3004};
3005
3006
3007class HBitXor: public HBitwiseBinaryOperation {
3008 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003009 HBitXor(HValue* context, HValue* left, HValue* right)
3010 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011
3012 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003013 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003015 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003016
3017 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003018 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019};
3020
3021
3022class HBitOr: public HBitwiseBinaryOperation {
3023 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003024 HBitOr(HValue* context, HValue* left, HValue* right)
3025 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003026
3027 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003028 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003029
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003030 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003031
3032 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003033 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003034
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003035 virtual Range* InferRange();
3036};
3037
3038
3039class HShl: public HBitwiseBinaryOperation {
3040 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003041 HShl(HValue* context, HValue* left, HValue* right)
3042 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043
3044 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003045 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003046
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003047 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003048
3049 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003050 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051};
3052
3053
3054class HShr: public HBitwiseBinaryOperation {
3055 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003056 HShr(HValue* context, HValue* left, HValue* right)
3057 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003058
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003059 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003060 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003062 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003063
3064 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003065 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066};
3067
3068
3069class HSar: public HBitwiseBinaryOperation {
3070 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003071 HSar(HValue* context, HValue* left, HValue* right)
3072 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073
3074 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003075 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003076
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003077 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003078
3079 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003080 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081};
3082
3083
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003084class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 public:
3086 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3087 SetFlag(kChangesOsrEntries);
3088 }
3089
3090 int ast_id() const { return ast_id_; }
3091
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003092 virtual Representation RequiredInputRepresentation(int index) const {
3093 return Representation::None();
3094 }
3095
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003096 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097
3098 private:
3099 int ast_id_;
3100};
3101
3102
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003103class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003104 public:
3105 explicit HParameter(unsigned index) : index_(index) {
3106 set_representation(Representation::Tagged());
3107 }
3108
3109 unsigned index() const { return index_; }
3110
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003111 virtual void PrintDataTo(StringStream* stream);
3112
3113 virtual Representation RequiredInputRepresentation(int index) const {
3114 return Representation::None();
3115 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003117 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118
3119 private:
3120 unsigned index_;
3121};
3122
3123
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003124class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003126 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3127 : HUnaryCall(context, argument_count),
3128 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 }
3131
3132 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003134 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003135
3136 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3137 transcendental_type_ = transcendental_type;
3138 }
3139 TranscendentalCache::Type transcendental_type() {
3140 return transcendental_type_;
3141 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003143 virtual void PrintDataTo(StringStream* stream);
3144
3145 virtual Representation RequiredInputRepresentation(int index) const {
3146 return Representation::Tagged();
3147 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003149 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003150
3151 private:
3152 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003153 TranscendentalCache::Type transcendental_type_;
3154};
3155
3156
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003157class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003158 public:
3159 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3160
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003161 virtual Representation RequiredInputRepresentation(int index) const {
3162 return Representation::None();
3163 }
3164
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003165 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166};
3167
3168
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003169class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003171 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172 : cell_(cell), check_hole_value_(check_hole_value) {
3173 set_representation(Representation::Tagged());
3174 SetFlag(kUseGVN);
3175 SetFlag(kDependsOnGlobalVars);
3176 }
3177
3178 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3179 bool check_hole_value() const { return check_hole_value_; }
3180
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003181 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003183 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003184 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003185 return reinterpret_cast<intptr_t>(*cell_);
3186 }
3187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003188 virtual Representation RequiredInputRepresentation(int index) const {
3189 return Representation::None();
3190 }
3191
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003192 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193
3194 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003195 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003196 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197 return cell_.is_identical_to(b->cell());
3198 }
3199
3200 private:
3201 Handle<JSGlobalPropertyCell> cell_;
3202 bool check_hole_value_;
3203};
3204
3205
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003206class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003207 public:
3208 HLoadGlobalGeneric(HValue* context,
3209 HValue* global_object,
3210 Handle<Object> name,
3211 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003212 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003213 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003214 SetOperandAt(0, context);
3215 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003216 set_representation(Representation::Tagged());
3217 SetAllSideEffects();
3218 }
3219
3220 HValue* context() { return OperandAt(0); }
3221 HValue* global_object() { return OperandAt(1); }
3222 Handle<Object> name() const { return name_; }
3223 bool for_typeof() const { return for_typeof_; }
3224
3225 virtual void PrintDataTo(StringStream* stream);
3226
3227 virtual Representation RequiredInputRepresentation(int index) const {
3228 return Representation::Tagged();
3229 }
3230
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003231 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003232
3233 private:
3234 Handle<Object> name_;
3235 bool for_typeof_;
3236};
3237
3238
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003239class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003240 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003241 HStoreGlobalCell(HValue* value,
3242 Handle<JSGlobalPropertyCell> cell,
3243 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003244 : HUnaryOperation(value),
3245 cell_(cell),
3246 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003247 SetFlag(kChangesGlobalVars);
3248 }
3249
3250 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003251 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003252
3253 virtual Representation RequiredInputRepresentation(int index) const {
3254 return Representation::Tagged();
3255 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003256 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003257
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003258 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003259
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003260 private:
3261 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003262 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263};
3264
3265
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003266class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3267 public:
3268 HStoreGlobalGeneric(HValue* context,
3269 HValue* global_object,
3270 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003271 HValue* value,
3272 bool strict_mode)
3273 : name_(name),
3274 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003275 SetOperandAt(0, context);
3276 SetOperandAt(1, global_object);
3277 SetOperandAt(2, value);
3278 set_representation(Representation::Tagged());
3279 SetAllSideEffects();
3280 }
3281
3282 HValue* context() { return OperandAt(0); }
3283 HValue* global_object() { return OperandAt(1); }
3284 Handle<Object> name() const { return name_; }
3285 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003286 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003287
3288 virtual void PrintDataTo(StringStream* stream);
3289
3290 virtual Representation RequiredInputRepresentation(int index) const {
3291 return Representation::Tagged();
3292 }
3293
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003294 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003295
3296 private:
3297 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003298 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003299};
3300
3301
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003302class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003303 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003304 HLoadContextSlot(HValue* context , int slot_index)
3305 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003306 set_representation(Representation::Tagged());
3307 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003308 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003309 }
3310
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003311 int slot_index() const { return slot_index_; }
3312
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003313 virtual Representation RequiredInputRepresentation(int index) const {
3314 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003315 }
3316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003317 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003318
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003319 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003320
3321 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003322 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003323 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003324 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003325 }
3326
3327 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003328 int slot_index_;
3329};
3330
3331
3332static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003333 return !value->type().IsBoolean()
3334 && !value->type().IsSmi()
3335 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003336}
3337
3338
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003339class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003340 public:
3341 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003342 : slot_index_(slot_index) {
3343 SetOperandAt(0, context);
3344 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003345 SetFlag(kChangesContextSlots);
3346 }
3347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003348 HValue* context() { return OperandAt(0); }
3349 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003350 int slot_index() const { return slot_index_; }
3351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003352 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003353 return StoringValueNeedsWriteBarrier(value());
3354 }
3355
3356 virtual Representation RequiredInputRepresentation(int index) const {
3357 return Representation::Tagged();
3358 }
3359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003360 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003361
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003362 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003363
3364 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003365 int slot_index_;
3366};
3367
3368
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003369class HLoadNamedField: public HUnaryOperation {
3370 public:
3371 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3372 : HUnaryOperation(object),
3373 is_in_object_(is_in_object),
3374 offset_(offset) {
3375 set_representation(Representation::Tagged());
3376 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003377 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003378 if (is_in_object) {
3379 SetFlag(kDependsOnInobjectFields);
3380 } else {
3381 SetFlag(kDependsOnBackingStoreFields);
3382 }
3383 }
3384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003385 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003386 bool is_in_object() const { return is_in_object_; }
3387 int offset() const { return offset_; }
3388
3389 virtual Representation RequiredInputRepresentation(int index) const {
3390 return Representation::Tagged();
3391 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003392 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003393
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003394 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003395
3396 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003397 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003398 HLoadNamedField* b = HLoadNamedField::cast(other);
3399 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3400 }
3401
3402 private:
3403 bool is_in_object_;
3404 int offset_;
3405};
3406
3407
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003408class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003409 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003410 HLoadNamedFieldPolymorphic(HValue* context,
3411 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003412 SmallMapList* types,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003413 Handle<String> name);
3414
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003415 HValue* context() { return OperandAt(0); }
3416 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003417 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003418 Handle<String> name() { return name_; }
3419 bool need_generic() { return need_generic_; }
3420
3421 virtual Representation RequiredInputRepresentation(int index) const {
3422 return Representation::Tagged();
3423 }
3424
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003425 virtual void PrintDataTo(StringStream* stream);
3426
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003427 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003428
3429 static const int kMaxLoadPolymorphism = 4;
3430
3431 protected:
3432 virtual bool DataEquals(HValue* value);
3433
3434 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003435 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003436 Handle<String> name_;
3437 bool need_generic_;
3438};
3439
3440
3441
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003442class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003443 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003444 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003445 : name_(name) {
3446 SetOperandAt(0, context);
3447 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003448 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003449 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450 }
3451
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003452 HValue* context() { return OperandAt(0); }
3453 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003454 Handle<Object> name() const { return name_; }
3455
3456 virtual Representation RequiredInputRepresentation(int index) const {
3457 return Representation::Tagged();
3458 }
3459
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003460 virtual void PrintDataTo(StringStream* stream);
3461
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003462 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003463
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003464 private:
3465 Handle<Object> name_;
3466};
3467
3468
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003469class HLoadFunctionPrototype: public HUnaryOperation {
3470 public:
3471 explicit HLoadFunctionPrototype(HValue* function)
3472 : HUnaryOperation(function) {
3473 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003474 SetFlag(kUseGVN);
3475 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003476 }
3477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003478 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003479
3480 virtual Representation RequiredInputRepresentation(int index) const {
3481 return Representation::Tagged();
3482 }
3483
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003484 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003485
3486 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003488};
3489
3490
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003491class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003492 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003493 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3494 SetOperandAt(0, obj);
3495 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003496 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003497 SetFlag(kDependsOnArrayElements);
3498 SetFlag(kUseGVN);
3499 }
3500
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003501 HValue* object() { return OperandAt(0); }
3502 HValue* key() { return OperandAt(1); }
3503
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003504 virtual Representation RequiredInputRepresentation(int index) const {
3505 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003506 return index == 0
3507 ? Representation::Tagged()
3508 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509 }
3510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003511 virtual void PrintDataTo(StringStream* stream);
3512
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003513 bool RequiresHoleCheck() const;
3514
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003515 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003516
3517 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003518 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519};
3520
3521
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003522class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3523 public:
3524 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3525 SetOperandAt(0, elements);
3526 SetOperandAt(1, key);
3527 set_representation(Representation::Double());
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003528 SetFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003529 SetFlag(kUseGVN);
3530 }
3531
3532 HValue* elements() { return OperandAt(0); }
3533 HValue* key() { return OperandAt(1); }
3534
3535 virtual Representation RequiredInputRepresentation(int index) const {
3536 // The key is supposed to be Integer32.
3537 return index == 0
3538 ? Representation::Tagged()
3539 : Representation::Integer32();
3540 }
3541
3542 virtual void PrintDataTo(StringStream* stream);
3543
3544 bool RequiresHoleCheck() const;
3545
3546 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3547
3548 protected:
3549 virtual bool DataEquals(HValue* other) { return true; }
3550};
3551
3552
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003553class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003554 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003555 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3556 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003557 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003558 : elements_kind_(elements_kind) {
3559 SetOperandAt(0, external_elements);
3560 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003561 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3562 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003563 set_representation(Representation::Double());
3564 } else {
3565 set_representation(Representation::Integer32());
3566 }
3567 SetFlag(kDependsOnSpecializedArrayElements);
3568 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003569 SetFlag(kDependsOnCalls);
3570 SetFlag(kUseGVN);
3571 }
3572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003573 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003574
3575 virtual Representation RequiredInputRepresentation(int index) const {
3576 // The key is supposed to be Integer32, but the base pointer
3577 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003578 return index == 0
3579 ? Representation::External()
3580 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003581 }
3582
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003583 HValue* external_pointer() { return OperandAt(0); }
3584 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003585 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003586
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003587 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003588
3589 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003590 virtual bool DataEquals(HValue* other) {
3591 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3592 HLoadKeyedSpecializedArrayElement* cast_other =
3593 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003594 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003595 }
3596
3597 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003598 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003599};
3600
3601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003602class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003604 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003605 set_representation(Representation::Tagged());
3606 SetOperandAt(0, obj);
3607 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003608 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003609 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003610 }
3611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003612 HValue* object() { return OperandAt(0); }
3613 HValue* key() { return OperandAt(1); }
3614 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003615
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003616 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003617
3618 virtual Representation RequiredInputRepresentation(int index) const {
3619 return Representation::Tagged();
3620 }
3621
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003622 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623};
3624
3625
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003626class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003627 public:
3628 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003629 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 HValue* val,
3631 bool in_object,
3632 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003633 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634 is_in_object_(in_object),
3635 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003636 SetOperandAt(0, obj);
3637 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003638 if (is_in_object_) {
3639 SetFlag(kChangesInobjectFields);
3640 } else {
3641 SetFlag(kChangesBackingStoreFields);
3642 }
3643 }
3644
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003645 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003646
3647 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003648 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003650 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003652 HValue* object() { return OperandAt(0); }
3653 HValue* value() { return OperandAt(1); }
3654
3655 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003656 bool is_in_object() const { return is_in_object_; }
3657 int offset() const { return offset_; }
3658 Handle<Map> transition() const { return transition_; }
3659 void set_transition(Handle<Map> map) { transition_ = map; }
3660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003661 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003662 return StoringValueNeedsWriteBarrier(value());
3663 }
3664
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003665 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003666 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003667 bool is_in_object_;
3668 int offset_;
3669 Handle<Map> transition_;
3670};
3671
3672
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003673class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003674 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003675 HStoreNamedGeneric(HValue* context,
3676 HValue* object,
3677 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003678 HValue* value,
3679 bool strict_mode)
3680 : name_(name),
3681 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003682 SetOperandAt(0, object);
3683 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003684 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003685 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003686 }
3687
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003688 HValue* object() { return OperandAt(0); }
3689 HValue* value() { return OperandAt(1); }
3690 HValue* context() { return OperandAt(2); }
3691 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003692 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003693
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003694 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695
3696 virtual Representation RequiredInputRepresentation(int index) const {
3697 return Representation::Tagged();
3698 }
3699
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003700 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003702 private:
3703 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003704 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003705};
3706
3707
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003708class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003709 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003710 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3711 SetOperandAt(0, obj);
3712 SetOperandAt(1, key);
3713 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003714 SetFlag(kChangesArrayElements);
3715 }
3716
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003717 virtual Representation RequiredInputRepresentation(int index) const {
3718 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003719 return index == 1
3720 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003721 : Representation::Tagged();
3722 }
3723
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003724 HValue* object() { return OperandAt(0); }
3725 HValue* key() { return OperandAt(1); }
3726 HValue* value() { return OperandAt(2); }
3727
3728 bool NeedsWriteBarrier() {
3729 return StoringValueNeedsWriteBarrier(value());
3730 }
3731
3732 virtual void PrintDataTo(StringStream* stream);
3733
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003734 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003735};
3736
3737
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003738class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3739 public:
3740 HStoreKeyedFastDoubleElement(HValue* elements,
3741 HValue* key,
3742 HValue* val) {
3743 SetOperandAt(0, elements);
3744 SetOperandAt(1, key);
3745 SetOperandAt(2, val);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003746 SetFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003747 }
3748
3749 virtual Representation RequiredInputRepresentation(int index) const {
3750 if (index == 1) {
3751 return Representation::Integer32();
3752 } else if (index == 2) {
3753 return Representation::Double();
3754 } else {
3755 return Representation::Tagged();
3756 }
3757 }
3758
3759 HValue* elements() { return OperandAt(0); }
3760 HValue* key() { return OperandAt(1); }
3761 HValue* value() { return OperandAt(2); }
3762
3763 bool NeedsWriteBarrier() {
3764 return StoringValueNeedsWriteBarrier(value());
3765 }
3766
3767 virtual void PrintDataTo(StringStream* stream);
3768
3769 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3770};
3771
3772
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003773class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003774 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003775 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3776 HValue* key,
3777 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003778 JSObject::ElementsKind elements_kind)
3779 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003780 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003781 SetOperandAt(0, external_elements);
3782 SetOperandAt(1, key);
3783 SetOperandAt(2, val);
3784 }
3785
3786 virtual void PrintDataTo(StringStream* stream);
3787
3788 virtual Representation RequiredInputRepresentation(int index) const {
3789 if (index == 0) {
3790 return Representation::External();
3791 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003792 bool float_or_double_elements =
3793 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3794 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3795 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003796 return Representation::Double();
3797 } else {
3798 return Representation::Integer32();
3799 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003800 }
3801 }
3802
3803 HValue* external_pointer() { return OperandAt(0); }
3804 HValue* key() { return OperandAt(1); }
3805 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003806 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003807
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003808 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3809
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003810 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003811 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003812};
3813
3814
3815class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003816 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003817 HStoreKeyedGeneric(HValue* context,
3818 HValue* object,
3819 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003820 HValue* value,
3821 bool strict_mode)
3822 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003823 SetOperandAt(0, object);
3824 SetOperandAt(1, key);
3825 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003826 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003827 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003828 }
3829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003830 HValue* object() { return OperandAt(0); }
3831 HValue* key() { return OperandAt(1); }
3832 HValue* value() { return OperandAt(2); }
3833 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003834 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003835
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003836 virtual Representation RequiredInputRepresentation(int index) const {
3837 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003838 }
3839
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003840 virtual void PrintDataTo(StringStream* stream);
3841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003842 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003843
3844 private:
3845 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003846};
3847
3848
danno@chromium.org160a7b02011-04-18 15:51:38 +00003849class HStringAdd: public HBinaryOperation {
3850 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003851 HStringAdd(HValue* context, HValue* left, HValue* right)
3852 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003853 set_representation(Representation::Tagged());
3854 SetFlag(kUseGVN);
3855 SetFlag(kDependsOnMaps);
3856 }
3857
3858 virtual Representation RequiredInputRepresentation(int index) const {
3859 return Representation::Tagged();
3860 }
3861
3862 virtual HType CalculateInferredType() {
3863 return HType::String();
3864 }
3865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003866 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003867
3868 protected:
3869 virtual bool DataEquals(HValue* other) { return true; }
3870};
3871
3872
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003873class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003874 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003875 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3876 SetOperandAt(0, context);
3877 SetOperandAt(1, string);
3878 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003879 set_representation(Representation::Integer32());
3880 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003881 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003882 }
3883
3884 virtual Representation RequiredInputRepresentation(int index) const {
3885 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003886 return index == 2
3887 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003888 : Representation::Tagged();
3889 }
3890
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003891 HValue* context() { return OperandAt(0); }
3892 HValue* string() { return OperandAt(1); }
3893 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003894
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003895 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003896
3897 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003898 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003899
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003900 virtual Range* InferRange() {
3901 return new Range(0, String::kMaxUC16CharCode);
3902 }
3903};
3904
3905
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003906class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003907 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003908 HStringCharFromCode(HValue* context, HValue* char_code) {
3909 SetOperandAt(0, context);
3910 SetOperandAt(1, char_code);
3911 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003912 SetFlag(kUseGVN);
3913 }
3914
3915 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003916 return index == 0
3917 ? Representation::Tagged()
3918 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003919 }
3920
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003921 HValue* context() { return OperandAt(0); }
3922 HValue* value() { return OperandAt(1); }
3923
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003924 virtual bool DataEquals(HValue* other) { return true; }
3925
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003926 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003927};
3928
3929
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003930class HStringLength: public HUnaryOperation {
3931 public:
3932 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3933 set_representation(Representation::Tagged());
3934 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003935 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003936 }
3937
3938 virtual Representation RequiredInputRepresentation(int index) const {
3939 return Representation::Tagged();
3940 }
3941
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003942 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003943 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3944 return HType::Smi();
3945 }
3946
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003947 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003948
3949 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003950 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003951
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003952 virtual Range* InferRange() {
3953 return new Range(0, String::kMaxLength);
3954 }
3955};
3956
3957
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003958template <int V>
3959class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003960 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003961 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003962 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003963 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003964 }
3965
3966 int literal_index() const { return literal_index_; }
3967 int depth() const { return depth_; }
3968
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003969 private:
3970 int literal_index_;
3971 int depth_;
3972};
3973
3974
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003975class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003976 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003977 HArrayLiteral(HValue* context,
3978 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003979 int length,
3980 int literal_index,
3981 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003982 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003983 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003984 constant_elements_(constant_elements) {
3985 SetOperandAt(0, context);
3986 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003987
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003988 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003989 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3990 int length() const { return length_; }
3991
3992 bool IsCopyOnWrite() const;
3993
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003994 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003995 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003996 }
3997
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003998 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003999
4000 private:
4001 int length_;
4002 Handle<FixedArray> constant_elements_;
4003};
4004
4005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004006class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004007 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004008 HObjectLiteral(HValue* context,
4009 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004010 bool fast_elements,
4011 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004012 int depth,
4013 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004014 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004015 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004016 fast_elements_(fast_elements),
4017 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004018 SetOperandAt(0, context);
4019 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004020
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004021 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004022 Handle<FixedArray> constant_properties() const {
4023 return constant_properties_;
4024 }
4025 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004026 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004027
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004028 virtual Representation RequiredInputRepresentation(int index) const {
4029 return Representation::Tagged();
4030 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004031
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004032 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004033
4034 private:
4035 Handle<FixedArray> constant_properties_;
4036 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004037 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004038};
4039
4040
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004041class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004042 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004043 HRegExpLiteral(HValue* context,
4044 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004045 Handle<String> flags,
4046 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004047 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004048 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004049 flags_(flags) {
4050 SetOperandAt(0, context);
4051 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004052
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004053 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004054 Handle<String> pattern() { return pattern_; }
4055 Handle<String> flags() { return flags_; }
4056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004057 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004058 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004059 }
4060
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004061 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004062
4063 private:
4064 Handle<String> pattern_;
4065 Handle<String> flags_;
4066};
4067
4068
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004069class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004070 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004071 HFunctionLiteral(HValue* context,
4072 Handle<SharedFunctionInfo> shared,
4073 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004074 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004075 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004076 set_representation(Representation::Tagged());
4077 }
4078
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004079 HValue* context() { return OperandAt(0); }
4080
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004081 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004082 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004083 }
4084
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004085 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004086
4087 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4088 bool pretenure() const { return pretenure_; }
4089
4090 private:
4091 Handle<SharedFunctionInfo> shared_info_;
4092 bool pretenure_;
4093};
4094
4095
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004096class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004097 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004098 explicit HTypeof(HValue* context, HValue* value) {
4099 SetOperandAt(0, context);
4100 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004101 set_representation(Representation::Tagged());
4102 }
4103
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004104 HValue* context() { return OperandAt(0); }
4105 HValue* value() { return OperandAt(1); }
4106
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004107 virtual Representation RequiredInputRepresentation(int index) const {
4108 return Representation::Tagged();
4109 }
4110
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004111 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004112};
4113
4114
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004115class HToFastProperties: public HUnaryOperation {
4116 public:
4117 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4118 // This instruction is not marked as having side effects, but
4119 // changes the map of the input operand. Use it only when creating
4120 // object literals.
4121 ASSERT(value->IsObjectLiteral());
4122 set_representation(Representation::Tagged());
4123 }
4124
4125 virtual Representation RequiredInputRepresentation(int index) const {
4126 return Representation::Tagged();
4127 }
4128
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004129 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004130};
4131
4132
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004133class HValueOf: public HUnaryOperation {
4134 public:
4135 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4136 set_representation(Representation::Tagged());
4137 }
4138
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004139 virtual Representation RequiredInputRepresentation(int index) const {
4140 return Representation::Tagged();
4141 }
4142
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004143 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004144};
4145
4146
4147class HDeleteProperty: public HBinaryOperation {
4148 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004149 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4150 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004151 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004152 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004153 }
4154
4155 virtual Representation RequiredInputRepresentation(int index) const {
4156 return Representation::Tagged();
4157 }
4158
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004159 virtual HType CalculateInferredType();
4160
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004161 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004162
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004163 HValue* object() { return left(); }
4164 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004165};
4166
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004167
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004168class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004169 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004170 HIn(HValue* context, HValue* key, HValue* object) {
4171 SetOperandAt(0, context);
4172 SetOperandAt(1, key);
4173 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004174 set_representation(Representation::Tagged());
4175 SetAllSideEffects();
4176 }
4177
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004178 HValue* context() { return OperandAt(0); }
4179 HValue* key() { return OperandAt(1); }
4180 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004181
4182 virtual Representation RequiredInputRepresentation(int index) const {
4183 return Representation::Tagged();
4184 }
4185
4186 virtual HType CalculateInferredType() {
4187 return HType::Boolean();
4188 }
4189
4190 virtual void PrintDataTo(StringStream* stream);
4191
4192 DECLARE_CONCRETE_INSTRUCTION(In)
4193};
4194
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004195#undef DECLARE_INSTRUCTION
4196#undef DECLARE_CONCRETE_INSTRUCTION
4197
4198} } // namespace v8::internal
4199
4200#endif // V8_HYDROGEN_INSTRUCTIONS_H_