blob: a6b2f566760cdb083e59b67222872d0a21edfac4 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
48class HInstruction;
49class HLoopInformation;
50class HValue;
51class LInstruction;
52class LChunkBuilder;
53
54
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000055#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 V(ControlInstruction) \
58 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059
60
61#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000062 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000063 V(AccessArgumentsAt) \
64 V(Add) \
65 V(ApplyArguments) \
66 V(ArgumentsElements) \
67 V(ArgumentsLength) \
68 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ArrayLiteral) \
70 V(BitAnd) \
71 V(BitNot) \
72 V(BitOr) \
73 V(BitXor) \
74 V(BlockEntry) \
75 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000076 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000077 V(CallConstantFunction) \
78 V(CallFunction) \
79 V(CallGlobal) \
80 V(CallKeyed) \
81 V(CallKnownGlobal) \
82 V(CallNamed) \
83 V(CallNew) \
84 V(CallRuntime) \
85 V(CallStub) \
86 V(Change) \
87 V(CheckFunction) \
88 V(CheckInstanceType) \
89 V(CheckMap) \
90 V(CheckNonSmi) \
91 V(CheckPrototypeMaps) \
92 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000093 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000094 V(ClassOfTestAndBranch) \
95 V(CompareIDAndBranch) \
96 V(CompareGeneric) \
97 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000098 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000099 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000101 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000105 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(EnterInlined) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000107 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000108 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000109 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000110 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(GlobalObject) \
112 V(GlobalReceiver) \
113 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000114 V(HasCachedArrayIndexAndBranch) \
115 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000116 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000118 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000119 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000120 V(IsConstructCallAndBranch) \
121 V(IsNullAndBranch) \
122 V(IsObjectAndBranch) \
123 V(IsSmiAndBranch) \
124 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000125 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000127 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000129 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000130 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000131 V(LoadGlobalCell) \
132 V(LoadGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000133 V(LoadKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadKeyedFastElement) \
135 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000136 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000138 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139 V(LoadNamedGeneric) \
140 V(Mod) \
141 V(Mul) \
142 V(ObjectLiteral) \
143 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000144 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000145 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000146 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(PushArgument) \
148 V(RegExpLiteral) \
149 V(Return) \
150 V(Sar) \
151 V(Shl) \
152 V(Shr) \
153 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000154 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000156 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000157 V(StoreGlobalCell) \
158 V(StoreGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000159 V(StoreKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(StoreKeyedFastElement) \
161 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000162 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 V(StoreNamedField) \
164 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000165 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000166 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000167 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000168 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000169 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000170 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000171 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000172 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000173 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000175 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(UnaryMathOperation) \
177 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000178 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 V(ValueOf)
180
181#define GVN_FLAG_LIST(V) \
182 V(Calls) \
183 V(InobjectFields) \
184 V(BackingStoreFields) \
185 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000186 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000187 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 V(GlobalVars) \
189 V(Maps) \
190 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000191 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192 V(OsrEntries)
193
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000194#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195 virtual bool Is##type() const { return true; } \
196 static H##type* cast(HValue* value) { \
197 ASSERT(value->Is##type()); \
198 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000199 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
201
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000202#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000204 static H##type* cast(HValue* value) { \
205 ASSERT(value->Is##type()); \
206 return reinterpret_cast<H##type*>(value); \
207 } \
208 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209
210
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211class Range: public ZoneObject {
212 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000213 Range()
214 : lower_(kMinInt),
215 upper_(kMaxInt),
216 next_(NULL),
217 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218
219 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000220 : lower_(lower),
221 upper_(upper),
222 next_(NULL),
223 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 int32_t upper() const { return upper_; }
226 int32_t lower() const { return lower_; }
227 Range* next() const { return next_; }
228 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
229 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000230 Range* Copy() const {
231 Range* result = new Range(lower_, upper_);
232 result->set_can_be_minus_zero(CanBeMinusZero());
233 return result;
234 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235 int32_t Mask() const;
236 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
237 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
238 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
239 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000240 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000241 bool IsMostGeneric() const {
242 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
243 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000244 bool IsInSmiRange() const {
245 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000246 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 void KeepOrder();
248 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000249
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000250 void StackUpon(Range* other) {
251 Intersect(other);
252 next_ = other;
253 }
254
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000255 void Intersect(Range* other);
256 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000257
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000258 void AddConstant(int32_t value);
259 void Sar(int32_t value);
260 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000261 bool AddAndCheckOverflow(Range* other);
262 bool SubAndCheckOverflow(Range* other);
263 bool MulAndCheckOverflow(Range* other);
264
265 private:
266 int32_t lower_;
267 int32_t upper_;
268 Range* next_;
269 bool can_be_minus_zero_;
270};
271
272
273class Representation {
274 public:
275 enum Kind {
276 kNone,
277 kTagged,
278 kDouble,
279 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000280 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000281 kNumRepresentations
282 };
283
284 Representation() : kind_(kNone) { }
285
286 static Representation None() { return Representation(kNone); }
287 static Representation Tagged() { return Representation(kTagged); }
288 static Representation Integer32() { return Representation(kInteger32); }
289 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000290 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000292 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000293 return kind_ == other.kind_;
294 }
295
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000296 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000297 bool IsNone() const { return kind_ == kNone; }
298 bool IsTagged() const { return kind_ == kTagged; }
299 bool IsInteger32() const { return kind_ == kInteger32; }
300 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000301 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302 bool IsSpecialization() const {
303 return kind_ == kInteger32 || kind_ == kDouble;
304 }
305 const char* Mnemonic() const;
306
307 private:
308 explicit Representation(Kind k) : kind_(k) { }
309
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000310 // Make sure kind fits in int8.
311 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
312
313 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000314};
315
316
317class HType {
318 public:
319 HType() : type_(kUninitialized) { }
320
321 static HType Tagged() { return HType(kTagged); }
322 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
323 static HType TaggedNumber() { return HType(kTaggedNumber); }
324 static HType Smi() { return HType(kSmi); }
325 static HType HeapNumber() { return HType(kHeapNumber); }
326 static HType String() { return HType(kString); }
327 static HType Boolean() { return HType(kBoolean); }
328 static HType NonPrimitive() { return HType(kNonPrimitive); }
329 static HType JSArray() { return HType(kJSArray); }
330 static HType JSObject() { return HType(kJSObject); }
331 static HType Uninitialized() { return HType(kUninitialized); }
332
333 // Return the weakest (least precise) common type.
334 HType Combine(HType other) {
335 return HType(static_cast<Type>(type_ & other.type_));
336 }
337
338 bool Equals(const HType& other) {
339 return type_ == other.type_;
340 }
341
342 bool IsSubtypeOf(const HType& other) {
343 return Combine(other).Equals(other);
344 }
345
346 bool IsTagged() {
347 ASSERT(type_ != kUninitialized);
348 return ((type_ & kTagged) == kTagged);
349 }
350
351 bool IsTaggedPrimitive() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
354 }
355
356 bool IsTaggedNumber() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kTaggedNumber) == kTaggedNumber);
359 }
360
361 bool IsSmi() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kSmi) == kSmi);
364 }
365
366 bool IsHeapNumber() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kHeapNumber) == kHeapNumber);
369 }
370
371 bool IsString() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kString) == kString);
374 }
375
376 bool IsBoolean() {
377 ASSERT(type_ != kUninitialized);
378 return ((type_ & kBoolean) == kBoolean);
379 }
380
381 bool IsNonPrimitive() {
382 ASSERT(type_ != kUninitialized);
383 return ((type_ & kNonPrimitive) == kNonPrimitive);
384 }
385
386 bool IsJSArray() {
387 ASSERT(type_ != kUninitialized);
388 return ((type_ & kJSArray) == kJSArray);
389 }
390
391 bool IsJSObject() {
392 ASSERT(type_ != kUninitialized);
393 return ((type_ & kJSObject) == kJSObject);
394 }
395
396 bool IsUninitialized() {
397 return type_ == kUninitialized;
398 }
399
400 static HType TypeFromValue(Handle<Object> value);
401
402 const char* ToString();
403 const char* ToShortString();
404
405 private:
406 enum Type {
407 kTagged = 0x1, // 0000 0000 0000 0001
408 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
409 kTaggedNumber = 0xd, // 0000 0000 0000 1101
410 kSmi = 0x1d, // 0000 0000 0001 1101
411 kHeapNumber = 0x2d, // 0000 0000 0010 1101
412 kString = 0x45, // 0000 0000 0100 0101
413 kBoolean = 0x85, // 0000 0000 1000 0101
414 kNonPrimitive = 0x101, // 0000 0001 0000 0001
415 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000416 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000417 kUninitialized = 0x1fff // 0001 1111 1111 1111
418 };
419
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000420 // Make sure type fits in int16.
421 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
422
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000423 explicit HType(Type t) : type_(t) { }
424
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000425 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000426};
427
428
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000429class HUseListNode: public ZoneObject {
430 public:
431 HUseListNode(HValue* value, int index, HUseListNode* tail)
432 : tail_(tail), value_(value), index_(index) {
433 }
434
435 HUseListNode* tail() const { return tail_; }
436 HValue* value() const { return value_; }
437 int index() const { return index_; }
438
439 void set_tail(HUseListNode* list) { tail_ = list; }
440
441#ifdef DEBUG
442 void Zap() {
443 tail_ = reinterpret_cast<HUseListNode*>(1);
444 value_ = NULL;
445 index_ = -1;
446 }
447#endif
448
449 private:
450 HUseListNode* tail_;
451 HValue* value_;
452 int index_;
453};
454
455
456// We reuse use list nodes behind the scenes as uses are added and deleted.
457// This class is the safe way to iterate uses while deleting them.
458class HUseIterator BASE_EMBEDDED {
459 public:
460 bool Done() { return current_ == NULL; }
461 void Advance();
462
463 HValue* value() {
464 ASSERT(!Done());
465 return value_;
466 }
467
468 int index() {
469 ASSERT(!Done());
470 return index_;
471 }
472
473 private:
474 explicit HUseIterator(HUseListNode* head);
475
476 HUseListNode* current_;
477 HUseListNode* next_;
478 HValue* value_;
479 int index_;
480
481 friend class HValue;
482};
483
484
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000485class HValue: public ZoneObject {
486 public:
487 static const int kNoNumber = -1;
488
489 // There must be one corresponding kDepends flag for every kChanges flag and
490 // the order of the kChanges flags must be exactly the same as of the kDepends
491 // flags.
492 enum Flag {
493 // Declare global value numbering flags.
494 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
495 GVN_FLAG_LIST(DECLARE_DO)
496 #undef DECLARE_DO
497 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000498 // Participate in Global Value Numbering, i.e. elimination of
499 // unnecessary recomputations. If an instruction sets this flag, it must
500 // implement DataEquals(), which will be used to determine if other
501 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000502 kUseGVN,
503 kCanOverflow,
504 kBailoutOnMinusZero,
505 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000506 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000507 kIsArguments,
508 kTruncatingToInt32,
509 kLastFlag = kTruncatingToInt32
510 };
511
512 STATIC_ASSERT(kLastFlag < kBitsPerInt);
513
514 static const int kChangesToDependsFlagsLeftShift = 1;
515
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000516 static int ConvertChangesToDependsFlags(int flags) {
517 return flags << kChangesToDependsFlagsLeftShift;
518 }
519
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000520 static HValue* cast(HValue* value) { return value; }
521
522 enum Opcode {
523 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000524 #define DECLARE_OPCODE(type) k##type,
525 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
526 kPhi
527 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000528 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000529 virtual Opcode opcode() const = 0;
530
531 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
532 #define DECLARE_PREDICATE(type) \
533 bool Is##type() const { return opcode() == k##type; }
534 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
535 #undef DECLARE_PREDICATE
536 bool IsPhi() const { return opcode() == kPhi; }
537
538 // Declare virtual predicates for abstract HInstruction or HValue
539 #define DECLARE_PREDICATE(type) \
540 virtual bool Is##type() const { return false; }
541 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
542 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000543
544 HValue() : block_(NULL),
545 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000546 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000547 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000548 range_(NULL),
549 flags_(0) {}
550 virtual ~HValue() {}
551
552 HBasicBlock* block() const { return block_; }
553 void SetBlock(HBasicBlock* block);
554
555 int id() const { return id_; }
556 void set_id(int id) { id_ = id; }
557
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000558 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000560 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000561 Representation representation() const { return representation_; }
562 void ChangeRepresentation(Representation r) {
563 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564 ASSERT(!r.IsNone());
565 ASSERT(CheckFlag(kFlexibleRepresentation));
566 RepresentationChanged(r);
567 representation_ = r;
568 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000569 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000570
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000571 virtual bool IsConvertibleToInteger() const { return true; }
572
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000573 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000574 void set_type(HType new_type) {
575 ASSERT(new_type.IsSubtypeOf(type_));
576 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577 }
578
579 // An operation needs to override this function iff:
580 // 1) it can produce an int32 output.
581 // 2) the true value of its output can potentially be minus zero.
582 // The implementation must set a flag so that it bails out in the case where
583 // it would otherwise output what should be a minus zero as an int32 zero.
584 // If the operation also exists in a form that takes int32 and outputs int32
585 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000586 // back. There are three operations that need to propagate back to more than
587 // one input. They are phi and binary div and mul. They always return NULL
588 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000589 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
590 visited->Add(id());
591 return NULL;
592 }
593
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000594 bool IsDefinedAfter(HBasicBlock* other) const;
595
596 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000597 virtual int OperandCount() = 0;
598 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599 void SetOperandAt(int index, HValue* value);
600
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000601 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000602 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000603 bool HasNoUses() const { return use_list_ == NULL; }
604 bool HasMultipleUses() const {
605 return use_list_ != NULL && use_list_->tail() != NULL;
606 }
607 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000608 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000609
610 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000611 void SetFlag(Flag f) { flags_ |= (1 << f); }
612 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
613 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
614
615 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
616 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
617 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000618
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000619 int ChangesFlags() const { return flags_ & ChangesFlagsMask(); }
620
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000621 Range* range() const { return range_; }
622 bool HasRange() const { return range_ != NULL; }
623 void AddNewRange(Range* r);
624 void RemoveLastAddedRange();
625 void ComputeInitialRange();
626
627 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000628 virtual Representation RequiredInputRepresentation(int index) const = 0;
629
630 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000631 return representation();
632 }
633
634 // This gives the instruction an opportunity to replace itself with an
635 // instruction that does the same in some better way. To replace an
636 // instruction with a new one, first add the new instruction to the graph,
637 // then return it. Return NULL to have the instruction deleted.
638 virtual HValue* Canonicalize() { return this; }
639
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000640 bool Equals(HValue* other);
641 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000642
643 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000644 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000646 void PrintTypeTo(StringStream* stream);
647 void PrintRangeTo(StringStream* stream);
648 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000649
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000650 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000651
652 // Updated the inferred type of this instruction and returns true if
653 // it has changed.
654 bool UpdateInferredType();
655
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000656 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000657
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000658#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000659 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660#endif
661
662 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000663 // This function must be overridden for instructions with flag kUseGVN, to
664 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000665 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000666 UNREACHABLE();
667 return false;
668 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000669 virtual void RepresentationChanged(Representation to) { }
670 virtual Range* InferRange();
671 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000672 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000673 void clear_block() {
674 ASSERT(block_ != NULL);
675 block_ = NULL;
676 }
677
678 void set_representation(Representation r) {
679 // Representation is set-once.
680 ASSERT(representation_.IsNone() && !r.IsNone());
681 representation_ = r;
682 }
683
684 private:
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000685 static int ChangesFlagsMask() {
686 int result = 0;
687 // Create changes mask.
688#define ADD_FLAG(type) result |= (1 << kChanges##type);
689 GVN_FLAG_LIST(ADD_FLAG)
690#undef ADD_FLAG
691 return result;
692 }
693
ager@chromium.org378b34e2011-01-28 08:04:38 +0000694 // A flag mask to mark an instruction as having arbitrary side effects.
695 static int AllSideEffects() {
696 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
697 }
698
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000699 // Remove the matching use from the use list if present. Returns the
700 // removed list node or NULL.
701 HUseListNode* RemoveUse(HValue* value, int index);
702
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000703 void RegisterUse(int index, HValue* new_value);
704
705 HBasicBlock* block_;
706
707 // The id of this instruction in the hydrogen graph, assigned when first
708 // added to the graph. Reflects creation order.
709 int id_;
710
711 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000712 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000713 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000714 Range* range_;
715 int flags_;
716
717 DISALLOW_COPY_AND_ASSIGN(HValue);
718};
719
720
721class HInstruction: public HValue {
722 public:
723 HInstruction* next() const { return next_; }
724 HInstruction* previous() const { return previous_; }
725
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000726 virtual void PrintTo(StringStream* stream);
727 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000728
729 bool IsLinked() const { return block() != NULL; }
730 void Unlink();
731 void InsertBefore(HInstruction* next);
732 void InsertAfter(HInstruction* previous);
733
734 int position() const { return position_; }
735 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
736 void set_position(int position) { position_ = position; }
737
738 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
739
740#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000741 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000742#endif
743
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000744 virtual bool IsCall() { return false; }
745
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000746 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000747
748 protected:
749 HInstruction()
750 : next_(NULL),
751 previous_(NULL),
752 position_(RelocInfo::kNoPosition) {
753 SetFlag(kDependsOnOsrEntries);
754 }
755
756 virtual void DeleteFromGraph() { Unlink(); }
757
758 private:
759 void InitializeAsFirst(HBasicBlock* block) {
760 ASSERT(!IsLinked());
761 SetBlock(block);
762 }
763
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000764 void PrintMnemonicTo(StringStream* stream);
765
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000766 HInstruction* next_;
767 HInstruction* previous_;
768 int position_;
769
770 friend class HBasicBlock;
771};
772
773
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000774template<int V>
775class HTemplateInstruction : public HInstruction {
776 public:
777 int OperandCount() { return V; }
778 HValue* OperandAt(int i) { return inputs_[i]; }
779
780 protected:
781 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
782
783 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000784 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000785};
786
787
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000788class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000789 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000790 virtual HBasicBlock* SuccessorAt(int i) = 0;
791 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000792 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000793
794 virtual void PrintDataTo(StringStream* stream);
795
796 HBasicBlock* FirstSuccessor() {
797 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
798 }
799 HBasicBlock* SecondSuccessor() {
800 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
801 }
802
803 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
804};
805
806
807class HSuccessorIterator BASE_EMBEDDED {
808 public:
809 explicit HSuccessorIterator(HControlInstruction* instr)
810 : instr_(instr), current_(0) { }
811
812 bool Done() { return current_ >= instr_->SuccessorCount(); }
813 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
814 void Advance() { current_++; }
815
816 private:
817 HControlInstruction* instr_;
818 int current_;
819};
820
821
822template<int S, int V>
823class HTemplateControlInstruction: public HControlInstruction {
824 public:
825 int SuccessorCount() { return S; }
826 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000827 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000829 int OperandCount() { return V; }
830 HValue* OperandAt(int i) { return inputs_[i]; }
831
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000832
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000833 protected:
834 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
835
836 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000837 EmbeddedContainer<HBasicBlock*, S> successors_;
838 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000839};
840
841
842class HBlockEntry: public HTemplateInstruction<0> {
843 public:
844 virtual Representation RequiredInputRepresentation(int index) const {
845 return Representation::None();
846 }
847
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000848 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000849};
850
851
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000852// We insert soft-deoptimize when we hit code with unknown typefeedback,
853// so that we get a chance of re-optimizing with useful typefeedback.
854// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
855class HSoftDeoptimize: public HTemplateInstruction<0> {
856 public:
857 virtual Representation RequiredInputRepresentation(int index) const {
858 return Representation::None();
859 }
860
861 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
862};
863
864
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000865class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000866 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000867 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868
869 virtual Representation RequiredInputRepresentation(int index) const {
870 return Representation::None();
871 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000872
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000873 virtual int OperandCount() { return values_.length(); }
874 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000875 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000876
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000877 virtual int SuccessorCount() { return 0; }
878 virtual HBasicBlock* SuccessorAt(int i) {
879 UNREACHABLE();
880 return NULL;
881 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000882 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
883 UNREACHABLE();
884 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000885
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886 void AddEnvironmentValue(HValue* value) {
887 values_.Add(NULL);
888 SetOperandAt(values_.length() - 1, value);
889 }
890
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000891 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000892
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000893 enum UseEnvironment {
894 kNoUses,
895 kUseAll
896 };
897
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000898 protected:
899 virtual void InternalSetOperandAt(int index, HValue* value) {
900 values_[index] = value;
901 }
902
903 private:
904 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000905};
906
907
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000908class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000910 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000911 SetSuccessorAt(0, target);
912 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000914 virtual Representation RequiredInputRepresentation(int index) const {
915 return Representation::None();
916 }
917
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000918 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919};
920
921
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000922class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000924 HUnaryControlInstruction(HValue* value,
925 HBasicBlock* true_target,
926 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000928 SetSuccessorAt(0, true_target);
929 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930 }
931
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000932 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000934 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935};
936
937
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000938class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000939 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000940 HBranch(HValue* value,
941 HBasicBlock* true_target,
942 HBasicBlock* false_target,
943 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
944 : HUnaryControlInstruction(value, true_target, false_target),
945 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000946 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000948 explicit HBranch(HValue* value)
949 : HUnaryControlInstruction(value, NULL, NULL) { }
950
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000951
952 virtual Representation RequiredInputRepresentation(int index) const {
953 return Representation::None();
954 }
955
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000956 ToBooleanStub::Types expected_input_types() const {
957 return expected_input_types_;
958 }
959
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000960 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000961
962 private:
963 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964};
965
966
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000967class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000968 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000969 HCompareMap(HValue* value,
970 Handle<Map> map,
971 HBasicBlock* true_target,
972 HBasicBlock* false_target)
973 : HUnaryControlInstruction(value, true_target, false_target),
974 map_(map) {
975 ASSERT(true_target != NULL);
976 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000977 ASSERT(!map.is_null());
978 }
979
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000980 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000981
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000982 Handle<Map> map() const { return map_; }
983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000984 virtual Representation RequiredInputRepresentation(int index) const {
985 return Representation::Tagged();
986 }
987
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000988 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000989
990 private:
991 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000992};
993
994
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000995class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000997 explicit HReturn(HValue* value) {
998 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000999 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001001 virtual Representation RequiredInputRepresentation(int index) const {
1002 return Representation::Tagged();
1003 }
1004
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001005 virtual void PrintDataTo(StringStream* stream);
1006
1007 HValue* value() { return OperandAt(0); }
1008
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001009 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001010};
1011
1012
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001013class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001014 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001015 virtual Representation RequiredInputRepresentation(int index) const {
1016 return Representation::None();
1017 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001018
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001019 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020};
1021
1022
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001023class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001024 public:
1025 explicit HUnaryOperation(HValue* value) {
1026 SetOperandAt(0, value);
1027 }
1028
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001029 static HUnaryOperation* cast(HValue* value) {
1030 return reinterpret_cast<HUnaryOperation*>(value);
1031 }
1032
1033 virtual bool CanTruncateToInt32() const {
1034 return CheckFlag(kTruncatingToInt32);
1035 }
1036
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001037 HValue* value() { return OperandAt(0); }
1038 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039};
1040
1041
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001042class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001043 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001044 HThrow(HValue* context, HValue* value) {
1045 SetOperandAt(0, context);
1046 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001047 SetAllSideEffects();
1048 }
1049
1050 virtual Representation RequiredInputRepresentation(int index) const {
1051 return Representation::Tagged();
1052 }
1053
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001054 HValue* context() { return OperandAt(0); }
1055 HValue* value() { return OperandAt(1); }
1056
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001057 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001058};
1059
1060
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001061class HUseConst: public HUnaryOperation {
1062 public:
1063 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1064
1065 virtual Representation RequiredInputRepresentation(int index) const {
1066 return Representation::None();
1067 }
1068
1069 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1070};
1071
1072
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001073class HForceRepresentation: public HTemplateInstruction<1> {
1074 public:
1075 HForceRepresentation(HValue* value, Representation required_representation) {
1076 SetOperandAt(0, value);
1077 set_representation(required_representation);
1078 }
1079
1080 HValue* value() { return OperandAt(0); }
1081
1082 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1083
1084 virtual Representation RequiredInputRepresentation(int index) const {
1085 return representation(); // Same as the output representation.
1086 }
1087
1088 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1089};
1090
1091
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001092class HChange: public HUnaryOperation {
1093 public:
1094 HChange(HValue* value,
1095 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001096 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001097 bool is_truncating,
1098 bool deoptimize_on_undefined)
1099 : HUnaryOperation(value),
1100 from_(from),
1101 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001102 ASSERT(!from.IsNone() && !to.IsNone());
1103 ASSERT(!from.Equals(to));
1104 set_representation(to);
1105 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001106 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001107 }
1108
1109 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1110
1111 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001112 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001113 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001114 virtual Representation RequiredInputRepresentation(int index) const {
1115 return from_;
1116 }
1117
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001118 virtual Range* InferRange();
1119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001120 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001121
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001122 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001123
1124 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001125 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126 if (!other->IsChange()) return false;
1127 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001128 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001129 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001130 }
1131
1132 private:
1133 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001134 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001135};
1136
1137
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001138class HClampToUint8: public HUnaryOperation {
1139 public:
1140 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001141 : HUnaryOperation(value) {
1142 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001143 SetFlag(kUseGVN);
1144 }
1145
1146 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001147 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001148 }
1149
1150 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1151
1152 protected:
1153 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001154};
1155
1156
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001157class HToInt32: public HUnaryOperation {
1158 public:
1159 explicit HToInt32(HValue* value)
1160 : HUnaryOperation(value) {
1161 set_representation(Representation::Integer32());
1162 SetFlag(kUseGVN);
1163 }
1164
1165 virtual Representation RequiredInputRepresentation(int index) const {
1166 return Representation::None();
1167 }
1168
1169 virtual bool CanTruncateToInt32() const {
1170 return true;
1171 }
1172
1173 virtual HValue* Canonicalize() {
1174 if (value()->representation().IsInteger32()) {
1175 return value();
1176 } else {
1177 return this;
1178 }
1179 }
1180
1181 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1182
1183 protected:
1184 virtual bool DataEquals(HValue* other) { return true; }
1185};
1186
1187
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001188class HSimulate: public HInstruction {
1189 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001190 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001191 : ast_id_(ast_id),
1192 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193 values_(2),
1194 assigned_indexes_(2) {}
1195 virtual ~HSimulate() {}
1196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001197 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001198
1199 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1200 int ast_id() const { return ast_id_; }
1201 void set_ast_id(int id) {
1202 ASSERT(!HasAstId());
1203 ast_id_ = id;
1204 }
1205
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001206 int pop_count() const { return pop_count_; }
1207 const ZoneList<HValue*>* values() const { return &values_; }
1208 int GetAssignedIndexAt(int index) const {
1209 ASSERT(HasAssignedIndexAt(index));
1210 return assigned_indexes_[index];
1211 }
1212 bool HasAssignedIndexAt(int index) const {
1213 return assigned_indexes_[index] != kNoIndex;
1214 }
1215 void AddAssignedValue(int index, HValue* value) {
1216 AddValue(index, value);
1217 }
1218 void AddPushedValue(HValue* value) {
1219 AddValue(kNoIndex, value);
1220 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001221 virtual int OperandCount() { return values_.length(); }
1222 virtual HValue* OperandAt(int index) { return values_[index]; }
1223
1224 virtual Representation RequiredInputRepresentation(int index) const {
1225 return Representation::None();
1226 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001227
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001228 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001229
1230#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001231 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001232#endif
1233
1234 protected:
1235 virtual void InternalSetOperandAt(int index, HValue* value) {
1236 values_[index] = value;
1237 }
1238
1239 private:
1240 static const int kNoIndex = -1;
1241 void AddValue(int index, HValue* value) {
1242 assigned_indexes_.Add(index);
1243 // Resize the list of pushed values.
1244 values_.Add(NULL);
1245 // Set the operand through the base method in HValue to make sure that the
1246 // use lists are correctly updated.
1247 SetOperandAt(values_.length() - 1, value);
1248 }
1249 int ast_id_;
1250 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001251 ZoneList<HValue*> values_;
1252 ZoneList<int> assigned_indexes_;
1253};
1254
1255
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001256class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001258 enum Type {
1259 kFunctionEntry,
1260 kBackwardsBranch
1261 };
1262
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001263 HStackCheck(HValue* context, Type type) : type_(type) {
1264 SetOperandAt(0, context);
1265 }
1266
1267 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001269 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001270 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001271 }
1272
ager@chromium.org04921a82011-06-27 13:21:41 +00001273 void Eliminate() {
1274 // The stack check eliminator might try to eliminate the same stack
1275 // check instruction multiple times.
1276 if (IsLinked()) {
1277 DeleteFromGraph();
1278 }
1279 }
1280
1281 bool is_function_entry() { return type_ == kFunctionEntry; }
1282 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1283
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001284 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001285
1286 private:
1287 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001288};
1289
1290
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001291class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001292 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001293 HEnterInlined(Handle<JSFunction> closure,
1294 FunctionLiteral* function,
1295 CallKind call_kind)
1296 : closure_(closure),
1297 function_(function),
1298 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001299 }
1300
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001301 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302
1303 Handle<JSFunction> closure() const { return closure_; }
1304 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001305 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307 virtual Representation RequiredInputRepresentation(int index) const {
1308 return Representation::None();
1309 }
1310
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001311 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312
1313 private:
1314 Handle<JSFunction> closure_;
1315 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001316 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001317};
1318
1319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001320class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001321 public:
1322 HLeaveInlined() {}
1323
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324 virtual Representation RequiredInputRepresentation(int index) const {
1325 return Representation::None();
1326 }
1327
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001328 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329};
1330
1331
1332class HPushArgument: public HUnaryOperation {
1333 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001334 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1335 set_representation(Representation::Tagged());
1336 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001337
1338 virtual Representation RequiredInputRepresentation(int index) const {
1339 return Representation::Tagged();
1340 }
1341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001342 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001344 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345};
1346
1347
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001348class HThisFunction: public HTemplateInstruction<0> {
1349 public:
1350 HThisFunction() {
1351 set_representation(Representation::Tagged());
1352 SetFlag(kUseGVN);
1353 }
1354
1355 virtual Representation RequiredInputRepresentation(int index) const {
1356 return Representation::None();
1357 }
1358
1359 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1360
1361 protected:
1362 virtual bool DataEquals(HValue* other) { return true; }
1363};
1364
1365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001366class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001368 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001369 set_representation(Representation::Tagged());
1370 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001371 }
1372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001373 virtual Representation RequiredInputRepresentation(int index) const {
1374 return Representation::None();
1375 }
1376
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001377 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001378
1379 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001380 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001381};
1382
1383
1384class HOuterContext: public HUnaryOperation {
1385 public:
1386 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1387 set_representation(Representation::Tagged());
1388 SetFlag(kUseGVN);
1389 }
1390
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001391 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001393 virtual Representation RequiredInputRepresentation(int index) const {
1394 return Representation::Tagged();
1395 }
1396
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001397 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001398 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001399};
1400
1401
1402class HGlobalObject: public HUnaryOperation {
1403 public:
1404 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1405 set_representation(Representation::Tagged());
1406 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407 }
1408
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001409 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001411 virtual Representation RequiredInputRepresentation(int index) const {
1412 return Representation::Tagged();
1413 }
1414
ager@chromium.org378b34e2011-01-28 08:04:38 +00001415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001416 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001417};
1418
1419
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001420class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001422 explicit HGlobalReceiver(HValue* global_object)
1423 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 set_representation(Representation::Tagged());
1425 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001426 }
1427
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001428 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001429
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001430 virtual Representation RequiredInputRepresentation(int index) const {
1431 return Representation::Tagged();
1432 }
1433
ager@chromium.org378b34e2011-01-28 08:04:38 +00001434 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001435 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001436};
1437
1438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439template <int V>
1440class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001442 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001443 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1444 this->set_representation(Representation::Tagged());
1445 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001446 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001448 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001450 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001451
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001452 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001454 private:
1455 int argument_count_;
1456};
1457
1458
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001459class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001460 public:
1461 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001462 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001463 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464 }
1465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 virtual Representation RequiredInputRepresentation(int index) const {
1467 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001468 }
1469
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001470 virtual void PrintDataTo(StringStream* stream);
1471
1472 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001473};
1474
1475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001477 public:
1478 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001479 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001480 SetOperandAt(0, first);
1481 SetOperandAt(1, second);
1482 }
1483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001484 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001485
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001486 virtual Representation RequiredInputRepresentation(int index) const {
1487 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001488 }
1489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001490 HValue* first() { return OperandAt(0); }
1491 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492};
1493
1494
danno@chromium.org160a7b02011-04-18 15:51:38 +00001495class HInvokeFunction: public HBinaryCall {
1496 public:
1497 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1498 : HBinaryCall(context, function, argument_count) {
1499 }
1500
1501 virtual Representation RequiredInputRepresentation(int index) const {
1502 return Representation::Tagged();
1503 }
1504
1505 HValue* context() { return first(); }
1506 HValue* function() { return second(); }
1507
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001508 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001509};
1510
1511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001512class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513 public:
1514 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001515 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516
1517 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001518
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001521 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522 }
1523
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001524 virtual void PrintDataTo(StringStream* stream);
1525
1526 virtual Representation RequiredInputRepresentation(int index) const {
1527 return Representation::None();
1528 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001530 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531
1532 private:
1533 Handle<JSFunction> function_;
1534};
1535
1536
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001537class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001539 HCallKeyed(HValue* context, HValue* key, int argument_count)
1540 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001541 }
1542
1543 virtual Representation RequiredInputRepresentation(int index) const {
1544 return Representation::Tagged();
1545 }
1546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001547 HValue* context() { return first(); }
1548 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001549
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001550 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551};
1552
1553
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001554class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001556 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1557 : HUnaryCall(context, argument_count), name_(name) {
1558 }
1559
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001560 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001562 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563 Handle<String> name() const { return name_; }
1564
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001565 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001567 virtual Representation RequiredInputRepresentation(int index) const {
1568 return Representation::Tagged();
1569 }
1570
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001571 private:
1572 Handle<String> name_;
1573};
1574
1575
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001576class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001578 HCallFunction(HValue* context, int argument_count)
1579 : HUnaryCall(context, argument_count) {
1580 }
1581
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001582 HValue* context() { return value(); }
1583
1584 virtual Representation RequiredInputRepresentation(int index) const {
1585 return Representation::Tagged();
1586 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001588 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001589};
1590
1591
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001592class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001594 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1595 : HUnaryCall(context, argument_count), name_(name) {
1596 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001598 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001600 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601 Handle<String> name() const { return name_; }
1602
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001603 virtual Representation RequiredInputRepresentation(int index) const {
1604 return Representation::Tagged();
1605 }
1606
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001607 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608
1609 private:
1610 Handle<String> name_;
1611};
1612
1613
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001614class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001616 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001617 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001619 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001620
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621 Handle<JSFunction> target() const { return target_; }
1622
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 virtual Representation RequiredInputRepresentation(int index) const {
1624 return Representation::None();
1625 }
1626
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001627 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628
1629 private:
1630 Handle<JSFunction> target_;
1631};
1632
1633
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001634class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001635 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001636 HCallNew(HValue* context, HValue* constructor, int argument_count)
1637 : HBinaryCall(context, constructor, argument_count) {
1638 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639
1640 virtual Representation RequiredInputRepresentation(int index) const {
1641 return Representation::Tagged();
1642 }
1643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001644 HValue* context() { return first(); }
1645 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001647 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001648};
1649
1650
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001651class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001653 HCallRuntime(HValue* context,
1654 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001655 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001656 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001657 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1658 SetOperandAt(0, context);
1659 }
1660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001661 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001662
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001663 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001664 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001665 Handle<String> name() const { return name_; }
1666
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001667 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001668 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001669 }
1670
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001671 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001672
1673 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001674 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001675 Handle<String> name_;
1676};
1677
1678
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001679class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001680 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001681 HJSArrayLength(HValue* value, HValue* typecheck) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682 // The length of an array is stored as a tagged value in the array
1683 // object. It is guaranteed to be 32 bit integer, but it can be
1684 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001685 SetOperandAt(0, value);
1686 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001687 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001688 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001689 SetFlag(kDependsOnArrayLengths);
1690 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001691 }
1692
1693 virtual Representation RequiredInputRepresentation(int index) const {
1694 return Representation::Tagged();
1695 }
1696
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001697 HValue* value() { return OperandAt(0); }
1698
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001699 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001700
1701 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001702 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001703};
1704
1705
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001706class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001707 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001708 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001709 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001710 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001711 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001712 }
1713
1714 virtual Representation RequiredInputRepresentation(int index) const {
1715 return Representation::Tagged();
1716 }
1717
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001718 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001719
1720 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001721 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001722};
1723
1724
whesse@chromium.org7b260152011-06-20 15:33:18 +00001725class HElementsKind: public HUnaryOperation {
1726 public:
1727 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1728 set_representation(Representation::Integer32());
1729 SetFlag(kUseGVN);
1730 SetFlag(kDependsOnMaps);
1731 }
1732
1733 virtual Representation RequiredInputRepresentation(int index) const {
1734 return Representation::Tagged();
1735 }
1736
1737 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1738
1739 protected:
1740 virtual bool DataEquals(HValue* other) { return true; }
1741};
1742
1743
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001744class HBitNot: public HUnaryOperation {
1745 public:
1746 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1747 set_representation(Representation::Integer32());
1748 SetFlag(kUseGVN);
1749 SetFlag(kTruncatingToInt32);
1750 }
1751
1752 virtual Representation RequiredInputRepresentation(int index) const {
1753 return Representation::Integer32();
1754 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001755 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001756
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001757 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001758
1759 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001760 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761};
1762
1763
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001764class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001766 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1767 : op_(op) {
1768 SetOperandAt(0, context);
1769 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770 switch (op) {
1771 case kMathFloor:
1772 case kMathRound:
1773 case kMathCeil:
1774 set_representation(Representation::Integer32());
1775 break;
1776 case kMathAbs:
1777 set_representation(Representation::Tagged());
1778 SetFlag(kFlexibleRepresentation);
1779 break;
1780 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001781 case kMathPowHalf:
1782 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001783 case kMathSin:
1784 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001786 break;
1787 default:
1788 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001789 }
1790 SetFlag(kUseGVN);
1791 }
1792
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001793 HValue* context() { return OperandAt(0); }
1794 HValue* value() { return OperandAt(1); }
1795
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001796 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001798 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001799
1800 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1801
1802 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001803 if (index == 0) {
1804 return Representation::Tagged();
1805 } else {
1806 switch (op_) {
1807 case kMathFloor:
1808 case kMathRound:
1809 case kMathCeil:
1810 case kMathSqrt:
1811 case kMathPowHalf:
1812 case kMathLog:
1813 case kMathSin:
1814 case kMathCos:
1815 return Representation::Double();
1816 case kMathAbs:
1817 return representation();
1818 default:
1819 UNREACHABLE();
1820 return Representation::None();
1821 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001822 }
1823 }
1824
1825 virtual HValue* Canonicalize() {
1826 // If the input is integer32 then we replace the floor instruction
1827 // with its inputs. This happens before the representation changes are
1828 // introduced.
1829 if (op() == kMathFloor) {
1830 if (value()->representation().IsInteger32()) return value();
1831 }
1832 return this;
1833 }
1834
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001835 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001836 const char* OpName() const;
1837
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001838 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001840 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001841 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001842 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1843 return op_ == b->op();
1844 }
1845
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001846 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001847 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848};
1849
1850
1851class HLoadElements: public HUnaryOperation {
1852 public:
1853 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1854 set_representation(Representation::Tagged());
1855 SetFlag(kUseGVN);
1856 SetFlag(kDependsOnMaps);
1857 }
1858
1859 virtual Representation RequiredInputRepresentation(int index) const {
1860 return Representation::Tagged();
1861 }
1862
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001863 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001864
1865 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001866 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867};
1868
1869
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001870class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001871 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001872 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001873 : HUnaryOperation(value) {
1874 set_representation(Representation::External());
1875 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001876 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001877 // change once set, so it's no necessary to introduce any additional
1878 // dependencies on top of the inputs.
1879 SetFlag(kUseGVN);
1880 }
1881
1882 virtual Representation RequiredInputRepresentation(int index) const {
1883 return Representation::Tagged();
1884 }
1885
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001886 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001887
1888 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001889 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001890};
1891
1892
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001893class HCheckMap: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001894 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001895 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
1896 : map_(map) {
1897 SetOperandAt(0, value);
1898 // If callers don't depend on a typecheck, they can pass in NULL. In that
1899 // case we use a copy of the |value| argument as a dummy value.
1900 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001901 set_representation(Representation::Tagged());
1902 SetFlag(kUseGVN);
1903 SetFlag(kDependsOnMaps);
1904 }
1905
1906 virtual Representation RequiredInputRepresentation(int index) const {
1907 return Representation::Tagged();
1908 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001909 virtual void PrintDataTo(StringStream* stream);
1910 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001912 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001913 Handle<Map> map() const { return map_; }
1914
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001915 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916
1917 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001918 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919 HCheckMap* b = HCheckMap::cast(other);
1920 return map_.is_identical_to(b->map());
1921 }
1922
1923 private:
1924 Handle<Map> map_;
1925};
1926
1927
1928class HCheckFunction: public HUnaryOperation {
1929 public:
1930 HCheckFunction(HValue* value, Handle<JSFunction> function)
1931 : HUnaryOperation(value), target_(function) {
1932 set_representation(Representation::Tagged());
1933 SetFlag(kUseGVN);
1934 }
1935
1936 virtual Representation RequiredInputRepresentation(int index) const {
1937 return Representation::Tagged();
1938 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001939 virtual void PrintDataTo(StringStream* stream);
1940 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001941
1942#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001943 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944#endif
1945
1946 Handle<JSFunction> target() const { return target_; }
1947
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001948 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001949
1950 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001951 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952 HCheckFunction* b = HCheckFunction::cast(other);
1953 return target_.is_identical_to(b->target());
1954 }
1955
1956 private:
1957 Handle<JSFunction> target_;
1958};
1959
1960
1961class HCheckInstanceType: public HUnaryOperation {
1962 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001963 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1964 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001965 }
1966 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1967 return new HCheckInstanceType(value, IS_JS_ARRAY);
1968 }
1969 static HCheckInstanceType* NewIsString(HValue* value) {
1970 return new HCheckInstanceType(value, IS_STRING);
1971 }
1972 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1973 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974 }
1975
1976 virtual Representation RequiredInputRepresentation(int index) const {
1977 return Representation::Tagged();
1978 }
1979
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00001980 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00001981
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001982 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1983 void GetCheckInterval(InstanceType* first, InstanceType* last);
1984 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001985
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001986 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001987
1988 protected:
1989 // TODO(ager): It could be nice to allow the ommision of instance
1990 // type checks if we have already performed an instance type check
1991 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001992 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001993 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001994 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995 }
1996
1997 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001998 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001999 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002000 IS_JS_ARRAY,
2001 IS_STRING,
2002 IS_SYMBOL,
2003 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2004 };
2005
2006 HCheckInstanceType(HValue* value, Check check)
2007 : HUnaryOperation(value), check_(check) {
2008 set_representation(Representation::Tagged());
2009 SetFlag(kUseGVN);
2010 }
2011
2012 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013};
2014
2015
2016class HCheckNonSmi: public HUnaryOperation {
2017 public:
2018 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2019 set_representation(Representation::Tagged());
2020 SetFlag(kUseGVN);
2021 }
2022
2023 virtual Representation RequiredInputRepresentation(int index) const {
2024 return Representation::Tagged();
2025 }
2026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002027 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002028
2029#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002030 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031#endif
2032
danno@chromium.org160a7b02011-04-18 15:51:38 +00002033 virtual HValue* Canonicalize() {
2034 HType value_type = value()->type();
2035 if (!value_type.IsUninitialized() &&
2036 (value_type.IsHeapNumber() ||
2037 value_type.IsString() ||
2038 value_type.IsBoolean() ||
2039 value_type.IsNonPrimitive())) {
2040 return NULL;
2041 }
2042 return this;
2043 }
2044
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002045 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002046
2047 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002048 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002049};
2050
2051
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002052class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002053 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002054 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2055 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056 SetFlag(kUseGVN);
2057 SetFlag(kDependsOnMaps);
2058 }
2059
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002061 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002062#endif
2063
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002064 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002065 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002067 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002068
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002069 virtual Representation RequiredInputRepresentation(int index) const {
2070 return Representation::None();
2071 }
2072
2073 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002074 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002075 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2076 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2077 return hash;
2078 }
2079
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002081 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002083 return prototype_.is_identical_to(b->prototype()) &&
2084 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002085 }
2086
2087 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002088 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002089 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090};
2091
2092
2093class HCheckSmi: public HUnaryOperation {
2094 public:
2095 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2096 set_representation(Representation::Tagged());
2097 SetFlag(kUseGVN);
2098 }
2099
2100 virtual Representation RequiredInputRepresentation(int index) const {
2101 return Representation::Tagged();
2102 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002103 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002104
2105#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002106 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002107#endif
2108
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002109 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002110
2111 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002112 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002113};
2114
2115
2116class HPhi: public HValue {
2117 public:
2118 explicit HPhi(int merged_index)
2119 : inputs_(2),
2120 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002121 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002122 is_live_(false),
2123 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2125 non_phi_uses_[i] = 0;
2126 indirect_uses_[i] = 0;
2127 }
2128 ASSERT(merged_index >= 0);
2129 set_representation(Representation::Tagged());
2130 SetFlag(kFlexibleRepresentation);
2131 }
2132
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002133 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002134 bool double_occurred = false;
2135 bool int32_occurred = false;
2136 for (int i = 0; i < OperandCount(); ++i) {
2137 HValue* value = OperandAt(i);
2138 if (value->representation().IsDouble()) double_occurred = true;
2139 if (value->representation().IsInteger32()) int32_occurred = true;
2140 if (value->representation().IsTagged()) return Representation::Tagged();
2141 }
2142
2143 if (double_occurred) return Representation::Double();
2144 if (int32_occurred) return Representation::Integer32();
2145 return Representation::None();
2146 }
2147
2148 virtual Range* InferRange();
2149 virtual Representation RequiredInputRepresentation(int index) const {
2150 return representation();
2151 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002152 virtual HType CalculateInferredType();
2153 virtual int OperandCount() { return inputs_.length(); }
2154 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2155 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002157 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002158
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002159 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160
2161 int merged_index() const { return merged_index_; }
2162
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002163 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002164
2165#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002166 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167#endif
2168
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002169 void InitRealUses(int id);
2170 void AddNonPhiUsesFrom(HPhi* other);
2171 void AddIndirectUsesTo(int* use_count);
2172
2173 int tagged_non_phi_uses() const {
2174 return non_phi_uses_[Representation::kTagged];
2175 }
2176 int int32_non_phi_uses() const {
2177 return non_phi_uses_[Representation::kInteger32];
2178 }
2179 int double_non_phi_uses() const {
2180 return non_phi_uses_[Representation::kDouble];
2181 }
2182 int tagged_indirect_uses() const {
2183 return indirect_uses_[Representation::kTagged];
2184 }
2185 int int32_indirect_uses() const {
2186 return indirect_uses_[Representation::kInteger32];
2187 }
2188 int double_indirect_uses() const {
2189 return indirect_uses_[Representation::kDouble];
2190 }
2191 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002192 bool is_live() { return is_live_; }
2193 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002194
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002195 static HPhi* cast(HValue* value) {
2196 ASSERT(value->IsPhi());
2197 return reinterpret_cast<HPhi*>(value);
2198 }
2199 virtual Opcode opcode() const { return HValue::kPhi; }
2200
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002201 virtual bool IsConvertibleToInteger() const {
2202 return is_convertible_to_integer_;
2203 }
2204
2205 void set_is_convertible_to_integer(bool b) {
2206 is_convertible_to_integer_ = b;
2207 }
2208
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002209 protected:
2210 virtual void DeleteFromGraph();
2211 virtual void InternalSetOperandAt(int index, HValue* value) {
2212 inputs_[index] = value;
2213 }
2214
2215 private:
2216 ZoneList<HValue*> inputs_;
2217 int merged_index_;
2218
2219 int non_phi_uses_[Representation::kNumRepresentations];
2220 int indirect_uses_[Representation::kNumRepresentations];
2221 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002222 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002223 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002224};
2225
2226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002227class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002228 public:
2229 HArgumentsObject() {
2230 set_representation(Representation::Tagged());
2231 SetFlag(kIsArguments);
2232 }
2233
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002234 virtual Representation RequiredInputRepresentation(int index) const {
2235 return Representation::None();
2236 }
2237
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002238 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239};
2240
2241
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002242class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243 public:
2244 HConstant(Handle<Object> handle, Representation r);
2245
2246 Handle<Object> handle() const { return handle_; }
2247
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002248 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002249
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002250 virtual Representation RequiredInputRepresentation(int index) const {
2251 return Representation::None();
2252 }
2253
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002254 virtual bool IsConvertibleToInteger() const {
2255 if (handle_->IsSmi()) return true;
2256 if (handle_->IsHeapNumber() &&
2257 (HeapNumber::cast(*handle_)->value() ==
2258 static_cast<double>(NumberToInt32(*handle_)))) return true;
2259 return false;
2260 }
2261
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002262 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002263 virtual void PrintDataTo(StringStream* stream);
2264 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265 bool IsInteger() const { return handle_->IsSmi(); }
2266 HConstant* CopyToRepresentation(Representation r) const;
2267 HConstant* CopyToTruncatedInt32() const;
2268 bool HasInteger32Value() const { return has_int32_value_; }
2269 int32_t Integer32Value() const {
2270 ASSERT(HasInteger32Value());
2271 return int32_value_;
2272 }
2273 bool HasDoubleValue() const { return has_double_value_; }
2274 double DoubleValue() const {
2275 ASSERT(HasDoubleValue());
2276 return double_value_;
2277 }
2278 bool HasStringValue() const { return handle_->IsString(); }
2279
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002280 bool ToBoolean() const;
2281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002282 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002283 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284 return reinterpret_cast<intptr_t>(*handle());
2285 }
2286
2287#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002288 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002289#endif
2290
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002291 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292
2293 protected:
2294 virtual Range* InferRange();
2295
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002296 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002297 HConstant* other_constant = HConstant::cast(other);
2298 return handle().is_identical_to(other_constant->handle());
2299 }
2300
2301 private:
2302 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002303
2304 // The following two values represent the int32 and the double value of the
2305 // given constant if there is a lossless conversion between the constant
2306 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002307 bool has_int32_value_ : 1;
2308 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002309 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310 double double_value_;
2311};
2312
2313
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002314class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002316 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002317 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002318 SetOperandAt(0, context);
2319 SetOperandAt(1, left);
2320 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002321 }
2322
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002323 HValue* context() { return OperandAt(0); }
2324 HValue* left() { return OperandAt(1); }
2325 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002326
2327 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2328 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002329 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002330 if (IsCommutative() && left()->IsConstant()) return right();
2331 return left();
2332 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002333 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002334 if (IsCommutative() && left()->IsConstant()) return left();
2335 return right();
2336 }
2337
2338 virtual bool IsCommutative() const { return false; }
2339
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002340 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002341};
2342
2343
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002344class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002345 public:
2346 HApplyArguments(HValue* function,
2347 HValue* receiver,
2348 HValue* length,
2349 HValue* elements) {
2350 set_representation(Representation::Tagged());
2351 SetOperandAt(0, function);
2352 SetOperandAt(1, receiver);
2353 SetOperandAt(2, length);
2354 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002355 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002356 }
2357
2358 virtual Representation RequiredInputRepresentation(int index) const {
2359 // The length is untagged, all other inputs are tagged.
2360 return (index == 2)
2361 ? Representation::Integer32()
2362 : Representation::Tagged();
2363 }
2364
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002365 HValue* function() { return OperandAt(0); }
2366 HValue* receiver() { return OperandAt(1); }
2367 HValue* length() { return OperandAt(2); }
2368 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002370 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002371};
2372
2373
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002374class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002375 public:
2376 HArgumentsElements() {
2377 // The value produced by this instruction is a pointer into the stack
2378 // that looks as if it was a smi because of alignment.
2379 set_representation(Representation::Tagged());
2380 SetFlag(kUseGVN);
2381 }
2382
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002383 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002385 virtual Representation RequiredInputRepresentation(int index) const {
2386 return Representation::None();
2387 }
2388
ager@chromium.org378b34e2011-01-28 08:04:38 +00002389 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002390 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002391};
2392
2393
2394class HArgumentsLength: public HUnaryOperation {
2395 public:
2396 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2397 set_representation(Representation::Integer32());
2398 SetFlag(kUseGVN);
2399 }
2400
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002401 virtual Representation RequiredInputRepresentation(int index) const {
2402 return Representation::Tagged();
2403 }
2404
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002405 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002406
2407 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002408 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409};
2410
2411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002412class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002413 public:
2414 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2415 set_representation(Representation::Tagged());
2416 SetFlag(kUseGVN);
2417 SetOperandAt(0, arguments);
2418 SetOperandAt(1, length);
2419 SetOperandAt(2, index);
2420 }
2421
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002422 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002423
2424 virtual Representation RequiredInputRepresentation(int index) const {
2425 // The arguments elements is considered tagged.
2426 return index == 0
2427 ? Representation::Tagged()
2428 : Representation::Integer32();
2429 }
2430
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002431 HValue* arguments() { return OperandAt(0); }
2432 HValue* length() { return OperandAt(1); }
2433 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002434
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002435 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002436
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002437 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438};
2439
2440
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002441class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002442 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002443 HBoundsCheck(HValue* index, HValue* length) {
2444 SetOperandAt(0, index);
2445 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002446 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002447 SetFlag(kUseGVN);
2448 }
2449
2450 virtual Representation RequiredInputRepresentation(int index) const {
2451 return Representation::Integer32();
2452 }
2453
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002454 virtual void PrintDataTo(StringStream* stream);
2455
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002456 HValue* index() { return OperandAt(0); }
2457 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002458
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002459 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002460
2461 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002462 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463};
2464
2465
2466class HBitwiseBinaryOperation: public HBinaryOperation {
2467 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002468 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2469 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002470 set_representation(Representation::Tagged());
2471 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002472 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002473 }
2474
2475 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002476 return index == 0
2477 ? Representation::Tagged()
2478 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002479 }
2480
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002481 virtual void RepresentationChanged(Representation to) {
2482 if (!to.IsTagged()) {
2483 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002484 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002485 SetFlag(kTruncatingToInt32);
2486 SetFlag(kUseGVN);
2487 }
2488 }
2489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002490 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002491
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002492 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002493};
2494
2495
2496class HArithmeticBinaryOperation: public HBinaryOperation {
2497 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002498 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2499 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002500 set_representation(Representation::Tagged());
2501 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002502 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002503 }
2504
2505 virtual void RepresentationChanged(Representation to) {
2506 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002507 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002508 SetFlag(kUseGVN);
2509 }
2510 }
2511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002512 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002513 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002514 return index == 0
2515 ? Representation::Tagged()
2516 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002517 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002518
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002519 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520 if (left()->representation().Equals(right()->representation())) {
2521 return left()->representation();
2522 }
2523 return HValue::InferredRepresentation();
2524 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002525};
2526
2527
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002528class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002529 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002530 HCompareGeneric(HValue* context,
2531 HValue* left,
2532 HValue* right,
2533 Token::Value token)
2534 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002535 ASSERT(Token::IsCompareOp(token));
2536 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002537 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 }
2539
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002541 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002542 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002543
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002545 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002547
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002549 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002551 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002552
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002553 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2554
2555 private:
2556 Token::Value token_;
2557};
2558
2559
2560class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2561 public:
2562 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2563 : token_(token) {
2564 ASSERT(Token::IsCompareOp(token));
2565 SetOperandAt(0, left);
2566 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002567 }
2568
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002569 HValue* left() { return OperandAt(0); }
2570 HValue* right() { return OperandAt(1); }
2571 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002572
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002573 void SetInputRepresentation(Representation r);
2574 Representation GetInputRepresentation() const {
2575 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002576 }
2577
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002578 virtual Representation RequiredInputRepresentation(int index) const {
2579 return input_representation_;
2580 }
2581 virtual void PrintDataTo(StringStream* stream);
2582
2583 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2584
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585 private:
2586 Representation input_representation_;
2587 Token::Value token_;
2588};
2589
2590
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002591class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002592 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002593 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2594 SetOperandAt(0, left);
2595 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002596 }
2597
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002598 HValue* left() { return OperandAt(0); }
2599 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002600
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 virtual Representation RequiredInputRepresentation(int index) const {
2602 return Representation::Tagged();
2603 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002605 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606};
2607
2608
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002609class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002610 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002611 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2612 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002613 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002614 }
2615
2616 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002617 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002618 int right() const { return right_; }
2619
whesse@chromium.org7b260152011-06-20 15:33:18 +00002620 virtual Representation RequiredInputRepresentation(int index) const {
2621 return Representation::Integer32();
2622 }
2623
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002624 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002625
2626 private:
2627 const Token::Value op_;
2628 const int right_;
2629};
2630
2631
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002632class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002633 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002634 HIsNullAndBranch(HValue* value, bool is_strict)
2635 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002636
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002637 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002638
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639 virtual Representation RequiredInputRepresentation(int index) const {
2640 return Representation::Tagged();
2641 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002642
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002643 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002644
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002645 private:
2646 bool is_strict_;
2647};
2648
2649
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002650class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002651 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002652 explicit HIsObjectAndBranch(HValue* value)
2653 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002654
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002655 virtual Representation RequiredInputRepresentation(int index) const {
2656 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002657 }
2658
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002659 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2660};
2661
2662
2663class HIsSmiAndBranch: public HUnaryControlInstruction {
2664 public:
2665 explicit HIsSmiAndBranch(HValue* value)
2666 : HUnaryControlInstruction(value, NULL, NULL) { }
2667
2668 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2669
2670 virtual Representation RequiredInputRepresentation(int index) const {
2671 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002672 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002673
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002674 protected:
2675 virtual bool DataEquals(HValue* other) { return true; }
2676};
2677
2678
2679class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2680 public:
2681 explicit HIsUndetectableAndBranch(HValue* value)
2682 : HUnaryControlInstruction(value, NULL, NULL) { }
2683
2684 virtual Representation RequiredInputRepresentation(int index) const {
2685 return Representation::Tagged();
2686 }
2687
2688 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2689};
2690
2691
2692class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2693 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002694 virtual Representation RequiredInputRepresentation(int index) const {
2695 return Representation::None();
2696 }
2697
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002698 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002699};
2700
2701
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002702class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002703 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002704 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2705 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2706 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2707 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002708 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2709 }
2710
2711 InstanceType from() { return from_; }
2712 InstanceType to() { return to_; }
2713
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002714 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002716 virtual Representation RequiredInputRepresentation(int index) const {
2717 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002718 }
2719
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002720 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2721
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722 private:
2723 InstanceType from_;
2724 InstanceType to_; // Inclusive range, not all combinations work.
2725};
2726
2727
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002728class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002729 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002730 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2731 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002732
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002733 virtual Representation RequiredInputRepresentation(int index) const {
2734 return Representation::Tagged();
2735 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002736
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002737 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738};
2739
2740
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002741class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002742 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002743 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2744 set_representation(Representation::Tagged());
2745 SetFlag(kUseGVN);
2746 }
2747
2748 virtual Representation RequiredInputRepresentation(int index) const {
2749 return Representation::Tagged();
2750 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002751
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002752 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002753
2754 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002755 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002756};
2757
2758
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002759class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002761 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2762 : HUnaryControlInstruction(value, NULL, NULL),
2763 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002765 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2766
2767 virtual Representation RequiredInputRepresentation(int index) const {
2768 return Representation::Tagged();
2769 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002770
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002771 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002772
2773 Handle<String> class_name() const { return class_name_; }
2774
2775 private:
2776 Handle<String> class_name_;
2777};
2778
2779
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002780class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002781 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002782 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2783 : HUnaryControlInstruction(value, NULL, NULL),
2784 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002785
2786 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002787 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002789 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002791 virtual Representation RequiredInputRepresentation(int index) const {
2792 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002793 }
2794
2795 private:
2796 Handle<String> type_literal_;
2797};
2798
2799
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002800class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002802 HInstanceOf(HValue* context, HValue* left, HValue* right)
2803 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002804 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002805 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806 }
2807
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 virtual Representation RequiredInputRepresentation(int index) const {
2809 return Representation::Tagged();
2810 }
2811
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002812 virtual HType CalculateInferredType();
2813
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002814 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002815
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002816 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817};
2818
2819
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002820class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002821 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002822 HInstanceOfKnownGlobal(HValue* context,
2823 HValue* left,
2824 Handle<JSFunction> right)
2825 : function_(right) {
2826 SetOperandAt(0, context);
2827 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002828 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002829 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002830 }
2831
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002832 HValue* context() { return OperandAt(0); }
2833 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002834 Handle<JSFunction> function() { return function_; }
2835
2836 virtual Representation RequiredInputRepresentation(int index) const {
2837 return Representation::Tagged();
2838 }
2839
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002840 virtual HType CalculateInferredType();
2841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002842 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002843
2844 private:
2845 Handle<JSFunction> function_;
2846};
2847
2848
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002849class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002850 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002851 HPower(HValue* left, HValue* right) {
2852 SetOperandAt(0, left);
2853 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002854 set_representation(Representation::Double());
2855 SetFlag(kUseGVN);
2856 }
2857
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002858 HValue* left() { return OperandAt(0); }
2859 HValue* right() { return OperandAt(1); }
2860
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002861 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002862 return index == 0
2863 ? Representation::Double()
2864 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002865 }
2866
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002867 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002868
2869 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002870 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002871};
2872
2873
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002874class HAdd: public HArithmeticBinaryOperation {
2875 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002876 HAdd(HValue* context, HValue* left, HValue* right)
2877 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002878 SetFlag(kCanOverflow);
2879 }
2880
2881 // Add is only commutative if two integer values are added and not if two
2882 // tagged values are added (because it might be a String concatenation).
2883 virtual bool IsCommutative() const {
2884 return !representation().IsTagged();
2885 }
2886
2887 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2888
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002889 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002890
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002891 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892
2893 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002894 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002895
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002896 virtual Range* InferRange();
2897};
2898
2899
2900class HSub: public HArithmeticBinaryOperation {
2901 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002902 HSub(HValue* context, HValue* left, HValue* right)
2903 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002904 SetFlag(kCanOverflow);
2905 }
2906
2907 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2908
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002909 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002910
2911 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002912 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002913
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002914 virtual Range* InferRange();
2915};
2916
2917
2918class HMul: public HArithmeticBinaryOperation {
2919 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002920 HMul(HValue* context, HValue* left, HValue* right)
2921 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002922 SetFlag(kCanOverflow);
2923 }
2924
2925 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2926
2927 // Only commutative if it is certain that not two objects are multiplicated.
2928 virtual bool IsCommutative() const {
2929 return !representation().IsTagged();
2930 }
2931
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002932 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933
2934 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002935 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002936
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002937 virtual Range* InferRange();
2938};
2939
2940
2941class HMod: public HArithmeticBinaryOperation {
2942 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002943 HMod(HValue* context, HValue* left, HValue* right)
2944 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945 SetFlag(kCanBeDivByZero);
2946 }
2947
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002948 bool HasPowerOf2Divisor() {
2949 if (right()->IsConstant() &&
2950 HConstant::cast(right())->HasInteger32Value()) {
2951 int32_t value = HConstant::cast(right())->Integer32Value();
2952 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2953 }
2954
2955 return false;
2956 }
2957
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002958 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2959
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002960 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002961
2962 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002963 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002964
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002965 virtual Range* InferRange();
2966};
2967
2968
2969class HDiv: public HArithmeticBinaryOperation {
2970 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002971 HDiv(HValue* context, HValue* left, HValue* right)
2972 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002973 SetFlag(kCanBeDivByZero);
2974 SetFlag(kCanOverflow);
2975 }
2976
2977 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2978
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002979 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002980
2981 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002982 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002983
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984 virtual Range* InferRange();
2985};
2986
2987
2988class HBitAnd: public HBitwiseBinaryOperation {
2989 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002990 HBitAnd(HValue* context, HValue* left, HValue* right)
2991 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992
2993 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002994 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002995
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002996 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002997
2998 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002999 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003000
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001 virtual Range* InferRange();
3002};
3003
3004
3005class HBitXor: public HBitwiseBinaryOperation {
3006 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003007 HBitXor(HValue* context, HValue* left, HValue* right)
3008 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009
3010 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003011 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003013 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003014
3015 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003016 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017};
3018
3019
3020class HBitOr: public HBitwiseBinaryOperation {
3021 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003022 HBitOr(HValue* context, HValue* left, HValue* right)
3023 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024
3025 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003026 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003028 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003029
3030 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003031 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003032
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003033 virtual Range* InferRange();
3034};
3035
3036
3037class HShl: public HBitwiseBinaryOperation {
3038 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003039 HShl(HValue* context, HValue* left, HValue* right)
3040 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003041
3042 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003043 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003045 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003046
3047 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003048 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003049};
3050
3051
3052class HShr: public HBitwiseBinaryOperation {
3053 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003054 HShr(HValue* context, HValue* left, HValue* right)
3055 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003056
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003057 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003058 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003060 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003061
3062 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003063 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003064};
3065
3066
3067class HSar: public HBitwiseBinaryOperation {
3068 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003069 HSar(HValue* context, HValue* left, HValue* right)
3070 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071
3072 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003073 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003075 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003076
3077 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003078 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079};
3080
3081
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003082class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003083 public:
3084 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3085 SetFlag(kChangesOsrEntries);
3086 }
3087
3088 int ast_id() const { return ast_id_; }
3089
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003090 virtual Representation RequiredInputRepresentation(int index) const {
3091 return Representation::None();
3092 }
3093
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003094 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003095
3096 private:
3097 int ast_id_;
3098};
3099
3100
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003101class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102 public:
3103 explicit HParameter(unsigned index) : index_(index) {
3104 set_representation(Representation::Tagged());
3105 }
3106
3107 unsigned index() const { return index_; }
3108
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003109 virtual void PrintDataTo(StringStream* stream);
3110
3111 virtual Representation RequiredInputRepresentation(int index) const {
3112 return Representation::None();
3113 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003115 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116
3117 private:
3118 unsigned index_;
3119};
3120
3121
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003122class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003124 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3125 : HUnaryCall(context, argument_count),
3126 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128 }
3129
3130 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003131
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003132 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133
3134 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3135 transcendental_type_ = transcendental_type;
3136 }
3137 TranscendentalCache::Type transcendental_type() {
3138 return transcendental_type_;
3139 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003140
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003141 virtual void PrintDataTo(StringStream* stream);
3142
3143 virtual Representation RequiredInputRepresentation(int index) const {
3144 return Representation::Tagged();
3145 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003147 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148
3149 private:
3150 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151 TranscendentalCache::Type transcendental_type_;
3152};
3153
3154
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003155class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156 public:
3157 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003159 virtual Representation RequiredInputRepresentation(int index) const {
3160 return Representation::None();
3161 }
3162
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003163 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164};
3165
3166
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003167class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003168 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003169 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 : cell_(cell), check_hole_value_(check_hole_value) {
3171 set_representation(Representation::Tagged());
3172 SetFlag(kUseGVN);
3173 SetFlag(kDependsOnGlobalVars);
3174 }
3175
3176 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3177 bool check_hole_value() const { return check_hole_value_; }
3178
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003179 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003181 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003182 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003183 return reinterpret_cast<intptr_t>(*cell_);
3184 }
3185
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003186 virtual Representation RequiredInputRepresentation(int index) const {
3187 return Representation::None();
3188 }
3189
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003190 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191
3192 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003194 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003195 return cell_.is_identical_to(b->cell());
3196 }
3197
3198 private:
3199 Handle<JSGlobalPropertyCell> cell_;
3200 bool check_hole_value_;
3201};
3202
3203
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003204class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003205 public:
3206 HLoadGlobalGeneric(HValue* context,
3207 HValue* global_object,
3208 Handle<Object> name,
3209 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003210 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003211 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003212 SetOperandAt(0, context);
3213 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003214 set_representation(Representation::Tagged());
3215 SetAllSideEffects();
3216 }
3217
3218 HValue* context() { return OperandAt(0); }
3219 HValue* global_object() { return OperandAt(1); }
3220 Handle<Object> name() const { return name_; }
3221 bool for_typeof() const { return for_typeof_; }
3222
3223 virtual void PrintDataTo(StringStream* stream);
3224
3225 virtual Representation RequiredInputRepresentation(int index) const {
3226 return Representation::Tagged();
3227 }
3228
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003229 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003230
3231 private:
3232 Handle<Object> name_;
3233 bool for_typeof_;
3234};
3235
3236
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003237class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003238 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003239 HStoreGlobalCell(HValue* value,
3240 Handle<JSGlobalPropertyCell> cell,
3241 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003242 : HUnaryOperation(value),
3243 cell_(cell),
3244 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003245 SetFlag(kChangesGlobalVars);
3246 }
3247
3248 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003249 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003250
3251 virtual Representation RequiredInputRepresentation(int index) const {
3252 return Representation::Tagged();
3253 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003254 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003255
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003256 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003257
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003258 private:
3259 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003260 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261};
3262
3263
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003264class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3265 public:
3266 HStoreGlobalGeneric(HValue* context,
3267 HValue* global_object,
3268 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003269 HValue* value,
3270 bool strict_mode)
3271 : name_(name),
3272 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003273 SetOperandAt(0, context);
3274 SetOperandAt(1, global_object);
3275 SetOperandAt(2, value);
3276 set_representation(Representation::Tagged());
3277 SetAllSideEffects();
3278 }
3279
3280 HValue* context() { return OperandAt(0); }
3281 HValue* global_object() { return OperandAt(1); }
3282 Handle<Object> name() const { return name_; }
3283 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003284 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003285
3286 virtual void PrintDataTo(StringStream* stream);
3287
3288 virtual Representation RequiredInputRepresentation(int index) const {
3289 return Representation::Tagged();
3290 }
3291
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003292 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003293
3294 private:
3295 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003296 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003297};
3298
3299
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003300class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003301 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003302 HLoadContextSlot(HValue* context , int slot_index)
3303 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003304 set_representation(Representation::Tagged());
3305 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003306 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003307 }
3308
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003309 int slot_index() const { return slot_index_; }
3310
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003311 virtual Representation RequiredInputRepresentation(int index) const {
3312 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003313 }
3314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003315 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003317 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003318
3319 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003320 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003321 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003322 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003323 }
3324
3325 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003326 int slot_index_;
3327};
3328
3329
3330static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003331 return !value->type().IsBoolean()
3332 && !value->type().IsSmi()
3333 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003334}
3335
3336
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003337class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003338 public:
3339 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003340 : slot_index_(slot_index) {
3341 SetOperandAt(0, context);
3342 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003343 SetFlag(kChangesContextSlots);
3344 }
3345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003346 HValue* context() { return OperandAt(0); }
3347 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003348 int slot_index() const { return slot_index_; }
3349
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003350 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003351 return StoringValueNeedsWriteBarrier(value());
3352 }
3353
3354 virtual Representation RequiredInputRepresentation(int index) const {
3355 return Representation::Tagged();
3356 }
3357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003359
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003360 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003361
3362 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003363 int slot_index_;
3364};
3365
3366
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003367class HLoadNamedField: public HUnaryOperation {
3368 public:
3369 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3370 : HUnaryOperation(object),
3371 is_in_object_(is_in_object),
3372 offset_(offset) {
3373 set_representation(Representation::Tagged());
3374 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003375 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003376 if (is_in_object) {
3377 SetFlag(kDependsOnInobjectFields);
3378 } else {
3379 SetFlag(kDependsOnBackingStoreFields);
3380 }
3381 }
3382
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003383 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003384 bool is_in_object() const { return is_in_object_; }
3385 int offset() const { return offset_; }
3386
3387 virtual Representation RequiredInputRepresentation(int index) const {
3388 return Representation::Tagged();
3389 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003390 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003391
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003392 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003393
3394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003395 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003396 HLoadNamedField* b = HLoadNamedField::cast(other);
3397 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3398 }
3399
3400 private:
3401 bool is_in_object_;
3402 int offset_;
3403};
3404
3405
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003406class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003407 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003408 HLoadNamedFieldPolymorphic(HValue* context,
3409 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003410 SmallMapList* types,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003411 Handle<String> name);
3412
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003413 HValue* context() { return OperandAt(0); }
3414 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003415 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003416 Handle<String> name() { return name_; }
3417 bool need_generic() { return need_generic_; }
3418
3419 virtual Representation RequiredInputRepresentation(int index) const {
3420 return Representation::Tagged();
3421 }
3422
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003423 virtual void PrintDataTo(StringStream* stream);
3424
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003425 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003426
3427 static const int kMaxLoadPolymorphism = 4;
3428
3429 protected:
3430 virtual bool DataEquals(HValue* value);
3431
3432 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003433 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003434 Handle<String> name_;
3435 bool need_generic_;
3436};
3437
3438
3439
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003440class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003441 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003442 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003443 : name_(name) {
3444 SetOperandAt(0, context);
3445 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003446 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003447 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003448 }
3449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003450 HValue* context() { return OperandAt(0); }
3451 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003452 Handle<Object> name() const { return name_; }
3453
3454 virtual Representation RequiredInputRepresentation(int index) const {
3455 return Representation::Tagged();
3456 }
3457
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003458 virtual void PrintDataTo(StringStream* stream);
3459
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003460 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003461
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003462 private:
3463 Handle<Object> name_;
3464};
3465
3466
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003467class HLoadFunctionPrototype: public HUnaryOperation {
3468 public:
3469 explicit HLoadFunctionPrototype(HValue* function)
3470 : HUnaryOperation(function) {
3471 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003472 SetFlag(kUseGVN);
3473 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003474 }
3475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003476 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003477
3478 virtual Representation RequiredInputRepresentation(int index) const {
3479 return Representation::Tagged();
3480 }
3481
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003482 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003483
3484 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003485 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003486};
3487
3488
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003489class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003490 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003491 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3492 SetOperandAt(0, obj);
3493 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003494 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003495 SetFlag(kDependsOnArrayElements);
3496 SetFlag(kUseGVN);
3497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 HValue* object() { return OperandAt(0); }
3500 HValue* key() { return OperandAt(1); }
3501
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003502 virtual Representation RequiredInputRepresentation(int index) const {
3503 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003504 return index == 0
3505 ? Representation::Tagged()
3506 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003507 }
3508
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003509 virtual void PrintDataTo(StringStream* stream);
3510
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003511 bool RequiresHoleCheck() const;
3512
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003513 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003514
3515 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003516 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003517};
3518
3519
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003520class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3521 public:
3522 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3523 SetOperandAt(0, elements);
3524 SetOperandAt(1, key);
3525 set_representation(Representation::Double());
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003526 SetFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003527 SetFlag(kUseGVN);
3528 }
3529
3530 HValue* elements() { return OperandAt(0); }
3531 HValue* key() { return OperandAt(1); }
3532
3533 virtual Representation RequiredInputRepresentation(int index) const {
3534 // The key is supposed to be Integer32.
3535 return index == 0
3536 ? Representation::Tagged()
3537 : Representation::Integer32();
3538 }
3539
3540 virtual void PrintDataTo(StringStream* stream);
3541
3542 bool RequiresHoleCheck() const;
3543
3544 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3545
3546 protected:
3547 virtual bool DataEquals(HValue* other) { return true; }
3548};
3549
3550
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003551class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003552 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003553 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3554 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003555 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003556 : elements_kind_(elements_kind) {
3557 SetOperandAt(0, external_elements);
3558 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003559 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3560 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003561 set_representation(Representation::Double());
3562 } else {
3563 set_representation(Representation::Integer32());
3564 }
3565 SetFlag(kDependsOnSpecializedArrayElements);
3566 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003567 SetFlag(kDependsOnCalls);
3568 SetFlag(kUseGVN);
3569 }
3570
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003571 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003572
3573 virtual Representation RequiredInputRepresentation(int index) const {
3574 // The key is supposed to be Integer32, but the base pointer
3575 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003576 return index == 0
3577 ? Representation::External()
3578 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003579 }
3580
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003581 HValue* external_pointer() { return OperandAt(0); }
3582 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003583 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003584
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003585 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003586
3587 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003588 virtual bool DataEquals(HValue* other) {
3589 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3590 HLoadKeyedSpecializedArrayElement* cast_other =
3591 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003592 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003593 }
3594
3595 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003596 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003597};
3598
3599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003600class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003601 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003602 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003603 set_representation(Representation::Tagged());
3604 SetOperandAt(0, obj);
3605 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003606 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003607 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003608 }
3609
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003610 HValue* object() { return OperandAt(0); }
3611 HValue* key() { return OperandAt(1); }
3612 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003613
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003614 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003615
3616 virtual Representation RequiredInputRepresentation(int index) const {
3617 return Representation::Tagged();
3618 }
3619
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003620 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003621};
3622
3623
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003624class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625 public:
3626 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003627 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628 HValue* val,
3629 bool in_object,
3630 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003631 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632 is_in_object_(in_object),
3633 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003634 SetOperandAt(0, obj);
3635 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636 if (is_in_object_) {
3637 SetFlag(kChangesInobjectFields);
3638 } else {
3639 SetFlag(kChangesBackingStoreFields);
3640 }
3641 }
3642
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003643 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003644
3645 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003646 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003650 HValue* object() { return OperandAt(0); }
3651 HValue* value() { return OperandAt(1); }
3652
3653 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003654 bool is_in_object() const { return is_in_object_; }
3655 int offset() const { return offset_; }
3656 Handle<Map> transition() const { return transition_; }
3657 void set_transition(Handle<Map> map) { transition_ = map; }
3658
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003659 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003660 return StoringValueNeedsWriteBarrier(value());
3661 }
3662
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003663 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003664 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003665 bool is_in_object_;
3666 int offset_;
3667 Handle<Map> transition_;
3668};
3669
3670
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003671class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003672 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003673 HStoreNamedGeneric(HValue* context,
3674 HValue* object,
3675 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003676 HValue* value,
3677 bool strict_mode)
3678 : name_(name),
3679 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003680 SetOperandAt(0, object);
3681 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003682 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003683 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003684 }
3685
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003686 HValue* object() { return OperandAt(0); }
3687 HValue* value() { return OperandAt(1); }
3688 HValue* context() { return OperandAt(2); }
3689 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003690 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003691
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003692 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003693
3694 virtual Representation RequiredInputRepresentation(int index) const {
3695 return Representation::Tagged();
3696 }
3697
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003698 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003699
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003700 private:
3701 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003702 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003703};
3704
3705
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003706class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003707 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003708 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3709 SetOperandAt(0, obj);
3710 SetOperandAt(1, key);
3711 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003712 SetFlag(kChangesArrayElements);
3713 }
3714
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003715 virtual Representation RequiredInputRepresentation(int index) const {
3716 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003717 return index == 1
3718 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003719 : Representation::Tagged();
3720 }
3721
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003722 HValue* object() { return OperandAt(0); }
3723 HValue* key() { return OperandAt(1); }
3724 HValue* value() { return OperandAt(2); }
3725
3726 bool NeedsWriteBarrier() {
3727 return StoringValueNeedsWriteBarrier(value());
3728 }
3729
3730 virtual void PrintDataTo(StringStream* stream);
3731
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003732 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003733};
3734
3735
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003736class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3737 public:
3738 HStoreKeyedFastDoubleElement(HValue* elements,
3739 HValue* key,
3740 HValue* val) {
3741 SetOperandAt(0, elements);
3742 SetOperandAt(1, key);
3743 SetOperandAt(2, val);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003744 SetFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003745 }
3746
3747 virtual Representation RequiredInputRepresentation(int index) const {
3748 if (index == 1) {
3749 return Representation::Integer32();
3750 } else if (index == 2) {
3751 return Representation::Double();
3752 } else {
3753 return Representation::Tagged();
3754 }
3755 }
3756
3757 HValue* elements() { return OperandAt(0); }
3758 HValue* key() { return OperandAt(1); }
3759 HValue* value() { return OperandAt(2); }
3760
3761 bool NeedsWriteBarrier() {
3762 return StoringValueNeedsWriteBarrier(value());
3763 }
3764
3765 virtual void PrintDataTo(StringStream* stream);
3766
3767 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3768};
3769
3770
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003771class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003772 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003773 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3774 HValue* key,
3775 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003776 JSObject::ElementsKind elements_kind)
3777 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003778 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003779 SetOperandAt(0, external_elements);
3780 SetOperandAt(1, key);
3781 SetOperandAt(2, val);
3782 }
3783
3784 virtual void PrintDataTo(StringStream* stream);
3785
3786 virtual Representation RequiredInputRepresentation(int index) const {
3787 if (index == 0) {
3788 return Representation::External();
3789 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003790 bool float_or_double_elements =
3791 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3792 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3793 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003794 return Representation::Double();
3795 } else {
3796 return Representation::Integer32();
3797 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003798 }
3799 }
3800
3801 HValue* external_pointer() { return OperandAt(0); }
3802 HValue* key() { return OperandAt(1); }
3803 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003804 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003805
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003806 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3807
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003808 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003809 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003810};
3811
3812
3813class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003814 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003815 HStoreKeyedGeneric(HValue* context,
3816 HValue* object,
3817 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003818 HValue* value,
3819 bool strict_mode)
3820 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003821 SetOperandAt(0, object);
3822 SetOperandAt(1, key);
3823 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003824 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003825 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003826 }
3827
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003828 HValue* object() { return OperandAt(0); }
3829 HValue* key() { return OperandAt(1); }
3830 HValue* value() { return OperandAt(2); }
3831 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003832 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003833
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003834 virtual Representation RequiredInputRepresentation(int index) const {
3835 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003836 }
3837
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003838 virtual void PrintDataTo(StringStream* stream);
3839
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003840 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003841
3842 private:
3843 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003844};
3845
3846
danno@chromium.org160a7b02011-04-18 15:51:38 +00003847class HStringAdd: public HBinaryOperation {
3848 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003849 HStringAdd(HValue* context, HValue* left, HValue* right)
3850 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003851 set_representation(Representation::Tagged());
3852 SetFlag(kUseGVN);
3853 SetFlag(kDependsOnMaps);
3854 }
3855
3856 virtual Representation RequiredInputRepresentation(int index) const {
3857 return Representation::Tagged();
3858 }
3859
3860 virtual HType CalculateInferredType() {
3861 return HType::String();
3862 }
3863
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003864 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003865
3866 protected:
3867 virtual bool DataEquals(HValue* other) { return true; }
3868};
3869
3870
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003871class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003872 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003873 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3874 SetOperandAt(0, context);
3875 SetOperandAt(1, string);
3876 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003877 set_representation(Representation::Integer32());
3878 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003879 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003880 }
3881
3882 virtual Representation RequiredInputRepresentation(int index) const {
3883 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003884 return index == 2
3885 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003886 : Representation::Tagged();
3887 }
3888
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003889 HValue* context() { return OperandAt(0); }
3890 HValue* string() { return OperandAt(1); }
3891 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003892
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003893 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003894
3895 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003896 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003897
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003898 virtual Range* InferRange() {
3899 return new Range(0, String::kMaxUC16CharCode);
3900 }
3901};
3902
3903
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003904class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003905 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003906 HStringCharFromCode(HValue* context, HValue* char_code) {
3907 SetOperandAt(0, context);
3908 SetOperandAt(1, char_code);
3909 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003910 SetFlag(kUseGVN);
3911 }
3912
3913 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003914 return index == 0
3915 ? Representation::Tagged()
3916 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003917 }
3918
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003919 HValue* context() { return OperandAt(0); }
3920 HValue* value() { return OperandAt(1); }
3921
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003922 virtual bool DataEquals(HValue* other) { return true; }
3923
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003924 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003925};
3926
3927
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003928class HStringLength: public HUnaryOperation {
3929 public:
3930 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3931 set_representation(Representation::Tagged());
3932 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003933 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003934 }
3935
3936 virtual Representation RequiredInputRepresentation(int index) const {
3937 return Representation::Tagged();
3938 }
3939
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003940 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003941 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3942 return HType::Smi();
3943 }
3944
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003945 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003946
3947 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003948 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003949
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003950 virtual Range* InferRange() {
3951 return new Range(0, String::kMaxLength);
3952 }
3953};
3954
3955
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003956template <int V>
3957class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003958 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003959 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003960 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003961 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003962 }
3963
3964 int literal_index() const { return literal_index_; }
3965 int depth() const { return depth_; }
3966
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003967 private:
3968 int literal_index_;
3969 int depth_;
3970};
3971
3972
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003973class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003974 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003975 HArrayLiteral(HValue* context,
3976 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003977 int length,
3978 int literal_index,
3979 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003980 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003981 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003982 constant_elements_(constant_elements) {
3983 SetOperandAt(0, context);
3984 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003985
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003986 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003987 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3988 int length() const { return length_; }
3989
3990 bool IsCopyOnWrite() const;
3991
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003992 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003993 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003994 }
3995
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003996 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003997
3998 private:
3999 int length_;
4000 Handle<FixedArray> constant_elements_;
4001};
4002
4003
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004004class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004005 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004006 HObjectLiteral(HValue* context,
4007 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004008 bool fast_elements,
4009 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004010 int depth,
4011 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004012 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004013 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004014 fast_elements_(fast_elements),
4015 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004016 SetOperandAt(0, context);
4017 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004019 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004020 Handle<FixedArray> constant_properties() const {
4021 return constant_properties_;
4022 }
4023 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004024 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004025
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004026 virtual Representation RequiredInputRepresentation(int index) const {
4027 return Representation::Tagged();
4028 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004029
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004030 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004031
4032 private:
4033 Handle<FixedArray> constant_properties_;
4034 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004035 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004036};
4037
4038
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004039class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004040 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004041 HRegExpLiteral(HValue* context,
4042 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004043 Handle<String> flags,
4044 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004045 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004046 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004047 flags_(flags) {
4048 SetOperandAt(0, context);
4049 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004050
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004051 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004052 Handle<String> pattern() { return pattern_; }
4053 Handle<String> flags() { return flags_; }
4054
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004055 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004056 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004057 }
4058
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004059 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004060
4061 private:
4062 Handle<String> pattern_;
4063 Handle<String> flags_;
4064};
4065
4066
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004067class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004068 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004069 HFunctionLiteral(HValue* context,
4070 Handle<SharedFunctionInfo> shared,
4071 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004072 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004073 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004074 set_representation(Representation::Tagged());
4075 }
4076
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004077 HValue* context() { return OperandAt(0); }
4078
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004079 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004080 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004081 }
4082
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004083 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004084
4085 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4086 bool pretenure() const { return pretenure_; }
4087
4088 private:
4089 Handle<SharedFunctionInfo> shared_info_;
4090 bool pretenure_;
4091};
4092
4093
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004094class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004095 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004096 explicit HTypeof(HValue* context, HValue* value) {
4097 SetOperandAt(0, context);
4098 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004099 set_representation(Representation::Tagged());
4100 }
4101
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004102 HValue* context() { return OperandAt(0); }
4103 HValue* value() { return OperandAt(1); }
4104
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004105 virtual Representation RequiredInputRepresentation(int index) const {
4106 return Representation::Tagged();
4107 }
4108
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004109 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004110};
4111
4112
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004113class HToFastProperties: public HUnaryOperation {
4114 public:
4115 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4116 // This instruction is not marked as having side effects, but
4117 // changes the map of the input operand. Use it only when creating
4118 // object literals.
4119 ASSERT(value->IsObjectLiteral());
4120 set_representation(Representation::Tagged());
4121 }
4122
4123 virtual Representation RequiredInputRepresentation(int index) const {
4124 return Representation::Tagged();
4125 }
4126
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004127 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004128};
4129
4130
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004131class HValueOf: public HUnaryOperation {
4132 public:
4133 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4134 set_representation(Representation::Tagged());
4135 }
4136
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004137 virtual Representation RequiredInputRepresentation(int index) const {
4138 return Representation::Tagged();
4139 }
4140
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004141 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004142};
4143
4144
4145class HDeleteProperty: public HBinaryOperation {
4146 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004147 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4148 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004149 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004150 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004151 }
4152
4153 virtual Representation RequiredInputRepresentation(int index) const {
4154 return Representation::Tagged();
4155 }
4156
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004157 virtual HType CalculateInferredType();
4158
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004159 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004160
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004161 HValue* object() { return left(); }
4162 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004163};
4164
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004165
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004166class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004167 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004168 HIn(HValue* context, HValue* key, HValue* object) {
4169 SetOperandAt(0, context);
4170 SetOperandAt(1, key);
4171 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004172 set_representation(Representation::Tagged());
4173 SetAllSideEffects();
4174 }
4175
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004176 HValue* context() { return OperandAt(0); }
4177 HValue* key() { return OperandAt(1); }
4178 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004179
4180 virtual Representation RequiredInputRepresentation(int index) const {
4181 return Representation::Tagged();
4182 }
4183
4184 virtual HType CalculateInferredType() {
4185 return HType::Boolean();
4186 }
4187
4188 virtual void PrintDataTo(StringStream* stream);
4189
4190 DECLARE_CONCRETE_INSTRUCTION(In)
4191};
4192
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004193#undef DECLARE_INSTRUCTION
4194#undef DECLARE_CONCRETE_INSTRUCTION
4195
4196} } // namespace v8::internal
4197
4198#endif // V8_HYDROGEN_INSTRUCTIONS_H_