blob: a0cab6aed1655deb8a6d5a1ba3a198dc39a6afae [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"
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000038#include "utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000039#include "zone.h"
40
41namespace v8 {
42namespace internal {
43
44// Forward declarations.
45class HBasicBlock;
46class HEnvironment;
47class HInstruction;
48class HLoopInformation;
49class HValue;
50class LInstruction;
51class LChunkBuilder;
52
53
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000054#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(ControlInstruction) \
57 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058
59
60#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000061 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000062 V(AccessArgumentsAt) \
63 V(Add) \
64 V(ApplyArguments) \
65 V(ArgumentsElements) \
66 V(ArgumentsLength) \
67 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000068 V(ArrayLiteral) \
69 V(BitAnd) \
70 V(BitNot) \
71 V(BitOr) \
72 V(BitXor) \
73 V(BlockEntry) \
74 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000075 V(CallConstantFunction) \
76 V(CallFunction) \
77 V(CallGlobal) \
78 V(CallKeyed) \
79 V(CallKnownGlobal) \
80 V(CallNamed) \
81 V(CallNew) \
82 V(CallRuntime) \
83 V(CallStub) \
84 V(Change) \
85 V(CheckFunction) \
86 V(CheckInstanceType) \
87 V(CheckMap) \
88 V(CheckNonSmi) \
89 V(CheckPrototypeMaps) \
90 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000091 V(ClampToUint8) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000092 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000093 V(Compare) \
lrn@chromium.orgac2828d2011-06-23 06:29:21 +000094 V(CompareObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000095 V(CompareMap) \
whesse@chromium.org7b260152011-06-20 15:33:18 +000096 V(CompareConstantEq) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000097 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000098 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000099 V(DeleteProperty) \
100 V(Deoptimize) \
101 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000102 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000103 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000104 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000105 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000106 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000107 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000108 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000109 V(GlobalObject) \
110 V(GlobalReceiver) \
111 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000112 V(HasCachedArrayIndex) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000113 V(HasInstanceType) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000114 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000116 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000117 V(InvokeFunction) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000118 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000119 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000120 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000121 V(IsSmi) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000122 V(IsUndetectable) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000123 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000125 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000127 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000128 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000129 V(LoadGlobalCell) \
130 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131 V(LoadKeyedFastElement) \
132 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000133 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000135 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(LoadNamedGeneric) \
137 V(Mod) \
138 V(Mul) \
139 V(ObjectLiteral) \
140 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000141 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000142 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000143 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000144 V(PushArgument) \
145 V(RegExpLiteral) \
146 V(Return) \
147 V(Sar) \
148 V(Shl) \
149 V(Shr) \
150 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000151 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000152 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000153 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000154 V(StoreGlobalCell) \
155 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(StoreKeyedFastElement) \
157 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000158 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159 V(StoreNamedField) \
160 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000161 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000162 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000163 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000164 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000166 V(Test) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000167 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000168 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000169 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000170 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000171 V(Typeof) \
172 V(TypeofIs) \
173 V(UnaryMathOperation) \
174 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000175 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(ValueOf)
177
178#define GVN_FLAG_LIST(V) \
179 V(Calls) \
180 V(InobjectFields) \
181 V(BackingStoreFields) \
182 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000183 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000184 V(GlobalVars) \
185 V(Maps) \
186 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000187 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 V(OsrEntries)
189
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000190#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191 virtual bool Is##type() const { return true; } \
192 static H##type* cast(HValue* value) { \
193 ASSERT(value->Is##type()); \
194 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000195 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000196
197
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000198#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000199 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000200 static H##type* cast(HValue* value) { \
201 ASSERT(value->Is##type()); \
202 return reinterpret_cast<H##type*>(value); \
203 } \
204 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205
206
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207class Range: public ZoneObject {
208 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000209 Range()
210 : lower_(kMinInt),
211 upper_(kMaxInt),
212 next_(NULL),
213 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214
215 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000216 : lower_(lower),
217 upper_(upper),
218 next_(NULL),
219 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000220
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221 int32_t upper() const { return upper_; }
222 int32_t lower() const { return lower_; }
223 Range* next() const { return next_; }
224 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
225 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227 int32_t Mask() const;
228 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
229 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
230 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
231 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000232 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
233 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
234 bool IsInSmiRange() const {
235 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000236 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000237 void KeepOrder();
238 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000239
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000240 void StackUpon(Range* other) {
241 Intersect(other);
242 next_ = other;
243 }
244
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000245 void Intersect(Range* other);
246 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000247
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000248 void AddConstant(int32_t value);
249 void Sar(int32_t value);
250 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000251 bool AddAndCheckOverflow(Range* other);
252 bool SubAndCheckOverflow(Range* other);
253 bool MulAndCheckOverflow(Range* other);
254
255 private:
256 int32_t lower_;
257 int32_t upper_;
258 Range* next_;
259 bool can_be_minus_zero_;
260};
261
262
263class Representation {
264 public:
265 enum Kind {
266 kNone,
267 kTagged,
268 kDouble,
269 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000270 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000271 kNumRepresentations
272 };
273
274 Representation() : kind_(kNone) { }
275
276 static Representation None() { return Representation(kNone); }
277 static Representation Tagged() { return Representation(kTagged); }
278 static Representation Integer32() { return Representation(kInteger32); }
279 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000280 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000282 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000283 return kind_ == other.kind_;
284 }
285
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000286 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000287 bool IsNone() const { return kind_ == kNone; }
288 bool IsTagged() const { return kind_ == kTagged; }
289 bool IsInteger32() const { return kind_ == kInteger32; }
290 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000291 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000292 bool IsSpecialization() const {
293 return kind_ == kInteger32 || kind_ == kDouble;
294 }
295 const char* Mnemonic() const;
296
297 private:
298 explicit Representation(Kind k) : kind_(k) { }
299
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000300 // Make sure kind fits in int8.
301 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
302
303 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000304};
305
306
307class HType {
308 public:
309 HType() : type_(kUninitialized) { }
310
311 static HType Tagged() { return HType(kTagged); }
312 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
313 static HType TaggedNumber() { return HType(kTaggedNumber); }
314 static HType Smi() { return HType(kSmi); }
315 static HType HeapNumber() { return HType(kHeapNumber); }
316 static HType String() { return HType(kString); }
317 static HType Boolean() { return HType(kBoolean); }
318 static HType NonPrimitive() { return HType(kNonPrimitive); }
319 static HType JSArray() { return HType(kJSArray); }
320 static HType JSObject() { return HType(kJSObject); }
321 static HType Uninitialized() { return HType(kUninitialized); }
322
323 // Return the weakest (least precise) common type.
324 HType Combine(HType other) {
325 return HType(static_cast<Type>(type_ & other.type_));
326 }
327
328 bool Equals(const HType& other) {
329 return type_ == other.type_;
330 }
331
332 bool IsSubtypeOf(const HType& other) {
333 return Combine(other).Equals(other);
334 }
335
336 bool IsTagged() {
337 ASSERT(type_ != kUninitialized);
338 return ((type_ & kTagged) == kTagged);
339 }
340
341 bool IsTaggedPrimitive() {
342 ASSERT(type_ != kUninitialized);
343 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
344 }
345
346 bool IsTaggedNumber() {
347 ASSERT(type_ != kUninitialized);
348 return ((type_ & kTaggedNumber) == kTaggedNumber);
349 }
350
351 bool IsSmi() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kSmi) == kSmi);
354 }
355
356 bool IsHeapNumber() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kHeapNumber) == kHeapNumber);
359 }
360
361 bool IsString() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kString) == kString);
364 }
365
366 bool IsBoolean() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kBoolean) == kBoolean);
369 }
370
371 bool IsNonPrimitive() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kNonPrimitive) == kNonPrimitive);
374 }
375
376 bool IsJSArray() {
377 ASSERT(type_ != kUninitialized);
378 return ((type_ & kJSArray) == kJSArray);
379 }
380
381 bool IsJSObject() {
382 ASSERT(type_ != kUninitialized);
383 return ((type_ & kJSObject) == kJSObject);
384 }
385
386 bool IsUninitialized() {
387 return type_ == kUninitialized;
388 }
389
390 static HType TypeFromValue(Handle<Object> value);
391
392 const char* ToString();
393 const char* ToShortString();
394
395 private:
396 enum Type {
397 kTagged = 0x1, // 0000 0000 0000 0001
398 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
399 kTaggedNumber = 0xd, // 0000 0000 0000 1101
400 kSmi = 0x1d, // 0000 0000 0001 1101
401 kHeapNumber = 0x2d, // 0000 0000 0010 1101
402 kString = 0x45, // 0000 0000 0100 0101
403 kBoolean = 0x85, // 0000 0000 1000 0101
404 kNonPrimitive = 0x101, // 0000 0001 0000 0001
405 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000406 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000407 kUninitialized = 0x1fff // 0001 1111 1111 1111
408 };
409
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000410 // Make sure type fits in int16.
411 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
412
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000413 explicit HType(Type t) : type_(t) { }
414
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000415 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000416};
417
418
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000419class HUseListNode: public ZoneObject {
420 public:
421 HUseListNode(HValue* value, int index, HUseListNode* tail)
422 : tail_(tail), value_(value), index_(index) {
423 }
424
425 HUseListNode* tail() const { return tail_; }
426 HValue* value() const { return value_; }
427 int index() const { return index_; }
428
429 void set_tail(HUseListNode* list) { tail_ = list; }
430
431#ifdef DEBUG
432 void Zap() {
433 tail_ = reinterpret_cast<HUseListNode*>(1);
434 value_ = NULL;
435 index_ = -1;
436 }
437#endif
438
439 private:
440 HUseListNode* tail_;
441 HValue* value_;
442 int index_;
443};
444
445
446// We reuse use list nodes behind the scenes as uses are added and deleted.
447// This class is the safe way to iterate uses while deleting them.
448class HUseIterator BASE_EMBEDDED {
449 public:
450 bool Done() { return current_ == NULL; }
451 void Advance();
452
453 HValue* value() {
454 ASSERT(!Done());
455 return value_;
456 }
457
458 int index() {
459 ASSERT(!Done());
460 return index_;
461 }
462
463 private:
464 explicit HUseIterator(HUseListNode* head);
465
466 HUseListNode* current_;
467 HUseListNode* next_;
468 HValue* value_;
469 int index_;
470
471 friend class HValue;
472};
473
474
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000475class HValue: public ZoneObject {
476 public:
477 static const int kNoNumber = -1;
478
479 // There must be one corresponding kDepends flag for every kChanges flag and
480 // the order of the kChanges flags must be exactly the same as of the kDepends
481 // flags.
482 enum Flag {
483 // Declare global value numbering flags.
484 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
485 GVN_FLAG_LIST(DECLARE_DO)
486 #undef DECLARE_DO
487 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000488 // Participate in Global Value Numbering, i.e. elimination of
489 // unnecessary recomputations. If an instruction sets this flag, it must
490 // implement DataEquals(), which will be used to determine if other
491 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000492 kUseGVN,
493 kCanOverflow,
494 kBailoutOnMinusZero,
495 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000496 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000497 kIsArguments,
498 kTruncatingToInt32,
499 kLastFlag = kTruncatingToInt32
500 };
501
502 STATIC_ASSERT(kLastFlag < kBitsPerInt);
503
504 static const int kChangesToDependsFlagsLeftShift = 1;
505
506 static int ChangesFlagsMask() {
507 int result = 0;
508 // Create changes mask.
509#define DECLARE_DO(type) result |= (1 << kChanges##type);
510 GVN_FLAG_LIST(DECLARE_DO)
511#undef DECLARE_DO
512 return result;
513 }
514
515 static int DependsFlagsMask() {
516 return ConvertChangesToDependsFlags(ChangesFlagsMask());
517 }
518
519 static int ConvertChangesToDependsFlags(int flags) {
520 return flags << kChangesToDependsFlagsLeftShift;
521 }
522
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000523 static HValue* cast(HValue* value) { return value; }
524
525 enum Opcode {
526 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000527 #define DECLARE_OPCODE(type) k##type,
528 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
529 kPhi
530 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000531 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000532 virtual Opcode opcode() const = 0;
533
534 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
535 #define DECLARE_PREDICATE(type) \
536 bool Is##type() const { return opcode() == k##type; }
537 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
538 #undef DECLARE_PREDICATE
539 bool IsPhi() const { return opcode() == kPhi; }
540
541 // Declare virtual predicates for abstract HInstruction or HValue
542 #define DECLARE_PREDICATE(type) \
543 virtual bool Is##type() const { return false; }
544 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
545 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000546
547 HValue() : block_(NULL),
548 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000549 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000550 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551 range_(NULL),
552 flags_(0) {}
553 virtual ~HValue() {}
554
555 HBasicBlock* block() const { return block_; }
556 void SetBlock(HBasicBlock* block);
557
558 int id() const { return id_; }
559 void set_id(int id) { id_ = id; }
560
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000561 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000562
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000563 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564 Representation representation() const { return representation_; }
565 void ChangeRepresentation(Representation r) {
566 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000567 ASSERT(!r.IsNone());
568 ASSERT(CheckFlag(kFlexibleRepresentation));
569 RepresentationChanged(r);
570 representation_ = r;
571 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000572 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000573
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000574 virtual bool IsConvertibleToInteger() const { return true; }
575
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000576 HType type() const { return type_; }
577 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000578 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000579 type_ = type;
580 }
581
582 // An operation needs to override this function iff:
583 // 1) it can produce an int32 output.
584 // 2) the true value of its output can potentially be minus zero.
585 // The implementation must set a flag so that it bails out in the case where
586 // it would otherwise output what should be a minus zero as an int32 zero.
587 // If the operation also exists in a form that takes int32 and outputs int32
588 // then the operation should return its input value so that we can propagate
589 // back. There are two operations that need to propagate back to more than
590 // one input. They are phi and binary add. They always return NULL and
591 // expect the caller to take care of things.
592 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
593 visited->Add(id());
594 return NULL;
595 }
596
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000597 bool IsDefinedAfter(HBasicBlock* other) const;
598
599 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000600 virtual int OperandCount() = 0;
601 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000602 void SetOperandAt(int index, HValue* value);
603
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000604 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000605 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000606 bool HasNoUses() const { return use_list_ == NULL; }
607 bool HasMultipleUses() const {
608 return use_list_ != NULL && use_list_->tail() != NULL;
609 }
610 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000611 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612
613 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000614 void SetFlag(Flag f) { flags_ |= (1 << f); }
615 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
616 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
617
618 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
619 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
620 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000621
622 Range* range() const { return range_; }
623 bool HasRange() const { return range_ != NULL; }
624 void AddNewRange(Range* r);
625 void RemoveLastAddedRange();
626 void ComputeInitialRange();
627
628 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000629 virtual Representation RequiredInputRepresentation(int index) const = 0;
630
631 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000632 return representation();
633 }
634
635 // This gives the instruction an opportunity to replace itself with an
636 // instruction that does the same in some better way. To replace an
637 // instruction with a new one, first add the new instruction to the graph,
638 // then return it. Return NULL to have the instruction deleted.
639 virtual HValue* Canonicalize() { return this; }
640
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000641 bool Equals(HValue* other);
642 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000643
644 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000645 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000646 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000647 void PrintTypeTo(StringStream* stream);
648 void PrintRangeTo(StringStream* stream);
649 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000650
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000651 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652
653 // Updated the inferred type of this instruction and returns true if
654 // it has changed.
655 bool UpdateInferredType();
656
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000657 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000658
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000659#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000660 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000661#endif
662
663 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000664 // This function must be overridden for instructions with flag kUseGVN, to
665 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000666 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000667 UNREACHABLE();
668 return false;
669 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000670 virtual void RepresentationChanged(Representation to) { }
671 virtual Range* InferRange();
672 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000673 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000674 void clear_block() {
675 ASSERT(block_ != NULL);
676 block_ = NULL;
677 }
678
679 void set_representation(Representation r) {
680 // Representation is set-once.
681 ASSERT(representation_.IsNone() && !r.IsNone());
682 representation_ = r;
683 }
684
685 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000686 // A flag mask to mark an instruction as having arbitrary side effects.
687 static int AllSideEffects() {
688 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
689 }
690
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000691 // Remove the matching use from the use list if present. Returns the
692 // removed list node or NULL.
693 HUseListNode* RemoveUse(HValue* value, int index);
694
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000695 void RegisterUse(int index, HValue* new_value);
696
697 HBasicBlock* block_;
698
699 // The id of this instruction in the hydrogen graph, assigned when first
700 // added to the graph. Reflects creation order.
701 int id_;
702
703 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000704 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000705 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000706 Range* range_;
707 int flags_;
708
709 DISALLOW_COPY_AND_ASSIGN(HValue);
710};
711
712
713class HInstruction: public HValue {
714 public:
715 HInstruction* next() const { return next_; }
716 HInstruction* previous() const { return previous_; }
717
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000718 virtual void PrintTo(StringStream* stream);
719 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000720
721 bool IsLinked() const { return block() != NULL; }
722 void Unlink();
723 void InsertBefore(HInstruction* next);
724 void InsertAfter(HInstruction* previous);
725
726 int position() const { return position_; }
727 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
728 void set_position(int position) { position_ = position; }
729
730 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
731
732#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000733 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000734#endif
735
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000736 virtual bool IsCall() { return false; }
737
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000738 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000739
740 protected:
741 HInstruction()
742 : next_(NULL),
743 previous_(NULL),
744 position_(RelocInfo::kNoPosition) {
745 SetFlag(kDependsOnOsrEntries);
746 }
747
748 virtual void DeleteFromGraph() { Unlink(); }
749
750 private:
751 void InitializeAsFirst(HBasicBlock* block) {
752 ASSERT(!IsLinked());
753 SetBlock(block);
754 }
755
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000756 void PrintMnemonicTo(StringStream* stream);
757
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000758 HInstruction* next_;
759 HInstruction* previous_;
760 int position_;
761
762 friend class HBasicBlock;
763};
764
765
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000766template<int V>
767class HTemplateInstruction : public HInstruction {
768 public:
769 int OperandCount() { return V; }
770 HValue* OperandAt(int i) { return inputs_[i]; }
771
772 protected:
773 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
774
775 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000776 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000777};
778
779
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000780class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000781 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000782 virtual HBasicBlock* SuccessorAt(int i) = 0;
783 virtual int SuccessorCount() = 0;
784
785 virtual void PrintDataTo(StringStream* stream);
786
787 HBasicBlock* FirstSuccessor() {
788 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
789 }
790 HBasicBlock* SecondSuccessor() {
791 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
792 }
793
794 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
795};
796
797
798class HSuccessorIterator BASE_EMBEDDED {
799 public:
800 explicit HSuccessorIterator(HControlInstruction* instr)
801 : instr_(instr), current_(0) { }
802
803 bool Done() { return current_ >= instr_->SuccessorCount(); }
804 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
805 void Advance() { current_++; }
806
807 private:
808 HControlInstruction* instr_;
809 int current_;
810};
811
812
813template<int S, int V>
814class HTemplateControlInstruction: public HControlInstruction {
815 public:
816 int SuccessorCount() { return S; }
817 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000819 int OperandCount() { return V; }
820 HValue* OperandAt(int i) { return inputs_[i]; }
821
822 protected:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000823 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000824 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
825
826 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000827 EmbeddedContainer<HBasicBlock*, S> successors_;
828 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000829};
830
831
832class HBlockEntry: public HTemplateInstruction<0> {
833 public:
834 virtual Representation RequiredInputRepresentation(int index) const {
835 return Representation::None();
836 }
837
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000838 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000839};
840
841
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000842// We insert soft-deoptimize when we hit code with unknown typefeedback,
843// so that we get a chance of re-optimizing with useful typefeedback.
844// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
845class HSoftDeoptimize: public HTemplateInstruction<0> {
846 public:
847 virtual Representation RequiredInputRepresentation(int index) const {
848 return Representation::None();
849 }
850
851 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
852};
853
854
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000855class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000856 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000857 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000858
859 virtual Representation RequiredInputRepresentation(int index) const {
860 return Representation::None();
861 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000862
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000863 virtual int OperandCount() { return values_.length(); }
864 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000865 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000866
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000867 virtual int SuccessorCount() { return 0; }
868 virtual HBasicBlock* SuccessorAt(int i) {
869 UNREACHABLE();
870 return NULL;
871 }
872
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000873 void AddEnvironmentValue(HValue* value) {
874 values_.Add(NULL);
875 SetOperandAt(values_.length() - 1, value);
876 }
877
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000878 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000879
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000880 enum UseEnvironment {
881 kNoUses,
882 kUseAll
883 };
884
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000885 protected:
886 virtual void InternalSetOperandAt(int index, HValue* value) {
887 values_[index] = value;
888 }
889
890 private:
891 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000892};
893
894
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000895class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000897 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000898 SetSuccessorAt(0, target);
899 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000901 virtual Representation RequiredInputRepresentation(int index) const {
902 return Representation::None();
903 }
904
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000905 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906};
907
908
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000909class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000910 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000911 HUnaryControlInstruction(HValue* value,
912 HBasicBlock* true_target,
913 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000914 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000915 SetSuccessorAt(0, true_target);
916 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917 }
918
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000919 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000920
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000921 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000922};
923
924
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000925class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000927 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
928 : HUnaryControlInstruction(value, true_target, false_target) {
929 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930 }
931
932 virtual Representation RequiredInputRepresentation(int index) const {
933 return Representation::None();
934 }
935
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000936 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000937};
938
939
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000940class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000942 HCompareMap(HValue* value,
943 Handle<Map> map,
944 HBasicBlock* true_target,
945 HBasicBlock* false_target)
946 : HUnaryControlInstruction(value, true_target, false_target),
947 map_(map) {
948 ASSERT(true_target != NULL);
949 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950 ASSERT(!map.is_null());
951 }
952
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000953 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000954
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000955 Handle<Map> map() const { return map_; }
956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000957 virtual Representation RequiredInputRepresentation(int index) const {
958 return Representation::Tagged();
959 }
960
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000961 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000962
963 private:
964 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965};
966
967
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000968class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000969 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000970 explicit HReturn(HValue* value) {
971 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000972 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000973
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000974 virtual Representation RequiredInputRepresentation(int index) const {
975 return Representation::Tagged();
976 }
977
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000978 virtual void PrintDataTo(StringStream* stream);
979
980 HValue* value() { return OperandAt(0); }
981
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000982 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983};
984
985
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000986class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000988 virtual Representation RequiredInputRepresentation(int index) const {
989 return Representation::None();
990 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000992 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000993};
994
995
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000996class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997 public:
998 explicit HUnaryOperation(HValue* value) {
999 SetOperandAt(0, value);
1000 }
1001
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001002 static HUnaryOperation* cast(HValue* value) {
1003 return reinterpret_cast<HUnaryOperation*>(value);
1004 }
1005
1006 virtual bool CanTruncateToInt32() const {
1007 return CheckFlag(kTruncatingToInt32);
1008 }
1009
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001010 HValue* value() { return OperandAt(0); }
1011 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001012};
1013
1014
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001015class HThrow: public HUnaryOperation {
1016 public:
1017 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1018 SetAllSideEffects();
1019 }
1020
1021 virtual Representation RequiredInputRepresentation(int index) const {
1022 return Representation::Tagged();
1023 }
1024
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001025 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001026};
1027
1028
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001029class HUseConst: public HUnaryOperation {
1030 public:
1031 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1032
1033 virtual Representation RequiredInputRepresentation(int index) const {
1034 return Representation::None();
1035 }
1036
1037 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1038};
1039
1040
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001041class HForceRepresentation: public HTemplateInstruction<1> {
1042 public:
1043 HForceRepresentation(HValue* value, Representation required_representation) {
1044 SetOperandAt(0, value);
1045 set_representation(required_representation);
1046 }
1047
1048 HValue* value() { return OperandAt(0); }
1049
1050 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1051
1052 virtual Representation RequiredInputRepresentation(int index) const {
1053 return representation(); // Same as the output representation.
1054 }
1055
1056 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1057};
1058
1059
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001060class HChange: public HUnaryOperation {
1061 public:
1062 HChange(HValue* value,
1063 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001064 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001065 bool is_truncating,
1066 bool deoptimize_on_undefined)
1067 : HUnaryOperation(value),
1068 from_(from),
1069 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001070 ASSERT(!from.IsNone() && !to.IsNone());
1071 ASSERT(!from.Equals(to));
1072 set_representation(to);
1073 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001074 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001075 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1076 value->range()->IsInSmiRange()) {
1077 set_type(HType::Smi());
1078 }
1079 }
1080
1081 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1082
1083 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001084 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001085 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001086 virtual Representation RequiredInputRepresentation(int index) const {
1087 return from_;
1088 }
1089
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001090 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001091
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001092 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001093
1094 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001095 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001096 if (!other->IsChange()) return false;
1097 HChange* change = HChange::cast(other);
1098 return value() == change->value()
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001099 && to().Equals(change->to())
1100 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001101 }
1102
1103 private:
1104 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001105 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001106};
1107
1108
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001109class HClampToUint8: public HUnaryOperation {
1110 public:
1111 explicit HClampToUint8(HValue* value)
1112 : HUnaryOperation(value),
1113 input_rep_(Representation::None()) {
1114 SetFlag(kFlexibleRepresentation);
1115 set_representation(Representation::Tagged());
1116 SetFlag(kUseGVN);
1117 }
1118
1119 virtual Representation RequiredInputRepresentation(int index) const {
1120 return input_rep_;
1121 }
1122
1123 virtual Representation InferredRepresentation() {
1124 // TODO(danno): Inference on input types should happen separately from
1125 // return representation.
1126 Representation new_rep = value()->representation();
1127 if (input_rep_.IsNone()) {
1128 if (!new_rep.IsNone()) {
1129 input_rep_ = new_rep;
1130 return Representation::Integer32();
1131 } else {
1132 return Representation::None();
1133 }
1134 } else {
1135 return Representation::Integer32();
1136 }
1137 }
1138
1139 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1140
1141 protected:
1142 virtual bool DataEquals(HValue* other) { return true; }
1143
1144 private:
1145 Representation input_rep_;
1146};
1147
1148
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001149class HToInt32: public HUnaryOperation {
1150 public:
1151 explicit HToInt32(HValue* value)
1152 : HUnaryOperation(value) {
1153 set_representation(Representation::Integer32());
1154 SetFlag(kUseGVN);
1155 }
1156
1157 virtual Representation RequiredInputRepresentation(int index) const {
1158 return Representation::None();
1159 }
1160
1161 virtual bool CanTruncateToInt32() const {
1162 return true;
1163 }
1164
1165 virtual HValue* Canonicalize() {
1166 if (value()->representation().IsInteger32()) {
1167 return value();
1168 } else {
1169 return this;
1170 }
1171 }
1172
1173 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1174
1175 protected:
1176 virtual bool DataEquals(HValue* other) { return true; }
1177};
1178
1179
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001180class HSimulate: public HInstruction {
1181 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001182 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001183 : ast_id_(ast_id),
1184 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001185 values_(2),
1186 assigned_indexes_(2) {}
1187 virtual ~HSimulate() {}
1188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001189 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190
1191 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1192 int ast_id() const { return ast_id_; }
1193 void set_ast_id(int id) {
1194 ASSERT(!HasAstId());
1195 ast_id_ = id;
1196 }
1197
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001198 int pop_count() const { return pop_count_; }
1199 const ZoneList<HValue*>* values() const { return &values_; }
1200 int GetAssignedIndexAt(int index) const {
1201 ASSERT(HasAssignedIndexAt(index));
1202 return assigned_indexes_[index];
1203 }
1204 bool HasAssignedIndexAt(int index) const {
1205 return assigned_indexes_[index] != kNoIndex;
1206 }
1207 void AddAssignedValue(int index, HValue* value) {
1208 AddValue(index, value);
1209 }
1210 void AddPushedValue(HValue* value) {
1211 AddValue(kNoIndex, value);
1212 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001213 virtual int OperandCount() { return values_.length(); }
1214 virtual HValue* OperandAt(int index) { return values_[index]; }
1215
1216 virtual Representation RequiredInputRepresentation(int index) const {
1217 return Representation::None();
1218 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001219
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001220 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001221
1222#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001223 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001224#endif
1225
1226 protected:
1227 virtual void InternalSetOperandAt(int index, HValue* value) {
1228 values_[index] = value;
1229 }
1230
1231 private:
1232 static const int kNoIndex = -1;
1233 void AddValue(int index, HValue* value) {
1234 assigned_indexes_.Add(index);
1235 // Resize the list of pushed values.
1236 values_.Add(NULL);
1237 // Set the operand through the base method in HValue to make sure that the
1238 // use lists are correctly updated.
1239 SetOperandAt(values_.length() - 1, value);
1240 }
1241 int ast_id_;
1242 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001243 ZoneList<HValue*> values_;
1244 ZoneList<int> assigned_indexes_;
1245};
1246
1247
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001248class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001249 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001250 enum Type {
1251 kFunctionEntry,
1252 kBackwardsBranch
1253 };
1254
1255 explicit HStackCheck(Type type) : type_(type) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001257 virtual Representation RequiredInputRepresentation(int index) const {
1258 return Representation::None();
1259 }
1260
ager@chromium.org04921a82011-06-27 13:21:41 +00001261 void Eliminate() {
1262 // The stack check eliminator might try to eliminate the same stack
1263 // check instruction multiple times.
1264 if (IsLinked()) {
1265 DeleteFromGraph();
1266 }
1267 }
1268
1269 bool is_function_entry() { return type_ == kFunctionEntry; }
1270 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1271
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001272 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001273
1274 private:
1275 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001276};
1277
1278
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001279class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001280 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001281 HEnterInlined(Handle<JSFunction> closure,
1282 FunctionLiteral* function,
1283 CallKind call_kind)
1284 : closure_(closure),
1285 function_(function),
1286 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287 }
1288
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001289 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001290
1291 Handle<JSFunction> closure() const { return closure_; }
1292 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001293 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001295 virtual Representation RequiredInputRepresentation(int index) const {
1296 return Representation::None();
1297 }
1298
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001299 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001300
1301 private:
1302 Handle<JSFunction> closure_;
1303 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001304 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305};
1306
1307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001308class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001309 public:
1310 HLeaveInlined() {}
1311
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001312 virtual Representation RequiredInputRepresentation(int index) const {
1313 return Representation::None();
1314 }
1315
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001316 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001317};
1318
1319
1320class HPushArgument: public HUnaryOperation {
1321 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001322 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1323 set_representation(Representation::Tagged());
1324 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325
1326 virtual Representation RequiredInputRepresentation(int index) const {
1327 return Representation::Tagged();
1328 }
1329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001330 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001331
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001332 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001333};
1334
1335
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001336class HThisFunction: public HTemplateInstruction<0> {
1337 public:
1338 HThisFunction() {
1339 set_representation(Representation::Tagged());
1340 SetFlag(kUseGVN);
1341 }
1342
1343 virtual Representation RequiredInputRepresentation(int index) const {
1344 return Representation::None();
1345 }
1346
1347 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1348
1349 protected:
1350 virtual bool DataEquals(HValue* other) { return true; }
1351};
1352
1353
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001354class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001356 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001357 set_representation(Representation::Tagged());
1358 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001359 }
1360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001361 virtual Representation RequiredInputRepresentation(int index) const {
1362 return Representation::None();
1363 }
1364
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001365 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001366
1367 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001368 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001369};
1370
1371
1372class HOuterContext: public HUnaryOperation {
1373 public:
1374 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1375 set_representation(Representation::Tagged());
1376 SetFlag(kUseGVN);
1377 }
1378
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001379 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001381 virtual Representation RequiredInputRepresentation(int index) const {
1382 return Representation::Tagged();
1383 }
1384
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001385 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001386 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001387};
1388
1389
1390class HGlobalObject: public HUnaryOperation {
1391 public:
1392 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1393 set_representation(Representation::Tagged());
1394 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001395 }
1396
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001397 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001398
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001399 virtual Representation RequiredInputRepresentation(int index) const {
1400 return Representation::Tagged();
1401 }
1402
ager@chromium.org378b34e2011-01-28 08:04:38 +00001403 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405};
1406
1407
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001408class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001410 explicit HGlobalReceiver(HValue* global_object)
1411 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412 set_representation(Representation::Tagged());
1413 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001414 }
1415
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001416 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001418 virtual Representation RequiredInputRepresentation(int index) const {
1419 return Representation::Tagged();
1420 }
1421
ager@chromium.org378b34e2011-01-28 08:04:38 +00001422 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001423 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424};
1425
1426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001427template <int V>
1428class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001429 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001430 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001431 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1432 this->set_representation(Representation::Tagged());
1433 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001434 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001436 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001437
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001438 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001439
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001440 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001442 private:
1443 int argument_count_;
1444};
1445
1446
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001447class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 public:
1449 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001450 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001451 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001452 }
1453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001454 virtual Representation RequiredInputRepresentation(int index) const {
1455 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001456 }
1457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458 virtual void PrintDataTo(StringStream* stream);
1459
1460 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001461};
1462
1463
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001464class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465 public:
1466 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001467 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001468 SetOperandAt(0, first);
1469 SetOperandAt(1, second);
1470 }
1471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001472 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001474 virtual Representation RequiredInputRepresentation(int index) const {
1475 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001476 }
1477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001478 HValue* first() { return OperandAt(0); }
1479 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001480};
1481
1482
danno@chromium.org160a7b02011-04-18 15:51:38 +00001483class HInvokeFunction: public HBinaryCall {
1484 public:
1485 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1486 : HBinaryCall(context, function, argument_count) {
1487 }
1488
1489 virtual Representation RequiredInputRepresentation(int index) const {
1490 return Representation::Tagged();
1491 }
1492
1493 HValue* context() { return first(); }
1494 HValue* function() { return second(); }
1495
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001496 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001497};
1498
1499
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001500class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001501 public:
1502 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001503 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001504
1505 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001506
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001508 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001509 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001510 }
1511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001512 virtual void PrintDataTo(StringStream* stream);
1513
1514 virtual Representation RequiredInputRepresentation(int index) const {
1515 return Representation::None();
1516 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001517
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001518 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519
1520 private:
1521 Handle<JSFunction> function_;
1522};
1523
1524
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001525class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001527 HCallKeyed(HValue* context, HValue* key, int argument_count)
1528 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529 }
1530
1531 virtual Representation RequiredInputRepresentation(int index) const {
1532 return Representation::Tagged();
1533 }
1534
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001535 HValue* context() { return first(); }
1536 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001538 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001539};
1540
1541
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001542class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001543 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001544 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1545 : HUnaryCall(context, argument_count), name_(name) {
1546 }
1547
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001548 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001549
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001550 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551 Handle<String> name() const { return name_; }
1552
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001553 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001555 virtual Representation RequiredInputRepresentation(int index) const {
1556 return Representation::Tagged();
1557 }
1558
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559 private:
1560 Handle<String> name_;
1561};
1562
1563
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001564class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001565 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001566 HCallFunction(HValue* context, int argument_count)
1567 : HUnaryCall(context, argument_count) {
1568 }
1569
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001570 HValue* context() { return value(); }
1571
1572 virtual Representation RequiredInputRepresentation(int index) const {
1573 return Representation::Tagged();
1574 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001575
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001576 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577};
1578
1579
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001580class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001581 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001582 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1583 : HUnaryCall(context, argument_count), name_(name) {
1584 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001586 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001588 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001589 Handle<String> name() const { return name_; }
1590
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001591 virtual Representation RequiredInputRepresentation(int index) const {
1592 return Representation::Tagged();
1593 }
1594
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001595 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596
1597 private:
1598 Handle<String> name_;
1599};
1600
1601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001604 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001605 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001607 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001608
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001609 Handle<JSFunction> target() const { return target_; }
1610
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001611 virtual Representation RequiredInputRepresentation(int index) const {
1612 return Representation::None();
1613 }
1614
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001615 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001616
1617 private:
1618 Handle<JSFunction> target_;
1619};
1620
1621
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001622class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001623 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001624 HCallNew(HValue* context, HValue* constructor, int argument_count)
1625 : HBinaryCall(context, constructor, argument_count) {
1626 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001627
1628 virtual Representation RequiredInputRepresentation(int index) const {
1629 return Representation::Tagged();
1630 }
1631
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001632 HValue* context() { return first(); }
1633 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001635 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001636};
1637
1638
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001639class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001640 public:
1641 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001642 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001643 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001644 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1645 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001647 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001648 Handle<String> name() const { return name_; }
1649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001650 virtual Representation RequiredInputRepresentation(int index) const {
1651 return Representation::None();
1652 }
1653
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001654 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001655
1656 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001657 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001658 Handle<String> name_;
1659};
1660
1661
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001662class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001664 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001665 // The length of an array is stored as a tagged value in the array
1666 // object. It is guaranteed to be 32 bit integer, but it can be
1667 // represented as either a smi or heap number.
1668 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001669 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001670 SetFlag(kDependsOnArrayLengths);
1671 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001672 }
1673
1674 virtual Representation RequiredInputRepresentation(int index) const {
1675 return Representation::Tagged();
1676 }
1677
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001678 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001679
1680 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001681 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001682};
1683
1684
1685class HFixedArrayLength: public HUnaryOperation {
1686 public:
1687 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1688 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001689 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001690 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001691 }
1692
1693 virtual Representation RequiredInputRepresentation(int index) const {
1694 return Representation::Tagged();
1695 }
1696
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001697 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
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; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001701};
1702
1703
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001704class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001705 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001706 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001707 set_representation(Representation::Integer32());
1708 // The result of this instruction is idempotent as long as its inputs don't
1709 // change. The length of a pixel array cannot change once set, so it's not
1710 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1711 SetFlag(kUseGVN);
1712 }
1713
1714 virtual Representation RequiredInputRepresentation(int index) const {
1715 return Representation::Tagged();
1716 }
1717
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001718 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001719
1720 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001721 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001722};
1723
1724
whesse@chromium.org7b260152011-06-20 15:33:18 +00001725class HElementsKind: public HUnaryOperation {
1726 public:
1727 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1728 set_representation(Representation::Integer32());
1729 SetFlag(kUseGVN);
1730 SetFlag(kDependsOnMaps);
1731 }
1732
1733 virtual Representation RequiredInputRepresentation(int index) const {
1734 return Representation::Tagged();
1735 }
1736
1737 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1738
1739 protected:
1740 virtual bool DataEquals(HValue* other) { return true; }
1741};
1742
1743
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001744class HBitNot: public HUnaryOperation {
1745 public:
1746 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1747 set_representation(Representation::Integer32());
1748 SetFlag(kUseGVN);
1749 SetFlag(kTruncatingToInt32);
1750 }
1751
1752 virtual Representation RequiredInputRepresentation(int index) const {
1753 return Representation::Integer32();
1754 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001755 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001756
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001757 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001758
1759 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001760 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761};
1762
1763
1764class HUnaryMathOperation: public HUnaryOperation {
1765 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001766 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767 : HUnaryOperation(value), op_(op) {
1768 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
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001791 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001792
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001793 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001794
1795 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1796
1797 virtual Representation RequiredInputRepresentation(int index) const {
1798 switch (op_) {
1799 case kMathFloor:
1800 case kMathRound:
1801 case kMathCeil:
1802 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001803 case kMathPowHalf:
1804 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001805 case kMathSin:
1806 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001807 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001808 case kMathAbs:
1809 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001810 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001811 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001812 return Representation::None();
1813 }
1814 }
1815
1816 virtual HValue* Canonicalize() {
1817 // If the input is integer32 then we replace the floor instruction
1818 // with its inputs. This happens before the representation changes are
1819 // introduced.
1820 if (op() == kMathFloor) {
1821 if (value()->representation().IsInteger32()) return value();
1822 }
1823 return this;
1824 }
1825
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001826 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001827 const char* OpName() const;
1828
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001829 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001831 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001832 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001833 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1834 return op_ == b->op();
1835 }
1836
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001837 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001838 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839};
1840
1841
1842class HLoadElements: public HUnaryOperation {
1843 public:
1844 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1845 set_representation(Representation::Tagged());
1846 SetFlag(kUseGVN);
1847 SetFlag(kDependsOnMaps);
1848 }
1849
1850 virtual Representation RequiredInputRepresentation(int index) const {
1851 return Representation::Tagged();
1852 }
1853
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001854 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001855
1856 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001857 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001858};
1859
1860
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001861class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001862 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001863 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001864 : HUnaryOperation(value) {
1865 set_representation(Representation::External());
1866 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001867 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001868 // change once set, so it's no necessary to introduce any additional
1869 // dependencies on top of the inputs.
1870 SetFlag(kUseGVN);
1871 }
1872
1873 virtual Representation RequiredInputRepresentation(int index) const {
1874 return Representation::Tagged();
1875 }
1876
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001877 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001878
1879 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001880 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001881};
1882
1883
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001884class HCheckMap: public HUnaryOperation {
1885 public:
1886 HCheckMap(HValue* value, Handle<Map> map)
1887 : HUnaryOperation(value), map_(map) {
1888 set_representation(Representation::Tagged());
1889 SetFlag(kUseGVN);
1890 SetFlag(kDependsOnMaps);
1891 }
1892
1893 virtual Representation RequiredInputRepresentation(int index) const {
1894 return Representation::Tagged();
1895 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001896 virtual void PrintDataTo(StringStream* stream);
1897 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001898
1899#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001900 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001901#endif
1902
1903 Handle<Map> map() const { return map_; }
1904
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001905 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001906
1907 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001908 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001909 HCheckMap* b = HCheckMap::cast(other);
1910 return map_.is_identical_to(b->map());
1911 }
1912
1913 private:
1914 Handle<Map> map_;
1915};
1916
1917
1918class HCheckFunction: public HUnaryOperation {
1919 public:
1920 HCheckFunction(HValue* value, Handle<JSFunction> function)
1921 : HUnaryOperation(value), target_(function) {
1922 set_representation(Representation::Tagged());
1923 SetFlag(kUseGVN);
1924 }
1925
1926 virtual Representation RequiredInputRepresentation(int index) const {
1927 return Representation::Tagged();
1928 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001929 virtual void PrintDataTo(StringStream* stream);
1930 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001931
1932#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001933 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001934#endif
1935
1936 Handle<JSFunction> target() const { return target_; }
1937
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001938 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001939
1940 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001941 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001942 HCheckFunction* b = HCheckFunction::cast(other);
1943 return target_.is_identical_to(b->target());
1944 }
1945
1946 private:
1947 Handle<JSFunction> target_;
1948};
1949
1950
1951class HCheckInstanceType: public HUnaryOperation {
1952 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001953 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1954 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001955 }
1956 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1957 return new HCheckInstanceType(value, IS_JS_ARRAY);
1958 }
1959 static HCheckInstanceType* NewIsString(HValue* value) {
1960 return new HCheckInstanceType(value, IS_STRING);
1961 }
1962 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1963 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001964 }
1965
1966 virtual Representation RequiredInputRepresentation(int index) const {
1967 return Representation::Tagged();
1968 }
1969
1970#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001971 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001972#endif
1973
danno@chromium.org160a7b02011-04-18 15:51:38 +00001974 virtual HValue* Canonicalize() {
1975 if (!value()->type().IsUninitialized() &&
1976 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001977 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001978 return NULL;
1979 }
1980 return this;
1981 }
1982
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001983 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1984 void GetCheckInterval(InstanceType* first, InstanceType* last);
1985 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001986
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001987 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001988
1989 protected:
1990 // TODO(ager): It could be nice to allow the ommision of instance
1991 // type checks if we have already performed an instance type check
1992 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001993 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001994 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001995 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996 }
1997
1998 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001999 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002000 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002001 IS_JS_ARRAY,
2002 IS_STRING,
2003 IS_SYMBOL,
2004 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2005 };
2006
2007 HCheckInstanceType(HValue* value, Check check)
2008 : HUnaryOperation(value), check_(check) {
2009 set_representation(Representation::Tagged());
2010 SetFlag(kUseGVN);
2011 }
2012
2013 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014};
2015
2016
2017class HCheckNonSmi: public HUnaryOperation {
2018 public:
2019 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2020 set_representation(Representation::Tagged());
2021 SetFlag(kUseGVN);
2022 }
2023
2024 virtual Representation RequiredInputRepresentation(int index) const {
2025 return Representation::Tagged();
2026 }
2027
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002028 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002029
2030#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002031 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002032#endif
2033
danno@chromium.org160a7b02011-04-18 15:51:38 +00002034 virtual HValue* Canonicalize() {
2035 HType value_type = value()->type();
2036 if (!value_type.IsUninitialized() &&
2037 (value_type.IsHeapNumber() ||
2038 value_type.IsString() ||
2039 value_type.IsBoolean() ||
2040 value_type.IsNonPrimitive())) {
2041 return NULL;
2042 }
2043 return this;
2044 }
2045
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002046 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002047
2048 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002049 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002050};
2051
2052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002053class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002055 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2056 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057 SetFlag(kUseGVN);
2058 SetFlag(kDependsOnMaps);
2059 }
2060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002061#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002062 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063#endif
2064
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002065 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002067
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002068 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070 virtual Representation RequiredInputRepresentation(int index) const {
2071 return Representation::None();
2072 }
2073
2074 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002075 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002076 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2077 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2078 return hash;
2079 }
2080
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002081 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002082 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002083 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002084 return prototype_.is_identical_to(b->prototype()) &&
2085 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002086 }
2087
2088 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002089 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091};
2092
2093
2094class HCheckSmi: public HUnaryOperation {
2095 public:
2096 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2097 set_representation(Representation::Tagged());
2098 SetFlag(kUseGVN);
2099 }
2100
2101 virtual Representation RequiredInputRepresentation(int index) const {
2102 return Representation::Tagged();
2103 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002104 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002105
2106#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002107 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002108#endif
2109
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002110 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002111
2112 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002113 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002114};
2115
2116
2117class HPhi: public HValue {
2118 public:
2119 explicit HPhi(int merged_index)
2120 : inputs_(2),
2121 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002122 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002123 is_live_(false),
2124 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002125 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2126 non_phi_uses_[i] = 0;
2127 indirect_uses_[i] = 0;
2128 }
2129 ASSERT(merged_index >= 0);
2130 set_representation(Representation::Tagged());
2131 SetFlag(kFlexibleRepresentation);
2132 }
2133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002134 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002135 bool double_occurred = false;
2136 bool int32_occurred = false;
2137 for (int i = 0; i < OperandCount(); ++i) {
2138 HValue* value = OperandAt(i);
2139 if (value->representation().IsDouble()) double_occurred = true;
2140 if (value->representation().IsInteger32()) int32_occurred = true;
2141 if (value->representation().IsTagged()) return Representation::Tagged();
2142 }
2143
2144 if (double_occurred) return Representation::Double();
2145 if (int32_occurred) return Representation::Integer32();
2146 return Representation::None();
2147 }
2148
2149 virtual Range* InferRange();
2150 virtual Representation RequiredInputRepresentation(int index) const {
2151 return representation();
2152 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002153 virtual HType CalculateInferredType();
2154 virtual int OperandCount() { return inputs_.length(); }
2155 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2156 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002157 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002158 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002160 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161
2162 int merged_index() const { return merged_index_; }
2163
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002164 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165
2166#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002167 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002168#endif
2169
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002170 void InitRealUses(int id);
2171 void AddNonPhiUsesFrom(HPhi* other);
2172 void AddIndirectUsesTo(int* use_count);
2173
2174 int tagged_non_phi_uses() const {
2175 return non_phi_uses_[Representation::kTagged];
2176 }
2177 int int32_non_phi_uses() const {
2178 return non_phi_uses_[Representation::kInteger32];
2179 }
2180 int double_non_phi_uses() const {
2181 return non_phi_uses_[Representation::kDouble];
2182 }
2183 int tagged_indirect_uses() const {
2184 return indirect_uses_[Representation::kTagged];
2185 }
2186 int int32_indirect_uses() const {
2187 return indirect_uses_[Representation::kInteger32];
2188 }
2189 int double_indirect_uses() const {
2190 return indirect_uses_[Representation::kDouble];
2191 }
2192 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002193 bool is_live() { return is_live_; }
2194 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002196 static HPhi* cast(HValue* value) {
2197 ASSERT(value->IsPhi());
2198 return reinterpret_cast<HPhi*>(value);
2199 }
2200 virtual Opcode opcode() const { return HValue::kPhi; }
2201
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002202 virtual bool IsConvertibleToInteger() const {
2203 return is_convertible_to_integer_;
2204 }
2205
2206 void set_is_convertible_to_integer(bool b) {
2207 is_convertible_to_integer_ = b;
2208 }
2209
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002210 protected:
2211 virtual void DeleteFromGraph();
2212 virtual void InternalSetOperandAt(int index, HValue* value) {
2213 inputs_[index] = value;
2214 }
2215
2216 private:
2217 ZoneList<HValue*> inputs_;
2218 int merged_index_;
2219
2220 int non_phi_uses_[Representation::kNumRepresentations];
2221 int indirect_uses_[Representation::kNumRepresentations];
2222 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002223 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002224 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002225};
2226
2227
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002228class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002229 public:
2230 HArgumentsObject() {
2231 set_representation(Representation::Tagged());
2232 SetFlag(kIsArguments);
2233 }
2234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002235 virtual Representation RequiredInputRepresentation(int index) const {
2236 return Representation::None();
2237 }
2238
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002239 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002240};
2241
2242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002243class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244 public:
2245 HConstant(Handle<Object> handle, Representation r);
2246
2247 Handle<Object> handle() const { return handle_; }
2248
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002249 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002250
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002251 virtual Representation RequiredInputRepresentation(int index) const {
2252 return Representation::None();
2253 }
2254
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002255 virtual bool IsConvertibleToInteger() const {
2256 if (handle_->IsSmi()) return true;
2257 if (handle_->IsHeapNumber() &&
2258 (HeapNumber::cast(*handle_)->value() ==
2259 static_cast<double>(NumberToInt32(*handle_)))) return true;
2260 return false;
2261 }
2262
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002263 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002264 virtual void PrintDataTo(StringStream* stream);
2265 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002266 bool IsInteger() const { return handle_->IsSmi(); }
2267 HConstant* CopyToRepresentation(Representation r) const;
2268 HConstant* CopyToTruncatedInt32() const;
2269 bool HasInteger32Value() const { return has_int32_value_; }
2270 int32_t Integer32Value() const {
2271 ASSERT(HasInteger32Value());
2272 return int32_value_;
2273 }
2274 bool HasDoubleValue() const { return has_double_value_; }
2275 double DoubleValue() const {
2276 ASSERT(HasDoubleValue());
2277 return double_value_;
2278 }
2279 bool HasStringValue() const { return handle_->IsString(); }
2280
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002281 bool ToBoolean() const;
2282
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002283 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002284 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002285 return reinterpret_cast<intptr_t>(*handle());
2286 }
2287
2288#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002289 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002290#endif
2291
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002292 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002293
2294 protected:
2295 virtual Range* InferRange();
2296
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002297 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002298 HConstant* other_constant = HConstant::cast(other);
2299 return handle().is_identical_to(other_constant->handle());
2300 }
2301
2302 private:
2303 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002304
2305 // The following two values represent the int32 and the double value of the
2306 // given constant if there is a lossless conversion between the constant
2307 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002308 bool has_int32_value_ : 1;
2309 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002311 double double_value_;
2312};
2313
2314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002315class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002316 public:
2317 HBinaryOperation(HValue* left, HValue* right) {
2318 ASSERT(left != NULL && right != NULL);
2319 SetOperandAt(0, left);
2320 SetOperandAt(1, right);
2321 }
2322
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002323 HValue* left() { return OperandAt(0); }
2324 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002325
2326 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2327 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002328 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002329 if (IsCommutative() && left()->IsConstant()) return right();
2330 return left();
2331 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002332 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002333 if (IsCommutative() && left()->IsConstant()) return left();
2334 return right();
2335 }
2336
2337 virtual bool IsCommutative() const { return false; }
2338
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002339 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002340};
2341
2342
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002343class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002344 public:
2345 HApplyArguments(HValue* function,
2346 HValue* receiver,
2347 HValue* length,
2348 HValue* elements) {
2349 set_representation(Representation::Tagged());
2350 SetOperandAt(0, function);
2351 SetOperandAt(1, receiver);
2352 SetOperandAt(2, length);
2353 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002354 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002355 }
2356
2357 virtual Representation RequiredInputRepresentation(int index) const {
2358 // The length is untagged, all other inputs are tagged.
2359 return (index == 2)
2360 ? Representation::Integer32()
2361 : Representation::Tagged();
2362 }
2363
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002364 HValue* function() { return OperandAt(0); }
2365 HValue* receiver() { return OperandAt(1); }
2366 HValue* length() { return OperandAt(2); }
2367 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002368
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002369 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002370};
2371
2372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374 public:
2375 HArgumentsElements() {
2376 // The value produced by this instruction is a pointer into the stack
2377 // that looks as if it was a smi because of alignment.
2378 set_representation(Representation::Tagged());
2379 SetFlag(kUseGVN);
2380 }
2381
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002382 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002383
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002384 virtual Representation RequiredInputRepresentation(int index) const {
2385 return Representation::None();
2386 }
2387
ager@chromium.org378b34e2011-01-28 08:04:38 +00002388 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002389 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002390};
2391
2392
2393class HArgumentsLength: public HUnaryOperation {
2394 public:
2395 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2396 set_representation(Representation::Integer32());
2397 SetFlag(kUseGVN);
2398 }
2399
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002400 virtual Representation RequiredInputRepresentation(int index) const {
2401 return Representation::Tagged();
2402 }
2403
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002404 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002405
2406 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002407 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002408};
2409
2410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002411class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412 public:
2413 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2414 set_representation(Representation::Tagged());
2415 SetFlag(kUseGVN);
2416 SetOperandAt(0, arguments);
2417 SetOperandAt(1, length);
2418 SetOperandAt(2, index);
2419 }
2420
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002422
2423 virtual Representation RequiredInputRepresentation(int index) const {
2424 // The arguments elements is considered tagged.
2425 return index == 0
2426 ? Representation::Tagged()
2427 : Representation::Integer32();
2428 }
2429
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002430 HValue* arguments() { return OperandAt(0); }
2431 HValue* length() { return OperandAt(1); }
2432 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002433
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002434 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002436 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002437};
2438
2439
2440class HBoundsCheck: public HBinaryOperation {
2441 public:
2442 HBoundsCheck(HValue* index, HValue* length)
2443 : HBinaryOperation(index, 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
2452#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002453 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454#endif
2455
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002456 HValue* index() { return left(); }
2457 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002458
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002459 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002460
2461 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002462 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463};
2464
2465
2466class HBitwiseBinaryOperation: public HBinaryOperation {
2467 public:
2468 HBitwiseBinaryOperation(HValue* left, HValue* right)
2469 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002470 set_representation(Representation::Tagged());
2471 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002472 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002473 }
2474
2475 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002476 return 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:
2496 HArithmeticBinaryOperation(HValue* left, HValue* right)
2497 : HBinaryOperation(left, right) {
2498 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 {
2512 return representation();
2513 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002514 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515 if (left()->representation().Equals(right()->representation())) {
2516 return left()->representation();
2517 }
2518 return HValue::InferredRepresentation();
2519 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520};
2521
2522
2523class HCompare: public HBinaryOperation {
2524 public:
2525 HCompare(HValue* left, HValue* right, Token::Value token)
2526 : HBinaryOperation(left, right), token_(token) {
2527 ASSERT(Token::IsCompareOp(token));
2528 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002529 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002530 }
2531
2532 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002533
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002534 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002535 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002536 }
2537
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 virtual Representation RequiredInputRepresentation(int index) const {
2539 return input_representation_;
2540 }
2541 Representation GetInputRepresentation() const {
2542 return input_representation_;
2543 }
2544 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002545 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002547 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002549 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550 return HValue::Hashcode() * 7 + token_;
2551 }
2552
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002553 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002554
2555 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002556 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002557 HCompare* comp = HCompare::cast(other);
2558 return token_ == comp->token();
2559 }
2560
2561 private:
2562 Representation input_representation_;
2563 Token::Value token_;
2564};
2565
2566
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002567class HCompareObjectEq: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002568 public:
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002569 HCompareObjectEq(HValue* left, HValue* right)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002570 : HBinaryOperation(left, right) {
2571 set_representation(Representation::Tagged());
2572 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002573 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002574 }
2575
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002576 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002577 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002578 }
2579
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002580 virtual Representation RequiredInputRepresentation(int index) const {
2581 return Representation::Tagged();
2582 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002583 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002584
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002585 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002586
2587 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002588 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002589};
2590
2591
whesse@chromium.org7b260152011-06-20 15:33:18 +00002592class HCompareConstantEq: public HUnaryOperation {
2593 public:
2594 HCompareConstantEq(HValue* left, int right, Token::Value op)
2595 : HUnaryOperation(left), op_(op), right_(right) {
2596 ASSERT(op == Token::EQ_STRICT);
2597 set_representation(Representation::Tagged());
2598 SetFlag(kUseGVN);
2599 }
2600
2601 Token::Value op() const { return op_; }
2602 int right() const { return right_; }
2603
2604 virtual bool EmitAtUses() {
2605 return !HasSideEffects() && !HasMultipleUses();
2606 }
2607
2608 virtual Representation RequiredInputRepresentation(int index) const {
2609 return Representation::Integer32();
2610 }
2611
2612 virtual HType CalculateInferredType() { return HType::Boolean(); }
2613
2614 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEq);
2615
2616 protected:
2617 virtual bool DataEquals(HValue* other) {
2618 HCompareConstantEq* other_instr = HCompareConstantEq::cast(other);
2619 return (op_ == other_instr->op_ &&
2620 right_ == other_instr->right_);
2621 }
2622
2623 private:
2624 const Token::Value op_;
2625 const int right_;
2626};
2627
2628
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002629class HUnaryPredicate: public HUnaryOperation {
2630 public:
2631 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2632 set_representation(Representation::Tagged());
2633 SetFlag(kUseGVN);
2634 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002635
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002636 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002637 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002638 }
2639
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002640 virtual Representation RequiredInputRepresentation(int index) const {
2641 return Representation::Tagged();
2642 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002643 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002644};
2645
2646
2647class HIsNull: public HUnaryPredicate {
2648 public:
2649 HIsNull(HValue* value, bool is_strict)
2650 : HUnaryPredicate(value), is_strict_(is_strict) { }
2651
2652 bool is_strict() const { return is_strict_; }
2653
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002654 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002655
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002656 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002657 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002658 HIsNull* b = HIsNull::cast(other);
2659 return is_strict_ == b->is_strict();
2660 }
2661
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002662 private:
2663 bool is_strict_;
2664};
2665
2666
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002667class HIsObject: public HUnaryPredicate {
2668 public:
2669 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2670
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002671 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002672
2673 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002674 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002675};
2676
2677
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002678class HIsSmi: public HUnaryPredicate {
2679 public:
2680 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2681
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002682 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002683
2684 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002685 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002686};
2687
2688
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002689class HIsUndetectable: public HUnaryPredicate {
2690 public:
2691 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2692
2693 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2694
2695 protected:
2696 virtual bool DataEquals(HValue* other) { return true; }
2697};
2698
2699
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002700class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002701 public:
2702 HIsConstructCall() {
2703 set_representation(Representation::Tagged());
2704 SetFlag(kUseGVN);
2705 }
2706
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002707 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002708 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002709 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002711 virtual Representation RequiredInputRepresentation(int index) const {
2712 return Representation::None();
2713 }
2714
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002715 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002716
2717 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002718 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002719};
2720
2721
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722class HHasInstanceType: public HUnaryPredicate {
2723 public:
2724 HHasInstanceType(HValue* value, InstanceType type)
2725 : HUnaryPredicate(value), from_(type), to_(type) { }
2726 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2727 : HUnaryPredicate(value), from_(from), to_(to) {
2728 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2729 }
2730
2731 InstanceType from() { return from_; }
2732 InstanceType to() { return to_; }
2733
whesse@chromium.org7b260152011-06-20 15:33:18 +00002734 virtual bool EmitAtUses() {
2735 return !HasSideEffects() && !HasMultipleUses();
2736 }
2737
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002738 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002740 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002742 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002743 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002744 HHasInstanceType* b = HHasInstanceType::cast(other);
2745 return (from_ == b->from()) && (to_ == b->to());
2746 }
2747
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002748 private:
2749 InstanceType from_;
2750 InstanceType to_; // Inclusive range, not all combinations work.
2751};
2752
2753
2754class HHasCachedArrayIndex: public HUnaryPredicate {
2755 public:
2756 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2757
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002758 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002759
2760 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002761 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002762};
2763
2764
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002765class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002766 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002767 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2768 set_representation(Representation::Tagged());
2769 SetFlag(kUseGVN);
2770 }
2771
2772 virtual Representation RequiredInputRepresentation(int index) const {
2773 return Representation::Tagged();
2774 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002775
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002776 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002777
2778 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002779 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002780};
2781
2782
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002783class HClassOfTest: public HUnaryPredicate {
2784 public:
2785 HClassOfTest(HValue* value, Handle<String> class_name)
2786 : HUnaryPredicate(value), class_name_(class_name) { }
2787
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002788 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002790 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791
2792 Handle<String> class_name() const { return class_name_; }
2793
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002794 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002795 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002796 HClassOfTest* b = HClassOfTest::cast(other);
2797 return class_name_.is_identical_to(b->class_name_);
2798 }
2799
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002800 private:
2801 Handle<String> class_name_;
2802};
2803
2804
2805class HTypeofIs: public HUnaryPredicate {
2806 public:
2807 HTypeofIs(HValue* value, Handle<String> type_literal)
2808 : HUnaryPredicate(value), type_literal_(type_literal) { }
2809
2810 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002811 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002812
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002813 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814
2815 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002816 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817 HTypeofIs* b = HTypeofIs::cast(other);
2818 return type_literal_.is_identical_to(b->type_literal_);
2819 }
2820
2821 private:
2822 Handle<String> type_literal_;
2823};
2824
2825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002826class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002828 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2829 SetOperandAt(0, context);
2830 SetOperandAt(1, left);
2831 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002832 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002833 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002834 }
2835
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002836 HValue* context() { return OperandAt(0); }
2837 HValue* left() { return OperandAt(1); }
2838 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002839
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002840 virtual Representation RequiredInputRepresentation(int index) const {
2841 return Representation::Tagged();
2842 }
2843
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002844 virtual HType CalculateInferredType();
2845
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002846 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002847
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002848 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002849};
2850
2851
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002852class HInstanceOfKnownGlobal: public HUnaryOperation {
2853 public:
2854 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2855 : HUnaryOperation(left), function_(right) {
2856 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002857 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002858 }
2859
2860 Handle<JSFunction> function() { return function_; }
2861
2862 virtual Representation RequiredInputRepresentation(int index) const {
2863 return Representation::Tagged();
2864 }
2865
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002866 virtual HType CalculateInferredType();
2867
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002868 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002869
2870 private:
2871 Handle<JSFunction> function_;
2872};
2873
2874
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002875class HPower: public HBinaryOperation {
2876 public:
2877 HPower(HValue* left, HValue* right)
2878 : HBinaryOperation(left, right) {
2879 set_representation(Representation::Double());
2880 SetFlag(kUseGVN);
2881 }
2882
2883 virtual Representation RequiredInputRepresentation(int index) const {
2884 return (index == 1) ? Representation::None() : Representation::Double();
2885 }
2886
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002887 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002888
2889 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002890 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002891};
2892
2893
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002894class HAdd: public HArithmeticBinaryOperation {
2895 public:
2896 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2897 SetFlag(kCanOverflow);
2898 }
2899
2900 // Add is only commutative if two integer values are added and not if two
2901 // tagged values are added (because it might be a String concatenation).
2902 virtual bool IsCommutative() const {
2903 return !representation().IsTagged();
2904 }
2905
2906 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2907
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002908 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002909
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002910 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002911
2912 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002913 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002914
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002915 virtual Range* InferRange();
2916};
2917
2918
2919class HSub: public HArithmeticBinaryOperation {
2920 public:
2921 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2922 SetFlag(kCanOverflow);
2923 }
2924
2925 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2926
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002927 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928
2929 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002930 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002931
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932 virtual Range* InferRange();
2933};
2934
2935
2936class HMul: public HArithmeticBinaryOperation {
2937 public:
2938 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2939 SetFlag(kCanOverflow);
2940 }
2941
2942 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2943
2944 // Only commutative if it is certain that not two objects are multiplicated.
2945 virtual bool IsCommutative() const {
2946 return !representation().IsTagged();
2947 }
2948
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002949 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950
2951 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002952 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002953
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002954 virtual Range* InferRange();
2955};
2956
2957
2958class HMod: public HArithmeticBinaryOperation {
2959 public:
2960 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2961 SetFlag(kCanBeDivByZero);
2962 }
2963
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002964 bool HasPowerOf2Divisor() {
2965 if (right()->IsConstant() &&
2966 HConstant::cast(right())->HasInteger32Value()) {
2967 int32_t value = HConstant::cast(right())->Integer32Value();
2968 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2969 }
2970
2971 return false;
2972 }
2973
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002974 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2975
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002976 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002977
2978 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002979 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002980
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002981 virtual Range* InferRange();
2982};
2983
2984
2985class HDiv: public HArithmeticBinaryOperation {
2986 public:
2987 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2988 SetFlag(kCanBeDivByZero);
2989 SetFlag(kCanOverflow);
2990 }
2991
2992 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2993
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002994 DECLARE_CONCRETE_INSTRUCTION(Div)
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 HBitAnd: public HBitwiseBinaryOperation {
3004 public:
3005 HBitAnd(HValue* left, HValue* right)
3006 : HBitwiseBinaryOperation(left, right) { }
3007
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(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012
3013 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003015
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016 virtual Range* InferRange();
3017};
3018
3019
3020class HBitXor: public HBitwiseBinaryOperation {
3021 public:
3022 HBitXor(HValue* left, HValue* right)
3023 : HBitwiseBinaryOperation(left, right) { }
3024
3025 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003026 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003028 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003029
3030 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003031 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032};
3033
3034
3035class HBitOr: public HBitwiseBinaryOperation {
3036 public:
3037 HBitOr(HValue* left, HValue* right)
3038 : HBitwiseBinaryOperation(left, right) { }
3039
3040 virtual bool IsCommutative() const { return true; }
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(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044
3045 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003047
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003048 virtual Range* InferRange();
3049};
3050
3051
3052class HShl: public HBitwiseBinaryOperation {
3053 public:
3054 HShl(HValue* left, HValue* right)
3055 : HBitwiseBinaryOperation(left, right) { }
3056
3057 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003058 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003060 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003061
3062 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003063 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003064};
3065
3066
3067class HShr: public HBitwiseBinaryOperation {
3068 public:
3069 HShr(HValue* left, HValue* right)
3070 : HBitwiseBinaryOperation(left, right) { }
3071
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003072 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003074 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003075
3076 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078};
3079
3080
3081class HSar: public HBitwiseBinaryOperation {
3082 public:
3083 HSar(HValue* left, HValue* right)
3084 : HBitwiseBinaryOperation(left, right) { }
3085
3086 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003087 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003088
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003089 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003090
3091 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003092 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003093};
3094
3095
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003096class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097 public:
3098 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3099 SetFlag(kChangesOsrEntries);
3100 }
3101
3102 int ast_id() const { return ast_id_; }
3103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104 virtual Representation RequiredInputRepresentation(int index) const {
3105 return Representation::None();
3106 }
3107
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003108 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003109
3110 private:
3111 int ast_id_;
3112};
3113
3114
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003115class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116 public:
3117 explicit HParameter(unsigned index) : index_(index) {
3118 set_representation(Representation::Tagged());
3119 }
3120
3121 unsigned index() const { return index_; }
3122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003123 virtual void PrintDataTo(StringStream* stream);
3124
3125 virtual Representation RequiredInputRepresentation(int index) const {
3126 return Representation::None();
3127 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003129 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130
3131 private:
3132 unsigned index_;
3133};
3134
3135
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003136class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003137 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003138 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3139 : HUnaryCall(context, argument_count),
3140 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 }
3143
3144 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003145
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003146 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003147
3148 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3149 transcendental_type_ = transcendental_type;
3150 }
3151 TranscendentalCache::Type transcendental_type() {
3152 return transcendental_type_;
3153 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003154
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003155 virtual void PrintDataTo(StringStream* stream);
3156
3157 virtual Representation RequiredInputRepresentation(int index) const {
3158 return Representation::Tagged();
3159 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003161 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162
3163 private:
3164 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003165 TranscendentalCache::Type transcendental_type_;
3166};
3167
3168
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003169class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 public:
3171 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003173 virtual Representation RequiredInputRepresentation(int index) const {
3174 return Representation::None();
3175 }
3176
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003177 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178};
3179
3180
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003181class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003183 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003184 : cell_(cell), check_hole_value_(check_hole_value) {
3185 set_representation(Representation::Tagged());
3186 SetFlag(kUseGVN);
3187 SetFlag(kDependsOnGlobalVars);
3188 }
3189
3190 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3191 bool check_hole_value() const { return check_hole_value_; }
3192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003195 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003196 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197 return reinterpret_cast<intptr_t>(*cell_);
3198 }
3199
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003200 virtual Representation RequiredInputRepresentation(int index) const {
3201 return Representation::None();
3202 }
3203
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003204 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003205
3206 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003207 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003208 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003209 return cell_.is_identical_to(b->cell());
3210 }
3211
3212 private:
3213 Handle<JSGlobalPropertyCell> cell_;
3214 bool check_hole_value_;
3215};
3216
3217
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003218class HLoadGlobalGeneric: public HBinaryOperation {
3219 public:
3220 HLoadGlobalGeneric(HValue* context,
3221 HValue* global_object,
3222 Handle<Object> name,
3223 bool for_typeof)
3224 : HBinaryOperation(context, global_object),
3225 name_(name),
3226 for_typeof_(for_typeof) {
3227 set_representation(Representation::Tagged());
3228 SetAllSideEffects();
3229 }
3230
3231 HValue* context() { return OperandAt(0); }
3232 HValue* global_object() { return OperandAt(1); }
3233 Handle<Object> name() const { return name_; }
3234 bool for_typeof() const { return for_typeof_; }
3235
3236 virtual void PrintDataTo(StringStream* stream);
3237
3238 virtual Representation RequiredInputRepresentation(int index) const {
3239 return Representation::Tagged();
3240 }
3241
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003242 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003243
3244 private:
3245 Handle<Object> name_;
3246 bool for_typeof_;
3247};
3248
3249
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003250class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003252 HStoreGlobalCell(HValue* value,
3253 Handle<JSGlobalPropertyCell> cell,
3254 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003255 : HUnaryOperation(value),
3256 cell_(cell),
3257 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003258 SetFlag(kChangesGlobalVars);
3259 }
3260
3261 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003262 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263
3264 virtual Representation RequiredInputRepresentation(int index) const {
3265 return Representation::Tagged();
3266 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003267 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003268
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003269 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003270
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003271 private:
3272 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003273 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003274};
3275
3276
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003277class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3278 public:
3279 HStoreGlobalGeneric(HValue* context,
3280 HValue* global_object,
3281 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003282 HValue* value,
3283 bool strict_mode)
3284 : name_(name),
3285 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003286 SetOperandAt(0, context);
3287 SetOperandAt(1, global_object);
3288 SetOperandAt(2, value);
3289 set_representation(Representation::Tagged());
3290 SetAllSideEffects();
3291 }
3292
3293 HValue* context() { return OperandAt(0); }
3294 HValue* global_object() { return OperandAt(1); }
3295 Handle<Object> name() const { return name_; }
3296 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003297 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003298
3299 virtual void PrintDataTo(StringStream* stream);
3300
3301 virtual Representation RequiredInputRepresentation(int index) const {
3302 return Representation::Tagged();
3303 }
3304
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003305 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003306
3307 private:
3308 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003309 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003310};
3311
3312
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003313class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003314 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003315 HLoadContextSlot(HValue* context , int slot_index)
3316 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003317 set_representation(Representation::Tagged());
3318 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003319 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003320 }
3321
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003322 int slot_index() const { return slot_index_; }
3323
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003324 virtual Representation RequiredInputRepresentation(int index) const {
3325 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003326 }
3327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003328 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003329
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003330 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003331
3332 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003333 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003334 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003335 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003336 }
3337
3338 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003339 int slot_index_;
3340};
3341
3342
3343static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3344 return !value->type().IsSmi() &&
3345 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3346}
3347
3348
3349class HStoreContextSlot: public HBinaryOperation {
3350 public:
3351 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3352 : HBinaryOperation(context, value), slot_index_(slot_index) {
3353 SetFlag(kChangesContextSlots);
3354 }
3355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003356 HValue* context() { return OperandAt(0); }
3357 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003358 int slot_index() const { return slot_index_; }
3359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003360 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003361 return StoringValueNeedsWriteBarrier(value());
3362 }
3363
3364 virtual Representation RequiredInputRepresentation(int index) const {
3365 return Representation::Tagged();
3366 }
3367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003368 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003369
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003370 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003371
3372 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003373 int slot_index_;
3374};
3375
3376
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003377class HLoadNamedField: public HUnaryOperation {
3378 public:
3379 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3380 : HUnaryOperation(object),
3381 is_in_object_(is_in_object),
3382 offset_(offset) {
3383 set_representation(Representation::Tagged());
3384 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003385 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003386 if (is_in_object) {
3387 SetFlag(kDependsOnInobjectFields);
3388 } else {
3389 SetFlag(kDependsOnBackingStoreFields);
3390 }
3391 }
3392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003393 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394 bool is_in_object() const { return is_in_object_; }
3395 int offset() const { return offset_; }
3396
3397 virtual Representation RequiredInputRepresentation(int index) const {
3398 return Representation::Tagged();
3399 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003400 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003402 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403
3404 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003405 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003406 HLoadNamedField* b = HLoadNamedField::cast(other);
3407 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3408 }
3409
3410 private:
3411 bool is_in_object_;
3412 int offset_;
3413};
3414
3415
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003416class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3417 public:
3418 HLoadNamedFieldPolymorphic(HValue* object,
3419 ZoneMapList* types,
3420 Handle<String> name);
3421
3422 HValue* object() { return OperandAt(0); }
3423 ZoneMapList* types() { return &types_; }
3424 Handle<String> name() { return name_; }
3425 bool need_generic() { return need_generic_; }
3426
3427 virtual Representation RequiredInputRepresentation(int index) const {
3428 return Representation::Tagged();
3429 }
3430
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003431 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003432
3433 static const int kMaxLoadPolymorphism = 4;
3434
3435 protected:
3436 virtual bool DataEquals(HValue* value);
3437
3438 private:
3439 ZoneMapList types_;
3440 Handle<String> name_;
3441 bool need_generic_;
3442};
3443
3444
3445
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003446class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003447 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003448 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3449 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003451 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003452 }
3453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003454 HValue* context() { return OperandAt(0); }
3455 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003456 Handle<Object> name() const { return name_; }
3457
3458 virtual Representation RequiredInputRepresentation(int index) const {
3459 return Representation::Tagged();
3460 }
3461
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003462 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003463
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003464 private:
3465 Handle<Object> name_;
3466};
3467
3468
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003469class HLoadFunctionPrototype: public HUnaryOperation {
3470 public:
3471 explicit HLoadFunctionPrototype(HValue* function)
3472 : HUnaryOperation(function) {
3473 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003474 SetFlag(kUseGVN);
3475 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003476 }
3477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003478 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003479
3480 virtual Representation RequiredInputRepresentation(int index) const {
3481 return Representation::Tagged();
3482 }
3483
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003484 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003485
3486 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003488};
3489
3490
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003491class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003492 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003493 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003494 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003495 SetFlag(kDependsOnArrayElements);
3496 SetFlag(kUseGVN);
3497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 HValue* object() { return OperandAt(0); }
3500 HValue* key() { return OperandAt(1); }
3501
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003502 virtual Representation RequiredInputRepresentation(int index) const {
3503 // The key is supposed to be Integer32.
3504 return (index == 1) ? Representation::Integer32()
3505 : Representation::Tagged();
3506 }
3507
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003508 virtual void PrintDataTo(StringStream* stream);
3509
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003510 bool RequiresHoleCheck() const;
3511
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003512 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003513
3514 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003515 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516};
3517
3518
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003519class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003520 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003521 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3522 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003523 JSObject::ElementsKind elements_kind)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003524 : HBinaryOperation(external_elements, key),
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003525 elements_kind_(elements_kind) {
3526 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3527 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003528 set_representation(Representation::Double());
3529 } else {
3530 set_representation(Representation::Integer32());
3531 }
3532 SetFlag(kDependsOnSpecializedArrayElements);
3533 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003534 SetFlag(kDependsOnCalls);
3535 SetFlag(kUseGVN);
3536 }
3537
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003538 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003539
3540 virtual Representation RequiredInputRepresentation(int index) const {
3541 // The key is supposed to be Integer32, but the base pointer
3542 // for the element load is a naked pointer.
3543 return (index == 1) ? Representation::Integer32()
3544 : Representation::External();
3545 }
3546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003547 HValue* external_pointer() { return OperandAt(0); }
3548 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003549 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003550
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003551 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003552
3553 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003554 virtual bool DataEquals(HValue* other) {
3555 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3556 HLoadKeyedSpecializedArrayElement* cast_other =
3557 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003558 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003559 }
3560
3561 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003562 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003563};
3564
3565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003566class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003568 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003569 set_representation(Representation::Tagged());
3570 SetOperandAt(0, obj);
3571 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003572 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003573 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003574 }
3575
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003576 HValue* object() { return OperandAt(0); }
3577 HValue* key() { return OperandAt(1); }
3578 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003579
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003580 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003581
3582 virtual Representation RequiredInputRepresentation(int index) const {
3583 return Representation::Tagged();
3584 }
3585
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003586 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003587};
3588
3589
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003590class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003591 public:
3592 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003593 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003594 HValue* val,
3595 bool in_object,
3596 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003597 : HBinaryOperation(obj, val),
3598 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 is_in_object_(in_object),
3600 offset_(offset) {
3601 if (is_in_object_) {
3602 SetFlag(kChangesInobjectFields);
3603 } else {
3604 SetFlag(kChangesBackingStoreFields);
3605 }
3606 }
3607
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003608 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003609
3610 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003611 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003612 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003613 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003615 HValue* object() { return OperandAt(0); }
3616 HValue* value() { return OperandAt(1); }
3617
3618 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619 bool is_in_object() const { return is_in_object_; }
3620 int offset() const { return offset_; }
3621 Handle<Map> transition() const { return transition_; }
3622 void set_transition(Handle<Map> map) { transition_ = map; }
3623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003624 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003625 return StoringValueNeedsWriteBarrier(value());
3626 }
3627
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003629 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 bool is_in_object_;
3631 int offset_;
3632 Handle<Map> transition_;
3633};
3634
3635
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003636class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003637 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003638 HStoreNamedGeneric(HValue* context,
3639 HValue* object,
3640 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003641 HValue* value,
3642 bool strict_mode)
3643 : name_(name),
3644 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003645 SetOperandAt(0, object);
3646 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003647 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003648 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649 }
3650
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003651 HValue* object() { return OperandAt(0); }
3652 HValue* value() { return OperandAt(1); }
3653 HValue* context() { return OperandAt(2); }
3654 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003655 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003656
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003657 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003658
3659 virtual Representation RequiredInputRepresentation(int index) const {
3660 return Representation::Tagged();
3661 }
3662
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003663 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003664
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003665 private:
3666 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003667 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668};
3669
3670
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003671class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003672 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003673 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3674 SetOperandAt(0, obj);
3675 SetOperandAt(1, key);
3676 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003677 SetFlag(kChangesArrayElements);
3678 }
3679
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680 virtual Representation RequiredInputRepresentation(int index) const {
3681 // The key is supposed to be Integer32.
3682 return (index == 1) ? Representation::Integer32()
3683 : Representation::Tagged();
3684 }
3685
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003686 HValue* object() { return OperandAt(0); }
3687 HValue* key() { return OperandAt(1); }
3688 HValue* value() { return OperandAt(2); }
3689
3690 bool NeedsWriteBarrier() {
3691 return StoringValueNeedsWriteBarrier(value());
3692 }
3693
3694 virtual void PrintDataTo(StringStream* stream);
3695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003696 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003697};
3698
3699
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003700class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003701 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003702 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3703 HValue* key,
3704 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003705 JSObject::ElementsKind elements_kind)
3706 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003707 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003708 SetOperandAt(0, external_elements);
3709 SetOperandAt(1, key);
3710 SetOperandAt(2, val);
3711 }
3712
3713 virtual void PrintDataTo(StringStream* stream);
3714
3715 virtual Representation RequiredInputRepresentation(int index) const {
3716 if (index == 0) {
3717 return Representation::External();
3718 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003719 bool float_or_double_elements =
3720 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3721 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3722 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003723 return Representation::Double();
3724 } else {
3725 return Representation::Integer32();
3726 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003727 }
3728 }
3729
3730 HValue* external_pointer() { return OperandAt(0); }
3731 HValue* key() { return OperandAt(1); }
3732 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003733 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003734
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003735 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3736
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003737 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003738 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003739};
3740
3741
3742class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003743 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003744 HStoreKeyedGeneric(HValue* context,
3745 HValue* object,
3746 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003747 HValue* value,
3748 bool strict_mode)
3749 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003750 SetOperandAt(0, object);
3751 SetOperandAt(1, key);
3752 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003753 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003754 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003755 }
3756
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003757 HValue* object() { return OperandAt(0); }
3758 HValue* key() { return OperandAt(1); }
3759 HValue* value() { return OperandAt(2); }
3760 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003761 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003762
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003763 virtual Representation RequiredInputRepresentation(int index) const {
3764 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003765 }
3766
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003767 virtual void PrintDataTo(StringStream* stream);
3768
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003769 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003770
3771 private:
3772 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003773};
3774
3775
danno@chromium.org160a7b02011-04-18 15:51:38 +00003776class HStringAdd: public HBinaryOperation {
3777 public:
3778 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3779 set_representation(Representation::Tagged());
3780 SetFlag(kUseGVN);
3781 SetFlag(kDependsOnMaps);
3782 }
3783
3784 virtual Representation RequiredInputRepresentation(int index) const {
3785 return Representation::Tagged();
3786 }
3787
3788 virtual HType CalculateInferredType() {
3789 return HType::String();
3790 }
3791
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003792 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003793
3794 protected:
3795 virtual bool DataEquals(HValue* other) { return true; }
3796};
3797
3798
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003799class HStringCharCodeAt: public HBinaryOperation {
3800 public:
3801 HStringCharCodeAt(HValue* string, HValue* index)
3802 : HBinaryOperation(string, index) {
3803 set_representation(Representation::Integer32());
3804 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003805 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003806 }
3807
3808 virtual Representation RequiredInputRepresentation(int index) const {
3809 // The index is supposed to be Integer32.
3810 return (index == 1) ? Representation::Integer32()
3811 : Representation::Tagged();
3812 }
3813
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003814 HValue* string() { return OperandAt(0); }
3815 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003816
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003817 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003818
3819 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003820 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003821
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003822 virtual Range* InferRange() {
3823 return new Range(0, String::kMaxUC16CharCode);
3824 }
3825};
3826
3827
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003828class HStringCharFromCode: public HUnaryOperation {
3829 public:
3830 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3831 set_representation(Representation::Tagged());
3832 SetFlag(kUseGVN);
3833 }
3834
3835 virtual Representation RequiredInputRepresentation(int index) const {
3836 return Representation::Integer32();
3837 }
3838
3839 virtual bool DataEquals(HValue* other) { return true; }
3840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003841 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003842};
3843
3844
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003845class HStringLength: public HUnaryOperation {
3846 public:
3847 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3848 set_representation(Representation::Tagged());
3849 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003850 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003851 }
3852
3853 virtual Representation RequiredInputRepresentation(int index) const {
3854 return Representation::Tagged();
3855 }
3856
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003857 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003858 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3859 return HType::Smi();
3860 }
3861
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003862 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003863
3864 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003865 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003866
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003867 virtual Range* InferRange() {
3868 return new Range(0, String::kMaxLength);
3869 }
3870};
3871
3872
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003873template <int V>
3874class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003875 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003876 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003877 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003878 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003879 }
3880
3881 int literal_index() const { return literal_index_; }
3882 int depth() const { return depth_; }
3883
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003884 private:
3885 int literal_index_;
3886 int depth_;
3887};
3888
3889
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003890class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003891 public:
3892 HArrayLiteral(Handle<FixedArray> constant_elements,
3893 int length,
3894 int literal_index,
3895 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003896 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003897 length_(length),
3898 constant_elements_(constant_elements) {}
3899
3900 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3901 int length() const { return length_; }
3902
3903 bool IsCopyOnWrite() const;
3904
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003905 virtual Representation RequiredInputRepresentation(int index) const {
3906 return Representation::None();
3907 }
3908
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003909 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003910
3911 private:
3912 int length_;
3913 Handle<FixedArray> constant_elements_;
3914};
3915
3916
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003917class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003918 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003919 HObjectLiteral(HValue* context,
3920 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003921 bool fast_elements,
3922 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003923 int depth,
3924 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003925 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003926 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003927 fast_elements_(fast_elements),
3928 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003929 SetOperandAt(0, context);
3930 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003931
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003932 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003933 Handle<FixedArray> constant_properties() const {
3934 return constant_properties_;
3935 }
3936 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003937 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003938
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003939 virtual Representation RequiredInputRepresentation(int index) const {
3940 return Representation::Tagged();
3941 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003942
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003943 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003944
3945 private:
3946 Handle<FixedArray> constant_properties_;
3947 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003948 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003949};
3950
3951
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003952class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003953 public:
3954 HRegExpLiteral(Handle<String> pattern,
3955 Handle<String> flags,
3956 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003957 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003958 pattern_(pattern),
3959 flags_(flags) { }
3960
3961 Handle<String> pattern() { return pattern_; }
3962 Handle<String> flags() { return flags_; }
3963
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003964 virtual Representation RequiredInputRepresentation(int index) const {
3965 return Representation::None();
3966 }
3967
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003968 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003969
3970 private:
3971 Handle<String> pattern_;
3972 Handle<String> flags_;
3973};
3974
3975
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003976class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003977 public:
3978 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3979 : shared_info_(shared), pretenure_(pretenure) {
3980 set_representation(Representation::Tagged());
3981 }
3982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003983 virtual Representation RequiredInputRepresentation(int index) const {
3984 return Representation::None();
3985 }
3986
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003987 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988
3989 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3990 bool pretenure() const { return pretenure_; }
3991
3992 private:
3993 Handle<SharedFunctionInfo> shared_info_;
3994 bool pretenure_;
3995};
3996
3997
3998class HTypeof: public HUnaryOperation {
3999 public:
4000 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
4001 set_representation(Representation::Tagged());
4002 }
4003
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004004 virtual Representation RequiredInputRepresentation(int index) const {
4005 return Representation::Tagged();
4006 }
4007
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004008 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004009};
4010
4011
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004012class HToFastProperties: public HUnaryOperation {
4013 public:
4014 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4015 // This instruction is not marked as having side effects, but
4016 // changes the map of the input operand. Use it only when creating
4017 // object literals.
4018 ASSERT(value->IsObjectLiteral());
4019 set_representation(Representation::Tagged());
4020 }
4021
4022 virtual Representation RequiredInputRepresentation(int index) const {
4023 return Representation::Tagged();
4024 }
4025
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004026 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004027};
4028
4029
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004030class HValueOf: public HUnaryOperation {
4031 public:
4032 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4033 set_representation(Representation::Tagged());
4034 }
4035
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004036 virtual Representation RequiredInputRepresentation(int index) const {
4037 return Representation::Tagged();
4038 }
4039
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004040 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004041};
4042
4043
4044class HDeleteProperty: public HBinaryOperation {
4045 public:
4046 HDeleteProperty(HValue* obj, HValue* key)
4047 : HBinaryOperation(obj, key) {
4048 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004049 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004050 }
4051
4052 virtual Representation RequiredInputRepresentation(int index) const {
4053 return Representation::Tagged();
4054 }
4055
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004056 virtual HType CalculateInferredType();
4057
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004058 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004060 HValue* object() { return left(); }
4061 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004062};
4063
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004064
4065class HIn: public HTemplateInstruction<2> {
4066 public:
4067 HIn(HValue* key, HValue* object) {
4068 SetOperandAt(0, key);
4069 SetOperandAt(1, object);
4070 set_representation(Representation::Tagged());
4071 SetAllSideEffects();
4072 }
4073
4074 HValue* key() { return OperandAt(0); }
4075 HValue* object() { return OperandAt(1); }
4076
4077 virtual Representation RequiredInputRepresentation(int index) const {
4078 return Representation::Tagged();
4079 }
4080
4081 virtual HType CalculateInferredType() {
4082 return HType::Boolean();
4083 }
4084
4085 virtual void PrintDataTo(StringStream* stream);
4086
4087 DECLARE_CONCRETE_INSTRUCTION(In)
4088};
4089
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004090#undef DECLARE_INSTRUCTION
4091#undef DECLARE_CONCRETE_INSTRUCTION
4092
4093} } // namespace v8::internal
4094
4095#endif // V8_HYDROGEN_INSTRUCTIONS_H_