blob: 82fdfa70a2161309b690b64b05e14eeeef14f2e3 [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
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000034#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000035#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000036#include "string-stream.h"
37#include "zone.h"
38
39namespace v8 {
40namespace internal {
41
42// Forward declarations.
43class HBasicBlock;
44class HEnvironment;
45class HInstruction;
46class HLoopInformation;
47class HValue;
48class LInstruction;
49class LChunkBuilder;
50
51
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000052#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000053 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(ControlInstruction) \
55 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056
57
58#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000059 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000060 V(AccessArgumentsAt) \
61 V(Add) \
62 V(ApplyArguments) \
63 V(ArgumentsElements) \
64 V(ArgumentsLength) \
65 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000066 V(ArrayLiteral) \
67 V(BitAnd) \
68 V(BitNot) \
69 V(BitOr) \
70 V(BitXor) \
71 V(BlockEntry) \
72 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000073 V(CallConstantFunction) \
74 V(CallFunction) \
75 V(CallGlobal) \
76 V(CallKeyed) \
77 V(CallKnownGlobal) \
78 V(CallNamed) \
79 V(CallNew) \
80 V(CallRuntime) \
81 V(CallStub) \
82 V(Change) \
83 V(CheckFunction) \
84 V(CheckInstanceType) \
85 V(CheckMap) \
86 V(CheckNonSmi) \
87 V(CheckPrototypeMaps) \
88 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000089 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000090 V(Compare) \
91 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000092 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000093 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000094 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000095 V(DeleteProperty) \
96 V(Deoptimize) \
97 V(Div) \
98 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000099 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000100 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000101 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000102 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000103 V(GlobalObject) \
104 V(GlobalReceiver) \
105 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000106 V(HasInstanceType) \
107 V(HasCachedArrayIndex) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000108 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000109 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000110 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000111 V(InvokeFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000113 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000114 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000115 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000116 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000118 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000119 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000120 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000121 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000122 V(LoadGlobalCell) \
123 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124 V(LoadKeyedFastElement) \
125 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000126 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000128 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LoadNamedGeneric) \
130 V(Mod) \
131 V(Mul) \
132 V(ObjectLiteral) \
133 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000134 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000136 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(PushArgument) \
138 V(RegExpLiteral) \
139 V(Return) \
140 V(Sar) \
141 V(Shl) \
142 V(Shr) \
143 V(Simulate) \
144 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000145 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000146 V(StoreGlobalCell) \
147 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000148 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000149 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000150 V(StoreKeyedGeneric) \
151 V(StoreNamedField) \
152 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000153 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000154 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000155 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000156 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000158 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000160 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 V(Typeof) \
162 V(TypeofIs) \
163 V(UnaryMathOperation) \
164 V(UnknownOSRValue) \
165 V(ValueOf)
166
167#define GVN_FLAG_LIST(V) \
168 V(Calls) \
169 V(InobjectFields) \
170 V(BackingStoreFields) \
171 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000172 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000173 V(GlobalVars) \
174 V(Maps) \
175 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000176 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000177 V(OsrEntries)
178
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000179#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000180 virtual bool Is##type() const { return true; } \
181 static H##type* cast(HValue* value) { \
182 ASSERT(value->Is##type()); \
183 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000184 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000185
186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000187#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000189 static H##type* cast(HValue* value) { \
190 ASSERT(value->Is##type()); \
191 return reinterpret_cast<H##type*>(value); \
192 } \
193 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000194
195
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000196class Range: public ZoneObject {
197 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000198 Range()
199 : lower_(kMinInt),
200 upper_(kMaxInt),
201 next_(NULL),
202 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203
204 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000205 : lower_(lower),
206 upper_(upper),
207 next_(NULL),
208 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000210 int32_t upper() const { return upper_; }
211 int32_t lower() const { return lower_; }
212 Range* next() const { return next_; }
213 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
214 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 int32_t Mask() const;
217 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
218 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
219 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
220 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000221 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
222 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
223 bool IsInSmiRange() const {
224 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000226 void KeepOrder();
227 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000228
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 void StackUpon(Range* other) {
230 Intersect(other);
231 next_ = other;
232 }
233
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000234 void Intersect(Range* other);
235 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000236
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000237 void AddConstant(int32_t value);
238 void Sar(int32_t value);
239 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000240 bool AddAndCheckOverflow(Range* other);
241 bool SubAndCheckOverflow(Range* other);
242 bool MulAndCheckOverflow(Range* other);
243
244 private:
245 int32_t lower_;
246 int32_t upper_;
247 Range* next_;
248 bool can_be_minus_zero_;
249};
250
251
252class Representation {
253 public:
254 enum Kind {
255 kNone,
256 kTagged,
257 kDouble,
258 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000259 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000260 kNumRepresentations
261 };
262
263 Representation() : kind_(kNone) { }
264
265 static Representation None() { return Representation(kNone); }
266 static Representation Tagged() { return Representation(kTagged); }
267 static Representation Integer32() { return Representation(kInteger32); }
268 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000269 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000270
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000271 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272 return kind_ == other.kind_;
273 }
274
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000275 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276 bool IsNone() const { return kind_ == kNone; }
277 bool IsTagged() const { return kind_ == kTagged; }
278 bool IsInteger32() const { return kind_ == kInteger32; }
279 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000280 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000281 bool IsSpecialization() const {
282 return kind_ == kInteger32 || kind_ == kDouble;
283 }
284 const char* Mnemonic() const;
285
286 private:
287 explicit Representation(Kind k) : kind_(k) { }
288
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000289 // Make sure kind fits in int8.
290 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
291
292 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000293};
294
295
296class HType {
297 public:
298 HType() : type_(kUninitialized) { }
299
300 static HType Tagged() { return HType(kTagged); }
301 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
302 static HType TaggedNumber() { return HType(kTaggedNumber); }
303 static HType Smi() { return HType(kSmi); }
304 static HType HeapNumber() { return HType(kHeapNumber); }
305 static HType String() { return HType(kString); }
306 static HType Boolean() { return HType(kBoolean); }
307 static HType NonPrimitive() { return HType(kNonPrimitive); }
308 static HType JSArray() { return HType(kJSArray); }
309 static HType JSObject() { return HType(kJSObject); }
310 static HType Uninitialized() { return HType(kUninitialized); }
311
312 // Return the weakest (least precise) common type.
313 HType Combine(HType other) {
314 return HType(static_cast<Type>(type_ & other.type_));
315 }
316
317 bool Equals(const HType& other) {
318 return type_ == other.type_;
319 }
320
321 bool IsSubtypeOf(const HType& other) {
322 return Combine(other).Equals(other);
323 }
324
325 bool IsTagged() {
326 ASSERT(type_ != kUninitialized);
327 return ((type_ & kTagged) == kTagged);
328 }
329
330 bool IsTaggedPrimitive() {
331 ASSERT(type_ != kUninitialized);
332 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
333 }
334
335 bool IsTaggedNumber() {
336 ASSERT(type_ != kUninitialized);
337 return ((type_ & kTaggedNumber) == kTaggedNumber);
338 }
339
340 bool IsSmi() {
341 ASSERT(type_ != kUninitialized);
342 return ((type_ & kSmi) == kSmi);
343 }
344
345 bool IsHeapNumber() {
346 ASSERT(type_ != kUninitialized);
347 return ((type_ & kHeapNumber) == kHeapNumber);
348 }
349
350 bool IsString() {
351 ASSERT(type_ != kUninitialized);
352 return ((type_ & kString) == kString);
353 }
354
355 bool IsBoolean() {
356 ASSERT(type_ != kUninitialized);
357 return ((type_ & kBoolean) == kBoolean);
358 }
359
360 bool IsNonPrimitive() {
361 ASSERT(type_ != kUninitialized);
362 return ((type_ & kNonPrimitive) == kNonPrimitive);
363 }
364
365 bool IsJSArray() {
366 ASSERT(type_ != kUninitialized);
367 return ((type_ & kJSArray) == kJSArray);
368 }
369
370 bool IsJSObject() {
371 ASSERT(type_ != kUninitialized);
372 return ((type_ & kJSObject) == kJSObject);
373 }
374
375 bool IsUninitialized() {
376 return type_ == kUninitialized;
377 }
378
379 static HType TypeFromValue(Handle<Object> value);
380
381 const char* ToString();
382 const char* ToShortString();
383
384 private:
385 enum Type {
386 kTagged = 0x1, // 0000 0000 0000 0001
387 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
388 kTaggedNumber = 0xd, // 0000 0000 0000 1101
389 kSmi = 0x1d, // 0000 0000 0001 1101
390 kHeapNumber = 0x2d, // 0000 0000 0010 1101
391 kString = 0x45, // 0000 0000 0100 0101
392 kBoolean = 0x85, // 0000 0000 1000 0101
393 kNonPrimitive = 0x101, // 0000 0001 0000 0001
394 kJSObject = 0x301, // 0000 0011 0000 0001
395 kJSArray = 0x701, // 0000 0111 1000 0001
396 kUninitialized = 0x1fff // 0001 1111 1111 1111
397 };
398
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000399 // Make sure type fits in int16.
400 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
401
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000402 explicit HType(Type t) : type_(t) { }
403
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000404 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000405};
406
407
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000408class HUseListNode: public ZoneObject {
409 public:
410 HUseListNode(HValue* value, int index, HUseListNode* tail)
411 : tail_(tail), value_(value), index_(index) {
412 }
413
414 HUseListNode* tail() const { return tail_; }
415 HValue* value() const { return value_; }
416 int index() const { return index_; }
417
418 void set_tail(HUseListNode* list) { tail_ = list; }
419
420#ifdef DEBUG
421 void Zap() {
422 tail_ = reinterpret_cast<HUseListNode*>(1);
423 value_ = NULL;
424 index_ = -1;
425 }
426#endif
427
428 private:
429 HUseListNode* tail_;
430 HValue* value_;
431 int index_;
432};
433
434
435// We reuse use list nodes behind the scenes as uses are added and deleted.
436// This class is the safe way to iterate uses while deleting them.
437class HUseIterator BASE_EMBEDDED {
438 public:
439 bool Done() { return current_ == NULL; }
440 void Advance();
441
442 HValue* value() {
443 ASSERT(!Done());
444 return value_;
445 }
446
447 int index() {
448 ASSERT(!Done());
449 return index_;
450 }
451
452 private:
453 explicit HUseIterator(HUseListNode* head);
454
455 HUseListNode* current_;
456 HUseListNode* next_;
457 HValue* value_;
458 int index_;
459
460 friend class HValue;
461};
462
463
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000464class HValue: public ZoneObject {
465 public:
466 static const int kNoNumber = -1;
467
468 // There must be one corresponding kDepends flag for every kChanges flag and
469 // the order of the kChanges flags must be exactly the same as of the kDepends
470 // flags.
471 enum Flag {
472 // Declare global value numbering flags.
473 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
474 GVN_FLAG_LIST(DECLARE_DO)
475 #undef DECLARE_DO
476 kFlexibleRepresentation,
477 kUseGVN,
478 kCanOverflow,
479 kBailoutOnMinusZero,
480 kCanBeDivByZero,
481 kIsArguments,
482 kTruncatingToInt32,
483 kLastFlag = kTruncatingToInt32
484 };
485
486 STATIC_ASSERT(kLastFlag < kBitsPerInt);
487
488 static const int kChangesToDependsFlagsLeftShift = 1;
489
490 static int ChangesFlagsMask() {
491 int result = 0;
492 // Create changes mask.
493#define DECLARE_DO(type) result |= (1 << kChanges##type);
494 GVN_FLAG_LIST(DECLARE_DO)
495#undef DECLARE_DO
496 return result;
497 }
498
499 static int DependsFlagsMask() {
500 return ConvertChangesToDependsFlags(ChangesFlagsMask());
501 }
502
503 static int ConvertChangesToDependsFlags(int flags) {
504 return flags << kChangesToDependsFlagsLeftShift;
505 }
506
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000507 static HValue* cast(HValue* value) { return value; }
508
509 enum Opcode {
510 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000511 #define DECLARE_OPCODE(type) k##type,
512 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
513 kPhi
514 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000515 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000516 virtual Opcode opcode() const = 0;
517
518 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
519 #define DECLARE_PREDICATE(type) \
520 bool Is##type() const { return opcode() == k##type; }
521 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
522 #undef DECLARE_PREDICATE
523 bool IsPhi() const { return opcode() == kPhi; }
524
525 // Declare virtual predicates for abstract HInstruction or HValue
526 #define DECLARE_PREDICATE(type) \
527 virtual bool Is##type() const { return false; }
528 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
529 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530
531 HValue() : block_(NULL),
532 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000534 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000535 range_(NULL),
536 flags_(0) {}
537 virtual ~HValue() {}
538
539 HBasicBlock* block() const { return block_; }
540 void SetBlock(HBasicBlock* block);
541
542 int id() const { return id_; }
543 void set_id(int id) { id_ = id; }
544
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000545 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000546
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000547 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000548 Representation representation() const { return representation_; }
549 void ChangeRepresentation(Representation r) {
550 // Representation was already set and is allowed to be changed.
551 ASSERT(!representation_.IsNone());
552 ASSERT(!r.IsNone());
553 ASSERT(CheckFlag(kFlexibleRepresentation));
554 RepresentationChanged(r);
555 representation_ = r;
556 }
557
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000558 virtual bool IsConvertibleToInteger() const { return true; }
559
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000560 HType type() const { return type_; }
561 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000562 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000563 type_ = type;
564 }
565
566 // An operation needs to override this function iff:
567 // 1) it can produce an int32 output.
568 // 2) the true value of its output can potentially be minus zero.
569 // The implementation must set a flag so that it bails out in the case where
570 // it would otherwise output what should be a minus zero as an int32 zero.
571 // If the operation also exists in a form that takes int32 and outputs int32
572 // then the operation should return its input value so that we can propagate
573 // back. There are two operations that need to propagate back to more than
574 // one input. They are phi and binary add. They always return NULL and
575 // expect the caller to take care of things.
576 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
577 visited->Add(id());
578 return NULL;
579 }
580
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581 bool IsDefinedAfter(HBasicBlock* other) const;
582
583 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000584 virtual int OperandCount() = 0;
585 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000586 void SetOperandAt(int index, HValue* value);
587
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000588 void DeleteAndReplaceWith(HValue* other);
589 bool HasNoUses() const { return use_list_ == NULL; }
590 bool HasMultipleUses() const {
591 return use_list_ != NULL && use_list_->tail() != NULL;
592 }
593 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000594 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000595
596 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000597 void SetFlag(Flag f) { flags_ |= (1 << f); }
598 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
599 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
600
601 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
602 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
603 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000604
605 Range* range() const { return range_; }
606 bool HasRange() const { return range_ != NULL; }
607 void AddNewRange(Range* r);
608 void RemoveLastAddedRange();
609 void ComputeInitialRange();
610
611 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000612 virtual Representation RequiredInputRepresentation(int index) const = 0;
613
614 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000615 return representation();
616 }
617
618 // This gives the instruction an opportunity to replace itself with an
619 // instruction that does the same in some better way. To replace an
620 // instruction with a new one, first add the new instruction to the graph,
621 // then return it. Return NULL to have the instruction deleted.
622 virtual HValue* Canonicalize() { return this; }
623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000624 bool Equals(HValue* other);
625 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000626
627 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000628 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000629 void PrintNameTo(StringStream* stream);
630 static void PrintTypeTo(HType type, StringStream* stream);
631
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000632 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000633
634 // Updated the inferred type of this instruction and returns true if
635 // it has changed.
636 bool UpdateInferredType();
637
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000638 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000639
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000640#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000641 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000642#endif
643
644 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000645 // This function must be overridden for instructions with flag kUseGVN, to
646 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000647 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000648 UNREACHABLE();
649 return false;
650 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000651 virtual void RepresentationChanged(Representation to) { }
652 virtual Range* InferRange();
653 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000654 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000655 void clear_block() {
656 ASSERT(block_ != NULL);
657 block_ = NULL;
658 }
659
660 void set_representation(Representation r) {
661 // Representation is set-once.
662 ASSERT(representation_.IsNone() && !r.IsNone());
663 representation_ = r;
664 }
665
666 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000667 // A flag mask to mark an instruction as having arbitrary side effects.
668 static int AllSideEffects() {
669 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
670 }
671
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000672 // Remove the matching use from the use list if present. Returns the
673 // removed list node or NULL.
674 HUseListNode* RemoveUse(HValue* value, int index);
675
676 void ReplaceAllUsesWith(HValue* other);
677
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678 void RegisterUse(int index, HValue* new_value);
679
680 HBasicBlock* block_;
681
682 // The id of this instruction in the hydrogen graph, assigned when first
683 // added to the graph. Reflects creation order.
684 int id_;
685
686 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000687 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000688 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000689 Range* range_;
690 int flags_;
691
692 DISALLOW_COPY_AND_ASSIGN(HValue);
693};
694
695
696class HInstruction: public HValue {
697 public:
698 HInstruction* next() const { return next_; }
699 HInstruction* previous() const { return previous_; }
700
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000701 virtual void PrintTo(StringStream* stream);
702 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000703
704 bool IsLinked() const { return block() != NULL; }
705 void Unlink();
706 void InsertBefore(HInstruction* next);
707 void InsertAfter(HInstruction* previous);
708
709 int position() const { return position_; }
710 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
711 void set_position(int position) { position_ = position; }
712
713 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
714
715#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000716 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000717#endif
718
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000719 // Returns whether this is some kind of deoptimizing check
720 // instruction.
721 virtual bool IsCheckInstruction() const { return false; }
722
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000723 virtual bool IsCall() { return false; }
724
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000725 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000726
727 protected:
728 HInstruction()
729 : next_(NULL),
730 previous_(NULL),
731 position_(RelocInfo::kNoPosition) {
732 SetFlag(kDependsOnOsrEntries);
733 }
734
735 virtual void DeleteFromGraph() { Unlink(); }
736
737 private:
738 void InitializeAsFirst(HBasicBlock* block) {
739 ASSERT(!IsLinked());
740 SetBlock(block);
741 }
742
743 HInstruction* next_;
744 HInstruction* previous_;
745 int position_;
746
747 friend class HBasicBlock;
748};
749
750
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000751class HControlInstruction: public HInstruction {
752 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000753 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
754 : first_successor_(first), second_successor_(second) {
755 }
756
757 HBasicBlock* FirstSuccessor() const { return first_successor_; }
758 HBasicBlock* SecondSuccessor() const { return second_successor_; }
759
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000760 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000761
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000762 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000763
764 private:
765 HBasicBlock* first_successor_;
766 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000767};
768
769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000770template<int NumElements>
771class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000772 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000773 HOperandContainer() : elems_() { }
774
775 int length() { return NumElements; }
776 HValue*& operator[](int i) {
777 ASSERT(i < length());
778 return elems_[i];
779 }
780
781 private:
782 HValue* elems_[NumElements];
783};
784
785
786template<>
787class HOperandContainer<0> {
788 public:
789 int length() { return 0; }
790 HValue*& operator[](int i) {
791 UNREACHABLE();
792 static HValue* t = 0;
793 return t;
794 }
795};
796
797
798template<int V>
799class HTemplateInstruction : public HInstruction {
800 public:
801 int OperandCount() { return V; }
802 HValue* OperandAt(int i) { return inputs_[i]; }
803
804 protected:
805 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
806
807 private:
808 HOperandContainer<V> inputs_;
809};
810
811
812template<int V>
813class HTemplateControlInstruction : public HControlInstruction {
814 public:
815 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
816 : HControlInstruction(first, second) { }
817 int OperandCount() { return V; }
818 HValue* OperandAt(int i) { return inputs_[i]; }
819
820 protected:
821 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
822
823 private:
824 HOperandContainer<V> inputs_;
825};
826
827
828class HBlockEntry: public HTemplateInstruction<0> {
829 public:
830 virtual Representation RequiredInputRepresentation(int index) const {
831 return Representation::None();
832 }
833
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000834 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000835};
836
837
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000838class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000839 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000840 explicit HDeoptimize(int environment_length)
841 : HControlInstruction(NULL, NULL),
842 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000843
844 virtual Representation RequiredInputRepresentation(int index) const {
845 return Representation::None();
846 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000847
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000848 virtual int OperandCount() { return values_.length(); }
849 virtual HValue* OperandAt(int index) { return values_[index]; }
850
851 void AddEnvironmentValue(HValue* value) {
852 values_.Add(NULL);
853 SetOperandAt(values_.length() - 1, value);
854 }
855
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000856 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000857
858 protected:
859 virtual void InternalSetOperandAt(int index, HValue* value) {
860 values_[index] = value;
861 }
862
863 private:
864 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000865};
866
867
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000869 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000870 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000871 : HTemplateControlInstruction<0>(target, NULL),
872 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000873
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000874 void set_include_stack_check(bool include_stack_check) {
875 include_stack_check_ = include_stack_check;
876 }
877 bool include_stack_check() const { return include_stack_check_; }
878
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000879 virtual Representation RequiredInputRepresentation(int index) const {
880 return Representation::None();
881 }
882
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000883 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000884
885 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000886 bool include_stack_check_;
887};
888
889
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000890class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000892 explicit HUnaryControlInstruction(HValue* value,
893 HBasicBlock* true_target,
894 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000895 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896 SetOperandAt(0, value);
897 }
898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000899 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000901 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000902};
903
904
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000905class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000907 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
908 : HUnaryControlInstruction(value, true_target, false_target) {
909 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000910 }
911
912 virtual Representation RequiredInputRepresentation(int index) const {
913 return Representation::None();
914 }
915
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000916 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917};
918
919
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000920class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000922 HCompareMap(HValue* value,
923 Handle<Map> map,
924 HBasicBlock* true_target,
925 HBasicBlock* false_target)
926 : HUnaryControlInstruction(value, true_target, false_target),
927 map_(map) {
928 ASSERT(true_target != NULL);
929 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930 ASSERT(!map.is_null());
931 }
932
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000933 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000934
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935 Handle<Map> map() const { return map_; }
936
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000937 virtual Representation RequiredInputRepresentation(int index) const {
938 return Representation::Tagged();
939 }
940
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000941 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942
943 private:
944 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000945};
946
947
948class HReturn: public HUnaryControlInstruction {
949 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000950 explicit HReturn(HValue* value)
951 : HUnaryControlInstruction(value, NULL, NULL) {
952 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000953
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000954 virtual Representation RequiredInputRepresentation(int index) const {
955 return Representation::Tagged();
956 }
957
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000958 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959};
960
961
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000962class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000963 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000964 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
965
966 virtual Representation RequiredInputRepresentation(int index) const {
967 return Representation::None();
968 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000969
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000970 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000971};
972
973
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000974class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000975 public:
976 explicit HUnaryOperation(HValue* value) {
977 SetOperandAt(0, value);
978 }
979
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000980 HValue* value() { return OperandAt(0); }
981 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000982};
983
984
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000985class HThrow: public HUnaryOperation {
986 public:
987 explicit HThrow(HValue* value) : HUnaryOperation(value) {
988 SetAllSideEffects();
989 }
990
991 virtual Representation RequiredInputRepresentation(int index) const {
992 return Representation::Tagged();
993 }
994
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000995 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000996};
997
998
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000999class HChange: public HUnaryOperation {
1000 public:
1001 HChange(HValue* value,
1002 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001003 Representation to,
1004 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001005 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001006 ASSERT(!from.IsNone() && !to.IsNone());
1007 ASSERT(!from.Equals(to));
1008 set_representation(to);
1009 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001010 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001011 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1012 value->range()->IsInSmiRange()) {
1013 set_type(HType::Smi());
1014 }
1015 }
1016
1017 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1018
1019 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001020 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001021 virtual Representation RequiredInputRepresentation(int index) const {
1022 return from_;
1023 }
1024
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001025 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001027 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001028
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001029 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001030
1031 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001032 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001033 if (!other->IsChange()) return false;
1034 HChange* change = HChange::cast(other);
1035 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001036 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001037 }
1038
1039 private:
1040 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001041};
1042
1043
1044class HSimulate: public HInstruction {
1045 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001046 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001047 : ast_id_(ast_id),
1048 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001049 values_(2),
1050 assigned_indexes_(2) {}
1051 virtual ~HSimulate() {}
1052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001053 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001054
1055 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1056 int ast_id() const { return ast_id_; }
1057 void set_ast_id(int id) {
1058 ASSERT(!HasAstId());
1059 ast_id_ = id;
1060 }
1061
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001062 int pop_count() const { return pop_count_; }
1063 const ZoneList<HValue*>* values() const { return &values_; }
1064 int GetAssignedIndexAt(int index) const {
1065 ASSERT(HasAssignedIndexAt(index));
1066 return assigned_indexes_[index];
1067 }
1068 bool HasAssignedIndexAt(int index) const {
1069 return assigned_indexes_[index] != kNoIndex;
1070 }
1071 void AddAssignedValue(int index, HValue* value) {
1072 AddValue(index, value);
1073 }
1074 void AddPushedValue(HValue* value) {
1075 AddValue(kNoIndex, value);
1076 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001077 virtual int OperandCount() { return values_.length(); }
1078 virtual HValue* OperandAt(int index) { return values_[index]; }
1079
1080 virtual Representation RequiredInputRepresentation(int index) const {
1081 return Representation::None();
1082 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001083
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001084 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085
1086#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001087 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001088#endif
1089
1090 protected:
1091 virtual void InternalSetOperandAt(int index, HValue* value) {
1092 values_[index] = value;
1093 }
1094
1095 private:
1096 static const int kNoIndex = -1;
1097 void AddValue(int index, HValue* value) {
1098 assigned_indexes_.Add(index);
1099 // Resize the list of pushed values.
1100 values_.Add(NULL);
1101 // Set the operand through the base method in HValue to make sure that the
1102 // use lists are correctly updated.
1103 SetOperandAt(values_.length() - 1, value);
1104 }
1105 int ast_id_;
1106 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001107 ZoneList<HValue*> values_;
1108 ZoneList<int> assigned_indexes_;
1109};
1110
1111
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001112class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001113 public:
1114 HStackCheck() { }
1115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001116 virtual Representation RequiredInputRepresentation(int index) const {
1117 return Representation::None();
1118 }
1119
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001120 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001121};
1122
1123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001124class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001125 public:
1126 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1127 : closure_(closure), function_(function) {
1128 }
1129
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001130 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001131
1132 Handle<JSFunction> closure() const { return closure_; }
1133 FunctionLiteral* function() const { return function_; }
1134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001135 virtual Representation RequiredInputRepresentation(int index) const {
1136 return Representation::None();
1137 }
1138
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001139 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001140
1141 private:
1142 Handle<JSFunction> closure_;
1143 FunctionLiteral* function_;
1144};
1145
1146
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001147class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148 public:
1149 HLeaveInlined() {}
1150
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001151 virtual Representation RequiredInputRepresentation(int index) const {
1152 return Representation::None();
1153 }
1154
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001155 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001156};
1157
1158
1159class HPushArgument: public HUnaryOperation {
1160 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001161 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1162 set_representation(Representation::Tagged());
1163 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001164
1165 virtual Representation RequiredInputRepresentation(int index) const {
1166 return Representation::Tagged();
1167 }
1168
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001169 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001170
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001171 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001172};
1173
1174
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001175class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001176 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001177 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001178 set_representation(Representation::Tagged());
1179 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001180 }
1181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001182 virtual Representation RequiredInputRepresentation(int index) const {
1183 return Representation::None();
1184 }
1185
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001186 DECLARE_CONCRETE_INSTRUCTION(Context);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001187
1188 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001189 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001190};
1191
1192
1193class HOuterContext: public HUnaryOperation {
1194 public:
1195 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1196 set_representation(Representation::Tagged());
1197 SetFlag(kUseGVN);
1198 }
1199
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001200 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001201
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001202 virtual Representation RequiredInputRepresentation(int index) const {
1203 return Representation::Tagged();
1204 }
1205
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001206 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001207 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001208};
1209
1210
1211class HGlobalObject: public HUnaryOperation {
1212 public:
1213 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1214 set_representation(Representation::Tagged());
1215 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001216 }
1217
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001218 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001219
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001220 virtual Representation RequiredInputRepresentation(int index) const {
1221 return Representation::Tagged();
1222 }
1223
ager@chromium.org378b34e2011-01-28 08:04:38 +00001224 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001225 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001226};
1227
1228
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001229class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001230 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001231 explicit HGlobalReceiver(HValue* global_object)
1232 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233 set_representation(Representation::Tagged());
1234 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001235 }
1236
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001237 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001239 virtual Representation RequiredInputRepresentation(int index) const {
1240 return Representation::Tagged();
1241 }
1242
ager@chromium.org378b34e2011-01-28 08:04:38 +00001243 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001244 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001245};
1246
1247
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001248template <int V>
1249class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001251 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001252 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1253 this->set_representation(Representation::Tagged());
1254 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001255 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001257 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001258
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001259 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001260
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001261 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001262
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001263 private:
1264 int argument_count_;
1265};
1266
1267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001268class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001269 public:
1270 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001271 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001272 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001273 }
1274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001275 virtual Representation RequiredInputRepresentation(int index) const {
1276 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001277 }
1278
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001279 virtual void PrintDataTo(StringStream* stream);
1280
1281 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001282};
1283
1284
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001285class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001286 public:
1287 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001288 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001289 SetOperandAt(0, first);
1290 SetOperandAt(1, second);
1291 }
1292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001293 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001295 virtual Representation RequiredInputRepresentation(int index) const {
1296 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001297 }
1298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001299 HValue* first() { return OperandAt(0); }
1300 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001301};
1302
1303
danno@chromium.org160a7b02011-04-18 15:51:38 +00001304class HInvokeFunction: public HBinaryCall {
1305 public:
1306 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1307 : HBinaryCall(context, function, argument_count) {
1308 }
1309
1310 virtual Representation RequiredInputRepresentation(int index) const {
1311 return Representation::Tagged();
1312 }
1313
1314 HValue* context() { return first(); }
1315 HValue* function() { return second(); }
1316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001317 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001318};
1319
1320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001322 public:
1323 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325
1326 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001327
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001329 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001330 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001331 }
1332
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001333 virtual void PrintDataTo(StringStream* stream);
1334
1335 virtual Representation RequiredInputRepresentation(int index) const {
1336 return Representation::None();
1337 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001338
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001339 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001340
1341 private:
1342 Handle<JSFunction> function_;
1343};
1344
1345
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001346class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001347 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001348 HCallKeyed(HValue* context, HValue* key, int argument_count)
1349 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001350 }
1351
1352 virtual Representation RequiredInputRepresentation(int index) const {
1353 return Representation::Tagged();
1354 }
1355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001356 HValue* context() { return first(); }
1357 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001358
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001359 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001360};
1361
1362
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001363class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001364 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001365 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1366 : HUnaryCall(context, argument_count), name_(name) {
1367 }
1368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001369 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001370
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001371 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001372 Handle<String> name() const { return name_; }
1373
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001374 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001376 virtual Representation RequiredInputRepresentation(int index) const {
1377 return Representation::Tagged();
1378 }
1379
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380 private:
1381 Handle<String> name_;
1382};
1383
1384
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001385class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001386 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001387 HCallFunction(HValue* context, int argument_count)
1388 : HUnaryCall(context, argument_count) {
1389 }
1390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001391 HValue* context() { return value(); }
1392
1393 virtual Representation RequiredInputRepresentation(int index) const {
1394 return Representation::Tagged();
1395 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001396
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001397 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001398};
1399
1400
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001401class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001402 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001403 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1404 : HUnaryCall(context, argument_count), name_(name) {
1405 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001407 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001409 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001410 Handle<String> name() const { return name_; }
1411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001412 virtual Representation RequiredInputRepresentation(int index) const {
1413 return Representation::Tagged();
1414 }
1415
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001416 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001417
1418 private:
1419 Handle<String> name_;
1420};
1421
1422
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001423class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001425 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001426 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001428 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001429
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430 Handle<JSFunction> target() const { return target_; }
1431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001432 virtual Representation RequiredInputRepresentation(int index) const {
1433 return Representation::None();
1434 }
1435
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001436 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001437
1438 private:
1439 Handle<JSFunction> target_;
1440};
1441
1442
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001443class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001444 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001445 HCallNew(HValue* context, HValue* constructor, int argument_count)
1446 : HBinaryCall(context, constructor, argument_count) {
1447 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001448
1449 virtual Representation RequiredInputRepresentation(int index) const {
1450 return Representation::Tagged();
1451 }
1452
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001453 HValue* context() { return first(); }
1454 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001455
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001456 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001457};
1458
1459
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001460class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001461 public:
1462 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001463 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1466 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001467
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001468 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001469 Handle<String> name() const { return name_; }
1470
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001471 virtual Representation RequiredInputRepresentation(int index) const {
1472 return Representation::None();
1473 }
1474
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001475 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001476
1477 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001478 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001479 Handle<String> name_;
1480};
1481
1482
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001483class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001484 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001485 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001486 // The length of an array is stored as a tagged value in the array
1487 // object. It is guaranteed to be 32 bit integer, but it can be
1488 // represented as either a smi or heap number.
1489 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001490 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001491 SetFlag(kDependsOnArrayLengths);
1492 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001493 }
1494
1495 virtual Representation RequiredInputRepresentation(int index) const {
1496 return Representation::Tagged();
1497 }
1498
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001499 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001500
1501 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001502 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001503};
1504
1505
1506class HFixedArrayLength: public HUnaryOperation {
1507 public:
1508 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1509 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001510 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001511 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001512 }
1513
1514 virtual Representation RequiredInputRepresentation(int index) const {
1515 return Representation::Tagged();
1516 }
1517
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001518 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001519
1520 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001521 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522};
1523
1524
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001525class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001526 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001527 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001528 set_representation(Representation::Integer32());
1529 // The result of this instruction is idempotent as long as its inputs don't
1530 // change. The length of a pixel array cannot change once set, so it's not
1531 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1532 SetFlag(kUseGVN);
1533 }
1534
1535 virtual Representation RequiredInputRepresentation(int index) const {
1536 return Representation::Tagged();
1537 }
1538
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001539 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001540
1541 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001542 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001543};
1544
1545
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001546class HBitNot: public HUnaryOperation {
1547 public:
1548 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1549 set_representation(Representation::Integer32());
1550 SetFlag(kUseGVN);
1551 SetFlag(kTruncatingToInt32);
1552 }
1553
1554 virtual Representation RequiredInputRepresentation(int index) const {
1555 return Representation::Integer32();
1556 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001557 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001558
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001559 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001560
1561 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001562 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563};
1564
1565
1566class HUnaryMathOperation: public HUnaryOperation {
1567 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001568 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001569 : HUnaryOperation(value), op_(op) {
1570 switch (op) {
1571 case kMathFloor:
1572 case kMathRound:
1573 case kMathCeil:
1574 set_representation(Representation::Integer32());
1575 break;
1576 case kMathAbs:
1577 set_representation(Representation::Tagged());
1578 SetFlag(kFlexibleRepresentation);
1579 break;
1580 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001581 case kMathPowHalf:
1582 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001583 case kMathSin:
1584 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001586 break;
1587 default:
1588 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001589 }
1590 SetFlag(kUseGVN);
1591 }
1592
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001593 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001594
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001595 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596
1597 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1598
1599 virtual Representation RequiredInputRepresentation(int index) const {
1600 switch (op_) {
1601 case kMathFloor:
1602 case kMathRound:
1603 case kMathCeil:
1604 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001605 case kMathPowHalf:
1606 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001607 case kMathSin:
1608 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001609 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001610 case kMathAbs:
1611 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001613 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614 return Representation::None();
1615 }
1616 }
1617
1618 virtual HValue* Canonicalize() {
1619 // If the input is integer32 then we replace the floor instruction
1620 // with its inputs. This happens before the representation changes are
1621 // introduced.
1622 if (op() == kMathFloor) {
1623 if (value()->representation().IsInteger32()) return value();
1624 }
1625 return this;
1626 }
1627
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001628 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001629 const char* OpName() const;
1630
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001631 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001632
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001633 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001634 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001635 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1636 return op_ == b->op();
1637 }
1638
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001640 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001641};
1642
1643
1644class HLoadElements: public HUnaryOperation {
1645 public:
1646 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1647 set_representation(Representation::Tagged());
1648 SetFlag(kUseGVN);
1649 SetFlag(kDependsOnMaps);
1650 }
1651
1652 virtual Representation RequiredInputRepresentation(int index) const {
1653 return Representation::Tagged();
1654 }
1655
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001656 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001657
1658 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001659 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660};
1661
1662
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001663class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001664 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001665 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001666 : HUnaryOperation(value) {
1667 set_representation(Representation::External());
1668 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001669 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001670 // change once set, so it's no necessary to introduce any additional
1671 // dependencies on top of the inputs.
1672 SetFlag(kUseGVN);
1673 }
1674
1675 virtual Representation RequiredInputRepresentation(int index) const {
1676 return Representation::Tagged();
1677 }
1678
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001679 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001680
1681 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001682 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001683};
1684
1685
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686class HCheckMap: public HUnaryOperation {
1687 public:
1688 HCheckMap(HValue* value, Handle<Map> map)
1689 : HUnaryOperation(value), map_(map) {
1690 set_representation(Representation::Tagged());
1691 SetFlag(kUseGVN);
1692 SetFlag(kDependsOnMaps);
1693 }
1694
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001695 virtual bool IsCheckInstruction() const { return true; }
1696
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001697 virtual Representation RequiredInputRepresentation(int index) const {
1698 return Representation::Tagged();
1699 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001700 virtual void PrintDataTo(StringStream* stream);
1701 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001702
1703#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001704 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001705#endif
1706
1707 Handle<Map> map() const { return map_; }
1708
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001709 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710
1711 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001712 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713 HCheckMap* b = HCheckMap::cast(other);
1714 return map_.is_identical_to(b->map());
1715 }
1716
1717 private:
1718 Handle<Map> map_;
1719};
1720
1721
1722class HCheckFunction: public HUnaryOperation {
1723 public:
1724 HCheckFunction(HValue* value, Handle<JSFunction> function)
1725 : HUnaryOperation(value), target_(function) {
1726 set_representation(Representation::Tagged());
1727 SetFlag(kUseGVN);
1728 }
1729
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001730 virtual bool IsCheckInstruction() const { return true; }
1731
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001732 virtual Representation RequiredInputRepresentation(int index) const {
1733 return Representation::Tagged();
1734 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001735 virtual void PrintDataTo(StringStream* stream);
1736 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001737
1738#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001739 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740#endif
1741
1742 Handle<JSFunction> target() const { return target_; }
1743
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001744 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745
1746 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001747 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001748 HCheckFunction* b = HCheckFunction::cast(other);
1749 return target_.is_identical_to(b->target());
1750 }
1751
1752 private:
1753 Handle<JSFunction> target_;
1754};
1755
1756
1757class HCheckInstanceType: public HUnaryOperation {
1758 public:
1759 // Check that the instance type is in the range [first, last] where
1760 // both first and last are included.
1761 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1762 : HUnaryOperation(value), first_(first), last_(last) {
1763 ASSERT(first <= last);
1764 set_representation(Representation::Tagged());
1765 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001766 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1767 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1768 // A particular string instance type can change because of GC or
1769 // externalization, but the value still remains a string.
1770 SetFlag(kDependsOnMaps);
1771 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001772 }
1773
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001774 virtual bool IsCheckInstruction() const { return true; }
1775
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001776 virtual Representation RequiredInputRepresentation(int index) const {
1777 return Representation::Tagged();
1778 }
1779
1780#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001781 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001782#endif
1783
danno@chromium.org160a7b02011-04-18 15:51:38 +00001784 virtual HValue* Canonicalize() {
1785 if (!value()->type().IsUninitialized() &&
1786 value()->type().IsString() &&
1787 first() == FIRST_STRING_TYPE &&
1788 last() == LAST_STRING_TYPE) {
1789 return NULL;
1790 }
1791 return this;
1792 }
1793
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001794 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1795
1796 InstanceType first() const { return first_; }
1797 InstanceType last() const { return last_; }
1798
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001799 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001800
1801 protected:
1802 // TODO(ager): It could be nice to allow the ommision of instance
1803 // type checks if we have already performed an instance type check
1804 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001805 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001806 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1807 return (first_ == b->first()) && (last_ == b->last());
1808 }
1809
1810 private:
1811 InstanceType first_;
1812 InstanceType last_;
1813};
1814
1815
1816class HCheckNonSmi: public HUnaryOperation {
1817 public:
1818 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1819 set_representation(Representation::Tagged());
1820 SetFlag(kUseGVN);
1821 }
1822
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001823 virtual bool IsCheckInstruction() const { return true; }
1824
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001825 virtual Representation RequiredInputRepresentation(int index) const {
1826 return Representation::Tagged();
1827 }
1828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001829 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830
1831#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001832 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001833#endif
1834
danno@chromium.org160a7b02011-04-18 15:51:38 +00001835 virtual HValue* Canonicalize() {
1836 HType value_type = value()->type();
1837 if (!value_type.IsUninitialized() &&
1838 (value_type.IsHeapNumber() ||
1839 value_type.IsString() ||
1840 value_type.IsBoolean() ||
1841 value_type.IsNonPrimitive())) {
1842 return NULL;
1843 }
1844 return this;
1845 }
1846
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001847 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001848
1849 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001850 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851};
1852
1853
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001854class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001855 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001856 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1857 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001858 SetFlag(kUseGVN);
1859 SetFlag(kDependsOnMaps);
1860 }
1861
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001862 virtual bool IsCheckInstruction() const { return true; }
1863
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001864#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001865 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001866#endif
1867
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001868 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001870
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001871 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001872
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001873 virtual Representation RequiredInputRepresentation(int index) const {
1874 return Representation::None();
1875 }
1876
1877 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001878 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001879 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1880 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1881 return hash;
1882 }
1883
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001884 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001885 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001886 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001887 return prototype_.is_identical_to(b->prototype()) &&
1888 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001889 }
1890
1891 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001892 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001893 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001894};
1895
1896
1897class HCheckSmi: public HUnaryOperation {
1898 public:
1899 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1900 set_representation(Representation::Tagged());
1901 SetFlag(kUseGVN);
1902 }
1903
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001904 virtual bool IsCheckInstruction() const { return true; }
1905
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001906 virtual Representation RequiredInputRepresentation(int index) const {
1907 return Representation::Tagged();
1908 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001909 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001910
1911#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001912 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001913#endif
1914
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001915 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001916
1917 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001918 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919};
1920
1921
1922class HPhi: public HValue {
1923 public:
1924 explicit HPhi(int merged_index)
1925 : inputs_(2),
1926 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001927 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001928 is_live_(false),
1929 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1931 non_phi_uses_[i] = 0;
1932 indirect_uses_[i] = 0;
1933 }
1934 ASSERT(merged_index >= 0);
1935 set_representation(Representation::Tagged());
1936 SetFlag(kFlexibleRepresentation);
1937 }
1938
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001939 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001940 bool double_occurred = false;
1941 bool int32_occurred = false;
1942 for (int i = 0; i < OperandCount(); ++i) {
1943 HValue* value = OperandAt(i);
1944 if (value->representation().IsDouble()) double_occurred = true;
1945 if (value->representation().IsInteger32()) int32_occurred = true;
1946 if (value->representation().IsTagged()) return Representation::Tagged();
1947 }
1948
1949 if (double_occurred) return Representation::Double();
1950 if (int32_occurred) return Representation::Integer32();
1951 return Representation::None();
1952 }
1953
1954 virtual Range* InferRange();
1955 virtual Representation RequiredInputRepresentation(int index) const {
1956 return representation();
1957 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001958 virtual HType CalculateInferredType();
1959 virtual int OperandCount() { return inputs_.length(); }
1960 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1961 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001962 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001963 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001964
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001965 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966
1967 int merged_index() const { return merged_index_; }
1968
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001969 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001970
1971#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001972 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001973#endif
1974
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001975 void InitRealUses(int id);
1976 void AddNonPhiUsesFrom(HPhi* other);
1977 void AddIndirectUsesTo(int* use_count);
1978
1979 int tagged_non_phi_uses() const {
1980 return non_phi_uses_[Representation::kTagged];
1981 }
1982 int int32_non_phi_uses() const {
1983 return non_phi_uses_[Representation::kInteger32];
1984 }
1985 int double_non_phi_uses() const {
1986 return non_phi_uses_[Representation::kDouble];
1987 }
1988 int tagged_indirect_uses() const {
1989 return indirect_uses_[Representation::kTagged];
1990 }
1991 int int32_indirect_uses() const {
1992 return indirect_uses_[Representation::kInteger32];
1993 }
1994 int double_indirect_uses() const {
1995 return indirect_uses_[Representation::kDouble];
1996 }
1997 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001998 bool is_live() { return is_live_; }
1999 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002001 static HPhi* cast(HValue* value) {
2002 ASSERT(value->IsPhi());
2003 return reinterpret_cast<HPhi*>(value);
2004 }
2005 virtual Opcode opcode() const { return HValue::kPhi; }
2006
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002007 virtual bool IsConvertibleToInteger() const {
2008 return is_convertible_to_integer_;
2009 }
2010
2011 void set_is_convertible_to_integer(bool b) {
2012 is_convertible_to_integer_ = b;
2013 }
2014
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015 protected:
2016 virtual void DeleteFromGraph();
2017 virtual void InternalSetOperandAt(int index, HValue* value) {
2018 inputs_[index] = value;
2019 }
2020
2021 private:
2022 ZoneList<HValue*> inputs_;
2023 int merged_index_;
2024
2025 int non_phi_uses_[Representation::kNumRepresentations];
2026 int indirect_uses_[Representation::kNumRepresentations];
2027 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002028 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002029 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030};
2031
2032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002033class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002034 public:
2035 HArgumentsObject() {
2036 set_representation(Representation::Tagged());
2037 SetFlag(kIsArguments);
2038 }
2039
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002040 virtual Representation RequiredInputRepresentation(int index) const {
2041 return Representation::None();
2042 }
2043
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002044 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002045};
2046
2047
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002048class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002049 public:
2050 HConstant(Handle<Object> handle, Representation r);
2051
2052 Handle<Object> handle() const { return handle_; }
2053
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002054 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002056 virtual Representation RequiredInputRepresentation(int index) const {
2057 return Representation::None();
2058 }
2059
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002060 virtual bool IsConvertibleToInteger() const {
2061 if (handle_->IsSmi()) return true;
2062 if (handle_->IsHeapNumber() &&
2063 (HeapNumber::cast(*handle_)->value() ==
2064 static_cast<double>(NumberToInt32(*handle_)))) return true;
2065 return false;
2066 }
2067
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002068 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002069 virtual void PrintDataTo(StringStream* stream);
2070 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071 bool IsInteger() const { return handle_->IsSmi(); }
2072 HConstant* CopyToRepresentation(Representation r) const;
2073 HConstant* CopyToTruncatedInt32() const;
2074 bool HasInteger32Value() const { return has_int32_value_; }
2075 int32_t Integer32Value() const {
2076 ASSERT(HasInteger32Value());
2077 return int32_value_;
2078 }
2079 bool HasDoubleValue() const { return has_double_value_; }
2080 double DoubleValue() const {
2081 ASSERT(HasDoubleValue());
2082 return double_value_;
2083 }
2084 bool HasStringValue() const { return handle_->IsString(); }
2085
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002086 bool ToBoolean() const;
2087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002088 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002089 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090 return reinterpret_cast<intptr_t>(*handle());
2091 }
2092
2093#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002094 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095#endif
2096
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002097 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002098
2099 protected:
2100 virtual Range* InferRange();
2101
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002102 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002103 HConstant* other_constant = HConstant::cast(other);
2104 return handle().is_identical_to(other_constant->handle());
2105 }
2106
2107 private:
2108 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109
2110 // The following two values represent the int32 and the double value of the
2111 // given constant if there is a lossless conversion between the constant
2112 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002113 bool has_int32_value_ : 1;
2114 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116 double double_value_;
2117};
2118
2119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002120class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002121 public:
2122 HBinaryOperation(HValue* left, HValue* right) {
2123 ASSERT(left != NULL && right != NULL);
2124 SetOperandAt(0, left);
2125 SetOperandAt(1, right);
2126 }
2127
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002128 HValue* left() { return OperandAt(0); }
2129 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002130
2131 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2132 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002133 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002134 if (IsCommutative() && left()->IsConstant()) return right();
2135 return left();
2136 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002137 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002138 if (IsCommutative() && left()->IsConstant()) return left();
2139 return right();
2140 }
2141
2142 virtual bool IsCommutative() const { return false; }
2143
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002144 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002145};
2146
2147
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002148class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002149 public:
2150 HApplyArguments(HValue* function,
2151 HValue* receiver,
2152 HValue* length,
2153 HValue* elements) {
2154 set_representation(Representation::Tagged());
2155 SetOperandAt(0, function);
2156 SetOperandAt(1, receiver);
2157 SetOperandAt(2, length);
2158 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002159 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160 }
2161
2162 virtual Representation RequiredInputRepresentation(int index) const {
2163 // The length is untagged, all other inputs are tagged.
2164 return (index == 2)
2165 ? Representation::Integer32()
2166 : Representation::Tagged();
2167 }
2168
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002169 HValue* function() { return OperandAt(0); }
2170 HValue* receiver() { return OperandAt(1); }
2171 HValue* length() { return OperandAt(2); }
2172 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002173
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002174 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002175};
2176
2177
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002178class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002179 public:
2180 HArgumentsElements() {
2181 // The value produced by this instruction is a pointer into the stack
2182 // that looks as if it was a smi because of alignment.
2183 set_representation(Representation::Tagged());
2184 SetFlag(kUseGVN);
2185 }
2186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002187 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002189 virtual Representation RequiredInputRepresentation(int index) const {
2190 return Representation::None();
2191 }
2192
ager@chromium.org378b34e2011-01-28 08:04:38 +00002193 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002194 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195};
2196
2197
2198class HArgumentsLength: public HUnaryOperation {
2199 public:
2200 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2201 set_representation(Representation::Integer32());
2202 SetFlag(kUseGVN);
2203 }
2204
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002205 virtual Representation RequiredInputRepresentation(int index) const {
2206 return Representation::Tagged();
2207 }
2208
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002209 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002210
2211 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002212 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002213};
2214
2215
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002216class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002217 public:
2218 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2219 set_representation(Representation::Tagged());
2220 SetFlag(kUseGVN);
2221 SetOperandAt(0, arguments);
2222 SetOperandAt(1, length);
2223 SetOperandAt(2, index);
2224 }
2225
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002226 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227
2228 virtual Representation RequiredInputRepresentation(int index) const {
2229 // The arguments elements is considered tagged.
2230 return index == 0
2231 ? Representation::Tagged()
2232 : Representation::Integer32();
2233 }
2234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002235 HValue* arguments() { return OperandAt(0); }
2236 HValue* length() { return OperandAt(1); }
2237 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002238
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002239 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002240
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002241 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002242};
2243
2244
2245class HBoundsCheck: public HBinaryOperation {
2246 public:
2247 HBoundsCheck(HValue* index, HValue* length)
2248 : HBinaryOperation(index, length) {
2249 SetFlag(kUseGVN);
2250 }
2251
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002252 virtual bool IsCheckInstruction() const { return true; }
2253
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002254 virtual Representation RequiredInputRepresentation(int index) const {
2255 return Representation::Integer32();
2256 }
2257
2258#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002259 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002260#endif
2261
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002262 HValue* index() { return left(); }
2263 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002264
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002265 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002266
2267 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002268 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002269};
2270
2271
2272class HBitwiseBinaryOperation: public HBinaryOperation {
2273 public:
2274 HBitwiseBinaryOperation(HValue* left, HValue* right)
2275 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002276 set_representation(Representation::Tagged());
2277 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002278 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002279 }
2280
2281 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002282 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002283 }
2284
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002285 virtual void RepresentationChanged(Representation to) {
2286 if (!to.IsTagged()) {
2287 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002288 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002289 SetFlag(kTruncatingToInt32);
2290 SetFlag(kUseGVN);
2291 }
2292 }
2293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002294 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002295
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002296 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002297};
2298
2299
2300class HArithmeticBinaryOperation: public HBinaryOperation {
2301 public:
2302 HArithmeticBinaryOperation(HValue* left, HValue* right)
2303 : HBinaryOperation(left, right) {
2304 set_representation(Representation::Tagged());
2305 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002306 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002307 }
2308
2309 virtual void RepresentationChanged(Representation to) {
2310 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002311 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002312 SetFlag(kUseGVN);
2313 }
2314 }
2315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002316 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002317 virtual Representation RequiredInputRepresentation(int index) const {
2318 return representation();
2319 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002320 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002321 if (left()->representation().Equals(right()->representation())) {
2322 return left()->representation();
2323 }
2324 return HValue::InferredRepresentation();
2325 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002326};
2327
2328
2329class HCompare: public HBinaryOperation {
2330 public:
2331 HCompare(HValue* left, HValue* right, Token::Value token)
2332 : HBinaryOperation(left, right), token_(token) {
2333 ASSERT(Token::IsCompareOp(token));
2334 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002335 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336 }
2337
2338 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002339
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002340 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002341 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002342 }
2343
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002344 virtual Representation RequiredInputRepresentation(int index) const {
2345 return input_representation_;
2346 }
2347 Representation GetInputRepresentation() const {
2348 return input_representation_;
2349 }
2350 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002351 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002353 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002354
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002356 return HValue::Hashcode() * 7 + token_;
2357 }
2358
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002359 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002360
2361 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002362 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363 HCompare* comp = HCompare::cast(other);
2364 return token_ == comp->token();
2365 }
2366
2367 private:
2368 Representation input_representation_;
2369 Token::Value token_;
2370};
2371
2372
2373class HCompareJSObjectEq: public HBinaryOperation {
2374 public:
2375 HCompareJSObjectEq(HValue* left, HValue* right)
2376 : HBinaryOperation(left, right) {
2377 set_representation(Representation::Tagged());
2378 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002379 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002380 }
2381
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002382 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002383 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002384 }
2385
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002386 virtual Representation RequiredInputRepresentation(int index) const {
2387 return Representation::Tagged();
2388 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002389 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002390
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002391 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002392
2393 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002394 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002395};
2396
2397
2398class HUnaryPredicate: public HUnaryOperation {
2399 public:
2400 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2401 set_representation(Representation::Tagged());
2402 SetFlag(kUseGVN);
2403 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002404
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002405 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002406 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002407 }
2408
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409 virtual Representation RequiredInputRepresentation(int index) const {
2410 return Representation::Tagged();
2411 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002412 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002413};
2414
2415
2416class HIsNull: public HUnaryPredicate {
2417 public:
2418 HIsNull(HValue* value, bool is_strict)
2419 : HUnaryPredicate(value), is_strict_(is_strict) { }
2420
2421 bool is_strict() const { return is_strict_; }
2422
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002423 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002424
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002425 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002427 HIsNull* b = HIsNull::cast(other);
2428 return is_strict_ == b->is_strict();
2429 }
2430
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002431 private:
2432 bool is_strict_;
2433};
2434
2435
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002436class HIsObject: public HUnaryPredicate {
2437 public:
2438 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2439
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002440 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002441
2442 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002443 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002444};
2445
2446
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002447class HIsSmi: public HUnaryPredicate {
2448 public:
2449 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2450
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002451 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002452
2453 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002454 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455};
2456
2457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002458class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002459 public:
2460 HIsConstructCall() {
2461 set_representation(Representation::Tagged());
2462 SetFlag(kUseGVN);
2463 }
2464
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002465 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002466 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002467 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002469 virtual Representation RequiredInputRepresentation(int index) const {
2470 return Representation::None();
2471 }
2472
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002473 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002474
2475 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002476 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002477};
2478
2479
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480class HHasInstanceType: public HUnaryPredicate {
2481 public:
2482 HHasInstanceType(HValue* value, InstanceType type)
2483 : HUnaryPredicate(value), from_(type), to_(type) { }
2484 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2485 : HUnaryPredicate(value), from_(from), to_(to) {
2486 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2487 }
2488
2489 InstanceType from() { return from_; }
2490 InstanceType to() { return to_; }
2491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002492 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002493
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002494 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002495
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002496 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002497 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002498 HHasInstanceType* b = HHasInstanceType::cast(other);
2499 return (from_ == b->from()) && (to_ == b->to());
2500 }
2501
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002502 private:
2503 InstanceType from_;
2504 InstanceType to_; // Inclusive range, not all combinations work.
2505};
2506
2507
2508class HHasCachedArrayIndex: public HUnaryPredicate {
2509 public:
2510 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2511
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002512 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002513
2514 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002515 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516};
2517
2518
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002519class HGetCachedArrayIndex: public HUnaryPredicate {
2520 public:
2521 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2522
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002523 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002524
2525 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002526 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002527};
2528
2529
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002530class HClassOfTest: public HUnaryPredicate {
2531 public:
2532 HClassOfTest(HValue* value, Handle<String> class_name)
2533 : HUnaryPredicate(value), class_name_(class_name) { }
2534
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002535 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002537 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538
2539 Handle<String> class_name() const { return class_name_; }
2540
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002541 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002542 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002543 HClassOfTest* b = HClassOfTest::cast(other);
2544 return class_name_.is_identical_to(b->class_name_);
2545 }
2546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547 private:
2548 Handle<String> class_name_;
2549};
2550
2551
2552class HTypeofIs: public HUnaryPredicate {
2553 public:
2554 HTypeofIs(HValue* value, Handle<String> type_literal)
2555 : HUnaryPredicate(value), type_literal_(type_literal) { }
2556
2557 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002558 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002559
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002560 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002561
2562 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002563 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002564 HTypeofIs* b = HTypeofIs::cast(other);
2565 return type_literal_.is_identical_to(b->type_literal_);
2566 }
2567
2568 private:
2569 Handle<String> type_literal_;
2570};
2571
2572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002573class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002574 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002575 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2576 SetOperandAt(0, context);
2577 SetOperandAt(1, left);
2578 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002579 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002580 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581 }
2582
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002583 HValue* context() { return OperandAt(0); }
2584 HValue* left() { return OperandAt(1); }
2585 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002586
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002587 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002588 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002589 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002590
2591 virtual Representation RequiredInputRepresentation(int index) const {
2592 return Representation::Tagged();
2593 }
2594
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002595 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002596
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002597 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002598};
2599
2600
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002601class HInstanceOfKnownGlobal: public HUnaryOperation {
2602 public:
2603 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2604 : HUnaryOperation(left), function_(right) {
2605 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002606 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002607 }
2608
2609 Handle<JSFunction> function() { return function_; }
2610
2611 virtual Representation RequiredInputRepresentation(int index) const {
2612 return Representation::Tagged();
2613 }
2614
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002615 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002616
2617 private:
2618 Handle<JSFunction> function_;
2619};
2620
2621
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002622class HPower: public HBinaryOperation {
2623 public:
2624 HPower(HValue* left, HValue* right)
2625 : HBinaryOperation(left, right) {
2626 set_representation(Representation::Double());
2627 SetFlag(kUseGVN);
2628 }
2629
2630 virtual Representation RequiredInputRepresentation(int index) const {
2631 return (index == 1) ? Representation::None() : Representation::Double();
2632 }
2633
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002634 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002635
2636 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002637 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002638};
2639
2640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641class HAdd: public HArithmeticBinaryOperation {
2642 public:
2643 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2644 SetFlag(kCanOverflow);
2645 }
2646
2647 // Add is only commutative if two integer values are added and not if two
2648 // tagged values are added (because it might be a String concatenation).
2649 virtual bool IsCommutative() const {
2650 return !representation().IsTagged();
2651 }
2652
2653 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2654
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002655 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002656
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002657 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002658
2659 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002660 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002661
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002662 virtual Range* InferRange();
2663};
2664
2665
2666class HSub: public HArithmeticBinaryOperation {
2667 public:
2668 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2669 SetFlag(kCanOverflow);
2670 }
2671
2672 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2673
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002674 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002675
2676 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002677 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002678
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002679 virtual Range* InferRange();
2680};
2681
2682
2683class HMul: public HArithmeticBinaryOperation {
2684 public:
2685 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2686 SetFlag(kCanOverflow);
2687 }
2688
2689 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2690
2691 // Only commutative if it is certain that not two objects are multiplicated.
2692 virtual bool IsCommutative() const {
2693 return !representation().IsTagged();
2694 }
2695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002696 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002697
2698 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002699 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002700
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002701 virtual Range* InferRange();
2702};
2703
2704
2705class HMod: public HArithmeticBinaryOperation {
2706 public:
2707 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2708 SetFlag(kCanBeDivByZero);
2709 }
2710
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002711 bool HasPowerOf2Divisor() {
2712 if (right()->IsConstant() &&
2713 HConstant::cast(right())->HasInteger32Value()) {
2714 int32_t value = HConstant::cast(right())->Integer32Value();
2715 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2716 }
2717
2718 return false;
2719 }
2720
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2722
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002723 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724
2725 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002726 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002727
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002728 virtual Range* InferRange();
2729};
2730
2731
2732class HDiv: public HArithmeticBinaryOperation {
2733 public:
2734 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2735 SetFlag(kCanBeDivByZero);
2736 SetFlag(kCanOverflow);
2737 }
2738
2739 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2740
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002741 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002742
2743 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002744 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002745
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002746 virtual Range* InferRange();
2747};
2748
2749
2750class HBitAnd: public HBitwiseBinaryOperation {
2751 public:
2752 HBitAnd(HValue* left, HValue* right)
2753 : HBitwiseBinaryOperation(left, right) { }
2754
2755 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002756 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002758 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002759
2760 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002761 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002762
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002763 virtual Range* InferRange();
2764};
2765
2766
2767class HBitXor: public HBitwiseBinaryOperation {
2768 public:
2769 HBitXor(HValue* left, HValue* right)
2770 : HBitwiseBinaryOperation(left, right) { }
2771
2772 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002773 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002775 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002776
2777 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002778 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779};
2780
2781
2782class HBitOr: public HBitwiseBinaryOperation {
2783 public:
2784 HBitOr(HValue* left, HValue* right)
2785 : HBitwiseBinaryOperation(left, right) { }
2786
2787 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002788 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002790 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791
2792 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002793 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002794
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002795 virtual Range* InferRange();
2796};
2797
2798
2799class HShl: public HBitwiseBinaryOperation {
2800 public:
2801 HShl(HValue* left, HValue* right)
2802 : HBitwiseBinaryOperation(left, right) { }
2803
2804 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002805 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002807 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002808
2809 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002810 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811};
2812
2813
2814class HShr: public HBitwiseBinaryOperation {
2815 public:
2816 HShr(HValue* left, HValue* right)
2817 : HBitwiseBinaryOperation(left, right) { }
2818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002819 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002821 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002822
2823 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002824 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825};
2826
2827
2828class HSar: public HBitwiseBinaryOperation {
2829 public:
2830 HSar(HValue* left, HValue* right)
2831 : HBitwiseBinaryOperation(left, right) { }
2832
2833 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002834 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002836 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002837
2838 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002839 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002840};
2841
2842
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002843class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002844 public:
2845 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2846 SetFlag(kChangesOsrEntries);
2847 }
2848
2849 int ast_id() const { return ast_id_; }
2850
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002851 virtual Representation RequiredInputRepresentation(int index) const {
2852 return Representation::None();
2853 }
2854
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002855 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002856
2857 private:
2858 int ast_id_;
2859};
2860
2861
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002862class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863 public:
2864 explicit HParameter(unsigned index) : index_(index) {
2865 set_representation(Representation::Tagged());
2866 }
2867
2868 unsigned index() const { return index_; }
2869
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002870 virtual void PrintDataTo(StringStream* stream);
2871
2872 virtual Representation RequiredInputRepresentation(int index) const {
2873 return Representation::None();
2874 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002875
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002876 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002877
2878 private:
2879 unsigned index_;
2880};
2881
2882
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002883class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002884 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002885 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2886 : HUnaryCall(context, argument_count),
2887 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002888 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002889 }
2890
2891 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002892
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002893 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002894
2895 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2896 transcendental_type_ = transcendental_type;
2897 }
2898 TranscendentalCache::Type transcendental_type() {
2899 return transcendental_type_;
2900 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002901
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002902 virtual void PrintDataTo(StringStream* stream);
2903
2904 virtual Representation RequiredInputRepresentation(int index) const {
2905 return Representation::Tagged();
2906 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002908 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002909
2910 private:
2911 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002912 TranscendentalCache::Type transcendental_type_;
2913};
2914
2915
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002916class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917 public:
2918 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2919
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002920 virtual Representation RequiredInputRepresentation(int index) const {
2921 return Representation::None();
2922 }
2923
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002924 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925};
2926
2927
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002928class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002929 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002930 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 : cell_(cell), check_hole_value_(check_hole_value) {
2932 set_representation(Representation::Tagged());
2933 SetFlag(kUseGVN);
2934 SetFlag(kDependsOnGlobalVars);
2935 }
2936
2937 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2938 bool check_hole_value() const { return check_hole_value_; }
2939
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002940 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002941
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002942 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002943 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944 return reinterpret_cast<intptr_t>(*cell_);
2945 }
2946
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002947 virtual Representation RequiredInputRepresentation(int index) const {
2948 return Representation::None();
2949 }
2950
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002951 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002952
2953 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002954 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002955 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956 return cell_.is_identical_to(b->cell());
2957 }
2958
2959 private:
2960 Handle<JSGlobalPropertyCell> cell_;
2961 bool check_hole_value_;
2962};
2963
2964
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002965class HLoadGlobalGeneric: public HBinaryOperation {
2966 public:
2967 HLoadGlobalGeneric(HValue* context,
2968 HValue* global_object,
2969 Handle<Object> name,
2970 bool for_typeof)
2971 : HBinaryOperation(context, global_object),
2972 name_(name),
2973 for_typeof_(for_typeof) {
2974 set_representation(Representation::Tagged());
2975 SetAllSideEffects();
2976 }
2977
2978 HValue* context() { return OperandAt(0); }
2979 HValue* global_object() { return OperandAt(1); }
2980 Handle<Object> name() const { return name_; }
2981 bool for_typeof() const { return for_typeof_; }
2982
2983 virtual void PrintDataTo(StringStream* stream);
2984
2985 virtual Representation RequiredInputRepresentation(int index) const {
2986 return Representation::Tagged();
2987 }
2988
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002989 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002990
2991 private:
2992 Handle<Object> name_;
2993 bool for_typeof_;
2994};
2995
2996
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002997class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002999 HStoreGlobalCell(HValue* value,
3000 Handle<JSGlobalPropertyCell> cell,
3001 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003002 : HUnaryOperation(value),
3003 cell_(cell),
3004 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005 SetFlag(kChangesGlobalVars);
3006 }
3007
3008 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003009 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010
3011 virtual Representation RequiredInputRepresentation(int index) const {
3012 return Representation::Tagged();
3013 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003016 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018 private:
3019 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003020 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021};
3022
3023
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003024class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3025 public:
3026 HStoreGlobalGeneric(HValue* context,
3027 HValue* global_object,
3028 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003029 HValue* value,
3030 bool strict_mode)
3031 : name_(name),
3032 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003033 SetOperandAt(0, context);
3034 SetOperandAt(1, global_object);
3035 SetOperandAt(2, value);
3036 set_representation(Representation::Tagged());
3037 SetAllSideEffects();
3038 }
3039
3040 HValue* context() { return OperandAt(0); }
3041 HValue* global_object() { return OperandAt(1); }
3042 Handle<Object> name() const { return name_; }
3043 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003044 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003045
3046 virtual void PrintDataTo(StringStream* stream);
3047
3048 virtual Representation RequiredInputRepresentation(int index) const {
3049 return Representation::Tagged();
3050 }
3051
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003052 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003053
3054 private:
3055 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003056 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003057};
3058
3059
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003060class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003061 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003062 HLoadContextSlot(HValue* context , int slot_index)
3063 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003064 set_representation(Representation::Tagged());
3065 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003066 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003067 }
3068
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003069 int slot_index() const { return slot_index_; }
3070
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003071 virtual Representation RequiredInputRepresentation(int index) const {
3072 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003073 }
3074
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003075 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003076
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003077 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003078
3079 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003080 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003081 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003082 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003083 }
3084
3085 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003086 int slot_index_;
3087};
3088
3089
3090static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3091 return !value->type().IsSmi() &&
3092 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3093}
3094
3095
3096class HStoreContextSlot: public HBinaryOperation {
3097 public:
3098 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3099 : HBinaryOperation(context, value), slot_index_(slot_index) {
3100 SetFlag(kChangesContextSlots);
3101 }
3102
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003103 HValue* context() { return OperandAt(0); }
3104 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003105 int slot_index() const { return slot_index_; }
3106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003107 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003108 return StoringValueNeedsWriteBarrier(value());
3109 }
3110
3111 virtual Representation RequiredInputRepresentation(int index) const {
3112 return Representation::Tagged();
3113 }
3114
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003115 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003116
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003117 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003118
3119 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003120 int slot_index_;
3121};
3122
3123
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124class HLoadNamedField: public HUnaryOperation {
3125 public:
3126 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3127 : HUnaryOperation(object),
3128 is_in_object_(is_in_object),
3129 offset_(offset) {
3130 set_representation(Representation::Tagged());
3131 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003132 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133 if (is_in_object) {
3134 SetFlag(kDependsOnInobjectFields);
3135 } else {
3136 SetFlag(kDependsOnBackingStoreFields);
3137 }
3138 }
3139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141 bool is_in_object() const { return is_in_object_; }
3142 int offset() const { return offset_; }
3143
3144 virtual Representation RequiredInputRepresentation(int index) const {
3145 return Representation::Tagged();
3146 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003147 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003149 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003150
3151 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003152 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003153 HLoadNamedField* b = HLoadNamedField::cast(other);
3154 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3155 }
3156
3157 private:
3158 bool is_in_object_;
3159 int offset_;
3160};
3161
3162
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003163class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3164 public:
3165 HLoadNamedFieldPolymorphic(HValue* object,
3166 ZoneMapList* types,
3167 Handle<String> name);
3168
3169 HValue* object() { return OperandAt(0); }
3170 ZoneMapList* types() { return &types_; }
3171 Handle<String> name() { return name_; }
3172 bool need_generic() { return need_generic_; }
3173
3174 virtual Representation RequiredInputRepresentation(int index) const {
3175 return Representation::Tagged();
3176 }
3177
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003178 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003179
3180 static const int kMaxLoadPolymorphism = 4;
3181
3182 protected:
3183 virtual bool DataEquals(HValue* value);
3184
3185 private:
3186 ZoneMapList types_;
3187 Handle<String> name_;
3188 bool need_generic_;
3189};
3190
3191
3192
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003193class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003195 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3196 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003198 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199 }
3200
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003201 HValue* context() { return OperandAt(0); }
3202 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203 Handle<Object> name() const { return name_; }
3204
3205 virtual Representation RequiredInputRepresentation(int index) const {
3206 return Representation::Tagged();
3207 }
3208
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003209 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003210
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211 private:
3212 Handle<Object> name_;
3213};
3214
3215
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003216class HLoadFunctionPrototype: public HUnaryOperation {
3217 public:
3218 explicit HLoadFunctionPrototype(HValue* function)
3219 : HUnaryOperation(function) {
3220 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003221 SetFlag(kUseGVN);
3222 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003223 }
3224
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003225 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003226
3227 virtual Representation RequiredInputRepresentation(int index) const {
3228 return Representation::Tagged();
3229 }
3230
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003231 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003232
3233 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003234 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003235};
3236
3237
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003238class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003239 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003240 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003241 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003242 SetFlag(kDependsOnArrayElements);
3243 SetFlag(kUseGVN);
3244 }
3245
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003246 HValue* object() { return OperandAt(0); }
3247 HValue* key() { return OperandAt(1); }
3248
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003249 virtual Representation RequiredInputRepresentation(int index) const {
3250 // The key is supposed to be Integer32.
3251 return (index == 1) ? Representation::Integer32()
3252 : Representation::Tagged();
3253 }
3254
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003255 virtual void PrintDataTo(StringStream* stream);
3256
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003257 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003258
3259 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003260 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261};
3262
3263
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003264class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003265 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003266 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3267 HValue* key,
3268 ExternalArrayType array_type)
3269 : HBinaryOperation(external_elements, key),
3270 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003271 if (array_type == kExternalFloatArray ||
3272 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003273 set_representation(Representation::Double());
3274 } else {
3275 set_representation(Representation::Integer32());
3276 }
3277 SetFlag(kDependsOnSpecializedArrayElements);
3278 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003279 SetFlag(kDependsOnCalls);
3280 SetFlag(kUseGVN);
3281 }
3282
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003283 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003284
3285 virtual Representation RequiredInputRepresentation(int index) const {
3286 // The key is supposed to be Integer32, but the base pointer
3287 // for the element load is a naked pointer.
3288 return (index == 1) ? Representation::Integer32()
3289 : Representation::External();
3290 }
3291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003292 HValue* external_pointer() { return OperandAt(0); }
3293 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003294 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003295
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003296 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003297
3298 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003299 virtual bool DataEquals(HValue* other) {
3300 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3301 HLoadKeyedSpecializedArrayElement* cast_other =
3302 HLoadKeyedSpecializedArrayElement::cast(other);
3303 return array_type_ == cast_other->array_type();
3304 }
3305
3306 private:
3307 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003308};
3309
3310
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003311class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003312 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003313 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3314 set_representation(Representation::Tagged());
3315 SetOperandAt(0, obj);
3316 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003317 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003318 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319 }
3320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003321 HValue* object() { return OperandAt(0); }
3322 HValue* key() { return OperandAt(1); }
3323 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003324
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003325 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003326
3327 virtual Representation RequiredInputRepresentation(int index) const {
3328 return Representation::Tagged();
3329 }
3330
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003331 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003332};
3333
3334
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003335class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003336 public:
3337 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003338 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003339 HValue* val,
3340 bool in_object,
3341 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003342 : HBinaryOperation(obj, val),
3343 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003344 is_in_object_(in_object),
3345 offset_(offset) {
3346 if (is_in_object_) {
3347 SetFlag(kChangesInobjectFields);
3348 } else {
3349 SetFlag(kChangesBackingStoreFields);
3350 }
3351 }
3352
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003353 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003354
3355 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003356 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003357 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003360 HValue* object() { return OperandAt(0); }
3361 HValue* value() { return OperandAt(1); }
3362
3363 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003364 bool is_in_object() const { return is_in_object_; }
3365 int offset() const { return offset_; }
3366 Handle<Map> transition() const { return transition_; }
3367 void set_transition(Handle<Map> map) { transition_ = map; }
3368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003369 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003370 return StoringValueNeedsWriteBarrier(value());
3371 }
3372
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003373 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003374 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003375 bool is_in_object_;
3376 int offset_;
3377 Handle<Map> transition_;
3378};
3379
3380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003381class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003382 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003383 HStoreNamedGeneric(HValue* context,
3384 HValue* object,
3385 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003386 HValue* value,
3387 bool strict_mode)
3388 : name_(name),
3389 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003390 SetOperandAt(0, object);
3391 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003392 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003393 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394 }
3395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003396 HValue* object() { return OperandAt(0); }
3397 HValue* value() { return OperandAt(1); }
3398 HValue* context() { return OperandAt(2); }
3399 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003400 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003401
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003402 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403
3404 virtual Representation RequiredInputRepresentation(int index) const {
3405 return Representation::Tagged();
3406 }
3407
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003408 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003410 private:
3411 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003412 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003413};
3414
3415
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003416class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003417 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003418 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3419 SetOperandAt(0, obj);
3420 SetOperandAt(1, key);
3421 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003422 SetFlag(kChangesArrayElements);
3423 }
3424
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003425 virtual Representation RequiredInputRepresentation(int index) const {
3426 // The key is supposed to be Integer32.
3427 return (index == 1) ? Representation::Integer32()
3428 : Representation::Tagged();
3429 }
3430
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003431 HValue* object() { return OperandAt(0); }
3432 HValue* key() { return OperandAt(1); }
3433 HValue* value() { return OperandAt(2); }
3434
3435 bool NeedsWriteBarrier() {
3436 return StoringValueNeedsWriteBarrier(value());
3437 }
3438
3439 virtual void PrintDataTo(StringStream* stream);
3440
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003441 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003442};
3443
3444
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003445class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003446 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003447 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3448 HValue* key,
3449 HValue* val,
3450 ExternalArrayType array_type)
3451 : array_type_(array_type) {
3452 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003453 SetOperandAt(0, external_elements);
3454 SetOperandAt(1, key);
3455 SetOperandAt(2, val);
3456 }
3457
3458 virtual void PrintDataTo(StringStream* stream);
3459
3460 virtual Representation RequiredInputRepresentation(int index) const {
3461 if (index == 0) {
3462 return Representation::External();
3463 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003464 if (index == 2 && (array_type() == kExternalFloatArray ||
3465 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003466 return Representation::Double();
3467 } else {
3468 return Representation::Integer32();
3469 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003470 }
3471 }
3472
3473 HValue* external_pointer() { return OperandAt(0); }
3474 HValue* key() { return OperandAt(1); }
3475 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003476 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003477
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003478 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3479
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003480 private:
3481 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003482};
3483
3484
3485class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003486 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003487 HStoreKeyedGeneric(HValue* context,
3488 HValue* object,
3489 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003490 HValue* value,
3491 bool strict_mode)
3492 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003493 SetOperandAt(0, object);
3494 SetOperandAt(1, key);
3495 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003496 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003497 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003498 }
3499
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003500 HValue* object() { return OperandAt(0); }
3501 HValue* key() { return OperandAt(1); }
3502 HValue* value() { return OperandAt(2); }
3503 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003504 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003505
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003506 virtual Representation RequiredInputRepresentation(int index) const {
3507 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003508 }
3509
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003510 virtual void PrintDataTo(StringStream* stream);
3511
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003512 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003513
3514 private:
3515 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516};
3517
3518
danno@chromium.org160a7b02011-04-18 15:51:38 +00003519class HStringAdd: public HBinaryOperation {
3520 public:
3521 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3522 set_representation(Representation::Tagged());
3523 SetFlag(kUseGVN);
3524 SetFlag(kDependsOnMaps);
3525 }
3526
3527 virtual Representation RequiredInputRepresentation(int index) const {
3528 return Representation::Tagged();
3529 }
3530
3531 virtual HType CalculateInferredType() {
3532 return HType::String();
3533 }
3534
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003535 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003536
3537 protected:
3538 virtual bool DataEquals(HValue* other) { return true; }
3539};
3540
3541
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003542class HStringCharCodeAt: public HBinaryOperation {
3543 public:
3544 HStringCharCodeAt(HValue* string, HValue* index)
3545 : HBinaryOperation(string, index) {
3546 set_representation(Representation::Integer32());
3547 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003548 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003549 }
3550
3551 virtual Representation RequiredInputRepresentation(int index) const {
3552 // The index is supposed to be Integer32.
3553 return (index == 1) ? Representation::Integer32()
3554 : Representation::Tagged();
3555 }
3556
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003557 HValue* string() { return OperandAt(0); }
3558 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003559
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003560 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003561
3562 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003563 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003564
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003565 virtual Range* InferRange() {
3566 return new Range(0, String::kMaxUC16CharCode);
3567 }
3568};
3569
3570
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003571class HStringCharFromCode: public HUnaryOperation {
3572 public:
3573 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3574 set_representation(Representation::Tagged());
3575 SetFlag(kUseGVN);
3576 }
3577
3578 virtual Representation RequiredInputRepresentation(int index) const {
3579 return Representation::Integer32();
3580 }
3581
3582 virtual bool DataEquals(HValue* other) { return true; }
3583
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003584 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003585};
3586
3587
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003588class HStringLength: public HUnaryOperation {
3589 public:
3590 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3591 set_representation(Representation::Tagged());
3592 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003593 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003594 }
3595
3596 virtual Representation RequiredInputRepresentation(int index) const {
3597 return Representation::Tagged();
3598 }
3599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003600 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003601 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3602 return HType::Smi();
3603 }
3604
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003605 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003606
3607 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003608 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003609
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003610 virtual Range* InferRange() {
3611 return new Range(0, String::kMaxLength);
3612 }
3613};
3614
3615
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003616template <int V>
3617class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003619 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003621 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003622 }
3623
3624 int literal_index() const { return literal_index_; }
3625 int depth() const { return depth_; }
3626
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003627 private:
3628 int literal_index_;
3629 int depth_;
3630};
3631
3632
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003633class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634 public:
3635 HArrayLiteral(Handle<FixedArray> constant_elements,
3636 int length,
3637 int literal_index,
3638 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003639 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003640 length_(length),
3641 constant_elements_(constant_elements) {}
3642
3643 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3644 int length() const { return length_; }
3645
3646 bool IsCopyOnWrite() const;
3647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 virtual Representation RequiredInputRepresentation(int index) const {
3649 return Representation::None();
3650 }
3651
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003652 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653
3654 private:
3655 int length_;
3656 Handle<FixedArray> constant_elements_;
3657};
3658
3659
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003660class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003662 HObjectLiteral(HValue* context,
3663 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003664 bool fast_elements,
3665 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003666 int depth,
3667 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003668 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003669 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003670 fast_elements_(fast_elements),
3671 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003672 SetOperandAt(0, context);
3673 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003674
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003675 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003676 Handle<FixedArray> constant_properties() const {
3677 return constant_properties_;
3678 }
3679 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003680 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003681
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003682 virtual Representation RequiredInputRepresentation(int index) const {
3683 return Representation::Tagged();
3684 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003685
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003686 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003687
3688 private:
3689 Handle<FixedArray> constant_properties_;
3690 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003691 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003692};
3693
3694
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003695class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003696 public:
3697 HRegExpLiteral(Handle<String> pattern,
3698 Handle<String> flags,
3699 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003700 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701 pattern_(pattern),
3702 flags_(flags) { }
3703
3704 Handle<String> pattern() { return pattern_; }
3705 Handle<String> flags() { return flags_; }
3706
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003707 virtual Representation RequiredInputRepresentation(int index) const {
3708 return Representation::None();
3709 }
3710
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003711 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003712
3713 private:
3714 Handle<String> pattern_;
3715 Handle<String> flags_;
3716};
3717
3718
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003719class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003720 public:
3721 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3722 : shared_info_(shared), pretenure_(pretenure) {
3723 set_representation(Representation::Tagged());
3724 }
3725
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003726 virtual Representation RequiredInputRepresentation(int index) const {
3727 return Representation::None();
3728 }
3729
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003730 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731
3732 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3733 bool pretenure() const { return pretenure_; }
3734
3735 private:
3736 Handle<SharedFunctionInfo> shared_info_;
3737 bool pretenure_;
3738};
3739
3740
3741class HTypeof: public HUnaryOperation {
3742 public:
3743 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3744 set_representation(Representation::Tagged());
3745 }
3746
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003747 virtual Representation RequiredInputRepresentation(int index) const {
3748 return Representation::Tagged();
3749 }
3750
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003751 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003752};
3753
3754
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003755class HToFastProperties: public HUnaryOperation {
3756 public:
3757 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3758 // This instruction is not marked as having side effects, but
3759 // changes the map of the input operand. Use it only when creating
3760 // object literals.
3761 ASSERT(value->IsObjectLiteral());
3762 set_representation(Representation::Tagged());
3763 }
3764
3765 virtual Representation RequiredInputRepresentation(int index) const {
3766 return Representation::Tagged();
3767 }
3768
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003769 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003770};
3771
3772
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003773class HValueOf: public HUnaryOperation {
3774 public:
3775 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3776 set_representation(Representation::Tagged());
3777 }
3778
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003779 virtual Representation RequiredInputRepresentation(int index) const {
3780 return Representation::Tagged();
3781 }
3782
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003783 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003784};
3785
3786
3787class HDeleteProperty: public HBinaryOperation {
3788 public:
3789 HDeleteProperty(HValue* obj, HValue* key)
3790 : HBinaryOperation(obj, key) {
3791 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003792 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003793 }
3794
3795 virtual Representation RequiredInputRepresentation(int index) const {
3796 return Representation::Tagged();
3797 }
3798
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003799 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003801 HValue* object() { return left(); }
3802 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003803};
3804
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003805
3806class HIn: public HTemplateInstruction<2> {
3807 public:
3808 HIn(HValue* key, HValue* object) {
3809 SetOperandAt(0, key);
3810 SetOperandAt(1, object);
3811 set_representation(Representation::Tagged());
3812 SetAllSideEffects();
3813 }
3814
3815 HValue* key() { return OperandAt(0); }
3816 HValue* object() { return OperandAt(1); }
3817
3818 virtual Representation RequiredInputRepresentation(int index) const {
3819 return Representation::Tagged();
3820 }
3821
3822 virtual HType CalculateInferredType() {
3823 return HType::Boolean();
3824 }
3825
3826 virtual void PrintDataTo(StringStream* stream);
3827
3828 DECLARE_CONCRETE_INSTRUCTION(In)
3829};
3830
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831#undef DECLARE_INSTRUCTION
3832#undef DECLARE_CONCRETE_INSTRUCTION
3833
3834} } // namespace v8::internal
3835
3836#endif // V8_HYDROGEN_INSTRUCTIONS_H_