blob: 8ee841937e8a145ed33ad1796e431a467003f0d3 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000038#include "utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000039#include "zone.h"
40
41namespace v8 {
42namespace internal {
43
44// Forward declarations.
45class HBasicBlock;
46class HEnvironment;
47class HInstruction;
48class HLoopInformation;
49class HValue;
50class LInstruction;
51class LChunkBuilder;
52
53
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000054#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(ControlInstruction) \
57 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058
59
60#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000061 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000062 V(AccessArgumentsAt) \
63 V(Add) \
64 V(ApplyArguments) \
65 V(ArgumentsElements) \
66 V(ArgumentsLength) \
67 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000068 V(ArrayLiteral) \
69 V(BitAnd) \
70 V(BitNot) \
71 V(BitOr) \
72 V(BitXor) \
73 V(BlockEntry) \
74 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000075 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000076 V(CallConstantFunction) \
77 V(CallFunction) \
78 V(CallGlobal) \
79 V(CallKeyed) \
80 V(CallKnownGlobal) \
81 V(CallNamed) \
82 V(CallNew) \
83 V(CallRuntime) \
84 V(CallStub) \
85 V(Change) \
86 V(CheckFunction) \
87 V(CheckInstanceType) \
88 V(CheckMap) \
89 V(CheckNonSmi) \
90 V(CheckPrototypeMaps) \
91 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000092 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000093 V(ClassOfTestAndBranch) \
94 V(CompareIDAndBranch) \
95 V(CompareGeneric) \
96 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000097 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000098 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000099 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000100 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000101 V(DeleteProperty) \
102 V(Deoptimize) \
103 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000104 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000105 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000106 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000107 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000108 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000109 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000110 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(GlobalObject) \
112 V(GlobalReceiver) \
113 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000114 V(HasCachedArrayIndexAndBranch) \
115 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000116 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000118 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000119 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000120 V(IsConstructCallAndBranch) \
121 V(IsNullAndBranch) \
122 V(IsObjectAndBranch) \
123 V(IsSmiAndBranch) \
124 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000125 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000127 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000129 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000130 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000131 V(LoadGlobalCell) \
132 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000133 V(LoadKeyedFastElement) \
134 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000135 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000137 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(LoadNamedGeneric) \
139 V(Mod) \
140 V(Mul) \
141 V(ObjectLiteral) \
142 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000143 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000144 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000145 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000146 V(PushArgument) \
147 V(RegExpLiteral) \
148 V(Return) \
149 V(Sar) \
150 V(Shl) \
151 V(Shr) \
152 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000153 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000154 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000155 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000156 V(StoreGlobalCell) \
157 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(StoreKeyedFastElement) \
159 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000160 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 V(StoreNamedField) \
162 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000163 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000164 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000165 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000166 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000167 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000168 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000169 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000170 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000171 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000172 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000173 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(UnaryMathOperation) \
175 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000176 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000177 V(ValueOf)
178
179#define GVN_FLAG_LIST(V) \
180 V(Calls) \
181 V(InobjectFields) \
182 V(BackingStoreFields) \
183 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000184 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000185 V(GlobalVars) \
186 V(Maps) \
187 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000188 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000189 V(OsrEntries)
190
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000191#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192 virtual bool Is##type() const { return true; } \
193 static H##type* cast(HValue* value) { \
194 ASSERT(value->Is##type()); \
195 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000196 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197
198
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000199#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000201 static H##type* cast(HValue* value) { \
202 ASSERT(value->Is##type()); \
203 return reinterpret_cast<H##type*>(value); \
204 } \
205 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206
207
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000208class Range: public ZoneObject {
209 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000210 Range()
211 : lower_(kMinInt),
212 upper_(kMaxInt),
213 next_(NULL),
214 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215
216 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000217 : lower_(lower),
218 upper_(upper),
219 next_(NULL),
220 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222 int32_t upper() const { return upper_; }
223 int32_t lower() const { return lower_; }
224 Range* next() const { return next_; }
225 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
226 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 int32_t Mask() const;
229 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
230 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
231 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
232 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000233 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
234 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
235 bool IsInSmiRange() const {
236 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000238 void KeepOrder();
239 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000240
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000241 void StackUpon(Range* other) {
242 Intersect(other);
243 next_ = other;
244 }
245
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000246 void Intersect(Range* other);
247 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000248
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000249 void AddConstant(int32_t value);
250 void Sar(int32_t value);
251 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000252 bool AddAndCheckOverflow(Range* other);
253 bool SubAndCheckOverflow(Range* other);
254 bool MulAndCheckOverflow(Range* other);
255
256 private:
257 int32_t lower_;
258 int32_t upper_;
259 Range* next_;
260 bool can_be_minus_zero_;
261};
262
263
264class Representation {
265 public:
266 enum Kind {
267 kNone,
268 kTagged,
269 kDouble,
270 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000271 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272 kNumRepresentations
273 };
274
275 Representation() : kind_(kNone) { }
276
277 static Representation None() { return Representation(kNone); }
278 static Representation Tagged() { return Representation(kTagged); }
279 static Representation Integer32() { return Representation(kInteger32); }
280 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000281 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000283 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000284 return kind_ == other.kind_;
285 }
286
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000287 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000288 bool IsNone() const { return kind_ == kNone; }
289 bool IsTagged() const { return kind_ == kTagged; }
290 bool IsInteger32() const { return kind_ == kInteger32; }
291 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000292 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000293 bool IsSpecialization() const {
294 return kind_ == kInteger32 || kind_ == kDouble;
295 }
296 const char* Mnemonic() const;
297
298 private:
299 explicit Representation(Kind k) : kind_(k) { }
300
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000301 // Make sure kind fits in int8.
302 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
303
304 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000305};
306
307
308class HType {
309 public:
310 HType() : type_(kUninitialized) { }
311
312 static HType Tagged() { return HType(kTagged); }
313 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
314 static HType TaggedNumber() { return HType(kTaggedNumber); }
315 static HType Smi() { return HType(kSmi); }
316 static HType HeapNumber() { return HType(kHeapNumber); }
317 static HType String() { return HType(kString); }
318 static HType Boolean() { return HType(kBoolean); }
319 static HType NonPrimitive() { return HType(kNonPrimitive); }
320 static HType JSArray() { return HType(kJSArray); }
321 static HType JSObject() { return HType(kJSObject); }
322 static HType Uninitialized() { return HType(kUninitialized); }
323
324 // Return the weakest (least precise) common type.
325 HType Combine(HType other) {
326 return HType(static_cast<Type>(type_ & other.type_));
327 }
328
329 bool Equals(const HType& other) {
330 return type_ == other.type_;
331 }
332
333 bool IsSubtypeOf(const HType& other) {
334 return Combine(other).Equals(other);
335 }
336
337 bool IsTagged() {
338 ASSERT(type_ != kUninitialized);
339 return ((type_ & kTagged) == kTagged);
340 }
341
342 bool IsTaggedPrimitive() {
343 ASSERT(type_ != kUninitialized);
344 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
345 }
346
347 bool IsTaggedNumber() {
348 ASSERT(type_ != kUninitialized);
349 return ((type_ & kTaggedNumber) == kTaggedNumber);
350 }
351
352 bool IsSmi() {
353 ASSERT(type_ != kUninitialized);
354 return ((type_ & kSmi) == kSmi);
355 }
356
357 bool IsHeapNumber() {
358 ASSERT(type_ != kUninitialized);
359 return ((type_ & kHeapNumber) == kHeapNumber);
360 }
361
362 bool IsString() {
363 ASSERT(type_ != kUninitialized);
364 return ((type_ & kString) == kString);
365 }
366
367 bool IsBoolean() {
368 ASSERT(type_ != kUninitialized);
369 return ((type_ & kBoolean) == kBoolean);
370 }
371
372 bool IsNonPrimitive() {
373 ASSERT(type_ != kUninitialized);
374 return ((type_ & kNonPrimitive) == kNonPrimitive);
375 }
376
377 bool IsJSArray() {
378 ASSERT(type_ != kUninitialized);
379 return ((type_ & kJSArray) == kJSArray);
380 }
381
382 bool IsJSObject() {
383 ASSERT(type_ != kUninitialized);
384 return ((type_ & kJSObject) == kJSObject);
385 }
386
387 bool IsUninitialized() {
388 return type_ == kUninitialized;
389 }
390
391 static HType TypeFromValue(Handle<Object> value);
392
393 const char* ToString();
394 const char* ToShortString();
395
396 private:
397 enum Type {
398 kTagged = 0x1, // 0000 0000 0000 0001
399 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
400 kTaggedNumber = 0xd, // 0000 0000 0000 1101
401 kSmi = 0x1d, // 0000 0000 0001 1101
402 kHeapNumber = 0x2d, // 0000 0000 0010 1101
403 kString = 0x45, // 0000 0000 0100 0101
404 kBoolean = 0x85, // 0000 0000 1000 0101
405 kNonPrimitive = 0x101, // 0000 0001 0000 0001
406 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000407 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000408 kUninitialized = 0x1fff // 0001 1111 1111 1111
409 };
410
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000411 // Make sure type fits in int16.
412 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
413
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000414 explicit HType(Type t) : type_(t) { }
415
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000416 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000417};
418
419
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000420class HUseListNode: public ZoneObject {
421 public:
422 HUseListNode(HValue* value, int index, HUseListNode* tail)
423 : tail_(tail), value_(value), index_(index) {
424 }
425
426 HUseListNode* tail() const { return tail_; }
427 HValue* value() const { return value_; }
428 int index() const { return index_; }
429
430 void set_tail(HUseListNode* list) { tail_ = list; }
431
432#ifdef DEBUG
433 void Zap() {
434 tail_ = reinterpret_cast<HUseListNode*>(1);
435 value_ = NULL;
436 index_ = -1;
437 }
438#endif
439
440 private:
441 HUseListNode* tail_;
442 HValue* value_;
443 int index_;
444};
445
446
447// We reuse use list nodes behind the scenes as uses are added and deleted.
448// This class is the safe way to iterate uses while deleting them.
449class HUseIterator BASE_EMBEDDED {
450 public:
451 bool Done() { return current_ == NULL; }
452 void Advance();
453
454 HValue* value() {
455 ASSERT(!Done());
456 return value_;
457 }
458
459 int index() {
460 ASSERT(!Done());
461 return index_;
462 }
463
464 private:
465 explicit HUseIterator(HUseListNode* head);
466
467 HUseListNode* current_;
468 HUseListNode* next_;
469 HValue* value_;
470 int index_;
471
472 friend class HValue;
473};
474
475
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000476class HValue: public ZoneObject {
477 public:
478 static const int kNoNumber = -1;
479
480 // There must be one corresponding kDepends flag for every kChanges flag and
481 // the order of the kChanges flags must be exactly the same as of the kDepends
482 // flags.
483 enum Flag {
484 // Declare global value numbering flags.
485 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
486 GVN_FLAG_LIST(DECLARE_DO)
487 #undef DECLARE_DO
488 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000489 // Participate in Global Value Numbering, i.e. elimination of
490 // unnecessary recomputations. If an instruction sets this flag, it must
491 // implement DataEquals(), which will be used to determine if other
492 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000493 kUseGVN,
494 kCanOverflow,
495 kBailoutOnMinusZero,
496 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000497 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000498 kIsArguments,
499 kTruncatingToInt32,
500 kLastFlag = kTruncatingToInt32
501 };
502
503 STATIC_ASSERT(kLastFlag < kBitsPerInt);
504
505 static const int kChangesToDependsFlagsLeftShift = 1;
506
507 static int ChangesFlagsMask() {
508 int result = 0;
509 // Create changes mask.
510#define DECLARE_DO(type) result |= (1 << kChanges##type);
511 GVN_FLAG_LIST(DECLARE_DO)
512#undef DECLARE_DO
513 return result;
514 }
515
516 static int DependsFlagsMask() {
517 return ConvertChangesToDependsFlags(ChangesFlagsMask());
518 }
519
520 static int ConvertChangesToDependsFlags(int flags) {
521 return flags << kChangesToDependsFlagsLeftShift;
522 }
523
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000524 static HValue* cast(HValue* value) { return value; }
525
526 enum Opcode {
527 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000528 #define DECLARE_OPCODE(type) k##type,
529 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
530 kPhi
531 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000532 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000533 virtual Opcode opcode() const = 0;
534
535 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
536 #define DECLARE_PREDICATE(type) \
537 bool Is##type() const { return opcode() == k##type; }
538 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
539 #undef DECLARE_PREDICATE
540 bool IsPhi() const { return opcode() == kPhi; }
541
542 // Declare virtual predicates for abstract HInstruction or HValue
543 #define DECLARE_PREDICATE(type) \
544 virtual bool Is##type() const { return false; }
545 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
546 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000547
548 HValue() : block_(NULL),
549 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000550 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000551 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000552 range_(NULL),
553 flags_(0) {}
554 virtual ~HValue() {}
555
556 HBasicBlock* block() const { return block_; }
557 void SetBlock(HBasicBlock* block);
558
559 int id() const { return id_; }
560 void set_id(int id) { id_ = id; }
561
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000562 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000563
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000564 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000565 Representation representation() const { return representation_; }
566 void ChangeRepresentation(Representation r) {
567 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568 ASSERT(!r.IsNone());
569 ASSERT(CheckFlag(kFlexibleRepresentation));
570 RepresentationChanged(r);
571 representation_ = r;
572 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000573 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000574
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000575 virtual bool IsConvertibleToInteger() const { return true; }
576
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577 HType type() const { return type_; }
578 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000579 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000580 type_ = type;
581 }
582
583 // An operation needs to override this function iff:
584 // 1) it can produce an int32 output.
585 // 2) the true value of its output can potentially be minus zero.
586 // The implementation must set a flag so that it bails out in the case where
587 // it would otherwise output what should be a minus zero as an int32 zero.
588 // If the operation also exists in a form that takes int32 and outputs int32
589 // then the operation should return its input value so that we can propagate
590 // back. There are two operations that need to propagate back to more than
591 // one input. They are phi and binary add. They always return NULL and
592 // expect the caller to take care of things.
593 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
594 visited->Add(id());
595 return NULL;
596 }
597
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000598 bool IsDefinedAfter(HBasicBlock* other) const;
599
600 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000601 virtual int OperandCount() = 0;
602 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000603 void SetOperandAt(int index, HValue* value);
604
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000605 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000606 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000607 bool HasNoUses() const { return use_list_ == NULL; }
608 bool HasMultipleUses() const {
609 return use_list_ != NULL && use_list_->tail() != NULL;
610 }
611 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000613
614 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000615 void SetFlag(Flag f) { flags_ |= (1 << f); }
616 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
617 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
618
619 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
620 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
621 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622
623 Range* range() const { return range_; }
624 bool HasRange() const { return range_ != NULL; }
625 void AddNewRange(Range* r);
626 void RemoveLastAddedRange();
627 void ComputeInitialRange();
628
629 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000630 virtual Representation RequiredInputRepresentation(int index) const = 0;
631
632 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000633 return representation();
634 }
635
636 // This gives the instruction an opportunity to replace itself with an
637 // instruction that does the same in some better way. To replace an
638 // instruction with a new one, first add the new instruction to the graph,
639 // then return it. Return NULL to have the instruction deleted.
640 virtual HValue* Canonicalize() { return this; }
641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000642 bool Equals(HValue* other);
643 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000644
645 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000646 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000647 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000648 void PrintTypeTo(StringStream* stream);
649 void PrintRangeTo(StringStream* stream);
650 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000651
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000652 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000653
654 // Updated the inferred type of this instruction and returns true if
655 // it has changed.
656 bool UpdateInferredType();
657
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000658 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000659
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000661 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000662#endif
663
664 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000665 // This function must be overridden for instructions with flag kUseGVN, to
666 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000667 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000668 UNREACHABLE();
669 return false;
670 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000671 virtual void RepresentationChanged(Representation to) { }
672 virtual Range* InferRange();
673 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000674 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000675 void clear_block() {
676 ASSERT(block_ != NULL);
677 block_ = NULL;
678 }
679
680 void set_representation(Representation r) {
681 // Representation is set-once.
682 ASSERT(representation_.IsNone() && !r.IsNone());
683 representation_ = r;
684 }
685
686 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000687 // A flag mask to mark an instruction as having arbitrary side effects.
688 static int AllSideEffects() {
689 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
690 }
691
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000692 // Remove the matching use from the use list if present. Returns the
693 // removed list node or NULL.
694 HUseListNode* RemoveUse(HValue* value, int index);
695
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000696 void RegisterUse(int index, HValue* new_value);
697
698 HBasicBlock* block_;
699
700 // The id of this instruction in the hydrogen graph, assigned when first
701 // added to the graph. Reflects creation order.
702 int id_;
703
704 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000705 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000706 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000707 Range* range_;
708 int flags_;
709
710 DISALLOW_COPY_AND_ASSIGN(HValue);
711};
712
713
714class HInstruction: public HValue {
715 public:
716 HInstruction* next() const { return next_; }
717 HInstruction* previous() const { return previous_; }
718
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000719 virtual void PrintTo(StringStream* stream);
720 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000721
722 bool IsLinked() const { return block() != NULL; }
723 void Unlink();
724 void InsertBefore(HInstruction* next);
725 void InsertAfter(HInstruction* previous);
726
727 int position() const { return position_; }
728 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
729 void set_position(int position) { position_ = position; }
730
731 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
732
733#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000734 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000735#endif
736
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000737 virtual bool IsCall() { return false; }
738
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000739 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000740
741 protected:
742 HInstruction()
743 : next_(NULL),
744 previous_(NULL),
745 position_(RelocInfo::kNoPosition) {
746 SetFlag(kDependsOnOsrEntries);
747 }
748
749 virtual void DeleteFromGraph() { Unlink(); }
750
751 private:
752 void InitializeAsFirst(HBasicBlock* block) {
753 ASSERT(!IsLinked());
754 SetBlock(block);
755 }
756
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000757 void PrintMnemonicTo(StringStream* stream);
758
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000759 HInstruction* next_;
760 HInstruction* previous_;
761 int position_;
762
763 friend class HBasicBlock;
764};
765
766
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000767template<int V>
768class HTemplateInstruction : public HInstruction {
769 public:
770 int OperandCount() { return V; }
771 HValue* OperandAt(int i) { return inputs_[i]; }
772
773 protected:
774 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
775
776 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000777 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000778};
779
780
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000781class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000782 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000783 virtual HBasicBlock* SuccessorAt(int i) = 0;
784 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000785 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000786
787 virtual void PrintDataTo(StringStream* stream);
788
789 HBasicBlock* FirstSuccessor() {
790 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
791 }
792 HBasicBlock* SecondSuccessor() {
793 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
794 }
795
796 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
797};
798
799
800class HSuccessorIterator BASE_EMBEDDED {
801 public:
802 explicit HSuccessorIterator(HControlInstruction* instr)
803 : instr_(instr), current_(0) { }
804
805 bool Done() { return current_ >= instr_->SuccessorCount(); }
806 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
807 void Advance() { current_++; }
808
809 private:
810 HControlInstruction* instr_;
811 int current_;
812};
813
814
815template<int S, int V>
816class HTemplateControlInstruction: public HControlInstruction {
817 public:
818 int SuccessorCount() { return S; }
819 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000820 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000821
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000822 int OperandCount() { return V; }
823 HValue* OperandAt(int i) { return inputs_[i]; }
824
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000826 protected:
827 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
828
829 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000830 EmbeddedContainer<HBasicBlock*, S> successors_;
831 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000832};
833
834
835class HBlockEntry: public HTemplateInstruction<0> {
836 public:
837 virtual Representation RequiredInputRepresentation(int index) const {
838 return Representation::None();
839 }
840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000841 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000842};
843
844
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000845// We insert soft-deoptimize when we hit code with unknown typefeedback,
846// so that we get a chance of re-optimizing with useful typefeedback.
847// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
848class HSoftDeoptimize: public HTemplateInstruction<0> {
849 public:
850 virtual Representation RequiredInputRepresentation(int index) const {
851 return Representation::None();
852 }
853
854 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
855};
856
857
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000858class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000859 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000860 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000861
862 virtual Representation RequiredInputRepresentation(int index) const {
863 return Representation::None();
864 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000865
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000866 virtual int OperandCount() { return values_.length(); }
867 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000868 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000870 virtual int SuccessorCount() { return 0; }
871 virtual HBasicBlock* SuccessorAt(int i) {
872 UNREACHABLE();
873 return NULL;
874 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000875 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
876 UNREACHABLE();
877 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000878
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000879 void AddEnvironmentValue(HValue* value) {
880 values_.Add(NULL);
881 SetOperandAt(values_.length() - 1, value);
882 }
883
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000884 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000885
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000886 enum UseEnvironment {
887 kNoUses,
888 kUseAll
889 };
890
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000891 protected:
892 virtual void InternalSetOperandAt(int index, HValue* value) {
893 values_[index] = value;
894 }
895
896 private:
897 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000898};
899
900
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000901class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000902 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000903 explicit HGoto(HBasicBlock* target) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000904 SetSuccessorAt(0, target);
905 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000907 virtual Representation RequiredInputRepresentation(int index) const {
908 return Representation::None();
909 }
910
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000911 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000912};
913
914
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000915class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000916 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000917 HUnaryControlInstruction(HValue* value,
918 HBasicBlock* true_target,
919 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000920 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000921 SetSuccessorAt(0, true_target);
922 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 }
924
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000925 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000927 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000928};
929
930
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000931class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000933 HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000934 : HUnaryControlInstruction(value, true_target, false_target) {
935 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000937 explicit HBranch(HValue* value)
938 : HUnaryControlInstruction(value, NULL, NULL) { }
939
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000940
941 virtual Representation RequiredInputRepresentation(int index) const {
942 return Representation::None();
943 }
944
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000945 DECLARE_CONCRETE_INSTRUCTION(Branch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000946};
947
948
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000949class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000951 HCompareMap(HValue* value,
952 Handle<Map> map,
953 HBasicBlock* true_target,
954 HBasicBlock* false_target)
955 : HUnaryControlInstruction(value, true_target, false_target),
956 map_(map) {
957 ASSERT(true_target != NULL);
958 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959 ASSERT(!map.is_null());
960 }
961
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000962 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000963
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964 Handle<Map> map() const { return map_; }
965
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000966 virtual Representation RequiredInputRepresentation(int index) const {
967 return Representation::Tagged();
968 }
969
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000970 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000971
972 private:
973 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974};
975
976
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000977class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000978 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000979 explicit HReturn(HValue* value) {
980 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000981 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000983 virtual Representation RequiredInputRepresentation(int index) const {
984 return Representation::Tagged();
985 }
986
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000987 virtual void PrintDataTo(StringStream* stream);
988
989 HValue* value() { return OperandAt(0); }
990
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000991 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000992};
993
994
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000995class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000997 virtual Representation RequiredInputRepresentation(int index) const {
998 return Representation::None();
999 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001001 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001002};
1003
1004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001005class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001006 public:
1007 explicit HUnaryOperation(HValue* value) {
1008 SetOperandAt(0, value);
1009 }
1010
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001011 static HUnaryOperation* cast(HValue* value) {
1012 return reinterpret_cast<HUnaryOperation*>(value);
1013 }
1014
1015 virtual bool CanTruncateToInt32() const {
1016 return CheckFlag(kTruncatingToInt32);
1017 }
1018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001019 HValue* value() { return OperandAt(0); }
1020 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001021};
1022
1023
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001024class HThrow: public HUnaryOperation {
1025 public:
1026 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1027 SetAllSideEffects();
1028 }
1029
1030 virtual Representation RequiredInputRepresentation(int index) const {
1031 return Representation::Tagged();
1032 }
1033
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001034 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001035};
1036
1037
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001038class HUseConst: public HUnaryOperation {
1039 public:
1040 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1041
1042 virtual Representation RequiredInputRepresentation(int index) const {
1043 return Representation::None();
1044 }
1045
1046 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1047};
1048
1049
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001050class HForceRepresentation: public HTemplateInstruction<1> {
1051 public:
1052 HForceRepresentation(HValue* value, Representation required_representation) {
1053 SetOperandAt(0, value);
1054 set_representation(required_representation);
1055 }
1056
1057 HValue* value() { return OperandAt(0); }
1058
1059 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1060
1061 virtual Representation RequiredInputRepresentation(int index) const {
1062 return representation(); // Same as the output representation.
1063 }
1064
1065 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1066};
1067
1068
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001069class HChange: public HUnaryOperation {
1070 public:
1071 HChange(HValue* value,
1072 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001073 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001074 bool is_truncating,
1075 bool deoptimize_on_undefined)
1076 : HUnaryOperation(value),
1077 from_(from),
1078 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001079 ASSERT(!from.IsNone() && !to.IsNone());
1080 ASSERT(!from.Equals(to));
1081 set_representation(to);
1082 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001083 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001084 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1085 value->range()->IsInSmiRange()) {
1086 set_type(HType::Smi());
1087 }
1088 }
1089
1090 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1091
1092 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001093 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001094 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001095 virtual Representation RequiredInputRepresentation(int index) const {
1096 return from_;
1097 }
1098
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001099 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001100
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001101 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001102
1103 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001104 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001105 if (!other->IsChange()) return false;
1106 HChange* change = HChange::cast(other);
1107 return value() == change->value()
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001108 && to().Equals(change->to())
1109 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110 }
1111
1112 private:
1113 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001114 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115};
1116
1117
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001118class HClampToUint8: public HUnaryOperation {
1119 public:
1120 explicit HClampToUint8(HValue* value)
1121 : HUnaryOperation(value),
1122 input_rep_(Representation::None()) {
1123 SetFlag(kFlexibleRepresentation);
1124 set_representation(Representation::Tagged());
1125 SetFlag(kUseGVN);
1126 }
1127
1128 virtual Representation RequiredInputRepresentation(int index) const {
1129 return input_rep_;
1130 }
1131
1132 virtual Representation InferredRepresentation() {
1133 // TODO(danno): Inference on input types should happen separately from
1134 // return representation.
1135 Representation new_rep = value()->representation();
1136 if (input_rep_.IsNone()) {
1137 if (!new_rep.IsNone()) {
1138 input_rep_ = new_rep;
1139 return Representation::Integer32();
1140 } else {
1141 return Representation::None();
1142 }
1143 } else {
1144 return Representation::Integer32();
1145 }
1146 }
1147
1148 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1149
1150 protected:
1151 virtual bool DataEquals(HValue* other) { return true; }
1152
1153 private:
1154 Representation input_rep_;
1155};
1156
1157
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001158class HToInt32: public HUnaryOperation {
1159 public:
1160 explicit HToInt32(HValue* value)
1161 : HUnaryOperation(value) {
1162 set_representation(Representation::Integer32());
1163 SetFlag(kUseGVN);
1164 }
1165
1166 virtual Representation RequiredInputRepresentation(int index) const {
1167 return Representation::None();
1168 }
1169
1170 virtual bool CanTruncateToInt32() const {
1171 return true;
1172 }
1173
1174 virtual HValue* Canonicalize() {
1175 if (value()->representation().IsInteger32()) {
1176 return value();
1177 } else {
1178 return this;
1179 }
1180 }
1181
1182 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1183
1184 protected:
1185 virtual bool DataEquals(HValue* other) { return true; }
1186};
1187
1188
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001189class HSimulate: public HInstruction {
1190 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001191 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001192 : ast_id_(ast_id),
1193 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194 values_(2),
1195 assigned_indexes_(2) {}
1196 virtual ~HSimulate() {}
1197
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001198 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001199
1200 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1201 int ast_id() const { return ast_id_; }
1202 void set_ast_id(int id) {
1203 ASSERT(!HasAstId());
1204 ast_id_ = id;
1205 }
1206
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001207 int pop_count() const { return pop_count_; }
1208 const ZoneList<HValue*>* values() const { return &values_; }
1209 int GetAssignedIndexAt(int index) const {
1210 ASSERT(HasAssignedIndexAt(index));
1211 return assigned_indexes_[index];
1212 }
1213 bool HasAssignedIndexAt(int index) const {
1214 return assigned_indexes_[index] != kNoIndex;
1215 }
1216 void AddAssignedValue(int index, HValue* value) {
1217 AddValue(index, value);
1218 }
1219 void AddPushedValue(HValue* value) {
1220 AddValue(kNoIndex, value);
1221 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001222 virtual int OperandCount() { return values_.length(); }
1223 virtual HValue* OperandAt(int index) { return values_[index]; }
1224
1225 virtual Representation RequiredInputRepresentation(int index) const {
1226 return Representation::None();
1227 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001228
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001229 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001230
1231#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001232 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233#endif
1234
1235 protected:
1236 virtual void InternalSetOperandAt(int index, HValue* value) {
1237 values_[index] = value;
1238 }
1239
1240 private:
1241 static const int kNoIndex = -1;
1242 void AddValue(int index, HValue* value) {
1243 assigned_indexes_.Add(index);
1244 // Resize the list of pushed values.
1245 values_.Add(NULL);
1246 // Set the operand through the base method in HValue to make sure that the
1247 // use lists are correctly updated.
1248 SetOperandAt(values_.length() - 1, value);
1249 }
1250 int ast_id_;
1251 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001252 ZoneList<HValue*> values_;
1253 ZoneList<int> assigned_indexes_;
1254};
1255
1256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001257class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001258 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001259 enum Type {
1260 kFunctionEntry,
1261 kBackwardsBranch
1262 };
1263
1264 explicit HStackCheck(Type type) : type_(type) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001265
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001266 virtual Representation RequiredInputRepresentation(int index) const {
1267 return Representation::None();
1268 }
1269
ager@chromium.org04921a82011-06-27 13:21:41 +00001270 void Eliminate() {
1271 // The stack check eliminator might try to eliminate the same stack
1272 // check instruction multiple times.
1273 if (IsLinked()) {
1274 DeleteFromGraph();
1275 }
1276 }
1277
1278 bool is_function_entry() { return type_ == kFunctionEntry; }
1279 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1280
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001281 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001282
1283 private:
1284 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001285};
1286
1287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001288class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001290 HEnterInlined(Handle<JSFunction> closure,
1291 FunctionLiteral* function,
1292 CallKind call_kind)
1293 : closure_(closure),
1294 function_(function),
1295 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001296 }
1297
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001298 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001299
1300 Handle<JSFunction> closure() const { return closure_; }
1301 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001302 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001303
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001304 virtual Representation RequiredInputRepresentation(int index) const {
1305 return Representation::None();
1306 }
1307
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001308 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001309
1310 private:
1311 Handle<JSFunction> closure_;
1312 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001313 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314};
1315
1316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001317class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318 public:
1319 HLeaveInlined() {}
1320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321 virtual Representation RequiredInputRepresentation(int index) const {
1322 return Representation::None();
1323 }
1324
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001325 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001326};
1327
1328
1329class HPushArgument: public HUnaryOperation {
1330 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001331 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1332 set_representation(Representation::Tagged());
1333 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001334
1335 virtual Representation RequiredInputRepresentation(int index) const {
1336 return Representation::Tagged();
1337 }
1338
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001339 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001340
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001341 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001342};
1343
1344
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001345class HThisFunction: public HTemplateInstruction<0> {
1346 public:
1347 HThisFunction() {
1348 set_representation(Representation::Tagged());
1349 SetFlag(kUseGVN);
1350 }
1351
1352 virtual Representation RequiredInputRepresentation(int index) const {
1353 return Representation::None();
1354 }
1355
1356 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1357
1358 protected:
1359 virtual bool DataEquals(HValue* other) { return true; }
1360};
1361
1362
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001363class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001364 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001365 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001366 set_representation(Representation::Tagged());
1367 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001368 }
1369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001370 virtual Representation RequiredInputRepresentation(int index) const {
1371 return Representation::None();
1372 }
1373
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001374 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001375
1376 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001377 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001378};
1379
1380
1381class HOuterContext: public HUnaryOperation {
1382 public:
1383 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1384 set_representation(Representation::Tagged());
1385 SetFlag(kUseGVN);
1386 }
1387
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001388 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390 virtual Representation RequiredInputRepresentation(int index) const {
1391 return Representation::Tagged();
1392 }
1393
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001395 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001396};
1397
1398
1399class HGlobalObject: public HUnaryOperation {
1400 public:
1401 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1402 set_representation(Representation::Tagged());
1403 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001404 }
1405
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001406 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001407
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001408 virtual Representation RequiredInputRepresentation(int index) const {
1409 return Representation::Tagged();
1410 }
1411
ager@chromium.org378b34e2011-01-28 08:04:38 +00001412 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001413 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001414};
1415
1416
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001417class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001418 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001419 explicit HGlobalReceiver(HValue* global_object)
1420 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421 set_representation(Representation::Tagged());
1422 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 }
1424
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001425 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001427 virtual Representation RequiredInputRepresentation(int index) const {
1428 return Representation::Tagged();
1429 }
1430
ager@chromium.org378b34e2011-01-28 08:04:38 +00001431 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001432 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001433};
1434
1435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001436template <int V>
1437class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001439 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001440 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1441 this->set_representation(Representation::Tagged());
1442 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001443 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001446
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001447 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001448
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001449 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001451 private:
1452 int argument_count_;
1453};
1454
1455
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001456class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001457 public:
1458 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001459 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001460 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001461 }
1462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001463 virtual Representation RequiredInputRepresentation(int index) const {
1464 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465 }
1466
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001467 virtual void PrintDataTo(StringStream* stream);
1468
1469 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001470};
1471
1472
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001473class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001474 public:
1475 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001477 SetOperandAt(0, first);
1478 SetOperandAt(1, second);
1479 }
1480
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001481 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001482
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001483 virtual Representation RequiredInputRepresentation(int index) const {
1484 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001485 }
1486
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001487 HValue* first() { return OperandAt(0); }
1488 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001489};
1490
1491
danno@chromium.org160a7b02011-04-18 15:51:38 +00001492class HInvokeFunction: public HBinaryCall {
1493 public:
1494 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1495 : HBinaryCall(context, function, argument_count) {
1496 }
1497
1498 virtual Representation RequiredInputRepresentation(int index) const {
1499 return Representation::Tagged();
1500 }
1501
1502 HValue* context() { return first(); }
1503 HValue* function() { return second(); }
1504
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001505 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001506};
1507
1508
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001509class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001510 public:
1511 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001512 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513
1514 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001515
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001517 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001518 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519 }
1520
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001521 virtual void PrintDataTo(StringStream* stream);
1522
1523 virtual Representation RequiredInputRepresentation(int index) const {
1524 return Representation::None();
1525 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001527 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528
1529 private:
1530 Handle<JSFunction> function_;
1531};
1532
1533
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001534class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001535 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001536 HCallKeyed(HValue* context, HValue* key, int argument_count)
1537 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538 }
1539
1540 virtual Representation RequiredInputRepresentation(int index) const {
1541 return Representation::Tagged();
1542 }
1543
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001544 HValue* context() { return first(); }
1545 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001546
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001547 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001548};
1549
1550
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001551class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001552 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001553 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1554 : HUnaryCall(context, argument_count), name_(name) {
1555 }
1556
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001557 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001558
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001559 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001560 Handle<String> name() const { return name_; }
1561
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001562 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001564 virtual Representation RequiredInputRepresentation(int index) const {
1565 return Representation::Tagged();
1566 }
1567
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001568 private:
1569 Handle<String> name_;
1570};
1571
1572
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001573class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001575 HCallFunction(HValue* context, int argument_count)
1576 : HUnaryCall(context, argument_count) {
1577 }
1578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001579 HValue* context() { return value(); }
1580
1581 virtual Representation RequiredInputRepresentation(int index) const {
1582 return Representation::Tagged();
1583 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001584
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001585 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586};
1587
1588
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001589class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001590 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001591 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1592 : HUnaryCall(context, argument_count), name_(name) {
1593 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001594
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001595 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001597 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001598 Handle<String> name() const { return name_; }
1599
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001600 virtual Representation RequiredInputRepresentation(int index) const {
1601 return Representation::Tagged();
1602 }
1603
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001604 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605
1606 private:
1607 Handle<String> name_;
1608};
1609
1610
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001611class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001613 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001614 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001616 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001617
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618 Handle<JSFunction> target() const { return target_; }
1619
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001620 virtual Representation RequiredInputRepresentation(int index) const {
1621 return Representation::None();
1622 }
1623
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001624 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625
1626 private:
1627 Handle<JSFunction> target_;
1628};
1629
1630
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001631class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001632 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001633 HCallNew(HValue* context, HValue* constructor, int argument_count)
1634 : HBinaryCall(context, constructor, argument_count) {
1635 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001636
1637 virtual Representation RequiredInputRepresentation(int index) const {
1638 return Representation::Tagged();
1639 }
1640
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001641 HValue* context() { return first(); }
1642 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001643
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001644 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001645};
1646
1647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001648class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001649 public:
1650 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001651 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001653 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1654 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001655
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001656 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001657 Handle<String> name() const { return name_; }
1658
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001659 virtual Representation RequiredInputRepresentation(int index) const {
1660 return Representation::None();
1661 }
1662
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001663 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001664
1665 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001666 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667 Handle<String> name_;
1668};
1669
1670
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001671class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001672 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001673 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674 // The length of an array is stored as a tagged value in the array
1675 // object. It is guaranteed to be 32 bit integer, but it can be
1676 // represented as either a smi or heap number.
1677 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001678 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001679 SetFlag(kDependsOnArrayLengths);
1680 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001681 }
1682
1683 virtual Representation RequiredInputRepresentation(int index) const {
1684 return Representation::Tagged();
1685 }
1686
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001687 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001688
1689 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001690 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001691};
1692
1693
1694class HFixedArrayLength: public HUnaryOperation {
1695 public:
1696 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1697 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001698 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001699 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001700 }
1701
1702 virtual Representation RequiredInputRepresentation(int index) const {
1703 return Representation::Tagged();
1704 }
1705
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001706 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001707
1708 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001709 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710};
1711
1712
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001713class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001714 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001715 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001716 set_representation(Representation::Integer32());
1717 // The result of this instruction is idempotent as long as its inputs don't
1718 // change. The length of a pixel array cannot change once set, so it's not
1719 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1720 SetFlag(kUseGVN);
1721 }
1722
1723 virtual Representation RequiredInputRepresentation(int index) const {
1724 return Representation::Tagged();
1725 }
1726
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001727 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001728
1729 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001730 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001731};
1732
1733
whesse@chromium.org7b260152011-06-20 15:33:18 +00001734class HElementsKind: public HUnaryOperation {
1735 public:
1736 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1737 set_representation(Representation::Integer32());
1738 SetFlag(kUseGVN);
1739 SetFlag(kDependsOnMaps);
1740 }
1741
1742 virtual Representation RequiredInputRepresentation(int index) const {
1743 return Representation::Tagged();
1744 }
1745
1746 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1747
1748 protected:
1749 virtual bool DataEquals(HValue* other) { return true; }
1750};
1751
1752
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001753class HBitNot: public HUnaryOperation {
1754 public:
1755 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1756 set_representation(Representation::Integer32());
1757 SetFlag(kUseGVN);
1758 SetFlag(kTruncatingToInt32);
1759 }
1760
1761 virtual Representation RequiredInputRepresentation(int index) const {
1762 return Representation::Integer32();
1763 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001764 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001766 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001767
1768 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001769 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770};
1771
1772
1773class HUnaryMathOperation: public HUnaryOperation {
1774 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001775 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001776 : HUnaryOperation(value), op_(op) {
1777 switch (op) {
1778 case kMathFloor:
1779 case kMathRound:
1780 case kMathCeil:
1781 set_representation(Representation::Integer32());
1782 break;
1783 case kMathAbs:
1784 set_representation(Representation::Tagged());
1785 SetFlag(kFlexibleRepresentation);
1786 break;
1787 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001788 case kMathPowHalf:
1789 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001790 case kMathSin:
1791 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001792 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001793 break;
1794 default:
1795 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001796 }
1797 SetFlag(kUseGVN);
1798 }
1799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001800 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001802 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803
1804 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1805
1806 virtual Representation RequiredInputRepresentation(int index) const {
1807 switch (op_) {
1808 case kMathFloor:
1809 case kMathRound:
1810 case kMathCeil:
1811 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001812 case kMathPowHalf:
1813 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001814 case kMathSin:
1815 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001816 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817 case kMathAbs:
1818 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001819 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001820 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001821 return Representation::None();
1822 }
1823 }
1824
1825 virtual HValue* Canonicalize() {
1826 // If the input is integer32 then we replace the floor instruction
1827 // with its inputs. This happens before the representation changes are
1828 // introduced.
1829 if (op() == kMathFloor) {
1830 if (value()->representation().IsInteger32()) return value();
1831 }
1832 return this;
1833 }
1834
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001835 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001836 const char* OpName() const;
1837
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001838 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001840 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001841 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001842 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1843 return op_ == b->op();
1844 }
1845
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001846 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001847 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848};
1849
1850
1851class HLoadElements: public HUnaryOperation {
1852 public:
1853 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1854 set_representation(Representation::Tagged());
1855 SetFlag(kUseGVN);
1856 SetFlag(kDependsOnMaps);
1857 }
1858
1859 virtual Representation RequiredInputRepresentation(int index) const {
1860 return Representation::Tagged();
1861 }
1862
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001863 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001864
1865 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001866 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867};
1868
1869
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001870class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001871 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001872 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001873 : HUnaryOperation(value) {
1874 set_representation(Representation::External());
1875 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001876 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001877 // change once set, so it's no necessary to introduce any additional
1878 // dependencies on top of the inputs.
1879 SetFlag(kUseGVN);
1880 }
1881
1882 virtual Representation RequiredInputRepresentation(int index) const {
1883 return Representation::Tagged();
1884 }
1885
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001886 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001887
1888 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001889 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001890};
1891
1892
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001893class HCheckMap: public HUnaryOperation {
1894 public:
1895 HCheckMap(HValue* value, Handle<Map> map)
1896 : HUnaryOperation(value), map_(map) {
1897 set_representation(Representation::Tagged());
1898 SetFlag(kUseGVN);
1899 SetFlag(kDependsOnMaps);
1900 }
1901
1902 virtual Representation RequiredInputRepresentation(int index) const {
1903 return Representation::Tagged();
1904 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001905 virtual void PrintDataTo(StringStream* stream);
1906 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001907
1908#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001909 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001910#endif
1911
1912 Handle<Map> map() const { return map_; }
1913
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001914 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001915
1916 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001917 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001918 HCheckMap* b = HCheckMap::cast(other);
1919 return map_.is_identical_to(b->map());
1920 }
1921
1922 private:
1923 Handle<Map> map_;
1924};
1925
1926
1927class HCheckFunction: public HUnaryOperation {
1928 public:
1929 HCheckFunction(HValue* value, Handle<JSFunction> function)
1930 : HUnaryOperation(value), target_(function) {
1931 set_representation(Representation::Tagged());
1932 SetFlag(kUseGVN);
1933 }
1934
1935 virtual Representation RequiredInputRepresentation(int index) const {
1936 return Representation::Tagged();
1937 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001938 virtual void PrintDataTo(StringStream* stream);
1939 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001940
1941#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001942 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001943#endif
1944
1945 Handle<JSFunction> target() const { return target_; }
1946
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001947 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001948
1949 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001950 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001951 HCheckFunction* b = HCheckFunction::cast(other);
1952 return target_.is_identical_to(b->target());
1953 }
1954
1955 private:
1956 Handle<JSFunction> target_;
1957};
1958
1959
1960class HCheckInstanceType: public HUnaryOperation {
1961 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001962 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1963 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001964 }
1965 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1966 return new HCheckInstanceType(value, IS_JS_ARRAY);
1967 }
1968 static HCheckInstanceType* NewIsString(HValue* value) {
1969 return new HCheckInstanceType(value, IS_STRING);
1970 }
1971 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1972 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001973 }
1974
1975 virtual Representation RequiredInputRepresentation(int index) const {
1976 return Representation::Tagged();
1977 }
1978
1979#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001980 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001981#endif
1982
danno@chromium.org160a7b02011-04-18 15:51:38 +00001983 virtual HValue* Canonicalize() {
1984 if (!value()->type().IsUninitialized() &&
1985 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001986 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001987 return NULL;
1988 }
1989 return this;
1990 }
1991
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001992 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1993 void GetCheckInterval(InstanceType* first, InstanceType* last);
1994 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001996 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997
1998 protected:
1999 // TODO(ager): It could be nice to allow the ommision of instance
2000 // type checks if we have already performed an instance type check
2001 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002002 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002003 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002004 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002005 }
2006
2007 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002008 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002009 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002010 IS_JS_ARRAY,
2011 IS_STRING,
2012 IS_SYMBOL,
2013 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2014 };
2015
2016 HCheckInstanceType(HValue* value, Check check)
2017 : HUnaryOperation(value), check_(check) {
2018 set_representation(Representation::Tagged());
2019 SetFlag(kUseGVN);
2020 }
2021
2022 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002023};
2024
2025
2026class HCheckNonSmi: public HUnaryOperation {
2027 public:
2028 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2029 set_representation(Representation::Tagged());
2030 SetFlag(kUseGVN);
2031 }
2032
2033 virtual Representation RequiredInputRepresentation(int index) const {
2034 return Representation::Tagged();
2035 }
2036
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002037 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002038
2039#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002040 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002041#endif
2042
danno@chromium.org160a7b02011-04-18 15:51:38 +00002043 virtual HValue* Canonicalize() {
2044 HType value_type = value()->type();
2045 if (!value_type.IsUninitialized() &&
2046 (value_type.IsHeapNumber() ||
2047 value_type.IsString() ||
2048 value_type.IsBoolean() ||
2049 value_type.IsNonPrimitive())) {
2050 return NULL;
2051 }
2052 return this;
2053 }
2054
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002055 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002056
2057 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002058 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002059};
2060
2061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002062class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002064 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2065 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066 SetFlag(kUseGVN);
2067 SetFlag(kDependsOnMaps);
2068 }
2069
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002070#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002071 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002072#endif
2073
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002074 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002075 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002076
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002077 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002078
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002079 virtual Representation RequiredInputRepresentation(int index) const {
2080 return Representation::None();
2081 }
2082
2083 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002084 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002085 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2086 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2087 return hash;
2088 }
2089
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002091 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002093 return prototype_.is_identical_to(b->prototype()) &&
2094 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095 }
2096
2097 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002098 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100};
2101
2102
2103class HCheckSmi: public HUnaryOperation {
2104 public:
2105 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2106 set_representation(Representation::Tagged());
2107 SetFlag(kUseGVN);
2108 }
2109
2110 virtual Representation RequiredInputRepresentation(int index) const {
2111 return Representation::Tagged();
2112 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002113 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002114
2115#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002116 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117#endif
2118
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002119 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002120
2121 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002122 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123};
2124
2125
2126class HPhi: public HValue {
2127 public:
2128 explicit HPhi(int merged_index)
2129 : inputs_(2),
2130 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002131 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002132 is_live_(false),
2133 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002134 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2135 non_phi_uses_[i] = 0;
2136 indirect_uses_[i] = 0;
2137 }
2138 ASSERT(merged_index >= 0);
2139 set_representation(Representation::Tagged());
2140 SetFlag(kFlexibleRepresentation);
2141 }
2142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002143 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002144 bool double_occurred = false;
2145 bool int32_occurred = false;
2146 for (int i = 0; i < OperandCount(); ++i) {
2147 HValue* value = OperandAt(i);
2148 if (value->representation().IsDouble()) double_occurred = true;
2149 if (value->representation().IsInteger32()) int32_occurred = true;
2150 if (value->representation().IsTagged()) return Representation::Tagged();
2151 }
2152
2153 if (double_occurred) return Representation::Double();
2154 if (int32_occurred) return Representation::Integer32();
2155 return Representation::None();
2156 }
2157
2158 virtual Range* InferRange();
2159 virtual Representation RequiredInputRepresentation(int index) const {
2160 return representation();
2161 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002162 virtual HType CalculateInferredType();
2163 virtual int OperandCount() { return inputs_.length(); }
2164 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2165 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002166 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002167 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002168
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002169 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002170
2171 int merged_index() const { return merged_index_; }
2172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002173 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174
2175#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002176 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002177#endif
2178
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002179 void InitRealUses(int id);
2180 void AddNonPhiUsesFrom(HPhi* other);
2181 void AddIndirectUsesTo(int* use_count);
2182
2183 int tagged_non_phi_uses() const {
2184 return non_phi_uses_[Representation::kTagged];
2185 }
2186 int int32_non_phi_uses() const {
2187 return non_phi_uses_[Representation::kInteger32];
2188 }
2189 int double_non_phi_uses() const {
2190 return non_phi_uses_[Representation::kDouble];
2191 }
2192 int tagged_indirect_uses() const {
2193 return indirect_uses_[Representation::kTagged];
2194 }
2195 int int32_indirect_uses() const {
2196 return indirect_uses_[Representation::kInteger32];
2197 }
2198 int double_indirect_uses() const {
2199 return indirect_uses_[Representation::kDouble];
2200 }
2201 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002202 bool is_live() { return is_live_; }
2203 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002204
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002205 static HPhi* cast(HValue* value) {
2206 ASSERT(value->IsPhi());
2207 return reinterpret_cast<HPhi*>(value);
2208 }
2209 virtual Opcode opcode() const { return HValue::kPhi; }
2210
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002211 virtual bool IsConvertibleToInteger() const {
2212 return is_convertible_to_integer_;
2213 }
2214
2215 void set_is_convertible_to_integer(bool b) {
2216 is_convertible_to_integer_ = b;
2217 }
2218
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002219 protected:
2220 virtual void DeleteFromGraph();
2221 virtual void InternalSetOperandAt(int index, HValue* value) {
2222 inputs_[index] = value;
2223 }
2224
2225 private:
2226 ZoneList<HValue*> inputs_;
2227 int merged_index_;
2228
2229 int non_phi_uses_[Representation::kNumRepresentations];
2230 int indirect_uses_[Representation::kNumRepresentations];
2231 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002232 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002233 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002234};
2235
2236
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002237class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002238 public:
2239 HArgumentsObject() {
2240 set_representation(Representation::Tagged());
2241 SetFlag(kIsArguments);
2242 }
2243
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002244 virtual Representation RequiredInputRepresentation(int index) const {
2245 return Representation::None();
2246 }
2247
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002248 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002249};
2250
2251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002252class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002253 public:
2254 HConstant(Handle<Object> handle, Representation r);
2255
2256 Handle<Object> handle() const { return handle_; }
2257
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002258 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002259
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002260 virtual Representation RequiredInputRepresentation(int index) const {
2261 return Representation::None();
2262 }
2263
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002264 virtual bool IsConvertibleToInteger() const {
2265 if (handle_->IsSmi()) return true;
2266 if (handle_->IsHeapNumber() &&
2267 (HeapNumber::cast(*handle_)->value() ==
2268 static_cast<double>(NumberToInt32(*handle_)))) return true;
2269 return false;
2270 }
2271
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002272 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002273 virtual void PrintDataTo(StringStream* stream);
2274 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002275 bool IsInteger() const { return handle_->IsSmi(); }
2276 HConstant* CopyToRepresentation(Representation r) const;
2277 HConstant* CopyToTruncatedInt32() const;
2278 bool HasInteger32Value() const { return has_int32_value_; }
2279 int32_t Integer32Value() const {
2280 ASSERT(HasInteger32Value());
2281 return int32_value_;
2282 }
2283 bool HasDoubleValue() const { return has_double_value_; }
2284 double DoubleValue() const {
2285 ASSERT(HasDoubleValue());
2286 return double_value_;
2287 }
2288 bool HasStringValue() const { return handle_->IsString(); }
2289
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002290 bool ToBoolean() const;
2291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002292 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002293 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002294 return reinterpret_cast<intptr_t>(*handle());
2295 }
2296
2297#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002298 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002299#endif
2300
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002301 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002302
2303 protected:
2304 virtual Range* InferRange();
2305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002306 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002307 HConstant* other_constant = HConstant::cast(other);
2308 return handle().is_identical_to(other_constant->handle());
2309 }
2310
2311 private:
2312 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002313
2314 // The following two values represent the int32 and the double value of the
2315 // given constant if there is a lossless conversion between the constant
2316 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002317 bool has_int32_value_ : 1;
2318 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002320 double double_value_;
2321};
2322
2323
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002324class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002325 public:
2326 HBinaryOperation(HValue* left, HValue* right) {
2327 ASSERT(left != NULL && right != NULL);
2328 SetOperandAt(0, left);
2329 SetOperandAt(1, right);
2330 }
2331
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002332 HValue* left() { return OperandAt(0); }
2333 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002334
2335 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2336 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002337 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338 if (IsCommutative() && left()->IsConstant()) return right();
2339 return left();
2340 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002341 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002342 if (IsCommutative() && left()->IsConstant()) return left();
2343 return right();
2344 }
2345
2346 virtual bool IsCommutative() const { return false; }
2347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002348 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002349};
2350
2351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002352class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002353 public:
2354 HApplyArguments(HValue* function,
2355 HValue* receiver,
2356 HValue* length,
2357 HValue* elements) {
2358 set_representation(Representation::Tagged());
2359 SetOperandAt(0, function);
2360 SetOperandAt(1, receiver);
2361 SetOperandAt(2, length);
2362 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002363 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002364 }
2365
2366 virtual Representation RequiredInputRepresentation(int index) const {
2367 // The length is untagged, all other inputs are tagged.
2368 return (index == 2)
2369 ? Representation::Integer32()
2370 : Representation::Tagged();
2371 }
2372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 HValue* function() { return OperandAt(0); }
2374 HValue* receiver() { return OperandAt(1); }
2375 HValue* length() { return OperandAt(2); }
2376 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002378 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002379};
2380
2381
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002382class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002383 public:
2384 HArgumentsElements() {
2385 // The value produced by this instruction is a pointer into the stack
2386 // that looks as if it was a smi because of alignment.
2387 set_representation(Representation::Tagged());
2388 SetFlag(kUseGVN);
2389 }
2390
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002391 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002393 virtual Representation RequiredInputRepresentation(int index) const {
2394 return Representation::None();
2395 }
2396
ager@chromium.org378b34e2011-01-28 08:04:38 +00002397 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002398 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002399};
2400
2401
2402class HArgumentsLength: public HUnaryOperation {
2403 public:
2404 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2405 set_representation(Representation::Integer32());
2406 SetFlag(kUseGVN);
2407 }
2408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002409 virtual Representation RequiredInputRepresentation(int index) const {
2410 return Representation::Tagged();
2411 }
2412
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002413 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002414
2415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002417};
2418
2419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002420class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002421 public:
2422 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2423 set_representation(Representation::Tagged());
2424 SetFlag(kUseGVN);
2425 SetOperandAt(0, arguments);
2426 SetOperandAt(1, length);
2427 SetOperandAt(2, index);
2428 }
2429
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002430 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002431
2432 virtual Representation RequiredInputRepresentation(int index) const {
2433 // The arguments elements is considered tagged.
2434 return index == 0
2435 ? Representation::Tagged()
2436 : Representation::Integer32();
2437 }
2438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002439 HValue* arguments() { return OperandAt(0); }
2440 HValue* length() { return OperandAt(1); }
2441 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002442
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002443 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002445 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002446};
2447
2448
2449class HBoundsCheck: public HBinaryOperation {
2450 public:
2451 HBoundsCheck(HValue* index, HValue* length)
2452 : HBinaryOperation(index, length) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002453 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454 SetFlag(kUseGVN);
2455 }
2456
2457 virtual Representation RequiredInputRepresentation(int index) const {
2458 return Representation::Integer32();
2459 }
2460
2461#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002462 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463#endif
2464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002465 HValue* index() { return left(); }
2466 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002467
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002468 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002469
2470 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002471 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002472};
2473
2474
2475class HBitwiseBinaryOperation: public HBinaryOperation {
2476 public:
2477 HBitwiseBinaryOperation(HValue* left, HValue* right)
2478 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002479 set_representation(Representation::Tagged());
2480 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002481 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002482 }
2483
2484 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002485 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486 }
2487
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002488 virtual void RepresentationChanged(Representation to) {
2489 if (!to.IsTagged()) {
2490 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002491 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002492 SetFlag(kTruncatingToInt32);
2493 SetFlag(kUseGVN);
2494 }
2495 }
2496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002497 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002498
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002499 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002500};
2501
2502
2503class HArithmeticBinaryOperation: public HBinaryOperation {
2504 public:
2505 HArithmeticBinaryOperation(HValue* left, HValue* right)
2506 : HBinaryOperation(left, right) {
2507 set_representation(Representation::Tagged());
2508 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002509 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002510 }
2511
2512 virtual void RepresentationChanged(Representation to) {
2513 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002514 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515 SetFlag(kUseGVN);
2516 }
2517 }
2518
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002519 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002520 virtual Representation RequiredInputRepresentation(int index) const {
2521 return representation();
2522 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002523 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002524 if (left()->representation().Equals(right()->representation())) {
2525 return left()->representation();
2526 }
2527 return HValue::InferredRepresentation();
2528 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002529};
2530
2531
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002532class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002533 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002534 HCompareGeneric(HValue* left, HValue* right, Token::Value token)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002535 : HBinaryOperation(left, right), token_(token) {
2536 ASSERT(Token::IsCompareOp(token));
2537 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002538 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002539 }
2540
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002541 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002542 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002543 }
2544 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002545 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002547
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002549 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002550
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002551 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002552
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002553 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2554
2555 private:
2556 Token::Value token_;
2557};
2558
2559
2560class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2561 public:
2562 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2563 : token_(token) {
2564 ASSERT(Token::IsCompareOp(token));
2565 SetOperandAt(0, left);
2566 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002567 }
2568
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002569 HValue* left() { return OperandAt(0); }
2570 HValue* right() { return OperandAt(1); }
2571 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002572
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002573 void SetInputRepresentation(Representation r);
2574 Representation GetInputRepresentation() const {
2575 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002576 }
2577
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002578 virtual Representation RequiredInputRepresentation(int index) const {
2579 return input_representation_;
2580 }
2581 virtual void PrintDataTo(StringStream* stream);
2582
2583 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2584
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585 private:
2586 Representation input_representation_;
2587 Token::Value token_;
2588};
2589
2590
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002591class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002592 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002593 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2594 SetOperandAt(0, left);
2595 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002596 }
2597
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002598 HValue* left() { return OperandAt(0); }
2599 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002600
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 virtual Representation RequiredInputRepresentation(int index) const {
2602 return Representation::Tagged();
2603 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002605 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606};
2607
2608
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002609class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002610 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002611 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2612 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002613 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002614 }
2615
2616 Token::Value op() const { return op_; }
2617 int right() const { return right_; }
2618
whesse@chromium.org7b260152011-06-20 15:33:18 +00002619 virtual Representation RequiredInputRepresentation(int index) const {
2620 return Representation::Integer32();
2621 }
2622
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002623 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002624
2625 private:
2626 const Token::Value op_;
2627 const int right_;
2628};
2629
2630
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002631class HIsNullAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002632 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002633 HIsNullAndBranch(HValue* value, bool is_strict)
2634 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002635
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002636 bool is_strict() const { return is_strict_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002637
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002638 virtual Representation RequiredInputRepresentation(int index) const {
2639 return Representation::Tagged();
2640 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002642 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002643
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002644 private:
2645 bool is_strict_;
2646};
2647
2648
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002649class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002650 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002651 explicit HIsObjectAndBranch(HValue* value)
2652 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002653
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002654 virtual Representation RequiredInputRepresentation(int index) const {
2655 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002656 }
2657
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002658 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2659};
2660
2661
2662class HIsSmiAndBranch: public HUnaryControlInstruction {
2663 public:
2664 explicit HIsSmiAndBranch(HValue* value)
2665 : HUnaryControlInstruction(value, NULL, NULL) { }
2666
2667 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2668
2669 virtual Representation RequiredInputRepresentation(int index) const {
2670 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002671 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002672
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002673 protected:
2674 virtual bool DataEquals(HValue* other) { return true; }
2675};
2676
2677
2678class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2679 public:
2680 explicit HIsUndetectableAndBranch(HValue* value)
2681 : HUnaryControlInstruction(value, NULL, NULL) { }
2682
2683 virtual Representation RequiredInputRepresentation(int index) const {
2684 return Representation::Tagged();
2685 }
2686
2687 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2688};
2689
2690
2691class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2692 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002693 virtual Representation RequiredInputRepresentation(int index) const {
2694 return Representation::None();
2695 }
2696
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002697 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002698};
2699
2700
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002701class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002702 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002703 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2704 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2705 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2706 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2708 }
2709
2710 InstanceType from() { return from_; }
2711 InstanceType to() { return to_; }
2712
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002713 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002714
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002715 virtual Representation RequiredInputRepresentation(int index) const {
2716 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002717 }
2718
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002719 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2720
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721 private:
2722 InstanceType from_;
2723 InstanceType to_; // Inclusive range, not all combinations work.
2724};
2725
2726
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002727class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002728 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002729 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2730 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002731
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002732 virtual Representation RequiredInputRepresentation(int index) const {
2733 return Representation::Tagged();
2734 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002735
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002736 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002737};
2738
2739
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002740class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002741 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002742 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2743 set_representation(Representation::Tagged());
2744 SetFlag(kUseGVN);
2745 }
2746
2747 virtual Representation RequiredInputRepresentation(int index) const {
2748 return Representation::Tagged();
2749 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002750
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002751 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002752
2753 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002754 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002755};
2756
2757
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002758class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002759 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002760 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2761 : HUnaryControlInstruction(value, NULL, NULL),
2762 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002763
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002764 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2765
2766 virtual Representation RequiredInputRepresentation(int index) const {
2767 return Representation::Tagged();
2768 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002770 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002771
2772 Handle<String> class_name() const { return class_name_; }
2773
2774 private:
2775 Handle<String> class_name_;
2776};
2777
2778
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002779class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002780 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002781 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2782 : HUnaryControlInstruction(value, NULL, NULL),
2783 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784
2785 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002786 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002788 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002790 virtual Representation RequiredInputRepresentation(int index) const {
2791 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792 }
2793
2794 private:
2795 Handle<String> type_literal_;
2796};
2797
2798
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002799class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002800 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002801 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2802 SetOperandAt(0, context);
2803 SetOperandAt(1, left);
2804 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002805 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002806 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807 }
2808
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002809 HValue* context() { return OperandAt(0); }
2810 HValue* left() { return OperandAt(1); }
2811 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002812
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813 virtual Representation RequiredInputRepresentation(int index) const {
2814 return Representation::Tagged();
2815 }
2816
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002817 virtual HType CalculateInferredType();
2818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002819 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002820
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002821 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002822};
2823
2824
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002825class HInstanceOfKnownGlobal: public HUnaryOperation {
2826 public:
2827 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2828 : HUnaryOperation(left), function_(right) {
2829 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002830 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002831 }
2832
2833 Handle<JSFunction> function() { return function_; }
2834
2835 virtual Representation RequiredInputRepresentation(int index) const {
2836 return Representation::Tagged();
2837 }
2838
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002839 virtual HType CalculateInferredType();
2840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002841 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002842
2843 private:
2844 Handle<JSFunction> function_;
2845};
2846
2847
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002848class HPower: public HBinaryOperation {
2849 public:
2850 HPower(HValue* left, HValue* right)
2851 : HBinaryOperation(left, right) {
2852 set_representation(Representation::Double());
2853 SetFlag(kUseGVN);
2854 }
2855
2856 virtual Representation RequiredInputRepresentation(int index) const {
2857 return (index == 1) ? Representation::None() : Representation::Double();
2858 }
2859
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002860 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002861
2862 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002863 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002864};
2865
2866
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002867class HAdd: public HArithmeticBinaryOperation {
2868 public:
2869 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2870 SetFlag(kCanOverflow);
2871 }
2872
2873 // Add is only commutative if two integer values are added and not if two
2874 // tagged values are added (because it might be a String concatenation).
2875 virtual bool IsCommutative() const {
2876 return !representation().IsTagged();
2877 }
2878
2879 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2880
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002881 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002882
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002883 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002884
2885 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002886 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002887
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002888 virtual Range* InferRange();
2889};
2890
2891
2892class HSub: public HArithmeticBinaryOperation {
2893 public:
2894 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2895 SetFlag(kCanOverflow);
2896 }
2897
2898 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2899
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002900 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002901
2902 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002903 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002904
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002905 virtual Range* InferRange();
2906};
2907
2908
2909class HMul: public HArithmeticBinaryOperation {
2910 public:
2911 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2912 SetFlag(kCanOverflow);
2913 }
2914
2915 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2916
2917 // Only commutative if it is certain that not two objects are multiplicated.
2918 virtual bool IsCommutative() const {
2919 return !representation().IsTagged();
2920 }
2921
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002922 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923
2924 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002925 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002926
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927 virtual Range* InferRange();
2928};
2929
2930
2931class HMod: public HArithmeticBinaryOperation {
2932 public:
2933 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2934 SetFlag(kCanBeDivByZero);
2935 }
2936
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002937 bool HasPowerOf2Divisor() {
2938 if (right()->IsConstant() &&
2939 HConstant::cast(right())->HasInteger32Value()) {
2940 int32_t value = HConstant::cast(right())->Integer32Value();
2941 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2942 }
2943
2944 return false;
2945 }
2946
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2948
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002949 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950
2951 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002952 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002953
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002954 virtual Range* InferRange();
2955};
2956
2957
2958class HDiv: public HArithmeticBinaryOperation {
2959 public:
2960 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2961 SetFlag(kCanBeDivByZero);
2962 SetFlag(kCanOverflow);
2963 }
2964
2965 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2966
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002967 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002968
2969 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002970 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002971
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002972 virtual Range* InferRange();
2973};
2974
2975
2976class HBitAnd: public HBitwiseBinaryOperation {
2977 public:
2978 HBitAnd(HValue* left, HValue* right)
2979 : HBitwiseBinaryOperation(left, right) { }
2980
2981 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002982 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002984 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002985
2986 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002987 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002988
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989 virtual Range* InferRange();
2990};
2991
2992
2993class HBitXor: public HBitwiseBinaryOperation {
2994 public:
2995 HBitXor(HValue* left, HValue* right)
2996 : HBitwiseBinaryOperation(left, right) { }
2997
2998 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002999 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003001 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003002
3003 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003004 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005};
3006
3007
3008class HBitOr: public HBitwiseBinaryOperation {
3009 public:
3010 HBitOr(HValue* left, HValue* right)
3011 : HBitwiseBinaryOperation(left, right) { }
3012
3013 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003014 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003016 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017
3018 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003019 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003020
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021 virtual Range* InferRange();
3022};
3023
3024
3025class HShl: public HBitwiseBinaryOperation {
3026 public:
3027 HShl(HValue* left, HValue* right)
3028 : HBitwiseBinaryOperation(left, right) { }
3029
3030 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003031 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003033 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003034
3035 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003036 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003037};
3038
3039
3040class HShr: public HBitwiseBinaryOperation {
3041 public:
3042 HShr(HValue* left, HValue* right)
3043 : HBitwiseBinaryOperation(left, right) { }
3044
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003045 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003046
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003047 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003048
3049 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003050 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051};
3052
3053
3054class HSar: public HBitwiseBinaryOperation {
3055 public:
3056 HSar(HValue* left, HValue* right)
3057 : HBitwiseBinaryOperation(left, right) { }
3058
3059 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003060 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003062 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003063
3064 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003065 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066};
3067
3068
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003069class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003070 public:
3071 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3072 SetFlag(kChangesOsrEntries);
3073 }
3074
3075 int ast_id() const { return ast_id_; }
3076
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077 virtual Representation RequiredInputRepresentation(int index) const {
3078 return Representation::None();
3079 }
3080
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003081 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082
3083 private:
3084 int ast_id_;
3085};
3086
3087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003088class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089 public:
3090 explicit HParameter(unsigned index) : index_(index) {
3091 set_representation(Representation::Tagged());
3092 }
3093
3094 unsigned index() const { return index_; }
3095
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003096 virtual void PrintDataTo(StringStream* stream);
3097
3098 virtual Representation RequiredInputRepresentation(int index) const {
3099 return Representation::None();
3100 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003102 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103
3104 private:
3105 unsigned index_;
3106};
3107
3108
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003109class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003111 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3112 : HUnaryCall(context, argument_count),
3113 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115 }
3116
3117 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003119 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120
3121 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3122 transcendental_type_ = transcendental_type;
3123 }
3124 TranscendentalCache::Type transcendental_type() {
3125 return transcendental_type_;
3126 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003127
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003128 virtual void PrintDataTo(StringStream* stream);
3129
3130 virtual Representation RequiredInputRepresentation(int index) const {
3131 return Representation::Tagged();
3132 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003134 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003135
3136 private:
3137 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138 TranscendentalCache::Type transcendental_type_;
3139};
3140
3141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003142class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003143 public:
3144 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3145
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003146 virtual Representation RequiredInputRepresentation(int index) const {
3147 return Representation::None();
3148 }
3149
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003150 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151};
3152
3153
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003154class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003156 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157 : cell_(cell), check_hole_value_(check_hole_value) {
3158 set_representation(Representation::Tagged());
3159 SetFlag(kUseGVN);
3160 SetFlag(kDependsOnGlobalVars);
3161 }
3162
3163 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3164 bool check_hole_value() const { return check_hole_value_; }
3165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003166 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003168 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003169 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 return reinterpret_cast<intptr_t>(*cell_);
3171 }
3172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003173 virtual Representation RequiredInputRepresentation(int index) const {
3174 return Representation::None();
3175 }
3176
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003177 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178
3179 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003180 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003181 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 return cell_.is_identical_to(b->cell());
3183 }
3184
3185 private:
3186 Handle<JSGlobalPropertyCell> cell_;
3187 bool check_hole_value_;
3188};
3189
3190
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003191class HLoadGlobalGeneric: public HBinaryOperation {
3192 public:
3193 HLoadGlobalGeneric(HValue* context,
3194 HValue* global_object,
3195 Handle<Object> name,
3196 bool for_typeof)
3197 : HBinaryOperation(context, global_object),
3198 name_(name),
3199 for_typeof_(for_typeof) {
3200 set_representation(Representation::Tagged());
3201 SetAllSideEffects();
3202 }
3203
3204 HValue* context() { return OperandAt(0); }
3205 HValue* global_object() { return OperandAt(1); }
3206 Handle<Object> name() const { return name_; }
3207 bool for_typeof() const { return for_typeof_; }
3208
3209 virtual void PrintDataTo(StringStream* stream);
3210
3211 virtual Representation RequiredInputRepresentation(int index) const {
3212 return Representation::Tagged();
3213 }
3214
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003215 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003216
3217 private:
3218 Handle<Object> name_;
3219 bool for_typeof_;
3220};
3221
3222
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003223class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003225 HStoreGlobalCell(HValue* value,
3226 Handle<JSGlobalPropertyCell> cell,
3227 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003228 : HUnaryOperation(value),
3229 cell_(cell),
3230 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003231 SetFlag(kChangesGlobalVars);
3232 }
3233
3234 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003235 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003236
3237 virtual Representation RequiredInputRepresentation(int index) const {
3238 return Representation::Tagged();
3239 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003240 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003241
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003242 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003244 private:
3245 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003246 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003247};
3248
3249
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003250class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3251 public:
3252 HStoreGlobalGeneric(HValue* context,
3253 HValue* global_object,
3254 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003255 HValue* value,
3256 bool strict_mode)
3257 : name_(name),
3258 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003259 SetOperandAt(0, context);
3260 SetOperandAt(1, global_object);
3261 SetOperandAt(2, value);
3262 set_representation(Representation::Tagged());
3263 SetAllSideEffects();
3264 }
3265
3266 HValue* context() { return OperandAt(0); }
3267 HValue* global_object() { return OperandAt(1); }
3268 Handle<Object> name() const { return name_; }
3269 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003270 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003271
3272 virtual void PrintDataTo(StringStream* stream);
3273
3274 virtual Representation RequiredInputRepresentation(int index) const {
3275 return Representation::Tagged();
3276 }
3277
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003278 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003279
3280 private:
3281 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003282 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003283};
3284
3285
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003286class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003287 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003288 HLoadContextSlot(HValue* context , int slot_index)
3289 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003290 set_representation(Representation::Tagged());
3291 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003292 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003293 }
3294
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003295 int slot_index() const { return slot_index_; }
3296
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003297 virtual Representation RequiredInputRepresentation(int index) const {
3298 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003299 }
3300
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003301 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003302
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003303 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003304
3305 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003306 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003307 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003308 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003309 }
3310
3311 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003312 int slot_index_;
3313};
3314
3315
3316static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3317 return !value->type().IsSmi() &&
3318 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3319}
3320
3321
3322class HStoreContextSlot: public HBinaryOperation {
3323 public:
3324 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3325 : HBinaryOperation(context, value), slot_index_(slot_index) {
3326 SetFlag(kChangesContextSlots);
3327 }
3328
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003329 HValue* context() { return OperandAt(0); }
3330 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003331 int slot_index() const { return slot_index_; }
3332
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003333 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003334 return StoringValueNeedsWriteBarrier(value());
3335 }
3336
3337 virtual Representation RequiredInputRepresentation(int index) const {
3338 return Representation::Tagged();
3339 }
3340
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003341 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003342
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003343 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003344
3345 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003346 int slot_index_;
3347};
3348
3349
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003350class HLoadNamedField: public HUnaryOperation {
3351 public:
3352 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3353 : HUnaryOperation(object),
3354 is_in_object_(is_in_object),
3355 offset_(offset) {
3356 set_representation(Representation::Tagged());
3357 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003358 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003359 if (is_in_object) {
3360 SetFlag(kDependsOnInobjectFields);
3361 } else {
3362 SetFlag(kDependsOnBackingStoreFields);
3363 }
3364 }
3365
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003366 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003367 bool is_in_object() const { return is_in_object_; }
3368 int offset() const { return offset_; }
3369
3370 virtual Representation RequiredInputRepresentation(int index) const {
3371 return Representation::Tagged();
3372 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003373 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003374
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003375 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003376
3377 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003378 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379 HLoadNamedField* b = HLoadNamedField::cast(other);
3380 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3381 }
3382
3383 private:
3384 bool is_in_object_;
3385 int offset_;
3386};
3387
3388
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003389class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3390 public:
3391 HLoadNamedFieldPolymorphic(HValue* object,
3392 ZoneMapList* types,
3393 Handle<String> name);
3394
3395 HValue* object() { return OperandAt(0); }
3396 ZoneMapList* types() { return &types_; }
3397 Handle<String> name() { return name_; }
3398 bool need_generic() { return need_generic_; }
3399
3400 virtual Representation RequiredInputRepresentation(int index) const {
3401 return Representation::Tagged();
3402 }
3403
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003404 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003405
3406 static const int kMaxLoadPolymorphism = 4;
3407
3408 protected:
3409 virtual bool DataEquals(HValue* value);
3410
3411 private:
3412 ZoneMapList types_;
3413 Handle<String> name_;
3414 bool need_generic_;
3415};
3416
3417
3418
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003419class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003420 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003421 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3422 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003423 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003424 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003425 }
3426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003427 HValue* context() { return OperandAt(0); }
3428 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003429 Handle<Object> name() const { return name_; }
3430
3431 virtual Representation RequiredInputRepresentation(int index) const {
3432 return Representation::Tagged();
3433 }
3434
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003435 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003436
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003437 private:
3438 Handle<Object> name_;
3439};
3440
3441
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003442class HLoadFunctionPrototype: public HUnaryOperation {
3443 public:
3444 explicit HLoadFunctionPrototype(HValue* function)
3445 : HUnaryOperation(function) {
3446 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003447 SetFlag(kUseGVN);
3448 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003449 }
3450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003451 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003452
3453 virtual Representation RequiredInputRepresentation(int index) const {
3454 return Representation::Tagged();
3455 }
3456
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003457 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003458
3459 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003460 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003461};
3462
3463
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003464class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003466 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003467 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003468 SetFlag(kDependsOnArrayElements);
3469 SetFlag(kUseGVN);
3470 }
3471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003472 HValue* object() { return OperandAt(0); }
3473 HValue* key() { return OperandAt(1); }
3474
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003475 virtual Representation RequiredInputRepresentation(int index) const {
3476 // The key is supposed to be Integer32.
3477 return (index == 1) ? Representation::Integer32()
3478 : Representation::Tagged();
3479 }
3480
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003481 virtual void PrintDataTo(StringStream* stream);
3482
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003483 bool RequiresHoleCheck() const;
3484
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003485 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003486
3487 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003488 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003489};
3490
3491
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003492class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003493 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003494 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3495 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003496 JSObject::ElementsKind elements_kind)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003497 : HBinaryOperation(external_elements, key),
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003498 elements_kind_(elements_kind) {
3499 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3500 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003501 set_representation(Representation::Double());
3502 } else {
3503 set_representation(Representation::Integer32());
3504 }
3505 SetFlag(kDependsOnSpecializedArrayElements);
3506 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003507 SetFlag(kDependsOnCalls);
3508 SetFlag(kUseGVN);
3509 }
3510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003511 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003512
3513 virtual Representation RequiredInputRepresentation(int index) const {
3514 // The key is supposed to be Integer32, but the base pointer
3515 // for the element load is a naked pointer.
3516 return (index == 1) ? Representation::Integer32()
3517 : Representation::External();
3518 }
3519
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003520 HValue* external_pointer() { return OperandAt(0); }
3521 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003522 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003523
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003524 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003525
3526 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003527 virtual bool DataEquals(HValue* other) {
3528 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3529 HLoadKeyedSpecializedArrayElement* cast_other =
3530 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003531 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003532 }
3533
3534 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003535 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003536};
3537
3538
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003539class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003540 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003541 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003542 set_representation(Representation::Tagged());
3543 SetOperandAt(0, obj);
3544 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003545 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003546 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003547 }
3548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003549 HValue* object() { return OperandAt(0); }
3550 HValue* key() { return OperandAt(1); }
3551 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003552
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003553 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003554
3555 virtual Representation RequiredInputRepresentation(int index) const {
3556 return Representation::Tagged();
3557 }
3558
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003559 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003560};
3561
3562
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003563class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003564 public:
3565 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003566 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567 HValue* val,
3568 bool in_object,
3569 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003570 : HBinaryOperation(obj, val),
3571 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003572 is_in_object_(in_object),
3573 offset_(offset) {
3574 if (is_in_object_) {
3575 SetFlag(kChangesInobjectFields);
3576 } else {
3577 SetFlag(kChangesBackingStoreFields);
3578 }
3579 }
3580
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003581 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003582
3583 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003584 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003585 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003586 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003588 HValue* object() { return OperandAt(0); }
3589 HValue* value() { return OperandAt(1); }
3590
3591 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592 bool is_in_object() const { return is_in_object_; }
3593 int offset() const { return offset_; }
3594 Handle<Map> transition() const { return transition_; }
3595 void set_transition(Handle<Map> map) { transition_ = map; }
3596
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003597 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003598 return StoringValueNeedsWriteBarrier(value());
3599 }
3600
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003601 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003602 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603 bool is_in_object_;
3604 int offset_;
3605 Handle<Map> transition_;
3606};
3607
3608
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003609class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003610 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003611 HStoreNamedGeneric(HValue* context,
3612 HValue* object,
3613 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003614 HValue* value,
3615 bool strict_mode)
3616 : name_(name),
3617 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003618 SetOperandAt(0, object);
3619 SetOperandAt(1, value);
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* value() { return OperandAt(1); }
3626 HValue* context() { return OperandAt(2); }
3627 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003628 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003629
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003630 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003631
3632 virtual Representation RequiredInputRepresentation(int index) const {
3633 return Representation::Tagged();
3634 }
3635
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003636 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003637
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003638 private:
3639 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003640 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641};
3642
3643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003644class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003645 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003646 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3647 SetOperandAt(0, obj);
3648 SetOperandAt(1, key);
3649 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003650 SetFlag(kChangesArrayElements);
3651 }
3652
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653 virtual Representation RequiredInputRepresentation(int index) const {
3654 // The key is supposed to be Integer32.
3655 return (index == 1) ? Representation::Integer32()
3656 : Representation::Tagged();
3657 }
3658
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003659 HValue* object() { return OperandAt(0); }
3660 HValue* key() { return OperandAt(1); }
3661 HValue* value() { return OperandAt(2); }
3662
3663 bool NeedsWriteBarrier() {
3664 return StoringValueNeedsWriteBarrier(value());
3665 }
3666
3667 virtual void PrintDataTo(StringStream* stream);
3668
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003669 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670};
3671
3672
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003673class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003674 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003675 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3676 HValue* key,
3677 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003678 JSObject::ElementsKind elements_kind)
3679 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003680 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003681 SetOperandAt(0, external_elements);
3682 SetOperandAt(1, key);
3683 SetOperandAt(2, val);
3684 }
3685
3686 virtual void PrintDataTo(StringStream* stream);
3687
3688 virtual Representation RequiredInputRepresentation(int index) const {
3689 if (index == 0) {
3690 return Representation::External();
3691 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003692 bool float_or_double_elements =
3693 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3694 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3695 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003696 return Representation::Double();
3697 } else {
3698 return Representation::Integer32();
3699 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003700 }
3701 }
3702
3703 HValue* external_pointer() { return OperandAt(0); }
3704 HValue* key() { return OperandAt(1); }
3705 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003706 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003707
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003708 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3709
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003710 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003711 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003712};
3713
3714
3715class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003716 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003717 HStoreKeyedGeneric(HValue* context,
3718 HValue* object,
3719 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003720 HValue* value,
3721 bool strict_mode)
3722 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003723 SetOperandAt(0, object);
3724 SetOperandAt(1, key);
3725 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003726 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003727 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003728 }
3729
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003730 HValue* object() { return OperandAt(0); }
3731 HValue* key() { return OperandAt(1); }
3732 HValue* value() { return OperandAt(2); }
3733 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003734 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003735
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003736 virtual Representation RequiredInputRepresentation(int index) const {
3737 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003738 }
3739
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003740 virtual void PrintDataTo(StringStream* stream);
3741
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003742 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003743
3744 private:
3745 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003746};
3747
3748
danno@chromium.org160a7b02011-04-18 15:51:38 +00003749class HStringAdd: public HBinaryOperation {
3750 public:
3751 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3752 set_representation(Representation::Tagged());
3753 SetFlag(kUseGVN);
3754 SetFlag(kDependsOnMaps);
3755 }
3756
3757 virtual Representation RequiredInputRepresentation(int index) const {
3758 return Representation::Tagged();
3759 }
3760
3761 virtual HType CalculateInferredType() {
3762 return HType::String();
3763 }
3764
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003765 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003766
3767 protected:
3768 virtual bool DataEquals(HValue* other) { return true; }
3769};
3770
3771
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003772class HStringCharCodeAt: public HBinaryOperation {
3773 public:
3774 HStringCharCodeAt(HValue* string, HValue* index)
3775 : HBinaryOperation(string, index) {
3776 set_representation(Representation::Integer32());
3777 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003778 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003779 }
3780
3781 virtual Representation RequiredInputRepresentation(int index) const {
3782 // The index is supposed to be Integer32.
3783 return (index == 1) ? Representation::Integer32()
3784 : Representation::Tagged();
3785 }
3786
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003787 HValue* string() { return OperandAt(0); }
3788 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003789
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003790 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003791
3792 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003793 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003794
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003795 virtual Range* InferRange() {
3796 return new Range(0, String::kMaxUC16CharCode);
3797 }
3798};
3799
3800
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003801class HStringCharFromCode: public HUnaryOperation {
3802 public:
3803 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3804 set_representation(Representation::Tagged());
3805 SetFlag(kUseGVN);
3806 }
3807
3808 virtual Representation RequiredInputRepresentation(int index) const {
3809 return Representation::Integer32();
3810 }
3811
3812 virtual bool DataEquals(HValue* other) { return true; }
3813
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003814 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003815};
3816
3817
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003818class HStringLength: public HUnaryOperation {
3819 public:
3820 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3821 set_representation(Representation::Tagged());
3822 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003823 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003824 }
3825
3826 virtual Representation RequiredInputRepresentation(int index) const {
3827 return Representation::Tagged();
3828 }
3829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003830 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003831 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3832 return HType::Smi();
3833 }
3834
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003835 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003836
3837 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003838 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003839
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003840 virtual Range* InferRange() {
3841 return new Range(0, String::kMaxLength);
3842 }
3843};
3844
3845
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003846template <int V>
3847class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003848 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003849 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003850 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003851 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003852 }
3853
3854 int literal_index() const { return literal_index_; }
3855 int depth() const { return depth_; }
3856
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003857 private:
3858 int literal_index_;
3859 int depth_;
3860};
3861
3862
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003863class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003864 public:
3865 HArrayLiteral(Handle<FixedArray> constant_elements,
3866 int length,
3867 int literal_index,
3868 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003869 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003870 length_(length),
3871 constant_elements_(constant_elements) {}
3872
3873 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3874 int length() const { return length_; }
3875
3876 bool IsCopyOnWrite() const;
3877
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003878 virtual Representation RequiredInputRepresentation(int index) const {
3879 return Representation::None();
3880 }
3881
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003882 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003883
3884 private:
3885 int length_;
3886 Handle<FixedArray> constant_elements_;
3887};
3888
3889
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003890class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003891 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003892 HObjectLiteral(HValue* context,
3893 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003894 bool fast_elements,
3895 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003896 int depth,
3897 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003898 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003899 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003900 fast_elements_(fast_elements),
3901 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003902 SetOperandAt(0, context);
3903 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003904
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003905 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003906 Handle<FixedArray> constant_properties() const {
3907 return constant_properties_;
3908 }
3909 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003910 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003911
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003912 virtual Representation RequiredInputRepresentation(int index) const {
3913 return Representation::Tagged();
3914 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003915
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003916 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003917
3918 private:
3919 Handle<FixedArray> constant_properties_;
3920 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003921 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003922};
3923
3924
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003925class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003926 public:
3927 HRegExpLiteral(Handle<String> pattern,
3928 Handle<String> flags,
3929 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003930 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003931 pattern_(pattern),
3932 flags_(flags) { }
3933
3934 Handle<String> pattern() { return pattern_; }
3935 Handle<String> flags() { return flags_; }
3936
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003937 virtual Representation RequiredInputRepresentation(int index) const {
3938 return Representation::None();
3939 }
3940
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003941 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003942
3943 private:
3944 Handle<String> pattern_;
3945 Handle<String> flags_;
3946};
3947
3948
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003949class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003950 public:
3951 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3952 : shared_info_(shared), pretenure_(pretenure) {
3953 set_representation(Representation::Tagged());
3954 }
3955
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003956 virtual Representation RequiredInputRepresentation(int index) const {
3957 return Representation::None();
3958 }
3959
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003960 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003961
3962 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3963 bool pretenure() const { return pretenure_; }
3964
3965 private:
3966 Handle<SharedFunctionInfo> shared_info_;
3967 bool pretenure_;
3968};
3969
3970
3971class HTypeof: public HUnaryOperation {
3972 public:
3973 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3974 set_representation(Representation::Tagged());
3975 }
3976
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003977 virtual Representation RequiredInputRepresentation(int index) const {
3978 return Representation::Tagged();
3979 }
3980
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003981 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003982};
3983
3984
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003985class HToFastProperties: public HUnaryOperation {
3986 public:
3987 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3988 // This instruction is not marked as having side effects, but
3989 // changes the map of the input operand. Use it only when creating
3990 // object literals.
3991 ASSERT(value->IsObjectLiteral());
3992 set_representation(Representation::Tagged());
3993 }
3994
3995 virtual Representation RequiredInputRepresentation(int index) const {
3996 return Representation::Tagged();
3997 }
3998
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003999 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004000};
4001
4002
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004003class HValueOf: public HUnaryOperation {
4004 public:
4005 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4006 set_representation(Representation::Tagged());
4007 }
4008
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004009 virtual Representation RequiredInputRepresentation(int index) const {
4010 return Representation::Tagged();
4011 }
4012
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004013 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004014};
4015
4016
4017class HDeleteProperty: public HBinaryOperation {
4018 public:
4019 HDeleteProperty(HValue* obj, HValue* key)
4020 : HBinaryOperation(obj, key) {
4021 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004022 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004023 }
4024
4025 virtual Representation RequiredInputRepresentation(int index) const {
4026 return Representation::Tagged();
4027 }
4028
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004029 virtual HType CalculateInferredType();
4030
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004031 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004033 HValue* object() { return left(); }
4034 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004035};
4036
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004037
4038class HIn: public HTemplateInstruction<2> {
4039 public:
4040 HIn(HValue* key, HValue* object) {
4041 SetOperandAt(0, key);
4042 SetOperandAt(1, object);
4043 set_representation(Representation::Tagged());
4044 SetAllSideEffects();
4045 }
4046
4047 HValue* key() { return OperandAt(0); }
4048 HValue* object() { return OperandAt(1); }
4049
4050 virtual Representation RequiredInputRepresentation(int index) const {
4051 return Representation::Tagged();
4052 }
4053
4054 virtual HType CalculateInferredType() {
4055 return HType::Boolean();
4056 }
4057
4058 virtual void PrintDataTo(StringStream* stream);
4059
4060 DECLARE_CONCRETE_INSTRUCTION(In)
4061};
4062
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004063#undef DECLARE_INSTRUCTION
4064#undef DECLARE_CONCRETE_INSTRUCTION
4065
4066} } // namespace v8::internal
4067
4068#endif // V8_HYDROGEN_INSTRUCTIONS_H_