blob: 15186ff264a750a5b2ef90012ae9834c810ef946 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
48class HInstruction;
49class HLoopInformation;
50class HValue;
51class LInstruction;
52class LChunkBuilder;
53
54
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000055#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 V(ControlInstruction) \
58 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059
60
61#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000062 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000063 V(AccessArgumentsAt) \
64 V(Add) \
65 V(ApplyArguments) \
66 V(ArgumentsElements) \
67 V(ArgumentsLength) \
68 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ArrayLiteral) \
70 V(BitAnd) \
71 V(BitNot) \
72 V(BitOr) \
73 V(BitXor) \
74 V(BlockEntry) \
75 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000076 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000077 V(CallConstantFunction) \
78 V(CallFunction) \
79 V(CallGlobal) \
80 V(CallKeyed) \
81 V(CallKnownGlobal) \
82 V(CallNamed) \
83 V(CallNew) \
84 V(CallRuntime) \
85 V(CallStub) \
86 V(Change) \
87 V(CheckFunction) \
88 V(CheckInstanceType) \
89 V(CheckMap) \
90 V(CheckNonSmi) \
91 V(CheckPrototypeMaps) \
92 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000093 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000094 V(ClassOfTestAndBranch) \
95 V(CompareIDAndBranch) \
96 V(CompareGeneric) \
97 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000098 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000099 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000101 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000105 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000107 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000108 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000109 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000111 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(GlobalObject) \
113 V(GlobalReceiver) \
114 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000115 V(HasCachedArrayIndexAndBranch) \
116 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000117 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000119 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000120 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000121 V(IsConstructCallAndBranch) \
122 V(IsNullAndBranch) \
123 V(IsObjectAndBranch) \
124 V(IsSmiAndBranch) \
125 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000126 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000128 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000130 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000131 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000132 V(LoadGlobalCell) \
133 V(LoadGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000134 V(LoadKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(LoadKeyedFastElement) \
136 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000137 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000139 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000140 V(LoadNamedGeneric) \
141 V(Mod) \
142 V(Mul) \
143 V(ObjectLiteral) \
144 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000145 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000146 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000147 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000148 V(PushArgument) \
149 V(RegExpLiteral) \
150 V(Return) \
151 V(Sar) \
152 V(Shl) \
153 V(Shr) \
154 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000155 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000157 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000158 V(StoreGlobalCell) \
159 V(StoreGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000160 V(StoreKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 V(StoreKeyedFastElement) \
162 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000163 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000164 V(StoreNamedField) \
165 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000166 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000167 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000168 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000169 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000171 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000172 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000173 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000174 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000176 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000177 V(UnaryMathOperation) \
178 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000179 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000180 V(ValueOf)
181
182#define GVN_FLAG_LIST(V) \
183 V(Calls) \
184 V(InobjectFields) \
185 V(BackingStoreFields) \
186 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000187 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 V(GlobalVars) \
189 V(Maps) \
190 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000191 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192 V(OsrEntries)
193
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000194#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195 virtual bool Is##type() const { return true; } \
196 static H##type* cast(HValue* value) { \
197 ASSERT(value->Is##type()); \
198 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000199 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
201
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000202#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000204 static H##type* cast(HValue* value) { \
205 ASSERT(value->Is##type()); \
206 return reinterpret_cast<H##type*>(value); \
207 } \
208 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209
210
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211class Range: public ZoneObject {
212 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000213 Range()
214 : lower_(kMinInt),
215 upper_(kMaxInt),
216 next_(NULL),
217 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218
219 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000220 : lower_(lower),
221 upper_(upper),
222 next_(NULL),
223 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 int32_t upper() const { return upper_; }
226 int32_t lower() const { return lower_; }
227 Range* next() const { return next_; }
228 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
229 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 int32_t Mask() const;
232 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
233 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
234 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
235 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000236 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
237 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
238 bool IsInSmiRange() const {
239 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000240 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000241 void KeepOrder();
242 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000243
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244 void StackUpon(Range* other) {
245 Intersect(other);
246 next_ = other;
247 }
248
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000249 void Intersect(Range* other);
250 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000251
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000252 void AddConstant(int32_t value);
253 void Sar(int32_t value);
254 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 bool AddAndCheckOverflow(Range* other);
256 bool SubAndCheckOverflow(Range* other);
257 bool MulAndCheckOverflow(Range* other);
258
259 private:
260 int32_t lower_;
261 int32_t upper_;
262 Range* next_;
263 bool can_be_minus_zero_;
264};
265
266
267class Representation {
268 public:
269 enum Kind {
270 kNone,
271 kTagged,
272 kDouble,
273 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000274 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000275 kNumRepresentations
276 };
277
278 Representation() : kind_(kNone) { }
279
280 static Representation None() { return Representation(kNone); }
281 static Representation Tagged() { return Representation(kTagged); }
282 static Representation Integer32() { return Representation(kInteger32); }
283 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000284 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000286 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000287 return kind_ == other.kind_;
288 }
289
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000290 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291 bool IsNone() const { return kind_ == kNone; }
292 bool IsTagged() const { return kind_ == kTagged; }
293 bool IsInteger32() const { return kind_ == kInteger32; }
294 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000295 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000296 bool IsSpecialization() const {
297 return kind_ == kInteger32 || kind_ == kDouble;
298 }
299 const char* Mnemonic() const;
300
301 private:
302 explicit Representation(Kind k) : kind_(k) { }
303
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000304 // Make sure kind fits in int8.
305 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
306
307 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000308};
309
310
311class HType {
312 public:
313 HType() : type_(kUninitialized) { }
314
315 static HType Tagged() { return HType(kTagged); }
316 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
317 static HType TaggedNumber() { return HType(kTaggedNumber); }
318 static HType Smi() { return HType(kSmi); }
319 static HType HeapNumber() { return HType(kHeapNumber); }
320 static HType String() { return HType(kString); }
321 static HType Boolean() { return HType(kBoolean); }
322 static HType NonPrimitive() { return HType(kNonPrimitive); }
323 static HType JSArray() { return HType(kJSArray); }
324 static HType JSObject() { return HType(kJSObject); }
325 static HType Uninitialized() { return HType(kUninitialized); }
326
327 // Return the weakest (least precise) common type.
328 HType Combine(HType other) {
329 return HType(static_cast<Type>(type_ & other.type_));
330 }
331
332 bool Equals(const HType& other) {
333 return type_ == other.type_;
334 }
335
336 bool IsSubtypeOf(const HType& other) {
337 return Combine(other).Equals(other);
338 }
339
340 bool IsTagged() {
341 ASSERT(type_ != kUninitialized);
342 return ((type_ & kTagged) == kTagged);
343 }
344
345 bool IsTaggedPrimitive() {
346 ASSERT(type_ != kUninitialized);
347 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
348 }
349
350 bool IsTaggedNumber() {
351 ASSERT(type_ != kUninitialized);
352 return ((type_ & kTaggedNumber) == kTaggedNumber);
353 }
354
355 bool IsSmi() {
356 ASSERT(type_ != kUninitialized);
357 return ((type_ & kSmi) == kSmi);
358 }
359
360 bool IsHeapNumber() {
361 ASSERT(type_ != kUninitialized);
362 return ((type_ & kHeapNumber) == kHeapNumber);
363 }
364
365 bool IsString() {
366 ASSERT(type_ != kUninitialized);
367 return ((type_ & kString) == kString);
368 }
369
370 bool IsBoolean() {
371 ASSERT(type_ != kUninitialized);
372 return ((type_ & kBoolean) == kBoolean);
373 }
374
375 bool IsNonPrimitive() {
376 ASSERT(type_ != kUninitialized);
377 return ((type_ & kNonPrimitive) == kNonPrimitive);
378 }
379
380 bool IsJSArray() {
381 ASSERT(type_ != kUninitialized);
382 return ((type_ & kJSArray) == kJSArray);
383 }
384
385 bool IsJSObject() {
386 ASSERT(type_ != kUninitialized);
387 return ((type_ & kJSObject) == kJSObject);
388 }
389
390 bool IsUninitialized() {
391 return type_ == kUninitialized;
392 }
393
394 static HType TypeFromValue(Handle<Object> value);
395
396 const char* ToString();
397 const char* ToShortString();
398
399 private:
400 enum Type {
401 kTagged = 0x1, // 0000 0000 0000 0001
402 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
403 kTaggedNumber = 0xd, // 0000 0000 0000 1101
404 kSmi = 0x1d, // 0000 0000 0001 1101
405 kHeapNumber = 0x2d, // 0000 0000 0010 1101
406 kString = 0x45, // 0000 0000 0100 0101
407 kBoolean = 0x85, // 0000 0000 1000 0101
408 kNonPrimitive = 0x101, // 0000 0001 0000 0001
409 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000410 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000411 kUninitialized = 0x1fff // 0001 1111 1111 1111
412 };
413
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000414 // Make sure type fits in int16.
415 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
416
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000417 explicit HType(Type t) : type_(t) { }
418
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000419 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000420};
421
422
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000423class HUseListNode: public ZoneObject {
424 public:
425 HUseListNode(HValue* value, int index, HUseListNode* tail)
426 : tail_(tail), value_(value), index_(index) {
427 }
428
429 HUseListNode* tail() const { return tail_; }
430 HValue* value() const { return value_; }
431 int index() const { return index_; }
432
433 void set_tail(HUseListNode* list) { tail_ = list; }
434
435#ifdef DEBUG
436 void Zap() {
437 tail_ = reinterpret_cast<HUseListNode*>(1);
438 value_ = NULL;
439 index_ = -1;
440 }
441#endif
442
443 private:
444 HUseListNode* tail_;
445 HValue* value_;
446 int index_;
447};
448
449
450// We reuse use list nodes behind the scenes as uses are added and deleted.
451// This class is the safe way to iterate uses while deleting them.
452class HUseIterator BASE_EMBEDDED {
453 public:
454 bool Done() { return current_ == NULL; }
455 void Advance();
456
457 HValue* value() {
458 ASSERT(!Done());
459 return value_;
460 }
461
462 int index() {
463 ASSERT(!Done());
464 return index_;
465 }
466
467 private:
468 explicit HUseIterator(HUseListNode* head);
469
470 HUseListNode* current_;
471 HUseListNode* next_;
472 HValue* value_;
473 int index_;
474
475 friend class HValue;
476};
477
478
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479class HValue: public ZoneObject {
480 public:
481 static const int kNoNumber = -1;
482
483 // There must be one corresponding kDepends flag for every kChanges flag and
484 // the order of the kChanges flags must be exactly the same as of the kDepends
485 // flags.
486 enum Flag {
487 // Declare global value numbering flags.
488 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
489 GVN_FLAG_LIST(DECLARE_DO)
490 #undef DECLARE_DO
491 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000492 // Participate in Global Value Numbering, i.e. elimination of
493 // unnecessary recomputations. If an instruction sets this flag, it must
494 // implement DataEquals(), which will be used to determine if other
495 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000496 kUseGVN,
497 kCanOverflow,
498 kBailoutOnMinusZero,
499 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000500 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000501 kIsArguments,
502 kTruncatingToInt32,
503 kLastFlag = kTruncatingToInt32
504 };
505
506 STATIC_ASSERT(kLastFlag < kBitsPerInt);
507
508 static const int kChangesToDependsFlagsLeftShift = 1;
509
510 static int ChangesFlagsMask() {
511 int result = 0;
512 // Create changes mask.
513#define DECLARE_DO(type) result |= (1 << kChanges##type);
514 GVN_FLAG_LIST(DECLARE_DO)
515#undef DECLARE_DO
516 return result;
517 }
518
519 static int DependsFlagsMask() {
520 return ConvertChangesToDependsFlags(ChangesFlagsMask());
521 }
522
523 static int ConvertChangesToDependsFlags(int flags) {
524 return flags << kChangesToDependsFlagsLeftShift;
525 }
526
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000527 static HValue* cast(HValue* value) { return value; }
528
529 enum Opcode {
530 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000531 #define DECLARE_OPCODE(type) k##type,
532 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
533 kPhi
534 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000535 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000536 virtual Opcode opcode() const = 0;
537
538 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
539 #define DECLARE_PREDICATE(type) \
540 bool Is##type() const { return opcode() == k##type; }
541 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
542 #undef DECLARE_PREDICATE
543 bool IsPhi() const { return opcode() == kPhi; }
544
545 // Declare virtual predicates for abstract HInstruction or HValue
546 #define DECLARE_PREDICATE(type) \
547 virtual bool Is##type() const { return false; }
548 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
549 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000550
551 HValue() : block_(NULL),
552 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000554 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000555 range_(NULL),
556 flags_(0) {}
557 virtual ~HValue() {}
558
559 HBasicBlock* block() const { return block_; }
560 void SetBlock(HBasicBlock* block);
561
562 int id() const { return id_; }
563 void set_id(int id) { id_ = id; }
564
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000565 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000567 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568 Representation representation() const { return representation_; }
569 void ChangeRepresentation(Representation r) {
570 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571 ASSERT(!r.IsNone());
572 ASSERT(CheckFlag(kFlexibleRepresentation));
573 RepresentationChanged(r);
574 representation_ = r;
575 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000576 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000578 virtual bool IsConvertibleToInteger() const { return true; }
579
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000580 HType type() const { return type_; }
581 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000582 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000583 type_ = type;
584 }
585
586 // An operation needs to override this function iff:
587 // 1) it can produce an int32 output.
588 // 2) the true value of its output can potentially be minus zero.
589 // The implementation must set a flag so that it bails out in the case where
590 // it would otherwise output what should be a minus zero as an int32 zero.
591 // If the operation also exists in a form that takes int32 and outputs int32
592 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000593 // back. There are three operations that need to propagate back to more than
594 // one input. They are phi and binary div and mul. They always return NULL
595 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000596 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
597 visited->Add(id());
598 return NULL;
599 }
600
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000601 bool IsDefinedAfter(HBasicBlock* other) const;
602
603 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000604 virtual int OperandCount() = 0;
605 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000606 void SetOperandAt(int index, HValue* value);
607
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000608 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000609 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000610 bool HasNoUses() const { return use_list_ == NULL; }
611 bool HasMultipleUses() const {
612 return use_list_ != NULL && use_list_->tail() != NULL;
613 }
614 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000615 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000616
617 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000618 void SetFlag(Flag f) { flags_ |= (1 << f); }
619 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
620 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
621
622 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
623 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
624 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000625
626 Range* range() const { return range_; }
627 bool HasRange() const { return range_ != NULL; }
628 void AddNewRange(Range* r);
629 void RemoveLastAddedRange();
630 void ComputeInitialRange();
631
632 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000633 virtual Representation RequiredInputRepresentation(int index) const = 0;
634
635 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000636 return representation();
637 }
638
639 // This gives the instruction an opportunity to replace itself with an
640 // instruction that does the same in some better way. To replace an
641 // instruction with a new one, first add the new instruction to the graph,
642 // then return it. Return NULL to have the instruction deleted.
643 virtual HValue* Canonicalize() { return this; }
644
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000645 bool Equals(HValue* other);
646 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000647
648 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000649 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000650 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000651 void PrintTypeTo(StringStream* stream);
652 void PrintRangeTo(StringStream* stream);
653 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000655 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000656
657 // Updated the inferred type of this instruction and returns true if
658 // it has changed.
659 bool UpdateInferredType();
660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000661 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000662
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000664 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000665#endif
666
667 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000668 // This function must be overridden for instructions with flag kUseGVN, to
669 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000670 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000671 UNREACHABLE();
672 return false;
673 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000674 virtual void RepresentationChanged(Representation to) { }
675 virtual Range* InferRange();
676 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000677 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678 void clear_block() {
679 ASSERT(block_ != NULL);
680 block_ = NULL;
681 }
682
683 void set_representation(Representation r) {
684 // Representation is set-once.
685 ASSERT(representation_.IsNone() && !r.IsNone());
686 representation_ = r;
687 }
688
689 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000690 // A flag mask to mark an instruction as having arbitrary side effects.
691 static int AllSideEffects() {
692 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
693 }
694
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000695 // Remove the matching use from the use list if present. Returns the
696 // removed list node or NULL.
697 HUseListNode* RemoveUse(HValue* value, int index);
698
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000699 void RegisterUse(int index, HValue* new_value);
700
701 HBasicBlock* block_;
702
703 // The id of this instruction in the hydrogen graph, assigned when first
704 // added to the graph. Reflects creation order.
705 int id_;
706
707 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000708 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000709 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000710 Range* range_;
711 int flags_;
712
713 DISALLOW_COPY_AND_ASSIGN(HValue);
714};
715
716
717class HInstruction: public HValue {
718 public:
719 HInstruction* next() const { return next_; }
720 HInstruction* previous() const { return previous_; }
721
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000722 virtual void PrintTo(StringStream* stream);
723 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000724
725 bool IsLinked() const { return block() != NULL; }
726 void Unlink();
727 void InsertBefore(HInstruction* next);
728 void InsertAfter(HInstruction* previous);
729
730 int position() const { return position_; }
731 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
732 void set_position(int position) { position_ = position; }
733
734 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
735
736#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000737 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000738#endif
739
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000740 virtual bool IsCall() { return false; }
741
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000742 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000743
744 protected:
745 HInstruction()
746 : next_(NULL),
747 previous_(NULL),
748 position_(RelocInfo::kNoPosition) {
749 SetFlag(kDependsOnOsrEntries);
750 }
751
752 virtual void DeleteFromGraph() { Unlink(); }
753
754 private:
755 void InitializeAsFirst(HBasicBlock* block) {
756 ASSERT(!IsLinked());
757 SetBlock(block);
758 }
759
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000760 void PrintMnemonicTo(StringStream* stream);
761
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000762 HInstruction* next_;
763 HInstruction* previous_;
764 int position_;
765
766 friend class HBasicBlock;
767};
768
769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000770template<int V>
771class HTemplateInstruction : public HInstruction {
772 public:
773 int OperandCount() { return V; }
774 HValue* OperandAt(int i) { return inputs_[i]; }
775
776 protected:
777 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
778
779 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000780 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000781};
782
783
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000784class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000785 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000786 virtual HBasicBlock* SuccessorAt(int i) = 0;
787 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000788 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000789
790 virtual void PrintDataTo(StringStream* stream);
791
792 HBasicBlock* FirstSuccessor() {
793 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
794 }
795 HBasicBlock* SecondSuccessor() {
796 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
797 }
798
799 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
800};
801
802
803class HSuccessorIterator BASE_EMBEDDED {
804 public:
805 explicit HSuccessorIterator(HControlInstruction* instr)
806 : instr_(instr), current_(0) { }
807
808 bool Done() { return current_ >= instr_->SuccessorCount(); }
809 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
810 void Advance() { current_++; }
811
812 private:
813 HControlInstruction* instr_;
814 int current_;
815};
816
817
818template<int S, int V>
819class HTemplateControlInstruction: public HControlInstruction {
820 public:
821 int SuccessorCount() { return S; }
822 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000823 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000825 int OperandCount() { return V; }
826 HValue* OperandAt(int i) { return inputs_[i]; }
827
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000829 protected:
830 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
831
832 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000833 EmbeddedContainer<HBasicBlock*, S> successors_;
834 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000835};
836
837
838class HBlockEntry: public HTemplateInstruction<0> {
839 public:
840 virtual Representation RequiredInputRepresentation(int index) const {
841 return Representation::None();
842 }
843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000844 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000845};
846
847
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000848// We insert soft-deoptimize when we hit code with unknown typefeedback,
849// so that we get a chance of re-optimizing with useful typefeedback.
850// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
851class HSoftDeoptimize: public HTemplateInstruction<0> {
852 public:
853 virtual Representation RequiredInputRepresentation(int index) const {
854 return Representation::None();
855 }
856
857 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
858};
859
860
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000861class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000862 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000863 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000864
865 virtual Representation RequiredInputRepresentation(int index) const {
866 return Representation::None();
867 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000868
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869 virtual int OperandCount() { return values_.length(); }
870 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000871 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000872
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000873 virtual int SuccessorCount() { return 0; }
874 virtual HBasicBlock* SuccessorAt(int i) {
875 UNREACHABLE();
876 return NULL;
877 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000878 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
879 UNREACHABLE();
880 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000881
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000882 void AddEnvironmentValue(HValue* value) {
883 values_.Add(NULL);
884 SetOperandAt(values_.length() - 1, value);
885 }
886
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000887 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000888
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000889 enum UseEnvironment {
890 kNoUses,
891 kUseAll
892 };
893
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000894 protected:
895 virtual void InternalSetOperandAt(int index, HValue* value) {
896 values_[index] = value;
897 }
898
899 private:
900 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000901};
902
903
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000904class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000905 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000906 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000907 SetSuccessorAt(0, target);
908 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000910 virtual Representation RequiredInputRepresentation(int index) const {
911 return Representation::None();
912 }
913
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000914 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915};
916
917
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000920 HUnaryControlInstruction(HValue* value,
921 HBasicBlock* true_target,
922 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000924 SetSuccessorAt(0, true_target);
925 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926 }
927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000928 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000929
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000930 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000931};
932
933
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000934class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000936 HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000937 : HUnaryControlInstruction(value, true_target, false_target) {
938 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000939 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000940 explicit HBranch(HValue* value)
941 : HUnaryControlInstruction(value, NULL, NULL) { }
942
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943
944 virtual Representation RequiredInputRepresentation(int index) const {
945 return Representation::None();
946 }
947
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000948 DECLARE_CONCRETE_INSTRUCTION(Branch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000949};
950
951
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000952class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000953 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000954 HCompareMap(HValue* value,
955 Handle<Map> map,
956 HBasicBlock* true_target,
957 HBasicBlock* false_target)
958 : HUnaryControlInstruction(value, true_target, false_target),
959 map_(map) {
960 ASSERT(true_target != NULL);
961 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000962 ASSERT(!map.is_null());
963 }
964
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000965 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000966
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000967 Handle<Map> map() const { return map_; }
968
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000969 virtual Representation RequiredInputRepresentation(int index) const {
970 return Representation::Tagged();
971 }
972
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000973 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974
975 private:
976 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000977};
978
979
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000980class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000981 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000982 explicit HReturn(HValue* value) {
983 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000984 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000985
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000986 virtual Representation RequiredInputRepresentation(int index) const {
987 return Representation::Tagged();
988 }
989
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000990 virtual void PrintDataTo(StringStream* stream);
991
992 HValue* value() { return OperandAt(0); }
993
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000994 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000995};
996
997
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000998class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000999 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001000 virtual Representation RequiredInputRepresentation(int index) const {
1001 return Representation::None();
1002 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001003
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001004 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001005};
1006
1007
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001008class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001009 public:
1010 explicit HUnaryOperation(HValue* value) {
1011 SetOperandAt(0, value);
1012 }
1013
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001014 static HUnaryOperation* cast(HValue* value) {
1015 return reinterpret_cast<HUnaryOperation*>(value);
1016 }
1017
1018 virtual bool CanTruncateToInt32() const {
1019 return CheckFlag(kTruncatingToInt32);
1020 }
1021
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001022 HValue* value() { return OperandAt(0); }
1023 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001024};
1025
1026
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001027class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001028 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001029 HThrow(HValue* context, HValue* value) {
1030 SetOperandAt(0, context);
1031 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001032 SetAllSideEffects();
1033 }
1034
1035 virtual Representation RequiredInputRepresentation(int index) const {
1036 return Representation::Tagged();
1037 }
1038
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001039 HValue* context() { return OperandAt(0); }
1040 HValue* value() { return OperandAt(1); }
1041
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001042 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001043};
1044
1045
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001046class HUseConst: public HUnaryOperation {
1047 public:
1048 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1049
1050 virtual Representation RequiredInputRepresentation(int index) const {
1051 return Representation::None();
1052 }
1053
1054 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1055};
1056
1057
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001058class HForceRepresentation: public HTemplateInstruction<1> {
1059 public:
1060 HForceRepresentation(HValue* value, Representation required_representation) {
1061 SetOperandAt(0, value);
1062 set_representation(required_representation);
1063 }
1064
1065 HValue* value() { return OperandAt(0); }
1066
1067 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1068
1069 virtual Representation RequiredInputRepresentation(int index) const {
1070 return representation(); // Same as the output representation.
1071 }
1072
1073 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1074};
1075
1076
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001077class HChange: public HUnaryOperation {
1078 public:
1079 HChange(HValue* value,
1080 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001081 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001082 bool is_truncating,
1083 bool deoptimize_on_undefined)
1084 : HUnaryOperation(value),
1085 from_(from),
1086 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001087 ASSERT(!from.IsNone() && !to.IsNone());
1088 ASSERT(!from.Equals(to));
1089 set_representation(to);
1090 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001091 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001092 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1093 value->range()->IsInSmiRange()) {
1094 set_type(HType::Smi());
1095 }
1096 }
1097
1098 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1099
1100 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001101 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001102 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001103 virtual Representation RequiredInputRepresentation(int index) const {
1104 return from_;
1105 }
1106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001107 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001109 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110
1111 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001112 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001113 if (!other->IsChange()) return false;
1114 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001115 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001116 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001117 }
1118
1119 private:
1120 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001121 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001122};
1123
1124
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001125class HClampToUint8: public HUnaryOperation {
1126 public:
1127 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001128 : HUnaryOperation(value) {
1129 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001130 SetFlag(kUseGVN);
1131 }
1132
1133 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001134 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001135 }
1136
1137 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1138
1139 protected:
1140 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001141};
1142
1143
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001144class HToInt32: public HUnaryOperation {
1145 public:
1146 explicit HToInt32(HValue* value)
1147 : HUnaryOperation(value) {
1148 set_representation(Representation::Integer32());
1149 SetFlag(kUseGVN);
1150 }
1151
1152 virtual Representation RequiredInputRepresentation(int index) const {
1153 return Representation::None();
1154 }
1155
1156 virtual bool CanTruncateToInt32() const {
1157 return true;
1158 }
1159
1160 virtual HValue* Canonicalize() {
1161 if (value()->representation().IsInteger32()) {
1162 return value();
1163 } else {
1164 return this;
1165 }
1166 }
1167
1168 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1169
1170 protected:
1171 virtual bool DataEquals(HValue* other) { return true; }
1172};
1173
1174
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001175class HSimulate: public HInstruction {
1176 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001177 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001178 : ast_id_(ast_id),
1179 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001180 values_(2),
1181 assigned_indexes_(2) {}
1182 virtual ~HSimulate() {}
1183
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001184 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001185
1186 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1187 int ast_id() const { return ast_id_; }
1188 void set_ast_id(int id) {
1189 ASSERT(!HasAstId());
1190 ast_id_ = id;
1191 }
1192
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193 int pop_count() const { return pop_count_; }
1194 const ZoneList<HValue*>* values() const { return &values_; }
1195 int GetAssignedIndexAt(int index) const {
1196 ASSERT(HasAssignedIndexAt(index));
1197 return assigned_indexes_[index];
1198 }
1199 bool HasAssignedIndexAt(int index) const {
1200 return assigned_indexes_[index] != kNoIndex;
1201 }
1202 void AddAssignedValue(int index, HValue* value) {
1203 AddValue(index, value);
1204 }
1205 void AddPushedValue(HValue* value) {
1206 AddValue(kNoIndex, value);
1207 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001208 virtual int OperandCount() { return values_.length(); }
1209 virtual HValue* OperandAt(int index) { return values_[index]; }
1210
1211 virtual Representation RequiredInputRepresentation(int index) const {
1212 return Representation::None();
1213 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001214
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001215 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001216
1217#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001218 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001219#endif
1220
1221 protected:
1222 virtual void InternalSetOperandAt(int index, HValue* value) {
1223 values_[index] = value;
1224 }
1225
1226 private:
1227 static const int kNoIndex = -1;
1228 void AddValue(int index, HValue* value) {
1229 assigned_indexes_.Add(index);
1230 // Resize the list of pushed values.
1231 values_.Add(NULL);
1232 // Set the operand through the base method in HValue to make sure that the
1233 // use lists are correctly updated.
1234 SetOperandAt(values_.length() - 1, value);
1235 }
1236 int ast_id_;
1237 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238 ZoneList<HValue*> values_;
1239 ZoneList<int> assigned_indexes_;
1240};
1241
1242
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001243class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001244 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001245 enum Type {
1246 kFunctionEntry,
1247 kBackwardsBranch
1248 };
1249
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001250 HStackCheck(HValue* context, Type type) : type_(type) {
1251 SetOperandAt(0, context);
1252 }
1253
1254 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001255
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001256 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001257 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001258 }
1259
ager@chromium.org04921a82011-06-27 13:21:41 +00001260 void Eliminate() {
1261 // The stack check eliminator might try to eliminate the same stack
1262 // check instruction multiple times.
1263 if (IsLinked()) {
1264 DeleteFromGraph();
1265 }
1266 }
1267
1268 bool is_function_entry() { return type_ == kFunctionEntry; }
1269 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1270
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001271 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001272
1273 private:
1274 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275};
1276
1277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001278class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001279 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001280 HEnterInlined(Handle<JSFunction> closure,
1281 FunctionLiteral* function,
1282 CallKind call_kind)
1283 : closure_(closure),
1284 function_(function),
1285 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001286 }
1287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001288 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289
1290 Handle<JSFunction> closure() const { return closure_; }
1291 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001292 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001294 virtual Representation RequiredInputRepresentation(int index) const {
1295 return Representation::None();
1296 }
1297
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001298 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001299
1300 private:
1301 Handle<JSFunction> closure_;
1302 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001303 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001304};
1305
1306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308 public:
1309 HLeaveInlined() {}
1310
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001311 virtual Representation RequiredInputRepresentation(int index) const {
1312 return Representation::None();
1313 }
1314
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001315 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001316};
1317
1318
1319class HPushArgument: public HUnaryOperation {
1320 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1322 set_representation(Representation::Tagged());
1323 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001324
1325 virtual Representation RequiredInputRepresentation(int index) const {
1326 return Representation::Tagged();
1327 }
1328
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001329 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001330
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001331 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001332};
1333
1334
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001335class HThisFunction: public HTemplateInstruction<0> {
1336 public:
1337 HThisFunction() {
1338 set_representation(Representation::Tagged());
1339 SetFlag(kUseGVN);
1340 }
1341
1342 virtual Representation RequiredInputRepresentation(int index) const {
1343 return Representation::None();
1344 }
1345
1346 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1347
1348 protected:
1349 virtual bool DataEquals(HValue* other) { return true; }
1350};
1351
1352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001353class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001354 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001355 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001356 set_representation(Representation::Tagged());
1357 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001358 }
1359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001360 virtual Representation RequiredInputRepresentation(int index) const {
1361 return Representation::None();
1362 }
1363
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001364 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001365
1366 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001367 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001368};
1369
1370
1371class HOuterContext: public HUnaryOperation {
1372 public:
1373 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1374 set_representation(Representation::Tagged());
1375 SetFlag(kUseGVN);
1376 }
1377
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001378 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001379
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001380 virtual Representation RequiredInputRepresentation(int index) const {
1381 return Representation::Tagged();
1382 }
1383
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001384 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001385 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001386};
1387
1388
1389class HGlobalObject: public HUnaryOperation {
1390 public:
1391 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1392 set_representation(Representation::Tagged());
1393 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394 }
1395
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001396 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001398 virtual Representation RequiredInputRepresentation(int index) const {
1399 return Representation::Tagged();
1400 }
1401
ager@chromium.org378b34e2011-01-28 08:04:38 +00001402 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001403 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001404};
1405
1406
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001407class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001408 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001409 explicit HGlobalReceiver(HValue* global_object)
1410 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411 set_representation(Representation::Tagged());
1412 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413 }
1414
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001415 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001417 virtual Representation RequiredInputRepresentation(int index) const {
1418 return Representation::Tagged();
1419 }
1420
ager@chromium.org378b34e2011-01-28 08:04:38 +00001421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001422 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423};
1424
1425
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001426template <int V>
1427class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001428 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001429 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001430 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1431 this->set_representation(Representation::Tagged());
1432 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001433 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001434
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001435 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001436
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001437 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001440
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001441 private:
1442 int argument_count_;
1443};
1444
1445
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001446class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001447 public:
1448 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001449 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001450 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001451 }
1452
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001453 virtual Representation RequiredInputRepresentation(int index) const {
1454 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001455 }
1456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001457 virtual void PrintDataTo(StringStream* stream);
1458
1459 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001460};
1461
1462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001463class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001464 public:
1465 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001467 SetOperandAt(0, first);
1468 SetOperandAt(1, second);
1469 }
1470
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001471 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001472
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001473 virtual Representation RequiredInputRepresentation(int index) const {
1474 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001475 }
1476
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001477 HValue* first() { return OperandAt(0); }
1478 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001479};
1480
1481
danno@chromium.org160a7b02011-04-18 15:51:38 +00001482class HInvokeFunction: public HBinaryCall {
1483 public:
1484 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1485 : HBinaryCall(context, function, argument_count) {
1486 }
1487
1488 virtual Representation RequiredInputRepresentation(int index) const {
1489 return Representation::Tagged();
1490 }
1491
1492 HValue* context() { return first(); }
1493 HValue* function() { return second(); }
1494
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001495 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001496};
1497
1498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001499class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001500 public:
1501 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001502 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001503
1504 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001505
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001506 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001507 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001508 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001509 }
1510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001511 virtual void PrintDataTo(StringStream* stream);
1512
1513 virtual Representation RequiredInputRepresentation(int index) const {
1514 return Representation::None();
1515 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001517 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001518
1519 private:
1520 Handle<JSFunction> function_;
1521};
1522
1523
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001524class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001525 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001526 HCallKeyed(HValue* context, HValue* key, int argument_count)
1527 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 }
1529
1530 virtual Representation RequiredInputRepresentation(int index) const {
1531 return Representation::Tagged();
1532 }
1533
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001534 HValue* context() { return first(); }
1535 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001537 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538};
1539
1540
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001541class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001542 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001543 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1544 : HUnaryCall(context, argument_count), name_(name) {
1545 }
1546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001547 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001549 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001550 Handle<String> name() const { return name_; }
1551
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001552 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001554 virtual Representation RequiredInputRepresentation(int index) const {
1555 return Representation::Tagged();
1556 }
1557
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001558 private:
1559 Handle<String> name_;
1560};
1561
1562
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001563class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001564 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001565 HCallFunction(HValue* context, int argument_count)
1566 : HUnaryCall(context, argument_count) {
1567 }
1568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001569 HValue* context() { return value(); }
1570
1571 virtual Representation RequiredInputRepresentation(int index) const {
1572 return Representation::Tagged();
1573 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001575 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576};
1577
1578
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001579class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001580 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001581 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1582 : HUnaryCall(context, argument_count), name_(name) {
1583 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001584
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001585 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001587 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588 Handle<String> name() const { return name_; }
1589
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001590 virtual Representation RequiredInputRepresentation(int index) const {
1591 return Representation::Tagged();
1592 }
1593
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001594 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595
1596 private:
1597 Handle<String> name_;
1598};
1599
1600
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001601class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001602 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001603 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001604 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001606 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001607
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608 Handle<JSFunction> target() const { return target_; }
1609
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001610 virtual Representation RequiredInputRepresentation(int index) const {
1611 return Representation::None();
1612 }
1613
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001614 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615
1616 private:
1617 Handle<JSFunction> target_;
1618};
1619
1620
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001621class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001622 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001623 HCallNew(HValue* context, HValue* constructor, int argument_count)
1624 : HBinaryCall(context, constructor, argument_count) {
1625 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001626
1627 virtual Representation RequiredInputRepresentation(int index) const {
1628 return Representation::Tagged();
1629 }
1630
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001631 HValue* context() { return first(); }
1632 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001634 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001635};
1636
1637
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001638class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001640 HCallRuntime(HValue* context,
1641 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001642 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001643 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001644 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1645 SetOperandAt(0, context);
1646 }
1647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001648 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001649
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001650 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001651 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 Handle<String> name() const { return name_; }
1653
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001654 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001655 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001656 }
1657
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001658 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001659
1660 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001661 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001662 Handle<String> name_;
1663};
1664
1665
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001666class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001668 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001669 // The length of an array is stored as a tagged value in the array
1670 // object. It is guaranteed to be 32 bit integer, but it can be
1671 // represented as either a smi or heap number.
1672 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001673 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001674 SetFlag(kDependsOnArrayLengths);
1675 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001676 }
1677
1678 virtual Representation RequiredInputRepresentation(int index) const {
1679 return Representation::Tagged();
1680 }
1681
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001682 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001683
1684 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001685 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001686};
1687
1688
1689class HFixedArrayLength: public HUnaryOperation {
1690 public:
1691 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1692 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001693 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001694 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001695 }
1696
1697 virtual Representation RequiredInputRepresentation(int index) const {
1698 return Representation::Tagged();
1699 }
1700
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001701 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001702
1703 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001704 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001705};
1706
1707
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001708class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001709 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001710 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001711 set_representation(Representation::Integer32());
1712 // The result of this instruction is idempotent as long as its inputs don't
1713 // change. The length of a pixel array cannot change once set, so it's not
1714 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1715 SetFlag(kUseGVN);
1716 }
1717
1718 virtual Representation RequiredInputRepresentation(int index) const {
1719 return Representation::Tagged();
1720 }
1721
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001722 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001723
1724 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001725 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001726};
1727
1728
whesse@chromium.org7b260152011-06-20 15:33:18 +00001729class HElementsKind: public HUnaryOperation {
1730 public:
1731 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1732 set_representation(Representation::Integer32());
1733 SetFlag(kUseGVN);
1734 SetFlag(kDependsOnMaps);
1735 }
1736
1737 virtual Representation RequiredInputRepresentation(int index) const {
1738 return Representation::Tagged();
1739 }
1740
1741 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1742
1743 protected:
1744 virtual bool DataEquals(HValue* other) { return true; }
1745};
1746
1747
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001748class HBitNot: public HUnaryOperation {
1749 public:
1750 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1751 set_representation(Representation::Integer32());
1752 SetFlag(kUseGVN);
1753 SetFlag(kTruncatingToInt32);
1754 }
1755
1756 virtual Representation RequiredInputRepresentation(int index) const {
1757 return Representation::Integer32();
1758 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001759 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001760
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001761 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001762
1763 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001764 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765};
1766
1767
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001768class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001769 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001770 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1771 : op_(op) {
1772 SetOperandAt(0, context);
1773 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001774 switch (op) {
1775 case kMathFloor:
1776 case kMathRound:
1777 case kMathCeil:
1778 set_representation(Representation::Integer32());
1779 break;
1780 case kMathAbs:
1781 set_representation(Representation::Tagged());
1782 SetFlag(kFlexibleRepresentation);
1783 break;
1784 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001785 case kMathPowHalf:
1786 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001787 case kMathSin:
1788 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001789 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001790 break;
1791 default:
1792 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793 }
1794 SetFlag(kUseGVN);
1795 }
1796
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001797 HValue* context() { return OperandAt(0); }
1798 HValue* value() { return OperandAt(1); }
1799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001800 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001802 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803
1804 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1805
1806 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001807 if (index == 0) {
1808 return Representation::Tagged();
1809 } else {
1810 switch (op_) {
1811 case kMathFloor:
1812 case kMathRound:
1813 case kMathCeil:
1814 case kMathSqrt:
1815 case kMathPowHalf:
1816 case kMathLog:
1817 case kMathSin:
1818 case kMathCos:
1819 return Representation::Double();
1820 case kMathAbs:
1821 return representation();
1822 default:
1823 UNREACHABLE();
1824 return Representation::None();
1825 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001826 }
1827 }
1828
1829 virtual HValue* Canonicalize() {
1830 // If the input is integer32 then we replace the floor instruction
1831 // with its inputs. This happens before the representation changes are
1832 // introduced.
1833 if (op() == kMathFloor) {
1834 if (value()->representation().IsInteger32()) return value();
1835 }
1836 return this;
1837 }
1838
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001839 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001840 const char* OpName() const;
1841
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001842 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001843
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001844 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001845 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001846 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1847 return op_ == b->op();
1848 }
1849
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001851 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001852};
1853
1854
1855class HLoadElements: public HUnaryOperation {
1856 public:
1857 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1858 set_representation(Representation::Tagged());
1859 SetFlag(kUseGVN);
1860 SetFlag(kDependsOnMaps);
1861 }
1862
1863 virtual Representation RequiredInputRepresentation(int index) const {
1864 return Representation::Tagged();
1865 }
1866
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001867 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001868
1869 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001870 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001871};
1872
1873
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001874class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001875 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001876 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001877 : HUnaryOperation(value) {
1878 set_representation(Representation::External());
1879 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001880 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001881 // change once set, so it's no necessary to introduce any additional
1882 // dependencies on top of the inputs.
1883 SetFlag(kUseGVN);
1884 }
1885
1886 virtual Representation RequiredInputRepresentation(int index) const {
1887 return Representation::Tagged();
1888 }
1889
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001890 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001891
1892 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001893 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001894};
1895
1896
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001897class HCheckMap: public HUnaryOperation {
1898 public:
1899 HCheckMap(HValue* value, Handle<Map> map)
1900 : HUnaryOperation(value), map_(map) {
1901 set_representation(Representation::Tagged());
1902 SetFlag(kUseGVN);
1903 SetFlag(kDependsOnMaps);
1904 }
1905
1906 virtual Representation RequiredInputRepresentation(int index) const {
1907 return Representation::Tagged();
1908 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001909 virtual void PrintDataTo(StringStream* stream);
1910 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001911
1912#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001913 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001914#endif
1915
1916 Handle<Map> map() const { return map_; }
1917
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001918 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919
1920 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001921 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001922 HCheckMap* b = HCheckMap::cast(other);
1923 return map_.is_identical_to(b->map());
1924 }
1925
1926 private:
1927 Handle<Map> map_;
1928};
1929
1930
1931class HCheckFunction: public HUnaryOperation {
1932 public:
1933 HCheckFunction(HValue* value, Handle<JSFunction> function)
1934 : HUnaryOperation(value), target_(function) {
1935 set_representation(Representation::Tagged());
1936 SetFlag(kUseGVN);
1937 }
1938
1939 virtual Representation RequiredInputRepresentation(int index) const {
1940 return Representation::Tagged();
1941 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001942 virtual void PrintDataTo(StringStream* stream);
1943 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944
1945#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001946 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001947#endif
1948
1949 Handle<JSFunction> target() const { return target_; }
1950
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001951 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952
1953 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001954 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001955 HCheckFunction* b = HCheckFunction::cast(other);
1956 return target_.is_identical_to(b->target());
1957 }
1958
1959 private:
1960 Handle<JSFunction> target_;
1961};
1962
1963
1964class HCheckInstanceType: public HUnaryOperation {
1965 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001966 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1967 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001968 }
1969 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1970 return new HCheckInstanceType(value, IS_JS_ARRAY);
1971 }
1972 static HCheckInstanceType* NewIsString(HValue* value) {
1973 return new HCheckInstanceType(value, IS_STRING);
1974 }
1975 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1976 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977 }
1978
1979 virtual Representation RequiredInputRepresentation(int index) const {
1980 return Representation::Tagged();
1981 }
1982
1983#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001984 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001985#endif
1986
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00001987 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00001988
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001989 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1990 void GetCheckInterval(InstanceType* first, InstanceType* last);
1991 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001992
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001993 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001994
1995 protected:
1996 // TODO(ager): It could be nice to allow the ommision of instance
1997 // type checks if we have already performed an instance type check
1998 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001999 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002001 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002002 }
2003
2004 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002005 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002006 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002007 IS_JS_ARRAY,
2008 IS_STRING,
2009 IS_SYMBOL,
2010 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2011 };
2012
2013 HCheckInstanceType(HValue* value, Check check)
2014 : HUnaryOperation(value), check_(check) {
2015 set_representation(Representation::Tagged());
2016 SetFlag(kUseGVN);
2017 }
2018
2019 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020};
2021
2022
2023class HCheckNonSmi: public HUnaryOperation {
2024 public:
2025 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2026 set_representation(Representation::Tagged());
2027 SetFlag(kUseGVN);
2028 }
2029
2030 virtual Representation RequiredInputRepresentation(int index) const {
2031 return Representation::Tagged();
2032 }
2033
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002034 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002035
2036#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002037 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002038#endif
2039
danno@chromium.org160a7b02011-04-18 15:51:38 +00002040 virtual HValue* Canonicalize() {
2041 HType value_type = value()->type();
2042 if (!value_type.IsUninitialized() &&
2043 (value_type.IsHeapNumber() ||
2044 value_type.IsString() ||
2045 value_type.IsBoolean() ||
2046 value_type.IsNonPrimitive())) {
2047 return NULL;
2048 }
2049 return this;
2050 }
2051
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002052 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002053
2054 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002055 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056};
2057
2058
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002059class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002061 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2062 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063 SetFlag(kUseGVN);
2064 SetFlag(kDependsOnMaps);
2065 }
2066
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002067#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002068 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002069#endif
2070
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002071 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002072 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002073
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002074 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002075
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002076 virtual Representation RequiredInputRepresentation(int index) const {
2077 return Representation::None();
2078 }
2079
2080 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002081 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002082 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2083 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2084 return hash;
2085 }
2086
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002087 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002088 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002089 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002090 return prototype_.is_identical_to(b->prototype()) &&
2091 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092 }
2093
2094 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002095 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002097};
2098
2099
2100class HCheckSmi: public HUnaryOperation {
2101 public:
2102 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2103 set_representation(Representation::Tagged());
2104 SetFlag(kUseGVN);
2105 }
2106
2107 virtual Representation RequiredInputRepresentation(int index) const {
2108 return Representation::Tagged();
2109 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002110 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111
2112#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002113 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002114#endif
2115
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002116 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002117
2118 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002119 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002120};
2121
2122
2123class HPhi: public HValue {
2124 public:
2125 explicit HPhi(int merged_index)
2126 : inputs_(2),
2127 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002128 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002129 is_live_(false),
2130 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002131 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2132 non_phi_uses_[i] = 0;
2133 indirect_uses_[i] = 0;
2134 }
2135 ASSERT(merged_index >= 0);
2136 set_representation(Representation::Tagged());
2137 SetFlag(kFlexibleRepresentation);
2138 }
2139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002140 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002141 bool double_occurred = false;
2142 bool int32_occurred = false;
2143 for (int i = 0; i < OperandCount(); ++i) {
2144 HValue* value = OperandAt(i);
2145 if (value->representation().IsDouble()) double_occurred = true;
2146 if (value->representation().IsInteger32()) int32_occurred = true;
2147 if (value->representation().IsTagged()) return Representation::Tagged();
2148 }
2149
2150 if (double_occurred) return Representation::Double();
2151 if (int32_occurred) return Representation::Integer32();
2152 return Representation::None();
2153 }
2154
2155 virtual Range* InferRange();
2156 virtual Representation RequiredInputRepresentation(int index) const {
2157 return representation();
2158 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002159 virtual HType CalculateInferredType();
2160 virtual int OperandCount() { return inputs_.length(); }
2161 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2162 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002163 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002164 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002166 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167
2168 int merged_index() const { return merged_index_; }
2169
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002170 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002171
2172#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002173 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174#endif
2175
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002176 void InitRealUses(int id);
2177 void AddNonPhiUsesFrom(HPhi* other);
2178 void AddIndirectUsesTo(int* use_count);
2179
2180 int tagged_non_phi_uses() const {
2181 return non_phi_uses_[Representation::kTagged];
2182 }
2183 int int32_non_phi_uses() const {
2184 return non_phi_uses_[Representation::kInteger32];
2185 }
2186 int double_non_phi_uses() const {
2187 return non_phi_uses_[Representation::kDouble];
2188 }
2189 int tagged_indirect_uses() const {
2190 return indirect_uses_[Representation::kTagged];
2191 }
2192 int int32_indirect_uses() const {
2193 return indirect_uses_[Representation::kInteger32];
2194 }
2195 int double_indirect_uses() const {
2196 return indirect_uses_[Representation::kDouble];
2197 }
2198 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002199 bool is_live() { return is_live_; }
2200 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002201
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002202 static HPhi* cast(HValue* value) {
2203 ASSERT(value->IsPhi());
2204 return reinterpret_cast<HPhi*>(value);
2205 }
2206 virtual Opcode opcode() const { return HValue::kPhi; }
2207
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002208 virtual bool IsConvertibleToInteger() const {
2209 return is_convertible_to_integer_;
2210 }
2211
2212 void set_is_convertible_to_integer(bool b) {
2213 is_convertible_to_integer_ = b;
2214 }
2215
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002216 protected:
2217 virtual void DeleteFromGraph();
2218 virtual void InternalSetOperandAt(int index, HValue* value) {
2219 inputs_[index] = value;
2220 }
2221
2222 private:
2223 ZoneList<HValue*> inputs_;
2224 int merged_index_;
2225
2226 int non_phi_uses_[Representation::kNumRepresentations];
2227 int indirect_uses_[Representation::kNumRepresentations];
2228 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002229 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002230 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002231};
2232
2233
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002234class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235 public:
2236 HArgumentsObject() {
2237 set_representation(Representation::Tagged());
2238 SetFlag(kIsArguments);
2239 }
2240
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002241 virtual Representation RequiredInputRepresentation(int index) const {
2242 return Representation::None();
2243 }
2244
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002245 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002246};
2247
2248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002249class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002250 public:
2251 HConstant(Handle<Object> handle, Representation r);
2252
2253 Handle<Object> handle() const { return handle_; }
2254
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002255 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002257 virtual Representation RequiredInputRepresentation(int index) const {
2258 return Representation::None();
2259 }
2260
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002261 virtual bool IsConvertibleToInteger() const {
2262 if (handle_->IsSmi()) return true;
2263 if (handle_->IsHeapNumber() &&
2264 (HeapNumber::cast(*handle_)->value() ==
2265 static_cast<double>(NumberToInt32(*handle_)))) return true;
2266 return false;
2267 }
2268
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002269 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002270 virtual void PrintDataTo(StringStream* stream);
2271 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002272 bool IsInteger() const { return handle_->IsSmi(); }
2273 HConstant* CopyToRepresentation(Representation r) const;
2274 HConstant* CopyToTruncatedInt32() const;
2275 bool HasInteger32Value() const { return has_int32_value_; }
2276 int32_t Integer32Value() const {
2277 ASSERT(HasInteger32Value());
2278 return int32_value_;
2279 }
2280 bool HasDoubleValue() const { return has_double_value_; }
2281 double DoubleValue() const {
2282 ASSERT(HasDoubleValue());
2283 return double_value_;
2284 }
2285 bool HasStringValue() const { return handle_->IsString(); }
2286
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002287 bool ToBoolean() const;
2288
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002289 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002290 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002291 return reinterpret_cast<intptr_t>(*handle());
2292 }
2293
2294#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002295 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002296#endif
2297
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002298 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002299
2300 protected:
2301 virtual Range* InferRange();
2302
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002303 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002304 HConstant* other_constant = HConstant::cast(other);
2305 return handle().is_identical_to(other_constant->handle());
2306 }
2307
2308 private:
2309 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310
2311 // The following two values represent the int32 and the double value of the
2312 // given constant if there is a lossless conversion between the constant
2313 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002314 bool has_int32_value_ : 1;
2315 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002316 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002317 double double_value_;
2318};
2319
2320
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002321class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002322 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002323 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002324 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002325 SetOperandAt(0, context);
2326 SetOperandAt(1, left);
2327 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002328 }
2329
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002330 HValue* context() { return OperandAt(0); }
2331 HValue* left() { return OperandAt(1); }
2332 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002333
2334 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2335 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002336 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002337 if (IsCommutative() && left()->IsConstant()) return right();
2338 return left();
2339 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002340 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002341 if (IsCommutative() && left()->IsConstant()) return left();
2342 return right();
2343 }
2344
2345 virtual bool IsCommutative() const { return false; }
2346
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002347 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002348};
2349
2350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002351class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002352 public:
2353 HApplyArguments(HValue* function,
2354 HValue* receiver,
2355 HValue* length,
2356 HValue* elements) {
2357 set_representation(Representation::Tagged());
2358 SetOperandAt(0, function);
2359 SetOperandAt(1, receiver);
2360 SetOperandAt(2, length);
2361 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002362 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363 }
2364
2365 virtual Representation RequiredInputRepresentation(int index) const {
2366 // The length is untagged, all other inputs are tagged.
2367 return (index == 2)
2368 ? Representation::Integer32()
2369 : Representation::Tagged();
2370 }
2371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002372 HValue* function() { return OperandAt(0); }
2373 HValue* receiver() { return OperandAt(1); }
2374 HValue* length() { return OperandAt(2); }
2375 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002377 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002378};
2379
2380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002381class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002382 public:
2383 HArgumentsElements() {
2384 // The value produced by this instruction is a pointer into the stack
2385 // that looks as if it was a smi because of alignment.
2386 set_representation(Representation::Tagged());
2387 SetFlag(kUseGVN);
2388 }
2389
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002390 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002392 virtual Representation RequiredInputRepresentation(int index) const {
2393 return Representation::None();
2394 }
2395
ager@chromium.org378b34e2011-01-28 08:04:38 +00002396 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002397 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002398};
2399
2400
2401class HArgumentsLength: public HUnaryOperation {
2402 public:
2403 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2404 set_representation(Representation::Integer32());
2405 SetFlag(kUseGVN);
2406 }
2407
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002408 virtual Representation RequiredInputRepresentation(int index) const {
2409 return Representation::Tagged();
2410 }
2411
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002412 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002413
2414 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002415 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002416};
2417
2418
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002419class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002420 public:
2421 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2422 set_representation(Representation::Tagged());
2423 SetFlag(kUseGVN);
2424 SetOperandAt(0, arguments);
2425 SetOperandAt(1, length);
2426 SetOperandAt(2, index);
2427 }
2428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002429 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002430
2431 virtual Representation RequiredInputRepresentation(int index) const {
2432 // The arguments elements is considered tagged.
2433 return index == 0
2434 ? Representation::Tagged()
2435 : Representation::Integer32();
2436 }
2437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002438 HValue* arguments() { return OperandAt(0); }
2439 HValue* length() { return OperandAt(1); }
2440 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002441
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002442 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002444 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445};
2446
2447
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002448class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002449 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002450 HBoundsCheck(HValue* index, HValue* length) {
2451 SetOperandAt(0, index);
2452 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002453 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454 SetFlag(kUseGVN);
2455 }
2456
2457 virtual Representation RequiredInputRepresentation(int index) const {
2458 return Representation::Integer32();
2459 }
2460
2461#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002462 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463#endif
2464
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002465 HValue* index() { return OperandAt(0); }
2466 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002467
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002468 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002469
2470 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002471 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002472};
2473
2474
2475class HBitwiseBinaryOperation: public HBinaryOperation {
2476 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002477 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2478 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002479 set_representation(Representation::Tagged());
2480 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002481 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002482 }
2483
2484 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002485 return index == 0
2486 ? Representation::Tagged()
2487 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002488 }
2489
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002490 virtual void RepresentationChanged(Representation to) {
2491 if (!to.IsTagged()) {
2492 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002493 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002494 SetFlag(kTruncatingToInt32);
2495 SetFlag(kUseGVN);
2496 }
2497 }
2498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002499 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002500
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002501 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002502};
2503
2504
2505class HArithmeticBinaryOperation: public HBinaryOperation {
2506 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002507 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2508 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002509 set_representation(Representation::Tagged());
2510 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002511 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002512 }
2513
2514 virtual void RepresentationChanged(Representation to) {
2515 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002516 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002517 SetFlag(kUseGVN);
2518 }
2519 }
2520
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002521 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002522 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002523 return index == 0
2524 ? Representation::Tagged()
2525 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002526 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002527
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002528 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002529 if (left()->representation().Equals(right()->representation())) {
2530 return left()->representation();
2531 }
2532 return HValue::InferredRepresentation();
2533 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002534};
2535
2536
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002537class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002539 HCompareGeneric(HValue* context,
2540 HValue* left,
2541 HValue* right,
2542 Token::Value token)
2543 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544 ASSERT(Token::IsCompareOp(token));
2545 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002546 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547 }
2548
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002549 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002550 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002551 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002552
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002554 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002556
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002557 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002558 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002559
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002560 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002561
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002562 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2563
2564 private:
2565 Token::Value token_;
2566};
2567
2568
2569class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2570 public:
2571 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2572 : token_(token) {
2573 ASSERT(Token::IsCompareOp(token));
2574 SetOperandAt(0, left);
2575 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002576 }
2577
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002578 HValue* left() { return OperandAt(0); }
2579 HValue* right() { return OperandAt(1); }
2580 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002582 void SetInputRepresentation(Representation r);
2583 Representation GetInputRepresentation() const {
2584 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585 }
2586
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002587 virtual Representation RequiredInputRepresentation(int index) const {
2588 return input_representation_;
2589 }
2590 virtual void PrintDataTo(StringStream* stream);
2591
2592 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2593
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002594 private:
2595 Representation input_representation_;
2596 Token::Value token_;
2597};
2598
2599
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002600class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002602 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2603 SetOperandAt(0, left);
2604 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002605 }
2606
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002607 HValue* left() { return OperandAt(0); }
2608 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002609
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002610 virtual Representation RequiredInputRepresentation(int index) const {
2611 return Representation::Tagged();
2612 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002613
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002614 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002615};
2616
2617
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002618class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002619 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002620 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2621 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002622 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002623 }
2624
2625 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002626 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002627 int right() const { return right_; }
2628
whesse@chromium.org7b260152011-06-20 15:33:18 +00002629 virtual Representation RequiredInputRepresentation(int index) const {
2630 return Representation::Integer32();
2631 }
2632
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002633 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002634
2635 private:
2636 const Token::Value op_;
2637 const int right_;
2638};
2639
2640
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002641class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002642 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002643 HIsNullAndBranch(HValue* value, bool is_strict)
2644 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002645
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002646 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002647
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002648 virtual Representation RequiredInputRepresentation(int index) const {
2649 return Representation::Tagged();
2650 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002651
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002652 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002653
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002654 private:
2655 bool is_strict_;
2656};
2657
2658
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002659class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002660 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002661 explicit HIsObjectAndBranch(HValue* value)
2662 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002663
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002664 virtual Representation RequiredInputRepresentation(int index) const {
2665 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002666 }
2667
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002668 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2669};
2670
2671
2672class HIsSmiAndBranch: public HUnaryControlInstruction {
2673 public:
2674 explicit HIsSmiAndBranch(HValue* value)
2675 : HUnaryControlInstruction(value, NULL, NULL) { }
2676
2677 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2678
2679 virtual Representation RequiredInputRepresentation(int index) const {
2680 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002681 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002682
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002683 protected:
2684 virtual bool DataEquals(HValue* other) { return true; }
2685};
2686
2687
2688class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2689 public:
2690 explicit HIsUndetectableAndBranch(HValue* value)
2691 : HUnaryControlInstruction(value, NULL, NULL) { }
2692
2693 virtual Representation RequiredInputRepresentation(int index) const {
2694 return Representation::Tagged();
2695 }
2696
2697 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2698};
2699
2700
2701class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2702 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002703 virtual Representation RequiredInputRepresentation(int index) const {
2704 return Representation::None();
2705 }
2706
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002707 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002708};
2709
2710
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002711class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002712 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002713 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2714 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2715 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2716 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002717 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2718 }
2719
2720 InstanceType from() { return from_; }
2721 InstanceType to() { return to_; }
2722
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002723 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002725 virtual Representation RequiredInputRepresentation(int index) const {
2726 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002727 }
2728
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002729 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2730
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002731 private:
2732 InstanceType from_;
2733 InstanceType to_; // Inclusive range, not all combinations work.
2734};
2735
2736
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002737class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002739 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2740 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002742 virtual Representation RequiredInputRepresentation(int index) const {
2743 return Representation::Tagged();
2744 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002745
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002746 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747};
2748
2749
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002750class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002751 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002752 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2753 set_representation(Representation::Tagged());
2754 SetFlag(kUseGVN);
2755 }
2756
2757 virtual Representation RequiredInputRepresentation(int index) const {
2758 return Representation::Tagged();
2759 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002760
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002761 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002762
2763 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002764 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002765};
2766
2767
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002768class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002770 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2771 : HUnaryControlInstruction(value, NULL, NULL),
2772 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002774 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2775
2776 virtual Representation RequiredInputRepresentation(int index) const {
2777 return Representation::Tagged();
2778 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002780 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002781
2782 Handle<String> class_name() const { return class_name_; }
2783
2784 private:
2785 Handle<String> class_name_;
2786};
2787
2788
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002789class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002791 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2792 : HUnaryControlInstruction(value, NULL, NULL),
2793 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002794
2795 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002796 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002797
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002798 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002800 virtual Representation RequiredInputRepresentation(int index) const {
2801 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002802 }
2803
2804 private:
2805 Handle<String> type_literal_;
2806};
2807
2808
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002809class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002810 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002811 HInstanceOf(HValue* context, HValue* left, HValue* right)
2812 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002814 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815 }
2816
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817 virtual Representation RequiredInputRepresentation(int index) const {
2818 return Representation::Tagged();
2819 }
2820
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002821 virtual HType CalculateInferredType();
2822
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002823 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002824
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002825 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826};
2827
2828
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002829class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002830 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002831 HInstanceOfKnownGlobal(HValue* context,
2832 HValue* left,
2833 Handle<JSFunction> right)
2834 : function_(right) {
2835 SetOperandAt(0, context);
2836 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002837 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002838 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002839 }
2840
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002841 HValue* context() { return OperandAt(0); }
2842 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002843 Handle<JSFunction> function() { return function_; }
2844
2845 virtual Representation RequiredInputRepresentation(int index) const {
2846 return Representation::Tagged();
2847 }
2848
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002849 virtual HType CalculateInferredType();
2850
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002851 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002852
2853 private:
2854 Handle<JSFunction> function_;
2855};
2856
2857
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002858class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002859 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002860 HPower(HValue* left, HValue* right) {
2861 SetOperandAt(0, left);
2862 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002863 set_representation(Representation::Double());
2864 SetFlag(kUseGVN);
2865 }
2866
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002867 HValue* left() { return OperandAt(0); }
2868 HValue* right() { return OperandAt(1); }
2869
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002870 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002871 return index == 0
2872 ? Representation::Double()
2873 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002874 }
2875
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002876 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002877
2878 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002879 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002880};
2881
2882
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002883class HAdd: public HArithmeticBinaryOperation {
2884 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002885 HAdd(HValue* context, HValue* left, HValue* right)
2886 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887 SetFlag(kCanOverflow);
2888 }
2889
2890 // Add is only commutative if two integer values are added and not if two
2891 // tagged values are added (because it might be a String concatenation).
2892 virtual bool IsCommutative() const {
2893 return !representation().IsTagged();
2894 }
2895
2896 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2897
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002898 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002900 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002901
2902 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002903 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002904
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002905 virtual Range* InferRange();
2906};
2907
2908
2909class HSub: public HArithmeticBinaryOperation {
2910 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002911 HSub(HValue* context, HValue* left, HValue* right)
2912 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913 SetFlag(kCanOverflow);
2914 }
2915
2916 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2917
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002918 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002919
2920 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002921 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002922
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923 virtual Range* InferRange();
2924};
2925
2926
2927class HMul: public HArithmeticBinaryOperation {
2928 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002929 HMul(HValue* context, HValue* left, HValue* right)
2930 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 SetFlag(kCanOverflow);
2932 }
2933
2934 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2935
2936 // Only commutative if it is certain that not two objects are multiplicated.
2937 virtual bool IsCommutative() const {
2938 return !representation().IsTagged();
2939 }
2940
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002941 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002942
2943 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002944 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002945
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002946 virtual Range* InferRange();
2947};
2948
2949
2950class HMod: public HArithmeticBinaryOperation {
2951 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002952 HMod(HValue* context, HValue* left, HValue* right)
2953 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002954 SetFlag(kCanBeDivByZero);
2955 }
2956
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002957 bool HasPowerOf2Divisor() {
2958 if (right()->IsConstant() &&
2959 HConstant::cast(right())->HasInteger32Value()) {
2960 int32_t value = HConstant::cast(right())->Integer32Value();
2961 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2962 }
2963
2964 return false;
2965 }
2966
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002967 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2968
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002969 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002970
2971 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002972 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002973
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002974 virtual Range* InferRange();
2975};
2976
2977
2978class HDiv: public HArithmeticBinaryOperation {
2979 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002980 HDiv(HValue* context, HValue* left, HValue* right)
2981 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982 SetFlag(kCanBeDivByZero);
2983 SetFlag(kCanOverflow);
2984 }
2985
2986 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2987
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002988 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989
2990 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002991 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002992
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993 virtual Range* InferRange();
2994};
2995
2996
2997class HBitAnd: public HBitwiseBinaryOperation {
2998 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002999 HBitAnd(HValue* context, HValue* left, HValue* right)
3000 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001
3002 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003003 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003004
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003005 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003006
3007 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003008 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003009
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010 virtual Range* InferRange();
3011};
3012
3013
3014class HBitXor: public HBitwiseBinaryOperation {
3015 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003016 HBitXor(HValue* context, HValue* left, HValue* right)
3017 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018
3019 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003020 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003022 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003023
3024 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003025 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003026};
3027
3028
3029class HBitOr: public HBitwiseBinaryOperation {
3030 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003031 HBitOr(HValue* context, HValue* left, HValue* right)
3032 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003033
3034 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003035 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003036
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003037 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003038
3039 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003040 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003041
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003042 virtual Range* InferRange();
3043};
3044
3045
3046class HShl: public HBitwiseBinaryOperation {
3047 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003048 HShl(HValue* context, HValue* left, HValue* right)
3049 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003050
3051 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003052 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003053
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003054 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003055
3056 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003057 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003058};
3059
3060
3061class HShr: public HBitwiseBinaryOperation {
3062 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003063 HShr(HValue* context, HValue* left, HValue* right)
3064 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003068 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003069
3070 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003071 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072};
3073
3074
3075class HSar: public HBitwiseBinaryOperation {
3076 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003077 HSar(HValue* context, HValue* left, HValue* right)
3078 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079
3080 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003083 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003084
3085 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003086 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087};
3088
3089
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003090class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091 public:
3092 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3093 SetFlag(kChangesOsrEntries);
3094 }
3095
3096 int ast_id() const { return ast_id_; }
3097
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003098 virtual Representation RequiredInputRepresentation(int index) const {
3099 return Representation::None();
3100 }
3101
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003102 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103
3104 private:
3105 int ast_id_;
3106};
3107
3108
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003109class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 public:
3111 explicit HParameter(unsigned index) : index_(index) {
3112 set_representation(Representation::Tagged());
3113 }
3114
3115 unsigned index() const { return index_; }
3116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003117 virtual void PrintDataTo(StringStream* stream);
3118
3119 virtual Representation RequiredInputRepresentation(int index) const {
3120 return Representation::None();
3121 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003123 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124
3125 private:
3126 unsigned index_;
3127};
3128
3129
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003130class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003131 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003132 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3133 : HUnaryCall(context, argument_count),
3134 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003135 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136 }
3137
3138 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141
3142 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3143 transcendental_type_ = transcendental_type;
3144 }
3145 TranscendentalCache::Type transcendental_type() {
3146 return transcendental_type_;
3147 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003148
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003149 virtual void PrintDataTo(StringStream* stream);
3150
3151 virtual Representation RequiredInputRepresentation(int index) const {
3152 return Representation::Tagged();
3153 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003155 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156
3157 private:
3158 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159 TranscendentalCache::Type transcendental_type_;
3160};
3161
3162
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003163class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164 public:
3165 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3166
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003167 virtual Representation RequiredInputRepresentation(int index) const {
3168 return Representation::None();
3169 }
3170
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003171 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172};
3173
3174
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003175class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003177 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178 : cell_(cell), check_hole_value_(check_hole_value) {
3179 set_representation(Representation::Tagged());
3180 SetFlag(kUseGVN);
3181 SetFlag(kDependsOnGlobalVars);
3182 }
3183
3184 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3185 bool check_hole_value() const { return check_hole_value_; }
3186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003187 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003189 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003190 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191 return reinterpret_cast<intptr_t>(*cell_);
3192 }
3193
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003194 virtual Representation RequiredInputRepresentation(int index) const {
3195 return Representation::None();
3196 }
3197
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003198 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199
3200 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003201 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003202 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203 return cell_.is_identical_to(b->cell());
3204 }
3205
3206 private:
3207 Handle<JSGlobalPropertyCell> cell_;
3208 bool check_hole_value_;
3209};
3210
3211
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003212class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003213 public:
3214 HLoadGlobalGeneric(HValue* context,
3215 HValue* global_object,
3216 Handle<Object> name,
3217 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003218 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003219 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003220 SetOperandAt(0, context);
3221 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003222 set_representation(Representation::Tagged());
3223 SetAllSideEffects();
3224 }
3225
3226 HValue* context() { return OperandAt(0); }
3227 HValue* global_object() { return OperandAt(1); }
3228 Handle<Object> name() const { return name_; }
3229 bool for_typeof() const { return for_typeof_; }
3230
3231 virtual void PrintDataTo(StringStream* stream);
3232
3233 virtual Representation RequiredInputRepresentation(int index) const {
3234 return Representation::Tagged();
3235 }
3236
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003237 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003238
3239 private:
3240 Handle<Object> name_;
3241 bool for_typeof_;
3242};
3243
3244
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003245class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003246 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003247 HStoreGlobalCell(HValue* value,
3248 Handle<JSGlobalPropertyCell> cell,
3249 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003250 : HUnaryOperation(value),
3251 cell_(cell),
3252 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003253 SetFlag(kChangesGlobalVars);
3254 }
3255
3256 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003257 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003258
3259 virtual Representation RequiredInputRepresentation(int index) const {
3260 return Representation::Tagged();
3261 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003262 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003264 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003265
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003266 private:
3267 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003268 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003269};
3270
3271
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003272class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3273 public:
3274 HStoreGlobalGeneric(HValue* context,
3275 HValue* global_object,
3276 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003277 HValue* value,
3278 bool strict_mode)
3279 : name_(name),
3280 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003281 SetOperandAt(0, context);
3282 SetOperandAt(1, global_object);
3283 SetOperandAt(2, value);
3284 set_representation(Representation::Tagged());
3285 SetAllSideEffects();
3286 }
3287
3288 HValue* context() { return OperandAt(0); }
3289 HValue* global_object() { return OperandAt(1); }
3290 Handle<Object> name() const { return name_; }
3291 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003292 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003293
3294 virtual void PrintDataTo(StringStream* stream);
3295
3296 virtual Representation RequiredInputRepresentation(int index) const {
3297 return Representation::Tagged();
3298 }
3299
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003300 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003301
3302 private:
3303 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003304 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003305};
3306
3307
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003308class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003309 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003310 HLoadContextSlot(HValue* context , int slot_index)
3311 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003312 set_representation(Representation::Tagged());
3313 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003314 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003315 }
3316
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003317 int slot_index() const { return slot_index_; }
3318
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003319 virtual Representation RequiredInputRepresentation(int index) const {
3320 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003321 }
3322
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003323 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003324
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003325 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003326
3327 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003328 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003329 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003330 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003331 }
3332
3333 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003334 int slot_index_;
3335};
3336
3337
3338static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003339 return !value->type().IsBoolean()
3340 && !value->type().IsSmi()
3341 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003342}
3343
3344
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003345class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003346 public:
3347 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003348 : slot_index_(slot_index) {
3349 SetOperandAt(0, context);
3350 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003351 SetFlag(kChangesContextSlots);
3352 }
3353
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003354 HValue* context() { return OperandAt(0); }
3355 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003356 int slot_index() const { return slot_index_; }
3357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003359 return StoringValueNeedsWriteBarrier(value());
3360 }
3361
3362 virtual Representation RequiredInputRepresentation(int index) const {
3363 return Representation::Tagged();
3364 }
3365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003366 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003367
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003368 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003369
3370 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003371 int slot_index_;
3372};
3373
3374
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003375class HLoadNamedField: public HUnaryOperation {
3376 public:
3377 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3378 : HUnaryOperation(object),
3379 is_in_object_(is_in_object),
3380 offset_(offset) {
3381 set_representation(Representation::Tagged());
3382 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003383 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003384 if (is_in_object) {
3385 SetFlag(kDependsOnInobjectFields);
3386 } else {
3387 SetFlag(kDependsOnBackingStoreFields);
3388 }
3389 }
3390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003391 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003392 bool is_in_object() const { return is_in_object_; }
3393 int offset() const { return offset_; }
3394
3395 virtual Representation RequiredInputRepresentation(int index) const {
3396 return Representation::Tagged();
3397 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003398 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003400 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401
3402 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003403 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003404 HLoadNamedField* b = HLoadNamedField::cast(other);
3405 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3406 }
3407
3408 private:
3409 bool is_in_object_;
3410 int offset_;
3411};
3412
3413
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003414class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003415 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003416 HLoadNamedFieldPolymorphic(HValue* context,
3417 HValue* object,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003418 ZoneMapList* types,
3419 Handle<String> name);
3420
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003421 HValue* context() { return OperandAt(0); }
3422 HValue* object() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003423 ZoneMapList* types() { return &types_; }
3424 Handle<String> name() { return name_; }
3425 bool need_generic() { return need_generic_; }
3426
3427 virtual Representation RequiredInputRepresentation(int index) const {
3428 return Representation::Tagged();
3429 }
3430
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003431 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003432
3433 static const int kMaxLoadPolymorphism = 4;
3434
3435 protected:
3436 virtual bool DataEquals(HValue* value);
3437
3438 private:
3439 ZoneMapList types_;
3440 Handle<String> name_;
3441 bool need_generic_;
3442};
3443
3444
3445
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003446class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003447 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003448 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003449 : name_(name) {
3450 SetOperandAt(0, context);
3451 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003452 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003453 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003454 }
3455
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003456 HValue* context() { return OperandAt(0); }
3457 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003458 Handle<Object> name() const { return name_; }
3459
3460 virtual Representation RequiredInputRepresentation(int index) const {
3461 return Representation::Tagged();
3462 }
3463
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003464 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003466 private:
3467 Handle<Object> name_;
3468};
3469
3470
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003471class HLoadFunctionPrototype: public HUnaryOperation {
3472 public:
3473 explicit HLoadFunctionPrototype(HValue* function)
3474 : HUnaryOperation(function) {
3475 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003476 SetFlag(kUseGVN);
3477 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003478 }
3479
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003480 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003481
3482 virtual Representation RequiredInputRepresentation(int index) const {
3483 return Representation::Tagged();
3484 }
3485
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003486 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003487
3488 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003489 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003490};
3491
3492
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003493class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003494 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003495 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3496 SetOperandAt(0, obj);
3497 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003498 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003499 SetFlag(kDependsOnArrayElements);
3500 SetFlag(kUseGVN);
3501 }
3502
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003503 HValue* object() { return OperandAt(0); }
3504 HValue* key() { return OperandAt(1); }
3505
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003506 virtual Representation RequiredInputRepresentation(int index) const {
3507 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003508 return index == 0
3509 ? Representation::Tagged()
3510 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003511 }
3512
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003513 virtual void PrintDataTo(StringStream* stream);
3514
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003515 bool RequiresHoleCheck() const;
3516
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003517 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003518
3519 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003520 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003521};
3522
3523
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003524class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3525 public:
3526 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3527 SetOperandAt(0, elements);
3528 SetOperandAt(1, key);
3529 set_representation(Representation::Double());
3530 SetFlag(kDependsOnArrayElements);
3531 SetFlag(kUseGVN);
3532 }
3533
3534 HValue* elements() { return OperandAt(0); }
3535 HValue* key() { return OperandAt(1); }
3536
3537 virtual Representation RequiredInputRepresentation(int index) const {
3538 // The key is supposed to be Integer32.
3539 return index == 0
3540 ? Representation::Tagged()
3541 : Representation::Integer32();
3542 }
3543
3544 virtual void PrintDataTo(StringStream* stream);
3545
3546 bool RequiresHoleCheck() const;
3547
3548 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3549
3550 protected:
3551 virtual bool DataEquals(HValue* other) { return true; }
3552};
3553
3554
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003555class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003556 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003557 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3558 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003559 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003560 : elements_kind_(elements_kind) {
3561 SetOperandAt(0, external_elements);
3562 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003563 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3564 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003565 set_representation(Representation::Double());
3566 } else {
3567 set_representation(Representation::Integer32());
3568 }
3569 SetFlag(kDependsOnSpecializedArrayElements);
3570 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003571 SetFlag(kDependsOnCalls);
3572 SetFlag(kUseGVN);
3573 }
3574
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003575 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003576
3577 virtual Representation RequiredInputRepresentation(int index) const {
3578 // The key is supposed to be Integer32, but the base pointer
3579 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003580 return index == 0
3581 ? Representation::External()
3582 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003583 }
3584
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003585 HValue* external_pointer() { return OperandAt(0); }
3586 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003587 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003588
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003589 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003590
3591 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003592 virtual bool DataEquals(HValue* other) {
3593 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3594 HLoadKeyedSpecializedArrayElement* cast_other =
3595 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003596 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003597 }
3598
3599 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003600 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003601};
3602
3603
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003604class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003605 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003606 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003607 set_representation(Representation::Tagged());
3608 SetOperandAt(0, obj);
3609 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003610 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003611 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003612 }
3613
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003614 HValue* object() { return OperandAt(0); }
3615 HValue* key() { return OperandAt(1); }
3616 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003617
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003618 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619
3620 virtual Representation RequiredInputRepresentation(int index) const {
3621 return Representation::Tagged();
3622 }
3623
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003624 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625};
3626
3627
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003628class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003629 public:
3630 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003631 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632 HValue* val,
3633 bool in_object,
3634 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003635 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636 is_in_object_(in_object),
3637 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003638 SetOperandAt(0, obj);
3639 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003640 if (is_in_object_) {
3641 SetFlag(kChangesInobjectFields);
3642 } else {
3643 SetFlag(kChangesBackingStoreFields);
3644 }
3645 }
3646
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003647 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003648
3649 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003650 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003652 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003654 HValue* object() { return OperandAt(0); }
3655 HValue* value() { return OperandAt(1); }
3656
3657 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003658 bool is_in_object() const { return is_in_object_; }
3659 int offset() const { return offset_; }
3660 Handle<Map> transition() const { return transition_; }
3661 void set_transition(Handle<Map> map) { transition_ = map; }
3662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003663 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003664 return StoringValueNeedsWriteBarrier(value());
3665 }
3666
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003667 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003668 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003669 bool is_in_object_;
3670 int offset_;
3671 Handle<Map> transition_;
3672};
3673
3674
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003675class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003676 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003677 HStoreNamedGeneric(HValue* context,
3678 HValue* object,
3679 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003680 HValue* value,
3681 bool strict_mode)
3682 : name_(name),
3683 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003684 SetOperandAt(0, object);
3685 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003686 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003687 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003688 }
3689
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003690 HValue* object() { return OperandAt(0); }
3691 HValue* value() { return OperandAt(1); }
3692 HValue* context() { return OperandAt(2); }
3693 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003694 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003695
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003696 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003697
3698 virtual Representation RequiredInputRepresentation(int index) const {
3699 return Representation::Tagged();
3700 }
3701
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003702 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003703
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003704 private:
3705 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003706 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003707};
3708
3709
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003710class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003711 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003712 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3713 SetOperandAt(0, obj);
3714 SetOperandAt(1, key);
3715 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003716 SetFlag(kChangesArrayElements);
3717 }
3718
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003719 virtual Representation RequiredInputRepresentation(int index) const {
3720 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003721 return index == 1
3722 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003723 : Representation::Tagged();
3724 }
3725
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003726 HValue* object() { return OperandAt(0); }
3727 HValue* key() { return OperandAt(1); }
3728 HValue* value() { return OperandAt(2); }
3729
3730 bool NeedsWriteBarrier() {
3731 return StoringValueNeedsWriteBarrier(value());
3732 }
3733
3734 virtual void PrintDataTo(StringStream* stream);
3735
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003736 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003737};
3738
3739
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003740class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3741 public:
3742 HStoreKeyedFastDoubleElement(HValue* elements,
3743 HValue* key,
3744 HValue* val) {
3745 SetOperandAt(0, elements);
3746 SetOperandAt(1, key);
3747 SetOperandAt(2, val);
3748 SetFlag(kChangesArrayElements);
3749 }
3750
3751 virtual Representation RequiredInputRepresentation(int index) const {
3752 if (index == 1) {
3753 return Representation::Integer32();
3754 } else if (index == 2) {
3755 return Representation::Double();
3756 } else {
3757 return Representation::Tagged();
3758 }
3759 }
3760
3761 HValue* elements() { return OperandAt(0); }
3762 HValue* key() { return OperandAt(1); }
3763 HValue* value() { return OperandAt(2); }
3764
3765 bool NeedsWriteBarrier() {
3766 return StoringValueNeedsWriteBarrier(value());
3767 }
3768
3769 virtual void PrintDataTo(StringStream* stream);
3770
3771 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3772};
3773
3774
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003775class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003776 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003777 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3778 HValue* key,
3779 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003780 JSObject::ElementsKind elements_kind)
3781 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003782 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003783 SetOperandAt(0, external_elements);
3784 SetOperandAt(1, key);
3785 SetOperandAt(2, val);
3786 }
3787
3788 virtual void PrintDataTo(StringStream* stream);
3789
3790 virtual Representation RequiredInputRepresentation(int index) const {
3791 if (index == 0) {
3792 return Representation::External();
3793 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003794 bool float_or_double_elements =
3795 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3796 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3797 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003798 return Representation::Double();
3799 } else {
3800 return Representation::Integer32();
3801 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003802 }
3803 }
3804
3805 HValue* external_pointer() { return OperandAt(0); }
3806 HValue* key() { return OperandAt(1); }
3807 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003808 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003809
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003810 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3811
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003812 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003813 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003814};
3815
3816
3817class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003818 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003819 HStoreKeyedGeneric(HValue* context,
3820 HValue* object,
3821 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003822 HValue* value,
3823 bool strict_mode)
3824 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003825 SetOperandAt(0, object);
3826 SetOperandAt(1, key);
3827 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003828 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003829 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003830 }
3831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003832 HValue* object() { return OperandAt(0); }
3833 HValue* key() { return OperandAt(1); }
3834 HValue* value() { return OperandAt(2); }
3835 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003836 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003837
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003838 virtual Representation RequiredInputRepresentation(int index) const {
3839 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003840 }
3841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003842 virtual void PrintDataTo(StringStream* stream);
3843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003844 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003845
3846 private:
3847 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003848};
3849
3850
danno@chromium.org160a7b02011-04-18 15:51:38 +00003851class HStringAdd: public HBinaryOperation {
3852 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003853 HStringAdd(HValue* context, HValue* left, HValue* right)
3854 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003855 set_representation(Representation::Tagged());
3856 SetFlag(kUseGVN);
3857 SetFlag(kDependsOnMaps);
3858 }
3859
3860 virtual Representation RequiredInputRepresentation(int index) const {
3861 return Representation::Tagged();
3862 }
3863
3864 virtual HType CalculateInferredType() {
3865 return HType::String();
3866 }
3867
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003868 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003869
3870 protected:
3871 virtual bool DataEquals(HValue* other) { return true; }
3872};
3873
3874
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003875class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003876 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003877 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3878 SetOperandAt(0, context);
3879 SetOperandAt(1, string);
3880 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003881 set_representation(Representation::Integer32());
3882 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003883 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003884 }
3885
3886 virtual Representation RequiredInputRepresentation(int index) const {
3887 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003888 return index == 2
3889 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003890 : Representation::Tagged();
3891 }
3892
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003893 HValue* context() { return OperandAt(0); }
3894 HValue* string() { return OperandAt(1); }
3895 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003896
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003897 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003898
3899 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003900 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003901
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003902 virtual Range* InferRange() {
3903 return new Range(0, String::kMaxUC16CharCode);
3904 }
3905};
3906
3907
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003908class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003909 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003910 HStringCharFromCode(HValue* context, HValue* char_code) {
3911 SetOperandAt(0, context);
3912 SetOperandAt(1, char_code);
3913 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003914 SetFlag(kUseGVN);
3915 }
3916
3917 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003918 return index == 0
3919 ? Representation::Tagged()
3920 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003921 }
3922
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003923 HValue* context() { return OperandAt(0); }
3924 HValue* value() { return OperandAt(1); }
3925
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003926 virtual bool DataEquals(HValue* other) { return true; }
3927
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003928 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003929};
3930
3931
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003932class HStringLength: public HUnaryOperation {
3933 public:
3934 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3935 set_representation(Representation::Tagged());
3936 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003937 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003938 }
3939
3940 virtual Representation RequiredInputRepresentation(int index) const {
3941 return Representation::Tagged();
3942 }
3943
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003944 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003945 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3946 return HType::Smi();
3947 }
3948
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003949 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003950
3951 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003952 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003953
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003954 virtual Range* InferRange() {
3955 return new Range(0, String::kMaxLength);
3956 }
3957};
3958
3959
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003960template <int V>
3961class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003962 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003963 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003964 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003965 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003966 }
3967
3968 int literal_index() const { return literal_index_; }
3969 int depth() const { return depth_; }
3970
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003971 private:
3972 int literal_index_;
3973 int depth_;
3974};
3975
3976
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003977class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003978 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003979 HArrayLiteral(HValue* context,
3980 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003981 int length,
3982 int literal_index,
3983 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003984 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003985 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003986 constant_elements_(constant_elements) {
3987 SetOperandAt(0, context);
3988 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003989
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003990 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003991 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3992 int length() const { return length_; }
3993
3994 bool IsCopyOnWrite() const;
3995
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003996 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003997 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003998 }
3999
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004000 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004001
4002 private:
4003 int length_;
4004 Handle<FixedArray> constant_elements_;
4005};
4006
4007
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004008class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004009 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004010 HObjectLiteral(HValue* context,
4011 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004012 bool fast_elements,
4013 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004014 int depth,
4015 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004016 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004017 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004018 fast_elements_(fast_elements),
4019 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004020 SetOperandAt(0, context);
4021 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004022
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004023 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004024 Handle<FixedArray> constant_properties() const {
4025 return constant_properties_;
4026 }
4027 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004028 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004030 virtual Representation RequiredInputRepresentation(int index) const {
4031 return Representation::Tagged();
4032 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004033
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004034 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004035
4036 private:
4037 Handle<FixedArray> constant_properties_;
4038 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004039 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004040};
4041
4042
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004043class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004044 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004045 HRegExpLiteral(HValue* context,
4046 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004047 Handle<String> flags,
4048 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004049 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004050 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004051 flags_(flags) {
4052 SetOperandAt(0, context);
4053 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004054
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004055 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004056 Handle<String> pattern() { return pattern_; }
4057 Handle<String> flags() { return flags_; }
4058
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004059 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004060 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004061 }
4062
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004063 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004064
4065 private:
4066 Handle<String> pattern_;
4067 Handle<String> flags_;
4068};
4069
4070
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004071class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004072 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004073 HFunctionLiteral(HValue* context,
4074 Handle<SharedFunctionInfo> shared,
4075 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004076 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004077 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004078 set_representation(Representation::Tagged());
4079 }
4080
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004081 HValue* context() { return OperandAt(0); }
4082
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004083 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004084 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004085 }
4086
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004087 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004088
4089 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4090 bool pretenure() const { return pretenure_; }
4091
4092 private:
4093 Handle<SharedFunctionInfo> shared_info_;
4094 bool pretenure_;
4095};
4096
4097
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004098class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004099 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004100 explicit HTypeof(HValue* context, HValue* value) {
4101 SetOperandAt(0, context);
4102 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004103 set_representation(Representation::Tagged());
4104 }
4105
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004106 HValue* context() { return OperandAt(0); }
4107 HValue* value() { return OperandAt(1); }
4108
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004109 virtual Representation RequiredInputRepresentation(int index) const {
4110 return Representation::Tagged();
4111 }
4112
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004113 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004114};
4115
4116
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004117class HToFastProperties: public HUnaryOperation {
4118 public:
4119 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4120 // This instruction is not marked as having side effects, but
4121 // changes the map of the input operand. Use it only when creating
4122 // object literals.
4123 ASSERT(value->IsObjectLiteral());
4124 set_representation(Representation::Tagged());
4125 }
4126
4127 virtual Representation RequiredInputRepresentation(int index) const {
4128 return Representation::Tagged();
4129 }
4130
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004131 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004132};
4133
4134
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004135class HValueOf: public HUnaryOperation {
4136 public:
4137 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4138 set_representation(Representation::Tagged());
4139 }
4140
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004141 virtual Representation RequiredInputRepresentation(int index) const {
4142 return Representation::Tagged();
4143 }
4144
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004145 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004146};
4147
4148
4149class HDeleteProperty: public HBinaryOperation {
4150 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004151 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4152 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004153 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004154 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004155 }
4156
4157 virtual Representation RequiredInputRepresentation(int index) const {
4158 return Representation::Tagged();
4159 }
4160
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004161 virtual HType CalculateInferredType();
4162
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004163 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004164
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004165 HValue* object() { return left(); }
4166 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004167};
4168
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004169
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004170class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004171 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004172 HIn(HValue* context, HValue* key, HValue* object) {
4173 SetOperandAt(0, context);
4174 SetOperandAt(1, key);
4175 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004176 set_representation(Representation::Tagged());
4177 SetAllSideEffects();
4178 }
4179
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004180 HValue* context() { return OperandAt(0); }
4181 HValue* key() { return OperandAt(1); }
4182 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004183
4184 virtual Representation RequiredInputRepresentation(int index) const {
4185 return Representation::Tagged();
4186 }
4187
4188 virtual HType CalculateInferredType() {
4189 return HType::Boolean();
4190 }
4191
4192 virtual void PrintDataTo(StringStream* stream);
4193
4194 DECLARE_CONCRETE_INSTRUCTION(In)
4195};
4196
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004197#undef DECLARE_INSTRUCTION
4198#undef DECLARE_CONCRETE_INSTRUCTION
4199
4200} } // namespace v8::internal
4201
4202#endif // V8_HYDROGEN_INSTRUCTIONS_H_