blob: e7a9104e87f64800fbbd05ec3dcfeeff379449c3 [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); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 int32_t Mask() const;
232 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
233 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
234 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
235 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000236 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
237 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
238 bool IsInSmiRange() const {
239 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000240 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000241 void KeepOrder();
242 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000243
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244 void StackUpon(Range* other) {
245 Intersect(other);
246 next_ = other;
247 }
248
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000249 void Intersect(Range* other);
250 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000251
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000252 void AddConstant(int32_t value);
253 void Sar(int32_t value);
254 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 bool AddAndCheckOverflow(Range* other);
256 bool SubAndCheckOverflow(Range* other);
257 bool MulAndCheckOverflow(Range* other);
258
259 private:
260 int32_t lower_;
261 int32_t upper_;
262 Range* next_;
263 bool can_be_minus_zero_;
264};
265
266
267class Representation {
268 public:
269 enum Kind {
270 kNone,
271 kTagged,
272 kDouble,
273 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000274 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000275 kNumRepresentations
276 };
277
278 Representation() : kind_(kNone) { }
279
280 static Representation None() { return Representation(kNone); }
281 static Representation Tagged() { return Representation(kTagged); }
282 static Representation Integer32() { return Representation(kInteger32); }
283 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000284 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000286 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000287 return kind_ == other.kind_;
288 }
289
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000290 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291 bool IsNone() const { return kind_ == kNone; }
292 bool IsTagged() const { return kind_ == kTagged; }
293 bool IsInteger32() const { return kind_ == kInteger32; }
294 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000295 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000296 bool IsSpecialization() const {
297 return kind_ == kInteger32 || kind_ == kDouble;
298 }
299 const char* Mnemonic() const;
300
301 private:
302 explicit Representation(Kind k) : kind_(k) { }
303
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000304 // Make sure kind fits in int8.
305 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
306
307 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000308};
309
310
311class HType {
312 public:
313 HType() : type_(kUninitialized) { }
314
315 static HType Tagged() { return HType(kTagged); }
316 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
317 static HType TaggedNumber() { return HType(kTaggedNumber); }
318 static HType Smi() { return HType(kSmi); }
319 static HType HeapNumber() { return HType(kHeapNumber); }
320 static HType String() { return HType(kString); }
321 static HType Boolean() { return HType(kBoolean); }
322 static HType NonPrimitive() { return HType(kNonPrimitive); }
323 static HType JSArray() { return HType(kJSArray); }
324 static HType JSObject() { return HType(kJSObject); }
325 static HType Uninitialized() { return HType(kUninitialized); }
326
327 // Return the weakest (least precise) common type.
328 HType Combine(HType other) {
329 return HType(static_cast<Type>(type_ & other.type_));
330 }
331
332 bool Equals(const HType& other) {
333 return type_ == other.type_;
334 }
335
336 bool IsSubtypeOf(const HType& other) {
337 return Combine(other).Equals(other);
338 }
339
340 bool IsTagged() {
341 ASSERT(type_ != kUninitialized);
342 return ((type_ & kTagged) == kTagged);
343 }
344
345 bool IsTaggedPrimitive() {
346 ASSERT(type_ != kUninitialized);
347 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
348 }
349
350 bool IsTaggedNumber() {
351 ASSERT(type_ != kUninitialized);
352 return ((type_ & kTaggedNumber) == kTaggedNumber);
353 }
354
355 bool IsSmi() {
356 ASSERT(type_ != kUninitialized);
357 return ((type_ & kSmi) == kSmi);
358 }
359
360 bool IsHeapNumber() {
361 ASSERT(type_ != kUninitialized);
362 return ((type_ & kHeapNumber) == kHeapNumber);
363 }
364
365 bool IsString() {
366 ASSERT(type_ != kUninitialized);
367 return ((type_ & kString) == kString);
368 }
369
370 bool IsBoolean() {
371 ASSERT(type_ != kUninitialized);
372 return ((type_ & kBoolean) == kBoolean);
373 }
374
375 bool IsNonPrimitive() {
376 ASSERT(type_ != kUninitialized);
377 return ((type_ & kNonPrimitive) == kNonPrimitive);
378 }
379
380 bool IsJSArray() {
381 ASSERT(type_ != kUninitialized);
382 return ((type_ & kJSArray) == kJSArray);
383 }
384
385 bool IsJSObject() {
386 ASSERT(type_ != kUninitialized);
387 return ((type_ & kJSObject) == kJSObject);
388 }
389
390 bool IsUninitialized() {
391 return type_ == kUninitialized;
392 }
393
394 static HType TypeFromValue(Handle<Object> value);
395
396 const char* ToString();
397 const char* ToShortString();
398
399 private:
400 enum Type {
401 kTagged = 0x1, // 0000 0000 0000 0001
402 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
403 kTaggedNumber = 0xd, // 0000 0000 0000 1101
404 kSmi = 0x1d, // 0000 0000 0001 1101
405 kHeapNumber = 0x2d, // 0000 0000 0010 1101
406 kString = 0x45, // 0000 0000 0100 0101
407 kBoolean = 0x85, // 0000 0000 1000 0101
408 kNonPrimitive = 0x101, // 0000 0001 0000 0001
409 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000410 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000411 kUninitialized = 0x1fff // 0001 1111 1111 1111
412 };
413
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000414 // Make sure type fits in int16.
415 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
416
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000417 explicit HType(Type t) : type_(t) { }
418
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000419 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000420};
421
422
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000423class HUseListNode: public ZoneObject {
424 public:
425 HUseListNode(HValue* value, int index, HUseListNode* tail)
426 : tail_(tail), value_(value), index_(index) {
427 }
428
429 HUseListNode* tail() const { return tail_; }
430 HValue* value() const { return value_; }
431 int index() const { return index_; }
432
433 void set_tail(HUseListNode* list) { tail_ = list; }
434
435#ifdef DEBUG
436 void Zap() {
437 tail_ = reinterpret_cast<HUseListNode*>(1);
438 value_ = NULL;
439 index_ = -1;
440 }
441#endif
442
443 private:
444 HUseListNode* tail_;
445 HValue* value_;
446 int index_;
447};
448
449
450// We reuse use list nodes behind the scenes as uses are added and deleted.
451// This class is the safe way to iterate uses while deleting them.
452class HUseIterator BASE_EMBEDDED {
453 public:
454 bool Done() { return current_ == NULL; }
455 void Advance();
456
457 HValue* value() {
458 ASSERT(!Done());
459 return value_;
460 }
461
462 int index() {
463 ASSERT(!Done());
464 return index_;
465 }
466
467 private:
468 explicit HUseIterator(HUseListNode* head);
469
470 HUseListNode* current_;
471 HUseListNode* next_;
472 HValue* value_;
473 int index_;
474
475 friend class HValue;
476};
477
478
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479class HValue: public ZoneObject {
480 public:
481 static const int kNoNumber = -1;
482
483 // There must be one corresponding kDepends flag for every kChanges flag and
484 // the order of the kChanges flags must be exactly the same as of the kDepends
485 // flags.
486 enum Flag {
487 // Declare global value numbering flags.
488 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
489 GVN_FLAG_LIST(DECLARE_DO)
490 #undef DECLARE_DO
491 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000492 // Participate in Global Value Numbering, i.e. elimination of
493 // unnecessary recomputations. If an instruction sets this flag, it must
494 // implement DataEquals(), which will be used to determine if other
495 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000496 kUseGVN,
497 kCanOverflow,
498 kBailoutOnMinusZero,
499 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000500 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000501 kIsArguments,
502 kTruncatingToInt32,
503 kLastFlag = kTruncatingToInt32
504 };
505
506 STATIC_ASSERT(kLastFlag < kBitsPerInt);
507
508 static const int kChangesToDependsFlagsLeftShift = 1;
509
510 static int ChangesFlagsMask() {
511 int result = 0;
512 // Create changes mask.
513#define DECLARE_DO(type) result |= (1 << kChanges##type);
514 GVN_FLAG_LIST(DECLARE_DO)
515#undef DECLARE_DO
516 return result;
517 }
518
519 static int DependsFlagsMask() {
520 return ConvertChangesToDependsFlags(ChangesFlagsMask());
521 }
522
523 static int ConvertChangesToDependsFlags(int flags) {
524 return flags << kChangesToDependsFlagsLeftShift;
525 }
526
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000527 static HValue* cast(HValue* value) { return value; }
528
529 enum Opcode {
530 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000531 #define DECLARE_OPCODE(type) k##type,
532 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
533 kPhi
534 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000535 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000536 virtual Opcode opcode() const = 0;
537
538 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
539 #define DECLARE_PREDICATE(type) \
540 bool Is##type() const { return opcode() == k##type; }
541 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
542 #undef DECLARE_PREDICATE
543 bool IsPhi() const { return opcode() == kPhi; }
544
545 // Declare virtual predicates for abstract HInstruction or HValue
546 #define DECLARE_PREDICATE(type) \
547 virtual bool Is##type() const { return false; }
548 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
549 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000550
551 HValue() : block_(NULL),
552 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000554 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000555 range_(NULL),
556 flags_(0) {}
557 virtual ~HValue() {}
558
559 HBasicBlock* block() const { return block_; }
560 void SetBlock(HBasicBlock* block);
561
562 int id() const { return id_; }
563 void set_id(int id) { id_ = id; }
564
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000565 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000567 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568 Representation representation() const { return representation_; }
569 void ChangeRepresentation(Representation r) {
570 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571 ASSERT(!r.IsNone());
572 ASSERT(CheckFlag(kFlexibleRepresentation));
573 RepresentationChanged(r);
574 representation_ = r;
575 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000576 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000578 virtual bool IsConvertibleToInteger() const { return true; }
579
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000580 HType type() const { return type_; }
581 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000582 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000583 type_ = type;
584 }
585
586 // An operation needs to override this function iff:
587 // 1) it can produce an int32 output.
588 // 2) the true value of its output can potentially be minus zero.
589 // The implementation must set a flag so that it bails out in the case where
590 // it would otherwise output what should be a minus zero as an int32 zero.
591 // If the operation also exists in a form that takes int32 and outputs int32
592 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000593 // back. There are three operations that need to propagate back to more than
594 // one input. They are phi and binary div and mul. They always return NULL
595 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000596 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
597 visited->Add(id());
598 return NULL;
599 }
600
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000601 bool IsDefinedAfter(HBasicBlock* other) const;
602
603 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000604 virtual int OperandCount() = 0;
605 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000606 void SetOperandAt(int index, HValue* value);
607
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000608 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000609 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000610 bool HasNoUses() const { return use_list_ == NULL; }
611 bool HasMultipleUses() const {
612 return use_list_ != NULL && use_list_->tail() != NULL;
613 }
614 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000615 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000616
617 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000618 void SetFlag(Flag f) { flags_ |= (1 << f); }
619 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
620 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
621
622 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
623 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
624 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000625
626 Range* range() const { return range_; }
627 bool HasRange() const { return range_ != NULL; }
628 void AddNewRange(Range* r);
629 void RemoveLastAddedRange();
630 void ComputeInitialRange();
631
632 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000633 virtual Representation RequiredInputRepresentation(int index) const = 0;
634
635 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000636 return representation();
637 }
638
639 // This gives the instruction an opportunity to replace itself with an
640 // instruction that does the same in some better way. To replace an
641 // instruction with a new one, first add the new instruction to the graph,
642 // then return it. Return NULL to have the instruction deleted.
643 virtual HValue* Canonicalize() { return this; }
644
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000645 bool Equals(HValue* other);
646 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000647
648 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000649 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000650 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000651 void PrintTypeTo(StringStream* stream);
652 void PrintRangeTo(StringStream* stream);
653 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000655 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000656
657 // Updated the inferred type of this instruction and returns true if
658 // it has changed.
659 bool UpdateInferredType();
660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000661 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000662
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000664 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000665#endif
666
667 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000668 // This function must be overridden for instructions with flag kUseGVN, to
669 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000670 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000671 UNREACHABLE();
672 return false;
673 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000674 virtual void RepresentationChanged(Representation to) { }
675 virtual Range* InferRange();
676 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000677 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678 void clear_block() {
679 ASSERT(block_ != NULL);
680 block_ = NULL;
681 }
682
683 void set_representation(Representation r) {
684 // Representation is set-once.
685 ASSERT(representation_.IsNone() && !r.IsNone());
686 representation_ = r;
687 }
688
689 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000690 // A flag mask to mark an instruction as having arbitrary side effects.
691 static int AllSideEffects() {
692 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
693 }
694
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000695 // Remove the matching use from the use list if present. Returns the
696 // removed list node or NULL.
697 HUseListNode* RemoveUse(HValue* value, int index);
698
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000699 void RegisterUse(int index, HValue* new_value);
700
701 HBasicBlock* block_;
702
703 // The id of this instruction in the hydrogen graph, assigned when first
704 // added to the graph. Reflects creation order.
705 int id_;
706
707 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000708 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000709 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000710 Range* range_;
711 int flags_;
712
713 DISALLOW_COPY_AND_ASSIGN(HValue);
714};
715
716
717class HInstruction: public HValue {
718 public:
719 HInstruction* next() const { return next_; }
720 HInstruction* previous() const { return previous_; }
721
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000722 virtual void PrintTo(StringStream* stream);
723 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000724
725 bool IsLinked() const { return block() != NULL; }
726 void Unlink();
727 void InsertBefore(HInstruction* next);
728 void InsertAfter(HInstruction* previous);
729
730 int position() const { return position_; }
731 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
732 void set_position(int position) { position_ = position; }
733
734 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
735
736#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000737 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000738#endif
739
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000740 virtual bool IsCall() { return false; }
741
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000742 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000743
744 protected:
745 HInstruction()
746 : next_(NULL),
747 previous_(NULL),
748 position_(RelocInfo::kNoPosition) {
749 SetFlag(kDependsOnOsrEntries);
750 }
751
752 virtual void DeleteFromGraph() { Unlink(); }
753
754 private:
755 void InitializeAsFirst(HBasicBlock* block) {
756 ASSERT(!IsLinked());
757 SetBlock(block);
758 }
759
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000760 void PrintMnemonicTo(StringStream* stream);
761
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000762 HInstruction* next_;
763 HInstruction* previous_;
764 int position_;
765
766 friend class HBasicBlock;
767};
768
769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000770template<int V>
771class HTemplateInstruction : public HInstruction {
772 public:
773 int OperandCount() { return V; }
774 HValue* OperandAt(int i) { return inputs_[i]; }
775
776 protected:
777 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
778
779 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000780 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000781};
782
783
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000784class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000785 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000786 virtual HBasicBlock* SuccessorAt(int i) = 0;
787 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000788 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000789
790 virtual void PrintDataTo(StringStream* stream);
791
792 HBasicBlock* FirstSuccessor() {
793 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
794 }
795 HBasicBlock* SecondSuccessor() {
796 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
797 }
798
799 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
800};
801
802
803class HSuccessorIterator BASE_EMBEDDED {
804 public:
805 explicit HSuccessorIterator(HControlInstruction* instr)
806 : instr_(instr), current_(0) { }
807
808 bool Done() { return current_ >= instr_->SuccessorCount(); }
809 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
810 void Advance() { current_++; }
811
812 private:
813 HControlInstruction* instr_;
814 int current_;
815};
816
817
818template<int S, int V>
819class HTemplateControlInstruction: public HControlInstruction {
820 public:
821 int SuccessorCount() { return S; }
822 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000823 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000825 int OperandCount() { return V; }
826 HValue* OperandAt(int i) { return inputs_[i]; }
827
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000829 protected:
830 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
831
832 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000833 EmbeddedContainer<HBasicBlock*, S> successors_;
834 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000835};
836
837
838class HBlockEntry: public HTemplateInstruction<0> {
839 public:
840 virtual Representation RequiredInputRepresentation(int index) const {
841 return Representation::None();
842 }
843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000844 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000845};
846
847
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000848// We insert soft-deoptimize when we hit code with unknown typefeedback,
849// so that we get a chance of re-optimizing with useful typefeedback.
850// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
851class HSoftDeoptimize: public HTemplateInstruction<0> {
852 public:
853 virtual Representation RequiredInputRepresentation(int index) const {
854 return Representation::None();
855 }
856
857 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
858};
859
860
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000861class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000862 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000863 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000864
865 virtual Representation RequiredInputRepresentation(int index) const {
866 return Representation::None();
867 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000868
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869 virtual int OperandCount() { return values_.length(); }
870 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000871 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000872
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000873 virtual int SuccessorCount() { return 0; }
874 virtual HBasicBlock* SuccessorAt(int i) {
875 UNREACHABLE();
876 return NULL;
877 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000878 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
879 UNREACHABLE();
880 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000881
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000882 void AddEnvironmentValue(HValue* value) {
883 values_.Add(NULL);
884 SetOperandAt(values_.length() - 1, value);
885 }
886
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000887 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000888
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000889 enum UseEnvironment {
890 kNoUses,
891 kUseAll
892 };
893
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000894 protected:
895 virtual void InternalSetOperandAt(int index, HValue* value) {
896 values_[index] = value;
897 }
898
899 private:
900 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000901};
902
903
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000904class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000905 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000906 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000907 SetSuccessorAt(0, target);
908 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000910 virtual Representation RequiredInputRepresentation(int index) const {
911 return Representation::None();
912 }
913
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000914 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915};
916
917
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000920 HUnaryControlInstruction(HValue* value,
921 HBasicBlock* true_target,
922 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000924 SetSuccessorAt(0, true_target);
925 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926 }
927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000928 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000929
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000930 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000931};
932
933
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000934class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000936 HBranch(HValue* value,
937 HBasicBlock* true_target,
938 HBasicBlock* false_target,
939 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
940 : HUnaryControlInstruction(value, true_target, false_target),
941 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000942 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000944 explicit HBranch(HValue* value)
945 : HUnaryControlInstruction(value, NULL, NULL) { }
946
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947
948 virtual Representation RequiredInputRepresentation(int index) const {
949 return Representation::None();
950 }
951
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000952 ToBooleanStub::Types expected_input_types() const {
953 return expected_input_types_;
954 }
955
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000956 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000957
958 private:
959 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960};
961
962
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000963class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000965 HCompareMap(HValue* value,
966 Handle<Map> map,
967 HBasicBlock* true_target,
968 HBasicBlock* false_target)
969 : HUnaryControlInstruction(value, true_target, false_target),
970 map_(map) {
971 ASSERT(true_target != NULL);
972 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000973 ASSERT(!map.is_null());
974 }
975
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000976 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000977
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000978 Handle<Map> map() const { return map_; }
979
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000980 virtual Representation RequiredInputRepresentation(int index) const {
981 return Representation::Tagged();
982 }
983
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000984 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000985
986 private:
987 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000988};
989
990
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000991class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000992 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000993 explicit HReturn(HValue* value) {
994 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000995 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000997 virtual Representation RequiredInputRepresentation(int index) const {
998 return Representation::Tagged();
999 }
1000
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001001 virtual void PrintDataTo(StringStream* stream);
1002
1003 HValue* value() { return OperandAt(0); }
1004
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001005 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001006};
1007
1008
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001009class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001010 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001011 virtual Representation RequiredInputRepresentation(int index) const {
1012 return Representation::None();
1013 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001014
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001015 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001016};
1017
1018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001019class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020 public:
1021 explicit HUnaryOperation(HValue* value) {
1022 SetOperandAt(0, value);
1023 }
1024
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001025 static HUnaryOperation* cast(HValue* value) {
1026 return reinterpret_cast<HUnaryOperation*>(value);
1027 }
1028
1029 virtual bool CanTruncateToInt32() const {
1030 return CheckFlag(kTruncatingToInt32);
1031 }
1032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001033 HValue* value() { return OperandAt(0); }
1034 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001035};
1036
1037
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001038class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001039 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001040 HThrow(HValue* context, HValue* value) {
1041 SetOperandAt(0, context);
1042 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001043 SetAllSideEffects();
1044 }
1045
1046 virtual Representation RequiredInputRepresentation(int index) const {
1047 return Representation::Tagged();
1048 }
1049
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001050 HValue* context() { return OperandAt(0); }
1051 HValue* value() { return OperandAt(1); }
1052
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001053 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001054};
1055
1056
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001057class HUseConst: public HUnaryOperation {
1058 public:
1059 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1060
1061 virtual Representation RequiredInputRepresentation(int index) const {
1062 return Representation::None();
1063 }
1064
1065 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1066};
1067
1068
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001069class HForceRepresentation: public HTemplateInstruction<1> {
1070 public:
1071 HForceRepresentation(HValue* value, Representation required_representation) {
1072 SetOperandAt(0, value);
1073 set_representation(required_representation);
1074 }
1075
1076 HValue* value() { return OperandAt(0); }
1077
1078 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1079
1080 virtual Representation RequiredInputRepresentation(int index) const {
1081 return representation(); // Same as the output representation.
1082 }
1083
1084 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1085};
1086
1087
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001088class HChange: public HUnaryOperation {
1089 public:
1090 HChange(HValue* value,
1091 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001092 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001093 bool is_truncating,
1094 bool deoptimize_on_undefined)
1095 : HUnaryOperation(value),
1096 from_(from),
1097 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001098 ASSERT(!from.IsNone() && !to.IsNone());
1099 ASSERT(!from.Equals(to));
1100 set_representation(to);
1101 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001102 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001103 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1104 value->range()->IsInSmiRange()) {
1105 set_type(HType::Smi());
1106 }
1107 }
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
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001118 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001119
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001120 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001121
1122 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001123 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001124 if (!other->IsChange()) return false;
1125 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001126 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001127 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001128 }
1129
1130 private:
1131 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001132 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001133};
1134
1135
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001136class HClampToUint8: public HUnaryOperation {
1137 public:
1138 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001139 : HUnaryOperation(value) {
1140 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001141 SetFlag(kUseGVN);
1142 }
1143
1144 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001145 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001146 }
1147
1148 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1149
1150 protected:
1151 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001152};
1153
1154
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001155class HToInt32: public HUnaryOperation {
1156 public:
1157 explicit HToInt32(HValue* value)
1158 : HUnaryOperation(value) {
1159 set_representation(Representation::Integer32());
1160 SetFlag(kUseGVN);
1161 }
1162
1163 virtual Representation RequiredInputRepresentation(int index) const {
1164 return Representation::None();
1165 }
1166
1167 virtual bool CanTruncateToInt32() const {
1168 return true;
1169 }
1170
1171 virtual HValue* Canonicalize() {
1172 if (value()->representation().IsInteger32()) {
1173 return value();
1174 } else {
1175 return this;
1176 }
1177 }
1178
1179 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1180
1181 protected:
1182 virtual bool DataEquals(HValue* other) { return true; }
1183};
1184
1185
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001186class HSimulate: public HInstruction {
1187 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001188 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001189 : ast_id_(ast_id),
1190 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001191 values_(2),
1192 assigned_indexes_(2) {}
1193 virtual ~HSimulate() {}
1194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001195 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001196
1197 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1198 int ast_id() const { return ast_id_; }
1199 void set_ast_id(int id) {
1200 ASSERT(!HasAstId());
1201 ast_id_ = id;
1202 }
1203
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001204 int pop_count() const { return pop_count_; }
1205 const ZoneList<HValue*>* values() const { return &values_; }
1206 int GetAssignedIndexAt(int index) const {
1207 ASSERT(HasAssignedIndexAt(index));
1208 return assigned_indexes_[index];
1209 }
1210 bool HasAssignedIndexAt(int index) const {
1211 return assigned_indexes_[index] != kNoIndex;
1212 }
1213 void AddAssignedValue(int index, HValue* value) {
1214 AddValue(index, value);
1215 }
1216 void AddPushedValue(HValue* value) {
1217 AddValue(kNoIndex, value);
1218 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001219 virtual int OperandCount() { return values_.length(); }
1220 virtual HValue* OperandAt(int index) { return values_[index]; }
1221
1222 virtual Representation RequiredInputRepresentation(int index) const {
1223 return Representation::None();
1224 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001225
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001226 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001227
1228#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001229 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001230#endif
1231
1232 protected:
1233 virtual void InternalSetOperandAt(int index, HValue* value) {
1234 values_[index] = value;
1235 }
1236
1237 private:
1238 static const int kNoIndex = -1;
1239 void AddValue(int index, HValue* value) {
1240 assigned_indexes_.Add(index);
1241 // Resize the list of pushed values.
1242 values_.Add(NULL);
1243 // Set the operand through the base method in HValue to make sure that the
1244 // use lists are correctly updated.
1245 SetOperandAt(values_.length() - 1, value);
1246 }
1247 int ast_id_;
1248 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001249 ZoneList<HValue*> values_;
1250 ZoneList<int> assigned_indexes_;
1251};
1252
1253
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001254class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001255 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001256 enum Type {
1257 kFunctionEntry,
1258 kBackwardsBranch
1259 };
1260
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001261 HStackCheck(HValue* context, Type type) : type_(type) {
1262 SetOperandAt(0, context);
1263 }
1264
1265 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001267 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001268 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001269 }
1270
ager@chromium.org04921a82011-06-27 13:21:41 +00001271 void Eliminate() {
1272 // The stack check eliminator might try to eliminate the same stack
1273 // check instruction multiple times.
1274 if (IsLinked()) {
1275 DeleteFromGraph();
1276 }
1277 }
1278
1279 bool is_function_entry() { return type_ == kFunctionEntry; }
1280 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1281
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001282 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001283
1284 private:
1285 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001286};
1287
1288
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001289class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001290 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001291 HEnterInlined(Handle<JSFunction> closure,
1292 FunctionLiteral* function,
1293 CallKind call_kind)
1294 : closure_(closure),
1295 function_(function),
1296 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001297 }
1298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001299 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001300
1301 Handle<JSFunction> closure() const { return closure_; }
1302 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001303 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001304
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001305 virtual Representation RequiredInputRepresentation(int index) const {
1306 return Representation::None();
1307 }
1308
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001309 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001310
1311 private:
1312 Handle<JSFunction> closure_;
1313 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001314 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001315};
1316
1317
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001318class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001319 public:
1320 HLeaveInlined() {}
1321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001322 virtual Representation RequiredInputRepresentation(int index) const {
1323 return Representation::None();
1324 }
1325
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001326 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327};
1328
1329
1330class HPushArgument: public HUnaryOperation {
1331 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001332 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1333 set_representation(Representation::Tagged());
1334 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335
1336 virtual Representation RequiredInputRepresentation(int index) const {
1337 return Representation::Tagged();
1338 }
1339
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001340 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001341
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001342 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343};
1344
1345
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001346class HThisFunction: public HTemplateInstruction<0> {
1347 public:
1348 HThisFunction() {
1349 set_representation(Representation::Tagged());
1350 SetFlag(kUseGVN);
1351 }
1352
1353 virtual Representation RequiredInputRepresentation(int index) const {
1354 return Representation::None();
1355 }
1356
1357 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1358
1359 protected:
1360 virtual bool DataEquals(HValue* other) { return true; }
1361};
1362
1363
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001364class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001365 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001366 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367 set_representation(Representation::Tagged());
1368 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001369 }
1370
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001371 virtual Representation RequiredInputRepresentation(int index) const {
1372 return Representation::None();
1373 }
1374
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001375 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001376
1377 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001378 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001379};
1380
1381
1382class HOuterContext: public HUnaryOperation {
1383 public:
1384 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1385 set_representation(Representation::Tagged());
1386 SetFlag(kUseGVN);
1387 }
1388
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001389 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001391 virtual Representation RequiredInputRepresentation(int index) const {
1392 return Representation::Tagged();
1393 }
1394
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001395 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001396 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001397};
1398
1399
1400class HGlobalObject: public HUnaryOperation {
1401 public:
1402 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1403 set_representation(Representation::Tagged());
1404 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405 }
1406
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001407 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001409 virtual Representation RequiredInputRepresentation(int index) const {
1410 return Representation::Tagged();
1411 }
1412
ager@chromium.org378b34e2011-01-28 08:04:38 +00001413 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001414 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415};
1416
1417
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001418class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001419 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001420 explicit HGlobalReceiver(HValue* global_object)
1421 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001422 set_representation(Representation::Tagged());
1423 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 }
1425
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001426 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001427
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001428 virtual Representation RequiredInputRepresentation(int index) const {
1429 return Representation::Tagged();
1430 }
1431
ager@chromium.org378b34e2011-01-28 08:04:38 +00001432 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001433 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001434};
1435
1436
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001437template <int V>
1438class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001439 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001440 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1442 this->set_representation(Representation::Tagged());
1443 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001444 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001445
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001446 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001447
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001450 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001451
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001452 private:
1453 int argument_count_;
1454};
1455
1456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001457class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001458 public:
1459 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001460 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001461 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001462 }
1463
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001464 virtual Representation RequiredInputRepresentation(int index) const {
1465 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001466 }
1467
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001468 virtual void PrintDataTo(StringStream* stream);
1469
1470 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001471};
1472
1473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001474class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001475 public:
1476 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001477 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001478 SetOperandAt(0, first);
1479 SetOperandAt(1, second);
1480 }
1481
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001482 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001484 virtual Representation RequiredInputRepresentation(int index) const {
1485 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001486 }
1487
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001488 HValue* first() { return OperandAt(0); }
1489 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001490};
1491
1492
danno@chromium.org160a7b02011-04-18 15:51:38 +00001493class HInvokeFunction: public HBinaryCall {
1494 public:
1495 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1496 : HBinaryCall(context, function, argument_count) {
1497 }
1498
1499 virtual Representation RequiredInputRepresentation(int index) const {
1500 return Representation::Tagged();
1501 }
1502
1503 HValue* context() { return first(); }
1504 HValue* function() { return second(); }
1505
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001506 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001507};
1508
1509
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001510class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001511 public:
1512 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001513 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514
1515 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001516
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001517 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001518 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001519 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001520 }
1521
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001522 virtual void PrintDataTo(StringStream* stream);
1523
1524 virtual Representation RequiredInputRepresentation(int index) const {
1525 return Representation::None();
1526 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001527
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001528 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529
1530 private:
1531 Handle<JSFunction> function_;
1532};
1533
1534
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001535class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001537 HCallKeyed(HValue* context, HValue* key, int argument_count)
1538 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001539 }
1540
1541 virtual Representation RequiredInputRepresentation(int index) const {
1542 return Representation::Tagged();
1543 }
1544
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001545 HValue* context() { return first(); }
1546 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001548 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001549};
1550
1551
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001552class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001553 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001554 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1555 : HUnaryCall(context, argument_count), name_(name) {
1556 }
1557
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001558 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001560 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561 Handle<String> name() const { return name_; }
1562
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001563 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001564
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001565 virtual Representation RequiredInputRepresentation(int index) const {
1566 return Representation::Tagged();
1567 }
1568
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001569 private:
1570 Handle<String> name_;
1571};
1572
1573
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001574class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001575 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001576 HCallFunction(HValue* context, int argument_count)
1577 : HUnaryCall(context, argument_count) {
1578 }
1579
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001580 HValue* context() { return value(); }
1581
1582 virtual Representation RequiredInputRepresentation(int index) const {
1583 return Representation::Tagged();
1584 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001586 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587};
1588
1589
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001590class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001591 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001592 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1593 : HUnaryCall(context, argument_count), name_(name) {
1594 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001596 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001598 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001599 Handle<String> name() const { return name_; }
1600
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001601 virtual Representation RequiredInputRepresentation(int index) const {
1602 return Representation::Tagged();
1603 }
1604
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001605 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606
1607 private:
1608 Handle<String> name_;
1609};
1610
1611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001612class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001613 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001614 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001615 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001617 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001618
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001619 Handle<JSFunction> target() const { return target_; }
1620
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001621 virtual Representation RequiredInputRepresentation(int index) const {
1622 return Representation::None();
1623 }
1624
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001625 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001626
1627 private:
1628 Handle<JSFunction> target_;
1629};
1630
1631
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001632class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001634 HCallNew(HValue* context, HValue* constructor, int argument_count)
1635 : HBinaryCall(context, constructor, argument_count) {
1636 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001637
1638 virtual Representation RequiredInputRepresentation(int index) const {
1639 return Representation::Tagged();
1640 }
1641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001642 HValue* context() { return first(); }
1643 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001644
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001645 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646};
1647
1648
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001649class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001650 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001651 HCallRuntime(HValue* context,
1652 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001653 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001655 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1656 SetOperandAt(0, context);
1657 }
1658
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001659 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001661 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001662 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663 Handle<String> name() const { return name_; }
1664
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001665 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001666 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001667 }
1668
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001669 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001670
1671 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001672 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001673 Handle<String> name_;
1674};
1675
1676
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001677class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001678 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001679 HJSArrayLength(HValue* value, HValue* typecheck) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001680 // The length of an array is stored as a tagged value in the array
1681 // object. It is guaranteed to be 32 bit integer, but it can be
1682 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001683 SetOperandAt(0, value);
1684 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001685 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001687 SetFlag(kDependsOnArrayLengths);
1688 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001689 }
1690
1691 virtual Representation RequiredInputRepresentation(int index) const {
1692 return Representation::Tagged();
1693 }
1694
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001695 HValue* value() { return OperandAt(0); }
1696
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001697 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001698
1699 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001700 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001701};
1702
1703
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001704class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001705 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001706 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001707 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001708 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001709 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001710 }
1711
1712 virtual Representation RequiredInputRepresentation(int index) const {
1713 return Representation::Tagged();
1714 }
1715
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001716 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001717
1718 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001719 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001720};
1721
1722
whesse@chromium.org7b260152011-06-20 15:33:18 +00001723class HElementsKind: public HUnaryOperation {
1724 public:
1725 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1726 set_representation(Representation::Integer32());
1727 SetFlag(kUseGVN);
1728 SetFlag(kDependsOnMaps);
1729 }
1730
1731 virtual Representation RequiredInputRepresentation(int index) const {
1732 return Representation::Tagged();
1733 }
1734
1735 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1736
1737 protected:
1738 virtual bool DataEquals(HValue* other) { return true; }
1739};
1740
1741
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001742class HBitNot: public HUnaryOperation {
1743 public:
1744 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1745 set_representation(Representation::Integer32());
1746 SetFlag(kUseGVN);
1747 SetFlag(kTruncatingToInt32);
1748 }
1749
1750 virtual Representation RequiredInputRepresentation(int index) const {
1751 return Representation::Integer32();
1752 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001753 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001754
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001755 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001756
1757 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001758 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001759};
1760
1761
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001762class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001764 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1765 : op_(op) {
1766 SetOperandAt(0, context);
1767 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001768 switch (op) {
1769 case kMathFloor:
1770 case kMathRound:
1771 case kMathCeil:
1772 set_representation(Representation::Integer32());
1773 break;
1774 case kMathAbs:
1775 set_representation(Representation::Tagged());
1776 SetFlag(kFlexibleRepresentation);
1777 break;
1778 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001779 case kMathPowHalf:
1780 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001781 case kMathSin:
1782 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001783 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001784 break;
1785 default:
1786 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787 }
1788 SetFlag(kUseGVN);
1789 }
1790
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001791 HValue* context() { return OperandAt(0); }
1792 HValue* value() { return OperandAt(1); }
1793
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001794 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001796 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001797
1798 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1799
1800 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001801 if (index == 0) {
1802 return Representation::Tagged();
1803 } else {
1804 switch (op_) {
1805 case kMathFloor:
1806 case kMathRound:
1807 case kMathCeil:
1808 case kMathSqrt:
1809 case kMathPowHalf:
1810 case kMathLog:
1811 case kMathSin:
1812 case kMathCos:
1813 return Representation::Double();
1814 case kMathAbs:
1815 return representation();
1816 default:
1817 UNREACHABLE();
1818 return Representation::None();
1819 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001820 }
1821 }
1822
1823 virtual HValue* Canonicalize() {
1824 // If the input is integer32 then we replace the floor instruction
1825 // with its inputs. This happens before the representation changes are
1826 // introduced.
1827 if (op() == kMathFloor) {
1828 if (value()->representation().IsInteger32()) return value();
1829 }
1830 return this;
1831 }
1832
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001833 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001834 const char* OpName() const;
1835
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001836 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001837
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001838 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001839 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001840 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1841 return op_ == b->op();
1842 }
1843
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001844 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001845 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001846};
1847
1848
1849class HLoadElements: public HUnaryOperation {
1850 public:
1851 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1852 set_representation(Representation::Tagged());
1853 SetFlag(kUseGVN);
1854 SetFlag(kDependsOnMaps);
1855 }
1856
1857 virtual Representation RequiredInputRepresentation(int index) const {
1858 return Representation::Tagged();
1859 }
1860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001861 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001862
1863 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001864 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001865};
1866
1867
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001868class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001869 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001870 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001871 : HUnaryOperation(value) {
1872 set_representation(Representation::External());
1873 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001874 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001875 // change once set, so it's no necessary to introduce any additional
1876 // dependencies on top of the inputs.
1877 SetFlag(kUseGVN);
1878 }
1879
1880 virtual Representation RequiredInputRepresentation(int index) const {
1881 return Representation::Tagged();
1882 }
1883
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001884 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001885
1886 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001887 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001888};
1889
1890
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001891class HCheckMap: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001892 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001893 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
1894 : map_(map) {
1895 SetOperandAt(0, value);
1896 // If callers don't depend on a typecheck, they can pass in NULL. In that
1897 // case we use a copy of the |value| argument as a dummy value.
1898 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001899 set_representation(Representation::Tagged());
1900 SetFlag(kUseGVN);
1901 SetFlag(kDependsOnMaps);
1902 }
1903
1904 virtual Representation RequiredInputRepresentation(int index) const {
1905 return Representation::Tagged();
1906 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001907 virtual void PrintDataTo(StringStream* stream);
1908 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001909
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001910 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911 Handle<Map> map() const { return map_; }
1912
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001913 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001914
1915 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001916 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001917 HCheckMap* b = HCheckMap::cast(other);
1918 return map_.is_identical_to(b->map());
1919 }
1920
1921 private:
1922 Handle<Map> map_;
1923};
1924
1925
1926class HCheckFunction: public HUnaryOperation {
1927 public:
1928 HCheckFunction(HValue* value, Handle<JSFunction> function)
1929 : HUnaryOperation(value), target_(function) {
1930 set_representation(Representation::Tagged());
1931 SetFlag(kUseGVN);
1932 }
1933
1934 virtual Representation RequiredInputRepresentation(int index) const {
1935 return Representation::Tagged();
1936 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001937 virtual void PrintDataTo(StringStream* stream);
1938 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001939
1940#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001941 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001942#endif
1943
1944 Handle<JSFunction> target() const { return target_; }
1945
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001946 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001947
1948 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001949 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001950 HCheckFunction* b = HCheckFunction::cast(other);
1951 return target_.is_identical_to(b->target());
1952 }
1953
1954 private:
1955 Handle<JSFunction> target_;
1956};
1957
1958
1959class HCheckInstanceType: public HUnaryOperation {
1960 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001961 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1962 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001963 }
1964 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1965 return new HCheckInstanceType(value, IS_JS_ARRAY);
1966 }
1967 static HCheckInstanceType* NewIsString(HValue* value) {
1968 return new HCheckInstanceType(value, IS_STRING);
1969 }
1970 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1971 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001972 }
1973
1974 virtual Representation RequiredInputRepresentation(int index) const {
1975 return Representation::Tagged();
1976 }
1977
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00001978 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00001979
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001980 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1981 void GetCheckInterval(InstanceType* first, InstanceType* last);
1982 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001983
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001984 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001985
1986 protected:
1987 // TODO(ager): It could be nice to allow the ommision of instance
1988 // type checks if we have already performed an instance type check
1989 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001990 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001991 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001992 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001993 }
1994
1995 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001996 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001997 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001998 IS_JS_ARRAY,
1999 IS_STRING,
2000 IS_SYMBOL,
2001 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2002 };
2003
2004 HCheckInstanceType(HValue* value, Check check)
2005 : HUnaryOperation(value), check_(check) {
2006 set_representation(Representation::Tagged());
2007 SetFlag(kUseGVN);
2008 }
2009
2010 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002011};
2012
2013
2014class HCheckNonSmi: public HUnaryOperation {
2015 public:
2016 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2017 set_representation(Representation::Tagged());
2018 SetFlag(kUseGVN);
2019 }
2020
2021 virtual Representation RequiredInputRepresentation(int index) const {
2022 return Representation::Tagged();
2023 }
2024
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002025 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002026
2027#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002028 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002029#endif
2030
danno@chromium.org160a7b02011-04-18 15:51:38 +00002031 virtual HValue* Canonicalize() {
2032 HType value_type = value()->type();
2033 if (!value_type.IsUninitialized() &&
2034 (value_type.IsHeapNumber() ||
2035 value_type.IsString() ||
2036 value_type.IsBoolean() ||
2037 value_type.IsNonPrimitive())) {
2038 return NULL;
2039 }
2040 return this;
2041 }
2042
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002043 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002044
2045 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002046 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002047};
2048
2049
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002050class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002051 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002052 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2053 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054 SetFlag(kUseGVN);
2055 SetFlag(kDependsOnMaps);
2056 }
2057
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002058#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002059 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060#endif
2061
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002062 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002065 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002067 virtual Representation RequiredInputRepresentation(int index) const {
2068 return Representation::None();
2069 }
2070
2071 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002072 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002073 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2074 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2075 return hash;
2076 }
2077
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002078 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002079 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002080 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002081 return prototype_.is_identical_to(b->prototype()) &&
2082 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002083 }
2084
2085 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002086 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002087 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088};
2089
2090
2091class HCheckSmi: public HUnaryOperation {
2092 public:
2093 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2094 set_representation(Representation::Tagged());
2095 SetFlag(kUseGVN);
2096 }
2097
2098 virtual Representation RequiredInputRepresentation(int index) const {
2099 return Representation::Tagged();
2100 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002101 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002102
2103#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002104 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002105#endif
2106
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002107 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002108
2109 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002110 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111};
2112
2113
2114class HPhi: public HValue {
2115 public:
2116 explicit HPhi(int merged_index)
2117 : inputs_(2),
2118 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002119 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002120 is_live_(false),
2121 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2123 non_phi_uses_[i] = 0;
2124 indirect_uses_[i] = 0;
2125 }
2126 ASSERT(merged_index >= 0);
2127 set_representation(Representation::Tagged());
2128 SetFlag(kFlexibleRepresentation);
2129 }
2130
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002131 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002132 bool double_occurred = false;
2133 bool int32_occurred = false;
2134 for (int i = 0; i < OperandCount(); ++i) {
2135 HValue* value = OperandAt(i);
2136 if (value->representation().IsDouble()) double_occurred = true;
2137 if (value->representation().IsInteger32()) int32_occurred = true;
2138 if (value->representation().IsTagged()) return Representation::Tagged();
2139 }
2140
2141 if (double_occurred) return Representation::Double();
2142 if (int32_occurred) return Representation::Integer32();
2143 return Representation::None();
2144 }
2145
2146 virtual Range* InferRange();
2147 virtual Representation RequiredInputRepresentation(int index) const {
2148 return representation();
2149 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002150 virtual HType CalculateInferredType();
2151 virtual int OperandCount() { return inputs_.length(); }
2152 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2153 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002154 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002155 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002157 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002158
2159 int merged_index() const { return merged_index_; }
2160
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002161 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002162
2163#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002164 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165#endif
2166
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167 void InitRealUses(int id);
2168 void AddNonPhiUsesFrom(HPhi* other);
2169 void AddIndirectUsesTo(int* use_count);
2170
2171 int tagged_non_phi_uses() const {
2172 return non_phi_uses_[Representation::kTagged];
2173 }
2174 int int32_non_phi_uses() const {
2175 return non_phi_uses_[Representation::kInteger32];
2176 }
2177 int double_non_phi_uses() const {
2178 return non_phi_uses_[Representation::kDouble];
2179 }
2180 int tagged_indirect_uses() const {
2181 return indirect_uses_[Representation::kTagged];
2182 }
2183 int int32_indirect_uses() const {
2184 return indirect_uses_[Representation::kInteger32];
2185 }
2186 int double_indirect_uses() const {
2187 return indirect_uses_[Representation::kDouble];
2188 }
2189 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002190 bool is_live() { return is_live_; }
2191 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002192
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002193 static HPhi* cast(HValue* value) {
2194 ASSERT(value->IsPhi());
2195 return reinterpret_cast<HPhi*>(value);
2196 }
2197 virtual Opcode opcode() const { return HValue::kPhi; }
2198
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002199 virtual bool IsConvertibleToInteger() const {
2200 return is_convertible_to_integer_;
2201 }
2202
2203 void set_is_convertible_to_integer(bool b) {
2204 is_convertible_to_integer_ = b;
2205 }
2206
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002207 protected:
2208 virtual void DeleteFromGraph();
2209 virtual void InternalSetOperandAt(int index, HValue* value) {
2210 inputs_[index] = value;
2211 }
2212
2213 private:
2214 ZoneList<HValue*> inputs_;
2215 int merged_index_;
2216
2217 int non_phi_uses_[Representation::kNumRepresentations];
2218 int indirect_uses_[Representation::kNumRepresentations];
2219 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002220 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002221 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002222};
2223
2224
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002225class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002226 public:
2227 HArgumentsObject() {
2228 set_representation(Representation::Tagged());
2229 SetFlag(kIsArguments);
2230 }
2231
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002232 virtual Representation RequiredInputRepresentation(int index) const {
2233 return Representation::None();
2234 }
2235
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002236 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002237};
2238
2239
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002240class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002241 public:
2242 HConstant(Handle<Object> handle, Representation r);
2243
2244 Handle<Object> handle() const { return handle_; }
2245
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002246 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002247
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002248 virtual Representation RequiredInputRepresentation(int index) const {
2249 return Representation::None();
2250 }
2251
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002252 virtual bool IsConvertibleToInteger() const {
2253 if (handle_->IsSmi()) return true;
2254 if (handle_->IsHeapNumber() &&
2255 (HeapNumber::cast(*handle_)->value() ==
2256 static_cast<double>(NumberToInt32(*handle_)))) return true;
2257 return false;
2258 }
2259
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002260 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002261 virtual void PrintDataTo(StringStream* stream);
2262 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002263 bool IsInteger() const { return handle_->IsSmi(); }
2264 HConstant* CopyToRepresentation(Representation r) const;
2265 HConstant* CopyToTruncatedInt32() const;
2266 bool HasInteger32Value() const { return has_int32_value_; }
2267 int32_t Integer32Value() const {
2268 ASSERT(HasInteger32Value());
2269 return int32_value_;
2270 }
2271 bool HasDoubleValue() const { return has_double_value_; }
2272 double DoubleValue() const {
2273 ASSERT(HasDoubleValue());
2274 return double_value_;
2275 }
2276 bool HasStringValue() const { return handle_->IsString(); }
2277
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002278 bool ToBoolean() const;
2279
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002280 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002281 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002282 return reinterpret_cast<intptr_t>(*handle());
2283 }
2284
2285#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002286 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002287#endif
2288
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002289 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002290
2291 protected:
2292 virtual Range* InferRange();
2293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002294 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002295 HConstant* other_constant = HConstant::cast(other);
2296 return handle().is_identical_to(other_constant->handle());
2297 }
2298
2299 private:
2300 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002301
2302 // The following two values represent the int32 and the double value of the
2303 // given constant if there is a lossless conversion between the constant
2304 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002305 bool has_int32_value_ : 1;
2306 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002307 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002308 double double_value_;
2309};
2310
2311
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002312class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002313 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002314 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002316 SetOperandAt(0, context);
2317 SetOperandAt(1, left);
2318 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319 }
2320
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002321 HValue* context() { return OperandAt(0); }
2322 HValue* left() { return OperandAt(1); }
2323 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002324
2325 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2326 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002327 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002328 if (IsCommutative() && left()->IsConstant()) return right();
2329 return left();
2330 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002331 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002332 if (IsCommutative() && left()->IsConstant()) return left();
2333 return right();
2334 }
2335
2336 virtual bool IsCommutative() const { return false; }
2337
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002338 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339};
2340
2341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002342class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002343 public:
2344 HApplyArguments(HValue* function,
2345 HValue* receiver,
2346 HValue* length,
2347 HValue* elements) {
2348 set_representation(Representation::Tagged());
2349 SetOperandAt(0, function);
2350 SetOperandAt(1, receiver);
2351 SetOperandAt(2, length);
2352 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002353 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002354 }
2355
2356 virtual Representation RequiredInputRepresentation(int index) const {
2357 // The length is untagged, all other inputs are tagged.
2358 return (index == 2)
2359 ? Representation::Integer32()
2360 : Representation::Tagged();
2361 }
2362
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002363 HValue* function() { return OperandAt(0); }
2364 HValue* receiver() { return OperandAt(1); }
2365 HValue* length() { return OperandAt(2); }
2366 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002367
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002368 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369};
2370
2371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002372class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002373 public:
2374 HArgumentsElements() {
2375 // The value produced by this instruction is a pointer into the stack
2376 // that looks as if it was a smi because of alignment.
2377 set_representation(Representation::Tagged());
2378 SetFlag(kUseGVN);
2379 }
2380
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002381 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002382
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002383 virtual Representation RequiredInputRepresentation(int index) const {
2384 return Representation::None();
2385 }
2386
ager@chromium.org378b34e2011-01-28 08:04:38 +00002387 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002388 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002389};
2390
2391
2392class HArgumentsLength: public HUnaryOperation {
2393 public:
2394 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2395 set_representation(Representation::Integer32());
2396 SetFlag(kUseGVN);
2397 }
2398
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002399 virtual Representation RequiredInputRepresentation(int index) const {
2400 return Representation::Tagged();
2401 }
2402
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002403 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002404
2405 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002406 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002407};
2408
2409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002410class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002411 public:
2412 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2413 set_representation(Representation::Tagged());
2414 SetFlag(kUseGVN);
2415 SetOperandAt(0, arguments);
2416 SetOperandAt(1, length);
2417 SetOperandAt(2, index);
2418 }
2419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002420 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002421
2422 virtual Representation RequiredInputRepresentation(int index) const {
2423 // The arguments elements is considered tagged.
2424 return index == 0
2425 ? Representation::Tagged()
2426 : Representation::Integer32();
2427 }
2428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002429 HValue* arguments() { return OperandAt(0); }
2430 HValue* length() { return OperandAt(1); }
2431 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002432
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002433 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002434
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002435 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002436};
2437
2438
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002439class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002440 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002441 HBoundsCheck(HValue* index, HValue* length) {
2442 SetOperandAt(0, index);
2443 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002444 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445 SetFlag(kUseGVN);
2446 }
2447
2448 virtual Representation RequiredInputRepresentation(int index) const {
2449 return Representation::Integer32();
2450 }
2451
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002452 virtual void PrintDataTo(StringStream* stream);
2453
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002454 HValue* index() { return OperandAt(0); }
2455 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002456
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002457 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002458
2459 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002460 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002461};
2462
2463
2464class HBitwiseBinaryOperation: public HBinaryOperation {
2465 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002466 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2467 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002468 set_representation(Representation::Tagged());
2469 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002470 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002471 }
2472
2473 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002474 return index == 0
2475 ? Representation::Tagged()
2476 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002477 }
2478
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002479 virtual void RepresentationChanged(Representation to) {
2480 if (!to.IsTagged()) {
2481 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002482 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002483 SetFlag(kTruncatingToInt32);
2484 SetFlag(kUseGVN);
2485 }
2486 }
2487
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002488 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002489
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002490 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002491};
2492
2493
2494class HArithmeticBinaryOperation: public HBinaryOperation {
2495 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002496 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2497 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002498 set_representation(Representation::Tagged());
2499 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002500 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002501 }
2502
2503 virtual void RepresentationChanged(Representation to) {
2504 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002505 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002506 SetFlag(kUseGVN);
2507 }
2508 }
2509
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002510 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002512 return index == 0
2513 ? Representation::Tagged()
2514 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002516
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002517 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002518 if (left()->representation().Equals(right()->representation())) {
2519 return left()->representation();
2520 }
2521 return HValue::InferredRepresentation();
2522 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002523};
2524
2525
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002526class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002527 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002528 HCompareGeneric(HValue* context,
2529 HValue* left,
2530 HValue* right,
2531 Token::Value token)
2532 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002533 ASSERT(Token::IsCompareOp(token));
2534 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002535 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536 }
2537
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002539 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002541
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002542 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002543 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002545
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002547 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002549 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002551 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2552
2553 private:
2554 Token::Value token_;
2555};
2556
2557
2558class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2559 public:
2560 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2561 : token_(token) {
2562 ASSERT(Token::IsCompareOp(token));
2563 SetOperandAt(0, left);
2564 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002565 }
2566
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002567 HValue* left() { return OperandAt(0); }
2568 HValue* right() { return OperandAt(1); }
2569 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002570
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002571 void SetInputRepresentation(Representation r);
2572 Representation GetInputRepresentation() const {
2573 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002574 }
2575
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002576 virtual Representation RequiredInputRepresentation(int index) const {
2577 return input_representation_;
2578 }
2579 virtual void PrintDataTo(StringStream* stream);
2580
2581 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2582
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 private:
2584 Representation input_representation_;
2585 Token::Value token_;
2586};
2587
2588
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002589class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002590 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002591 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2592 SetOperandAt(0, left);
2593 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002594 }
2595
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002596 HValue* left() { return OperandAt(0); }
2597 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002598
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002599 virtual Representation RequiredInputRepresentation(int index) const {
2600 return Representation::Tagged();
2601 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002602
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002603 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604};
2605
2606
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002607class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002608 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002609 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2610 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002611 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002612 }
2613
2614 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002615 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002616 int right() const { return right_; }
2617
whesse@chromium.org7b260152011-06-20 15:33:18 +00002618 virtual Representation RequiredInputRepresentation(int index) const {
2619 return Representation::Integer32();
2620 }
2621
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002622 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002623
2624 private:
2625 const Token::Value op_;
2626 const int right_;
2627};
2628
2629
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002630class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002631 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002632 HIsNullAndBranch(HValue* value, bool is_strict)
2633 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002634
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002635 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002636
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002637 virtual Representation RequiredInputRepresentation(int index) const {
2638 return Representation::Tagged();
2639 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002640
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002641 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002642
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002643 private:
2644 bool is_strict_;
2645};
2646
2647
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002648class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002649 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002650 explicit HIsObjectAndBranch(HValue* value)
2651 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002652
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002653 virtual Representation RequiredInputRepresentation(int index) const {
2654 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002655 }
2656
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002657 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2658};
2659
2660
2661class HIsSmiAndBranch: public HUnaryControlInstruction {
2662 public:
2663 explicit HIsSmiAndBranch(HValue* value)
2664 : HUnaryControlInstruction(value, NULL, NULL) { }
2665
2666 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2667
2668 virtual Representation RequiredInputRepresentation(int index) const {
2669 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002670 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002671
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002672 protected:
2673 virtual bool DataEquals(HValue* other) { return true; }
2674};
2675
2676
2677class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2678 public:
2679 explicit HIsUndetectableAndBranch(HValue* value)
2680 : HUnaryControlInstruction(value, NULL, NULL) { }
2681
2682 virtual Representation RequiredInputRepresentation(int index) const {
2683 return Representation::Tagged();
2684 }
2685
2686 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2687};
2688
2689
2690class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2691 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002692 virtual Representation RequiredInputRepresentation(int index) const {
2693 return Representation::None();
2694 }
2695
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002696 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002697};
2698
2699
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002700class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002701 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002702 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2703 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2704 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2705 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002706 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2707 }
2708
2709 InstanceType from() { return from_; }
2710 InstanceType to() { return to_; }
2711
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002712 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002713
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002714 virtual Representation RequiredInputRepresentation(int index) const {
2715 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002716 }
2717
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002718 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2719
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002720 private:
2721 InstanceType from_;
2722 InstanceType to_; // Inclusive range, not all combinations work.
2723};
2724
2725
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002726class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002727 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002728 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2729 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002730
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002731 virtual Representation RequiredInputRepresentation(int index) const {
2732 return Representation::Tagged();
2733 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002734
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002735 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736};
2737
2738
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002739class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002740 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002741 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2742 set_representation(Representation::Tagged());
2743 SetFlag(kUseGVN);
2744 }
2745
2746 virtual Representation RequiredInputRepresentation(int index) const {
2747 return Representation::Tagged();
2748 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002749
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002750 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002751
2752 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002753 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002754};
2755
2756
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002757class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002758 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002759 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2760 : HUnaryControlInstruction(value, NULL, NULL),
2761 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002762
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002763 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2764
2765 virtual Representation RequiredInputRepresentation(int index) const {
2766 return Representation::Tagged();
2767 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002769 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002770
2771 Handle<String> class_name() const { return class_name_; }
2772
2773 private:
2774 Handle<String> class_name_;
2775};
2776
2777
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002778class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002780 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2781 : HUnaryControlInstruction(value, NULL, NULL),
2782 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002783
2784 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002785 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002786
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002787 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002789 virtual Representation RequiredInputRepresentation(int index) const {
2790 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791 }
2792
2793 private:
2794 Handle<String> type_literal_;
2795};
2796
2797
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002798class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002800 HInstanceOf(HValue* context, HValue* left, HValue* right)
2801 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002802 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002803 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002804 }
2805
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806 virtual Representation RequiredInputRepresentation(int index) const {
2807 return Representation::Tagged();
2808 }
2809
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002810 virtual HType CalculateInferredType();
2811
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002812 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002813
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002814 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815};
2816
2817
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002818class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002819 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002820 HInstanceOfKnownGlobal(HValue* context,
2821 HValue* left,
2822 Handle<JSFunction> right)
2823 : function_(right) {
2824 SetOperandAt(0, context);
2825 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002826 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002827 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002828 }
2829
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002830 HValue* context() { return OperandAt(0); }
2831 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002832 Handle<JSFunction> function() { return function_; }
2833
2834 virtual Representation RequiredInputRepresentation(int index) const {
2835 return Representation::Tagged();
2836 }
2837
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002838 virtual HType CalculateInferredType();
2839
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002840 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002841
2842 private:
2843 Handle<JSFunction> function_;
2844};
2845
2846
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002847class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002848 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002849 HPower(HValue* left, HValue* right) {
2850 SetOperandAt(0, left);
2851 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002852 set_representation(Representation::Double());
2853 SetFlag(kUseGVN);
2854 }
2855
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002856 HValue* left() { return OperandAt(0); }
2857 HValue* right() { return OperandAt(1); }
2858
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002859 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002860 return index == 0
2861 ? Representation::Double()
2862 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002863 }
2864
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002865 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002866
2867 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002868 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002869};
2870
2871
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002872class HAdd: public HArithmeticBinaryOperation {
2873 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002874 HAdd(HValue* context, HValue* left, HValue* right)
2875 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002876 SetFlag(kCanOverflow);
2877 }
2878
2879 // Add is only commutative if two integer values are added and not if two
2880 // tagged values are added (because it might be a String concatenation).
2881 virtual bool IsCommutative() const {
2882 return !representation().IsTagged();
2883 }
2884
2885 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002887 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002888
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002889 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002890
2891 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002892 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002893
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002894 virtual Range* InferRange();
2895};
2896
2897
2898class HSub: public HArithmeticBinaryOperation {
2899 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002900 HSub(HValue* context, HValue* left, HValue* right)
2901 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902 SetFlag(kCanOverflow);
2903 }
2904
2905 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2906
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002907 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908
2909 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002910 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002911
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002912 virtual Range* InferRange();
2913};
2914
2915
2916class HMul: public HArithmeticBinaryOperation {
2917 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002918 HMul(HValue* context, HValue* left, HValue* right)
2919 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920 SetFlag(kCanOverflow);
2921 }
2922
2923 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2924
2925 // Only commutative if it is certain that not two objects are multiplicated.
2926 virtual bool IsCommutative() const {
2927 return !representation().IsTagged();
2928 }
2929
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002930 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931
2932 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002933 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002934
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002935 virtual Range* InferRange();
2936};
2937
2938
2939class HMod: public HArithmeticBinaryOperation {
2940 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002941 HMod(HValue* context, HValue* left, HValue* right)
2942 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002943 SetFlag(kCanBeDivByZero);
2944 }
2945
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002946 bool HasPowerOf2Divisor() {
2947 if (right()->IsConstant() &&
2948 HConstant::cast(right())->HasInteger32Value()) {
2949 int32_t value = HConstant::cast(right())->Integer32Value();
2950 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2951 }
2952
2953 return false;
2954 }
2955
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2957
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002958 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002959
2960 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002961 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002962
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002963 virtual Range* InferRange();
2964};
2965
2966
2967class HDiv: public HArithmeticBinaryOperation {
2968 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002969 HDiv(HValue* context, HValue* left, HValue* right)
2970 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002971 SetFlag(kCanBeDivByZero);
2972 SetFlag(kCanOverflow);
2973 }
2974
2975 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2976
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002977 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002978
2979 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002980 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002981
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982 virtual Range* InferRange();
2983};
2984
2985
2986class HBitAnd: public HBitwiseBinaryOperation {
2987 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002988 HBitAnd(HValue* context, HValue* left, HValue* right)
2989 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002990
2991 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002992 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002994 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002995
2996 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002997 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002998
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999 virtual Range* InferRange();
3000};
3001
3002
3003class HBitXor: public HBitwiseBinaryOperation {
3004 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003005 HBitXor(HValue* context, HValue* left, HValue* right)
3006 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003007
3008 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003009 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003011 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003012
3013 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015};
3016
3017
3018class HBitOr: public HBitwiseBinaryOperation {
3019 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003020 HBitOr(HValue* context, HValue* left, HValue* right)
3021 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022
3023 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003024 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003026 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
3028 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003029 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003030
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003031 virtual Range* InferRange();
3032};
3033
3034
3035class HShl: public HBitwiseBinaryOperation {
3036 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003037 HShl(HValue* context, HValue* left, HValue* right)
3038 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003039
3040 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003041 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003042
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003043 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003044
3045 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047};
3048
3049
3050class HShr: public HBitwiseBinaryOperation {
3051 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003052 HShr(HValue* context, HValue* left, HValue* right)
3053 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003054
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003055 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003056 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003057
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003058 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003059
3060 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003061 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062};
3063
3064
3065class HSar: public HBitwiseBinaryOperation {
3066 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003067 HSar(HValue* context, HValue* left, HValue* right)
3068 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003069
3070 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003071 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003073 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003074
3075 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003076 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077};
3078
3079
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003080class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081 public:
3082 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3083 SetFlag(kChangesOsrEntries);
3084 }
3085
3086 int ast_id() const { return ast_id_; }
3087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003088 virtual Representation RequiredInputRepresentation(int index) const {
3089 return Representation::None();
3090 }
3091
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003092 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003093
3094 private:
3095 int ast_id_;
3096};
3097
3098
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003099class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003100 public:
3101 explicit HParameter(unsigned index) : index_(index) {
3102 set_representation(Representation::Tagged());
3103 }
3104
3105 unsigned index() const { return index_; }
3106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003107 virtual void PrintDataTo(StringStream* stream);
3108
3109 virtual Representation RequiredInputRepresentation(int index) const {
3110 return Representation::None();
3111 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003113 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114
3115 private:
3116 unsigned index_;
3117};
3118
3119
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003120class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003121 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003122 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3123 : HUnaryCall(context, argument_count),
3124 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003126 }
3127
3128 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003129
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003130 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003131
3132 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3133 transcendental_type_ = transcendental_type;
3134 }
3135 TranscendentalCache::Type transcendental_type() {
3136 return transcendental_type_;
3137 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003138
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003139 virtual void PrintDataTo(StringStream* stream);
3140
3141 virtual Representation RequiredInputRepresentation(int index) const {
3142 return Representation::Tagged();
3143 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003144
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003145 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146
3147 private:
3148 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149 TranscendentalCache::Type transcendental_type_;
3150};
3151
3152
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003153class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154 public:
3155 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3156
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003157 virtual Representation RequiredInputRepresentation(int index) const {
3158 return Representation::None();
3159 }
3160
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003161 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162};
3163
3164
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003165class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003167 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003168 : cell_(cell), check_hole_value_(check_hole_value) {
3169 set_representation(Representation::Tagged());
3170 SetFlag(kUseGVN);
3171 SetFlag(kDependsOnGlobalVars);
3172 }
3173
3174 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3175 bool check_hole_value() const { return check_hole_value_; }
3176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003177 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003179 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003180 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003181 return reinterpret_cast<intptr_t>(*cell_);
3182 }
3183
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003184 virtual Representation RequiredInputRepresentation(int index) const {
3185 return Representation::None();
3186 }
3187
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003188 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003189
3190 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003191 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003192 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193 return cell_.is_identical_to(b->cell());
3194 }
3195
3196 private:
3197 Handle<JSGlobalPropertyCell> cell_;
3198 bool check_hole_value_;
3199};
3200
3201
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003202class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003203 public:
3204 HLoadGlobalGeneric(HValue* context,
3205 HValue* global_object,
3206 Handle<Object> name,
3207 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003208 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003209 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003210 SetOperandAt(0, context);
3211 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003212 set_representation(Representation::Tagged());
3213 SetAllSideEffects();
3214 }
3215
3216 HValue* context() { return OperandAt(0); }
3217 HValue* global_object() { return OperandAt(1); }
3218 Handle<Object> name() const { return name_; }
3219 bool for_typeof() const { return for_typeof_; }
3220
3221 virtual void PrintDataTo(StringStream* stream);
3222
3223 virtual Representation RequiredInputRepresentation(int index) const {
3224 return Representation::Tagged();
3225 }
3226
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003227 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003228
3229 private:
3230 Handle<Object> name_;
3231 bool for_typeof_;
3232};
3233
3234
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003235class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003236 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003237 HStoreGlobalCell(HValue* value,
3238 Handle<JSGlobalPropertyCell> cell,
3239 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003240 : HUnaryOperation(value),
3241 cell_(cell),
3242 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243 SetFlag(kChangesGlobalVars);
3244 }
3245
3246 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003247 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003248
3249 virtual Representation RequiredInputRepresentation(int index) const {
3250 return Representation::Tagged();
3251 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003252 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003253
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003254 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003255
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003256 private:
3257 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003258 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003259};
3260
3261
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003262class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3263 public:
3264 HStoreGlobalGeneric(HValue* context,
3265 HValue* global_object,
3266 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003267 HValue* value,
3268 bool strict_mode)
3269 : name_(name),
3270 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003271 SetOperandAt(0, context);
3272 SetOperandAt(1, global_object);
3273 SetOperandAt(2, value);
3274 set_representation(Representation::Tagged());
3275 SetAllSideEffects();
3276 }
3277
3278 HValue* context() { return OperandAt(0); }
3279 HValue* global_object() { return OperandAt(1); }
3280 Handle<Object> name() const { return name_; }
3281 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003282 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003283
3284 virtual void PrintDataTo(StringStream* stream);
3285
3286 virtual Representation RequiredInputRepresentation(int index) const {
3287 return Representation::Tagged();
3288 }
3289
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003290 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003291
3292 private:
3293 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003294 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003295};
3296
3297
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003298class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003299 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003300 HLoadContextSlot(HValue* context , int slot_index)
3301 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003302 set_representation(Representation::Tagged());
3303 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003304 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003305 }
3306
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003307 int slot_index() const { return slot_index_; }
3308
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003309 virtual Representation RequiredInputRepresentation(int index) const {
3310 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003311 }
3312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003313 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003314
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003315 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003316
3317 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003318 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003319 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003320 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003321 }
3322
3323 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003324 int slot_index_;
3325};
3326
3327
3328static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003329 return !value->type().IsBoolean()
3330 && !value->type().IsSmi()
3331 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003332}
3333
3334
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003335class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003336 public:
3337 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003338 : slot_index_(slot_index) {
3339 SetOperandAt(0, context);
3340 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003341 SetFlag(kChangesContextSlots);
3342 }
3343
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003344 HValue* context() { return OperandAt(0); }
3345 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003346 int slot_index() const { return slot_index_; }
3347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003348 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003349 return StoringValueNeedsWriteBarrier(value());
3350 }
3351
3352 virtual Representation RequiredInputRepresentation(int index) const {
3353 return Representation::Tagged();
3354 }
3355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003356 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003357
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003358 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003359
3360 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003361 int slot_index_;
3362};
3363
3364
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003365class HLoadNamedField: public HUnaryOperation {
3366 public:
3367 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3368 : HUnaryOperation(object),
3369 is_in_object_(is_in_object),
3370 offset_(offset) {
3371 set_representation(Representation::Tagged());
3372 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003373 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003374 if (is_in_object) {
3375 SetFlag(kDependsOnInobjectFields);
3376 } else {
3377 SetFlag(kDependsOnBackingStoreFields);
3378 }
3379 }
3380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003381 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003382 bool is_in_object() const { return is_in_object_; }
3383 int offset() const { return offset_; }
3384
3385 virtual Representation RequiredInputRepresentation(int index) const {
3386 return Representation::Tagged();
3387 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003388 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003389
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003390 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003391
3392 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003393 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394 HLoadNamedField* b = HLoadNamedField::cast(other);
3395 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3396 }
3397
3398 private:
3399 bool is_in_object_;
3400 int offset_;
3401};
3402
3403
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003404class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003405 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003406 HLoadNamedFieldPolymorphic(HValue* context,
3407 HValue* object,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003408 ZoneMapList* types,
3409 Handle<String> name);
3410
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003411 HValue* context() { return OperandAt(0); }
3412 HValue* object() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003413 ZoneMapList* types() { return &types_; }
3414 Handle<String> name() { return name_; }
3415 bool need_generic() { return need_generic_; }
3416
3417 virtual Representation RequiredInputRepresentation(int index) const {
3418 return Representation::Tagged();
3419 }
3420
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003421 virtual void PrintDataTo(StringStream* stream);
3422
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003423 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003424
3425 static const int kMaxLoadPolymorphism = 4;
3426
3427 protected:
3428 virtual bool DataEquals(HValue* value);
3429
3430 private:
3431 ZoneMapList types_;
3432 Handle<String> name_;
3433 bool need_generic_;
3434};
3435
3436
3437
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003438class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003439 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003440 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003441 : name_(name) {
3442 SetOperandAt(0, context);
3443 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003444 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003445 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003446 }
3447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003448 HValue* context() { return OperandAt(0); }
3449 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450 Handle<Object> name() const { return name_; }
3451
3452 virtual Representation RequiredInputRepresentation(int index) const {
3453 return Representation::Tagged();
3454 }
3455
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003456 virtual void PrintDataTo(StringStream* stream);
3457
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003458 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003459
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003460 private:
3461 Handle<Object> name_;
3462};
3463
3464
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003465class HLoadFunctionPrototype: public HUnaryOperation {
3466 public:
3467 explicit HLoadFunctionPrototype(HValue* function)
3468 : HUnaryOperation(function) {
3469 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003470 SetFlag(kUseGVN);
3471 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003472 }
3473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003474 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003475
3476 virtual Representation RequiredInputRepresentation(int index) const {
3477 return Representation::Tagged();
3478 }
3479
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003480 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003481
3482 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003483 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003484};
3485
3486
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003487class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003488 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003489 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3490 SetOperandAt(0, obj);
3491 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003492 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003493 SetFlag(kDependsOnArrayElements);
3494 SetFlag(kUseGVN);
3495 }
3496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003497 HValue* object() { return OperandAt(0); }
3498 HValue* key() { return OperandAt(1); }
3499
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003500 virtual Representation RequiredInputRepresentation(int index) const {
3501 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003502 return index == 0
3503 ? Representation::Tagged()
3504 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003505 }
3506
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003507 virtual void PrintDataTo(StringStream* stream);
3508
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003509 bool RequiresHoleCheck() const;
3510
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003511 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003512
3513 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003514 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003515};
3516
3517
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003518class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3519 public:
3520 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3521 SetOperandAt(0, elements);
3522 SetOperandAt(1, key);
3523 set_representation(Representation::Double());
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003524 SetFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003525 SetFlag(kUseGVN);
3526 }
3527
3528 HValue* elements() { return OperandAt(0); }
3529 HValue* key() { return OperandAt(1); }
3530
3531 virtual Representation RequiredInputRepresentation(int index) const {
3532 // The key is supposed to be Integer32.
3533 return index == 0
3534 ? Representation::Tagged()
3535 : Representation::Integer32();
3536 }
3537
3538 virtual void PrintDataTo(StringStream* stream);
3539
3540 bool RequiresHoleCheck() const;
3541
3542 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3543
3544 protected:
3545 virtual bool DataEquals(HValue* other) { return true; }
3546};
3547
3548
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003549class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003550 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003551 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3552 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003553 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003554 : elements_kind_(elements_kind) {
3555 SetOperandAt(0, external_elements);
3556 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003557 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3558 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003559 set_representation(Representation::Double());
3560 } else {
3561 set_representation(Representation::Integer32());
3562 }
3563 SetFlag(kDependsOnSpecializedArrayElements);
3564 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003565 SetFlag(kDependsOnCalls);
3566 SetFlag(kUseGVN);
3567 }
3568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003569 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003570
3571 virtual Representation RequiredInputRepresentation(int index) const {
3572 // The key is supposed to be Integer32, but the base pointer
3573 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003574 return index == 0
3575 ? Representation::External()
3576 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003577 }
3578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 HValue* external_pointer() { return OperandAt(0); }
3580 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003581 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003582
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003583 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003584
3585 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003586 virtual bool DataEquals(HValue* other) {
3587 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3588 HLoadKeyedSpecializedArrayElement* cast_other =
3589 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003590 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003591 }
3592
3593 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003594 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003595};
3596
3597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003598class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003600 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003601 set_representation(Representation::Tagged());
3602 SetOperandAt(0, obj);
3603 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003604 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003605 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003606 }
3607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003608 HValue* object() { return OperandAt(0); }
3609 HValue* key() { return OperandAt(1); }
3610 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003612 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613
3614 virtual Representation RequiredInputRepresentation(int index) const {
3615 return Representation::Tagged();
3616 }
3617
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003618 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619};
3620
3621
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003622class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623 public:
3624 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003625 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003626 HValue* val,
3627 bool in_object,
3628 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003629 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 is_in_object_(in_object),
3631 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003632 SetOperandAt(0, obj);
3633 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634 if (is_in_object_) {
3635 SetFlag(kChangesInobjectFields);
3636 } else {
3637 SetFlag(kChangesBackingStoreFields);
3638 }
3639 }
3640
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003641 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003642
3643 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003644 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003645 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003646 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 HValue* object() { return OperandAt(0); }
3649 HValue* value() { return OperandAt(1); }
3650
3651 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003652 bool is_in_object() const { return is_in_object_; }
3653 int offset() const { return offset_; }
3654 Handle<Map> transition() const { return transition_; }
3655 void set_transition(Handle<Map> map) { transition_ = map; }
3656
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003657 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003658 return StoringValueNeedsWriteBarrier(value());
3659 }
3660
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003662 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003663 bool is_in_object_;
3664 int offset_;
3665 Handle<Map> transition_;
3666};
3667
3668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003669class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003671 HStoreNamedGeneric(HValue* context,
3672 HValue* object,
3673 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003674 HValue* value,
3675 bool strict_mode)
3676 : name_(name),
3677 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003678 SetOperandAt(0, object);
3679 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003680 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003681 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003682 }
3683
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003684 HValue* object() { return OperandAt(0); }
3685 HValue* value() { return OperandAt(1); }
3686 HValue* context() { return OperandAt(2); }
3687 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003688 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003689
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003690 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691
3692 virtual Representation RequiredInputRepresentation(int index) const {
3693 return Representation::Tagged();
3694 }
3695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003696 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003697
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003698 private:
3699 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003700 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701};
3702
3703
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003704class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003705 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003706 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3707 SetOperandAt(0, obj);
3708 SetOperandAt(1, key);
3709 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003710 SetFlag(kChangesArrayElements);
3711 }
3712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713 virtual Representation RequiredInputRepresentation(int index) const {
3714 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003715 return index == 1
3716 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003717 : Representation::Tagged();
3718 }
3719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003720 HValue* object() { return OperandAt(0); }
3721 HValue* key() { return OperandAt(1); }
3722 HValue* value() { return OperandAt(2); }
3723
3724 bool NeedsWriteBarrier() {
3725 return StoringValueNeedsWriteBarrier(value());
3726 }
3727
3728 virtual void PrintDataTo(StringStream* stream);
3729
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003730 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731};
3732
3733
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003734class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3735 public:
3736 HStoreKeyedFastDoubleElement(HValue* elements,
3737 HValue* key,
3738 HValue* val) {
3739 SetOperandAt(0, elements);
3740 SetOperandAt(1, key);
3741 SetOperandAt(2, val);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003742 SetFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003743 }
3744
3745 virtual Representation RequiredInputRepresentation(int index) const {
3746 if (index == 1) {
3747 return Representation::Integer32();
3748 } else if (index == 2) {
3749 return Representation::Double();
3750 } else {
3751 return Representation::Tagged();
3752 }
3753 }
3754
3755 HValue* elements() { return OperandAt(0); }
3756 HValue* key() { return OperandAt(1); }
3757 HValue* value() { return OperandAt(2); }
3758
3759 bool NeedsWriteBarrier() {
3760 return StoringValueNeedsWriteBarrier(value());
3761 }
3762
3763 virtual void PrintDataTo(StringStream* stream);
3764
3765 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3766};
3767
3768
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003769class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003770 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003771 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3772 HValue* key,
3773 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003774 JSObject::ElementsKind elements_kind)
3775 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003776 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003777 SetOperandAt(0, external_elements);
3778 SetOperandAt(1, key);
3779 SetOperandAt(2, val);
3780 }
3781
3782 virtual void PrintDataTo(StringStream* stream);
3783
3784 virtual Representation RequiredInputRepresentation(int index) const {
3785 if (index == 0) {
3786 return Representation::External();
3787 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003788 bool float_or_double_elements =
3789 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3790 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3791 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003792 return Representation::Double();
3793 } else {
3794 return Representation::Integer32();
3795 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003796 }
3797 }
3798
3799 HValue* external_pointer() { return OperandAt(0); }
3800 HValue* key() { return OperandAt(1); }
3801 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003802 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003803
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003804 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3805
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003806 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003807 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003808};
3809
3810
3811class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003812 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003813 HStoreKeyedGeneric(HValue* context,
3814 HValue* object,
3815 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003816 HValue* value,
3817 bool strict_mode)
3818 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003819 SetOperandAt(0, object);
3820 SetOperandAt(1, key);
3821 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003822 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003823 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003824 }
3825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003826 HValue* object() { return OperandAt(0); }
3827 HValue* key() { return OperandAt(1); }
3828 HValue* value() { return OperandAt(2); }
3829 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003830 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003832 virtual Representation RequiredInputRepresentation(int index) const {
3833 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003834 }
3835
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003836 virtual void PrintDataTo(StringStream* stream);
3837
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003838 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003839
3840 private:
3841 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003842};
3843
3844
danno@chromium.org160a7b02011-04-18 15:51:38 +00003845class HStringAdd: public HBinaryOperation {
3846 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003847 HStringAdd(HValue* context, HValue* left, HValue* right)
3848 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003849 set_representation(Representation::Tagged());
3850 SetFlag(kUseGVN);
3851 SetFlag(kDependsOnMaps);
3852 }
3853
3854 virtual Representation RequiredInputRepresentation(int index) const {
3855 return Representation::Tagged();
3856 }
3857
3858 virtual HType CalculateInferredType() {
3859 return HType::String();
3860 }
3861
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003862 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003863
3864 protected:
3865 virtual bool DataEquals(HValue* other) { return true; }
3866};
3867
3868
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003869class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003870 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003871 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3872 SetOperandAt(0, context);
3873 SetOperandAt(1, string);
3874 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003875 set_representation(Representation::Integer32());
3876 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003877 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003878 }
3879
3880 virtual Representation RequiredInputRepresentation(int index) const {
3881 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003882 return index == 2
3883 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003884 : Representation::Tagged();
3885 }
3886
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003887 HValue* context() { return OperandAt(0); }
3888 HValue* string() { return OperandAt(1); }
3889 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003890
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003891 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003892
3893 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003894 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003895
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003896 virtual Range* InferRange() {
3897 return new Range(0, String::kMaxUC16CharCode);
3898 }
3899};
3900
3901
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003902class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003903 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003904 HStringCharFromCode(HValue* context, HValue* char_code) {
3905 SetOperandAt(0, context);
3906 SetOperandAt(1, char_code);
3907 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003908 SetFlag(kUseGVN);
3909 }
3910
3911 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003912 return index == 0
3913 ? Representation::Tagged()
3914 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003915 }
3916
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003917 HValue* context() { return OperandAt(0); }
3918 HValue* value() { return OperandAt(1); }
3919
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003920 virtual bool DataEquals(HValue* other) { return true; }
3921
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003922 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003923};
3924
3925
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003926class HStringLength: public HUnaryOperation {
3927 public:
3928 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3929 set_representation(Representation::Tagged());
3930 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003931 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003932 }
3933
3934 virtual Representation RequiredInputRepresentation(int index) const {
3935 return Representation::Tagged();
3936 }
3937
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003938 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003939 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3940 return HType::Smi();
3941 }
3942
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003943 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003944
3945 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003946 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003947
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003948 virtual Range* InferRange() {
3949 return new Range(0, String::kMaxLength);
3950 }
3951};
3952
3953
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003954template <int V>
3955class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003956 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003957 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003958 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003959 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003960 }
3961
3962 int literal_index() const { return literal_index_; }
3963 int depth() const { return depth_; }
3964
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003965 private:
3966 int literal_index_;
3967 int depth_;
3968};
3969
3970
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003971class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003972 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003973 HArrayLiteral(HValue* context,
3974 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003975 int length,
3976 int literal_index,
3977 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003978 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003979 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003980 constant_elements_(constant_elements) {
3981 SetOperandAt(0, context);
3982 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003983
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003984 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003985 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3986 int length() const { return length_; }
3987
3988 bool IsCopyOnWrite() const;
3989
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003990 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003991 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003992 }
3993
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003994 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003995
3996 private:
3997 int length_;
3998 Handle<FixedArray> constant_elements_;
3999};
4000
4001
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004002class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004003 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004004 HObjectLiteral(HValue* context,
4005 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004006 bool fast_elements,
4007 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004008 int depth,
4009 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004010 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004011 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004012 fast_elements_(fast_elements),
4013 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004014 SetOperandAt(0, context);
4015 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004016
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004017 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004018 Handle<FixedArray> constant_properties() const {
4019 return constant_properties_;
4020 }
4021 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004022 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004023
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004024 virtual Representation RequiredInputRepresentation(int index) const {
4025 return Representation::Tagged();
4026 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004027
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004028 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004029
4030 private:
4031 Handle<FixedArray> constant_properties_;
4032 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004033 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004034};
4035
4036
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004037class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004038 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004039 HRegExpLiteral(HValue* context,
4040 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004041 Handle<String> flags,
4042 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004043 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004044 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004045 flags_(flags) {
4046 SetOperandAt(0, context);
4047 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004048
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004049 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004050 Handle<String> pattern() { return pattern_; }
4051 Handle<String> flags() { return flags_; }
4052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004053 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004054 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004055 }
4056
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004057 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004058
4059 private:
4060 Handle<String> pattern_;
4061 Handle<String> flags_;
4062};
4063
4064
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004065class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004066 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004067 HFunctionLiteral(HValue* context,
4068 Handle<SharedFunctionInfo> shared,
4069 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004070 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004071 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004072 set_representation(Representation::Tagged());
4073 }
4074
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004075 HValue* context() { return OperandAt(0); }
4076
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004077 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004078 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004079 }
4080
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004081 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004082
4083 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4084 bool pretenure() const { return pretenure_; }
4085
4086 private:
4087 Handle<SharedFunctionInfo> shared_info_;
4088 bool pretenure_;
4089};
4090
4091
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004092class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004093 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004094 explicit HTypeof(HValue* context, HValue* value) {
4095 SetOperandAt(0, context);
4096 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004097 set_representation(Representation::Tagged());
4098 }
4099
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004100 HValue* context() { return OperandAt(0); }
4101 HValue* value() { return OperandAt(1); }
4102
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004103 virtual Representation RequiredInputRepresentation(int index) const {
4104 return Representation::Tagged();
4105 }
4106
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004107 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004108};
4109
4110
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004111class HToFastProperties: public HUnaryOperation {
4112 public:
4113 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4114 // This instruction is not marked as having side effects, but
4115 // changes the map of the input operand. Use it only when creating
4116 // object literals.
4117 ASSERT(value->IsObjectLiteral());
4118 set_representation(Representation::Tagged());
4119 }
4120
4121 virtual Representation RequiredInputRepresentation(int index) const {
4122 return Representation::Tagged();
4123 }
4124
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004125 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004126};
4127
4128
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004129class HValueOf: public HUnaryOperation {
4130 public:
4131 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4132 set_representation(Representation::Tagged());
4133 }
4134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004135 virtual Representation RequiredInputRepresentation(int index) const {
4136 return Representation::Tagged();
4137 }
4138
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004139 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004140};
4141
4142
4143class HDeleteProperty: public HBinaryOperation {
4144 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004145 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4146 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004147 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004148 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004149 }
4150
4151 virtual Representation RequiredInputRepresentation(int index) const {
4152 return Representation::Tagged();
4153 }
4154
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004155 virtual HType CalculateInferredType();
4156
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004157 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004159 HValue* object() { return left(); }
4160 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004161};
4162
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004163
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004164class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004165 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004166 HIn(HValue* context, HValue* key, HValue* object) {
4167 SetOperandAt(0, context);
4168 SetOperandAt(1, key);
4169 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004170 set_representation(Representation::Tagged());
4171 SetAllSideEffects();
4172 }
4173
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004174 HValue* context() { return OperandAt(0); }
4175 HValue* key() { return OperandAt(1); }
4176 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004177
4178 virtual Representation RequiredInputRepresentation(int index) const {
4179 return Representation::Tagged();
4180 }
4181
4182 virtual HType CalculateInferredType() {
4183 return HType::Boolean();
4184 }
4185
4186 virtual void PrintDataTo(StringStream* stream);
4187
4188 DECLARE_CONCRETE_INSTRUCTION(In)
4189};
4190
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004191#undef DECLARE_INSTRUCTION
4192#undef DECLARE_CONCRETE_INSTRUCTION
4193
4194} } // namespace v8::internal
4195
4196#endif // V8_HYDROGEN_INSTRUCTIONS_H_