blob: f2ca730b404d6c62585b7de1905cec0d4e4a79e5 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000038#include "utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000039#include "zone.h"
40
41namespace v8 {
42namespace internal {
43
44// Forward declarations.
45class HBasicBlock;
46class HEnvironment;
47class HInstruction;
48class HLoopInformation;
49class HValue;
50class LInstruction;
51class LChunkBuilder;
52
53
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000054#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(ControlInstruction) \
57 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058
59
60#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000061 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000062 V(AccessArgumentsAt) \
63 V(Add) \
64 V(ApplyArguments) \
65 V(ArgumentsElements) \
66 V(ArgumentsLength) \
67 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000068 V(ArrayLiteral) \
69 V(BitAnd) \
70 V(BitNot) \
71 V(BitOr) \
72 V(BitXor) \
73 V(BlockEntry) \
74 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000075 V(CallConstantFunction) \
76 V(CallFunction) \
77 V(CallGlobal) \
78 V(CallKeyed) \
79 V(CallKnownGlobal) \
80 V(CallNamed) \
81 V(CallNew) \
82 V(CallRuntime) \
83 V(CallStub) \
84 V(Change) \
85 V(CheckFunction) \
86 V(CheckInstanceType) \
87 V(CheckMap) \
88 V(CheckNonSmi) \
89 V(CheckPrototypeMaps) \
90 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000091 V(ClampToUint8) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000092 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000093 V(Compare) \
94 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000095 V(CompareMap) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +000096 V(CompareSymbolEq) \
whesse@chromium.org7b260152011-06-20 15:33:18 +000097 V(CompareConstantEq) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000099 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(DeleteProperty) \
101 V(Deoptimize) \
102 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000103 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000104 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000105 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000106 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000107 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000109 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(GlobalObject) \
111 V(GlobalReceiver) \
112 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000113 V(HasCachedArrayIndex) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000114 V(HasInstanceType) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000115 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000117 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000118 V(InvokeFunction) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000119 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000121 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(IsSmi) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000123 V(IsUndetectable) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000124 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000126 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000127 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000128 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000129 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000130 V(LoadGlobalCell) \
131 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132 V(LoadKeyedFastElement) \
133 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000134 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000136 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadNamedGeneric) \
138 V(Mod) \
139 V(Mul) \
140 V(ObjectLiteral) \
141 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000142 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000144 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000145 V(PushArgument) \
146 V(RegExpLiteral) \
147 V(Return) \
148 V(Sar) \
149 V(Shl) \
150 V(Shr) \
151 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000152 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000154 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000155 V(StoreGlobalCell) \
156 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157 V(StoreKeyedFastElement) \
158 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000159 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(StoreNamedField) \
161 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000162 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000163 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000164 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000165 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000166 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000167 V(Test) \
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) \
173 V(TypeofIs) \
174 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;
785
786 virtual void PrintDataTo(StringStream* stream);
787
788 HBasicBlock* FirstSuccessor() {
789 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
790 }
791 HBasicBlock* SecondSuccessor() {
792 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
793 }
794
795 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
796};
797
798
799class HSuccessorIterator BASE_EMBEDDED {
800 public:
801 explicit HSuccessorIterator(HControlInstruction* instr)
802 : instr_(instr), current_(0) { }
803
804 bool Done() { return current_ >= instr_->SuccessorCount(); }
805 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
806 void Advance() { current_++; }
807
808 private:
809 HControlInstruction* instr_;
810 int current_;
811};
812
813
814template<int S, int V>
815class HTemplateControlInstruction: public HControlInstruction {
816 public:
817 int SuccessorCount() { return S; }
818 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
819
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000820 int OperandCount() { return V; }
821 HValue* OperandAt(int i) { return inputs_[i]; }
822
823 protected:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000824 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000825 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
826
827 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000828 EmbeddedContainer<HBasicBlock*, S> successors_;
829 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000830};
831
832
833class HBlockEntry: public HTemplateInstruction<0> {
834 public:
835 virtual Representation RequiredInputRepresentation(int index) const {
836 return Representation::None();
837 }
838
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000839 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000840};
841
842
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000843// We insert soft-deoptimize when we hit code with unknown typefeedback,
844// so that we get a chance of re-optimizing with useful typefeedback.
845// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
846class HSoftDeoptimize: public HTemplateInstruction<0> {
847 public:
848 virtual Representation RequiredInputRepresentation(int index) const {
849 return Representation::None();
850 }
851
852 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
853};
854
855
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000856class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000857 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000858 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000859
860 virtual Representation RequiredInputRepresentation(int index) const {
861 return Representation::None();
862 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000863
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000864 virtual int OperandCount() { return values_.length(); }
865 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000866 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000867
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000868 virtual int SuccessorCount() { return 0; }
869 virtual HBasicBlock* SuccessorAt(int i) {
870 UNREACHABLE();
871 return NULL;
872 }
873
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000874 void AddEnvironmentValue(HValue* value) {
875 values_.Add(NULL);
876 SetOperandAt(values_.length() - 1, value);
877 }
878
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000879 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000880
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000881 enum UseEnvironment {
882 kNoUses,
883 kUseAll
884 };
885
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886 protected:
887 virtual void InternalSetOperandAt(int index, HValue* value) {
888 values_[index] = value;
889 }
890
891 private:
892 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000893};
894
895
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000896class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000897 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000898 explicit HGoto(HBasicBlock* target)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000899 : include_stack_check_(false) {
900 SetSuccessorAt(0, target);
901 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000902
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 void set_include_stack_check(bool include_stack_check) {
904 include_stack_check_ = include_stack_check;
905 }
906 bool include_stack_check() const { return include_stack_check_; }
907
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000908 virtual Representation RequiredInputRepresentation(int index) const {
909 return Representation::None();
910 }
911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000912 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913
914 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915 bool include_stack_check_;
916};
917
918
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000919class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000920 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000921 HUnaryControlInstruction(HValue* value,
922 HBasicBlock* true_target,
923 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000924 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000925 SetSuccessorAt(0, true_target);
926 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927 }
928
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000929 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000931 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932};
933
934
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000935class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000937 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
938 : HUnaryControlInstruction(value, true_target, false_target) {
939 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000940 }
941
942 virtual Representation RequiredInputRepresentation(int index) const {
943 return Representation::None();
944 }
945
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000946 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947};
948
949
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000950class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000951 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000952 HCompareMap(HValue* value,
953 Handle<Map> map,
954 HBasicBlock* true_target,
955 HBasicBlock* false_target)
956 : HUnaryControlInstruction(value, true_target, false_target),
957 map_(map) {
958 ASSERT(true_target != NULL);
959 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960 ASSERT(!map.is_null());
961 }
962
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000963 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000964
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965 Handle<Map> map() const { return map_; }
966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000967 virtual Representation RequiredInputRepresentation(int index) const {
968 return Representation::Tagged();
969 }
970
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000971 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000972
973 private:
974 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000975};
976
977
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000978class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000980 explicit HReturn(HValue* value) {
981 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000982 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000984 virtual Representation RequiredInputRepresentation(int index) const {
985 return Representation::Tagged();
986 }
987
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000988 virtual void PrintDataTo(StringStream* stream);
989
990 HValue* value() { return OperandAt(0); }
991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000992 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000993};
994
995
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000996class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000998 virtual Representation RequiredInputRepresentation(int index) const {
999 return Representation::None();
1000 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001001
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001002 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001003};
1004
1005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001006class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001007 public:
1008 explicit HUnaryOperation(HValue* value) {
1009 SetOperandAt(0, value);
1010 }
1011
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001012 static HUnaryOperation* cast(HValue* value) {
1013 return reinterpret_cast<HUnaryOperation*>(value);
1014 }
1015
1016 virtual bool CanTruncateToInt32() const {
1017 return CheckFlag(kTruncatingToInt32);
1018 }
1019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001020 HValue* value() { return OperandAt(0); }
1021 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022};
1023
1024
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001025class HThrow: public HUnaryOperation {
1026 public:
1027 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1028 SetAllSideEffects();
1029 }
1030
1031 virtual Representation RequiredInputRepresentation(int index) const {
1032 return Representation::Tagged();
1033 }
1034
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001035 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001036};
1037
1038
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001039class HUseConst: public HUnaryOperation {
1040 public:
1041 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1042
1043 virtual Representation RequiredInputRepresentation(int index) const {
1044 return Representation::None();
1045 }
1046
1047 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1048};
1049
1050
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001051class HForceRepresentation: public HTemplateInstruction<1> {
1052 public:
1053 HForceRepresentation(HValue* value, Representation required_representation) {
1054 SetOperandAt(0, value);
1055 set_representation(required_representation);
1056 }
1057
1058 HValue* value() { return OperandAt(0); }
1059
1060 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1061
1062 virtual Representation RequiredInputRepresentation(int index) const {
1063 return representation(); // Same as the output representation.
1064 }
1065
1066 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1067};
1068
1069
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001070class HChange: public HUnaryOperation {
1071 public:
1072 HChange(HValue* value,
1073 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001074 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001075 bool is_truncating,
1076 bool deoptimize_on_undefined)
1077 : HUnaryOperation(value),
1078 from_(from),
1079 deoptimize_on_undefined_(deoptimize_on_undefined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001080 ASSERT(!from.IsNone() && !to.IsNone());
1081 ASSERT(!from.Equals(to));
1082 set_representation(to);
1083 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001084 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1086 value->range()->IsInSmiRange()) {
1087 set_type(HType::Smi());
1088 }
1089 }
1090
1091 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1092
1093 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001094 Representation to() const { return representation(); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001095 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001096 virtual Representation RequiredInputRepresentation(int index) const {
1097 return from_;
1098 }
1099
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001100 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001101
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001102 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001103
1104 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001105 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001106 if (!other->IsChange()) return false;
1107 HChange* change = HChange::cast(other);
1108 return value() == change->value()
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001109 && to().Equals(change->to())
1110 && deoptimize_on_undefined() == change->deoptimize_on_undefined();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001111 }
1112
1113 private:
1114 Representation from_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001115 bool deoptimize_on_undefined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001116};
1117
1118
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001119class HClampToUint8: public HUnaryOperation {
1120 public:
1121 explicit HClampToUint8(HValue* value)
1122 : HUnaryOperation(value),
1123 input_rep_(Representation::None()) {
1124 SetFlag(kFlexibleRepresentation);
1125 set_representation(Representation::Tagged());
1126 SetFlag(kUseGVN);
1127 }
1128
1129 virtual Representation RequiredInputRepresentation(int index) const {
1130 return input_rep_;
1131 }
1132
1133 virtual Representation InferredRepresentation() {
1134 // TODO(danno): Inference on input types should happen separately from
1135 // return representation.
1136 Representation new_rep = value()->representation();
1137 if (input_rep_.IsNone()) {
1138 if (!new_rep.IsNone()) {
1139 input_rep_ = new_rep;
1140 return Representation::Integer32();
1141 } else {
1142 return Representation::None();
1143 }
1144 } else {
1145 return Representation::Integer32();
1146 }
1147 }
1148
1149 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1150
1151 protected:
1152 virtual bool DataEquals(HValue* other) { return true; }
1153
1154 private:
1155 Representation input_rep_;
1156};
1157
1158
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001159class HToInt32: public HUnaryOperation {
1160 public:
1161 explicit HToInt32(HValue* value)
1162 : HUnaryOperation(value) {
1163 set_representation(Representation::Integer32());
1164 SetFlag(kUseGVN);
1165 }
1166
1167 virtual Representation RequiredInputRepresentation(int index) const {
1168 return Representation::None();
1169 }
1170
1171 virtual bool CanTruncateToInt32() const {
1172 return true;
1173 }
1174
1175 virtual HValue* Canonicalize() {
1176 if (value()->representation().IsInteger32()) {
1177 return value();
1178 } else {
1179 return this;
1180 }
1181 }
1182
1183 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1184
1185 protected:
1186 virtual bool DataEquals(HValue* other) { return true; }
1187};
1188
1189
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190class HSimulate: public HInstruction {
1191 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001192 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193 : ast_id_(ast_id),
1194 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001195 values_(2),
1196 assigned_indexes_(2) {}
1197 virtual ~HSimulate() {}
1198
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001199 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001200
1201 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1202 int ast_id() const { return ast_id_; }
1203 void set_ast_id(int id) {
1204 ASSERT(!HasAstId());
1205 ast_id_ = id;
1206 }
1207
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001208 int pop_count() const { return pop_count_; }
1209 const ZoneList<HValue*>* values() const { return &values_; }
1210 int GetAssignedIndexAt(int index) const {
1211 ASSERT(HasAssignedIndexAt(index));
1212 return assigned_indexes_[index];
1213 }
1214 bool HasAssignedIndexAt(int index) const {
1215 return assigned_indexes_[index] != kNoIndex;
1216 }
1217 void AddAssignedValue(int index, HValue* value) {
1218 AddValue(index, value);
1219 }
1220 void AddPushedValue(HValue* value) {
1221 AddValue(kNoIndex, value);
1222 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001223 virtual int OperandCount() { return values_.length(); }
1224 virtual HValue* OperandAt(int index) { return values_[index]; }
1225
1226 virtual Representation RequiredInputRepresentation(int index) const {
1227 return Representation::None();
1228 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001229
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001230 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001231
1232#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001233 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001234#endif
1235
1236 protected:
1237 virtual void InternalSetOperandAt(int index, HValue* value) {
1238 values_[index] = value;
1239 }
1240
1241 private:
1242 static const int kNoIndex = -1;
1243 void AddValue(int index, HValue* value) {
1244 assigned_indexes_.Add(index);
1245 // Resize the list of pushed values.
1246 values_.Add(NULL);
1247 // Set the operand through the base method in HValue to make sure that the
1248 // use lists are correctly updated.
1249 SetOperandAt(values_.length() - 1, value);
1250 }
1251 int ast_id_;
1252 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253 ZoneList<HValue*> values_;
1254 ZoneList<int> assigned_indexes_;
1255};
1256
1257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001258class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001259 public:
1260 HStackCheck() { }
1261
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001262 virtual Representation RequiredInputRepresentation(int index) const {
1263 return Representation::None();
1264 }
1265
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001266 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001267};
1268
1269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001270class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001271 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001272 HEnterInlined(Handle<JSFunction> closure,
1273 FunctionLiteral* function,
1274 CallKind call_kind)
1275 : closure_(closure),
1276 function_(function),
1277 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001278 }
1279
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001280 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001281
1282 Handle<JSFunction> closure() const { return closure_; }
1283 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001284 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001286 virtual Representation RequiredInputRepresentation(int index) const {
1287 return Representation::None();
1288 }
1289
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001290 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001291
1292 private:
1293 Handle<JSFunction> closure_;
1294 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001295 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001296};
1297
1298
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001299class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001300 public:
1301 HLeaveInlined() {}
1302
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001303 virtual Representation RequiredInputRepresentation(int index) const {
1304 return Representation::None();
1305 }
1306
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001307 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308};
1309
1310
1311class HPushArgument: public HUnaryOperation {
1312 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001313 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1314 set_representation(Representation::Tagged());
1315 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001316
1317 virtual Representation RequiredInputRepresentation(int index) const {
1318 return Representation::Tagged();
1319 }
1320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001322
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001323 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001324};
1325
1326
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001327class HThisFunction: public HTemplateInstruction<0> {
1328 public:
1329 HThisFunction() {
1330 set_representation(Representation::Tagged());
1331 SetFlag(kUseGVN);
1332 }
1333
1334 virtual Representation RequiredInputRepresentation(int index) const {
1335 return Representation::None();
1336 }
1337
1338 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1339
1340 protected:
1341 virtual bool DataEquals(HValue* other) { return true; }
1342};
1343
1344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001345class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001347 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001348 set_representation(Representation::Tagged());
1349 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001350 }
1351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001352 virtual Representation RequiredInputRepresentation(int index) const {
1353 return Representation::None();
1354 }
1355
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001356 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001357
1358 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001359 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001360};
1361
1362
1363class HOuterContext: public HUnaryOperation {
1364 public:
1365 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1366 set_representation(Representation::Tagged());
1367 SetFlag(kUseGVN);
1368 }
1369
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001370 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372 virtual Representation RequiredInputRepresentation(int index) const {
1373 return Representation::Tagged();
1374 }
1375
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001376 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 HGlobalObject: public HUnaryOperation {
1382 public:
1383 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1384 set_representation(Representation::Tagged());
1385 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001386 }
1387
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001388 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390 virtual Representation RequiredInputRepresentation(int index) const {
1391 return Representation::Tagged();
1392 }
1393
ager@chromium.org378b34e2011-01-28 08:04:38 +00001394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001395 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001396};
1397
1398
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001399class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001400 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001401 explicit HGlobalReceiver(HValue* global_object)
1402 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403 set_representation(Representation::Tagged());
1404 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405 }
1406
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001407 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001409 virtual Representation RequiredInputRepresentation(int index) const {
1410 return Representation::Tagged();
1411 }
1412
ager@chromium.org378b34e2011-01-28 08:04:38 +00001413 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001414 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415};
1416
1417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001418template <int V>
1419class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001420 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001421 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001422 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1423 this->set_representation(Representation::Tagged());
1424 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001425 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001427 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001428
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001429 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001431 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001433 private:
1434 int argument_count_;
1435};
1436
1437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001438class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001439 public:
1440 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001441 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001442 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001443 }
1444
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445 virtual Representation RequiredInputRepresentation(int index) const {
1446 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001447 }
1448
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001449 virtual void PrintDataTo(StringStream* stream);
1450
1451 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001452};
1453
1454
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001455class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001456 public:
1457 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001458 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001459 SetOperandAt(0, first);
1460 SetOperandAt(1, second);
1461 }
1462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001463 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465 virtual Representation RequiredInputRepresentation(int index) const {
1466 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001467 }
1468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001469 HValue* first() { return OperandAt(0); }
1470 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001471};
1472
1473
danno@chromium.org160a7b02011-04-18 15:51:38 +00001474class HInvokeFunction: public HBinaryCall {
1475 public:
1476 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1477 : HBinaryCall(context, function, argument_count) {
1478 }
1479
1480 virtual Representation RequiredInputRepresentation(int index) const {
1481 return Representation::Tagged();
1482 }
1483
1484 HValue* context() { return first(); }
1485 HValue* function() { return second(); }
1486
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001487 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001488};
1489
1490
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001491class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492 public:
1493 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001494 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001495
1496 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001497
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001499 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001500 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001501 }
1502
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001503 virtual void PrintDataTo(StringStream* stream);
1504
1505 virtual Representation RequiredInputRepresentation(int index) const {
1506 return Representation::None();
1507 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001508
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001509 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001510
1511 private:
1512 Handle<JSFunction> function_;
1513};
1514
1515
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001516class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001517 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001518 HCallKeyed(HValue* context, HValue* key, int argument_count)
1519 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001520 }
1521
1522 virtual Representation RequiredInputRepresentation(int index) const {
1523 return Representation::Tagged();
1524 }
1525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001526 HValue* context() { return first(); }
1527 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001529 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001530};
1531
1532
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001533class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001535 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1536 : HUnaryCall(context, argument_count), name_(name) {
1537 }
1538
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001539 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001540
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001541 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001542 Handle<String> name() const { return name_; }
1543
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001544 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001545
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001546 virtual Representation RequiredInputRepresentation(int index) const {
1547 return Representation::Tagged();
1548 }
1549
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001550 private:
1551 Handle<String> name_;
1552};
1553
1554
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001555class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001556 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001557 HCallFunction(HValue* context, int argument_count)
1558 : HUnaryCall(context, argument_count) {
1559 }
1560
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001561 HValue* context() { return value(); }
1562
1563 virtual Representation RequiredInputRepresentation(int index) const {
1564 return Representation::Tagged();
1565 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001567 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001568};
1569
1570
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001571class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001573 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1574 : HUnaryCall(context, argument_count), name_(name) {
1575 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001577 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001579 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001580 Handle<String> name() const { return name_; }
1581
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001582 virtual Representation RequiredInputRepresentation(int index) const {
1583 return Representation::Tagged();
1584 }
1585
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001586 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587
1588 private:
1589 Handle<String> name_;
1590};
1591
1592
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001593class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001594 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001595 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001596 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001598 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001599
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001600 Handle<JSFunction> target() const { return target_; }
1601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 virtual Representation RequiredInputRepresentation(int index) const {
1603 return Representation::None();
1604 }
1605
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001606 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607
1608 private:
1609 Handle<JSFunction> target_;
1610};
1611
1612
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001613class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001615 HCallNew(HValue* context, HValue* constructor, int argument_count)
1616 : HBinaryCall(context, constructor, argument_count) {
1617 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618
1619 virtual Representation RequiredInputRepresentation(int index) const {
1620 return Representation::Tagged();
1621 }
1622
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 HValue* context() { return first(); }
1624 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001626 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001627};
1628
1629
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001630class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001631 public:
1632 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001633 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001634 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001635 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1636 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001637
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001638 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639 Handle<String> name() const { return name_; }
1640
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001641 virtual Representation RequiredInputRepresentation(int index) const {
1642 return Representation::None();
1643 }
1644
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001645 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646
1647 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001648 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001649 Handle<String> name_;
1650};
1651
1652
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001653class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001655 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001656 // The length of an array is stored as a tagged value in the array
1657 // object. It is guaranteed to be 32 bit integer, but it can be
1658 // represented as either a smi or heap number.
1659 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001661 SetFlag(kDependsOnArrayLengths);
1662 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663 }
1664
1665 virtual Representation RequiredInputRepresentation(int index) const {
1666 return Representation::Tagged();
1667 }
1668
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001669 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001670
1671 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001672 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001673};
1674
1675
1676class HFixedArrayLength: public HUnaryOperation {
1677 public:
1678 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1679 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001680 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001681 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001682 }
1683
1684 virtual Representation RequiredInputRepresentation(int index) const {
1685 return Representation::Tagged();
1686 }
1687
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001688 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001689
1690 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001691 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001692};
1693
1694
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001695class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001696 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001697 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001698 set_representation(Representation::Integer32());
1699 // The result of this instruction is idempotent as long as its inputs don't
1700 // change. The length of a pixel array cannot change once set, so it's not
1701 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1702 SetFlag(kUseGVN);
1703 }
1704
1705 virtual Representation RequiredInputRepresentation(int index) const {
1706 return Representation::Tagged();
1707 }
1708
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001709 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001710
1711 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001712 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001713};
1714
1715
whesse@chromium.org7b260152011-06-20 15:33:18 +00001716class HElementsKind: public HUnaryOperation {
1717 public:
1718 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1719 set_representation(Representation::Integer32());
1720 SetFlag(kUseGVN);
1721 SetFlag(kDependsOnMaps);
1722 }
1723
1724 virtual Representation RequiredInputRepresentation(int index) const {
1725 return Representation::Tagged();
1726 }
1727
1728 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1729
1730 protected:
1731 virtual bool DataEquals(HValue* other) { return true; }
1732};
1733
1734
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001735class HBitNot: public HUnaryOperation {
1736 public:
1737 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1738 set_representation(Representation::Integer32());
1739 SetFlag(kUseGVN);
1740 SetFlag(kTruncatingToInt32);
1741 }
1742
1743 virtual Representation RequiredInputRepresentation(int index) const {
1744 return Representation::Integer32();
1745 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001746 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001747
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001748 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001749
1750 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001751 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001752};
1753
1754
1755class HUnaryMathOperation: public HUnaryOperation {
1756 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001757 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758 : HUnaryOperation(value), op_(op) {
1759 switch (op) {
1760 case kMathFloor:
1761 case kMathRound:
1762 case kMathCeil:
1763 set_representation(Representation::Integer32());
1764 break;
1765 case kMathAbs:
1766 set_representation(Representation::Tagged());
1767 SetFlag(kFlexibleRepresentation);
1768 break;
1769 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001770 case kMathPowHalf:
1771 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001772 case kMathSin:
1773 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001774 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001775 break;
1776 default:
1777 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001778 }
1779 SetFlag(kUseGVN);
1780 }
1781
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001782 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001783
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001784 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785
1786 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1787
1788 virtual Representation RequiredInputRepresentation(int index) const {
1789 switch (op_) {
1790 case kMathFloor:
1791 case kMathRound:
1792 case kMathCeil:
1793 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001794 case kMathPowHalf:
1795 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001796 case kMathSin:
1797 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001798 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001799 case kMathAbs:
1800 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001801 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001802 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 return Representation::None();
1804 }
1805 }
1806
1807 virtual HValue* Canonicalize() {
1808 // If the input is integer32 then we replace the floor instruction
1809 // with its inputs. This happens before the representation changes are
1810 // introduced.
1811 if (op() == kMathFloor) {
1812 if (value()->representation().IsInteger32()) return value();
1813 }
1814 return this;
1815 }
1816
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001817 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001818 const char* OpName() const;
1819
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001820 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001821
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001822 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001823 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001824 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1825 return op_ == b->op();
1826 }
1827
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001828 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001829 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830};
1831
1832
1833class HLoadElements: public HUnaryOperation {
1834 public:
1835 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1836 set_representation(Representation::Tagged());
1837 SetFlag(kUseGVN);
1838 SetFlag(kDependsOnMaps);
1839 }
1840
1841 virtual Representation RequiredInputRepresentation(int index) const {
1842 return Representation::Tagged();
1843 }
1844
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001845 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001846
1847 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001848 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001849};
1850
1851
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001852class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001853 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001854 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001855 : HUnaryOperation(value) {
1856 set_representation(Representation::External());
1857 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001858 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001859 // change once set, so it's no necessary to introduce any additional
1860 // dependencies on top of the inputs.
1861 SetFlag(kUseGVN);
1862 }
1863
1864 virtual Representation RequiredInputRepresentation(int index) const {
1865 return Representation::Tagged();
1866 }
1867
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001868 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001869
1870 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001871 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001872};
1873
1874
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875class HCheckMap: public HUnaryOperation {
1876 public:
1877 HCheckMap(HValue* value, Handle<Map> map)
1878 : HUnaryOperation(value), map_(map) {
1879 set_representation(Representation::Tagged());
1880 SetFlag(kUseGVN);
1881 SetFlag(kDependsOnMaps);
1882 }
1883
1884 virtual Representation RequiredInputRepresentation(int index) const {
1885 return Representation::Tagged();
1886 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001887 virtual void PrintDataTo(StringStream* stream);
1888 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001889
1890#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001891 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001892#endif
1893
1894 Handle<Map> map() const { return map_; }
1895
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001896 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001897
1898 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001899 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001900 HCheckMap* b = HCheckMap::cast(other);
1901 return map_.is_identical_to(b->map());
1902 }
1903
1904 private:
1905 Handle<Map> map_;
1906};
1907
1908
1909class HCheckFunction: public HUnaryOperation {
1910 public:
1911 HCheckFunction(HValue* value, Handle<JSFunction> function)
1912 : HUnaryOperation(value), target_(function) {
1913 set_representation(Representation::Tagged());
1914 SetFlag(kUseGVN);
1915 }
1916
1917 virtual Representation RequiredInputRepresentation(int index) const {
1918 return Representation::Tagged();
1919 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001920 virtual void PrintDataTo(StringStream* stream);
1921 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001922
1923#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001924 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001925#endif
1926
1927 Handle<JSFunction> target() const { return target_; }
1928
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001929 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930
1931 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001932 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001933 HCheckFunction* b = HCheckFunction::cast(other);
1934 return target_.is_identical_to(b->target());
1935 }
1936
1937 private:
1938 Handle<JSFunction> target_;
1939};
1940
1941
1942class HCheckInstanceType: public HUnaryOperation {
1943 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001944 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1945 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001946 }
1947 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1948 return new HCheckInstanceType(value, IS_JS_ARRAY);
1949 }
1950 static HCheckInstanceType* NewIsString(HValue* value) {
1951 return new HCheckInstanceType(value, IS_STRING);
1952 }
1953 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1954 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001955 }
1956
1957 virtual Representation RequiredInputRepresentation(int index) const {
1958 return Representation::Tagged();
1959 }
1960
1961#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001962 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963#endif
1964
danno@chromium.org160a7b02011-04-18 15:51:38 +00001965 virtual HValue* Canonicalize() {
1966 if (!value()->type().IsUninitialized() &&
1967 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001968 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001969 return NULL;
1970 }
1971 return this;
1972 }
1973
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001974 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1975 void GetCheckInterval(InstanceType* first, InstanceType* last);
1976 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001978 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001979
1980 protected:
1981 // TODO(ager): It could be nice to allow the ommision of instance
1982 // type checks if we have already performed an instance type check
1983 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001984 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001985 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001986 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001987 }
1988
1989 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001990 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001991 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001992 IS_JS_ARRAY,
1993 IS_STRING,
1994 IS_SYMBOL,
1995 LAST_INTERVAL_CHECK = IS_JS_ARRAY
1996 };
1997
1998 HCheckInstanceType(HValue* value, Check check)
1999 : HUnaryOperation(value), check_(check) {
2000 set_representation(Representation::Tagged());
2001 SetFlag(kUseGVN);
2002 }
2003
2004 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002005};
2006
2007
2008class HCheckNonSmi: public HUnaryOperation {
2009 public:
2010 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2011 set_representation(Representation::Tagged());
2012 SetFlag(kUseGVN);
2013 }
2014
2015 virtual Representation RequiredInputRepresentation(int index) const {
2016 return Representation::Tagged();
2017 }
2018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002019 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020
2021#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002022 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002023#endif
2024
danno@chromium.org160a7b02011-04-18 15:51:38 +00002025 virtual HValue* Canonicalize() {
2026 HType value_type = value()->type();
2027 if (!value_type.IsUninitialized() &&
2028 (value_type.IsHeapNumber() ||
2029 value_type.IsString() ||
2030 value_type.IsBoolean() ||
2031 value_type.IsNonPrimitive())) {
2032 return NULL;
2033 }
2034 return this;
2035 }
2036
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002037 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002038
2039 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002040 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002041};
2042
2043
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002044class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002045 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002046 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2047 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002048 SetFlag(kUseGVN);
2049 SetFlag(kDependsOnMaps);
2050 }
2051
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002053 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054#endif
2055
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002056 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002058
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002059 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002061 virtual Representation RequiredInputRepresentation(int index) const {
2062 return Representation::None();
2063 }
2064
2065 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002066 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002067 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2068 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2069 return hash;
2070 }
2071
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002072 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002073 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002074 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002075 return prototype_.is_identical_to(b->prototype()) &&
2076 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002077 }
2078
2079 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002080 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002081 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082};
2083
2084
2085class HCheckSmi: public HUnaryOperation {
2086 public:
2087 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2088 set_representation(Representation::Tagged());
2089 SetFlag(kUseGVN);
2090 }
2091
2092 virtual Representation RequiredInputRepresentation(int index) const {
2093 return Representation::Tagged();
2094 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002095 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096
2097#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002098 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099#endif
2100
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002101 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002102
2103 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002104 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002105};
2106
2107
2108class HPhi: public HValue {
2109 public:
2110 explicit HPhi(int merged_index)
2111 : inputs_(2),
2112 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002113 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002114 is_live_(false),
2115 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2117 non_phi_uses_[i] = 0;
2118 indirect_uses_[i] = 0;
2119 }
2120 ASSERT(merged_index >= 0);
2121 set_representation(Representation::Tagged());
2122 SetFlag(kFlexibleRepresentation);
2123 }
2124
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002125 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002126 bool double_occurred = false;
2127 bool int32_occurred = false;
2128 for (int i = 0; i < OperandCount(); ++i) {
2129 HValue* value = OperandAt(i);
2130 if (value->representation().IsDouble()) double_occurred = true;
2131 if (value->representation().IsInteger32()) int32_occurred = true;
2132 if (value->representation().IsTagged()) return Representation::Tagged();
2133 }
2134
2135 if (double_occurred) return Representation::Double();
2136 if (int32_occurred) return Representation::Integer32();
2137 return Representation::None();
2138 }
2139
2140 virtual Range* InferRange();
2141 virtual Representation RequiredInputRepresentation(int index) const {
2142 return representation();
2143 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002144 virtual HType CalculateInferredType();
2145 virtual int OperandCount() { return inputs_.length(); }
2146 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2147 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002148 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002149 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002150
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002151 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002152
2153 int merged_index() const { return merged_index_; }
2154
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002155 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156
2157#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002158 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159#endif
2160
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161 void InitRealUses(int id);
2162 void AddNonPhiUsesFrom(HPhi* other);
2163 void AddIndirectUsesTo(int* use_count);
2164
2165 int tagged_non_phi_uses() const {
2166 return non_phi_uses_[Representation::kTagged];
2167 }
2168 int int32_non_phi_uses() const {
2169 return non_phi_uses_[Representation::kInteger32];
2170 }
2171 int double_non_phi_uses() const {
2172 return non_phi_uses_[Representation::kDouble];
2173 }
2174 int tagged_indirect_uses() const {
2175 return indirect_uses_[Representation::kTagged];
2176 }
2177 int int32_indirect_uses() const {
2178 return indirect_uses_[Representation::kInteger32];
2179 }
2180 int double_indirect_uses() const {
2181 return indirect_uses_[Representation::kDouble];
2182 }
2183 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002184 bool is_live() { return is_live_; }
2185 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002187 static HPhi* cast(HValue* value) {
2188 ASSERT(value->IsPhi());
2189 return reinterpret_cast<HPhi*>(value);
2190 }
2191 virtual Opcode opcode() const { return HValue::kPhi; }
2192
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002193 virtual bool IsConvertibleToInteger() const {
2194 return is_convertible_to_integer_;
2195 }
2196
2197 void set_is_convertible_to_integer(bool b) {
2198 is_convertible_to_integer_ = b;
2199 }
2200
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002201 protected:
2202 virtual void DeleteFromGraph();
2203 virtual void InternalSetOperandAt(int index, HValue* value) {
2204 inputs_[index] = value;
2205 }
2206
2207 private:
2208 ZoneList<HValue*> inputs_;
2209 int merged_index_;
2210
2211 int non_phi_uses_[Representation::kNumRepresentations];
2212 int indirect_uses_[Representation::kNumRepresentations];
2213 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002214 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002215 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002216};
2217
2218
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002219class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002220 public:
2221 HArgumentsObject() {
2222 set_representation(Representation::Tagged());
2223 SetFlag(kIsArguments);
2224 }
2225
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002226 virtual Representation RequiredInputRepresentation(int index) const {
2227 return Representation::None();
2228 }
2229
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002230 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002231};
2232
2233
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002234class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235 public:
2236 HConstant(Handle<Object> handle, Representation r);
2237
2238 Handle<Object> handle() const { return handle_; }
2239
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002240 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002241
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002242 virtual Representation RequiredInputRepresentation(int index) const {
2243 return Representation::None();
2244 }
2245
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002246 virtual bool IsConvertibleToInteger() const {
2247 if (handle_->IsSmi()) return true;
2248 if (handle_->IsHeapNumber() &&
2249 (HeapNumber::cast(*handle_)->value() ==
2250 static_cast<double>(NumberToInt32(*handle_)))) return true;
2251 return false;
2252 }
2253
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002254 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002255 virtual void PrintDataTo(StringStream* stream);
2256 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002257 bool IsInteger() const { return handle_->IsSmi(); }
2258 HConstant* CopyToRepresentation(Representation r) const;
2259 HConstant* CopyToTruncatedInt32() const;
2260 bool HasInteger32Value() const { return has_int32_value_; }
2261 int32_t Integer32Value() const {
2262 ASSERT(HasInteger32Value());
2263 return int32_value_;
2264 }
2265 bool HasDoubleValue() const { return has_double_value_; }
2266 double DoubleValue() const {
2267 ASSERT(HasDoubleValue());
2268 return double_value_;
2269 }
2270 bool HasStringValue() const { return handle_->IsString(); }
2271
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002272 bool ToBoolean() const;
2273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002274 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002275 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276 return reinterpret_cast<intptr_t>(*handle());
2277 }
2278
2279#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002280 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002281#endif
2282
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002283 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284
2285 protected:
2286 virtual Range* InferRange();
2287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002288 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002289 HConstant* other_constant = HConstant::cast(other);
2290 return handle().is_identical_to(other_constant->handle());
2291 }
2292
2293 private:
2294 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002295
2296 // The following two values represent the int32 and the double value of the
2297 // given constant if there is a lossless conversion between the constant
2298 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002299 bool has_int32_value_ : 1;
2300 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002301 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002302 double double_value_;
2303};
2304
2305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002306class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002307 public:
2308 HBinaryOperation(HValue* left, HValue* right) {
2309 ASSERT(left != NULL && right != NULL);
2310 SetOperandAt(0, left);
2311 SetOperandAt(1, right);
2312 }
2313
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002314 HValue* left() { return OperandAt(0); }
2315 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002316
2317 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2318 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002319 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002320 if (IsCommutative() && left()->IsConstant()) return right();
2321 return left();
2322 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002323 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002324 if (IsCommutative() && left()->IsConstant()) return left();
2325 return right();
2326 }
2327
2328 virtual bool IsCommutative() const { return false; }
2329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002330 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331};
2332
2333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002334class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002335 public:
2336 HApplyArguments(HValue* function,
2337 HValue* receiver,
2338 HValue* length,
2339 HValue* elements) {
2340 set_representation(Representation::Tagged());
2341 SetOperandAt(0, function);
2342 SetOperandAt(1, receiver);
2343 SetOperandAt(2, length);
2344 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002345 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002346 }
2347
2348 virtual Representation RequiredInputRepresentation(int index) const {
2349 // The length is untagged, all other inputs are tagged.
2350 return (index == 2)
2351 ? Representation::Integer32()
2352 : Representation::Tagged();
2353 }
2354
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 HValue* function() { return OperandAt(0); }
2356 HValue* receiver() { return OperandAt(1); }
2357 HValue* length() { return OperandAt(2); }
2358 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002359
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002360 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361};
2362
2363
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002364class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002365 public:
2366 HArgumentsElements() {
2367 // The value produced by this instruction is a pointer into the stack
2368 // that looks as if it was a smi because of alignment.
2369 set_representation(Representation::Tagged());
2370 SetFlag(kUseGVN);
2371 }
2372
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002373 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002375 virtual Representation RequiredInputRepresentation(int index) const {
2376 return Representation::None();
2377 }
2378
ager@chromium.org378b34e2011-01-28 08:04:38 +00002379 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002380 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002381};
2382
2383
2384class HArgumentsLength: public HUnaryOperation {
2385 public:
2386 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2387 set_representation(Representation::Integer32());
2388 SetFlag(kUseGVN);
2389 }
2390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002391 virtual Representation RequiredInputRepresentation(int index) const {
2392 return Representation::Tagged();
2393 }
2394
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002395 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002396
2397 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
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002402class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002403 public:
2404 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2405 set_representation(Representation::Tagged());
2406 SetFlag(kUseGVN);
2407 SetOperandAt(0, arguments);
2408 SetOperandAt(1, length);
2409 SetOperandAt(2, index);
2410 }
2411
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002412 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002413
2414 virtual Representation RequiredInputRepresentation(int index) const {
2415 // The arguments elements is considered tagged.
2416 return index == 0
2417 ? Representation::Tagged()
2418 : Representation::Integer32();
2419 }
2420
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 HValue* arguments() { return OperandAt(0); }
2422 HValue* length() { return OperandAt(1); }
2423 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002424
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002425 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002427 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002428};
2429
2430
2431class HBoundsCheck: public HBinaryOperation {
2432 public:
2433 HBoundsCheck(HValue* index, HValue* length)
2434 : HBinaryOperation(index, length) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002435 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002436 SetFlag(kUseGVN);
2437 }
2438
2439 virtual Representation RequiredInputRepresentation(int index) const {
2440 return Representation::Integer32();
2441 }
2442
2443#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002444 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445#endif
2446
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002447 HValue* index() { return left(); }
2448 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002449
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002450 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002451
2452 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002453 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454};
2455
2456
2457class HBitwiseBinaryOperation: public HBinaryOperation {
2458 public:
2459 HBitwiseBinaryOperation(HValue* left, HValue* right)
2460 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002461 set_representation(Representation::Tagged());
2462 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002463 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002464 }
2465
2466 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002467 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002468 }
2469
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002470 virtual void RepresentationChanged(Representation to) {
2471 if (!to.IsTagged()) {
2472 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002473 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002474 SetFlag(kTruncatingToInt32);
2475 SetFlag(kUseGVN);
2476 }
2477 }
2478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002479 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002480
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002481 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002482};
2483
2484
2485class HArithmeticBinaryOperation: public HBinaryOperation {
2486 public:
2487 HArithmeticBinaryOperation(HValue* left, HValue* right)
2488 : HBinaryOperation(left, right) {
2489 set_representation(Representation::Tagged());
2490 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002491 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002492 }
2493
2494 virtual void RepresentationChanged(Representation to) {
2495 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002496 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002497 SetFlag(kUseGVN);
2498 }
2499 }
2500
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002501 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002502 virtual Representation RequiredInputRepresentation(int index) const {
2503 return representation();
2504 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002505 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002506 if (left()->representation().Equals(right()->representation())) {
2507 return left()->representation();
2508 }
2509 return HValue::InferredRepresentation();
2510 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511};
2512
2513
2514class HCompare: public HBinaryOperation {
2515 public:
2516 HCompare(HValue* left, HValue* right, Token::Value token)
2517 : HBinaryOperation(left, right), token_(token) {
2518 ASSERT(Token::IsCompareOp(token));
2519 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002520 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521 }
2522
2523 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002524
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002525 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002526 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002527 }
2528
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002529 virtual Representation RequiredInputRepresentation(int index) const {
2530 return input_representation_;
2531 }
2532 Representation GetInputRepresentation() const {
2533 return input_representation_;
2534 }
2535 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002536 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002537
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002538 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002540 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002541 return HValue::Hashcode() * 7 + token_;
2542 }
2543
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002544 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002545
2546 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002547 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548 HCompare* comp = HCompare::cast(other);
2549 return token_ == comp->token();
2550 }
2551
2552 private:
2553 Representation input_representation_;
2554 Token::Value token_;
2555};
2556
2557
2558class HCompareJSObjectEq: public HBinaryOperation {
2559 public:
2560 HCompareJSObjectEq(HValue* left, HValue* right)
2561 : HBinaryOperation(left, right) {
2562 set_representation(Representation::Tagged());
2563 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002564 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002565 }
2566
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002567 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002568 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002569 }
2570
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002571 virtual Representation RequiredInputRepresentation(int index) const {
2572 return Representation::Tagged();
2573 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002574 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002576 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002577
2578 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002579 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002580};
2581
2582
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002583class HCompareSymbolEq: public HBinaryOperation {
2584 public:
2585 HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
2586 : HBinaryOperation(left, right), op_(op) {
2587 ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
2588 set_representation(Representation::Tagged());
2589 SetFlag(kUseGVN);
2590 SetFlag(kDependsOnMaps);
2591 }
2592
2593 Token::Value op() const { return op_; }
2594
2595 virtual bool EmitAtUses() {
2596 return !HasSideEffects() && !HasMultipleUses();
2597 }
2598
2599 virtual Representation RequiredInputRepresentation(int index) const {
2600 return Representation::Tagged();
2601 }
2602
2603 virtual HType CalculateInferredType() { return HType::Boolean(); }
2604
2605 DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
2606
2607 protected:
2608 virtual bool DataEquals(HValue* other) {
2609 return op_ == HCompareSymbolEq::cast(other)->op_;
2610 }
2611
2612 private:
2613 const Token::Value op_;
2614};
2615
2616
whesse@chromium.org7b260152011-06-20 15:33:18 +00002617class HCompareConstantEq: public HUnaryOperation {
2618 public:
2619 HCompareConstantEq(HValue* left, int right, Token::Value op)
2620 : HUnaryOperation(left), op_(op), right_(right) {
2621 ASSERT(op == Token::EQ_STRICT);
2622 set_representation(Representation::Tagged());
2623 SetFlag(kUseGVN);
2624 }
2625
2626 Token::Value op() const { return op_; }
2627 int right() const { return right_; }
2628
2629 virtual bool EmitAtUses() {
2630 return !HasSideEffects() && !HasMultipleUses();
2631 }
2632
2633 virtual Representation RequiredInputRepresentation(int index) const {
2634 return Representation::Integer32();
2635 }
2636
2637 virtual HType CalculateInferredType() { return HType::Boolean(); }
2638
2639 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEq);
2640
2641 protected:
2642 virtual bool DataEquals(HValue* other) {
2643 HCompareConstantEq* other_instr = HCompareConstantEq::cast(other);
2644 return (op_ == other_instr->op_ &&
2645 right_ == other_instr->right_);
2646 }
2647
2648 private:
2649 const Token::Value op_;
2650 const int right_;
2651};
2652
2653
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002654class HUnaryPredicate: public HUnaryOperation {
2655 public:
2656 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2657 set_representation(Representation::Tagged());
2658 SetFlag(kUseGVN);
2659 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002660
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002661 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002662 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002663 }
2664
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002665 virtual Representation RequiredInputRepresentation(int index) const {
2666 return Representation::Tagged();
2667 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002668 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002669};
2670
2671
2672class HIsNull: public HUnaryPredicate {
2673 public:
2674 HIsNull(HValue* value, bool is_strict)
2675 : HUnaryPredicate(value), is_strict_(is_strict) { }
2676
2677 bool is_strict() const { return is_strict_; }
2678
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002679 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002681 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002682 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002683 HIsNull* b = HIsNull::cast(other);
2684 return is_strict_ == b->is_strict();
2685 }
2686
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002687 private:
2688 bool is_strict_;
2689};
2690
2691
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002692class HIsObject: public HUnaryPredicate {
2693 public:
2694 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002696 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002697
2698 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002699 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002700};
2701
2702
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002703class HIsSmi: public HUnaryPredicate {
2704 public:
2705 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2706
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002707 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002708
2709 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002710 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002711};
2712
2713
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002714class HIsUndetectable: public HUnaryPredicate {
2715 public:
2716 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2717
2718 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2719
2720 protected:
2721 virtual bool DataEquals(HValue* other) { return true; }
2722};
2723
2724
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002725class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002726 public:
2727 HIsConstructCall() {
2728 set_representation(Representation::Tagged());
2729 SetFlag(kUseGVN);
2730 }
2731
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002732 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002733 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002734 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002735
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002736 virtual Representation RequiredInputRepresentation(int index) const {
2737 return Representation::None();
2738 }
2739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002740 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002741
2742 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002743 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002744};
2745
2746
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747class HHasInstanceType: public HUnaryPredicate {
2748 public:
2749 HHasInstanceType(HValue* value, InstanceType type)
2750 : HUnaryPredicate(value), from_(type), to_(type) { }
2751 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2752 : HUnaryPredicate(value), from_(from), to_(to) {
2753 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2754 }
2755
2756 InstanceType from() { return from_; }
2757 InstanceType to() { return to_; }
2758
whesse@chromium.org7b260152011-06-20 15:33:18 +00002759 virtual bool EmitAtUses() {
2760 return !HasSideEffects() && !HasMultipleUses();
2761 }
2762
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002763 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002765 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002767 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002768 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002769 HHasInstanceType* b = HHasInstanceType::cast(other);
2770 return (from_ == b->from()) && (to_ == b->to());
2771 }
2772
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773 private:
2774 InstanceType from_;
2775 InstanceType to_; // Inclusive range, not all combinations work.
2776};
2777
2778
2779class HHasCachedArrayIndex: public HUnaryPredicate {
2780 public:
2781 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2782
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002783 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002784
2785 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002786 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787};
2788
2789
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002790class HGetCachedArrayIndex: public HUnaryPredicate {
2791 public:
2792 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2793
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002794 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002795
2796 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002797 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002798};
2799
2800
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801class HClassOfTest: public HUnaryPredicate {
2802 public:
2803 HClassOfTest(HValue* value, Handle<String> class_name)
2804 : HUnaryPredicate(value), class_name_(class_name) { }
2805
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002806 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002808 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809
2810 Handle<String> class_name() const { return class_name_; }
2811
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002812 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002813 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002814 HClassOfTest* b = HClassOfTest::cast(other);
2815 return class_name_.is_identical_to(b->class_name_);
2816 }
2817
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002818 private:
2819 Handle<String> class_name_;
2820};
2821
2822
2823class HTypeofIs: public HUnaryPredicate {
2824 public:
2825 HTypeofIs(HValue* value, Handle<String> type_literal)
2826 : HUnaryPredicate(value), type_literal_(type_literal) { }
2827
2828 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002829 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002830
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002831 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002832
2833 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002834 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835 HTypeofIs* b = HTypeofIs::cast(other);
2836 return type_literal_.is_identical_to(b->type_literal_);
2837 }
2838
2839 private:
2840 Handle<String> type_literal_;
2841};
2842
2843
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002844class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002845 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002846 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2847 SetOperandAt(0, context);
2848 SetOperandAt(1, left);
2849 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002850 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002851 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002852 }
2853
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002854 HValue* context() { return OperandAt(0); }
2855 HValue* left() { return OperandAt(1); }
2856 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002857
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858 virtual Representation RequiredInputRepresentation(int index) const {
2859 return Representation::Tagged();
2860 }
2861
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002862 virtual HType CalculateInferredType();
2863
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002864 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002866 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002867};
2868
2869
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002870class HInstanceOfKnownGlobal: public HUnaryOperation {
2871 public:
2872 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2873 : HUnaryOperation(left), function_(right) {
2874 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002875 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002876 }
2877
2878 Handle<JSFunction> function() { return function_; }
2879
2880 virtual Representation RequiredInputRepresentation(int index) const {
2881 return Representation::Tagged();
2882 }
2883
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002884 virtual HType CalculateInferredType();
2885
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002886 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002887
2888 private:
2889 Handle<JSFunction> function_;
2890};
2891
2892
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002893class HPower: public HBinaryOperation {
2894 public:
2895 HPower(HValue* left, HValue* right)
2896 : HBinaryOperation(left, right) {
2897 set_representation(Representation::Double());
2898 SetFlag(kUseGVN);
2899 }
2900
2901 virtual Representation RequiredInputRepresentation(int index) const {
2902 return (index == 1) ? Representation::None() : Representation::Double();
2903 }
2904
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002905 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002906
2907 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002908 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002909};
2910
2911
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002912class HAdd: public HArithmeticBinaryOperation {
2913 public:
2914 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2915 SetFlag(kCanOverflow);
2916 }
2917
2918 // Add is only commutative if two integer values are added and not if two
2919 // tagged values are added (because it might be a String concatenation).
2920 virtual bool IsCommutative() const {
2921 return !representation().IsTagged();
2922 }
2923
2924 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2925
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002926 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002928 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002929
2930 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002931 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002932
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933 virtual Range* InferRange();
2934};
2935
2936
2937class HSub: public HArithmeticBinaryOperation {
2938 public:
2939 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2940 SetFlag(kCanOverflow);
2941 }
2942
2943 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2944
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002945 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002946
2947 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002948 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002949
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950 virtual Range* InferRange();
2951};
2952
2953
2954class HMul: public HArithmeticBinaryOperation {
2955 public:
2956 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2957 SetFlag(kCanOverflow);
2958 }
2959
2960 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2961
2962 // Only commutative if it is certain that not two objects are multiplicated.
2963 virtual bool IsCommutative() const {
2964 return !representation().IsTagged();
2965 }
2966
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002967 DECLARE_CONCRETE_INSTRUCTION(Mul)
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 HMod: public HArithmeticBinaryOperation {
2977 public:
2978 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2979 SetFlag(kCanBeDivByZero);
2980 }
2981
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002982 bool HasPowerOf2Divisor() {
2983 if (right()->IsConstant() &&
2984 HConstant::cast(right())->HasInteger32Value()) {
2985 int32_t value = HConstant::cast(right())->Integer32Value();
2986 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2987 }
2988
2989 return false;
2990 }
2991
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2993
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002994 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002995
2996 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002997 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002998
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999 virtual Range* InferRange();
3000};
3001
3002
3003class HDiv: public HArithmeticBinaryOperation {
3004 public:
3005 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
3006 SetFlag(kCanBeDivByZero);
3007 SetFlag(kCanOverflow);
3008 }
3009
3010 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3011
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003012 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003013
3014 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003015 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003016
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017 virtual Range* InferRange();
3018};
3019
3020
3021class HBitAnd: public HBitwiseBinaryOperation {
3022 public:
3023 HBitAnd(HValue* left, HValue* right)
3024 : HBitwiseBinaryOperation(left, right) { }
3025
3026 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003027 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003028
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003029 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030
3031 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003032 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003033
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003034 virtual Range* InferRange();
3035};
3036
3037
3038class HBitXor: public HBitwiseBinaryOperation {
3039 public:
3040 HBitXor(HValue* left, HValue* right)
3041 : HBitwiseBinaryOperation(left, right) { }
3042
3043 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003044 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003045
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003046 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003047
3048 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003049 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003050};
3051
3052
3053class HBitOr: public HBitwiseBinaryOperation {
3054 public:
3055 HBitOr(HValue* left, HValue* right)
3056 : HBitwiseBinaryOperation(left, right) { }
3057
3058 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003059 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003061 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062
3063 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003064 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003065
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066 virtual Range* InferRange();
3067};
3068
3069
3070class HShl: public HBitwiseBinaryOperation {
3071 public:
3072 HShl(HValue* left, HValue* right)
3073 : HBitwiseBinaryOperation(left, right) { }
3074
3075 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003076 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003078 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003079
3080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082};
3083
3084
3085class HShr: public HBitwiseBinaryOperation {
3086 public:
3087 HShr(HValue* left, HValue* right)
3088 : HBitwiseBinaryOperation(left, right) { }
3089
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003090 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003092 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003093
3094 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003095 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003096};
3097
3098
3099class HSar: public HBitwiseBinaryOperation {
3100 public:
3101 HSar(HValue* left, HValue* right)
3102 : HBitwiseBinaryOperation(left, right) { }
3103
3104 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003105 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003106
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003107 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003108
3109 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003110 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003111};
3112
3113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003114class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115 public:
3116 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3117 SetFlag(kChangesOsrEntries);
3118 }
3119
3120 int ast_id() const { return ast_id_; }
3121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003122 virtual Representation RequiredInputRepresentation(int index) const {
3123 return Representation::None();
3124 }
3125
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003126 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127
3128 private:
3129 int ast_id_;
3130};
3131
3132
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003133class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 public:
3135 explicit HParameter(unsigned index) : index_(index) {
3136 set_representation(Representation::Tagged());
3137 }
3138
3139 unsigned index() const { return index_; }
3140
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003141 virtual void PrintDataTo(StringStream* stream);
3142
3143 virtual Representation RequiredInputRepresentation(int index) const {
3144 return Representation::None();
3145 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003147 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148
3149 private:
3150 unsigned index_;
3151};
3152
3153
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003154class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003156 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3157 : HUnaryCall(context, argument_count),
3158 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160 }
3161
3162 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003163
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003164 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003165
3166 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3167 transcendental_type_ = transcendental_type;
3168 }
3169 TranscendentalCache::Type transcendental_type() {
3170 return transcendental_type_;
3171 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003173 virtual void PrintDataTo(StringStream* stream);
3174
3175 virtual Representation RequiredInputRepresentation(int index) const {
3176 return Representation::Tagged();
3177 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003179 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180
3181 private:
3182 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003183 TranscendentalCache::Type transcendental_type_;
3184};
3185
3186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003187class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188 public:
3189 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3190
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003191 virtual Representation RequiredInputRepresentation(int index) const {
3192 return Representation::None();
3193 }
3194
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003195 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003196};
3197
3198
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003199class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003200 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003201 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003202 : cell_(cell), check_hole_value_(check_hole_value) {
3203 set_representation(Representation::Tagged());
3204 SetFlag(kUseGVN);
3205 SetFlag(kDependsOnGlobalVars);
3206 }
3207
3208 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3209 bool check_hole_value() const { return check_hole_value_; }
3210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003211 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003213 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003214 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215 return reinterpret_cast<intptr_t>(*cell_);
3216 }
3217
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003218 virtual Representation RequiredInputRepresentation(int index) const {
3219 return Representation::None();
3220 }
3221
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003222 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003223
3224 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003225 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003226 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003227 return cell_.is_identical_to(b->cell());
3228 }
3229
3230 private:
3231 Handle<JSGlobalPropertyCell> cell_;
3232 bool check_hole_value_;
3233};
3234
3235
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003236class HLoadGlobalGeneric: public HBinaryOperation {
3237 public:
3238 HLoadGlobalGeneric(HValue* context,
3239 HValue* global_object,
3240 Handle<Object> name,
3241 bool for_typeof)
3242 : HBinaryOperation(context, global_object),
3243 name_(name),
3244 for_typeof_(for_typeof) {
3245 set_representation(Representation::Tagged());
3246 SetAllSideEffects();
3247 }
3248
3249 HValue* context() { return OperandAt(0); }
3250 HValue* global_object() { return OperandAt(1); }
3251 Handle<Object> name() const { return name_; }
3252 bool for_typeof() const { return for_typeof_; }
3253
3254 virtual void PrintDataTo(StringStream* stream);
3255
3256 virtual Representation RequiredInputRepresentation(int index) const {
3257 return Representation::Tagged();
3258 }
3259
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003260 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003261
3262 private:
3263 Handle<Object> name_;
3264 bool for_typeof_;
3265};
3266
3267
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003268class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003269 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003270 HStoreGlobalCell(HValue* value,
3271 Handle<JSGlobalPropertyCell> cell,
3272 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003273 : HUnaryOperation(value),
3274 cell_(cell),
3275 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003276 SetFlag(kChangesGlobalVars);
3277 }
3278
3279 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003280 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003281
3282 virtual Representation RequiredInputRepresentation(int index) const {
3283 return Representation::Tagged();
3284 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003285 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003286
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003287 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003288
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003289 private:
3290 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003291 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003292};
3293
3294
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003295class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3296 public:
3297 HStoreGlobalGeneric(HValue* context,
3298 HValue* global_object,
3299 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003300 HValue* value,
3301 bool strict_mode)
3302 : name_(name),
3303 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003304 SetOperandAt(0, context);
3305 SetOperandAt(1, global_object);
3306 SetOperandAt(2, value);
3307 set_representation(Representation::Tagged());
3308 SetAllSideEffects();
3309 }
3310
3311 HValue* context() { return OperandAt(0); }
3312 HValue* global_object() { return OperandAt(1); }
3313 Handle<Object> name() const { return name_; }
3314 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003315 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003316
3317 virtual void PrintDataTo(StringStream* stream);
3318
3319 virtual Representation RequiredInputRepresentation(int index) const {
3320 return Representation::Tagged();
3321 }
3322
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003323 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003324
3325 private:
3326 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003327 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003328};
3329
3330
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003331class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003332 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003333 HLoadContextSlot(HValue* context , int slot_index)
3334 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003335 set_representation(Representation::Tagged());
3336 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003337 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003338 }
3339
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003340 int slot_index() const { return slot_index_; }
3341
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003342 virtual Representation RequiredInputRepresentation(int index) const {
3343 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003344 }
3345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003346 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003347
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003348 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003349
3350 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003351 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003352 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003353 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003354 }
3355
3356 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003357 int slot_index_;
3358};
3359
3360
3361static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3362 return !value->type().IsSmi() &&
3363 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3364}
3365
3366
3367class HStoreContextSlot: public HBinaryOperation {
3368 public:
3369 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3370 : HBinaryOperation(context, value), slot_index_(slot_index) {
3371 SetFlag(kChangesContextSlots);
3372 }
3373
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003374 HValue* context() { return OperandAt(0); }
3375 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003376 int slot_index() const { return slot_index_; }
3377
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003378 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003379 return StoringValueNeedsWriteBarrier(value());
3380 }
3381
3382 virtual Representation RequiredInputRepresentation(int index) const {
3383 return Representation::Tagged();
3384 }
3385
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003386 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003387
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003388 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003389
3390 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003391 int slot_index_;
3392};
3393
3394
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003395class HLoadNamedField: public HUnaryOperation {
3396 public:
3397 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3398 : HUnaryOperation(object),
3399 is_in_object_(is_in_object),
3400 offset_(offset) {
3401 set_representation(Representation::Tagged());
3402 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003403 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003404 if (is_in_object) {
3405 SetFlag(kDependsOnInobjectFields);
3406 } else {
3407 SetFlag(kDependsOnBackingStoreFields);
3408 }
3409 }
3410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003411 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003412 bool is_in_object() const { return is_in_object_; }
3413 int offset() const { return offset_; }
3414
3415 virtual Representation RequiredInputRepresentation(int index) const {
3416 return Representation::Tagged();
3417 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003418 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003419
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003420 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003421
3422 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003423 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003424 HLoadNamedField* b = HLoadNamedField::cast(other);
3425 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3426 }
3427
3428 private:
3429 bool is_in_object_;
3430 int offset_;
3431};
3432
3433
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003434class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3435 public:
3436 HLoadNamedFieldPolymorphic(HValue* object,
3437 ZoneMapList* types,
3438 Handle<String> name);
3439
3440 HValue* object() { return OperandAt(0); }
3441 ZoneMapList* types() { return &types_; }
3442 Handle<String> name() { return name_; }
3443 bool need_generic() { return need_generic_; }
3444
3445 virtual Representation RequiredInputRepresentation(int index) const {
3446 return Representation::Tagged();
3447 }
3448
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003449 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003450
3451 static const int kMaxLoadPolymorphism = 4;
3452
3453 protected:
3454 virtual bool DataEquals(HValue* value);
3455
3456 private:
3457 ZoneMapList types_;
3458 Handle<String> name_;
3459 bool need_generic_;
3460};
3461
3462
3463
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003464class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003466 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3467 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003468 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003469 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003470 }
3471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003472 HValue* context() { return OperandAt(0); }
3473 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003474 Handle<Object> name() const { return name_; }
3475
3476 virtual Representation RequiredInputRepresentation(int index) const {
3477 return Representation::Tagged();
3478 }
3479
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003480 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003481
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003482 private:
3483 Handle<Object> name_;
3484};
3485
3486
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003487class HLoadFunctionPrototype: public HUnaryOperation {
3488 public:
3489 explicit HLoadFunctionPrototype(HValue* function)
3490 : HUnaryOperation(function) {
3491 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003492 SetFlag(kUseGVN);
3493 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003494 }
3495
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003496 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003497
3498 virtual Representation RequiredInputRepresentation(int index) const {
3499 return Representation::Tagged();
3500 }
3501
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003502 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003503
3504 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003505 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003506};
3507
3508
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003509class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003510 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003511 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003512 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003513 SetFlag(kDependsOnArrayElements);
3514 SetFlag(kUseGVN);
3515 }
3516
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003517 HValue* object() { return OperandAt(0); }
3518 HValue* key() { return OperandAt(1); }
3519
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003520 virtual Representation RequiredInputRepresentation(int index) const {
3521 // The key is supposed to be Integer32.
3522 return (index == 1) ? Representation::Integer32()
3523 : Representation::Tagged();
3524 }
3525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003526 virtual void PrintDataTo(StringStream* stream);
3527
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003528 bool RequiresHoleCheck() const;
3529
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003530 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003531
3532 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003533 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003534};
3535
3536
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003537class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003538 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003539 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3540 HValue* key,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003541 JSObject::ElementsKind elements_kind)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003542 : HBinaryOperation(external_elements, key),
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003543 elements_kind_(elements_kind) {
3544 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3545 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003546 set_representation(Representation::Double());
3547 } else {
3548 set_representation(Representation::Integer32());
3549 }
3550 SetFlag(kDependsOnSpecializedArrayElements);
3551 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003552 SetFlag(kDependsOnCalls);
3553 SetFlag(kUseGVN);
3554 }
3555
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003556 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003557
3558 virtual Representation RequiredInputRepresentation(int index) const {
3559 // The key is supposed to be Integer32, but the base pointer
3560 // for the element load is a naked pointer.
3561 return (index == 1) ? Representation::Integer32()
3562 : Representation::External();
3563 }
3564
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003565 HValue* external_pointer() { return OperandAt(0); }
3566 HValue* key() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003567 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003568
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003569 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003570
3571 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003572 virtual bool DataEquals(HValue* other) {
3573 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3574 HLoadKeyedSpecializedArrayElement* cast_other =
3575 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003576 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003577 }
3578
3579 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003580 JSObject::ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003581};
3582
3583
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003584class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003585 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003586 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003587 set_representation(Representation::Tagged());
3588 SetOperandAt(0, obj);
3589 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003590 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003591 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592 }
3593
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003594 HValue* object() { return OperandAt(0); }
3595 HValue* key() { return OperandAt(1); }
3596 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003597
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003598 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599
3600 virtual Representation RequiredInputRepresentation(int index) const {
3601 return Representation::Tagged();
3602 }
3603
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003604 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003605};
3606
3607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003608class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003609 public:
3610 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003611 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003612 HValue* val,
3613 bool in_object,
3614 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003615 : HBinaryOperation(obj, val),
3616 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003617 is_in_object_(in_object),
3618 offset_(offset) {
3619 if (is_in_object_) {
3620 SetFlag(kChangesInobjectFields);
3621 } else {
3622 SetFlag(kChangesBackingStoreFields);
3623 }
3624 }
3625
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003626 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003627
3628 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003629 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003631 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003633 HValue* object() { return OperandAt(0); }
3634 HValue* value() { return OperandAt(1); }
3635
3636 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003637 bool is_in_object() const { return is_in_object_; }
3638 int offset() const { return offset_; }
3639 Handle<Map> transition() const { return transition_; }
3640 void set_transition(Handle<Map> map) { transition_ = map; }
3641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003642 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003643 return StoringValueNeedsWriteBarrier(value());
3644 }
3645
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003646 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003647 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003648 bool is_in_object_;
3649 int offset_;
3650 Handle<Map> transition_;
3651};
3652
3653
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003654class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003655 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003656 HStoreNamedGeneric(HValue* context,
3657 HValue* object,
3658 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003659 HValue* value,
3660 bool strict_mode)
3661 : name_(name),
3662 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003663 SetOperandAt(0, object);
3664 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003665 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003666 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003667 }
3668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003669 HValue* object() { return OperandAt(0); }
3670 HValue* value() { return OperandAt(1); }
3671 HValue* context() { return OperandAt(2); }
3672 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003673 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003674
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003675 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003676
3677 virtual Representation RequiredInputRepresentation(int index) const {
3678 return Representation::Tagged();
3679 }
3680
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003681 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003682
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003683 private:
3684 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003685 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003686};
3687
3688
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003689class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003691 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3692 SetOperandAt(0, obj);
3693 SetOperandAt(1, key);
3694 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695 SetFlag(kChangesArrayElements);
3696 }
3697
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003698 virtual Representation RequiredInputRepresentation(int index) const {
3699 // The key is supposed to be Integer32.
3700 return (index == 1) ? Representation::Integer32()
3701 : Representation::Tagged();
3702 }
3703
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003704 HValue* object() { return OperandAt(0); }
3705 HValue* key() { return OperandAt(1); }
3706 HValue* value() { return OperandAt(2); }
3707
3708 bool NeedsWriteBarrier() {
3709 return StoringValueNeedsWriteBarrier(value());
3710 }
3711
3712 virtual void PrintDataTo(StringStream* stream);
3713
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003714 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003715};
3716
3717
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003718class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003719 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003720 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3721 HValue* key,
3722 HValue* val,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003723 JSObject::ElementsKind elements_kind)
3724 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003725 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003726 SetOperandAt(0, external_elements);
3727 SetOperandAt(1, key);
3728 SetOperandAt(2, val);
3729 }
3730
3731 virtual void PrintDataTo(StringStream* stream);
3732
3733 virtual Representation RequiredInputRepresentation(int index) const {
3734 if (index == 0) {
3735 return Representation::External();
3736 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003737 bool float_or_double_elements =
3738 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3739 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
3740 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003741 return Representation::Double();
3742 } else {
3743 return Representation::Integer32();
3744 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003745 }
3746 }
3747
3748 HValue* external_pointer() { return OperandAt(0); }
3749 HValue* key() { return OperandAt(1); }
3750 HValue* value() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003751 JSObject::ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003752
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003753 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3754
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003755 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003756 JSObject::ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003757};
3758
3759
3760class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003761 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003762 HStoreKeyedGeneric(HValue* context,
3763 HValue* object,
3764 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003765 HValue* value,
3766 bool strict_mode)
3767 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003768 SetOperandAt(0, object);
3769 SetOperandAt(1, key);
3770 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003771 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003772 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003773 }
3774
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003775 HValue* object() { return OperandAt(0); }
3776 HValue* key() { return OperandAt(1); }
3777 HValue* value() { return OperandAt(2); }
3778 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003779 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003780
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003781 virtual Representation RequiredInputRepresentation(int index) const {
3782 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003783 }
3784
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003785 virtual void PrintDataTo(StringStream* stream);
3786
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003787 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003788
3789 private:
3790 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003791};
3792
3793
danno@chromium.org160a7b02011-04-18 15:51:38 +00003794class HStringAdd: public HBinaryOperation {
3795 public:
3796 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3797 set_representation(Representation::Tagged());
3798 SetFlag(kUseGVN);
3799 SetFlag(kDependsOnMaps);
3800 }
3801
3802 virtual Representation RequiredInputRepresentation(int index) const {
3803 return Representation::Tagged();
3804 }
3805
3806 virtual HType CalculateInferredType() {
3807 return HType::String();
3808 }
3809
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003810 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003811
3812 protected:
3813 virtual bool DataEquals(HValue* other) { return true; }
3814};
3815
3816
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003817class HStringCharCodeAt: public HBinaryOperation {
3818 public:
3819 HStringCharCodeAt(HValue* string, HValue* index)
3820 : HBinaryOperation(string, index) {
3821 set_representation(Representation::Integer32());
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 // The index is supposed to be Integer32.
3828 return (index == 1) ? Representation::Integer32()
3829 : Representation::Tagged();
3830 }
3831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003832 HValue* string() { return OperandAt(0); }
3833 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003834
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003835 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
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::kMaxUC16CharCode);
3842 }
3843};
3844
3845
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003846class HStringCharFromCode: public HUnaryOperation {
3847 public:
3848 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3849 set_representation(Representation::Tagged());
3850 SetFlag(kUseGVN);
3851 }
3852
3853 virtual Representation RequiredInputRepresentation(int index) const {
3854 return Representation::Integer32();
3855 }
3856
3857 virtual bool DataEquals(HValue* other) { return true; }
3858
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003859 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003860};
3861
3862
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003863class HStringLength: public HUnaryOperation {
3864 public:
3865 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3866 set_representation(Representation::Tagged());
3867 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003868 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003869 }
3870
3871 virtual Representation RequiredInputRepresentation(int index) const {
3872 return Representation::Tagged();
3873 }
3874
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003875 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003876 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3877 return HType::Smi();
3878 }
3879
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003880 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003881
3882 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003883 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003884
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003885 virtual Range* InferRange() {
3886 return new Range(0, String::kMaxLength);
3887 }
3888};
3889
3890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003891template <int V>
3892class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003893 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003894 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003895 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003896 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003897 }
3898
3899 int literal_index() const { return literal_index_; }
3900 int depth() const { return depth_; }
3901
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003902 private:
3903 int literal_index_;
3904 int depth_;
3905};
3906
3907
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003908class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003909 public:
3910 HArrayLiteral(Handle<FixedArray> constant_elements,
3911 int length,
3912 int literal_index,
3913 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003914 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003915 length_(length),
3916 constant_elements_(constant_elements) {}
3917
3918 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3919 int length() const { return length_; }
3920
3921 bool IsCopyOnWrite() const;
3922
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003923 virtual Representation RequiredInputRepresentation(int index) const {
3924 return Representation::None();
3925 }
3926
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003927 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003928
3929 private:
3930 int length_;
3931 Handle<FixedArray> constant_elements_;
3932};
3933
3934
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003935class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003936 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003937 HObjectLiteral(HValue* context,
3938 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003939 bool fast_elements,
3940 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003941 int depth,
3942 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003943 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003944 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003945 fast_elements_(fast_elements),
3946 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003947 SetOperandAt(0, context);
3948 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003949
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003950 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003951 Handle<FixedArray> constant_properties() const {
3952 return constant_properties_;
3953 }
3954 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003955 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003957 virtual Representation RequiredInputRepresentation(int index) const {
3958 return Representation::Tagged();
3959 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003960
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003961 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003962
3963 private:
3964 Handle<FixedArray> constant_properties_;
3965 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003966 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003967};
3968
3969
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003970class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003971 public:
3972 HRegExpLiteral(Handle<String> pattern,
3973 Handle<String> flags,
3974 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003975 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003976 pattern_(pattern),
3977 flags_(flags) { }
3978
3979 Handle<String> pattern() { return pattern_; }
3980 Handle<String> flags() { return flags_; }
3981
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003982 virtual Representation RequiredInputRepresentation(int index) const {
3983 return Representation::None();
3984 }
3985
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003986 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003987
3988 private:
3989 Handle<String> pattern_;
3990 Handle<String> flags_;
3991};
3992
3993
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003994class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003995 public:
3996 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3997 : shared_info_(shared), pretenure_(pretenure) {
3998 set_representation(Representation::Tagged());
3999 }
4000
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004001 virtual Representation RequiredInputRepresentation(int index) const {
4002 return Representation::None();
4003 }
4004
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004005 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004006
4007 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4008 bool pretenure() const { return pretenure_; }
4009
4010 private:
4011 Handle<SharedFunctionInfo> shared_info_;
4012 bool pretenure_;
4013};
4014
4015
4016class HTypeof: public HUnaryOperation {
4017 public:
4018 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
4019 set_representation(Representation::Tagged());
4020 }
4021
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004022 virtual Representation RequiredInputRepresentation(int index) const {
4023 return Representation::Tagged();
4024 }
4025
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004026 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004027};
4028
4029
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004030class HToFastProperties: public HUnaryOperation {
4031 public:
4032 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4033 // This instruction is not marked as having side effects, but
4034 // changes the map of the input operand. Use it only when creating
4035 // object literals.
4036 ASSERT(value->IsObjectLiteral());
4037 set_representation(Representation::Tagged());
4038 }
4039
4040 virtual Representation RequiredInputRepresentation(int index) const {
4041 return Representation::Tagged();
4042 }
4043
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004044 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004045};
4046
4047
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004048class HValueOf: public HUnaryOperation {
4049 public:
4050 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4051 set_representation(Representation::Tagged());
4052 }
4053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004054 virtual Representation RequiredInputRepresentation(int index) const {
4055 return Representation::Tagged();
4056 }
4057
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004058 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004059};
4060
4061
4062class HDeleteProperty: public HBinaryOperation {
4063 public:
4064 HDeleteProperty(HValue* obj, HValue* key)
4065 : HBinaryOperation(obj, key) {
4066 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004067 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004068 }
4069
4070 virtual Representation RequiredInputRepresentation(int index) const {
4071 return Representation::Tagged();
4072 }
4073
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004074 virtual HType CalculateInferredType();
4075
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004076 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004077
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004078 HValue* object() { return left(); }
4079 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004080};
4081
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004082
4083class HIn: public HTemplateInstruction<2> {
4084 public:
4085 HIn(HValue* key, HValue* object) {
4086 SetOperandAt(0, key);
4087 SetOperandAt(1, object);
4088 set_representation(Representation::Tagged());
4089 SetAllSideEffects();
4090 }
4091
4092 HValue* key() { return OperandAt(0); }
4093 HValue* object() { return OperandAt(1); }
4094
4095 virtual Representation RequiredInputRepresentation(int index) const {
4096 return Representation::Tagged();
4097 }
4098
4099 virtual HType CalculateInferredType() {
4100 return HType::Boolean();
4101 }
4102
4103 virtual void PrintDataTo(StringStream* stream);
4104
4105 DECLARE_CONCRETE_INSTRUCTION(In)
4106};
4107
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004108#undef DECLARE_INSTRUCTION
4109#undef DECLARE_CONCRETE_INSTRUCTION
4110
4111} } // namespace v8::internal
4112
4113#endif // V8_HYDROGEN_INSTRUCTIONS_H_