blob: 8e122a2ef27e1be069aa44ea2acebd275fa88fa4 [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
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002765class HGetCachedArrayIndex: public HUnaryPredicate {
2766 public:
2767 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2768
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002769 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002770
2771 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002772 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002773};
2774
2775
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002776class HClassOfTest: public HUnaryPredicate {
2777 public:
2778 HClassOfTest(HValue* value, Handle<String> class_name)
2779 : HUnaryPredicate(value), class_name_(class_name) { }
2780
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002781 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002782
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002783 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784
2785 Handle<String> class_name() const { return class_name_; }
2786
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002787 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002788 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002789 HClassOfTest* b = HClassOfTest::cast(other);
2790 return class_name_.is_identical_to(b->class_name_);
2791 }
2792
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002793 private:
2794 Handle<String> class_name_;
2795};
2796
2797
2798class HTypeofIs: public HUnaryPredicate {
2799 public:
2800 HTypeofIs(HValue* value, Handle<String> type_literal)
2801 : HUnaryPredicate(value), type_literal_(type_literal) { }
2802
2803 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002804 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002805
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002806 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807
2808 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002809 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002810 HTypeofIs* b = HTypeofIs::cast(other);
2811 return type_literal_.is_identical_to(b->type_literal_);
2812 }
2813
2814 private:
2815 Handle<String> type_literal_;
2816};
2817
2818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002819class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002821 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2822 SetOperandAt(0, context);
2823 SetOperandAt(1, left);
2824 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002826 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827 }
2828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002829 HValue* context() { return OperandAt(0); }
2830 HValue* left() { return OperandAt(1); }
2831 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002832
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002833 virtual Representation RequiredInputRepresentation(int index) const {
2834 return Representation::Tagged();
2835 }
2836
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002837 virtual HType CalculateInferredType();
2838
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002839 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002841 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002842};
2843
2844
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002845class HInstanceOfKnownGlobal: public HUnaryOperation {
2846 public:
2847 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2848 : HUnaryOperation(left), function_(right) {
2849 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002850 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002851 }
2852
2853 Handle<JSFunction> function() { return function_; }
2854
2855 virtual Representation RequiredInputRepresentation(int index) const {
2856 return Representation::Tagged();
2857 }
2858
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002859 virtual HType CalculateInferredType();
2860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002861 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002862
2863 private:
2864 Handle<JSFunction> function_;
2865};
2866
2867
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002868class HPower: public HBinaryOperation {
2869 public:
2870 HPower(HValue* left, HValue* right)
2871 : HBinaryOperation(left, right) {
2872 set_representation(Representation::Double());
2873 SetFlag(kUseGVN);
2874 }
2875
2876 virtual Representation RequiredInputRepresentation(int index) const {
2877 return (index == 1) ? Representation::None() : Representation::Double();
2878 }
2879
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002880 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002881
2882 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002883 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002884};
2885
2886
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887class HAdd: public HArithmeticBinaryOperation {
2888 public:
2889 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2890 SetFlag(kCanOverflow);
2891 }
2892
2893 // Add is only commutative if two integer values are added and not if two
2894 // tagged values are added (because it might be a String concatenation).
2895 virtual bool IsCommutative() const {
2896 return !representation().IsTagged();
2897 }
2898
2899 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2900
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002901 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002903 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002904
2905 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002906 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002907
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908 virtual Range* InferRange();
2909};
2910
2911
2912class HSub: public HArithmeticBinaryOperation {
2913 public:
2914 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2915 SetFlag(kCanOverflow);
2916 }
2917
2918 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2919
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002920 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002921
2922 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002923 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002924
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925 virtual Range* InferRange();
2926};
2927
2928
2929class HMul: public HArithmeticBinaryOperation {
2930 public:
2931 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2932 SetFlag(kCanOverflow);
2933 }
2934
2935 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2936
2937 // Only commutative if it is certain that not two objects are multiplicated.
2938 virtual bool IsCommutative() const {
2939 return !representation().IsTagged();
2940 }
2941
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002942 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002943
2944 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002945 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002946
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947 virtual Range* InferRange();
2948};
2949
2950
2951class HMod: public HArithmeticBinaryOperation {
2952 public:
2953 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2954 SetFlag(kCanBeDivByZero);
2955 }
2956
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002957 bool HasPowerOf2Divisor() {
2958 if (right()->IsConstant() &&
2959 HConstant::cast(right())->HasInteger32Value()) {
2960 int32_t value = HConstant::cast(right())->Integer32Value();
2961 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2962 }
2963
2964 return false;
2965 }
2966
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002967 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2968
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002969 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002970
2971 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002972 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002973
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002974 virtual Range* InferRange();
2975};
2976
2977
2978class HDiv: public HArithmeticBinaryOperation {
2979 public:
2980 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2981 SetFlag(kCanBeDivByZero);
2982 SetFlag(kCanOverflow);
2983 }
2984
2985 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2986
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002987 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002988
2989 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002990 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002991
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992 virtual Range* InferRange();
2993};
2994
2995
2996class HBitAnd: public HBitwiseBinaryOperation {
2997 public:
2998 HBitAnd(HValue* left, HValue* right)
2999 : HBitwiseBinaryOperation(left, right) { }
3000
3001 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003002 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003004 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005
3006 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003007 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003008
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009 virtual Range* InferRange();
3010};
3011
3012
3013class HBitXor: public HBitwiseBinaryOperation {
3014 public:
3015 HBitXor(HValue* left, HValue* right)
3016 : HBitwiseBinaryOperation(left, right) { }
3017
3018 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003019 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003020
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003021 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003022
3023 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003024 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025};
3026
3027
3028class HBitOr: public HBitwiseBinaryOperation {
3029 public:
3030 HBitOr(HValue* left, HValue* right)
3031 : HBitwiseBinaryOperation(left, right) { }
3032
3033 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003034 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003035
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003036 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003037
3038 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003039 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003040
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003041 virtual Range* InferRange();
3042};
3043
3044
3045class HShl: public HBitwiseBinaryOperation {
3046 public:
3047 HShl(HValue* left, HValue* right)
3048 : HBitwiseBinaryOperation(left, right) { }
3049
3050 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003051 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003052
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003053 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003054
3055 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003056 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003057};
3058
3059
3060class HShr: public HBitwiseBinaryOperation {
3061 public:
3062 HShr(HValue* left, HValue* right)
3063 : HBitwiseBinaryOperation(left, right) { }
3064
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003065 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003067 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003068
3069 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003070 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071};
3072
3073
3074class HSar: public HBitwiseBinaryOperation {
3075 public:
3076 HSar(HValue* left, HValue* right)
3077 : HBitwiseBinaryOperation(left, right) { }
3078
3079 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003080 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003082 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003083
3084 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003085 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003086};
3087
3088
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003089class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003090 public:
3091 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3092 SetFlag(kChangesOsrEntries);
3093 }
3094
3095 int ast_id() const { return ast_id_; }
3096
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003097 virtual Representation RequiredInputRepresentation(int index) const {
3098 return Representation::None();
3099 }
3100
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003101 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102
3103 private:
3104 int ast_id_;
3105};
3106
3107
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003108class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003109 public:
3110 explicit HParameter(unsigned index) : index_(index) {
3111 set_representation(Representation::Tagged());
3112 }
3113
3114 unsigned index() const { return index_; }
3115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003116 virtual void PrintDataTo(StringStream* stream);
3117
3118 virtual Representation RequiredInputRepresentation(int index) const {
3119 return Representation::None();
3120 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003121
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003122 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123
3124 private:
3125 unsigned index_;
3126};
3127
3128
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003129class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003131 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3132 : HUnaryCall(context, argument_count),
3133 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003135 }
3136
3137 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003138
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003139 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140
3141 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3142 transcendental_type_ = transcendental_type;
3143 }
3144 TranscendentalCache::Type transcendental_type() {
3145 return transcendental_type_;
3146 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003147
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003148 virtual void PrintDataTo(StringStream* stream);
3149
3150 virtual Representation RequiredInputRepresentation(int index) const {
3151 return Representation::Tagged();
3152 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003153
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003154 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155
3156 private:
3157 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003158 TranscendentalCache::Type transcendental_type_;
3159};
3160
3161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003162class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003163 public:
3164 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003166 virtual Representation RequiredInputRepresentation(int index) const {
3167 return Representation::None();
3168 }
3169
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003170 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003171};
3172
3173
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003174class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003175 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003176 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003177 : cell_(cell), check_hole_value_(check_hole_value) {
3178 set_representation(Representation::Tagged());
3179 SetFlag(kUseGVN);
3180 SetFlag(kDependsOnGlobalVars);
3181 }
3182
3183 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3184 bool check_hole_value() const { return check_hole_value_; }
3185
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003186 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003188 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003189 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190 return reinterpret_cast<intptr_t>(*cell_);
3191 }
3192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 virtual Representation RequiredInputRepresentation(int index) const {
3194 return Representation::None();
3195 }
3196
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003197 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198
3199 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003200 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003201 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003202 return cell_.is_identical_to(b->cell());
3203 }
3204
3205 private:
3206 Handle<JSGlobalPropertyCell> cell_;
3207 bool check_hole_value_;
3208};
3209
3210
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003211class HLoadGlobalGeneric: public HBinaryOperation {
3212 public:
3213 HLoadGlobalGeneric(HValue* context,
3214 HValue* global_object,
3215 Handle<Object> name,
3216 bool for_typeof)
3217 : HBinaryOperation(context, global_object),
3218 name_(name),
3219 for_typeof_(for_typeof) {
3220 set_representation(Representation::Tagged());
3221 SetAllSideEffects();
3222 }
3223
3224 HValue* context() { return OperandAt(0); }
3225 HValue* global_object() { return OperandAt(1); }
3226 Handle<Object> name() const { return name_; }
3227 bool for_typeof() const { return for_typeof_; }
3228
3229 virtual void PrintDataTo(StringStream* stream);
3230
3231 virtual Representation RequiredInputRepresentation(int index) const {
3232 return Representation::Tagged();
3233 }
3234
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003235 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003236
3237 private:
3238 Handle<Object> name_;
3239 bool for_typeof_;
3240};
3241
3242
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003243class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003244 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003245 HStoreGlobalCell(HValue* value,
3246 Handle<JSGlobalPropertyCell> cell,
3247 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003248 : HUnaryOperation(value),
3249 cell_(cell),
3250 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251 SetFlag(kChangesGlobalVars);
3252 }
3253
3254 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003255 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003256
3257 virtual Representation RequiredInputRepresentation(int index) const {
3258 return Representation::Tagged();
3259 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003260 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003262 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264 private:
3265 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003266 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003267};
3268
3269
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003270class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3271 public:
3272 HStoreGlobalGeneric(HValue* context,
3273 HValue* global_object,
3274 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003275 HValue* value,
3276 bool strict_mode)
3277 : name_(name),
3278 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003279 SetOperandAt(0, context);
3280 SetOperandAt(1, global_object);
3281 SetOperandAt(2, value);
3282 set_representation(Representation::Tagged());
3283 SetAllSideEffects();
3284 }
3285
3286 HValue* context() { return OperandAt(0); }
3287 HValue* global_object() { return OperandAt(1); }
3288 Handle<Object> name() const { return name_; }
3289 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003290 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003291
3292 virtual void PrintDataTo(StringStream* stream);
3293
3294 virtual Representation RequiredInputRepresentation(int index) const {
3295 return Representation::Tagged();
3296 }
3297
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003298 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003299
3300 private:
3301 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003302 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003303};
3304
3305
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003306class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003307 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003308 HLoadContextSlot(HValue* context , int slot_index)
3309 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003310 set_representation(Representation::Tagged());
3311 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003312 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003313 }
3314
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003315 int slot_index() const { return slot_index_; }
3316
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003317 virtual Representation RequiredInputRepresentation(int index) const {
3318 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003319 }
3320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003321 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003322
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003323 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003324
3325 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003326 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003327 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003328 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003329 }
3330
3331 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003332 int slot_index_;
3333};
3334
3335
3336static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3337 return !value->type().IsSmi() &&
3338 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3339}
3340
3341
3342class HStoreContextSlot: public HBinaryOperation {
3343 public:
3344 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3345 : HBinaryOperation(context, value), slot_index_(slot_index) {
3346 SetFlag(kChangesContextSlots);
3347 }
3348
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003349 HValue* context() { return OperandAt(0); }
3350 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003351 int slot_index() const { return slot_index_; }
3352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003353 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003354 return StoringValueNeedsWriteBarrier(value());
3355 }
3356
3357 virtual Representation RequiredInputRepresentation(int index) const {
3358 return Representation::Tagged();
3359 }
3360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003361 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003362
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003363 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003364
3365 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003366 int slot_index_;
3367};
3368
3369
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003370class HLoadNamedField: public HUnaryOperation {
3371 public:
3372 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3373 : HUnaryOperation(object),
3374 is_in_object_(is_in_object),
3375 offset_(offset) {
3376 set_representation(Representation::Tagged());
3377 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003378 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379 if (is_in_object) {
3380 SetFlag(kDependsOnInobjectFields);
3381 } else {
3382 SetFlag(kDependsOnBackingStoreFields);
3383 }
3384 }
3385
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003386 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003387 bool is_in_object() const { return is_in_object_; }
3388 int offset() const { return offset_; }
3389
3390 virtual Representation RequiredInputRepresentation(int index) const {
3391 return Representation::Tagged();
3392 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003393 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003395 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003396
3397 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003398 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399 HLoadNamedField* b = HLoadNamedField::cast(other);
3400 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3401 }
3402
3403 private:
3404 bool is_in_object_;
3405 int offset_;
3406};
3407
3408
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003409class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3410 public:
3411 HLoadNamedFieldPolymorphic(HValue* object,
3412 ZoneMapList* types,
3413 Handle<String> name);
3414
3415 HValue* object() { return OperandAt(0); }
3416 ZoneMapList* types() { return &types_; }
3417 Handle<String> name() { return name_; }
3418 bool need_generic() { return need_generic_; }
3419
3420 virtual Representation RequiredInputRepresentation(int index) const {
3421 return Representation::Tagged();
3422 }
3423
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003424 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003425
3426 static const int kMaxLoadPolymorphism = 4;
3427
3428 protected:
3429 virtual bool DataEquals(HValue* value);
3430
3431 private:
3432 ZoneMapList types_;
3433 Handle<String> name_;
3434 bool need_generic_;
3435};
3436
3437
3438
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003439class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003440 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003441 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3442 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003443 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003444 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445 }
3446
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003447 HValue* context() { return OperandAt(0); }
3448 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003449 Handle<Object> name() const { return name_; }
3450
3451 virtual Representation RequiredInputRepresentation(int index) const {
3452 return Representation::Tagged();
3453 }
3454
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003455 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003456
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003457 private:
3458 Handle<Object> name_;
3459};
3460
3461
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003462class HLoadFunctionPrototype: public HUnaryOperation {
3463 public:
3464 explicit HLoadFunctionPrototype(HValue* function)
3465 : HUnaryOperation(function) {
3466 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003467 SetFlag(kUseGVN);
3468 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003469 }
3470
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003471 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003472
3473 virtual Representation RequiredInputRepresentation(int index) const {
3474 return Representation::Tagged();
3475 }
3476
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003477 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003478
3479 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003480 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003481};
3482
3483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003484class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003485 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003486 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003488 SetFlag(kDependsOnArrayElements);
3489 SetFlag(kUseGVN);
3490 }
3491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003492 HValue* object() { return OperandAt(0); }
3493 HValue* key() { return OperandAt(1); }
3494
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003495 virtual Representation RequiredInputRepresentation(int index) const {
3496 // The key is supposed to be Integer32.
3497 return (index == 1) ? Representation::Integer32()
3498 : Representation::Tagged();
3499 }
3500
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003501 virtual void PrintDataTo(StringStream* stream);
3502
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003503 bool RequiresHoleCheck() const;
3504
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003505 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003506
3507 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003508 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509};
3510
3511
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003512class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003513 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003514 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3515 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003516 JSObject::ElementsKind elements_kind)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003517 : HBinaryOperation(external_elements, key),
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003518 elements_kind_(elements_kind) {
3519 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3520 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003521 set_representation(Representation::Double());
3522 } else {
3523 set_representation(Representation::Integer32());
3524 }
3525 SetFlag(kDependsOnSpecializedArrayElements);
3526 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003527 SetFlag(kDependsOnCalls);
3528 SetFlag(kUseGVN);
3529 }
3530
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003531 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003532
3533 virtual Representation RequiredInputRepresentation(int index) const {
3534 // The key is supposed to be Integer32, but the base pointer
3535 // for the element load is a naked pointer.
3536 return (index == 1) ? Representation::Integer32()
3537 : Representation::External();
3538 }
3539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003540 HValue* external_pointer() { return OperandAt(0); }
3541 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003542 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003543
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003544 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003545
3546 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003547 virtual bool DataEquals(HValue* other) {
3548 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3549 HLoadKeyedSpecializedArrayElement* cast_other =
3550 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003551 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003552 }
3553
3554 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003555 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003556};
3557
3558
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003559class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003560 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003561 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003562 set_representation(Representation::Tagged());
3563 SetOperandAt(0, obj);
3564 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003565 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003566 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567 }
3568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003569 HValue* object() { return OperandAt(0); }
3570 HValue* key() { return OperandAt(1); }
3571 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003573 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003574
3575 virtual Representation RequiredInputRepresentation(int index) const {
3576 return Representation::Tagged();
3577 }
3578
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003579 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003580};
3581
3582
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003583class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584 public:
3585 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003586 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003587 HValue* val,
3588 bool in_object,
3589 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003590 : HBinaryOperation(obj, val),
3591 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592 is_in_object_(in_object),
3593 offset_(offset) {
3594 if (is_in_object_) {
3595 SetFlag(kChangesInobjectFields);
3596 } else {
3597 SetFlag(kChangesBackingStoreFields);
3598 }
3599 }
3600
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003601 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003602
3603 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003604 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003605 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003606 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003608 HValue* object() { return OperandAt(0); }
3609 HValue* value() { return OperandAt(1); }
3610
3611 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003612 bool is_in_object() const { return is_in_object_; }
3613 int offset() const { return offset_; }
3614 Handle<Map> transition() const { return transition_; }
3615 void set_transition(Handle<Map> map) { transition_ = map; }
3616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003618 return StoringValueNeedsWriteBarrier(value());
3619 }
3620
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003621 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003622 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623 bool is_in_object_;
3624 int offset_;
3625 Handle<Map> transition_;
3626};
3627
3628
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003629class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003631 HStoreNamedGeneric(HValue* context,
3632 HValue* object,
3633 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003634 HValue* value,
3635 bool strict_mode)
3636 : name_(name),
3637 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003638 SetOperandAt(0, object);
3639 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003640 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003641 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003642 }
3643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003644 HValue* object() { return OperandAt(0); }
3645 HValue* value() { return OperandAt(1); }
3646 HValue* context() { return OperandAt(2); }
3647 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003648 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003650 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651
3652 virtual Representation RequiredInputRepresentation(int index) const {
3653 return Representation::Tagged();
3654 }
3655
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003656 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003657
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003658 private:
3659 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003660 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661};
3662
3663
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003664class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003665 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003666 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3667 SetOperandAt(0, obj);
3668 SetOperandAt(1, key);
3669 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670 SetFlag(kChangesArrayElements);
3671 }
3672
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003673 virtual Representation RequiredInputRepresentation(int index) const {
3674 // The key is supposed to be Integer32.
3675 return (index == 1) ? Representation::Integer32()
3676 : Representation::Tagged();
3677 }
3678
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003679 HValue* object() { return OperandAt(0); }
3680 HValue* key() { return OperandAt(1); }
3681 HValue* value() { return OperandAt(2); }
3682
3683 bool NeedsWriteBarrier() {
3684 return StoringValueNeedsWriteBarrier(value());
3685 }
3686
3687 virtual void PrintDataTo(StringStream* stream);
3688
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003689 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690};
3691
3692
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003693class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003694 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003695 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3696 HValue* key,
3697 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003698 JSObject::ElementsKind elements_kind)
3699 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003700 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003701 SetOperandAt(0, external_elements);
3702 SetOperandAt(1, key);
3703 SetOperandAt(2, val);
3704 }
3705
3706 virtual void PrintDataTo(StringStream* stream);
3707
3708 virtual Representation RequiredInputRepresentation(int index) const {
3709 if (index == 0) {
3710 return Representation::External();
3711 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003712 bool float_or_double_elements =
3713 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3714 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3715 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003716 return Representation::Double();
3717 } else {
3718 return Representation::Integer32();
3719 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003720 }
3721 }
3722
3723 HValue* external_pointer() { return OperandAt(0); }
3724 HValue* key() { return OperandAt(1); }
3725 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003726 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003727
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003728 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3729
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003730 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003731 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003732};
3733
3734
3735class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003736 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003737 HStoreKeyedGeneric(HValue* context,
3738 HValue* object,
3739 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003740 HValue* value,
3741 bool strict_mode)
3742 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003743 SetOperandAt(0, object);
3744 SetOperandAt(1, key);
3745 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003746 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003747 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003748 }
3749
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003750 HValue* object() { return OperandAt(0); }
3751 HValue* key() { return OperandAt(1); }
3752 HValue* value() { return OperandAt(2); }
3753 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003754 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003755
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003756 virtual Representation RequiredInputRepresentation(int index) const {
3757 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003758 }
3759
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003760 virtual void PrintDataTo(StringStream* stream);
3761
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003762 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003763
3764 private:
3765 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003766};
3767
3768
danno@chromium.org160a7b02011-04-18 15:51:38 +00003769class HStringAdd: public HBinaryOperation {
3770 public:
3771 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3772 set_representation(Representation::Tagged());
3773 SetFlag(kUseGVN);
3774 SetFlag(kDependsOnMaps);
3775 }
3776
3777 virtual Representation RequiredInputRepresentation(int index) const {
3778 return Representation::Tagged();
3779 }
3780
3781 virtual HType CalculateInferredType() {
3782 return HType::String();
3783 }
3784
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003785 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003786
3787 protected:
3788 virtual bool DataEquals(HValue* other) { return true; }
3789};
3790
3791
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003792class HStringCharCodeAt: public HBinaryOperation {
3793 public:
3794 HStringCharCodeAt(HValue* string, HValue* index)
3795 : HBinaryOperation(string, index) {
3796 set_representation(Representation::Integer32());
3797 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003798 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003799 }
3800
3801 virtual Representation RequiredInputRepresentation(int index) const {
3802 // The index is supposed to be Integer32.
3803 return (index == 1) ? Representation::Integer32()
3804 : Representation::Tagged();
3805 }
3806
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003807 HValue* string() { return OperandAt(0); }
3808 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003809
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003810 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003811
3812 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003813 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003814
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003815 virtual Range* InferRange() {
3816 return new Range(0, String::kMaxUC16CharCode);
3817 }
3818};
3819
3820
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003821class HStringCharFromCode: public HUnaryOperation {
3822 public:
3823 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3824 set_representation(Representation::Tagged());
3825 SetFlag(kUseGVN);
3826 }
3827
3828 virtual Representation RequiredInputRepresentation(int index) const {
3829 return Representation::Integer32();
3830 }
3831
3832 virtual bool DataEquals(HValue* other) { return true; }
3833
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003834 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003835};
3836
3837
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003838class HStringLength: public HUnaryOperation {
3839 public:
3840 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3841 set_representation(Representation::Tagged());
3842 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003843 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003844 }
3845
3846 virtual Representation RequiredInputRepresentation(int index) const {
3847 return Representation::Tagged();
3848 }
3849
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003850 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003851 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3852 return HType::Smi();
3853 }
3854
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003855 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003856
3857 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003858 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003859
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003860 virtual Range* InferRange() {
3861 return new Range(0, String::kMaxLength);
3862 }
3863};
3864
3865
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003866template <int V>
3867class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003868 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003869 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003870 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003871 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003872 }
3873
3874 int literal_index() const { return literal_index_; }
3875 int depth() const { return depth_; }
3876
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003877 private:
3878 int literal_index_;
3879 int depth_;
3880};
3881
3882
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003883class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003884 public:
3885 HArrayLiteral(Handle<FixedArray> constant_elements,
3886 int length,
3887 int literal_index,
3888 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003889 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003890 length_(length),
3891 constant_elements_(constant_elements) {}
3892
3893 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3894 int length() const { return length_; }
3895
3896 bool IsCopyOnWrite() const;
3897
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003898 virtual Representation RequiredInputRepresentation(int index) const {
3899 return Representation::None();
3900 }
3901
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003902 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003903
3904 private:
3905 int length_;
3906 Handle<FixedArray> constant_elements_;
3907};
3908
3909
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003910class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003911 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003912 HObjectLiteral(HValue* context,
3913 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003914 bool fast_elements,
3915 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003916 int depth,
3917 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003918 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003919 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003920 fast_elements_(fast_elements),
3921 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003922 SetOperandAt(0, context);
3923 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003924
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003925 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003926 Handle<FixedArray> constant_properties() const {
3927 return constant_properties_;
3928 }
3929 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003930 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003931
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003932 virtual Representation RequiredInputRepresentation(int index) const {
3933 return Representation::Tagged();
3934 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003935
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003936 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003937
3938 private:
3939 Handle<FixedArray> constant_properties_;
3940 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003941 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003942};
3943
3944
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003945class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003946 public:
3947 HRegExpLiteral(Handle<String> pattern,
3948 Handle<String> flags,
3949 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003950 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003951 pattern_(pattern),
3952 flags_(flags) { }
3953
3954 Handle<String> pattern() { return pattern_; }
3955 Handle<String> flags() { return flags_; }
3956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003957 virtual Representation RequiredInputRepresentation(int index) const {
3958 return Representation::None();
3959 }
3960
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003961 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003962
3963 private:
3964 Handle<String> pattern_;
3965 Handle<String> flags_;
3966};
3967
3968
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003969class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003970 public:
3971 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3972 : shared_info_(shared), pretenure_(pretenure) {
3973 set_representation(Representation::Tagged());
3974 }
3975
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003976 virtual Representation RequiredInputRepresentation(int index) const {
3977 return Representation::None();
3978 }
3979
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003980 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003981
3982 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3983 bool pretenure() const { return pretenure_; }
3984
3985 private:
3986 Handle<SharedFunctionInfo> shared_info_;
3987 bool pretenure_;
3988};
3989
3990
3991class HTypeof: public HUnaryOperation {
3992 public:
3993 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3994 set_representation(Representation::Tagged());
3995 }
3996
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003997 virtual Representation RequiredInputRepresentation(int index) const {
3998 return Representation::Tagged();
3999 }
4000
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004001 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004002};
4003
4004
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004005class HToFastProperties: public HUnaryOperation {
4006 public:
4007 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4008 // This instruction is not marked as having side effects, but
4009 // changes the map of the input operand. Use it only when creating
4010 // object literals.
4011 ASSERT(value->IsObjectLiteral());
4012 set_representation(Representation::Tagged());
4013 }
4014
4015 virtual Representation RequiredInputRepresentation(int index) const {
4016 return Representation::Tagged();
4017 }
4018
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004019 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004020};
4021
4022
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004023class HValueOf: public HUnaryOperation {
4024 public:
4025 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4026 set_representation(Representation::Tagged());
4027 }
4028
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004029 virtual Representation RequiredInputRepresentation(int index) const {
4030 return Representation::Tagged();
4031 }
4032
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004033 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004034};
4035
4036
4037class HDeleteProperty: public HBinaryOperation {
4038 public:
4039 HDeleteProperty(HValue* obj, HValue* key)
4040 : HBinaryOperation(obj, key) {
4041 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004042 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004043 }
4044
4045 virtual Representation RequiredInputRepresentation(int index) const {
4046 return Representation::Tagged();
4047 }
4048
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004049 virtual HType CalculateInferredType();
4050
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004051 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004053 HValue* object() { return left(); }
4054 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004055};
4056
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004057
4058class HIn: public HTemplateInstruction<2> {
4059 public:
4060 HIn(HValue* key, HValue* object) {
4061 SetOperandAt(0, key);
4062 SetOperandAt(1, object);
4063 set_representation(Representation::Tagged());
4064 SetAllSideEffects();
4065 }
4066
4067 HValue* key() { return OperandAt(0); }
4068 HValue* object() { return OperandAt(1); }
4069
4070 virtual Representation RequiredInputRepresentation(int index) const {
4071 return Representation::Tagged();
4072 }
4073
4074 virtual HType CalculateInferredType() {
4075 return HType::Boolean();
4076 }
4077
4078 virtual void PrintDataTo(StringStream* stream);
4079
4080 DECLARE_CONCRETE_INSTRUCTION(In)
4081};
4082
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004083#undef DECLARE_INSTRUCTION
4084#undef DECLARE_CONCRETE_INSTRUCTION
4085
4086} } // namespace v8::internal
4087
4088#endif // V8_HYDROGEN_INSTRUCTIONS_H_