blob: 52fed8844235145c281132e3b81d17a6da9b4960 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
48class HInstruction;
49class HLoopInformation;
50class HValue;
51class LInstruction;
52class LChunkBuilder;
53
54
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000055#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 V(ControlInstruction) \
58 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059
60
61#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000062 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000063 V(AccessArgumentsAt) \
64 V(Add) \
65 V(ApplyArguments) \
66 V(ArgumentsElements) \
67 V(ArgumentsLength) \
68 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ArrayLiteral) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000070 V(Bitwise) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071 V(BitNot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000072 V(BlockEntry) \
73 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000074 V(Branch) \
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) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000092 V(ClassOfTestAndBranch) \
93 V(CompareIDAndBranch) \
94 V(CompareGeneric) \
95 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000096 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000097 V(CompareConstantEqAndBranch) \
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) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000105 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000106 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000107 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000108 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000109 V(GlobalObject) \
110 V(GlobalReceiver) \
111 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000112 V(HasCachedArrayIndexAndBranch) \
113 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000114 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000116 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000117 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000118 V(IsConstructCallAndBranch) \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000119 V(IsNilAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000120 V(IsObjectAndBranch) \
erikcorry0ad885c2011-11-21 13:51:57 +0000121 V(IsStringAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000122 V(IsSmiAndBranch) \
123 V(IsUndetectableAndBranch) \
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000124 V(StringCompareAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000125 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000127 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000129 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000130 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000131 V(LoadGlobalCell) \
132 V(LoadGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000133 V(LoadKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadKeyedFastElement) \
135 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000136 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000138 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139 V(LoadNamedGeneric) \
140 V(Mod) \
141 V(Mul) \
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000142 V(ObjectLiteralFast) \
143 V(ObjectLiteralGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000144 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000145 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000146 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000147 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000148 V(PushArgument) \
149 V(RegExpLiteral) \
150 V(Return) \
151 V(Sar) \
152 V(Shl) \
153 V(Shr) \
154 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000155 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000157 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000158 V(StoreGlobalCell) \
159 V(StoreGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000160 V(StoreKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 V(StoreKeyedFastElement) \
162 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000163 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000164 V(StoreNamedField) \
165 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000166 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000167 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000168 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000169 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000171 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000172 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000173 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000174 V(ToInt32) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000175 V(TransitionElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000177 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178 V(UnaryMathOperation) \
179 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000180 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 V(ValueOf)
182
183#define GVN_FLAG_LIST(V) \
184 V(Calls) \
185 V(InobjectFields) \
186 V(BackingStoreFields) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000187 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000189 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000190 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191 V(GlobalVars) \
192 V(Maps) \
193 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000194 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195 V(OsrEntries)
196
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000197#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198 virtual bool Is##type() const { return true; } \
199 static H##type* cast(HValue* value) { \
200 ASSERT(value->Is##type()); \
201 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000202 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203
204
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000205#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000207 static H##type* cast(HValue* value) { \
208 ASSERT(value->Is##type()); \
209 return reinterpret_cast<H##type*>(value); \
210 } \
211 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212
213
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214class Range: public ZoneObject {
215 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000216 Range()
217 : lower_(kMinInt),
218 upper_(kMaxInt),
219 next_(NULL),
220 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221
222 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000223 : lower_(lower),
224 upper_(upper),
225 next_(NULL),
226 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 int32_t upper() const { return upper_; }
229 int32_t lower() const { return lower_; }
230 Range* next() const { return next_; }
231 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
232 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000233 Range* Copy() const {
234 Range* result = new Range(lower_, upper_);
235 result->set_can_be_minus_zero(CanBeMinusZero());
236 return result;
237 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238 int32_t Mask() const;
239 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
240 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
241 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
242 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000243 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000244 bool IsMostGeneric() const {
245 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
246 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 bool IsInSmiRange() const {
248 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000249 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000250 void KeepOrder();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000251#ifdef DEBUG
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000252 void Verify() const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000253#endif
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000254
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 void StackUpon(Range* other) {
256 Intersect(other);
257 next_ = other;
258 }
259
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000260 void Intersect(Range* other);
261 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000262
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000263 void AddConstant(int32_t value);
264 void Sar(int32_t value);
265 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000266 bool AddAndCheckOverflow(Range* other);
267 bool SubAndCheckOverflow(Range* other);
268 bool MulAndCheckOverflow(Range* other);
269
270 private:
271 int32_t lower_;
272 int32_t upper_;
273 Range* next_;
274 bool can_be_minus_zero_;
275};
276
277
278class Representation {
279 public:
280 enum Kind {
281 kNone,
282 kTagged,
283 kDouble,
284 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000285 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000286 kNumRepresentations
287 };
288
289 Representation() : kind_(kNone) { }
290
291 static Representation None() { return Representation(kNone); }
292 static Representation Tagged() { return Representation(kTagged); }
293 static Representation Integer32() { return Representation(kInteger32); }
294 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000295 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000296
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000297 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000298 return kind_ == other.kind_;
299 }
300
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000301 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302 bool IsNone() const { return kind_ == kNone; }
303 bool IsTagged() const { return kind_ == kTagged; }
304 bool IsInteger32() const { return kind_ == kInteger32; }
305 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000306 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000307 bool IsSpecialization() const {
308 return kind_ == kInteger32 || kind_ == kDouble;
309 }
310 const char* Mnemonic() const;
311
312 private:
313 explicit Representation(Kind k) : kind_(k) { }
314
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000315 // Make sure kind fits in int8.
316 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
317
318 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000319};
320
321
322class HType {
323 public:
324 HType() : type_(kUninitialized) { }
325
326 static HType Tagged() { return HType(kTagged); }
327 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
328 static HType TaggedNumber() { return HType(kTaggedNumber); }
329 static HType Smi() { return HType(kSmi); }
330 static HType HeapNumber() { return HType(kHeapNumber); }
331 static HType String() { return HType(kString); }
332 static HType Boolean() { return HType(kBoolean); }
333 static HType NonPrimitive() { return HType(kNonPrimitive); }
334 static HType JSArray() { return HType(kJSArray); }
335 static HType JSObject() { return HType(kJSObject); }
336 static HType Uninitialized() { return HType(kUninitialized); }
337
338 // Return the weakest (least precise) common type.
339 HType Combine(HType other) {
340 return HType(static_cast<Type>(type_ & other.type_));
341 }
342
343 bool Equals(const HType& other) {
344 return type_ == other.type_;
345 }
346
347 bool IsSubtypeOf(const HType& other) {
348 return Combine(other).Equals(other);
349 }
350
351 bool IsTagged() {
352 ASSERT(type_ != kUninitialized);
353 return ((type_ & kTagged) == kTagged);
354 }
355
356 bool IsTaggedPrimitive() {
357 ASSERT(type_ != kUninitialized);
358 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
359 }
360
361 bool IsTaggedNumber() {
362 ASSERT(type_ != kUninitialized);
363 return ((type_ & kTaggedNumber) == kTaggedNumber);
364 }
365
366 bool IsSmi() {
367 ASSERT(type_ != kUninitialized);
368 return ((type_ & kSmi) == kSmi);
369 }
370
371 bool IsHeapNumber() {
372 ASSERT(type_ != kUninitialized);
373 return ((type_ & kHeapNumber) == kHeapNumber);
374 }
375
376 bool IsString() {
377 ASSERT(type_ != kUninitialized);
378 return ((type_ & kString) == kString);
379 }
380
381 bool IsBoolean() {
382 ASSERT(type_ != kUninitialized);
383 return ((type_ & kBoolean) == kBoolean);
384 }
385
386 bool IsNonPrimitive() {
387 ASSERT(type_ != kUninitialized);
388 return ((type_ & kNonPrimitive) == kNonPrimitive);
389 }
390
391 bool IsJSArray() {
392 ASSERT(type_ != kUninitialized);
393 return ((type_ & kJSArray) == kJSArray);
394 }
395
396 bool IsJSObject() {
397 ASSERT(type_ != kUninitialized);
398 return ((type_ & kJSObject) == kJSObject);
399 }
400
401 bool IsUninitialized() {
402 return type_ == kUninitialized;
403 }
404
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000405 bool IsHeapObject() {
406 ASSERT(type_ != kUninitialized);
407 return IsHeapNumber() || IsString() || IsNonPrimitive();
408 }
409
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000410 static HType TypeFromValue(Handle<Object> value);
411
412 const char* ToString();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000413
414 private:
415 enum Type {
416 kTagged = 0x1, // 0000 0000 0000 0001
417 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
418 kTaggedNumber = 0xd, // 0000 0000 0000 1101
419 kSmi = 0x1d, // 0000 0000 0001 1101
420 kHeapNumber = 0x2d, // 0000 0000 0010 1101
421 kString = 0x45, // 0000 0000 0100 0101
422 kBoolean = 0x85, // 0000 0000 1000 0101
423 kNonPrimitive = 0x101, // 0000 0001 0000 0001
424 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000425 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000426 kUninitialized = 0x1fff // 0001 1111 1111 1111
427 };
428
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000429 // Make sure type fits in int16.
430 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
431
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000432 explicit HType(Type t) : type_(t) { }
433
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000434 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000435};
436
437
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000438class HUseListNode: public ZoneObject {
439 public:
440 HUseListNode(HValue* value, int index, HUseListNode* tail)
441 : tail_(tail), value_(value), index_(index) {
442 }
443
444 HUseListNode* tail() const { return tail_; }
445 HValue* value() const { return value_; }
446 int index() const { return index_; }
447
448 void set_tail(HUseListNode* list) { tail_ = list; }
449
450#ifdef DEBUG
451 void Zap() {
452 tail_ = reinterpret_cast<HUseListNode*>(1);
453 value_ = NULL;
454 index_ = -1;
455 }
456#endif
457
458 private:
459 HUseListNode* tail_;
460 HValue* value_;
461 int index_;
462};
463
464
465// We reuse use list nodes behind the scenes as uses are added and deleted.
466// This class is the safe way to iterate uses while deleting them.
467class HUseIterator BASE_EMBEDDED {
468 public:
469 bool Done() { return current_ == NULL; }
470 void Advance();
471
472 HValue* value() {
473 ASSERT(!Done());
474 return value_;
475 }
476
477 int index() {
478 ASSERT(!Done());
479 return index_;
480 }
481
482 private:
483 explicit HUseIterator(HUseListNode* head);
484
485 HUseListNode* current_;
486 HUseListNode* next_;
487 HValue* value_;
488 int index_;
489
490 friend class HValue;
491};
492
493
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000494class HValue: public ZoneObject {
495 public:
496 static const int kNoNumber = -1;
497
498 // There must be one corresponding kDepends flag for every kChanges flag and
499 // the order of the kChanges flags must be exactly the same as of the kDepends
500 // flags.
501 enum Flag {
502 // Declare global value numbering flags.
503 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
504 GVN_FLAG_LIST(DECLARE_DO)
505 #undef DECLARE_DO
506 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000507 // Participate in Global Value Numbering, i.e. elimination of
508 // unnecessary recomputations. If an instruction sets this flag, it must
509 // implement DataEquals(), which will be used to determine if other
510 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000511 kUseGVN,
512 kCanOverflow,
513 kBailoutOnMinusZero,
514 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000515 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000516 kIsArguments,
517 kTruncatingToInt32,
518 kLastFlag = kTruncatingToInt32
519 };
520
521 STATIC_ASSERT(kLastFlag < kBitsPerInt);
522
523 static const int kChangesToDependsFlagsLeftShift = 1;
524
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000525 static int ConvertChangesToDependsFlags(int flags) {
526 return flags << kChangesToDependsFlagsLeftShift;
527 }
528
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000529 static HValue* cast(HValue* value) { return value; }
530
531 enum Opcode {
532 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000533 #define DECLARE_OPCODE(type) k##type,
534 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
535 kPhi
536 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000537 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000538 virtual Opcode opcode() const = 0;
539
540 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
541 #define DECLARE_PREDICATE(type) \
542 bool Is##type() const { return opcode() == k##type; }
543 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
544 #undef DECLARE_PREDICATE
545 bool IsPhi() const { return opcode() == kPhi; }
546
547 // Declare virtual predicates for abstract HInstruction or HValue
548 #define DECLARE_PREDICATE(type) \
549 virtual bool Is##type() const { return false; }
550 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
551 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000552
553 HValue() : block_(NULL),
554 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000555 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000556 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557 range_(NULL),
558 flags_(0) {}
559 virtual ~HValue() {}
560
561 HBasicBlock* block() const { return block_; }
562 void SetBlock(HBasicBlock* block);
563
564 int id() const { return id_; }
565 void set_id(int id) { id_ = id; }
566
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000567 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000569 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000570 Representation representation() const { return representation_; }
571 void ChangeRepresentation(Representation r) {
572 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000573 ASSERT(!r.IsNone());
574 ASSERT(CheckFlag(kFlexibleRepresentation));
575 RepresentationChanged(r);
576 representation_ = r;
577 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000578 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000579
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000580 virtual bool IsConvertibleToInteger() const { return true; }
581
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000583 void set_type(HType new_type) {
584 ASSERT(new_type.IsSubtypeOf(type_));
585 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000586 }
587
588 // An operation needs to override this function iff:
589 // 1) it can produce an int32 output.
590 // 2) the true value of its output can potentially be minus zero.
591 // The implementation must set a flag so that it bails out in the case where
592 // it would otherwise output what should be a minus zero as an int32 zero.
593 // If the operation also exists in a form that takes int32 and outputs int32
594 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000595 // back. There are three operations that need to propagate back to more than
596 // one input. They are phi and binary div and mul. They always return NULL
597 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000598 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
599 visited->Add(id());
600 return NULL;
601 }
602
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000603 bool IsDefinedAfter(HBasicBlock* other) const;
604
605 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000606 virtual int OperandCount() = 0;
607 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000608 void SetOperandAt(int index, HValue* value);
609
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000610 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000611 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000612 bool HasNoUses() const { return use_list_ == NULL; }
613 bool HasMultipleUses() const {
614 return use_list_ != NULL && use_list_->tail() != NULL;
615 }
616 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000617 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000618
619 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000620 void SetFlag(Flag f) { flags_ |= (1 << f); }
621 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
622 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
623
624 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
625 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
626 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000627 bool HasObservableSideEffects() const {
628 return (flags_ & ObservableSideEffects()) != 0;
629 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000630
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000631 int ChangesFlags() const { return flags_ & ChangesFlagsMask(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000632 int ObservableChangesFlags() const {
633 return flags_ & ChangesFlagsMask() & ObservableSideEffects();
634 }
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000635
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000636 Range* range() const { return range_; }
637 bool HasRange() const { return range_ != NULL; }
638 void AddNewRange(Range* r);
639 void RemoveLastAddedRange();
640 void ComputeInitialRange();
641
642 // Representation helpers.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000643 virtual Representation RequiredInputRepresentation(int index) = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000644
645 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000646 return representation();
647 }
648
649 // This gives the instruction an opportunity to replace itself with an
650 // instruction that does the same in some better way. To replace an
651 // instruction with a new one, first add the new instruction to the graph,
652 // then return it. Return NULL to have the instruction deleted.
653 virtual HValue* Canonicalize() { return this; }
654
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000655 bool Equals(HValue* other);
656 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000657
658 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000659 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000661 void PrintTypeTo(StringStream* stream);
662 void PrintRangeTo(StringStream* stream);
663 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000664
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000665 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000666
667 // Updated the inferred type of this instruction and returns true if
668 // it has changed.
669 bool UpdateInferredType();
670
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000671 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000672
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000673#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000674 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000675#endif
676
677 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000678 // This function must be overridden for instructions with flag kUseGVN, to
679 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000680 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000681 UNREACHABLE();
682 return false;
683 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684 virtual void RepresentationChanged(Representation to) { }
685 virtual Range* InferRange();
686 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000687 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 void clear_block() {
689 ASSERT(block_ != NULL);
690 block_ = NULL;
691 }
692
693 void set_representation(Representation r) {
694 // Representation is set-once.
695 ASSERT(representation_.IsNone() && !r.IsNone());
696 representation_ = r;
697 }
698
699 private:
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000700 static int ChangesFlagsMask() {
701 int result = 0;
702 // Create changes mask.
703#define ADD_FLAG(type) result |= (1 << kChanges##type);
704 GVN_FLAG_LIST(ADD_FLAG)
705#undef ADD_FLAG
706 return result;
707 }
708
ager@chromium.org378b34e2011-01-28 08:04:38 +0000709 // A flag mask to mark an instruction as having arbitrary side effects.
710 static int AllSideEffects() {
711 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
712 }
713
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000714 // A flag mask of all side effects that can make observable changes in
715 // an executing program (i.e. are not safe to repeat, move or remove);
716 static int ObservableSideEffects() {
717 return ChangesFlagsMask() & ~(1 << kChangesElementsKind);
718 }
719
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000720 // Remove the matching use from the use list if present. Returns the
721 // removed list node or NULL.
722 HUseListNode* RemoveUse(HValue* value, int index);
723
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000724 void RegisterUse(int index, HValue* new_value);
725
726 HBasicBlock* block_;
727
728 // The id of this instruction in the hydrogen graph, assigned when first
729 // added to the graph. Reflects creation order.
730 int id_;
731
732 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000733 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000734 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000735 Range* range_;
736 int flags_;
737
738 DISALLOW_COPY_AND_ASSIGN(HValue);
739};
740
741
742class HInstruction: public HValue {
743 public:
744 HInstruction* next() const { return next_; }
745 HInstruction* previous() const { return previous_; }
746
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000747 virtual void PrintTo(StringStream* stream);
748 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000749
750 bool IsLinked() const { return block() != NULL; }
751 void Unlink();
752 void InsertBefore(HInstruction* next);
753 void InsertAfter(HInstruction* previous);
754
755 int position() const { return position_; }
756 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
757 void set_position(int position) { position_ = position; }
758
759 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
760
761#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000762 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000763#endif
764
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000765 virtual bool IsCall() { return false; }
766
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000767 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000768
769 protected:
770 HInstruction()
771 : next_(NULL),
772 previous_(NULL),
773 position_(RelocInfo::kNoPosition) {
774 SetFlag(kDependsOnOsrEntries);
775 }
776
777 virtual void DeleteFromGraph() { Unlink(); }
778
779 private:
780 void InitializeAsFirst(HBasicBlock* block) {
781 ASSERT(!IsLinked());
782 SetBlock(block);
783 }
784
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000785 void PrintMnemonicTo(StringStream* stream);
786
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000787 HInstruction* next_;
788 HInstruction* previous_;
789 int position_;
790
791 friend class HBasicBlock;
792};
793
794
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000795template<int V>
796class HTemplateInstruction : public HInstruction {
797 public:
798 int OperandCount() { return V; }
799 HValue* OperandAt(int i) { return inputs_[i]; }
800
801 protected:
802 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
803
804 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000805 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000806};
807
808
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000809class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000810 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000811 virtual HBasicBlock* SuccessorAt(int i) = 0;
812 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000813 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000814
815 virtual void PrintDataTo(StringStream* stream);
816
817 HBasicBlock* FirstSuccessor() {
818 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
819 }
820 HBasicBlock* SecondSuccessor() {
821 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
822 }
823
824 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
825};
826
827
828class HSuccessorIterator BASE_EMBEDDED {
829 public:
830 explicit HSuccessorIterator(HControlInstruction* instr)
831 : instr_(instr), current_(0) { }
832
833 bool Done() { return current_ >= instr_->SuccessorCount(); }
834 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
835 void Advance() { current_++; }
836
837 private:
838 HControlInstruction* instr_;
839 int current_;
840};
841
842
843template<int S, int V>
844class HTemplateControlInstruction: public HControlInstruction {
845 public:
846 int SuccessorCount() { return S; }
847 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000848 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000849
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000850 int OperandCount() { return V; }
851 HValue* OperandAt(int i) { return inputs_[i]; }
852
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000853
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000854 protected:
855 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
856
857 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000858 EmbeddedContainer<HBasicBlock*, S> successors_;
859 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000860};
861
862
863class HBlockEntry: public HTemplateInstruction<0> {
864 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000865 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000866 return Representation::None();
867 }
868
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000869 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000870};
871
872
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000873// We insert soft-deoptimize when we hit code with unknown typefeedback,
874// so that we get a chance of re-optimizing with useful typefeedback.
875// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
876class HSoftDeoptimize: public HTemplateInstruction<0> {
877 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000878 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000879 return Representation::None();
880 }
881
882 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
883};
884
885
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000887 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000888 explicit HDeoptimize(int environment_length) : values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000889
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000890 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000891 return Representation::None();
892 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000893
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000894 virtual int OperandCount() { return values_.length(); }
895 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000896 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000897
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000898 virtual int SuccessorCount() { return 0; }
899 virtual HBasicBlock* SuccessorAt(int i) {
900 UNREACHABLE();
901 return NULL;
902 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000903 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
904 UNREACHABLE();
905 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000906
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000907 void AddEnvironmentValue(HValue* value) {
908 values_.Add(NULL);
909 SetOperandAt(values_.length() - 1, value);
910 }
911
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000912 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000913
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000914 enum UseEnvironment {
915 kNoUses,
916 kUseAll
917 };
918
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000919 protected:
920 virtual void InternalSetOperandAt(int index, HValue* value) {
921 values_[index] = value;
922 }
923
924 private:
925 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926};
927
928
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000929class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930 public:
ager@chromium.org04921a82011-06-27 13:21:41 +0000931 explicit HGoto(HBasicBlock* target) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000932 SetSuccessorAt(0, target);
933 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000935 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000936 return Representation::None();
937 }
938
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000939 virtual void PrintDataTo(StringStream* stream);
940
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000941 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942};
943
944
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000945class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000946 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000947 HUnaryControlInstruction(HValue* value,
948 HBasicBlock* true_target,
949 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000951 SetSuccessorAt(0, true_target);
952 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000953 }
954
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000955 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000957 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958};
959
960
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000961class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000962 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000963 HBranch(HValue* value,
964 HBasicBlock* true_target,
965 HBasicBlock* false_target,
966 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
967 : HUnaryControlInstruction(value, true_target, false_target),
968 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000969 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000970 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000971 explicit HBranch(HValue* value)
972 : HUnaryControlInstruction(value, NULL, NULL) { }
973
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000975 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976 return Representation::None();
977 }
978
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000979 ToBooleanStub::Types expected_input_types() const {
980 return expected_input_types_;
981 }
982
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000983 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000984
985 private:
986 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987};
988
989
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000990class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000991 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000992 HCompareMap(HValue* value,
993 Handle<Map> map,
994 HBasicBlock* true_target,
995 HBasicBlock* false_target)
996 : HUnaryControlInstruction(value, true_target, false_target),
997 map_(map) {
998 ASSERT(true_target != NULL);
999 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000 ASSERT(!map.is_null());
1001 }
1002
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001003 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +00001004
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001005 Handle<Map> map() const { return map_; }
1006
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001007 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001008 return Representation::Tagged();
1009 }
1010
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001011 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001012
1013 private:
1014 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001015};
1016
1017
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001018class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001019 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001020 explicit HReturn(HValue* value) {
1021 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001022 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001023
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001024 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001025 return Representation::Tagged();
1026 }
1027
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001028 virtual void PrintDataTo(StringStream* stream);
1029
1030 HValue* value() { return OperandAt(0); }
1031
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001032 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001033};
1034
1035
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001036class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001037 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001038 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001039 return Representation::None();
1040 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001041
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001042 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001043};
1044
1045
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001046class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001047 public:
1048 explicit HUnaryOperation(HValue* value) {
1049 SetOperandAt(0, value);
1050 }
1051
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001052 static HUnaryOperation* cast(HValue* value) {
1053 return reinterpret_cast<HUnaryOperation*>(value);
1054 }
1055
1056 virtual bool CanTruncateToInt32() const {
1057 return CheckFlag(kTruncatingToInt32);
1058 }
1059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001060 HValue* value() { return OperandAt(0); }
1061 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001062};
1063
1064
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001065class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001066 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001067 HThrow(HValue* context, HValue* value) {
1068 SetOperandAt(0, context);
1069 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001070 SetAllSideEffects();
1071 }
1072
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001073 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001074 return Representation::Tagged();
1075 }
1076
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001077 HValue* context() { return OperandAt(0); }
1078 HValue* value() { return OperandAt(1); }
1079
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001080 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001081};
1082
1083
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001084class HUseConst: public HUnaryOperation {
1085 public:
1086 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1087
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001088 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001089 return Representation::None();
1090 }
1091
1092 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1093};
1094
1095
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001096class HForceRepresentation: public HTemplateInstruction<1> {
1097 public:
1098 HForceRepresentation(HValue* value, Representation required_representation) {
1099 SetOperandAt(0, value);
1100 set_representation(required_representation);
1101 }
1102
1103 HValue* value() { return OperandAt(0); }
1104
1105 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1106
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001107 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001108 return representation(); // Same as the output representation.
1109 }
1110
1111 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1112};
1113
1114
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115class HChange: public HUnaryOperation {
1116 public:
1117 HChange(HValue* value,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001118 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001119 bool is_truncating,
1120 bool deoptimize_on_undefined)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001121 : HUnaryOperation(value) {
1122 ASSERT(!value->representation().IsNone() && !to.IsNone());
1123 ASSERT(!value->representation().Equals(to));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001124 set_representation(to);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001125 set_type(HType::TaggedNumber());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126 SetFlag(kUseGVN);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001127 if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001128 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001129 }
1130
1131 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001132 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001133
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001134 Representation from() { return value()->representation(); }
1135 Representation to() { return representation(); }
1136 bool deoptimize_on_undefined() const {
1137 return CheckFlag(kDeoptimizeOnUndefined);
1138 }
1139 virtual Representation RequiredInputRepresentation(int index) {
1140 return from();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001141 }
1142
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001143 virtual Range* InferRange();
1144
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001145 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001146
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001147 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148
1149 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001150 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001151};
1152
1153
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001154class HClampToUint8: public HUnaryOperation {
1155 public:
1156 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001157 : HUnaryOperation(value) {
1158 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001159 SetFlag(kUseGVN);
1160 }
1161
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001162 virtual Representation RequiredInputRepresentation(int index) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001163 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001164 }
1165
1166 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1167
1168 protected:
1169 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001170};
1171
1172
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001173class HToInt32: public HUnaryOperation {
1174 public:
1175 explicit HToInt32(HValue* value)
1176 : HUnaryOperation(value) {
1177 set_representation(Representation::Integer32());
1178 SetFlag(kUseGVN);
1179 }
1180
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001181 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001182 return Representation::None();
1183 }
1184
1185 virtual bool CanTruncateToInt32() const {
1186 return true;
1187 }
1188
1189 virtual HValue* Canonicalize() {
1190 if (value()->representation().IsInteger32()) {
1191 return value();
1192 } else {
1193 return this;
1194 }
1195 }
1196
1197 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1198
1199 protected:
1200 virtual bool DataEquals(HValue* other) { return true; }
1201};
1202
1203
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001204class HSimulate: public HInstruction {
1205 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001206 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001207 : ast_id_(ast_id),
1208 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001209 values_(2),
1210 assigned_indexes_(2) {}
1211 virtual ~HSimulate() {}
1212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001213 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001214
1215 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1216 int ast_id() const { return ast_id_; }
1217 void set_ast_id(int id) {
1218 ASSERT(!HasAstId());
1219 ast_id_ = id;
1220 }
1221
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001222 int pop_count() const { return pop_count_; }
1223 const ZoneList<HValue*>* values() const { return &values_; }
1224 int GetAssignedIndexAt(int index) const {
1225 ASSERT(HasAssignedIndexAt(index));
1226 return assigned_indexes_[index];
1227 }
1228 bool HasAssignedIndexAt(int index) const {
1229 return assigned_indexes_[index] != kNoIndex;
1230 }
1231 void AddAssignedValue(int index, HValue* value) {
1232 AddValue(index, value);
1233 }
1234 void AddPushedValue(HValue* value) {
1235 AddValue(kNoIndex, value);
1236 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001237 virtual int OperandCount() { return values_.length(); }
1238 virtual HValue* OperandAt(int index) { return values_[index]; }
1239
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001240 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001241 return Representation::None();
1242 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001243
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001244 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001245
1246#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001247 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001248#endif
1249
1250 protected:
1251 virtual void InternalSetOperandAt(int index, HValue* value) {
1252 values_[index] = value;
1253 }
1254
1255 private:
1256 static const int kNoIndex = -1;
1257 void AddValue(int index, HValue* value) {
1258 assigned_indexes_.Add(index);
1259 // Resize the list of pushed values.
1260 values_.Add(NULL);
1261 // Set the operand through the base method in HValue to make sure that the
1262 // use lists are correctly updated.
1263 SetOperandAt(values_.length() - 1, value);
1264 }
1265 int ast_id_;
1266 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001267 ZoneList<HValue*> values_;
1268 ZoneList<int> assigned_indexes_;
1269};
1270
1271
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001272class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001273 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001274 enum Type {
1275 kFunctionEntry,
1276 kBackwardsBranch
1277 };
1278
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001279 HStackCheck(HValue* context, Type type) : type_(type) {
1280 SetOperandAt(0, context);
1281 }
1282
1283 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001284
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001285 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001286 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001287 }
1288
ager@chromium.org04921a82011-06-27 13:21:41 +00001289 void Eliminate() {
1290 // The stack check eliminator might try to eliminate the same stack
1291 // check instruction multiple times.
1292 if (IsLinked()) {
1293 DeleteFromGraph();
1294 }
1295 }
1296
1297 bool is_function_entry() { return type_ == kFunctionEntry; }
1298 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1299
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001300 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001301
1302 private:
1303 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001304};
1305
1306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001309 HEnterInlined(Handle<JSFunction> closure,
1310 FunctionLiteral* function,
1311 CallKind call_kind)
1312 : closure_(closure),
1313 function_(function),
1314 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001315 }
1316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001317 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318
1319 Handle<JSFunction> closure() const { return closure_; }
1320 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001321 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001322
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001323 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324 return Representation::None();
1325 }
1326
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001327 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328
1329 private:
1330 Handle<JSFunction> closure_;
1331 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001332 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001333};
1334
1335
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001336class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001337 public:
1338 HLeaveInlined() {}
1339
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001340 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001341 return Representation::None();
1342 }
1343
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001344 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345};
1346
1347
1348class HPushArgument: public HUnaryOperation {
1349 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001350 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1351 set_representation(Representation::Tagged());
1352 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001353
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001354 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 return Representation::Tagged();
1356 }
1357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001358 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001359
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001360 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001361};
1362
1363
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001364class HThisFunction: public HTemplateInstruction<0> {
1365 public:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001366 explicit HThisFunction(Handle<JSFunction> closure) : closure_(closure) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001367 set_representation(Representation::Tagged());
1368 SetFlag(kUseGVN);
1369 }
1370
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001371 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001372 return Representation::None();
1373 }
1374
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001375 Handle<JSFunction> closure() const { return closure_; }
1376
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001377 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1378
1379 protected:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001380 virtual bool DataEquals(HValue* other) {
1381 HThisFunction* b = HThisFunction::cast(other);
1382 return *closure() == *b->closure();
1383 }
1384
1385 private:
1386 Handle<JSFunction> closure_;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001387};
1388
1389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001391 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001392 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001393 set_representation(Representation::Tagged());
1394 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001395 }
1396
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001397 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001398 return Representation::None();
1399 }
1400
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001401 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001402
1403 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001405};
1406
1407
1408class HOuterContext: public HUnaryOperation {
1409 public:
1410 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1411 set_representation(Representation::Tagged());
1412 SetFlag(kUseGVN);
1413 }
1414
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001415 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001416
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001417 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001418 return Representation::Tagged();
1419 }
1420
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001422 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001423};
1424
1425
1426class HGlobalObject: public HUnaryOperation {
1427 public:
1428 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1429 set_representation(Representation::Tagged());
1430 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001431 }
1432
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001433 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001434
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001435 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001436 return Representation::Tagged();
1437 }
1438
ager@chromium.org378b34e2011-01-28 08:04:38 +00001439 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001440 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441};
1442
1443
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001444class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001445 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001446 explicit HGlobalReceiver(HValue* global_object)
1447 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001448 set_representation(Representation::Tagged());
1449 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450 }
1451
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001452 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001453
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001454 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001455 return Representation::Tagged();
1456 }
1457
ager@chromium.org378b34e2011-01-28 08:04:38 +00001458 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001459 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001460};
1461
1462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001463template <int V>
1464class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001465 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001466 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001467 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1468 this->set_representation(Representation::Tagged());
1469 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001470 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001472 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001473
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001474 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001478 private:
1479 int argument_count_;
1480};
1481
1482
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001483class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001484 public:
1485 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001486 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001487 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001488 }
1489
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001490 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001491 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001492 }
1493
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001494 virtual void PrintDataTo(StringStream* stream);
1495
1496 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001497};
1498
1499
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001500class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001501 public:
1502 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001503 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001504 SetOperandAt(0, first);
1505 SetOperandAt(1, second);
1506 }
1507
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001508 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001509
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001510 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001511 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001512 }
1513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001514 HValue* first() { return OperandAt(0); }
1515 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516};
1517
1518
danno@chromium.org160a7b02011-04-18 15:51:38 +00001519class HInvokeFunction: public HBinaryCall {
1520 public:
1521 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1522 : HBinaryCall(context, function, argument_count) {
1523 }
1524
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001525 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001526 return Representation::Tagged();
1527 }
1528
1529 HValue* context() { return first(); }
1530 HValue* function() { return second(); }
1531
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001532 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001533};
1534
1535
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001536class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537 public:
1538 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001539 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001540
1541 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001542
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001543 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001544 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001545 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001546 }
1547
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001548 virtual void PrintDataTo(StringStream* stream);
1549
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001550 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001551 return Representation::None();
1552 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001553
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001554 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555
1556 private:
1557 Handle<JSFunction> function_;
1558};
1559
1560
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001561class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001562 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001563 HCallKeyed(HValue* context, HValue* key, int argument_count)
1564 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001565 }
1566
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001567 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001568 return Representation::Tagged();
1569 }
1570
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001571 HValue* context() { return first(); }
1572 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001573
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001574 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001575};
1576
1577
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001578class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001579 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001580 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1581 : HUnaryCall(context, argument_count), name_(name) {
1582 }
1583
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001584 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001586 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587 Handle<String> name() const { return name_; }
1588
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001589 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001590
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001591 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001592 return Representation::Tagged();
1593 }
1594
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595 private:
1596 Handle<String> name_;
1597};
1598
1599
danno@chromium.orgc612e022011-11-10 11:38:15 +00001600class HCallFunction: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +00001602 HCallFunction(HValue* context, HValue* function, int argument_count)
1603 : HBinaryCall(context, function, argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001604 }
1605
danno@chromium.orgc612e022011-11-10 11:38:15 +00001606 HValue* context() { return first(); }
1607 HValue* function() { return second(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001608
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001609 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001610 return Representation::Tagged();
1611 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001613 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614};
1615
1616
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001617class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001619 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1620 : HUnaryCall(context, argument_count), name_(name) {
1621 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001622
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001625 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001626 Handle<String> name() const { return name_; }
1627
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001628 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001629 return Representation::Tagged();
1630 }
1631
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001632 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633
1634 private:
1635 Handle<String> name_;
1636};
1637
1638
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001639class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001640 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001641 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001642 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001644 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001645
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646 Handle<JSFunction> target() const { return target_; }
1647
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001648 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001649 return Representation::None();
1650 }
1651
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001652 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001653
1654 private:
1655 Handle<JSFunction> target_;
1656};
1657
1658
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001659class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001661 HCallNew(HValue* context, HValue* constructor, int argument_count)
1662 : HBinaryCall(context, constructor, argument_count) {
1663 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001664
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001665 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001666 return Representation::Tagged();
1667 }
1668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001669 HValue* context() { return first(); }
1670 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001672 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001673};
1674
1675
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001676class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001677 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001678 HCallRuntime(HValue* context,
1679 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001680 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001681 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001682 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1683 SetOperandAt(0, context);
1684 }
1685
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001686 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001687
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001688 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001689 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001690 Handle<String> name() const { return name_; }
1691
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001692 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001693 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001694 }
1695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001696 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001697
1698 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001699 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001700 Handle<String> name_;
1701};
1702
1703
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001704class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001705 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001706 HJSArrayLength(HValue* value, HValue* typecheck) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707 // The length of an array is stored as a tagged value in the array
1708 // object. It is guaranteed to be 32 bit integer, but it can be
1709 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001710 SetOperandAt(0, value);
1711 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001712 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001714 SetFlag(kDependsOnArrayLengths);
1715 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001716 }
1717
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001718 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001719 return Representation::Tagged();
1720 }
1721
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001722 virtual void PrintDataTo(StringStream* stream);
1723
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001724 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001725 HValue* typecheck() { return OperandAt(1); }
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001726
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001727 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001728
1729 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001730 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001731};
1732
1733
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001734class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001735 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001736 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001737 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001738 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001739 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001740 }
1741
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001742 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001743 return Representation::Tagged();
1744 }
1745
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001746 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001747
1748 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001749 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001750};
1751
1752
whesse@chromium.org7b260152011-06-20 15:33:18 +00001753class HElementsKind: public HUnaryOperation {
1754 public:
1755 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1756 set_representation(Representation::Integer32());
1757 SetFlag(kUseGVN);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001758 SetFlag(kDependsOnElementsKind);
whesse@chromium.org7b260152011-06-20 15:33:18 +00001759 }
1760
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001761 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00001762 return Representation::Tagged();
1763 }
1764
1765 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1766
1767 protected:
1768 virtual bool DataEquals(HValue* other) { return true; }
1769};
1770
1771
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001772class HBitNot: public HUnaryOperation {
1773 public:
1774 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1775 set_representation(Representation::Integer32());
1776 SetFlag(kUseGVN);
1777 SetFlag(kTruncatingToInt32);
1778 }
1779
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001780 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001781 return Representation::Integer32();
1782 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001783 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001784
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001785 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001786
1787 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001788 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001789};
1790
1791
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001792class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001794 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1795 : op_(op) {
1796 SetOperandAt(0, context);
1797 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001798 switch (op) {
1799 case kMathFloor:
1800 case kMathRound:
1801 case kMathCeil:
1802 set_representation(Representation::Integer32());
1803 break;
1804 case kMathAbs:
1805 set_representation(Representation::Tagged());
1806 SetFlag(kFlexibleRepresentation);
1807 break;
1808 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001809 case kMathPowHalf:
1810 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001811 case kMathSin:
1812 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001813 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001814 break;
1815 default:
1816 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817 }
1818 SetFlag(kUseGVN);
1819 }
1820
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001821 HValue* context() { return OperandAt(0); }
1822 HValue* value() { return OperandAt(1); }
1823
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001824 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001826 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001827
1828 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1829
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001830 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001831 if (index == 0) {
1832 return Representation::Tagged();
1833 } else {
1834 switch (op_) {
1835 case kMathFloor:
1836 case kMathRound:
1837 case kMathCeil:
1838 case kMathSqrt:
1839 case kMathPowHalf:
1840 case kMathLog:
1841 case kMathSin:
1842 case kMathCos:
1843 return Representation::Double();
1844 case kMathAbs:
1845 return representation();
1846 default:
1847 UNREACHABLE();
1848 return Representation::None();
1849 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850 }
1851 }
1852
1853 virtual HValue* Canonicalize() {
1854 // If the input is integer32 then we replace the floor instruction
1855 // with its inputs. This happens before the representation changes are
1856 // introduced.
1857 if (op() == kMathFloor) {
1858 if (value()->representation().IsInteger32()) return value();
1859 }
1860 return this;
1861 }
1862
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001863 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001864 const char* OpName() const;
1865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001866 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001868 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001869 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001870 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1871 return op_ == b->op();
1872 }
1873
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001874 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001875 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001876};
1877
1878
1879class HLoadElements: public HUnaryOperation {
1880 public:
1881 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1882 set_representation(Representation::Tagged());
1883 SetFlag(kUseGVN);
1884 SetFlag(kDependsOnMaps);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001885 SetFlag(kDependsOnElementsKind);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001886 }
1887
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001888 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001889 return Representation::Tagged();
1890 }
1891
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001892 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001893
1894 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001895 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001896};
1897
1898
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001899class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001900 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001901 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001902 : HUnaryOperation(value) {
1903 set_representation(Representation::External());
1904 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001905 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001906 // change once set, so it's no necessary to introduce any additional
1907 // dependencies on top of the inputs.
1908 SetFlag(kUseGVN);
1909 }
1910
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001911 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001912 return Representation::Tagged();
1913 }
1914
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001915 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001916
1917 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001918 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001919};
1920
1921
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001922class HCheckMap: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001923 public:
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001924 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
1925 : map_(map) {
1926 SetOperandAt(0, value);
1927 // If callers don't depend on a typecheck, they can pass in NULL. In that
1928 // case we use a copy of the |value| argument as a dummy value.
1929 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930 set_representation(Representation::Tagged());
1931 SetFlag(kUseGVN);
1932 SetFlag(kDependsOnMaps);
1933 }
1934
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001935 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001936 return Representation::Tagged();
1937 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001938 virtual void PrintDataTo(StringStream* stream);
1939 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001940
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001941 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001942 Handle<Map> map() const { return map_; }
1943
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001944 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001945
1946 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001947 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001948 HCheckMap* b = HCheckMap::cast(other);
1949 return map_.is_identical_to(b->map());
1950 }
1951
1952 private:
1953 Handle<Map> map_;
1954};
1955
1956
1957class HCheckFunction: public HUnaryOperation {
1958 public:
1959 HCheckFunction(HValue* value, Handle<JSFunction> function)
1960 : HUnaryOperation(value), target_(function) {
1961 set_representation(Representation::Tagged());
1962 SetFlag(kUseGVN);
1963 }
1964
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001965 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966 return Representation::Tagged();
1967 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001968 virtual void PrintDataTo(StringStream* stream);
1969 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001970
1971#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001972 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001973#endif
1974
1975 Handle<JSFunction> target() const { return target_; }
1976
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001977 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001978
1979 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001980 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001981 HCheckFunction* b = HCheckFunction::cast(other);
1982 return target_.is_identical_to(b->target());
1983 }
1984
1985 private:
1986 Handle<JSFunction> target_;
1987};
1988
1989
1990class HCheckInstanceType: public HUnaryOperation {
1991 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001992 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1993 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001994 }
1995 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1996 return new HCheckInstanceType(value, IS_JS_ARRAY);
1997 }
1998 static HCheckInstanceType* NewIsString(HValue* value) {
1999 return new HCheckInstanceType(value, IS_STRING);
2000 }
2001 static HCheckInstanceType* NewIsSymbol(HValue* value) {
2002 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002003 }
2004
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002005 virtual void PrintDataTo(StringStream* stream);
2006
2007 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002008 return Representation::Tagged();
2009 }
2010
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002011 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002012
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002013 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2014 void GetCheckInterval(InstanceType* first, InstanceType* last);
2015 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002016
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002017 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002018
2019 protected:
2020 // TODO(ager): It could be nice to allow the ommision of instance
2021 // type checks if we have already performed an instance type check
2022 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002023 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002024 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002025 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002026 }
2027
2028 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002029 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002030 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002031 IS_JS_ARRAY,
2032 IS_STRING,
2033 IS_SYMBOL,
2034 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2035 };
2036
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002037 const char* GetCheckName();
2038
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002039 HCheckInstanceType(HValue* value, Check check)
2040 : HUnaryOperation(value), check_(check) {
2041 set_representation(Representation::Tagged());
2042 SetFlag(kUseGVN);
2043 }
2044
2045 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002046};
2047
2048
2049class HCheckNonSmi: public HUnaryOperation {
2050 public:
2051 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2052 set_representation(Representation::Tagged());
2053 SetFlag(kUseGVN);
2054 }
2055
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002056 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057 return Representation::Tagged();
2058 }
2059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002060 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002061
2062#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002063 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064#endif
2065
danno@chromium.org160a7b02011-04-18 15:51:38 +00002066 virtual HValue* Canonicalize() {
2067 HType value_type = value()->type();
2068 if (!value_type.IsUninitialized() &&
2069 (value_type.IsHeapNumber() ||
2070 value_type.IsString() ||
2071 value_type.IsBoolean() ||
2072 value_type.IsNonPrimitive())) {
2073 return NULL;
2074 }
2075 return this;
2076 }
2077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002078 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002079
2080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002081 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082};
2083
2084
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002085class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002086 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002087 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2088 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002089 SetFlag(kUseGVN);
2090 SetFlag(kDependsOnMaps);
2091 }
2092
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002093#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002094 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095#endif
2096
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002097 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002098 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002100 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002101
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002102 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002103 return Representation::None();
2104 }
2105
2106 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002107 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002108 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2109 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2110 return hash;
2111 }
2112
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002113 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002114 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002116 return prototype_.is_identical_to(b->prototype()) &&
2117 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002118 }
2119
2120 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002121 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123};
2124
2125
2126class HCheckSmi: public HUnaryOperation {
2127 public:
2128 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2129 set_representation(Representation::Tagged());
2130 SetFlag(kUseGVN);
2131 }
2132
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002133 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002134 return Representation::Tagged();
2135 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002136 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002137
2138#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002139 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002140#endif
2141
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002142 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002143
2144 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002145 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002146};
2147
2148
2149class HPhi: public HValue {
2150 public:
2151 explicit HPhi(int merged_index)
2152 : inputs_(2),
2153 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002154 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002155 is_live_(false),
2156 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002157 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2158 non_phi_uses_[i] = 0;
2159 indirect_uses_[i] = 0;
2160 }
2161 ASSERT(merged_index >= 0);
2162 set_representation(Representation::Tagged());
2163 SetFlag(kFlexibleRepresentation);
2164 }
2165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002166 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002167 bool double_occurred = false;
2168 bool int32_occurred = false;
2169 for (int i = 0; i < OperandCount(); ++i) {
2170 HValue* value = OperandAt(i);
2171 if (value->representation().IsDouble()) double_occurred = true;
2172 if (value->representation().IsInteger32()) int32_occurred = true;
2173 if (value->representation().IsTagged()) return Representation::Tagged();
2174 }
2175
2176 if (double_occurred) return Representation::Double();
2177 if (int32_occurred) return Representation::Integer32();
2178 return Representation::None();
2179 }
2180
2181 virtual Range* InferRange();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002182 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002183 return representation();
2184 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002185 virtual HType CalculateInferredType();
2186 virtual int OperandCount() { return inputs_.length(); }
2187 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2188 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002189 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002190 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002192 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002193
2194 int merged_index() const { return merged_index_; }
2195
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002196 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002197
2198#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002199 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002200#endif
2201
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002202 void InitRealUses(int id);
2203 void AddNonPhiUsesFrom(HPhi* other);
2204 void AddIndirectUsesTo(int* use_count);
2205
2206 int tagged_non_phi_uses() const {
2207 return non_phi_uses_[Representation::kTagged];
2208 }
2209 int int32_non_phi_uses() const {
2210 return non_phi_uses_[Representation::kInteger32];
2211 }
2212 int double_non_phi_uses() const {
2213 return non_phi_uses_[Representation::kDouble];
2214 }
2215 int tagged_indirect_uses() const {
2216 return indirect_uses_[Representation::kTagged];
2217 }
2218 int int32_indirect_uses() const {
2219 return indirect_uses_[Representation::kInteger32];
2220 }
2221 int double_indirect_uses() const {
2222 return indirect_uses_[Representation::kDouble];
2223 }
2224 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002225 bool is_live() { return is_live_; }
2226 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002228 static HPhi* cast(HValue* value) {
2229 ASSERT(value->IsPhi());
2230 return reinterpret_cast<HPhi*>(value);
2231 }
2232 virtual Opcode opcode() const { return HValue::kPhi; }
2233
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002234 virtual bool IsConvertibleToInteger() const {
2235 return is_convertible_to_integer_;
2236 }
2237
2238 void set_is_convertible_to_integer(bool b) {
2239 is_convertible_to_integer_ = b;
2240 }
2241
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002242 bool AllOperandsConvertibleToInteger() {
2243 for (int i = 0; i < OperandCount(); ++i) {
2244 if (!OperandAt(i)->IsConvertibleToInteger()) return false;
2245 }
2246 return true;
2247 }
2248
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002249 protected:
2250 virtual void DeleteFromGraph();
2251 virtual void InternalSetOperandAt(int index, HValue* value) {
2252 inputs_[index] = value;
2253 }
2254
2255 private:
2256 ZoneList<HValue*> inputs_;
2257 int merged_index_;
2258
2259 int non_phi_uses_[Representation::kNumRepresentations];
2260 int indirect_uses_[Representation::kNumRepresentations];
2261 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002262 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002263 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002264};
2265
2266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002267class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002268 public:
2269 HArgumentsObject() {
2270 set_representation(Representation::Tagged());
2271 SetFlag(kIsArguments);
2272 }
2273
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002274 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002275 return Representation::None();
2276 }
2277
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002278 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002279};
2280
2281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002282class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002283 public:
2284 HConstant(Handle<Object> handle, Representation r);
2285
2286 Handle<Object> handle() const { return handle_; }
2287
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002288 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002289
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002290 bool ImmortalImmovable() const {
2291 Heap* heap = HEAP;
2292 if (*handle_ == heap->undefined_value()) return true;
2293 if (*handle_ == heap->null_value()) return true;
2294 if (*handle_ == heap->true_value()) return true;
2295 if (*handle_ == heap->false_value()) return true;
2296 if (*handle_ == heap->the_hole_value()) return true;
2297 if (*handle_ == heap->minus_zero_value()) return true;
2298 if (*handle_ == heap->nan_value()) return true;
2299 if (*handle_ == heap->empty_string()) return true;
2300 return false;
2301 }
2302
2303 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002304 return Representation::None();
2305 }
2306
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002307 virtual bool IsConvertibleToInteger() const {
2308 if (handle_->IsSmi()) return true;
2309 if (handle_->IsHeapNumber() &&
2310 (HeapNumber::cast(*handle_)->value() ==
2311 static_cast<double>(NumberToInt32(*handle_)))) return true;
2312 return false;
2313 }
2314
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002315 virtual bool EmitAtUses() { return !representation().IsDouble(); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002316 virtual HValue* Canonicalize();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002317 virtual void PrintDataTo(StringStream* stream);
2318 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319 bool IsInteger() const { return handle_->IsSmi(); }
2320 HConstant* CopyToRepresentation(Representation r) const;
2321 HConstant* CopyToTruncatedInt32() const;
2322 bool HasInteger32Value() const { return has_int32_value_; }
2323 int32_t Integer32Value() const {
2324 ASSERT(HasInteger32Value());
2325 return int32_value_;
2326 }
2327 bool HasDoubleValue() const { return has_double_value_; }
2328 double DoubleValue() const {
2329 ASSERT(HasDoubleValue());
2330 return double_value_;
2331 }
erikcorry0ad885c2011-11-21 13:51:57 +00002332 bool HasNumberValue() const { return has_int32_value_ || has_double_value_; }
2333 int32_t NumberValueAsInteger32() const {
2334 ASSERT(HasNumberValue());
2335 if (has_int32_value_) return int32_value_;
2336 return DoubleToInt32(double_value_);
2337 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338 bool HasStringValue() const { return handle_->IsString(); }
2339
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002340 bool ToBoolean() const;
2341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002342 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002343 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002344 return reinterpret_cast<intptr_t>(*handle());
2345 }
2346
2347#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002348 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002349#endif
2350
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002351 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002352
2353 protected:
2354 virtual Range* InferRange();
2355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002356 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002357 HConstant* other_constant = HConstant::cast(other);
2358 return handle().is_identical_to(other_constant->handle());
2359 }
2360
2361 private:
2362 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363
2364 // The following two values represent the int32 and the double value of the
2365 // given constant if there is a lossless conversion between the constant
2366 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002367 bool has_int32_value_ : 1;
2368 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002370 double double_value_;
2371};
2372
2373
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002374class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002375 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002376 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002378 SetOperandAt(0, context);
2379 SetOperandAt(1, left);
2380 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002381 }
2382
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002383 HValue* context() { return OperandAt(0); }
2384 HValue* left() { return OperandAt(1); }
2385 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002386
2387 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2388 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002389 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002390 if (IsCommutative() && left()->IsConstant()) return right();
2391 return left();
2392 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002393 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002394 if (IsCommutative() && left()->IsConstant()) return left();
2395 return right();
2396 }
2397
2398 virtual bool IsCommutative() const { return false; }
2399
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002400 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002401};
2402
2403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002404class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002405 public:
2406 HApplyArguments(HValue* function,
2407 HValue* receiver,
2408 HValue* length,
2409 HValue* elements) {
2410 set_representation(Representation::Tagged());
2411 SetOperandAt(0, function);
2412 SetOperandAt(1, receiver);
2413 SetOperandAt(2, length);
2414 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002415 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002416 }
2417
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002418 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002419 // The length is untagged, all other inputs are tagged.
2420 return (index == 2)
2421 ? Representation::Integer32()
2422 : Representation::Tagged();
2423 }
2424
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002425 HValue* function() { return OperandAt(0); }
2426 HValue* receiver() { return OperandAt(1); }
2427 HValue* length() { return OperandAt(2); }
2428 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002429
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002430 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002431};
2432
2433
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002434class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002435 public:
2436 HArgumentsElements() {
2437 // The value produced by this instruction is a pointer into the stack
2438 // that looks as if it was a smi because of alignment.
2439 set_representation(Representation::Tagged());
2440 SetFlag(kUseGVN);
2441 }
2442
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002443 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002444
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002445 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002446 return Representation::None();
2447 }
2448
ager@chromium.org378b34e2011-01-28 08:04:38 +00002449 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002450 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002451};
2452
2453
2454class HArgumentsLength: public HUnaryOperation {
2455 public:
2456 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2457 set_representation(Representation::Integer32());
2458 SetFlag(kUseGVN);
2459 }
2460
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002461 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002462 return Representation::Tagged();
2463 }
2464
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002465 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002466
2467 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002468 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002469};
2470
2471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002472class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002473 public:
2474 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2475 set_representation(Representation::Tagged());
2476 SetFlag(kUseGVN);
2477 SetOperandAt(0, arguments);
2478 SetOperandAt(1, length);
2479 SetOperandAt(2, index);
2480 }
2481
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002482 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002483
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002484 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002485 // The arguments elements is considered tagged.
2486 return index == 0
2487 ? Representation::Tagged()
2488 : Representation::Integer32();
2489 }
2490
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002491 HValue* arguments() { return OperandAt(0); }
2492 HValue* length() { return OperandAt(1); }
2493 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002494
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002495 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002497 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002498};
2499
2500
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002501class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002502 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002503 HBoundsCheck(HValue* index, HValue* length) {
2504 SetOperandAt(0, index);
2505 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002506 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002507 SetFlag(kUseGVN);
2508 }
2509
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002510 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002511 return Representation::Integer32();
2512 }
2513
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002514 virtual void PrintDataTo(StringStream* stream);
2515
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002516 HValue* index() { return OperandAt(0); }
2517 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002518
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002519 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002520
2521 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002522 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002523};
2524
2525
2526class HBitwiseBinaryOperation: public HBinaryOperation {
2527 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002528 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2529 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002530 set_representation(Representation::Tagged());
2531 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002532 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002533 }
2534
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002535 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002536 return index == 0
2537 ? Representation::Tagged()
2538 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002539 }
2540
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002541 virtual void RepresentationChanged(Representation to) {
2542 if (!to.IsTagged()) {
2543 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002544 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002545 SetFlag(kTruncatingToInt32);
2546 SetFlag(kUseGVN);
2547 }
2548 }
2549
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002550 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002551
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002552 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553};
2554
2555
2556class HArithmeticBinaryOperation: public HBinaryOperation {
2557 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002558 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2559 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560 set_representation(Representation::Tagged());
2561 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002562 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002563 }
2564
2565 virtual void RepresentationChanged(Representation to) {
2566 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002567 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002568 SetFlag(kUseGVN);
2569 }
2570 }
2571
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002572 virtual HType CalculateInferredType();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002573 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002574 return index == 0
2575 ? Representation::Tagged()
2576 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002577 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002579 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002580 if (left()->representation().Equals(right()->representation())) {
2581 return left()->representation();
2582 }
2583 return HValue::InferredRepresentation();
2584 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585};
2586
2587
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002588class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002589 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002590 HCompareGeneric(HValue* context,
2591 HValue* left,
2592 HValue* right,
2593 Token::Value token)
2594 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002595 ASSERT(Token::IsCompareOp(token));
2596 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002597 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002598 }
2599
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002600 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002601 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002602 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002603
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002605 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002607
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002608 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002609 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002610
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002611 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002612
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002613 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2614
2615 private:
2616 Token::Value token_;
2617};
2618
2619
2620class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2621 public:
2622 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2623 : token_(token) {
2624 ASSERT(Token::IsCompareOp(token));
2625 SetOperandAt(0, left);
2626 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002627 }
2628
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002629 HValue* left() { return OperandAt(0); }
2630 HValue* right() { return OperandAt(1); }
2631 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002632
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002633 void SetInputRepresentation(Representation r);
2634 Representation GetInputRepresentation() const {
2635 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002636 }
2637
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002638 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002639 return input_representation_;
2640 }
2641 virtual void PrintDataTo(StringStream* stream);
2642
2643 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2644
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002645 private:
2646 Representation input_representation_;
2647 Token::Value token_;
2648};
2649
2650
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002651class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002652 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002653 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2654 SetOperandAt(0, left);
2655 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002656 }
2657
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002658 HValue* left() { return OperandAt(0); }
2659 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002660
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002661 virtual void PrintDataTo(StringStream* stream);
2662
2663 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002664 return Representation::Tagged();
2665 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002666
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002667 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002668};
2669
2670
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002671class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002672 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002673 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2674 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002675 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002676 }
2677
2678 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002679 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002680 int right() const { return right_; }
2681
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002682 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002683 return Representation::Integer32();
2684 }
2685
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002686 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002687
2688 private:
2689 const Token::Value op_;
2690 const int right_;
2691};
2692
2693
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002694class HIsNilAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002695 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002696 HIsNilAndBranch(HValue* value, EqualityKind kind, NilValue nil)
2697 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002698
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002699 EqualityKind kind() const { return kind_; }
2700 NilValue nil() const { return nil_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002701
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002702 virtual void PrintDataTo(StringStream* stream);
2703
2704 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002705 return Representation::Tagged();
2706 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002708 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002709
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002710 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002711 EqualityKind kind_;
2712 NilValue nil_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002713};
2714
2715
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002716class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002717 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002718 explicit HIsObjectAndBranch(HValue* value)
2719 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002720
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002721 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002722 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002723 }
2724
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002725 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2726};
2727
erikcorry0ad885c2011-11-21 13:51:57 +00002728class HIsStringAndBranch: public HUnaryControlInstruction {
2729 public:
2730 explicit HIsStringAndBranch(HValue* value)
2731 : HUnaryControlInstruction(value, NULL, NULL) { }
2732
2733 virtual Representation RequiredInputRepresentation(int index) {
2734 return Representation::Tagged();
2735 }
2736
2737 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
2738};
2739
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002740
2741class HIsSmiAndBranch: public HUnaryControlInstruction {
2742 public:
2743 explicit HIsSmiAndBranch(HValue* value)
2744 : HUnaryControlInstruction(value, NULL, NULL) { }
2745
2746 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2747
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002748 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002749 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002750 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002751
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002752 protected:
2753 virtual bool DataEquals(HValue* other) { return true; }
2754};
2755
2756
2757class HIsUndetectableAndBranch: public HUnaryControlInstruction {
2758 public:
2759 explicit HIsUndetectableAndBranch(HValue* value)
2760 : HUnaryControlInstruction(value, NULL, NULL) { }
2761
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002762 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002763 return Representation::Tagged();
2764 }
2765
2766 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
2767};
2768
2769
erikcorry0ad885c2011-11-21 13:51:57 +00002770class HStringCompareAndBranch: public HTemplateControlInstruction<2, 3> {
2771 public:
2772 HStringCompareAndBranch(HValue* context,
2773 HValue* left,
2774 HValue* right,
2775 Token::Value token)
2776 : token_(token) {
2777 ASSERT(Token::IsCompareOp(token));
2778 SetOperandAt(0, context);
2779 SetOperandAt(1, left);
2780 SetOperandAt(2, right);
2781 set_representation(Representation::Tagged());
2782 }
2783
2784 HValue* context() { return OperandAt(0); }
2785 HValue* left() { return OperandAt(1); }
2786 HValue* right() { return OperandAt(2); }
2787 Token::Value token() const { return token_; }
2788
2789 virtual void PrintDataTo(StringStream* stream);
2790
2791 virtual Representation RequiredInputRepresentation(int index) {
2792 return Representation::Tagged();
2793 }
2794
2795 Representation GetInputRepresentation() const {
2796 return Representation::Tagged();
2797 }
2798
2799 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
2800
2801 private:
2802 Token::Value token_;
2803};
2804
2805
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002806class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
2807 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002808 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002809 return Representation::None();
2810 }
2811
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002812 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002813};
2814
2815
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002816class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002818 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
2819 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
2820 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
2821 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002822 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2823 }
2824
2825 InstanceType from() { return from_; }
2826 InstanceType to() { return to_; }
2827
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002828 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002829
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002830 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002831 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002832 }
2833
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002834 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
2835
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836 private:
2837 InstanceType from_;
2838 InstanceType to_; // Inclusive range, not all combinations work.
2839};
2840
2841
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002842class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002843 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002844 explicit HHasCachedArrayIndexAndBranch(HValue* value)
2845 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002847 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002848 return Representation::Tagged();
2849 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002850
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002851 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002852};
2853
2854
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002855class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002856 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002857 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
2858 set_representation(Representation::Tagged());
2859 SetFlag(kUseGVN);
2860 }
2861
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002862 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00002863 return Representation::Tagged();
2864 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002866 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002867
2868 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002869 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002870};
2871
2872
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002873class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002874 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002875 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
2876 : HUnaryControlInstruction(value, NULL, NULL),
2877 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002878
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002879 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
2880
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002881 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002882 return Representation::Tagged();
2883 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002884
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002885 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002886
2887 Handle<String> class_name() const { return class_name_; }
2888
2889 private:
2890 Handle<String> class_name_;
2891};
2892
2893
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002894class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002896 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
2897 : HUnaryControlInstruction(value, NULL, NULL),
2898 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899
2900 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002901 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002903 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002904
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002905 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002906 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907 }
2908
2909 private:
2910 Handle<String> type_literal_;
2911};
2912
2913
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002914class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002915 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002916 HInstanceOf(HValue* context, HValue* left, HValue* right)
2917 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002918 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002919 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920 }
2921
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002922 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923 return Representation::Tagged();
2924 }
2925
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002926 virtual HType CalculateInferredType();
2927
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002928 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002929
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002930 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931};
2932
2933
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002934class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002935 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002936 HInstanceOfKnownGlobal(HValue* context,
2937 HValue* left,
2938 Handle<JSFunction> right)
2939 : function_(right) {
2940 SetOperandAt(0, context);
2941 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002942 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002943 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002944 }
2945
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002946 HValue* context() { return OperandAt(0); }
2947 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002948 Handle<JSFunction> function() { return function_; }
2949
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002950 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002951 return Representation::Tagged();
2952 }
2953
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002954 virtual HType CalculateInferredType();
2955
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002956 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002957
2958 private:
2959 Handle<JSFunction> function_;
2960};
2961
2962
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002963class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002964 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002965 HPower(HValue* left, HValue* right) {
2966 SetOperandAt(0, left);
2967 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002968 set_representation(Representation::Double());
2969 SetFlag(kUseGVN);
2970 }
2971
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002972 HValue* left() { return OperandAt(0); }
2973 HValue* right() { return OperandAt(1); }
2974
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002975 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002976 return index == 0
2977 ? Representation::Double()
2978 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002979 }
2980
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002981 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002982
2983 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002984 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002985};
2986
2987
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002988class HAdd: public HArithmeticBinaryOperation {
2989 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002990 HAdd(HValue* context, HValue* left, HValue* right)
2991 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992 SetFlag(kCanOverflow);
2993 }
2994
2995 // Add is only commutative if two integer values are added and not if two
2996 // tagged values are added (because it might be a String concatenation).
2997 virtual bool IsCommutative() const {
2998 return !representation().IsTagged();
2999 }
3000
3001 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3002
erikcorry0ad885c2011-11-21 13:51:57 +00003003 static HInstruction* NewHAdd(Zone* zone,
3004 HValue* context,
3005 HValue* left,
3006 HValue* right);
3007
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003008 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003010 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011
3012 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003013 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003014
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015 virtual Range* InferRange();
3016};
3017
3018
3019class HSub: public HArithmeticBinaryOperation {
3020 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003021 HSub(HValue* context, HValue* left, HValue* right)
3022 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023 SetFlag(kCanOverflow);
3024 }
3025
3026 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3027
erikcorry0ad885c2011-11-21 13:51:57 +00003028 static HInstruction* NewHSub(Zone* zone,
3029 HValue* context,
3030 HValue* left,
3031 HValue* right);
3032
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003033 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003034
3035 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003036 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003037
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003038 virtual Range* InferRange();
3039};
3040
3041
3042class HMul: public HArithmeticBinaryOperation {
3043 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003044 HMul(HValue* context, HValue* left, HValue* right)
3045 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003046 SetFlag(kCanOverflow);
3047 }
3048
3049 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3050
3051 // Only commutative if it is certain that not two objects are multiplicated.
3052 virtual bool IsCommutative() const {
3053 return !representation().IsTagged();
3054 }
3055
erikcorry0ad885c2011-11-21 13:51:57 +00003056 static HInstruction* NewHMul(Zone* zone,
3057 HValue* context,
3058 HValue* left,
3059 HValue* right);
3060
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003061 DECLARE_CONCRETE_INSTRUCTION(Mul)
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 HMod: public HArithmeticBinaryOperation {
3071 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003072 HMod(HValue* context, HValue* left, HValue* right)
3073 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074 SetFlag(kCanBeDivByZero);
3075 }
3076
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003077 bool HasPowerOf2Divisor() {
3078 if (right()->IsConstant() &&
3079 HConstant::cast(right())->HasInteger32Value()) {
3080 int32_t value = HConstant::cast(right())->Integer32Value();
3081 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
3082 }
3083
3084 return false;
3085 }
3086
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3088
erikcorry0ad885c2011-11-21 13:51:57 +00003089 static HInstruction* NewHMod(Zone* zone,
3090 HValue* context,
3091 HValue* left,
3092 HValue* right);
3093
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003094 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003095
3096 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003097 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003098
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099 virtual Range* InferRange();
3100};
3101
3102
3103class HDiv: public HArithmeticBinaryOperation {
3104 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003105 HDiv(HValue* context, HValue* left, HValue* right)
3106 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107 SetFlag(kCanBeDivByZero);
3108 SetFlag(kCanOverflow);
3109 }
3110
3111 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3112
erikcorry0ad885c2011-11-21 13:51:57 +00003113
3114 static HInstruction* NewHDiv(Zone* zone,
3115 HValue* context,
3116 HValue* left,
3117 HValue* right);
3118
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003119 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120
3121 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003122 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003123
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124 virtual Range* InferRange();
3125};
3126
3127
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003128class HBitwise: public HBitwiseBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129 public:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003130 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
3131 : HBitwiseBinaryOperation(context, left, right), op_(op) {
3132 ASSERT(op == Token::BIT_AND ||
3133 op == Token::BIT_OR ||
3134 op == Token::BIT_XOR);
3135 }
3136
3137 Token::Value op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138
3139 virtual bool IsCommutative() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140
erikcorry0ad885c2011-11-21 13:51:57 +00003141 static HInstruction* NewHBitwise(Zone* zone,
3142 Token::Value op,
3143 HValue* context,
3144 HValue* left,
3145 HValue* right);
3146
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003147 DECLARE_CONCRETE_INSTRUCTION(Bitwise)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148
3149 protected:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003150 virtual bool DataEquals(HValue* other) {
3151 return op() == HBitwise::cast(other)->op();
3152 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003153
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154 virtual Range* InferRange();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003156 private:
3157 Token::Value op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003158};
3159
3160
3161class HShl: public HBitwiseBinaryOperation {
3162 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003163 HShl(HValue* context, HValue* left, HValue* right)
3164 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003165
3166 virtual Range* InferRange();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167
erikcorry0ad885c2011-11-21 13:51:57 +00003168 static HInstruction* NewHShl(Zone* zone,
3169 HValue* context,
3170 HValue* left,
3171 HValue* right);
3172
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003173 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003174
3175 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003176 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003177};
3178
3179
3180class HShr: public HBitwiseBinaryOperation {
3181 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003182 HShr(HValue* context, HValue* left, HValue* right)
3183 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003184
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003185 virtual Range* InferRange();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186
erikcorry0ad885c2011-11-21 13:51:57 +00003187 static HInstruction* NewHShr(Zone* zone,
3188 HValue* context,
3189 HValue* left,
3190 HValue* right);
3191
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003192 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003193
3194 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003195 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003196};
3197
3198
3199class HSar: public HBitwiseBinaryOperation {
3200 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003201 HSar(HValue* context, HValue* left, HValue* right)
3202 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203
3204 virtual Range* InferRange();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003205
erikcorry0ad885c2011-11-21 13:51:57 +00003206 static HInstruction* NewHSar(Zone* zone,
3207 HValue* context,
3208 HValue* left,
3209 HValue* right);
3210
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003211 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003212
3213 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003214 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215};
3216
3217
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003218class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003219 public:
3220 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3221 SetFlag(kChangesOsrEntries);
3222 }
3223
3224 int ast_id() const { return ast_id_; }
3225
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003226 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003227 return Representation::None();
3228 }
3229
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003230 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003231
3232 private:
3233 int ast_id_;
3234};
3235
3236
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003237class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003238 public:
3239 explicit HParameter(unsigned index) : index_(index) {
3240 set_representation(Representation::Tagged());
3241 }
3242
3243 unsigned index() const { return index_; }
3244
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003245 virtual void PrintDataTo(StringStream* stream);
3246
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003247 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003248 return Representation::None();
3249 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003250
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003251 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003252
3253 private:
3254 unsigned index_;
3255};
3256
3257
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003258class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003259 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003260 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3261 : HUnaryCall(context, argument_count),
3262 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264 }
3265
3266 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003268 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003269
3270 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3271 transcendental_type_ = transcendental_type;
3272 }
3273 TranscendentalCache::Type transcendental_type() {
3274 return transcendental_type_;
3275 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003276
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003277 virtual void PrintDataTo(StringStream* stream);
3278
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003279 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003280 return Representation::Tagged();
3281 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003282
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003283 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003284
3285 private:
3286 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003287 TranscendentalCache::Type transcendental_type_;
3288};
3289
3290
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003291class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003292 public:
3293 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3294
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003295 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003296 return Representation::None();
3297 }
3298
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003299 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003300};
3301
3302
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003303class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003304 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003305 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
3306 : cell_(cell), details_(details) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003307 set_representation(Representation::Tagged());
3308 SetFlag(kUseGVN);
3309 SetFlag(kDependsOnGlobalVars);
3310 }
3311
3312 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003313 bool RequiresHoleCheck();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003315 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003317 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003318 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319 return reinterpret_cast<intptr_t>(*cell_);
3320 }
3321
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003322 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003323 return Representation::None();
3324 }
3325
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003326 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327
3328 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003329 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003330 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003331 return cell_.is_identical_to(b->cell());
3332 }
3333
3334 private:
3335 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003336 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003337};
3338
3339
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003340class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003341 public:
3342 HLoadGlobalGeneric(HValue* context,
3343 HValue* global_object,
3344 Handle<Object> name,
3345 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003346 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003347 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003348 SetOperandAt(0, context);
3349 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003350 set_representation(Representation::Tagged());
3351 SetAllSideEffects();
3352 }
3353
3354 HValue* context() { return OperandAt(0); }
3355 HValue* global_object() { return OperandAt(1); }
3356 Handle<Object> name() const { return name_; }
3357 bool for_typeof() const { return for_typeof_; }
3358
3359 virtual void PrintDataTo(StringStream* stream);
3360
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003361 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003362 return Representation::Tagged();
3363 }
3364
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003365 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003366
3367 private:
3368 Handle<Object> name_;
3369 bool for_typeof_;
3370};
3371
3372
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003373inline bool StoringValueNeedsWriteBarrier(HValue* value) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003374 return !value->type().IsBoolean()
3375 && !value->type().IsSmi()
3376 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
3377}
3378
3379
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003380class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003381 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003382 HStoreGlobalCell(HValue* value,
3383 Handle<JSGlobalPropertyCell> cell,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003384 PropertyDetails details)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003385 : HUnaryOperation(value),
3386 cell_(cell),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003387 details_(details) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003388 SetFlag(kChangesGlobalVars);
3389 }
3390
3391 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003392 bool RequiresHoleCheck() {
3393 return !details_.IsDontDelete() || details_.IsReadOnly();
3394 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003395 bool NeedsWriteBarrier() {
3396 return StoringValueNeedsWriteBarrier(value());
3397 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003398
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003399 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003400 return Representation::Tagged();
3401 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003402 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003404 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003405
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003406 private:
3407 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003408 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003409};
3410
3411
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003412class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3413 public:
3414 HStoreGlobalGeneric(HValue* context,
3415 HValue* global_object,
3416 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003417 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003418 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003419 : name_(name),
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003420 strict_mode_flag_(strict_mode_flag) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003421 SetOperandAt(0, context);
3422 SetOperandAt(1, global_object);
3423 SetOperandAt(2, value);
3424 set_representation(Representation::Tagged());
3425 SetAllSideEffects();
3426 }
3427
3428 HValue* context() { return OperandAt(0); }
3429 HValue* global_object() { return OperandAt(1); }
3430 Handle<Object> name() const { return name_; }
3431 HValue* value() { return OperandAt(2); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003432 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003433
3434 virtual void PrintDataTo(StringStream* stream);
3435
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003436 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003437 return Representation::Tagged();
3438 }
3439
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003440 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003441
3442 private:
3443 Handle<Object> name_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003444 StrictModeFlag strict_mode_flag_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003445};
3446
3447
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003448class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003449 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003450 HLoadContextSlot(HValue* context , int slot_index)
3451 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003452 set_representation(Representation::Tagged());
3453 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003454 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003455 }
3456
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003457 int slot_index() const { return slot_index_; }
3458
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003459 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003460 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003461 }
3462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003463 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003464
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003465 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003466
3467 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003468 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003469 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003470 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003471 }
3472
3473 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003474 int slot_index_;
3475};
3476
3477
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003478class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003479 public:
3480 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003481 : slot_index_(slot_index) {
3482 SetOperandAt(0, context);
3483 SetOperandAt(1, value);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003484 SetFlag(kChangesContextSlots);
3485 }
3486
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 HValue* context() { return OperandAt(0); }
3488 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003489 int slot_index() const { return slot_index_; }
3490
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003491 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003492 return StoringValueNeedsWriteBarrier(value());
3493 }
3494
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003495 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003496 return Representation::Tagged();
3497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003500
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003501 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003502
3503 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003504 int slot_index_;
3505};
3506
3507
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003508class HLoadNamedField: public HUnaryOperation {
3509 public:
3510 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3511 : HUnaryOperation(object),
3512 is_in_object_(is_in_object),
3513 offset_(offset) {
3514 set_representation(Representation::Tagged());
3515 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003516 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003517 if (is_in_object) {
3518 SetFlag(kDependsOnInobjectFields);
3519 } else {
3520 SetFlag(kDependsOnBackingStoreFields);
3521 }
3522 }
3523
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003524 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003525 bool is_in_object() const { return is_in_object_; }
3526 int offset() const { return offset_; }
3527
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003528 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003529 return Representation::Tagged();
3530 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003531 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003532
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003533 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003534
3535 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003536 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003537 HLoadNamedField* b = HLoadNamedField::cast(other);
3538 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3539 }
3540
3541 private:
3542 bool is_in_object_;
3543 int offset_;
3544};
3545
3546
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003547class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003548 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003549 HLoadNamedFieldPolymorphic(HValue* context,
3550 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003551 SmallMapList* types,
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003552 Handle<String> name);
3553
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003554 HValue* context() { return OperandAt(0); }
3555 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003556 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003557 Handle<String> name() { return name_; }
3558 bool need_generic() { return need_generic_; }
3559
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003560 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003561 return Representation::Tagged();
3562 }
3563
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003564 virtual void PrintDataTo(StringStream* stream);
3565
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003566 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003567
3568 static const int kMaxLoadPolymorphism = 4;
3569
3570 protected:
3571 virtual bool DataEquals(HValue* value);
3572
3573 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003574 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003575 Handle<String> name_;
3576 bool need_generic_;
3577};
3578
3579
3580
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003581class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003582 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003583 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003584 : name_(name) {
3585 SetOperandAt(0, context);
3586 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003587 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003588 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003589 }
3590
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003591 HValue* context() { return OperandAt(0); }
3592 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003593 Handle<Object> name() const { return name_; }
3594
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003595 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003596 return Representation::Tagged();
3597 }
3598
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003599 virtual void PrintDataTo(StringStream* stream);
3600
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003601 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603 private:
3604 Handle<Object> name_;
3605};
3606
3607
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003608class HLoadFunctionPrototype: public HUnaryOperation {
3609 public:
3610 explicit HLoadFunctionPrototype(HValue* function)
3611 : HUnaryOperation(function) {
3612 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003613 SetFlag(kUseGVN);
3614 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003615 }
3616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003617 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003618
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003619 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003620 return Representation::Tagged();
3621 }
3622
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003623 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003624
3625 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003626 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003627};
3628
3629
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003630class HLoadKeyedFastElement: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003631 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003632 HLoadKeyedFastElement(HValue* obj, HValue* key) {
3633 SetOperandAt(0, obj);
3634 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636 SetFlag(kDependsOnArrayElements);
3637 SetFlag(kUseGVN);
3638 }
3639
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003640 HValue* object() { return OperandAt(0); }
3641 HValue* key() { return OperandAt(1); }
3642
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003643 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003644 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003645 return index == 0
3646 ? Representation::Tagged()
3647 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003648 }
3649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003650 virtual void PrintDataTo(StringStream* stream);
3651
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003652 bool RequiresHoleCheck();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003653
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003654 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003655
3656 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003657 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003658};
3659
3660
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003661class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
3662 public:
3663 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3664 SetOperandAt(0, elements);
3665 SetOperandAt(1, key);
3666 set_representation(Representation::Double());
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003667 SetFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003668 SetFlag(kUseGVN);
3669 }
3670
3671 HValue* elements() { return OperandAt(0); }
3672 HValue* key() { return OperandAt(1); }
3673
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003674 virtual Representation RequiredInputRepresentation(int index) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003675 // The key is supposed to be Integer32.
3676 return index == 0
3677 ? Representation::Tagged()
3678 : Representation::Integer32();
3679 }
3680
3681 virtual void PrintDataTo(StringStream* stream);
3682
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003683 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
3684
3685 protected:
3686 virtual bool DataEquals(HValue* other) { return true; }
3687};
3688
3689
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003690class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003691 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003692 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3693 HValue* key,
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003694 ElementsKind elements_kind)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003695 : elements_kind_(elements_kind) {
3696 SetOperandAt(0, external_elements);
3697 SetOperandAt(1, key);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003698 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3699 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003700 set_representation(Representation::Double());
3701 } else {
3702 set_representation(Representation::Integer32());
3703 }
3704 SetFlag(kDependsOnSpecializedArrayElements);
3705 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003706 SetFlag(kDependsOnCalls);
3707 SetFlag(kUseGVN);
3708 }
3709
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003710 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003711
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003712 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003713 // The key is supposed to be Integer32, but the base pointer
3714 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003715 return index == 0
3716 ? Representation::External()
3717 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003718 }
3719
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003720 HValue* external_pointer() { return OperandAt(0); }
3721 HValue* key() { return OperandAt(1); }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003722 ElementsKind elements_kind() const { return elements_kind_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003723
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003724 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003725
3726 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003727 virtual bool DataEquals(HValue* other) {
3728 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3729 HLoadKeyedSpecializedArrayElement* cast_other =
3730 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003731 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003732 }
3733
3734 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003735 ElementsKind elements_kind_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003736};
3737
3738
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003739class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003740 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003741 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003742 set_representation(Representation::Tagged());
3743 SetOperandAt(0, obj);
3744 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003745 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003746 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003747 }
3748
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003749 HValue* object() { return OperandAt(0); }
3750 HValue* key() { return OperandAt(1); }
3751 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003752
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003753 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003754
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003755 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003756 return Representation::Tagged();
3757 }
3758
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003759 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003760};
3761
3762
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003763class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003764 public:
3765 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003766 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003767 HValue* val,
3768 bool in_object,
3769 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003770 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003771 is_in_object_(in_object),
3772 offset_(offset) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003773 SetOperandAt(0, obj);
3774 SetOperandAt(1, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003775 if (is_in_object_) {
3776 SetFlag(kChangesInobjectFields);
3777 } else {
3778 SetFlag(kChangesBackingStoreFields);
3779 }
3780 }
3781
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003782 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003783
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003784 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003785 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003786 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003787 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003788
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003789 HValue* object() { return OperandAt(0); }
3790 HValue* value() { return OperandAt(1); }
3791
3792 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003793 bool is_in_object() const { return is_in_object_; }
3794 int offset() const { return offset_; }
3795 Handle<Map> transition() const { return transition_; }
3796 void set_transition(Handle<Map> map) { transition_ = map; }
3797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003798 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003799 return StoringValueNeedsWriteBarrier(value());
3800 }
3801
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003802 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003803 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003804 bool is_in_object_;
3805 int offset_;
3806 Handle<Map> transition_;
3807};
3808
3809
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003810class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003811 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003812 HStoreNamedGeneric(HValue* context,
3813 HValue* object,
3814 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003815 HValue* value,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003816 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003817 : name_(name),
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003818 strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003819 SetOperandAt(0, object);
3820 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003821 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003822 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003823 }
3824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003825 HValue* object() { return OperandAt(0); }
3826 HValue* value() { return OperandAt(1); }
3827 HValue* context() { return OperandAt(2); }
3828 Handle<String> name() { return name_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003829 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003830
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003831 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003832
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003833 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003834 return Representation::Tagged();
3835 }
3836
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003837 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003838
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003839 private:
3840 Handle<String> name_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003841 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003842};
3843
3844
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003845class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003846 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003847 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val,
3848 ElementsKind elements_kind = FAST_ELEMENTS)
3849 : elements_kind_(elements_kind) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003850 SetOperandAt(0, obj);
3851 SetOperandAt(1, key);
3852 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003853 SetFlag(kChangesArrayElements);
3854 }
3855
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003856 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003857 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003858 return index == 1
3859 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003860 : Representation::Tagged();
3861 }
3862
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003863 HValue* object() { return OperandAt(0); }
3864 HValue* key() { return OperandAt(1); }
3865 HValue* value() { return OperandAt(2); }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003866 bool value_is_smi() {
3867 return elements_kind_ == FAST_SMI_ONLY_ELEMENTS;
3868 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003869
3870 bool NeedsWriteBarrier() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003871 if (value_is_smi()) {
3872 return false;
3873 } else {
3874 return StoringValueNeedsWriteBarrier(value());
3875 }
3876 }
3877
3878 bool ValueNeedsSmiCheck() {
3879 return value_is_smi();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003880 }
3881
3882 virtual void PrintDataTo(StringStream* stream);
3883
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003884 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003885
3886 private:
3887 ElementsKind elements_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003888};
3889
3890
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003891class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
3892 public:
3893 HStoreKeyedFastDoubleElement(HValue* elements,
3894 HValue* key,
3895 HValue* val) {
3896 SetOperandAt(0, elements);
3897 SetOperandAt(1, key);
3898 SetOperandAt(2, val);
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003899 SetFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003900 }
3901
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003902 virtual Representation RequiredInputRepresentation(int index) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003903 if (index == 1) {
3904 return Representation::Integer32();
3905 } else if (index == 2) {
3906 return Representation::Double();
3907 } else {
3908 return Representation::Tagged();
3909 }
3910 }
3911
3912 HValue* elements() { return OperandAt(0); }
3913 HValue* key() { return OperandAt(1); }
3914 HValue* value() { return OperandAt(2); }
3915
3916 bool NeedsWriteBarrier() {
3917 return StoringValueNeedsWriteBarrier(value());
3918 }
3919
3920 virtual void PrintDataTo(StringStream* stream);
3921
3922 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
3923};
3924
3925
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003926class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003927 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003928 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3929 HValue* key,
3930 HValue* val,
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003931 ElementsKind elements_kind)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003932 : elements_kind_(elements_kind) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003933 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003934 SetOperandAt(0, external_elements);
3935 SetOperandAt(1, key);
3936 SetOperandAt(2, val);
3937 }
3938
3939 virtual void PrintDataTo(StringStream* stream);
3940
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003941 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003942 if (index == 0) {
3943 return Representation::External();
3944 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003945 bool float_or_double_elements =
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003946 elements_kind() == EXTERNAL_FLOAT_ELEMENTS ||
3947 elements_kind() == EXTERNAL_DOUBLE_ELEMENTS;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003948 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003949 return Representation::Double();
3950 } else {
3951 return Representation::Integer32();
3952 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003953 }
3954 }
3955
3956 HValue* external_pointer() { return OperandAt(0); }
3957 HValue* key() { return OperandAt(1); }
3958 HValue* value() { return OperandAt(2); }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003959 ElementsKind elements_kind() const { return elements_kind_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003960
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003961 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3962
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003963 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003964 ElementsKind elements_kind_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003965};
3966
3967
3968class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003969 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003970 HStoreKeyedGeneric(HValue* context,
3971 HValue* object,
3972 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003973 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003974 StrictModeFlag strict_mode_flag)
3975 : strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003976 SetOperandAt(0, object);
3977 SetOperandAt(1, key);
3978 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003979 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003980 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003981 }
3982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003983 HValue* object() { return OperandAt(0); }
3984 HValue* key() { return OperandAt(1); }
3985 HValue* value() { return OperandAt(2); }
3986 HValue* context() { return OperandAt(3); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003987 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003988
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003989 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003990 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003991 }
3992
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003993 virtual void PrintDataTo(StringStream* stream);
3994
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003995 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003996
3997 private:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003998 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003999};
4000
4001
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004002class HTransitionElementsKind: public HTemplateInstruction<1> {
4003 public:
4004 HTransitionElementsKind(HValue* object,
4005 Handle<Map> original_map,
4006 Handle<Map> transitioned_map)
4007 : original_map_(original_map),
4008 transitioned_map_(transitioned_map) {
4009 SetOperandAt(0, object);
4010 SetFlag(kUseGVN);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004011 SetFlag(kChangesElementsKind);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004012 set_representation(Representation::Tagged());
4013 }
4014
4015 virtual Representation RequiredInputRepresentation(int index) {
4016 return Representation::Tagged();
4017 }
4018
4019 HValue* object() { return OperandAt(0); }
4020 Handle<Map> original_map() { return original_map_; }
4021 Handle<Map> transitioned_map() { return transitioned_map_; }
4022
4023 virtual void PrintDataTo(StringStream* stream);
4024
4025 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
4026
4027 protected:
4028 virtual bool DataEquals(HValue* other) {
4029 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
4030 return original_map_.is_identical_to(instr->original_map()) &&
4031 transitioned_map_.is_identical_to(instr->transitioned_map());
4032 }
4033
4034 private:
4035 Handle<Map> original_map_;
4036 Handle<Map> transitioned_map_;
4037};
4038
4039
danno@chromium.org160a7b02011-04-18 15:51:38 +00004040class HStringAdd: public HBinaryOperation {
4041 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004042 HStringAdd(HValue* context, HValue* left, HValue* right)
4043 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00004044 set_representation(Representation::Tagged());
4045 SetFlag(kUseGVN);
4046 SetFlag(kDependsOnMaps);
4047 }
4048
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004049 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00004050 return Representation::Tagged();
4051 }
4052
4053 virtual HType CalculateInferredType() {
4054 return HType::String();
4055 }
4056
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004057 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00004058
4059 protected:
4060 virtual bool DataEquals(HValue* other) { return true; }
4061};
4062
4063
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004064class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004065 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004066 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
4067 SetOperandAt(0, context);
4068 SetOperandAt(1, string);
4069 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004070 set_representation(Representation::Integer32());
4071 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004072 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004073 }
4074
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004075 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004076 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004077 return index == 2
4078 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004079 : Representation::Tagged();
4080 }
4081
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004082 HValue* context() { return OperandAt(0); }
4083 HValue* string() { return OperandAt(1); }
4084 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004085
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004086 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004087
4088 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004089 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004090
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004091 virtual Range* InferRange() {
4092 return new Range(0, String::kMaxUC16CharCode);
4093 }
4094};
4095
4096
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004097class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004098 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004099 HStringCharFromCode(HValue* context, HValue* char_code) {
4100 SetOperandAt(0, context);
4101 SetOperandAt(1, char_code);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004102 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004103 SetFlag(kUseGVN);
4104 }
4105
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004106 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004107 return index == 0
4108 ? Representation::Tagged()
4109 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004110 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004111 virtual HType CalculateInferredType();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004112
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004113 HValue* context() { return OperandAt(0); }
4114 HValue* value() { return OperandAt(1); }
4115
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004116 virtual bool DataEquals(HValue* other) { return true; }
4117
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004118 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004119};
4120
4121
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004122class HStringLength: public HUnaryOperation {
4123 public:
4124 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
4125 set_representation(Representation::Tagged());
4126 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004127 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004128 }
4129
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004130 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004131 return Representation::Tagged();
4132 }
4133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004134 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004135 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
4136 return HType::Smi();
4137 }
4138
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004139 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004140
4141 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004142 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004143
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004144 virtual Range* InferRange() {
4145 return new Range(0, String::kMaxLength);
4146 }
4147};
4148
4149
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004150template <int V>
4151class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004152 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004153 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004154 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004155 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004156 }
4157
4158 int literal_index() const { return literal_index_; }
4159 int depth() const { return depth_; }
4160
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004161 private:
4162 int literal_index_;
4163 int depth_;
4164};
4165
4166
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004167class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004168 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004169 HArrayLiteral(HValue* context,
4170 Handle<FixedArray> constant_elements,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004171 int length,
4172 int literal_index,
4173 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004174 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004175 length_(length),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004176 constant_elements_(constant_elements) {
4177 SetOperandAt(0, context);
4178 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004179
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004180 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004181 Handle<FixedArray> constant_elements() const { return constant_elements_; }
4182 int length() const { return length_; }
4183
4184 bool IsCopyOnWrite() const;
4185
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004186 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004187 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004188 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004189 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004190
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004191 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004192
4193 private:
4194 int length_;
4195 Handle<FixedArray> constant_elements_;
4196};
4197
4198
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004199class HObjectLiteralFast: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004200 public:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004201 HObjectLiteralFast(HValue* context,
4202 Handle<JSObject> boilerplate,
4203 int total_size,
4204 int literal_index,
4205 int depth)
4206 : HMaterializedLiteral<1>(literal_index, depth),
4207 boilerplate_(boilerplate),
4208 total_size_(total_size) {
4209 SetOperandAt(0, context);
4210 }
4211
4212 // Maximum depth and total number of properties for object literal
4213 // graphs to be considered for fast deep-copying.
4214 static const int kMaxObjectLiteralDepth = 3;
4215 static const int kMaxObjectLiteralProperties = 8;
4216
4217 HValue* context() { return OperandAt(0); }
4218 Handle<JSObject> boilerplate() const { return boilerplate_; }
4219 int total_size() const { return total_size_; }
4220
4221 virtual Representation RequiredInputRepresentation(int index) {
4222 return Representation::Tagged();
4223 }
4224 virtual HType CalculateInferredType();
4225
4226 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralFast)
4227
4228 private:
4229 Handle<JSObject> boilerplate_;
4230 int total_size_;
4231};
4232
4233
4234class HObjectLiteralGeneric: public HMaterializedLiteral<1> {
4235 public:
4236 HObjectLiteralGeneric(HValue* context,
4237 Handle<FixedArray> constant_properties,
4238 bool fast_elements,
4239 int literal_index,
4240 int depth,
4241 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004242 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004243 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004244 fast_elements_(fast_elements),
4245 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004246 SetOperandAt(0, context);
4247 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004249 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004250 Handle<FixedArray> constant_properties() const {
4251 return constant_properties_;
4252 }
4253 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004254 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004255
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004256 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004257 return Representation::Tagged();
4258 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004259 virtual HType CalculateInferredType();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004260
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004261 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004262
4263 private:
4264 Handle<FixedArray> constant_properties_;
4265 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004266 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004267};
4268
4269
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004270class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004271 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004272 HRegExpLiteral(HValue* context,
4273 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004274 Handle<String> flags,
4275 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004276 : HMaterializedLiteral<1>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004277 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004278 flags_(flags) {
4279 SetOperandAt(0, context);
ricow@chromium.org27bf2882011-11-17 08:34:43 +00004280 SetAllSideEffects();
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004281 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004282
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004283 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004284 Handle<String> pattern() { return pattern_; }
4285 Handle<String> flags() { return flags_; }
4286
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004287 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004288 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004289 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004290 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004291
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004292 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004293
4294 private:
4295 Handle<String> pattern_;
4296 Handle<String> flags_;
4297};
4298
4299
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004300class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004301 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004302 HFunctionLiteral(HValue* context,
4303 Handle<SharedFunctionInfo> shared,
4304 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004305 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004306 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004307 set_representation(Representation::Tagged());
4308 }
4309
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004310 HValue* context() { return OperandAt(0); }
4311
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004312 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004313 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004314 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004315 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004316
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004317 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004318
4319 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4320 bool pretenure() const { return pretenure_; }
4321
4322 private:
4323 Handle<SharedFunctionInfo> shared_info_;
4324 bool pretenure_;
4325};
4326
4327
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004328class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004329 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004330 explicit HTypeof(HValue* context, HValue* value) {
4331 SetOperandAt(0, context);
4332 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004333 set_representation(Representation::Tagged());
4334 }
4335
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004336 HValue* context() { return OperandAt(0); }
4337 HValue* value() { return OperandAt(1); }
4338
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004339 virtual HValue* Canonicalize();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004340 virtual void PrintDataTo(StringStream* stream);
4341
4342 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004343 return Representation::Tagged();
4344 }
4345
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004346 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004347};
4348
4349
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004350class HToFastProperties: public HUnaryOperation {
4351 public:
4352 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4353 // This instruction is not marked as having side effects, but
4354 // changes the map of the input operand. Use it only when creating
4355 // object literals.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004356 ASSERT(value->IsObjectLiteralGeneric() || value->IsObjectLiteralFast());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004357 set_representation(Representation::Tagged());
4358 }
4359
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004360 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004361 return Representation::Tagged();
4362 }
4363
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004364 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004365};
4366
4367
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004368class HValueOf: public HUnaryOperation {
4369 public:
4370 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4371 set_representation(Representation::Tagged());
4372 }
4373
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004374 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004375 return Representation::Tagged();
4376 }
4377
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004378 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004379};
4380
4381
4382class HDeleteProperty: public HBinaryOperation {
4383 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004384 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4385 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004386 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004387 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004388 }
4389
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004390 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004391 return Representation::Tagged();
4392 }
4393
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004394 virtual HType CalculateInferredType();
4395
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004396 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004398 HValue* object() { return left(); }
4399 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004400};
4401
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004402
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004403class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004404 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004405 HIn(HValue* context, HValue* key, HValue* object) {
4406 SetOperandAt(0, context);
4407 SetOperandAt(1, key);
4408 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004409 set_representation(Representation::Tagged());
4410 SetAllSideEffects();
4411 }
4412
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004413 HValue* context() { return OperandAt(0); }
4414 HValue* key() { return OperandAt(1); }
4415 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004416
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004417 virtual Representation RequiredInputRepresentation(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004418 return Representation::Tagged();
4419 }
4420
4421 virtual HType CalculateInferredType() {
4422 return HType::Boolean();
4423 }
4424
4425 virtual void PrintDataTo(StringStream* stream);
4426
4427 DECLARE_CONCRETE_INSTRUCTION(In)
4428};
4429
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004430#undef DECLARE_INSTRUCTION
4431#undef DECLARE_CONCRETE_INSTRUCTION
4432
4433} } // namespace v8::internal
4434
4435#endif // V8_HYDROGEN_INSTRUCTIONS_H_