blob: 23c0ae664cdf88ef38f4ea1ebc4296552610e38f [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) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000187 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000188 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000189 V(GlobalVars) \
190 V(Maps) \
191 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000192 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193 V(OsrEntries)
194
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000195#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000196 virtual bool Is##type() const { return true; } \
197 static H##type* cast(HValue* value) { \
198 ASSERT(value->Is##type()); \
199 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000200 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201
202
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000203#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000205 static H##type* cast(HValue* value) { \
206 ASSERT(value->Is##type()); \
207 return reinterpret_cast<H##type*>(value); \
208 } \
209 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000210
211
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212class Range: public ZoneObject {
213 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000214 Range()
215 : lower_(kMinInt),
216 upper_(kMaxInt),
217 next_(NULL),
218 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000219
220 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000221 : lower_(lower),
222 upper_(upper),
223 next_(NULL),
224 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 int32_t upper() const { return upper_; }
227 int32_t lower() const { return lower_; }
228 Range* next() const { return next_; }
229 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
230 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000232 int32_t Mask() const;
233 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
234 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
235 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
236 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000237 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
238 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
239 bool IsInSmiRange() const {
240 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000241 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000242 void KeepOrder();
243 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000244
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000245 void StackUpon(Range* other) {
246 Intersect(other);
247 next_ = other;
248 }
249
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000250 void Intersect(Range* other);
251 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000252
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000253 void AddConstant(int32_t value);
254 void Sar(int32_t value);
255 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000256 bool AddAndCheckOverflow(Range* other);
257 bool SubAndCheckOverflow(Range* other);
258 bool MulAndCheckOverflow(Range* other);
259
260 private:
261 int32_t lower_;
262 int32_t upper_;
263 Range* next_;
264 bool can_be_minus_zero_;
265};
266
267
268class Representation {
269 public:
270 enum Kind {
271 kNone,
272 kTagged,
273 kDouble,
274 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000275 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276 kNumRepresentations
277 };
278
279 Representation() : kind_(kNone) { }
280
281 static Representation None() { return Representation(kNone); }
282 static Representation Tagged() { return Representation(kTagged); }
283 static Representation Integer32() { return Representation(kInteger32); }
284 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000285 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000286
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000287 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000288 return kind_ == other.kind_;
289 }
290
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000291 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000292 bool IsNone() const { return kind_ == kNone; }
293 bool IsTagged() const { return kind_ == kTagged; }
294 bool IsInteger32() const { return kind_ == kInteger32; }
295 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000296 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000297 bool IsSpecialization() const {
298 return kind_ == kInteger32 || kind_ == kDouble;
299 }
300 const char* Mnemonic() const;
301
302 private:
303 explicit Representation(Kind k) : kind_(k) { }
304
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000305 // Make sure kind fits in int8.
306 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
307
308 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000309};
310
311
312class HType {
313 public:
314 HType() : type_(kUninitialized) { }
315
316 static HType Tagged() { return HType(kTagged); }
317 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
318 static HType TaggedNumber() { return HType(kTaggedNumber); }
319 static HType Smi() { return HType(kSmi); }
320 static HType HeapNumber() { return HType(kHeapNumber); }
321 static HType String() { return HType(kString); }
322 static HType Boolean() { return HType(kBoolean); }
323 static HType NonPrimitive() { return HType(kNonPrimitive); }
324 static HType JSArray() { return HType(kJSArray); }
325 static HType JSObject() { return HType(kJSObject); }
326 static HType Uninitialized() { return HType(kUninitialized); }
327
328 // Return the weakest (least precise) common type.
329 HType Combine(HType other) {
330 return HType(static_cast<Type>(type_ & other.type_));
331 }
332
333 bool Equals(const HType& other) {
334 return type_ == other.type_;
335 }
336
337 bool IsSubtypeOf(const HType& other) {
338 return Combine(other).Equals(other);
339 }
340
341 bool IsTagged() {
342 ASSERT(type_ != kUninitialized);
343 return ((type_ & kTagged) == kTagged);
344 }
345
346 bool IsTaggedPrimitive() {
347 ASSERT(type_ != kUninitialized);
348 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
349 }
350
351 bool IsTaggedNumber() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kTaggedNumber) == kTaggedNumber);
354 }
355
356 bool IsSmi() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kSmi) == kSmi);
359 }
360
361 bool IsHeapNumber() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kHeapNumber) == kHeapNumber);
364 }
365
366 bool IsString() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kString) == kString);
369 }
370
371 bool IsBoolean() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kBoolean) == kBoolean);
374 }
375
376 bool IsNonPrimitive() {
377 ASSERT(type_ != kUninitialized);
378 return ((type_ & kNonPrimitive) == kNonPrimitive);
379 }
380
381 bool IsJSArray() {
382 ASSERT(type_ != kUninitialized);
383 return ((type_ & kJSArray) == kJSArray);
384 }
385
386 bool IsJSObject() {
387 ASSERT(type_ != kUninitialized);
388 return ((type_ & kJSObject) == kJSObject);
389 }
390
391 bool IsUninitialized() {
392 return type_ == kUninitialized;
393 }
394
395 static HType TypeFromValue(Handle<Object> value);
396
397 const char* ToString();
398 const char* ToShortString();
399
400 private:
401 enum Type {
402 kTagged = 0x1, // 0000 0000 0000 0001
403 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
404 kTaggedNumber = 0xd, // 0000 0000 0000 1101
405 kSmi = 0x1d, // 0000 0000 0001 1101
406 kHeapNumber = 0x2d, // 0000 0000 0010 1101
407 kString = 0x45, // 0000 0000 0100 0101
408 kBoolean = 0x85, // 0000 0000 1000 0101
409 kNonPrimitive = 0x101, // 0000 0001 0000 0001
410 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000411 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000412 kUninitialized = 0x1fff // 0001 1111 1111 1111
413 };
414
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000415 // Make sure type fits in int16.
416 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
417
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000418 explicit HType(Type t) : type_(t) { }
419
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000420 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000421};
422
423
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000424class HUseListNode: public ZoneObject {
425 public:
426 HUseListNode(HValue* value, int index, HUseListNode* tail)
427 : tail_(tail), value_(value), index_(index) {
428 }
429
430 HUseListNode* tail() const { return tail_; }
431 HValue* value() const { return value_; }
432 int index() const { return index_; }
433
434 void set_tail(HUseListNode* list) { tail_ = list; }
435
436#ifdef DEBUG
437 void Zap() {
438 tail_ = reinterpret_cast<HUseListNode*>(1);
439 value_ = NULL;
440 index_ = -1;
441 }
442#endif
443
444 private:
445 HUseListNode* tail_;
446 HValue* value_;
447 int index_;
448};
449
450
451// We reuse use list nodes behind the scenes as uses are added and deleted.
452// This class is the safe way to iterate uses while deleting them.
453class HUseIterator BASE_EMBEDDED {
454 public:
455 bool Done() { return current_ == NULL; }
456 void Advance();
457
458 HValue* value() {
459 ASSERT(!Done());
460 return value_;
461 }
462
463 int index() {
464 ASSERT(!Done());
465 return index_;
466 }
467
468 private:
469 explicit HUseIterator(HUseListNode* head);
470
471 HUseListNode* current_;
472 HUseListNode* next_;
473 HValue* value_;
474 int index_;
475
476 friend class HValue;
477};
478
479
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000480class HValue: public ZoneObject {
481 public:
482 static const int kNoNumber = -1;
483
484 // There must be one corresponding kDepends flag for every kChanges flag and
485 // the order of the kChanges flags must be exactly the same as of the kDepends
486 // flags.
487 enum Flag {
488 // Declare global value numbering flags.
489 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
490 GVN_FLAG_LIST(DECLARE_DO)
491 #undef DECLARE_DO
492 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000493 // Participate in Global Value Numbering, i.e. elimination of
494 // unnecessary recomputations. If an instruction sets this flag, it must
495 // implement DataEquals(), which will be used to determine if other
496 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000497 kUseGVN,
498 kCanOverflow,
499 kBailoutOnMinusZero,
500 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000501 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000502 kIsArguments,
503 kTruncatingToInt32,
504 kLastFlag = kTruncatingToInt32
505 };
506
507 STATIC_ASSERT(kLastFlag < kBitsPerInt);
508
509 static const int kChangesToDependsFlagsLeftShift = 1;
510
511 static int ChangesFlagsMask() {
512 int result = 0;
513 // Create changes mask.
514#define DECLARE_DO(type) result |= (1 << kChanges##type);
515 GVN_FLAG_LIST(DECLARE_DO)
516#undef DECLARE_DO
517 return result;
518 }
519
520 static int DependsFlagsMask() {
521 return ConvertChangesToDependsFlags(ChangesFlagsMask());
522 }
523
524 static int ConvertChangesToDependsFlags(int flags) {
525 return flags << kChangesToDependsFlagsLeftShift;
526 }
527
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000528 static HValue* cast(HValue* value) { return value; }
529
530 enum Opcode {
531 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000532 #define DECLARE_OPCODE(type) k##type,
533 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
534 kPhi
535 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000536 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000537 virtual Opcode opcode() const = 0;
538
539 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
540 #define DECLARE_PREDICATE(type) \
541 bool Is##type() const { return opcode() == k##type; }
542 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
543 #undef DECLARE_PREDICATE
544 bool IsPhi() const { return opcode() == kPhi; }
545
546 // Declare virtual predicates for abstract HInstruction or HValue
547 #define DECLARE_PREDICATE(type) \
548 virtual bool Is##type() const { return false; }
549 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
550 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551
552 HValue() : block_(NULL),
553 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000554 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000555 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000556 range_(NULL),
557 flags_(0) {}
558 virtual ~HValue() {}
559
560 HBasicBlock* block() const { return block_; }
561 void SetBlock(HBasicBlock* block);
562
563 int id() const { return id_; }
564 void set_id(int id) { id_ = id; }
565
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000566 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000567
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000568 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569 Representation representation() const { return representation_; }
570 void ChangeRepresentation(Representation r) {
571 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000572 ASSERT(!r.IsNone());
573 ASSERT(CheckFlag(kFlexibleRepresentation));
574 RepresentationChanged(r);
575 representation_ = r;
576 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000577 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000579 virtual bool IsConvertibleToInteger() const { return true; }
580
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581 HType type() const { return type_; }
582 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000583 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000584 type_ = type;
585 }
586
587 // An operation needs to override this function iff:
588 // 1) it can produce an int32 output.
589 // 2) the true value of its output can potentially be minus zero.
590 // The implementation must set a flag so that it bails out in the case where
591 // it would otherwise output what should be a minus zero as an int32 zero.
592 // If the operation also exists in a form that takes int32 and outputs int32
593 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000594 // back. There are three operations that need to propagate back to more than
595 // one input. They are phi and binary div and mul. They always return NULL
596 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000597 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
598 visited->Add(id());
599 return NULL;
600 }
601
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000602 bool IsDefinedAfter(HBasicBlock* other) const;
603
604 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000605 virtual int OperandCount() = 0;
606 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000607 void SetOperandAt(int index, HValue* value);
608
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000609 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000610 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000611 bool HasNoUses() const { return use_list_ == NULL; }
612 bool HasMultipleUses() const {
613 return use_list_ != NULL && use_list_->tail() != NULL;
614 }
615 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000616 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000617
618 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000619 void SetFlag(Flag f) { flags_ |= (1 << f); }
620 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
621 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
622
623 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
624 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
625 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000626
627 Range* range() const { return range_; }
628 bool HasRange() const { return range_ != NULL; }
629 void AddNewRange(Range* r);
630 void RemoveLastAddedRange();
631 void ComputeInitialRange();
632
633 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000634 virtual Representation RequiredInputRepresentation(int index) const = 0;
635
636 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000637 return representation();
638 }
639
640 // This gives the instruction an opportunity to replace itself with an
641 // instruction that does the same in some better way. To replace an
642 // instruction with a new one, first add the new instruction to the graph,
643 // then return it. Return NULL to have the instruction deleted.
644 virtual HValue* Canonicalize() { return this; }
645
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000646 bool Equals(HValue* other);
647 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648
649 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000650 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000651 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000652 void PrintTypeTo(StringStream* stream);
653 void PrintRangeTo(StringStream* stream);
654 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000655
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000656 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000657
658 // Updated the inferred type of this instruction and returns true if
659 // it has changed.
660 bool UpdateInferredType();
661
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000662 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000664#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000665 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000666#endif
667
668 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000669 // This function must be overridden for instructions with flag kUseGVN, to
670 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000671 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000672 UNREACHABLE();
673 return false;
674 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000675 virtual void RepresentationChanged(Representation to) { }
676 virtual Range* InferRange();
677 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000678 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000679 void clear_block() {
680 ASSERT(block_ != NULL);
681 block_ = NULL;
682 }
683
684 void set_representation(Representation r) {
685 // Representation is set-once.
686 ASSERT(representation_.IsNone() && !r.IsNone());
687 representation_ = r;
688 }
689
690 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000691 // A flag mask to mark an instruction as having arbitrary side effects.
692 static int AllSideEffects() {
693 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
694 }
695
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000696 // Remove the matching use from the use list if present. Returns the
697 // removed list node or NULL.
698 HUseListNode* RemoveUse(HValue* value, int index);
699
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000700 void RegisterUse(int index, HValue* new_value);
701
702 HBasicBlock* block_;
703
704 // The id of this instruction in the hydrogen graph, assigned when first
705 // added to the graph. Reflects creation order.
706 int id_;
707
708 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000709 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000710 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000711 Range* range_;
712 int flags_;
713
714 DISALLOW_COPY_AND_ASSIGN(HValue);
715};
716
717
718class HInstruction: public HValue {
719 public:
720 HInstruction* next() const { return next_; }
721 HInstruction* previous() const { return previous_; }
722
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000723 virtual void PrintTo(StringStream* stream);
724 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000725
726 bool IsLinked() const { return block() != NULL; }
727 void Unlink();
728 void InsertBefore(HInstruction* next);
729 void InsertAfter(HInstruction* previous);
730
731 int position() const { return position_; }
732 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
733 void set_position(int position) { position_ = position; }
734
735 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
736
737#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000738 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000739#endif
740
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000741 virtual bool IsCall() { return false; }
742
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000743 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000744
745 protected:
746 HInstruction()
747 : next_(NULL),
748 previous_(NULL),
749 position_(RelocInfo::kNoPosition) {
750 SetFlag(kDependsOnOsrEntries);
751 }
752
753 virtual void DeleteFromGraph() { Unlink(); }
754
755 private:
756 void InitializeAsFirst(HBasicBlock* block) {
757 ASSERT(!IsLinked());
758 SetBlock(block);
759 }
760
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000761 void PrintMnemonicTo(StringStream* stream);
762
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000763 HInstruction* next_;
764 HInstruction* previous_;
765 int position_;
766
767 friend class HBasicBlock;
768};
769
770
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000771template<int V>
772class HTemplateInstruction : public HInstruction {
773 public:
774 int OperandCount() { return V; }
775 HValue* OperandAt(int i) { return inputs_[i]; }
776
777 protected:
778 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
779
780 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000781 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000782};
783
784
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000785class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000786 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000787 virtual HBasicBlock* SuccessorAt(int i) = 0;
788 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000789 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000790
791 virtual void PrintDataTo(StringStream* stream);
792
793 HBasicBlock* FirstSuccessor() {
794 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
795 }
796 HBasicBlock* SecondSuccessor() {
797 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
798 }
799
800 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
801};
802
803
804class HSuccessorIterator BASE_EMBEDDED {
805 public:
806 explicit HSuccessorIterator(HControlInstruction* instr)
807 : instr_(instr), current_(0) { }
808
809 bool Done() { return current_ >= instr_->SuccessorCount(); }
810 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
811 void Advance() { current_++; }
812
813 private:
814 HControlInstruction* instr_;
815 int current_;
816};
817
818
819template<int S, int V>
820class HTemplateControlInstruction: public HControlInstruction {
821 public:
822 int SuccessorCount() { return S; }
823 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000824 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000826 int OperandCount() { return V; }
827 HValue* OperandAt(int i) { return inputs_[i]; }
828
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000830 protected:
831 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
832
833 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000834 EmbeddedContainer<HBasicBlock*, S> successors_;
835 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000836};
837
838
839class HBlockEntry: public HTemplateInstruction<0> {
840 public:
841 virtual Representation RequiredInputRepresentation(int index) const {
842 return Representation::None();
843 }
844
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000845 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000846};
847
848
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000849// We insert soft-deoptimize when we hit code with unknown typefeedback,
850// so that we get a chance of re-optimizing with useful typefeedback.
851// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
852class HSoftDeoptimize: public HTemplateInstruction<0> {
853 public:
854 virtual Representation RequiredInputRepresentation(int index) const {
855 return Representation::None();
856 }
857
858 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
859};
860
861
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000862class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000863 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000864 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000865
866 virtual Representation RequiredInputRepresentation(int index) const {
867 return Representation::None();
868 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000869
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870 virtual int OperandCount() { return values_.length(); }
871 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000872 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000873
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000874 virtual int SuccessorCount() { return 0; }
875 virtual HBasicBlock* SuccessorAt(int i) {
876 UNREACHABLE();
877 return NULL;
878 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000879 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
880 UNREACHABLE();
881 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000882
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000883 void AddEnvironmentValue(HValue* value) {
884 values_.Add(NULL);
885 SetOperandAt(values_.length() - 1, value);
886 }
887
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000888 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000889
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000890 enum UseEnvironment {
891 kNoUses,
892 kUseAll
893 };
894
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000895 protected:
896 virtual void InternalSetOperandAt(int index, HValue* value) {
897 values_[index] = value;
898 }
899
900 private:
901 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000902};
903
904
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000905class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000907 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000908 SetSuccessorAt(0, target);
909 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000910
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000911 virtual Representation RequiredInputRepresentation(int index) const {
912 return Representation::None();
913 }
914
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000915 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000916};
917
918
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000919class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000920 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000921 HUnaryControlInstruction(HValue* value,
922 HBasicBlock* true_target,
923 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000924 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000925 SetSuccessorAt(0, true_target);
926 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927 }
928
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000929 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000931 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932};
933
934
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000935class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000937 HBranch(HValue* value,
938 HBasicBlock* true_target,
939 HBasicBlock* false_target,
940 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
941 : HUnaryControlInstruction(value, true_target, false_target),
942 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000943 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000944 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000945 explicit HBranch(HValue* value)
946 : HUnaryControlInstruction(value, NULL, NULL) { }
947
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000948
949 virtual Representation RequiredInputRepresentation(int index) const {
950 return Representation::None();
951 }
952
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000953 ToBooleanStub::Types expected_input_types() const {
954 return expected_input_types_;
955 }
956
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000957 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000958
959 private:
960 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000961};
962
963
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000964class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000966 HCompareMap(HValue* value,
967 Handle<Map> map,
968 HBasicBlock* true_target,
969 HBasicBlock* false_target)
970 : HUnaryControlInstruction(value, true_target, false_target),
971 map_(map) {
972 ASSERT(true_target != NULL);
973 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974 ASSERT(!map.is_null());
975 }
976
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000977 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000978
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 Handle<Map> map() const { return map_; }
980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000981 virtual Representation RequiredInputRepresentation(int index) const {
982 return Representation::Tagged();
983 }
984
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000985 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000986
987 private:
988 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000989};
990
991
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000992class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000993 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000994 explicit HReturn(HValue* value) {
995 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000996 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000998 virtual Representation RequiredInputRepresentation(int index) const {
999 return Representation::Tagged();
1000 }
1001
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001002 virtual void PrintDataTo(StringStream* stream);
1003
1004 HValue* value() { return OperandAt(0); }
1005
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001006 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001007};
1008
1009
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001010class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001011 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001012 virtual Representation RequiredInputRepresentation(int index) const {
1013 return Representation::None();
1014 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001015
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001016 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001017};
1018
1019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001020class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001021 public:
1022 explicit HUnaryOperation(HValue* value) {
1023 SetOperandAt(0, value);
1024 }
1025
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001026 static HUnaryOperation* cast(HValue* value) {
1027 return reinterpret_cast<HUnaryOperation*>(value);
1028 }
1029
1030 virtual bool CanTruncateToInt32() const {
1031 return CheckFlag(kTruncatingToInt32);
1032 }
1033
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001034 HValue* value() { return OperandAt(0); }
1035 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001036};
1037
1038
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001039class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001040 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001041 HThrow(HValue* context, HValue* value) {
1042 SetOperandAt(0, context);
1043 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001044 SetAllSideEffects();
1045 }
1046
1047 virtual Representation RequiredInputRepresentation(int index) const {
1048 return Representation::Tagged();
1049 }
1050
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001051 HValue* context() { return OperandAt(0); }
1052 HValue* value() { return OperandAt(1); }
1053
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001054 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001055};
1056
1057
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001058class HUseConst: public HUnaryOperation {
1059 public:
1060 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1061
1062 virtual Representation RequiredInputRepresentation(int index) const {
1063 return Representation::None();
1064 }
1065
1066 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1067};
1068
1069
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001070class HForceRepresentation: public HTemplateInstruction<1> {
1071 public:
1072 HForceRepresentation(HValue* value, Representation required_representation) {
1073 SetOperandAt(0, value);
1074 set_representation(required_representation);
1075 }
1076
1077 HValue* value() { return OperandAt(0); }
1078
1079 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1080
1081 virtual Representation RequiredInputRepresentation(int index) const {
1082 return representation(); // Same as the output representation.
1083 }
1084
1085 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1086};
1087
1088
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001089class HChange: public HUnaryOperation {
1090 public:
1091 HChange(HValue* value,
1092 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001093 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001094 bool is_truncating,
1095 bool deoptimize_on_undefined)
1096 : HUnaryOperation(value),
1097 from_(from),
1098 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001099 ASSERT(!from.IsNone() && !to.IsNone());
1100 ASSERT(!from.Equals(to));
1101 set_representation(to);
1102 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001103 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1105 value->range()->IsInSmiRange()) {
1106 set_type(HType::Smi());
1107 }
1108 }
1109
1110 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1111
1112 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001113 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001114 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115 virtual Representation RequiredInputRepresentation(int index) const {
1116 return from_;
1117 }
1118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001119 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001120
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001121 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001122
1123 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001124 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001125 if (!other->IsChange()) return false;
1126 HChange* change = HChange::cast(other);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001127 return to().Equals(change->to())
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001128 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001129 }
1130
1131 private:
1132 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001133 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001134};
1135
1136
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001137class HClampToUint8: public HUnaryOperation {
1138 public:
1139 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001140 : HUnaryOperation(value) {
1141 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001142 SetFlag(kUseGVN);
1143 }
1144
1145 virtual Representation RequiredInputRepresentation(int index) const {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001146 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001147 }
1148
1149 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1150
1151 protected:
1152 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001153};
1154
1155
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001156class HToInt32: public HUnaryOperation {
1157 public:
1158 explicit HToInt32(HValue* value)
1159 : HUnaryOperation(value) {
1160 set_representation(Representation::Integer32());
1161 SetFlag(kUseGVN);
1162 }
1163
1164 virtual Representation RequiredInputRepresentation(int index) const {
1165 return Representation::None();
1166 }
1167
1168 virtual bool CanTruncateToInt32() const {
1169 return true;
1170 }
1171
1172 virtual HValue* Canonicalize() {
1173 if (value()->representation().IsInteger32()) {
1174 return value();
1175 } else {
1176 return this;
1177 }
1178 }
1179
1180 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1181
1182 protected:
1183 virtual bool DataEquals(HValue* other) { return true; }
1184};
1185
1186
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001187class HSimulate: public HInstruction {
1188 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001189 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190 : ast_id_(ast_id),
1191 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001192 values_(2),
1193 assigned_indexes_(2) {}
1194 virtual ~HSimulate() {}
1195
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001196 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001197
1198 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1199 int ast_id() const { return ast_id_; }
1200 void set_ast_id(int id) {
1201 ASSERT(!HasAstId());
1202 ast_id_ = id;
1203 }
1204
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205 int pop_count() const { return pop_count_; }
1206 const ZoneList<HValue*>* values() const { return &values_; }
1207 int GetAssignedIndexAt(int index) const {
1208 ASSERT(HasAssignedIndexAt(index));
1209 return assigned_indexes_[index];
1210 }
1211 bool HasAssignedIndexAt(int index) const {
1212 return assigned_indexes_[index] != kNoIndex;
1213 }
1214 void AddAssignedValue(int index, HValue* value) {
1215 AddValue(index, value);
1216 }
1217 void AddPushedValue(HValue* value) {
1218 AddValue(kNoIndex, value);
1219 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001220 virtual int OperandCount() { return values_.length(); }
1221 virtual HValue* OperandAt(int index) { return values_[index]; }
1222
1223 virtual Representation RequiredInputRepresentation(int index) const {
1224 return Representation::None();
1225 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001226
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001227 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001228
1229#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001230 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001231#endif
1232
1233 protected:
1234 virtual void InternalSetOperandAt(int index, HValue* value) {
1235 values_[index] = value;
1236 }
1237
1238 private:
1239 static const int kNoIndex = -1;
1240 void AddValue(int index, HValue* value) {
1241 assigned_indexes_.Add(index);
1242 // Resize the list of pushed values.
1243 values_.Add(NULL);
1244 // Set the operand through the base method in HValue to make sure that the
1245 // use lists are correctly updated.
1246 SetOperandAt(values_.length() - 1, value);
1247 }
1248 int ast_id_;
1249 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 ZoneList<HValue*> values_;
1251 ZoneList<int> assigned_indexes_;
1252};
1253
1254
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001255class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001256 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001257 enum Type {
1258 kFunctionEntry,
1259 kBackwardsBranch
1260 };
1261
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001262 HStackCheck(HValue* context, Type type) : type_(type) {
1263 SetOperandAt(0, context);
1264 }
1265
1266 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001268 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001269 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001270 }
1271
ager@chromium.org04921a82011-06-27 13:21:41 +00001272 void Eliminate() {
1273 // The stack check eliminator might try to eliminate the same stack
1274 // check instruction multiple times.
1275 if (IsLinked()) {
1276 DeleteFromGraph();
1277 }
1278 }
1279
1280 bool is_function_entry() { return type_ == kFunctionEntry; }
1281 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1282
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001283 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001284
1285 private:
1286 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287};
1288
1289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001290class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001291 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001292 HEnterInlined(Handle<JSFunction> closure,
1293 FunctionLiteral* function,
1294 CallKind call_kind)
1295 : closure_(closure),
1296 function_(function),
1297 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001298 }
1299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001300 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001301
1302 Handle<JSFunction> closure() const { return closure_; }
1303 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001304 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001306 virtual Representation RequiredInputRepresentation(int index) const {
1307 return Representation::None();
1308 }
1309
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001310 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001311
1312 private:
1313 Handle<JSFunction> closure_;
1314 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001315 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001316};
1317
1318
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001319class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001320 public:
1321 HLeaveInlined() {}
1322
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001323 virtual Representation RequiredInputRepresentation(int index) const {
1324 return Representation::None();
1325 }
1326
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001327 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328};
1329
1330
1331class HPushArgument: public HUnaryOperation {
1332 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001333 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1334 set_representation(Representation::Tagged());
1335 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001336
1337 virtual Representation RequiredInputRepresentation(int index) const {
1338 return Representation::Tagged();
1339 }
1340
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001341 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001342
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001343 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001344};
1345
1346
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001347class HThisFunction: public HTemplateInstruction<0> {
1348 public:
1349 HThisFunction() {
1350 set_representation(Representation::Tagged());
1351 SetFlag(kUseGVN);
1352 }
1353
1354 virtual Representation RequiredInputRepresentation(int index) const {
1355 return Representation::None();
1356 }
1357
1358 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1359
1360 protected:
1361 virtual bool DataEquals(HValue* other) { return true; }
1362};
1363
1364
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001365class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001366 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001367 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001368 set_representation(Representation::Tagged());
1369 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001370 }
1371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372 virtual Representation RequiredInputRepresentation(int index) const {
1373 return Representation::None();
1374 }
1375
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001376 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001377
1378 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001379 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001380};
1381
1382
1383class HOuterContext: public HUnaryOperation {
1384 public:
1385 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1386 set_representation(Representation::Tagged());
1387 SetFlag(kUseGVN);
1388 }
1389
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001390 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001392 virtual Representation RequiredInputRepresentation(int index) const {
1393 return Representation::Tagged();
1394 }
1395
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001396 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001397 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001398};
1399
1400
1401class HGlobalObject: public HUnaryOperation {
1402 public:
1403 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1404 set_representation(Representation::Tagged());
1405 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406 }
1407
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001408 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001410 virtual Representation RequiredInputRepresentation(int index) const {
1411 return Representation::Tagged();
1412 }
1413
ager@chromium.org378b34e2011-01-28 08:04:38 +00001414 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001415 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001416};
1417
1418
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001419class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001420 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001421 explicit HGlobalReceiver(HValue* global_object)
1422 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 set_representation(Representation::Tagged());
1424 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001425 }
1426
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001427 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001429 virtual Representation RequiredInputRepresentation(int index) const {
1430 return Representation::Tagged();
1431 }
1432
ager@chromium.org378b34e2011-01-28 08:04:38 +00001433 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001434 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001435};
1436
1437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001438template <int V>
1439class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001440 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001441 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001442 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1443 this->set_representation(Representation::Tagged());
1444 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001445 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001446
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001447 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001448
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001449 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001451 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001452
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001453 private:
1454 int argument_count_;
1455};
1456
1457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001459 public:
1460 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001461 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001462 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001463 }
1464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465 virtual Representation RequiredInputRepresentation(int index) const {
1466 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001467 }
1468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001469 virtual void PrintDataTo(StringStream* stream);
1470
1471 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001472};
1473
1474
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001475class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001476 public:
1477 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001478 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001479 SetOperandAt(0, first);
1480 SetOperandAt(1, second);
1481 }
1482
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001483 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001484
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001485 virtual Representation RequiredInputRepresentation(int index) const {
1486 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001487 }
1488
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001489 HValue* first() { return OperandAt(0); }
1490 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001491};
1492
1493
danno@chromium.org160a7b02011-04-18 15:51:38 +00001494class HInvokeFunction: public HBinaryCall {
1495 public:
1496 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1497 : HBinaryCall(context, function, argument_count) {
1498 }
1499
1500 virtual Representation RequiredInputRepresentation(int index) const {
1501 return Representation::Tagged();
1502 }
1503
1504 HValue* context() { return first(); }
1505 HValue* function() { return second(); }
1506
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001507 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001508};
1509
1510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001511class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001512 public:
1513 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001514 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001515
1516 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001517
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001518 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001519 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001520 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001521 }
1522
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001523 virtual void PrintDataTo(StringStream* stream);
1524
1525 virtual Representation RequiredInputRepresentation(int index) const {
1526 return Representation::None();
1527 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001529 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001530
1531 private:
1532 Handle<JSFunction> function_;
1533};
1534
1535
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001536class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001538 HCallKeyed(HValue* context, HValue* key, int argument_count)
1539 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001540 }
1541
1542 virtual Representation RequiredInputRepresentation(int index) const {
1543 return Representation::Tagged();
1544 }
1545
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001546 HValue* context() { return first(); }
1547 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001548
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001549 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001550};
1551
1552
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001553class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001555 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1556 : HUnaryCall(context, argument_count), name_(name) {
1557 }
1558
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001559 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001560
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001561 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001562 Handle<String> name() const { return name_; }
1563
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001564 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001566 virtual Representation RequiredInputRepresentation(int index) const {
1567 return Representation::Tagged();
1568 }
1569
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001570 private:
1571 Handle<String> name_;
1572};
1573
1574
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001575class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001577 HCallFunction(HValue* context, int argument_count)
1578 : HUnaryCall(context, argument_count) {
1579 }
1580
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001581 HValue* context() { return value(); }
1582
1583 virtual Representation RequiredInputRepresentation(int index) const {
1584 return Representation::Tagged();
1585 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001587 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588};
1589
1590
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001591class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001592 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001593 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1594 : HUnaryCall(context, argument_count), name_(name) {
1595 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001597 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001598
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001599 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001600 Handle<String> name() const { return name_; }
1601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 virtual Representation RequiredInputRepresentation(int index) const {
1603 return Representation::Tagged();
1604 }
1605
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001606 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607
1608 private:
1609 Handle<String> name_;
1610};
1611
1612
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001613class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001615 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001616 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001617
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001618 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001620 Handle<JSFunction> target() const { return target_; }
1621
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001622 virtual Representation RequiredInputRepresentation(int index) const {
1623 return Representation::None();
1624 }
1625
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001626 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001627
1628 private:
1629 Handle<JSFunction> target_;
1630};
1631
1632
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001633class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001635 HCallNew(HValue* context, HValue* constructor, int argument_count)
1636 : HBinaryCall(context, constructor, argument_count) {
1637 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001638
1639 virtual Representation RequiredInputRepresentation(int index) const {
1640 return Representation::Tagged();
1641 }
1642
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001643 HValue* context() { return first(); }
1644 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001645
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001646 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001647};
1648
1649
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001650class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001651 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001652 HCallRuntime(HValue* context,
1653 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001654 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001655 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001656 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1657 SetOperandAt(0, context);
1658 }
1659
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001660 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001661
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001662 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001663 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001664 Handle<String> name() const { return name_; }
1665
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001666 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001667 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001668 }
1669
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001670 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671
1672 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001673 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674 Handle<String> name_;
1675};
1676
1677
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001678class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001679 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001680 HJSArrayLength(HValue* value, HValue* typecheck) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001681 // The length of an array is stored as a tagged value in the array
1682 // object. It is guaranteed to be 32 bit integer, but it can be
1683 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001684 SetOperandAt(0, value);
1685 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001687 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001688 SetFlag(kDependsOnArrayLengths);
1689 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001690 }
1691
1692 virtual Representation RequiredInputRepresentation(int index) const {
1693 return Representation::Tagged();
1694 }
1695
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001696 HValue* value() { return OperandAt(0); }
1697
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001698 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001699
1700 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001701 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001702};
1703
1704
1705class HFixedArrayLength: public HUnaryOperation {
1706 public:
1707 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1708 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001709 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001710 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001711 }
1712
1713 virtual Representation RequiredInputRepresentation(int index) const {
1714 return Representation::Tagged();
1715 }
1716
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001717 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001718
1719 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001720 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001721};
1722
1723
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001724class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001725 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001726 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001727 set_representation(Representation::Integer32());
1728 // The result of this instruction is idempotent as long as its inputs don't
1729 // change. The length of a pixel array cannot change once set, so it's not
1730 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1731 SetFlag(kUseGVN);
1732 }
1733
1734 virtual Representation RequiredInputRepresentation(int index) const {
1735 return Representation::Tagged();
1736 }
1737
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001738 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001739
1740 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001741 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001742};
1743
1744
whesse@chromium.org7b260152011-06-20 15:33:18 +00001745class HElementsKind: public HUnaryOperation {
1746 public:
1747 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1748 set_representation(Representation::Integer32());
1749 SetFlag(kUseGVN);
1750 SetFlag(kDependsOnMaps);
1751 }
1752
1753 virtual Representation RequiredInputRepresentation(int index) const {
1754 return Representation::Tagged();
1755 }
1756
1757 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1758
1759 protected:
1760 virtual bool DataEquals(HValue* other) { return true; }
1761};
1762
1763
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001764class HBitNot: public HUnaryOperation {
1765 public:
1766 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1767 set_representation(Representation::Integer32());
1768 SetFlag(kUseGVN);
1769 SetFlag(kTruncatingToInt32);
1770 }
1771
1772 virtual Representation RequiredInputRepresentation(int index) const {
1773 return Representation::Integer32();
1774 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001775 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001776
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001777 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001778
1779 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001780 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001781};
1782
1783
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001784class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001786 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1787 : op_(op) {
1788 SetOperandAt(0, context);
1789 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001790 switch (op) {
1791 case kMathFloor:
1792 case kMathRound:
1793 case kMathCeil:
1794 set_representation(Representation::Integer32());
1795 break;
1796 case kMathAbs:
1797 set_representation(Representation::Tagged());
1798 SetFlag(kFlexibleRepresentation);
1799 break;
1800 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001801 case kMathPowHalf:
1802 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001803 case kMathSin:
1804 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001805 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001806 break;
1807 default:
1808 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809 }
1810 SetFlag(kUseGVN);
1811 }
1812
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001813 HValue* context() { return OperandAt(0); }
1814 HValue* value() { return OperandAt(1); }
1815
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001816 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001818 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001819
1820 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1821
1822 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001823 if (index == 0) {
1824 return Representation::Tagged();
1825 } else {
1826 switch (op_) {
1827 case kMathFloor:
1828 case kMathRound:
1829 case kMathCeil:
1830 case kMathSqrt:
1831 case kMathPowHalf:
1832 case kMathLog:
1833 case kMathSin:
1834 case kMathCos:
1835 return Representation::Double();
1836 case kMathAbs:
1837 return representation();
1838 default:
1839 UNREACHABLE();
1840 return Representation::None();
1841 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001842 }
1843 }
1844
1845 virtual HValue* Canonicalize() {
1846 // If the input is integer32 then we replace the floor instruction
1847 // with its inputs. This happens before the representation changes are
1848 // introduced.
1849 if (op() == kMathFloor) {
1850 if (value()->representation().IsInteger32()) return value();
1851 }
1852 return this;
1853 }
1854
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001855 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001856 const char* OpName() const;
1857
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001858 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001859
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001860 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001861 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001862 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1863 return op_ == b->op();
1864 }
1865
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001866 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001867 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001868};
1869
1870
1871class HLoadElements: public HUnaryOperation {
1872 public:
1873 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1874 set_representation(Representation::Tagged());
1875 SetFlag(kUseGVN);
1876 SetFlag(kDependsOnMaps);
1877 }
1878
1879 virtual Representation RequiredInputRepresentation(int index) const {
1880 return Representation::Tagged();
1881 }
1882
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001883 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001884
1885 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001886 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001887};
1888
1889
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001890class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001891 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001892 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001893 : HUnaryOperation(value) {
1894 set_representation(Representation::External());
1895 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001896 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001897 // change once set, so it's no necessary to introduce any additional
1898 // dependencies on top of the inputs.
1899 SetFlag(kUseGVN);
1900 }
1901
1902 virtual Representation RequiredInputRepresentation(int index) const {
1903 return Representation::Tagged();
1904 }
1905
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001906 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001907
1908 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001909 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001910};
1911
1912
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001913class HCheckMap: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001914 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001915 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
1916 : map_(map) {
1917 SetOperandAt(0, value);
1918 // If callers don't depend on a typecheck, they can pass in NULL. In that
1919 // case we use a copy of the |value| argument as a dummy value.
1920 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001921 set_representation(Representation::Tagged());
1922 SetFlag(kUseGVN);
1923 SetFlag(kDependsOnMaps);
1924 }
1925
1926 virtual Representation RequiredInputRepresentation(int index) const {
1927 return Representation::Tagged();
1928 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001929 virtual void PrintDataTo(StringStream* stream);
1930 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001931
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001932 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001933 Handle<Map> map() const { return map_; }
1934
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001935 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001936
1937 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001938 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001939 HCheckMap* b = HCheckMap::cast(other);
1940 return map_.is_identical_to(b->map());
1941 }
1942
1943 private:
1944 Handle<Map> map_;
1945};
1946
1947
1948class HCheckFunction: public HUnaryOperation {
1949 public:
1950 HCheckFunction(HValue* value, Handle<JSFunction> function)
1951 : HUnaryOperation(value), target_(function) {
1952 set_representation(Representation::Tagged());
1953 SetFlag(kUseGVN);
1954 }
1955
1956 virtual Representation RequiredInputRepresentation(int index) const {
1957 return Representation::Tagged();
1958 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001959 virtual void PrintDataTo(StringStream* stream);
1960 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001961
1962#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001963 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001964#endif
1965
1966 Handle<JSFunction> target() const { return target_; }
1967
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001968 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001969
1970 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001971 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001972 HCheckFunction* b = HCheckFunction::cast(other);
1973 return target_.is_identical_to(b->target());
1974 }
1975
1976 private:
1977 Handle<JSFunction> target_;
1978};
1979
1980
1981class HCheckInstanceType: public HUnaryOperation {
1982 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001983 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1984 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001985 }
1986 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1987 return new HCheckInstanceType(value, IS_JS_ARRAY);
1988 }
1989 static HCheckInstanceType* NewIsString(HValue* value) {
1990 return new HCheckInstanceType(value, IS_STRING);
1991 }
1992 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1993 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001994 }
1995
1996 virtual Representation RequiredInputRepresentation(int index) const {
1997 return Representation::Tagged();
1998 }
1999
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002000 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002001
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002002 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2003 void GetCheckInterval(InstanceType* first, InstanceType* last);
2004 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002005
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002006 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002007
2008 protected:
2009 // TODO(ager): It could be nice to allow the ommision of instance
2010 // type checks if we have already performed an instance type check
2011 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002012 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002014 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015 }
2016
2017 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002018 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002019 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002020 IS_JS_ARRAY,
2021 IS_STRING,
2022 IS_SYMBOL,
2023 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2024 };
2025
2026 HCheckInstanceType(HValue* value, Check check)
2027 : HUnaryOperation(value), check_(check) {
2028 set_representation(Representation::Tagged());
2029 SetFlag(kUseGVN);
2030 }
2031
2032 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033};
2034
2035
2036class HCheckNonSmi: public HUnaryOperation {
2037 public:
2038 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2039 set_representation(Representation::Tagged());
2040 SetFlag(kUseGVN);
2041 }
2042
2043 virtual Representation RequiredInputRepresentation(int index) const {
2044 return Representation::Tagged();
2045 }
2046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002047 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002048
2049#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002050 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002051#endif
2052
danno@chromium.org160a7b02011-04-18 15:51:38 +00002053 virtual HValue* Canonicalize() {
2054 HType value_type = value()->type();
2055 if (!value_type.IsUninitialized() &&
2056 (value_type.IsHeapNumber() ||
2057 value_type.IsString() ||
2058 value_type.IsBoolean() ||
2059 value_type.IsNonPrimitive())) {
2060 return NULL;
2061 }
2062 return this;
2063 }
2064
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002065 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002066
2067 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002068 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002069};
2070
2071
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002072class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002073 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002074 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2075 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002076 SetFlag(kUseGVN);
2077 SetFlag(kDependsOnMaps);
2078 }
2079
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002080#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002081 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082#endif
2083
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002084 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002085 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002086
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002087 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002089 virtual Representation RequiredInputRepresentation(int index) const {
2090 return Representation::None();
2091 }
2092
2093 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002094 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002095 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2096 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2097 return hash;
2098 }
2099
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002101 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002102 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002103 return prototype_.is_identical_to(b->prototype()) &&
2104 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002105 }
2106
2107 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002108 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002110};
2111
2112
2113class HCheckSmi: public HUnaryOperation {
2114 public:
2115 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2116 set_representation(Representation::Tagged());
2117 SetFlag(kUseGVN);
2118 }
2119
2120 virtual Representation RequiredInputRepresentation(int index) const {
2121 return Representation::Tagged();
2122 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002123 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124
2125#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002126 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002127#endif
2128
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002129 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002130
2131 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002132 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002133};
2134
2135
2136class HPhi: public HValue {
2137 public:
2138 explicit HPhi(int merged_index)
2139 : inputs_(2),
2140 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002141 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002142 is_live_(false),
2143 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002144 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2145 non_phi_uses_[i] = 0;
2146 indirect_uses_[i] = 0;
2147 }
2148 ASSERT(merged_index >= 0);
2149 set_representation(Representation::Tagged());
2150 SetFlag(kFlexibleRepresentation);
2151 }
2152
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002153 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002154 bool double_occurred = false;
2155 bool int32_occurred = false;
2156 for (int i = 0; i < OperandCount(); ++i) {
2157 HValue* value = OperandAt(i);
2158 if (value->representation().IsDouble()) double_occurred = true;
2159 if (value->representation().IsInteger32()) int32_occurred = true;
2160 if (value->representation().IsTagged()) return Representation::Tagged();
2161 }
2162
2163 if (double_occurred) return Representation::Double();
2164 if (int32_occurred) return Representation::Integer32();
2165 return Representation::None();
2166 }
2167
2168 virtual Range* InferRange();
2169 virtual Representation RequiredInputRepresentation(int index) const {
2170 return representation();
2171 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002172 virtual HType CalculateInferredType();
2173 virtual int OperandCount() { return inputs_.length(); }
2174 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2175 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002176 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002177 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002178
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002179 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002180
2181 int merged_index() const { return merged_index_; }
2182
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002183 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002184
2185#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002186 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002187#endif
2188
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002189 void InitRealUses(int id);
2190 void AddNonPhiUsesFrom(HPhi* other);
2191 void AddIndirectUsesTo(int* use_count);
2192
2193 int tagged_non_phi_uses() const {
2194 return non_phi_uses_[Representation::kTagged];
2195 }
2196 int int32_non_phi_uses() const {
2197 return non_phi_uses_[Representation::kInteger32];
2198 }
2199 int double_non_phi_uses() const {
2200 return non_phi_uses_[Representation::kDouble];
2201 }
2202 int tagged_indirect_uses() const {
2203 return indirect_uses_[Representation::kTagged];
2204 }
2205 int int32_indirect_uses() const {
2206 return indirect_uses_[Representation::kInteger32];
2207 }
2208 int double_indirect_uses() const {
2209 return indirect_uses_[Representation::kDouble];
2210 }
2211 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002212 bool is_live() { return is_live_; }
2213 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002214
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002215 static HPhi* cast(HValue* value) {
2216 ASSERT(value->IsPhi());
2217 return reinterpret_cast<HPhi*>(value);
2218 }
2219 virtual Opcode opcode() const { return HValue::kPhi; }
2220
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002221 virtual bool IsConvertibleToInteger() const {
2222 return is_convertible_to_integer_;
2223 }
2224
2225 void set_is_convertible_to_integer(bool b) {
2226 is_convertible_to_integer_ = b;
2227 }
2228
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002229 protected:
2230 virtual void DeleteFromGraph();
2231 virtual void InternalSetOperandAt(int index, HValue* value) {
2232 inputs_[index] = value;
2233 }
2234
2235 private:
2236 ZoneList<HValue*> inputs_;
2237 int merged_index_;
2238
2239 int non_phi_uses_[Representation::kNumRepresentations];
2240 int indirect_uses_[Representation::kNumRepresentations];
2241 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002242 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002243 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244};
2245
2246
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002247class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248 public:
2249 HArgumentsObject() {
2250 set_representation(Representation::Tagged());
2251 SetFlag(kIsArguments);
2252 }
2253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002254 virtual Representation RequiredInputRepresentation(int index) const {
2255 return Representation::None();
2256 }
2257
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002258 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002259};
2260
2261
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002262class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002263 public:
2264 HConstant(Handle<Object> handle, Representation r);
2265
2266 Handle<Object> handle() const { return handle_; }
2267
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002268 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002270 virtual Representation RequiredInputRepresentation(int index) const {
2271 return Representation::None();
2272 }
2273
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002274 virtual bool IsConvertibleToInteger() const {
2275 if (handle_->IsSmi()) return true;
2276 if (handle_->IsHeapNumber() &&
2277 (HeapNumber::cast(*handle_)->value() ==
2278 static_cast<double>(NumberToInt32(*handle_)))) return true;
2279 return false;
2280 }
2281
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002282 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002283 virtual void PrintDataTo(StringStream* stream);
2284 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002285 bool IsInteger() const { return handle_->IsSmi(); }
2286 HConstant* CopyToRepresentation(Representation r) const;
2287 HConstant* CopyToTruncatedInt32() const;
2288 bool HasInteger32Value() const { return has_int32_value_; }
2289 int32_t Integer32Value() const {
2290 ASSERT(HasInteger32Value());
2291 return int32_value_;
2292 }
2293 bool HasDoubleValue() const { return has_double_value_; }
2294 double DoubleValue() const {
2295 ASSERT(HasDoubleValue());
2296 return double_value_;
2297 }
2298 bool HasStringValue() const { return handle_->IsString(); }
2299
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002300 bool ToBoolean() const;
2301
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002302 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002303 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002304 return reinterpret_cast<intptr_t>(*handle());
2305 }
2306
2307#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002308 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002309#endif
2310
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002311 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002312
2313 protected:
2314 virtual Range* InferRange();
2315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002316 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002317 HConstant* other_constant = HConstant::cast(other);
2318 return handle().is_identical_to(other_constant->handle());
2319 }
2320
2321 private:
2322 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002323
2324 // The following two values represent the int32 and the double value of the
2325 // given constant if there is a lossless conversion between the constant
2326 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002327 bool has_int32_value_ : 1;
2328 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002329 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002330 double double_value_;
2331};
2332
2333
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002334class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002335 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002336 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002337 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002338 SetOperandAt(0, context);
2339 SetOperandAt(1, left);
2340 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002341 }
2342
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002343 HValue* context() { return OperandAt(0); }
2344 HValue* left() { return OperandAt(1); }
2345 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002346
2347 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2348 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002349 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002350 if (IsCommutative() && left()->IsConstant()) return right();
2351 return left();
2352 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002353 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002354 if (IsCommutative() && left()->IsConstant()) return left();
2355 return right();
2356 }
2357
2358 virtual bool IsCommutative() const { return false; }
2359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002360 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361};
2362
2363
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002364class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002365 public:
2366 HApplyArguments(HValue* function,
2367 HValue* receiver,
2368 HValue* length,
2369 HValue* elements) {
2370 set_representation(Representation::Tagged());
2371 SetOperandAt(0, function);
2372 SetOperandAt(1, receiver);
2373 SetOperandAt(2, length);
2374 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002375 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376 }
2377
2378 virtual Representation RequiredInputRepresentation(int index) const {
2379 // The length is untagged, all other inputs are tagged.
2380 return (index == 2)
2381 ? Representation::Integer32()
2382 : Representation::Tagged();
2383 }
2384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002385 HValue* function() { return OperandAt(0); }
2386 HValue* receiver() { return OperandAt(1); }
2387 HValue* length() { return OperandAt(2); }
2388 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002389
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002390 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002391};
2392
2393
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002394class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002395 public:
2396 HArgumentsElements() {
2397 // The value produced by this instruction is a pointer into the stack
2398 // that looks as if it was a smi because of alignment.
2399 set_representation(Representation::Tagged());
2400 SetFlag(kUseGVN);
2401 }
2402
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002403 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002404
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002405 virtual Representation RequiredInputRepresentation(int index) const {
2406 return Representation::None();
2407 }
2408
ager@chromium.org378b34e2011-01-28 08:04:38 +00002409 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002410 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002411};
2412
2413
2414class HArgumentsLength: public HUnaryOperation {
2415 public:
2416 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2417 set_representation(Representation::Integer32());
2418 SetFlag(kUseGVN);
2419 }
2420
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 virtual Representation RequiredInputRepresentation(int index) const {
2422 return Representation::Tagged();
2423 }
2424
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002425 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002426
2427 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002428 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002429};
2430
2431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002432class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002433 public:
2434 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2435 set_representation(Representation::Tagged());
2436 SetFlag(kUseGVN);
2437 SetOperandAt(0, arguments);
2438 SetOperandAt(1, length);
2439 SetOperandAt(2, index);
2440 }
2441
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002442 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443
2444 virtual Representation RequiredInputRepresentation(int index) const {
2445 // The arguments elements is considered tagged.
2446 return index == 0
2447 ? Representation::Tagged()
2448 : Representation::Integer32();
2449 }
2450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002451 HValue* arguments() { return OperandAt(0); }
2452 HValue* length() { return OperandAt(1); }
2453 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002455 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002457 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002458};
2459
2460
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002461class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002462 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002463 HBoundsCheck(HValue* index, HValue* length) {
2464 SetOperandAt(0, index);
2465 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002466 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002467 SetFlag(kUseGVN);
2468 }
2469
2470 virtual Representation RequiredInputRepresentation(int index) const {
2471 return Representation::Integer32();
2472 }
2473
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002474 HValue* index() { return OperandAt(0); }
2475 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002476
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002477 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002478
2479 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002480 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002481};
2482
2483
2484class HBitwiseBinaryOperation: public HBinaryOperation {
2485 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002486 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2487 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002488 set_representation(Representation::Tagged());
2489 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002490 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002491 }
2492
2493 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002494 return index == 0
2495 ? Representation::Tagged()
2496 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002497 }
2498
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002499 virtual void RepresentationChanged(Representation to) {
2500 if (!to.IsTagged()) {
2501 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002502 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002503 SetFlag(kTruncatingToInt32);
2504 SetFlag(kUseGVN);
2505 }
2506 }
2507
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002508 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002509
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002510 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511};
2512
2513
2514class HArithmeticBinaryOperation: public HBinaryOperation {
2515 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002516 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2517 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002518 set_representation(Representation::Tagged());
2519 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002520 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521 }
2522
2523 virtual void RepresentationChanged(Representation to) {
2524 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002525 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002526 SetFlag(kUseGVN);
2527 }
2528 }
2529
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002530 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002532 return index == 0
2533 ? Representation::Tagged()
2534 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002535 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002537 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 if (left()->representation().Equals(right()->representation())) {
2539 return left()->representation();
2540 }
2541 return HValue::InferredRepresentation();
2542 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002543};
2544
2545
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002546class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002548 HCompareGeneric(HValue* context,
2549 HValue* left,
2550 HValue* right,
2551 Token::Value token)
2552 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553 ASSERT(Token::IsCompareOp(token));
2554 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002555 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002556 }
2557
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002558 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002559 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002561
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002562 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002563 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002564 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002565
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002566 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002567 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002569 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002570
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002571 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2572
2573 private:
2574 Token::Value token_;
2575};
2576
2577
2578class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2579 public:
2580 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2581 : token_(token) {
2582 ASSERT(Token::IsCompareOp(token));
2583 SetOperandAt(0, left);
2584 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585 }
2586
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002587 HValue* left() { return OperandAt(0); }
2588 HValue* right() { return OperandAt(1); }
2589 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002590
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002591 void SetInputRepresentation(Representation r);
2592 Representation GetInputRepresentation() const {
2593 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002594 }
2595
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002596 virtual Representation RequiredInputRepresentation(int index) const {
2597 return input_representation_;
2598 }
2599 virtual void PrintDataTo(StringStream* stream);
2600
2601 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603 private:
2604 Representation input_representation_;
2605 Token::Value token_;
2606};
2607
2608
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002609class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002610 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002611 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2612 SetOperandAt(0, left);
2613 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002614 }
2615
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002616 HValue* left() { return OperandAt(0); }
2617 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002618
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002619 virtual Representation RequiredInputRepresentation(int index) const {
2620 return Representation::Tagged();
2621 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002622
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002623 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002624};
2625
2626
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002627class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002628 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002629 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2630 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002631 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002632 }
2633
2634 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002635 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002636 int right() const { return right_; }
2637
whesse@chromium.org7b260152011-06-20 15:33:18 +00002638 virtual Representation RequiredInputRepresentation(int index) const {
2639 return Representation::Integer32();
2640 }
2641
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002642 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002643
2644 private:
2645 const Token::Value op_;
2646 const int right_;
2647};
2648
2649
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002650class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002651 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002652 HIsNullAndBranch(HValue* value, bool is_strict)
2653 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002654
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002655 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002656
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002657 virtual Representation RequiredInputRepresentation(int index) const {
2658 return Representation::Tagged();
2659 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002660
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002661 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002662
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002663 private:
2664 bool is_strict_;
2665};
2666
2667
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002668class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002669 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002670 explicit HIsObjectAndBranch(HValue* value)
2671 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002672
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002673 virtual Representation RequiredInputRepresentation(int index) const {
2674 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002675 }
2676
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002677 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2678};
2679
2680
2681class HIsSmiAndBranch: public HUnaryControlInstruction {
2682 public:
2683 explicit HIsSmiAndBranch(HValue* value)
2684 : HUnaryControlInstruction(value, NULL, NULL) { }
2685
2686 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2687
2688 virtual Representation RequiredInputRepresentation(int index) const {
2689 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002690 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002691
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002692 protected:
2693 virtual bool DataEquals(HValue* other) { return true; }
2694};
2695
2696
2697class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2698 public:
2699 explicit HIsUndetectableAndBranch(HValue* value)
2700 : HUnaryControlInstruction(value, NULL, NULL) { }
2701
2702 virtual Representation RequiredInputRepresentation(int index) const {
2703 return Representation::Tagged();
2704 }
2705
2706 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2707};
2708
2709
2710class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2711 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002712 virtual Representation RequiredInputRepresentation(int index) const {
2713 return Representation::None();
2714 }
2715
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002716 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002717};
2718
2719
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002720class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002722 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2723 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2724 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2725 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002726 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2727 }
2728
2729 InstanceType from() { return from_; }
2730 InstanceType to() { return to_; }
2731
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002732 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002733
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002734 virtual Representation RequiredInputRepresentation(int index) const {
2735 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002736 }
2737
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002738 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2739
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002740 private:
2741 InstanceType from_;
2742 InstanceType to_; // Inclusive range, not all combinations work.
2743};
2744
2745
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002746class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002748 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2749 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002751 virtual Representation RequiredInputRepresentation(int index) const {
2752 return Representation::Tagged();
2753 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002754
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002755 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002756};
2757
2758
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002759class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002760 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002761 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2762 set_representation(Representation::Tagged());
2763 SetFlag(kUseGVN);
2764 }
2765
2766 virtual Representation RequiredInputRepresentation(int index) const {
2767 return Representation::Tagged();
2768 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002769
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002770 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002771
2772 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002773 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002774};
2775
2776
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002777class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002778 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002779 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2780 : HUnaryControlInstruction(value, NULL, NULL),
2781 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002782
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002783 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2784
2785 virtual Representation RequiredInputRepresentation(int index) const {
2786 return Representation::Tagged();
2787 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002788
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790
2791 Handle<String> class_name() const { return class_name_; }
2792
2793 private:
2794 Handle<String> class_name_;
2795};
2796
2797
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002798class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002800 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2801 : HUnaryControlInstruction(value, NULL, NULL),
2802 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002803
2804 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002805 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002807 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002809 virtual Representation RequiredInputRepresentation(int index) const {
2810 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811 }
2812
2813 private:
2814 Handle<String> type_literal_;
2815};
2816
2817
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002818class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002819 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002820 HInstanceOf(HValue* context, HValue* left, HValue* right)
2821 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002822 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002823 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824 }
2825
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826 virtual Representation RequiredInputRepresentation(int index) const {
2827 return Representation::Tagged();
2828 }
2829
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002830 virtual HType CalculateInferredType();
2831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002832 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002833
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002834 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835};
2836
2837
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002838class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002839 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002840 HInstanceOfKnownGlobal(HValue* context,
2841 HValue* left,
2842 Handle<JSFunction> right)
2843 : function_(right) {
2844 SetOperandAt(0, context);
2845 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002846 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002847 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002848 }
2849
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002850 HValue* context() { return OperandAt(0); }
2851 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002852 Handle<JSFunction> function() { return function_; }
2853
2854 virtual Representation RequiredInputRepresentation(int index) const {
2855 return Representation::Tagged();
2856 }
2857
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002858 virtual HType CalculateInferredType();
2859
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002860 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002861
2862 private:
2863 Handle<JSFunction> function_;
2864};
2865
2866
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002867class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002868 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002869 HPower(HValue* left, HValue* right) {
2870 SetOperandAt(0, left);
2871 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002872 set_representation(Representation::Double());
2873 SetFlag(kUseGVN);
2874 }
2875
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002876 HValue* left() { return OperandAt(0); }
2877 HValue* right() { return OperandAt(1); }
2878
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002879 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002880 return index == 0
2881 ? Representation::Double()
2882 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002883 }
2884
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002885 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002886
2887 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002888 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002889};
2890
2891
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892class HAdd: public HArithmeticBinaryOperation {
2893 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002894 HAdd(HValue* context, HValue* left, HValue* right)
2895 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002896 SetFlag(kCanOverflow);
2897 }
2898
2899 // Add is only commutative if two integer values are added and not if two
2900 // tagged values are added (because it might be a String concatenation).
2901 virtual bool IsCommutative() const {
2902 return !representation().IsTagged();
2903 }
2904
2905 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002907 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002909 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002910
2911 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002912 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002913
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002914 virtual Range* InferRange();
2915};
2916
2917
2918class HSub: public HArithmeticBinaryOperation {
2919 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002920 HSub(HValue* context, HValue* left, HValue* right)
2921 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002922 SetFlag(kCanOverflow);
2923 }
2924
2925 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2926
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002927 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928
2929 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002930 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002931
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932 virtual Range* InferRange();
2933};
2934
2935
2936class HMul: public HArithmeticBinaryOperation {
2937 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002938 HMul(HValue* context, HValue* left, HValue* right)
2939 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940 SetFlag(kCanOverflow);
2941 }
2942
2943 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2944
2945 // Only commutative if it is certain that not two objects are multiplicated.
2946 virtual bool IsCommutative() const {
2947 return !representation().IsTagged();
2948 }
2949
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002950 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002951
2952 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002953 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002954
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002955 virtual Range* InferRange();
2956};
2957
2958
2959class HMod: public HArithmeticBinaryOperation {
2960 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002961 HMod(HValue* context, HValue* left, HValue* right)
2962 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002963 SetFlag(kCanBeDivByZero);
2964 }
2965
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002966 bool HasPowerOf2Divisor() {
2967 if (right()->IsConstant() &&
2968 HConstant::cast(right())->HasInteger32Value()) {
2969 int32_t value = HConstant::cast(right())->Integer32Value();
2970 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2971 }
2972
2973 return false;
2974 }
2975
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002976 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2977
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002978 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979
2980 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002981 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002982
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983 virtual Range* InferRange();
2984};
2985
2986
2987class HDiv: public HArithmeticBinaryOperation {
2988 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002989 HDiv(HValue* context, HValue* left, HValue* right)
2990 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 SetFlag(kCanBeDivByZero);
2992 SetFlag(kCanOverflow);
2993 }
2994
2995 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2996
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002997 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998
2999 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003000 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003001
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002 virtual Range* InferRange();
3003};
3004
3005
3006class HBitAnd: public HBitwiseBinaryOperation {
3007 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003008 HBitAnd(HValue* context, HValue* left, HValue* right)
3009 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010
3011 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003012 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003013
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003014 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015
3016 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003017 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003018
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019 virtual Range* InferRange();
3020};
3021
3022
3023class HBitXor: public HBitwiseBinaryOperation {
3024 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003025 HBitXor(HValue* context, HValue* left, HValue* right)
3026 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027
3028 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003029 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003031 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003032
3033 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003034 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003035};
3036
3037
3038class HBitOr: public HBitwiseBinaryOperation {
3039 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003040 HBitOr(HValue* context, HValue* left, HValue* right)
3041 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003042
3043 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003044 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003045
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003046 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047
3048 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003049 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003050
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051 virtual Range* InferRange();
3052};
3053
3054
3055class HShl: public HBitwiseBinaryOperation {
3056 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003057 HShl(HValue* context, HValue* left, HValue* right)
3058 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
3060 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003061 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003063 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003064
3065 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067};
3068
3069
3070class HShr: public HBitwiseBinaryOperation {
3071 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003072 HShr(HValue* context, HValue* left, HValue* right)
3073 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003075 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003076 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003078 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003079
3080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082};
3083
3084
3085class HSar: public HBitwiseBinaryOperation {
3086 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003087 HSar(HValue* context, HValue* left, HValue* right)
3088 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089
3090 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003091 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003093 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003094
3095 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003096 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097};
3098
3099
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003100class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101 public:
3102 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3103 SetFlag(kChangesOsrEntries);
3104 }
3105
3106 int ast_id() const { return ast_id_; }
3107
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003108 virtual Representation RequiredInputRepresentation(int index) const {
3109 return Representation::None();
3110 }
3111
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003112 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113
3114 private:
3115 int ast_id_;
3116};
3117
3118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003119class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120 public:
3121 explicit HParameter(unsigned index) : index_(index) {
3122 set_representation(Representation::Tagged());
3123 }
3124
3125 unsigned index() const { return index_; }
3126
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003127 virtual void PrintDataTo(StringStream* stream);
3128
3129 virtual Representation RequiredInputRepresentation(int index) const {
3130 return Representation::None();
3131 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003133 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134
3135 private:
3136 unsigned index_;
3137};
3138
3139
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003140class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003142 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3143 : HUnaryCall(context, argument_count),
3144 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003145 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146 }
3147
3148 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003149
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003150 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151
3152 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3153 transcendental_type_ = transcendental_type;
3154 }
3155 TranscendentalCache::Type transcendental_type() {
3156 return transcendental_type_;
3157 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003159 virtual void PrintDataTo(StringStream* stream);
3160
3161 virtual Representation RequiredInputRepresentation(int index) const {
3162 return Representation::Tagged();
3163 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003165 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166
3167 private:
3168 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003169 TranscendentalCache::Type transcendental_type_;
3170};
3171
3172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003173class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003174 public:
3175 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003177 virtual Representation RequiredInputRepresentation(int index) const {
3178 return Representation::None();
3179 }
3180
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003181 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182};
3183
3184
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003185class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003187 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188 : cell_(cell), check_hole_value_(check_hole_value) {
3189 set_representation(Representation::Tagged());
3190 SetFlag(kUseGVN);
3191 SetFlag(kDependsOnGlobalVars);
3192 }
3193
3194 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3195 bool check_hole_value() const { return check_hole_value_; }
3196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003197 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003199 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003200 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 return reinterpret_cast<intptr_t>(*cell_);
3202 }
3203
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003204 virtual Representation RequiredInputRepresentation(int index) const {
3205 return Representation::None();
3206 }
3207
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003208 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003209
3210 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003211 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003212 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003213 return cell_.is_identical_to(b->cell());
3214 }
3215
3216 private:
3217 Handle<JSGlobalPropertyCell> cell_;
3218 bool check_hole_value_;
3219};
3220
3221
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003222class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003223 public:
3224 HLoadGlobalGeneric(HValue* context,
3225 HValue* global_object,
3226 Handle<Object> name,
3227 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003228 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003229 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003230 SetOperandAt(0, context);
3231 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003232 set_representation(Representation::Tagged());
3233 SetAllSideEffects();
3234 }
3235
3236 HValue* context() { return OperandAt(0); }
3237 HValue* global_object() { return OperandAt(1); }
3238 Handle<Object> name() const { return name_; }
3239 bool for_typeof() const { return for_typeof_; }
3240
3241 virtual void PrintDataTo(StringStream* stream);
3242
3243 virtual Representation RequiredInputRepresentation(int index) const {
3244 return Representation::Tagged();
3245 }
3246
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003247 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003248
3249 private:
3250 Handle<Object> name_;
3251 bool for_typeof_;
3252};
3253
3254
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003255class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003256 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003257 HStoreGlobalCell(HValue* value,
3258 Handle<JSGlobalPropertyCell> cell,
3259 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003260 : HUnaryOperation(value),
3261 cell_(cell),
3262 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263 SetFlag(kChangesGlobalVars);
3264 }
3265
3266 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003267 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003268
3269 virtual Representation RequiredInputRepresentation(int index) const {
3270 return Representation::Tagged();
3271 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003272 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003273
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003274 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003275
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003276 private:
3277 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003278 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003279};
3280
3281
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003282class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3283 public:
3284 HStoreGlobalGeneric(HValue* context,
3285 HValue* global_object,
3286 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003287 HValue* value,
3288 bool strict_mode)
3289 : name_(name),
3290 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003291 SetOperandAt(0, context);
3292 SetOperandAt(1, global_object);
3293 SetOperandAt(2, value);
3294 set_representation(Representation::Tagged());
3295 SetAllSideEffects();
3296 }
3297
3298 HValue* context() { return OperandAt(0); }
3299 HValue* global_object() { return OperandAt(1); }
3300 Handle<Object> name() const { return name_; }
3301 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003302 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003303
3304 virtual void PrintDataTo(StringStream* stream);
3305
3306 virtual Representation RequiredInputRepresentation(int index) const {
3307 return Representation::Tagged();
3308 }
3309
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003310 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003311
3312 private:
3313 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003314 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003315};
3316
3317
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003318class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003319 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003320 HLoadContextSlot(HValue* context , int slot_index)
3321 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003322 set_representation(Representation::Tagged());
3323 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003324 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003325 }
3326
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003327 int slot_index() const { return slot_index_; }
3328
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003329 virtual Representation RequiredInputRepresentation(int index) const {
3330 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003331 }
3332
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003333 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003334
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003335 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003336
3337 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003338 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003339 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003340 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003341 }
3342
3343 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003344 int slot_index_;
3345};
3346
3347
3348static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00003349 return !value->type().IsBoolean()
3350 && !value->type().IsSmi()
3351 && !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003352}
3353
3354
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003355class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003356 public:
3357 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003358 : slot_index_(slot_index) {
3359 SetOperandAt(0, context);
3360 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003361 SetFlag(kChangesContextSlots);
3362 }
3363
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003364 HValue* context() { return OperandAt(0); }
3365 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003366 int slot_index() const { return slot_index_; }
3367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003368 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003369 return StoringValueNeedsWriteBarrier(value());
3370 }
3371
3372 virtual Representation RequiredInputRepresentation(int index) const {
3373 return Representation::Tagged();
3374 }
3375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003376 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003377
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003378 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003379
3380 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003381 int slot_index_;
3382};
3383
3384
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003385class HLoadNamedField: public HUnaryOperation {
3386 public:
3387 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3388 : HUnaryOperation(object),
3389 is_in_object_(is_in_object),
3390 offset_(offset) {
3391 set_representation(Representation::Tagged());
3392 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003393 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394 if (is_in_object) {
3395 SetFlag(kDependsOnInobjectFields);
3396 } else {
3397 SetFlag(kDependsOnBackingStoreFields);
3398 }
3399 }
3400
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003401 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003402 bool is_in_object() const { return is_in_object_; }
3403 int offset() const { return offset_; }
3404
3405 virtual Representation RequiredInputRepresentation(int index) const {
3406 return Representation::Tagged();
3407 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003408 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003409
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003410 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003411
3412 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003413 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003414 HLoadNamedField* b = HLoadNamedField::cast(other);
3415 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3416 }
3417
3418 private:
3419 bool is_in_object_;
3420 int offset_;
3421};
3422
3423
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003424class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003425 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003426 HLoadNamedFieldPolymorphic(HValue* context,
3427 HValue* object,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003428 ZoneMapList* types,
3429 Handle<String> name);
3430
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003431 HValue* context() { return OperandAt(0); }
3432 HValue* object() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003433 ZoneMapList* types() { return &types_; }
3434 Handle<String> name() { return name_; }
3435 bool need_generic() { return need_generic_; }
3436
3437 virtual Representation RequiredInputRepresentation(int index) const {
3438 return Representation::Tagged();
3439 }
3440
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003441 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003442
3443 static const int kMaxLoadPolymorphism = 4;
3444
3445 protected:
3446 virtual bool DataEquals(HValue* value);
3447
3448 private:
3449 ZoneMapList types_;
3450 Handle<String> name_;
3451 bool need_generic_;
3452};
3453
3454
3455
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003456class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003457 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003458 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003459 : name_(name) {
3460 SetOperandAt(0, context);
3461 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003462 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003463 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003464 }
3465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003466 HValue* context() { return OperandAt(0); }
3467 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003468 Handle<Object> name() const { return name_; }
3469
3470 virtual Representation RequiredInputRepresentation(int index) const {
3471 return Representation::Tagged();
3472 }
3473
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003474 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003475
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003476 private:
3477 Handle<Object> name_;
3478};
3479
3480
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003481class HLoadFunctionPrototype: public HUnaryOperation {
3482 public:
3483 explicit HLoadFunctionPrototype(HValue* function)
3484 : HUnaryOperation(function) {
3485 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003486 SetFlag(kUseGVN);
3487 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003488 }
3489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003490 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003491
3492 virtual Representation RequiredInputRepresentation(int index) const {
3493 return Representation::Tagged();
3494 }
3495
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003496 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003497
3498 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003500};
3501
3502
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003503class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003504 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003505 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3506 SetOperandAt(0, obj);
3507 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003508 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509 SetFlag(kDependsOnArrayElements);
3510 SetFlag(kUseGVN);
3511 }
3512
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003513 HValue* object() { return OperandAt(0); }
3514 HValue* key() { return OperandAt(1); }
3515
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516 virtual Representation RequiredInputRepresentation(int index) const {
3517 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003518 return index == 0
3519 ? Representation::Tagged()
3520 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003521 }
3522
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003523 virtual void PrintDataTo(StringStream* stream);
3524
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003525 bool RequiresHoleCheck() const;
3526
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003527 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003528
3529 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003530 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003531};
3532
3533
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003534class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3535 public:
3536 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3537 SetOperandAt(0, elements);
3538 SetOperandAt(1, key);
3539 set_representation(Representation::Double());
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003540 SetFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003541 SetFlag(kUseGVN);
3542 }
3543
3544 HValue* elements() { return OperandAt(0); }
3545 HValue* key() { return OperandAt(1); }
3546
3547 virtual Representation RequiredInputRepresentation(int index) const {
3548 // The key is supposed to be Integer32.
3549 return index == 0
3550 ? Representation::Tagged()
3551 : Representation::Integer32();
3552 }
3553
3554 virtual void PrintDataTo(StringStream* stream);
3555
3556 bool RequiresHoleCheck() const;
3557
3558 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3559
3560 protected:
3561 virtual bool DataEquals(HValue* other) { return true; }
3562};
3563
3564
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003565class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003566 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003567 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3568 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003569 JSObject::ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003570 : elements_kind_(elements_kind) {
3571 SetOperandAt(0, external_elements);
3572 SetOperandAt(1, key);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003573 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3574 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003575 set_representation(Representation::Double());
3576 } else {
3577 set_representation(Representation::Integer32());
3578 }
3579 SetFlag(kDependsOnSpecializedArrayElements);
3580 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003581 SetFlag(kDependsOnCalls);
3582 SetFlag(kUseGVN);
3583 }
3584
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003585 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003586
3587 virtual Representation RequiredInputRepresentation(int index) const {
3588 // The key is supposed to be Integer32, but the base pointer
3589 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003590 return index == 0
3591 ? Representation::External()
3592 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003593 }
3594
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003595 HValue* external_pointer() { return OperandAt(0); }
3596 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003597 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003598
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003599 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003600
3601 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003602 virtual bool DataEquals(HValue* other) {
3603 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3604 HLoadKeyedSpecializedArrayElement* cast_other =
3605 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003606 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003607 }
3608
3609 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003610 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003611};
3612
3613
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003614class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003615 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003616 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617 set_representation(Representation::Tagged());
3618 SetOperandAt(0, obj);
3619 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003620 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003621 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003622 }
3623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003624 HValue* object() { return OperandAt(0); }
3625 HValue* key() { return OperandAt(1); }
3626 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003627
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003628 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003629
3630 virtual Representation RequiredInputRepresentation(int index) const {
3631 return Representation::Tagged();
3632 }
3633
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003634 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635};
3636
3637
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003638class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003639 public:
3640 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003641 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003642 HValue* val,
3643 bool in_object,
3644 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003645 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003646 is_in_object_(in_object),
3647 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003648 SetOperandAt(0, obj);
3649 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003650 if (is_in_object_) {
3651 SetFlag(kChangesInobjectFields);
3652 } else {
3653 SetFlag(kChangesBackingStoreFields);
3654 }
3655 }
3656
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003657 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003658
3659 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003660 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003662 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003663
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003664 HValue* object() { return OperandAt(0); }
3665 HValue* value() { return OperandAt(1); }
3666
3667 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668 bool is_in_object() const { return is_in_object_; }
3669 int offset() const { return offset_; }
3670 Handle<Map> transition() const { return transition_; }
3671 void set_transition(Handle<Map> map) { transition_ = map; }
3672
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003673 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003674 return StoringValueNeedsWriteBarrier(value());
3675 }
3676
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003677 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003678 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003679 bool is_in_object_;
3680 int offset_;
3681 Handle<Map> transition_;
3682};
3683
3684
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003685class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003686 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003687 HStoreNamedGeneric(HValue* context,
3688 HValue* object,
3689 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003690 HValue* value,
3691 bool strict_mode)
3692 : name_(name),
3693 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003694 SetOperandAt(0, object);
3695 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003696 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003697 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003698 }
3699
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003700 HValue* object() { return OperandAt(0); }
3701 HValue* value() { return OperandAt(1); }
3702 HValue* context() { return OperandAt(2); }
3703 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003704 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003705
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003706 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003707
3708 virtual Representation RequiredInputRepresentation(int index) const {
3709 return Representation::Tagged();
3710 }
3711
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003712 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003714 private:
3715 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003716 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003717};
3718
3719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003720class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003721 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003722 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3723 SetOperandAt(0, obj);
3724 SetOperandAt(1, key);
3725 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003726 SetFlag(kChangesArrayElements);
3727 }
3728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003729 virtual Representation RequiredInputRepresentation(int index) const {
3730 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003731 return index == 1
3732 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003733 : Representation::Tagged();
3734 }
3735
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003736 HValue* object() { return OperandAt(0); }
3737 HValue* key() { return OperandAt(1); }
3738 HValue* value() { return OperandAt(2); }
3739
3740 bool NeedsWriteBarrier() {
3741 return StoringValueNeedsWriteBarrier(value());
3742 }
3743
3744 virtual void PrintDataTo(StringStream* stream);
3745
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003746 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003747};
3748
3749
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003750class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3751 public:
3752 HStoreKeyedFastDoubleElement(HValue* elements,
3753 HValue* key,
3754 HValue* val) {
3755 SetOperandAt(0, elements);
3756 SetOperandAt(1, key);
3757 SetOperandAt(2, val);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003758 SetFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003759 }
3760
3761 virtual Representation RequiredInputRepresentation(int index) const {
3762 if (index == 1) {
3763 return Representation::Integer32();
3764 } else if (index == 2) {
3765 return Representation::Double();
3766 } else {
3767 return Representation::Tagged();
3768 }
3769 }
3770
3771 HValue* elements() { return OperandAt(0); }
3772 HValue* key() { return OperandAt(1); }
3773 HValue* value() { return OperandAt(2); }
3774
3775 bool NeedsWriteBarrier() {
3776 return StoringValueNeedsWriteBarrier(value());
3777 }
3778
3779 virtual void PrintDataTo(StringStream* stream);
3780
3781 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3782};
3783
3784
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003785class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003786 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003787 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3788 HValue* key,
3789 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003790 JSObject::ElementsKind elements_kind)
3791 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003792 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003793 SetOperandAt(0, external_elements);
3794 SetOperandAt(1, key);
3795 SetOperandAt(2, val);
3796 }
3797
3798 virtual void PrintDataTo(StringStream* stream);
3799
3800 virtual Representation RequiredInputRepresentation(int index) const {
3801 if (index == 0) {
3802 return Representation::External();
3803 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003804 bool float_or_double_elements =
3805 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3806 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3807 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003808 return Representation::Double();
3809 } else {
3810 return Representation::Integer32();
3811 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003812 }
3813 }
3814
3815 HValue* external_pointer() { return OperandAt(0); }
3816 HValue* key() { return OperandAt(1); }
3817 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003818 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003819
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003820 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3821
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003822 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003823 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003824};
3825
3826
3827class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003828 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003829 HStoreKeyedGeneric(HValue* context,
3830 HValue* object,
3831 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003832 HValue* value,
3833 bool strict_mode)
3834 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003835 SetOperandAt(0, object);
3836 SetOperandAt(1, key);
3837 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003838 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003839 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003840 }
3841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003842 HValue* object() { return OperandAt(0); }
3843 HValue* key() { return OperandAt(1); }
3844 HValue* value() { return OperandAt(2); }
3845 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003846 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003847
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003848 virtual Representation RequiredInputRepresentation(int index) const {
3849 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003850 }
3851
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003852 virtual void PrintDataTo(StringStream* stream);
3853
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003854 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003855
3856 private:
3857 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003858};
3859
3860
danno@chromium.org160a7b02011-04-18 15:51:38 +00003861class HStringAdd: public HBinaryOperation {
3862 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003863 HStringAdd(HValue* context, HValue* left, HValue* right)
3864 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00003865 set_representation(Representation::Tagged());
3866 SetFlag(kUseGVN);
3867 SetFlag(kDependsOnMaps);
3868 }
3869
3870 virtual Representation RequiredInputRepresentation(int index) const {
3871 return Representation::Tagged();
3872 }
3873
3874 virtual HType CalculateInferredType() {
3875 return HType::String();
3876 }
3877
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003878 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003879
3880 protected:
3881 virtual bool DataEquals(HValue* other) { return true; }
3882};
3883
3884
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003885class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003886 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003887 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
3888 SetOperandAt(0, context);
3889 SetOperandAt(1, string);
3890 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003891 set_representation(Representation::Integer32());
3892 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003893 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003894 }
3895
3896 virtual Representation RequiredInputRepresentation(int index) const {
3897 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003898 return index == 2
3899 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003900 : Representation::Tagged();
3901 }
3902
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003903 HValue* context() { return OperandAt(0); }
3904 HValue* string() { return OperandAt(1); }
3905 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003906
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003907 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003908
3909 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003910 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003911
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003912 virtual Range* InferRange() {
3913 return new Range(0, String::kMaxUC16CharCode);
3914 }
3915};
3916
3917
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003918class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003919 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003920 HStringCharFromCode(HValue* context, HValue* char_code) {
3921 SetOperandAt(0, context);
3922 SetOperandAt(1, char_code);
3923 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003924 SetFlag(kUseGVN);
3925 }
3926
3927 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003928 return index == 0
3929 ? Representation::Tagged()
3930 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003931 }
3932
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003933 HValue* context() { return OperandAt(0); }
3934 HValue* value() { return OperandAt(1); }
3935
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003936 virtual bool DataEquals(HValue* other) { return true; }
3937
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003938 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003939};
3940
3941
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003942class HStringLength: public HUnaryOperation {
3943 public:
3944 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3945 set_representation(Representation::Tagged());
3946 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003947 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003948 }
3949
3950 virtual Representation RequiredInputRepresentation(int index) const {
3951 return Representation::Tagged();
3952 }
3953
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003954 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003955 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3956 return HType::Smi();
3957 }
3958
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003959 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003960
3961 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003962 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003963
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003964 virtual Range* InferRange() {
3965 return new Range(0, String::kMaxLength);
3966 }
3967};
3968
3969
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003970template <int V>
3971class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003972 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003973 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003974 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003975 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003976 }
3977
3978 int literal_index() const { return literal_index_; }
3979 int depth() const { return depth_; }
3980
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003981 private:
3982 int literal_index_;
3983 int depth_;
3984};
3985
3986
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003987class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003989 HArrayLiteral(HValue* context,
3990 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003991 int length,
3992 int literal_index,
3993 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003994 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003995 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003996 constant_elements_(constant_elements) {
3997 SetOperandAt(0, context);
3998 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003999
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004000 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004001 Handle<FixedArray> constant_elements() const { return constant_elements_; }
4002 int length() const { return length_; }
4003
4004 bool IsCopyOnWrite() const;
4005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004006 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004007 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004008 }
4009
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004010 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004011
4012 private:
4013 int length_;
4014 Handle<FixedArray> constant_elements_;
4015};
4016
4017
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004018class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004019 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004020 HObjectLiteral(HValue* context,
4021 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004022 bool fast_elements,
4023 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004024 int depth,
4025 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004026 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004027 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004028 fast_elements_(fast_elements),
4029 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004030 SetOperandAt(0, context);
4031 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004033 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004034 Handle<FixedArray> constant_properties() const {
4035 return constant_properties_;
4036 }
4037 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004038 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004039
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004040 virtual Representation RequiredInputRepresentation(int index) const {
4041 return Representation::Tagged();
4042 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004043
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004044 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004045
4046 private:
4047 Handle<FixedArray> constant_properties_;
4048 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004049 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004050};
4051
4052
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004053class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004054 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004055 HRegExpLiteral(HValue* context,
4056 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004057 Handle<String> flags,
4058 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004059 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004060 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004061 flags_(flags) {
4062 SetOperandAt(0, context);
4063 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004064
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004065 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004066 Handle<String> pattern() { return pattern_; }
4067 Handle<String> flags() { return flags_; }
4068
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004069 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004070 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004071 }
4072
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004073 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004074
4075 private:
4076 Handle<String> pattern_;
4077 Handle<String> flags_;
4078};
4079
4080
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004081class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004082 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004083 HFunctionLiteral(HValue* context,
4084 Handle<SharedFunctionInfo> shared,
4085 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004086 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004087 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004088 set_representation(Representation::Tagged());
4089 }
4090
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004091 HValue* context() { return OperandAt(0); }
4092
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004093 virtual Representation RequiredInputRepresentation(int index) const {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004094 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004095 }
4096
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004097 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004098
4099 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4100 bool pretenure() const { return pretenure_; }
4101
4102 private:
4103 Handle<SharedFunctionInfo> shared_info_;
4104 bool pretenure_;
4105};
4106
4107
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004108class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004109 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004110 explicit HTypeof(HValue* context, HValue* value) {
4111 SetOperandAt(0, context);
4112 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004113 set_representation(Representation::Tagged());
4114 }
4115
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004116 HValue* context() { return OperandAt(0); }
4117 HValue* value() { return OperandAt(1); }
4118
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004119 virtual Representation RequiredInputRepresentation(int index) const {
4120 return Representation::Tagged();
4121 }
4122
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004123 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004124};
4125
4126
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004127class HToFastProperties: public HUnaryOperation {
4128 public:
4129 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4130 // This instruction is not marked as having side effects, but
4131 // changes the map of the input operand. Use it only when creating
4132 // object literals.
4133 ASSERT(value->IsObjectLiteral());
4134 set_representation(Representation::Tagged());
4135 }
4136
4137 virtual Representation RequiredInputRepresentation(int index) const {
4138 return Representation::Tagged();
4139 }
4140
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004141 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004142};
4143
4144
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004145class HValueOf: public HUnaryOperation {
4146 public:
4147 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4148 set_representation(Representation::Tagged());
4149 }
4150
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004151 virtual Representation RequiredInputRepresentation(int index) const {
4152 return Representation::Tagged();
4153 }
4154
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004155 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004156};
4157
4158
4159class HDeleteProperty: public HBinaryOperation {
4160 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004161 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4162 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004163 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004164 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004165 }
4166
4167 virtual Representation RequiredInputRepresentation(int index) const {
4168 return Representation::Tagged();
4169 }
4170
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004171 virtual HType CalculateInferredType();
4172
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004173 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004174
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004175 HValue* object() { return left(); }
4176 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004177};
4178
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004179
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004180class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004181 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004182 HIn(HValue* context, HValue* key, HValue* object) {
4183 SetOperandAt(0, context);
4184 SetOperandAt(1, key);
4185 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004186 set_representation(Representation::Tagged());
4187 SetAllSideEffects();
4188 }
4189
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004190 HValue* context() { return OperandAt(0); }
4191 HValue* key() { return OperandAt(1); }
4192 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004193
4194 virtual Representation RequiredInputRepresentation(int index) const {
4195 return Representation::Tagged();
4196 }
4197
4198 virtual HType CalculateInferredType() {
4199 return HType::Boolean();
4200 }
4201
4202 virtual void PrintDataTo(StringStream* stream);
4203
4204 DECLARE_CONCRETE_INSTRUCTION(In)
4205};
4206
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004207#undef DECLARE_INSTRUCTION
4208#undef DECLARE_CONCRETE_INSTRUCTION
4209
4210} } // namespace v8::internal
4211
4212#endif // V8_HYDROGEN_INSTRUCTIONS_H_