Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: src/hydrogen-instructions.h

Issue 149413010: A64: Synchronize with r16024. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-bch.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 V(InstanceOfKnownGlobal) \ 128 V(InstanceOfKnownGlobal) \
129 V(InstanceSize) \ 129 V(InstanceSize) \
130 V(InvokeFunction) \ 130 V(InvokeFunction) \
131 V(IsConstructCallAndBranch) \ 131 V(IsConstructCallAndBranch) \
132 V(IsObjectAndBranch) \ 132 V(IsObjectAndBranch) \
133 V(IsNumberAndBranch) \ 133 V(IsNumberAndBranch) \
134 V(IsStringAndBranch) \ 134 V(IsStringAndBranch) \
135 V(IsSmiAndBranch) \ 135 V(IsSmiAndBranch) \
136 V(IsUndetectableAndBranch) \ 136 V(IsUndetectableAndBranch) \
137 V(LeaveInlined) \ 137 V(LeaveInlined) \
138 V(LinkObjectInList) \
139 V(LoadContextSlot) \ 138 V(LoadContextSlot) \
140 V(LoadExternalArrayPointer) \ 139 V(LoadExternalArrayPointer) \
141 V(LoadFieldByIndex) \ 140 V(LoadFieldByIndex) \
142 V(LoadFunctionPrototype) \ 141 V(LoadFunctionPrototype) \
143 V(LoadGlobalCell) \ 142 V(LoadGlobalCell) \
144 V(LoadGlobalGeneric) \ 143 V(LoadGlobalGeneric) \
145 V(LoadKeyed) \ 144 V(LoadKeyed) \
146 V(LoadKeyedGeneric) \ 145 V(LoadKeyedGeneric) \
147 V(LoadNamedField) \ 146 V(LoadNamedField) \
148 V(LoadNamedFieldPolymorphic) \ 147 V(LoadNamedFieldPolymorphic) \
(...skipping 23 matching lines...) Expand all
172 V(StoreGlobalCell) \ 171 V(StoreGlobalCell) \
173 V(StoreGlobalGeneric) \ 172 V(StoreGlobalGeneric) \
174 V(StoreKeyed) \ 173 V(StoreKeyed) \
175 V(StoreKeyedGeneric) \ 174 V(StoreKeyedGeneric) \
176 V(StoreNamedField) \ 175 V(StoreNamedField) \
177 V(StoreNamedGeneric) \ 176 V(StoreNamedGeneric) \
178 V(StringAdd) \ 177 V(StringAdd) \
179 V(StringCharCodeAt) \ 178 V(StringCharCodeAt) \
180 V(StringCharFromCode) \ 179 V(StringCharFromCode) \
181 V(StringCompareAndBranch) \ 180 V(StringCompareAndBranch) \
182 V(StringLength) \
183 V(Sub) \ 181 V(Sub) \
184 V(ThisFunction) \ 182 V(ThisFunction) \
185 V(Throw) \ 183 V(Throw) \
186 V(ToFastProperties) \ 184 V(ToFastProperties) \
187 V(TransitionElementsKind) \ 185 V(TransitionElementsKind) \
188 V(TrapAllocationMemento) \ 186 V(TrapAllocationMemento) \
189 V(Typeof) \ 187 V(Typeof) \
190 V(TypeofIsAndBranch) \ 188 V(TypeofIsAndBranch) \
191 V(UnaryMathOperation) \ 189 V(UnaryMathOperation) \
192 V(UnknownOSRValue) \ 190 V(UnknownOSRValue) \
193 V(UseConst) \ 191 V(UseConst) \
194 V(ValueOf) \ 192 V(ValueOf) \
195 V(WrapReceiver) 193 V(WrapReceiver)
196 194
197 #define GVN_TRACKED_FLAG_LIST(V) \ 195 #define GVN_TRACKED_FLAG_LIST(V) \
198 V(Maps) \ 196 V(Maps) \
199 V(NewSpacePromotion) 197 V(NewSpacePromotion)
200 198
201 #define GVN_UNTRACKED_FLAG_LIST(V) \ 199 #define GVN_UNTRACKED_FLAG_LIST(V) \
202 V(ArrayElements) \ 200 V(ArrayElements) \
203 V(ArrayLengths) \ 201 V(ArrayLengths) \
202 V(StringLengths) \
204 V(BackingStoreFields) \ 203 V(BackingStoreFields) \
205 V(Calls) \ 204 V(Calls) \
206 V(ContextSlots) \ 205 V(ContextSlots) \
207 V(DoubleArrayElements) \ 206 V(DoubleArrayElements) \
208 V(DoubleFields) \ 207 V(DoubleFields) \
209 V(ElementsKind) \ 208 V(ElementsKind) \
210 V(ElementsPointer) \ 209 V(ElementsPointer) \
211 V(GlobalVars) \ 210 V(GlobalVars) \
212 V(InobjectFields) \ 211 V(InobjectFields) \
213 V(OsrEntries) \ 212 V(OsrEntries) \
214 V(SpecializedArrayElements) 213 V(ExternalMemory)
215 214
216 215
217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ 216 #define DECLARE_ABSTRACT_INSTRUCTION(type) \
218 virtual bool Is##type() const { return true; } \ 217 virtual bool Is##type() const { return true; } \
219 static H##type* cast(HValue* value) { \ 218 static H##type* cast(HValue* value) { \
220 ASSERT(value->Is##type()); \ 219 ASSERT(value->Is##type()); \
221 return reinterpret_cast<H##type*>(value); \ 220 return reinterpret_cast<H##type*>(value); \
222 } 221 }
223 222
224 223
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 return reinterpret_cast<intptr_t>(raw_address_); 342 return reinterpret_cast<intptr_t>(raw_address_);
344 } 343 }
345 344
346 private: 345 private:
347 Address raw_address_; 346 Address raw_address_;
348 }; 347 };
349 348
350 349
351 class HType { 350 class HType {
352 public: 351 public:
353 HType() : type_(kUninitialized) { } 352 static HType None() { return HType(kNone); }
354
355 static HType Tagged() { return HType(kTagged); } 353 static HType Tagged() { return HType(kTagged); }
356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } 354 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
357 static HType TaggedNumber() { return HType(kTaggedNumber); } 355 static HType TaggedNumber() { return HType(kTaggedNumber); }
358 static HType Smi() { return HType(kSmi); } 356 static HType Smi() { return HType(kSmi); }
359 static HType HeapNumber() { return HType(kHeapNumber); } 357 static HType HeapNumber() { return HType(kHeapNumber); }
360 static HType String() { return HType(kString); } 358 static HType String() { return HType(kString); }
361 static HType Boolean() { return HType(kBoolean); } 359 static HType Boolean() { return HType(kBoolean); }
362 static HType NonPrimitive() { return HType(kNonPrimitive); } 360 static HType NonPrimitive() { return HType(kNonPrimitive); }
363 static HType JSArray() { return HType(kJSArray); } 361 static HType JSArray() { return HType(kJSArray); }
364 static HType JSObject() { return HType(kJSObject); } 362 static HType JSObject() { return HType(kJSObject); }
365 static HType Uninitialized() { return HType(kUninitialized); }
366 363
367 // Return the weakest (least precise) common type. 364 // Return the weakest (least precise) common type.
368 HType Combine(HType other) { 365 HType Combine(HType other) {
369 return HType(static_cast<Type>(type_ & other.type_)); 366 return HType(static_cast<Type>(type_ & other.type_));
370 } 367 }
371 368
372 bool Equals(const HType& other) const { 369 bool Equals(const HType& other) const {
373 return type_ == other.type_; 370 return type_ == other.type_;
374 } 371 }
375 372
376 bool IsSubtypeOf(const HType& other) { 373 bool IsSubtypeOf(const HType& other) {
377 return Combine(other).Equals(other); 374 return Combine(other).Equals(other);
378 } 375 }
379 376
380 bool IsTagged() const { 377 bool IsTagged() const {
381 ASSERT(type_ != kUninitialized);
382 return ((type_ & kTagged) == kTagged); 378 return ((type_ & kTagged) == kTagged);
383 } 379 }
384 380
385 bool IsTaggedPrimitive() const { 381 bool IsTaggedPrimitive() const {
386 ASSERT(type_ != kUninitialized);
387 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); 382 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
388 } 383 }
389 384
390 bool IsTaggedNumber() const { 385 bool IsTaggedNumber() const {
391 ASSERT(type_ != kUninitialized);
392 return ((type_ & kTaggedNumber) == kTaggedNumber); 386 return ((type_ & kTaggedNumber) == kTaggedNumber);
393 } 387 }
394 388
395 bool IsSmi() const { 389 bool IsSmi() const {
396 ASSERT(type_ != kUninitialized);
397 return ((type_ & kSmi) == kSmi); 390 return ((type_ & kSmi) == kSmi);
398 } 391 }
399 392
400 bool IsHeapNumber() const { 393 bool IsHeapNumber() const {
401 ASSERT(type_ != kUninitialized);
402 return ((type_ & kHeapNumber) == kHeapNumber); 394 return ((type_ & kHeapNumber) == kHeapNumber);
403 } 395 }
404 396
405 bool IsString() const { 397 bool IsString() const {
406 ASSERT(type_ != kUninitialized);
407 return ((type_ & kString) == kString); 398 return ((type_ & kString) == kString);
408 } 399 }
409 400
410 bool IsNonString() const { 401 bool IsNonString() const {
411 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || 402 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() ||
412 IsBoolean() || IsJSArray(); 403 IsBoolean() || IsJSArray();
413 } 404 }
414 405
415 bool IsBoolean() const { 406 bool IsBoolean() const {
416 ASSERT(type_ != kUninitialized);
417 return ((type_ & kBoolean) == kBoolean); 407 return ((type_ & kBoolean) == kBoolean);
418 } 408 }
419 409
420 bool IsNonPrimitive() const { 410 bool IsNonPrimitive() const {
421 ASSERT(type_ != kUninitialized);
422 return ((type_ & kNonPrimitive) == kNonPrimitive); 411 return ((type_ & kNonPrimitive) == kNonPrimitive);
423 } 412 }
424 413
425 bool IsJSArray() const { 414 bool IsJSArray() const {
426 ASSERT(type_ != kUninitialized);
427 return ((type_ & kJSArray) == kJSArray); 415 return ((type_ & kJSArray) == kJSArray);
428 } 416 }
429 417
430 bool IsJSObject() const { 418 bool IsJSObject() const {
431 ASSERT(type_ != kUninitialized);
432 return ((type_ & kJSObject) == kJSObject); 419 return ((type_ & kJSObject) == kJSObject);
433 } 420 }
434 421
435 bool IsUninitialized() const { 422 bool IsHeapObject() const {
436 return type_ == kUninitialized; 423 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
437 } 424 }
438 425
439 bool IsHeapObject() const { 426 bool ToStringOrToNumberCanBeObserved(Representation representation) {
440 ASSERT(type_ != kUninitialized); 427 switch (type_) {
441 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); 428 case kTaggedPrimitive: // fallthru
429 case kTaggedNumber: // fallthru
430 case kSmi: // fallthru
431 case kHeapNumber: // fallthru
432 case kString: // fallthru
433 case kBoolean:
434 return false;
435 case kJSArray: // fallthru
436 case kJSObject:
437 return true;
438 case kTagged:
439 break;
440 }
441 return !representation.IsSmiOrInteger32() && !representation.IsDouble();
442 } 442 }
443 443
444 static HType TypeFromValue(Handle<Object> value); 444 static HType TypeFromValue(Handle<Object> value);
445 445
446 const char* ToString(); 446 const char* ToString();
447 447
448 private: 448 private:
449 enum Type { 449 enum Type {
450 kNone = 0x0, // 0000 0000 0000 0000
450 kTagged = 0x1, // 0000 0000 0000 0001 451 kTagged = 0x1, // 0000 0000 0000 0001
451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 452 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
452 kTaggedNumber = 0xd, // 0000 0000 0000 1101 453 kTaggedNumber = 0xd, // 0000 0000 0000 1101
453 kSmi = 0x1d, // 0000 0000 0001 1101 454 kSmi = 0x1d, // 0000 0000 0001 1101
454 kHeapNumber = 0x2d, // 0000 0000 0010 1101 455 kHeapNumber = 0x2d, // 0000 0000 0010 1101
455 kString = 0x45, // 0000 0000 0100 0101 456 kString = 0x45, // 0000 0000 0100 0101
456 kBoolean = 0x85, // 0000 0000 1000 0101 457 kBoolean = 0x85, // 0000 0000 1000 0101
457 kNonPrimitive = 0x101, // 0000 0001 0000 0001 458 kNonPrimitive = 0x101, // 0000 0001 0000 0001
458 kJSObject = 0x301, // 0000 0011 0000 0001 459 kJSObject = 0x301, // 0000 0011 0000 0001
459 kJSArray = 0x701, // 0000 0111 0000 0001 460 kJSArray = 0x701 // 0000 0111 0000 0001
460 kUninitialized = 0x1fff // 0001 1111 1111 1111
461 }; 461 };
462 462
463 // Make sure type fits in int16. 463 // Make sure type fits in int16.
464 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); 464 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte)));
465 465
466 explicit HType(Type t) : type_(t) { } 466 explicit HType(Type t) : type_(t) { }
467 467
468 int16_t type_; 468 int16_t type_;
469 }; 469 };
470 470
471 471
472 class HUseListNode: public ZoneObject { 472 class HUseListNode: public ZoneObject {
473 public: 473 public:
474 HUseListNode(HValue* value, int index, HUseListNode* tail) 474 HUseListNode(HValue* value, int index, HUseListNode* tail)
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) 865 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
866 #undef DECLARE_PREDICATE 866 #undef DECLARE_PREDICATE
867 bool IsPhi() const { return opcode() == kPhi; } 867 bool IsPhi() const { return opcode() == kPhi; }
868 868
869 // Declare virtual predicates for abstract HInstruction or HValue 869 // Declare virtual predicates for abstract HInstruction or HValue
870 #define DECLARE_PREDICATE(type) \ 870 #define DECLARE_PREDICATE(type) \
871 virtual bool Is##type() const { return false; } 871 virtual bool Is##type() const { return false; }
872 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE) 872 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
873 #undef DECLARE_PREDICATE 873 #undef DECLARE_PREDICATE
874 874
875 HValue() : block_(NULL), 875 HValue(HType type = HType::Tagged())
876 id_(kNoNumber), 876 : block_(NULL),
877 type_(HType::Tagged()), 877 id_(kNoNumber),
878 use_list_(NULL), 878 type_(type),
879 range_(NULL), 879 use_list_(NULL),
880 flags_(0) {} 880 range_(NULL),
881 flags_(0) {}
881 virtual ~HValue() {} 882 virtual ~HValue() {}
882 883
883 HBasicBlock* block() const { return block_; } 884 HBasicBlock* block() const { return block_; }
884 void SetBlock(HBasicBlock* block); 885 void SetBlock(HBasicBlock* block);
885 int LoopWeight() const; 886 int LoopWeight() const;
886 887
887 // Note: Never call this method for an unlinked value. 888 // Note: Never call this method for an unlinked value.
888 Isolate* isolate() const; 889 Isolate* isolate() const;
889 890
890 int id() const { return id_; } 891 int id() const { return id_; }
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 1139
1139 bool TryGuaranteeRange(HValue* upper_bound); 1140 bool TryGuaranteeRange(HValue* upper_bound);
1140 virtual bool TryDecompose(DecompositionResult* decomposition) { 1141 virtual bool TryDecompose(DecompositionResult* decomposition) {
1141 if (RedefinedOperand() != NULL) { 1142 if (RedefinedOperand() != NULL) {
1142 return RedefinedOperand()->TryDecompose(decomposition); 1143 return RedefinedOperand()->TryDecompose(decomposition);
1143 } else { 1144 } else {
1144 return false; 1145 return false;
1145 } 1146 }
1146 } 1147 }
1147 1148
1149 // Returns true conservatively if the program might be able to observe a
1150 // ToString() operation on this value.
1151 bool ToStringCanBeObserved() const {
1152 return type().ToStringOrToNumberCanBeObserved(representation());
1153 }
1154
1155 // Returns true conservatively if the program might be able to observe a
1156 // ToNumber() operation on this value.
1157 bool ToNumberCanBeObserved() const {
1158 return type().ToStringOrToNumberCanBeObserved(representation());
1159 }
1160
1148 protected: 1161 protected:
1149 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); 1162 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1150 1163
1151 enum RangeGuaranteeDirection { 1164 enum RangeGuaranteeDirection {
1152 DIRECTION_NONE = 0, 1165 DIRECTION_NONE = 0,
1153 DIRECTION_UPPER = 1, 1166 DIRECTION_UPPER = 1,
1154 DIRECTION_LOWER = 2, 1167 DIRECTION_LOWER = 2,
1155 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER 1168 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1156 }; 1169 };
1157 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} 1170 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 int flags_; 1301 int flags_;
1289 GVNFlagSet gvn_flags_; 1302 GVNFlagSet gvn_flags_;
1290 1303
1291 private: 1304 private:
1292 virtual bool IsDeletable() const { return false; } 1305 virtual bool IsDeletable() const { return false; }
1293 1306
1294 DISALLOW_COPY_AND_ASSIGN(HValue); 1307 DISALLOW_COPY_AND_ASSIGN(HValue);
1295 }; 1308 };
1296 1309
1297 1310
1311 #define DECLARE_INSTRUCTION_FACTORY_P0(I) \
1312 static I* New(Zone* zone, HValue* context) { \
1313 return new(zone) I(); \
1314 }
1315
1316 #define DECLARE_INSTRUCTION_FACTORY_P1(I, P1) \
1317 static I* New(Zone* zone, HValue* context, P1 p1) { \
1318 return new(zone) I(p1); \
1319 }
1320
1321 #define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2) \
1322 static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) { \
1323 return new(zone) I(p1, p2); \
1324 }
1325
1326 #define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3) \
1327 static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) { \
1328 return new(zone) I(p1, p2, p3); \
1329 }
1330
1331 #define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4) \
1332 static I* New(Zone* zone, \
1333 HValue* context, \
1334 P1 p1, \
1335 P2 p2, \
1336 P3 p3, \
1337 P4 p4) { \
1338 return new(zone) I(p1, p2, p3, p4); \
1339 }
1340
1341 #define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5) \
1342 static I* New(Zone* zone, \
1343 HValue* context, \
1344 P1 p1, \
1345 P2 p2, \
1346 P3 p3, \
1347 P4 p4, \
1348 P5 p5) { \
1349 return new(zone) I(p1, p2, p3, p4, p5); \
1350 }
1351
1352
1298 class HInstruction: public HValue { 1353 class HInstruction: public HValue {
1299 public: 1354 public:
1300 HInstruction* next() const { return next_; } 1355 HInstruction* next() const { return next_; }
1301 HInstruction* previous() const { return previous_; } 1356 HInstruction* previous() const { return previous_; }
1302 1357
1303 virtual void PrintTo(StringStream* stream); 1358 virtual void PrintTo(StringStream* stream);
1304 virtual void PrintDataTo(StringStream* stream); 1359 virtual void PrintDataTo(StringStream* stream);
1305 1360
1306 bool IsLinked() const { return block() != NULL; } 1361 bool IsLinked() const { return block() != NULL; }
1307 void Unlink(); 1362 void Unlink();
(...skipping 15 matching lines...) Expand all
1323 1378
1324 #ifdef DEBUG 1379 #ifdef DEBUG
1325 virtual void Verify(); 1380 virtual void Verify();
1326 #endif 1381 #endif
1327 1382
1328 virtual bool IsCall() { return false; } 1383 virtual bool IsCall() { return false; }
1329 1384
1330 DECLARE_ABSTRACT_INSTRUCTION(Instruction) 1385 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
1331 1386
1332 protected: 1387 protected:
1333 HInstruction() 1388 HInstruction(HType type = HType::Tagged())
1334 : next_(NULL), 1389 : HValue(type),
1390 next_(NULL),
1335 previous_(NULL), 1391 previous_(NULL),
1336 position_(RelocInfo::kNoPosition) { 1392 position_(RelocInfo::kNoPosition) {
1337 SetGVNFlag(kDependsOnOsrEntries); 1393 SetGVNFlag(kDependsOnOsrEntries);
1338 } 1394 }
1339 1395
1340 virtual void DeleteFromGraph() { Unlink(); } 1396 virtual void DeleteFromGraph() { Unlink(); }
1341 1397
1342 private: 1398 private:
1343 void InitializeAsFirst(HBasicBlock* block) { 1399 void InitializeAsFirst(HBasicBlock* block) {
1344 ASSERT(!IsLinked()); 1400 ASSERT(!IsLinked());
(...skipping 10 matching lines...) Expand all
1355 }; 1411 };
1356 1412
1357 1413
1358 template<int V> 1414 template<int V>
1359 class HTemplateInstruction : public HInstruction { 1415 class HTemplateInstruction : public HInstruction {
1360 public: 1416 public:
1361 int OperandCount() { return V; } 1417 int OperandCount() { return V; }
1362 HValue* OperandAt(int i) const { return inputs_[i]; } 1418 HValue* OperandAt(int i) const { return inputs_[i]; }
1363 1419
1364 protected: 1420 protected:
1421 HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {}
1422
1365 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } 1423 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1366 1424
1367 private: 1425 private:
1368 EmbeddedContainer<HValue*, V> inputs_; 1426 EmbeddedContainer<HValue*, V> inputs_;
1369 }; 1427 };
1370 1428
1371 1429
1372 class HControlInstruction: public HInstruction { 1430 class HControlInstruction: public HInstruction {
1373 public: 1431 public:
1374 virtual HBasicBlock* SuccessorAt(int i) = 0; 1432 virtual HBasicBlock* SuccessorAt(int i) = 0;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 virtual Representation RequiredInputRepresentation(int index) { 1486 virtual Representation RequiredInputRepresentation(int index) {
1429 return Representation::None(); 1487 return Representation::None();
1430 } 1488 }
1431 1489
1432 DECLARE_CONCRETE_INSTRUCTION(BlockEntry) 1490 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
1433 }; 1491 };
1434 1492
1435 1493
1436 class HDummyUse: public HTemplateInstruction<1> { 1494 class HDummyUse: public HTemplateInstruction<1> {
1437 public: 1495 public:
1438 explicit HDummyUse(HValue* value) { 1496 explicit HDummyUse(HValue* value)
1497 : HTemplateInstruction<1>(HType::Smi()) {
1439 SetOperandAt(0, value); 1498 SetOperandAt(0, value);
1440 // Pretend to be a Smi so that the HChange instructions inserted 1499 // Pretend to be a Smi so that the HChange instructions inserted
1441 // before any use generate as little code as possible. 1500 // before any use generate as little code as possible.
1442 set_representation(Representation::Tagged()); 1501 set_representation(Representation::Tagged());
1443 set_type(HType::Smi());
1444 } 1502 }
1445 1503
1446 HValue* value() { return OperandAt(0); } 1504 HValue* value() { return OperandAt(0); }
1447 1505
1448 virtual bool HasEscapingOperandAt(int index) { return false; } 1506 virtual bool HasEscapingOperandAt(int index) { return false; }
1449 virtual Representation RequiredInputRepresentation(int index) { 1507 virtual Representation RequiredInputRepresentation(int index) {
1450 return Representation::None(); 1508 return Representation::None();
1451 } 1509 }
1452 1510
1453 virtual void PrintDataTo(StringStream* stream); 1511 virtual void PrintDataTo(StringStream* stream);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 SetOperandAt(0, constrained_value); 1555 SetOperandAt(0, constrained_value);
1498 SetOperandAt(1, related_value); 1556 SetOperandAt(1, related_value);
1499 } 1557 }
1500 1558
1501 NumericRelation relation_; 1559 NumericRelation relation_;
1502 }; 1560 };
1503 1561
1504 1562
1505 class HDeoptimize: public HTemplateInstruction<0> { 1563 class HDeoptimize: public HTemplateInstruction<0> {
1506 public: 1564 public:
1507 explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {} 1565 DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType);
1508 1566
1509 virtual Representation RequiredInputRepresentation(int index) { 1567 virtual Representation RequiredInputRepresentation(int index) {
1510 return Representation::None(); 1568 return Representation::None();
1511 } 1569 }
1512 1570
1513 Deoptimizer::BailoutType type() { return type_; } 1571 Deoptimizer::BailoutType type() { return type_; }
1514 1572
1515 DECLARE_CONCRETE_INSTRUCTION(Deoptimize) 1573 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1516 1574
1517 private: 1575 private:
1576 explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
1577
1518 Deoptimizer::BailoutType type_; 1578 Deoptimizer::BailoutType type_;
1519 }; 1579 };
1520 1580
1521 1581
1522 // Inserts an int3/stop break instruction for debugging purposes. 1582 // Inserts an int3/stop break instruction for debugging purposes.
1523 class HDebugBreak: public HTemplateInstruction<0> { 1583 class HDebugBreak: public HTemplateInstruction<0> {
1524 public: 1584 public:
1525 virtual Representation RequiredInputRepresentation(int index) { 1585 virtual Representation RequiredInputRepresentation(int index) {
1526 return Representation::None(); 1586 return Representation::None();
1527 } 1587 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 return Representation::Tagged(); 1668 return Representation::Tagged();
1609 } 1669 }
1610 1670
1611 DECLARE_CONCRETE_INSTRUCTION(CompareMap) 1671 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
1612 1672
1613 private: 1673 private:
1614 Handle<Map> map_; 1674 Handle<Map> map_;
1615 }; 1675 };
1616 1676
1617 1677
1678 class HContext: public HTemplateInstruction<0> {
1679 public:
1680 static HContext* New(Zone* zone) {
1681 return new(zone) HContext();
1682 }
1683
1684 virtual Representation RequiredInputRepresentation(int index) {
1685 return Representation::None();
1686 }
1687
1688 DECLARE_CONCRETE_INSTRUCTION(Context)
1689
1690 protected:
1691 virtual bool DataEquals(HValue* other) { return true; }
1692
1693 private:
1694 HContext() {
1695 set_representation(Representation::Tagged());
1696 SetFlag(kUseGVN);
1697 }
1698
1699 virtual bool IsDeletable() const { return true; }
1700 };
1701
1702
1618 class HReturn: public HTemplateControlInstruction<0, 3> { 1703 class HReturn: public HTemplateControlInstruction<0, 3> {
1619 public: 1704 public:
1620 HReturn(HValue* value, HValue* context, HValue* parameter_count) { 1705 static HInstruction* New(Zone* zone,
1621 SetOperandAt(0, value); 1706 HValue* context,
1622 SetOperandAt(1, context); 1707 HValue* value,
1623 SetOperandAt(2, parameter_count); 1708 HValue* parameter_count) {
1709 return new(zone) HReturn(value, context, parameter_count);
1710 }
1711
1712 static HInstruction* New(Zone* zone,
1713 HValue* context,
1714 HValue* value) {
1715 return new(zone) HReturn(value, context, 0);
1624 } 1716 }
1625 1717
1626 virtual Representation RequiredInputRepresentation(int index) { 1718 virtual Representation RequiredInputRepresentation(int index) {
1627 return Representation::Tagged(); 1719 return Representation::Tagged();
1628 } 1720 }
1629 1721
1630 virtual void PrintDataTo(StringStream* stream); 1722 virtual void PrintDataTo(StringStream* stream);
1631 1723
1632 HValue* value() { return OperandAt(0); } 1724 HValue* value() { return OperandAt(0); }
1633 HValue* context() { return OperandAt(1); } 1725 HValue* context() { return OperandAt(1); }
1634 HValue* parameter_count() { return OperandAt(2); } 1726 HValue* parameter_count() { return OperandAt(2); }
1635 1727
1636 DECLARE_CONCRETE_INSTRUCTION(Return) 1728 DECLARE_CONCRETE_INSTRUCTION(Return)
1729
1730 private:
1731 HReturn(HValue* value, HValue* context, HValue* parameter_count) {
1732 SetOperandAt(0, value);
1733 SetOperandAt(1, context);
1734 SetOperandAt(2, parameter_count);
1735 }
1637 }; 1736 };
1638 1737
1639 1738
1640 class HAbnormalExit: public HTemplateControlInstruction<0, 0> { 1739 class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
1641 public: 1740 public:
1642 virtual Representation RequiredInputRepresentation(int index) { 1741 virtual Representation RequiredInputRepresentation(int index) {
1643 return Representation::None(); 1742 return Representation::None();
1644 } 1743 }
1645 1744
1646 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) 1745 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
1647 }; 1746 };
1648 1747
1649 1748
1650 class HUnaryOperation: public HTemplateInstruction<1> { 1749 class HUnaryOperation: public HTemplateInstruction<1> {
1651 public: 1750 public:
1652 explicit HUnaryOperation(HValue* value) { 1751 HUnaryOperation(HValue* value, HType type = HType::Tagged())
1752 : HTemplateInstruction<1>(type) {
1653 SetOperandAt(0, value); 1753 SetOperandAt(0, value);
1654 } 1754 }
1655 1755
1656 static HUnaryOperation* cast(HValue* value) { 1756 static HUnaryOperation* cast(HValue* value) {
1657 return reinterpret_cast<HUnaryOperation*>(value); 1757 return reinterpret_cast<HUnaryOperation*>(value);
1658 } 1758 }
1659 1759
1660 HValue* value() const { return OperandAt(0); } 1760 HValue* value() const { return OperandAt(0); }
1661 virtual void PrintDataTo(StringStream* stream); 1761 virtual void PrintDataTo(StringStream* stream);
1662 }; 1762 };
1663 1763
1664 1764
1665 class HThrow: public HTemplateInstruction<2> { 1765 class HThrow: public HTemplateInstruction<2> {
1666 public: 1766 public:
1667 HThrow(HValue* context, HValue* value) { 1767 static HThrow* New(Zone* zone,
1668 SetOperandAt(0, context); 1768 HValue* context,
1669 SetOperandAt(1, value); 1769 HValue* value) {
1670 SetAllSideEffects(); 1770 return new(zone) HThrow(context, value);
1671 } 1771 }
1672 1772
1673 virtual Representation RequiredInputRepresentation(int index) { 1773 virtual Representation RequiredInputRepresentation(int index) {
1674 return Representation::Tagged(); 1774 return Representation::Tagged();
1675 } 1775 }
1676 1776
1677 HValue* context() { return OperandAt(0); } 1777 HValue* context() { return OperandAt(0); }
1678 HValue* value() { return OperandAt(1); } 1778 HValue* value() { return OperandAt(1); }
1679 1779
1680 DECLARE_CONCRETE_INSTRUCTION(Throw) 1780 DECLARE_CONCRETE_INSTRUCTION(Throw)
1781
1782 private:
1783 HThrow(HValue* context, HValue* value) {
1784 SetOperandAt(0, context);
1785 SetOperandAt(1, value);
1786 SetAllSideEffects();
1787 }
1681 }; 1788 };
1682 1789
1683 1790
1684 class HUseConst: public HUnaryOperation { 1791 class HUseConst: public HUnaryOperation {
1685 public: 1792 public:
1686 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { } 1793 DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
1687 1794
1688 virtual Representation RequiredInputRepresentation(int index) { 1795 virtual Representation RequiredInputRepresentation(int index) {
1689 return Representation::None(); 1796 return Representation::None();
1690 } 1797 }
1691 1798
1692 DECLARE_CONCRETE_INSTRUCTION(UseConst) 1799 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1800
1801 private:
1802 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1693 }; 1803 };
1694 1804
1695 1805
1696 class HForceRepresentation: public HTemplateInstruction<1> { 1806 class HForceRepresentation: public HTemplateInstruction<1> {
1697 public: 1807 public:
1698 HForceRepresentation(HValue* value, Representation required_representation) { 1808 DECLARE_INSTRUCTION_FACTORY_P2(HForceRepresentation, HValue*, Representation);
1699 SetOperandAt(0, value);
1700 set_representation(required_representation);
1701 }
1702 1809
1703 HValue* value() { return OperandAt(0); } 1810 HValue* value() { return OperandAt(0); }
1704 1811
1705 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 1812 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1706 1813
1707 virtual Representation RequiredInputRepresentation(int index) { 1814 virtual Representation RequiredInputRepresentation(int index) {
1708 return representation(); // Same as the output representation. 1815 return representation(); // Same as the output representation.
1709 } 1816 }
1710 1817
1711 virtual void PrintDataTo(StringStream* stream); 1818 virtual void PrintDataTo(StringStream* stream);
1712 1819
1713 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) 1820 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1821
1822 private:
1823 HForceRepresentation(HValue* value, Representation required_representation) {
1824 SetOperandAt(0, value);
1825 set_representation(required_representation);
1826 }
1714 }; 1827 };
1715 1828
1716 1829
1717 class HChange: public HUnaryOperation { 1830 class HChange: public HUnaryOperation {
1718 public: 1831 public:
1719 HChange(HValue* value, 1832 HChange(HValue* value,
1720 Representation to, 1833 Representation to,
1721 bool is_truncating_to_smi, 1834 bool is_truncating_to_smi,
1722 bool is_truncating_to_int32, 1835 bool is_truncating_to_int32,
1723 bool allow_undefined_as_nan) 1836 bool allow_undefined_as_nan)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 1878
1766 private: 1879 private:
1767 virtual bool IsDeletable() const { 1880 virtual bool IsDeletable() const {
1768 return !from().IsTagged() || value()->type().IsSmi(); 1881 return !from().IsTagged() || value()->type().IsSmi();
1769 } 1882 }
1770 }; 1883 };
1771 1884
1772 1885
1773 class HClampToUint8: public HUnaryOperation { 1886 class HClampToUint8: public HUnaryOperation {
1774 public: 1887 public:
1775 explicit HClampToUint8(HValue* value) 1888 DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*);
1776 : HUnaryOperation(value) {
1777 set_representation(Representation::Integer32());
1778 SetFlag(kAllowUndefinedAsNaN);
1779 SetFlag(kUseGVN);
1780 }
1781 1889
1782 virtual Representation RequiredInputRepresentation(int index) { 1890 virtual Representation RequiredInputRepresentation(int index) {
1783 return Representation::None(); 1891 return Representation::None();
1784 } 1892 }
1785 1893
1786 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) 1894 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1787 1895
1788 protected: 1896 protected:
1789 virtual bool DataEquals(HValue* other) { return true; } 1897 virtual bool DataEquals(HValue* other) { return true; }
1790 1898
1791 private: 1899 private:
1900 explicit HClampToUint8(HValue* value)
1901 : HUnaryOperation(value) {
1902 set_representation(Representation::Integer32());
1903 SetFlag(kAllowUndefinedAsNaN);
1904 SetFlag(kUseGVN);
1905 }
1906
1792 virtual bool IsDeletable() const { return true; } 1907 virtual bool IsDeletable() const { return true; }
1793 }; 1908 };
1794 1909
1795 1910
1796 enum RemovableSimulate { 1911 enum RemovableSimulate {
1797 REMOVABLE_SIMULATE, 1912 REMOVABLE_SIMULATE,
1798 FIXED_SIMULATE 1913 FIXED_SIMULATE
1799 }; 1914 };
1800 1915
1801 1916
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 }; 2053 };
1939 2054
1940 2055
1941 class HStackCheck: public HTemplateInstruction<1> { 2056 class HStackCheck: public HTemplateInstruction<1> {
1942 public: 2057 public:
1943 enum Type { 2058 enum Type {
1944 kFunctionEntry, 2059 kFunctionEntry,
1945 kBackwardsBranch 2060 kBackwardsBranch
1946 }; 2061 };
1947 2062
1948 HStackCheck(HValue* context, Type type) : type_(type) { 2063 DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type);
1949 SetOperandAt(0, context);
1950 SetGVNFlag(kChangesNewSpacePromotion);
1951 }
1952 2064
1953 HValue* context() { return OperandAt(0); } 2065 HValue* context() { return OperandAt(0); }
1954 2066
1955 virtual Representation RequiredInputRepresentation(int index) { 2067 virtual Representation RequiredInputRepresentation(int index) {
1956 return Representation::Tagged(); 2068 return Representation::Tagged();
1957 } 2069 }
1958 2070
1959 void Eliminate() { 2071 void Eliminate() {
1960 // The stack check eliminator might try to eliminate the same stack 2072 // The stack check eliminator might try to eliminate the same stack
1961 // check instruction multiple times. 2073 // check instruction multiple times.
1962 if (IsLinked()) { 2074 if (IsLinked()) {
1963 DeleteAndReplaceWith(NULL); 2075 DeleteAndReplaceWith(NULL);
1964 } 2076 }
1965 } 2077 }
1966 2078
1967 bool is_function_entry() { return type_ == kFunctionEntry; } 2079 bool is_function_entry() { return type_ == kFunctionEntry; }
1968 bool is_backwards_branch() { return type_ == kBackwardsBranch; } 2080 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1969 2081
1970 DECLARE_CONCRETE_INSTRUCTION(StackCheck) 2082 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
1971 2083
1972 private: 2084 private:
2085 HStackCheck(HValue* context, Type type) : type_(type) {
2086 SetOperandAt(0, context);
2087 SetGVNFlag(kChangesNewSpacePromotion);
2088 }
2089
1973 Type type_; 2090 Type type_;
1974 }; 2091 };
1975 2092
1976 2093
1977 enum InliningKind { 2094 enum InliningKind {
1978 NORMAL_RETURN, // Normal function/method call and return. 2095 NORMAL_RETURN, // Normal function/method call and return.
1979 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return. 2096 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return.
1980 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value. 2097 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
1981 GETTER_CALL_RETURN, // Returning from a getter, need to restore context. 2098 GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
1982 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value. 2099 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value.
1983 }; 2100 };
1984 2101
1985 2102
1986 class HArgumentsObject; 2103 class HArgumentsObject;
1987 2104
1988 2105
1989 class HEnterInlined: public HTemplateInstruction<0> { 2106 class HEnterInlined: public HTemplateInstruction<0> {
1990 public: 2107 public:
1991 HEnterInlined(Handle<JSFunction> closure, 2108 static HEnterInlined* New(Zone* zone,
1992 int arguments_count, 2109 HValue* context,
1993 FunctionLiteral* function, 2110 Handle<JSFunction> closure,
1994 InliningKind inlining_kind, 2111 int arguments_count,
1995 Variable* arguments_var, 2112 FunctionLiteral* function,
1996 HArgumentsObject* arguments_object, 2113 InliningKind inlining_kind,
1997 bool undefined_receiver, 2114 Variable* arguments_var,
1998 Zone* zone) 2115 HArgumentsObject* arguments_object,
1999 : closure_(closure), 2116 bool undefined_receiver) {
2000 arguments_count_(arguments_count), 2117 return new(zone) HEnterInlined(closure, arguments_count, function,
2001 arguments_pushed_(false), 2118 inlining_kind, arguments_var,
2002 function_(function), 2119 arguments_object, undefined_receiver, zone);
2003 inlining_kind_(inlining_kind),
2004 arguments_var_(arguments_var),
2005 arguments_object_(arguments_object),
2006 undefined_receiver_(undefined_receiver),
2007 return_targets_(2, zone) {
2008 } 2120 }
2009 2121
2010 void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone); 2122 void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
2011 ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; } 2123 ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; }
2012 2124
2013 virtual void PrintDataTo(StringStream* stream); 2125 virtual void PrintDataTo(StringStream* stream);
2014 2126
2015 Handle<JSFunction> closure() const { return closure_; } 2127 Handle<JSFunction> closure() const { return closure_; }
2016 int arguments_count() const { return arguments_count_; } 2128 int arguments_count() const { return arguments_count_; }
2017 bool arguments_pushed() const { return arguments_pushed_; } 2129 bool arguments_pushed() const { return arguments_pushed_; }
2018 void set_arguments_pushed() { arguments_pushed_ = true; } 2130 void set_arguments_pushed() { arguments_pushed_ = true; }
2019 FunctionLiteral* function() const { return function_; } 2131 FunctionLiteral* function() const { return function_; }
2020 InliningKind inlining_kind() const { return inlining_kind_; } 2132 InliningKind inlining_kind() const { return inlining_kind_; }
2021 bool undefined_receiver() const { return undefined_receiver_; } 2133 bool undefined_receiver() const { return undefined_receiver_; }
2022 2134
2023 virtual Representation RequiredInputRepresentation(int index) { 2135 virtual Representation RequiredInputRepresentation(int index) {
2024 return Representation::None(); 2136 return Representation::None();
2025 } 2137 }
2026 2138
2027 Variable* arguments_var() { return arguments_var_; } 2139 Variable* arguments_var() { return arguments_var_; }
2028 HArgumentsObject* arguments_object() { return arguments_object_; } 2140 HArgumentsObject* arguments_object() { return arguments_object_; }
2029 2141
2030 DECLARE_CONCRETE_INSTRUCTION(EnterInlined) 2142 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
2031 2143
2032 private: 2144 private:
2145 HEnterInlined(Handle<JSFunction> closure,
2146 int arguments_count,
2147 FunctionLiteral* function,
2148 InliningKind inlining_kind,
2149 Variable* arguments_var,
2150 HArgumentsObject* arguments_object,
2151 bool undefined_receiver,
2152 Zone* zone)
2153 : closure_(closure),
2154 arguments_count_(arguments_count),
2155 arguments_pushed_(false),
2156 function_(function),
2157 inlining_kind_(inlining_kind),
2158 arguments_var_(arguments_var),
2159 arguments_object_(arguments_object),
2160 undefined_receiver_(undefined_receiver),
2161 return_targets_(2, zone) {
2162 }
2163
2033 Handle<JSFunction> closure_; 2164 Handle<JSFunction> closure_;
2034 int arguments_count_; 2165 int arguments_count_;
2035 bool arguments_pushed_; 2166 bool arguments_pushed_;
2036 FunctionLiteral* function_; 2167 FunctionLiteral* function_;
2037 InliningKind inlining_kind_; 2168 InliningKind inlining_kind_;
2038 Variable* arguments_var_; 2169 Variable* arguments_var_;
2039 HArgumentsObject* arguments_object_; 2170 HArgumentsObject* arguments_object_;
2040 bool undefined_receiver_; 2171 bool undefined_receiver_;
2041 ZoneList<HBasicBlock*> return_targets_; 2172 ZoneList<HBasicBlock*> return_targets_;
2042 }; 2173 };
2043 2174
2044 2175
2045 class HLeaveInlined: public HTemplateInstruction<0> { 2176 class HLeaveInlined: public HTemplateInstruction<0> {
2046 public: 2177 public:
2047 HLeaveInlined() { } 2178 HLeaveInlined() { }
2048 2179
2049 virtual Representation RequiredInputRepresentation(int index) { 2180 virtual Representation RequiredInputRepresentation(int index) {
2050 return Representation::None(); 2181 return Representation::None();
2051 } 2182 }
2052 2183
2053 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined) 2184 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
2054 }; 2185 };
2055 2186
2056 2187
2057 class HPushArgument: public HUnaryOperation { 2188 class HPushArgument: public HUnaryOperation {
2058 public: 2189 public:
2059 explicit HPushArgument(HValue* value) : HUnaryOperation(value) { 2190 DECLARE_INSTRUCTION_FACTORY_P1(HPushArgument, HValue*);
2060 set_representation(Representation::Tagged());
2061 }
2062 2191
2063 virtual Representation RequiredInputRepresentation(int index) { 2192 virtual Representation RequiredInputRepresentation(int index) {
2064 return Representation::Tagged(); 2193 return Representation::Tagged();
2065 } 2194 }
2066 2195
2067 HValue* argument() { return OperandAt(0); } 2196 HValue* argument() { return OperandAt(0); }
2068 2197
2069 DECLARE_CONCRETE_INSTRUCTION(PushArgument) 2198 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
2199
2200 private:
2201 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
2202 set_representation(Representation::Tagged());
2203 }
2070 }; 2204 };
2071 2205
2072 2206
2073 class HThisFunction: public HTemplateInstruction<0> { 2207 class HThisFunction: public HTemplateInstruction<0> {
2074 public: 2208 public:
2075 HThisFunction() { 2209 HThisFunction() {
2076 set_representation(Representation::Tagged()); 2210 set_representation(Representation::Tagged());
2077 SetFlag(kUseGVN); 2211 SetFlag(kUseGVN);
2078 } 2212 }
2079 2213
2080 virtual Representation RequiredInputRepresentation(int index) { 2214 virtual Representation RequiredInputRepresentation(int index) {
2081 return Representation::None(); 2215 return Representation::None();
2082 } 2216 }
2083 2217
2084 DECLARE_CONCRETE_INSTRUCTION(ThisFunction) 2218 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
2085 2219
2086 protected: 2220 protected:
2087 virtual bool DataEquals(HValue* other) { return true; } 2221 virtual bool DataEquals(HValue* other) { return true; }
2088 2222
2089 private: 2223 private:
2090 virtual bool IsDeletable() const { return true; } 2224 virtual bool IsDeletable() const { return true; }
2091 }; 2225 };
2092 2226
2093 2227
2094 class HContext: public HTemplateInstruction<0> {
2095 public:
2096 HContext() {
2097 set_representation(Representation::Tagged());
2098 SetFlag(kUseGVN);
2099 }
2100
2101 virtual Representation RequiredInputRepresentation(int index) {
2102 return Representation::None();
2103 }
2104
2105 DECLARE_CONCRETE_INSTRUCTION(Context)
2106
2107 protected:
2108 virtual bool DataEquals(HValue* other) { return true; }
2109
2110 private:
2111 virtual bool IsDeletable() const { return true; }
2112 };
2113
2114
2115 class HOuterContext: public HUnaryOperation { 2228 class HOuterContext: public HUnaryOperation {
2116 public: 2229 public:
2117 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { 2230 DECLARE_INSTRUCTION_FACTORY_P1(HOuterContext, HValue*);
2118 set_representation(Representation::Tagged());
2119 SetFlag(kUseGVN);
2120 }
2121 2231
2122 DECLARE_CONCRETE_INSTRUCTION(OuterContext); 2232 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
2123 2233
2124 virtual Representation RequiredInputRepresentation(int index) { 2234 virtual Representation RequiredInputRepresentation(int index) {
2125 return Representation::Tagged(); 2235 return Representation::Tagged();
2126 } 2236 }
2127 2237
2128 protected: 2238 protected:
2129 virtual bool DataEquals(HValue* other) { return true; } 2239 virtual bool DataEquals(HValue* other) { return true; }
2130 2240
2131 private: 2241 private:
2242 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
2243 set_representation(Representation::Tagged());
2244 SetFlag(kUseGVN);
2245 }
2246
2132 virtual bool IsDeletable() const { return true; } 2247 virtual bool IsDeletable() const { return true; }
2133 }; 2248 };
2134 2249
2135 2250
2136 class HDeclareGlobals: public HUnaryOperation { 2251 class HDeclareGlobals: public HUnaryOperation {
2137 public: 2252 public:
2138 HDeclareGlobals(HValue* context, 2253 HDeclareGlobals(HValue* context,
2139 Handle<FixedArray> pairs, 2254 Handle<FixedArray> pairs,
2140 int flags) 2255 int flags)
2141 : HUnaryOperation(context), 2256 : HUnaryOperation(context),
2142 pairs_(pairs), 2257 pairs_(pairs),
2143 flags_(flags) { 2258 flags_(flags) {
2144 set_representation(Representation::Tagged()); 2259 set_representation(Representation::Tagged());
2145 SetAllSideEffects(); 2260 SetAllSideEffects();
2146 } 2261 }
2147 2262
2263 static HDeclareGlobals* New(Zone* zone,
2264 HValue* context,
2265 Handle<FixedArray> pairs,
2266 int flags) {
2267 return new(zone) HDeclareGlobals(context, pairs, flags);
2268 }
2269
2148 HValue* context() { return OperandAt(0); } 2270 HValue* context() { return OperandAt(0); }
2149 Handle<FixedArray> pairs() const { return pairs_; } 2271 Handle<FixedArray> pairs() const { return pairs_; }
2150 int flags() const { return flags_; } 2272 int flags() const { return flags_; }
2151 2273
2152 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals) 2274 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
2153 2275
2154 virtual Representation RequiredInputRepresentation(int index) { 2276 virtual Representation RequiredInputRepresentation(int index) {
2155 return Representation::Tagged(); 2277 return Representation::Tagged();
2156 } 2278 }
2279
2157 private: 2280 private:
2158 Handle<FixedArray> pairs_; 2281 Handle<FixedArray> pairs_;
2159 int flags_; 2282 int flags_;
2160 }; 2283 };
2161 2284
2162 2285
2163 class HGlobalObject: public HUnaryOperation { 2286 class HGlobalObject: public HUnaryOperation {
2164 public: 2287 public:
2165 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { 2288 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
2166 set_representation(Representation::Tagged()); 2289 set_representation(Representation::Tagged());
2167 SetFlag(kUseGVN); 2290 SetFlag(kUseGVN);
2168 } 2291 }
2169 2292
2293 static HGlobalObject* New(Zone* zone, HValue* context) {
2294 return new(zone) HGlobalObject(context);
2295 }
2296
2170 DECLARE_CONCRETE_INSTRUCTION(GlobalObject) 2297 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
2171 2298
2172 virtual Representation RequiredInputRepresentation(int index) { 2299 virtual Representation RequiredInputRepresentation(int index) {
2173 return Representation::Tagged(); 2300 return Representation::Tagged();
2174 } 2301 }
2175 2302
2176 protected: 2303 protected:
2177 virtual bool DataEquals(HValue* other) { return true; } 2304 virtual bool DataEquals(HValue* other) { return true; }
2178 2305
2179 private: 2306 private:
2180 virtual bool IsDeletable() const { return true; } 2307 virtual bool IsDeletable() const { return true; }
2181 }; 2308 };
2182 2309
2183 2310
2184 class HGlobalReceiver: public HUnaryOperation { 2311 class HGlobalReceiver: public HUnaryOperation {
2185 public: 2312 public:
2186 explicit HGlobalReceiver(HValue* global_object) 2313 DECLARE_INSTRUCTION_FACTORY_P1(HGlobalReceiver, HValue*);
2187 : HUnaryOperation(global_object) {
2188 set_representation(Representation::Tagged());
2189 SetFlag(kUseGVN);
2190 }
2191 2314
2192 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver) 2315 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
2193 2316
2194 virtual Representation RequiredInputRepresentation(int index) { 2317 virtual Representation RequiredInputRepresentation(int index) {
2195 return Representation::Tagged(); 2318 return Representation::Tagged();
2196 } 2319 }
2197 2320
2198 protected: 2321 protected:
2199 virtual bool DataEquals(HValue* other) { return true; } 2322 virtual bool DataEquals(HValue* other) { return true; }
2200 2323
2201 private: 2324 private:
2325 explicit HGlobalReceiver(HValue* global_object)
2326 : HUnaryOperation(global_object) {
2327 set_representation(Representation::Tagged());
2328 SetFlag(kUseGVN);
2329 }
2330
2202 virtual bool IsDeletable() const { return true; } 2331 virtual bool IsDeletable() const { return true; }
2203 }; 2332 };
2204 2333
2205 2334
2206 template <int V> 2335 template <int V>
2207 class HCall: public HTemplateInstruction<V> { 2336 class HCall: public HTemplateInstruction<V> {
2208 public: 2337 public:
2209 // The argument count includes the receiver. 2338 // The argument count includes the receiver.
2210 explicit HCall<V>(int argument_count) : argument_count_(argument_count) { 2339 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
2211 this->set_representation(Representation::Tagged()); 2340 this->set_representation(Representation::Tagged());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 HValue* second() { return OperandAt(1); } 2387 HValue* second() { return OperandAt(1); }
2259 }; 2388 };
2260 2389
2261 2390
2262 class HInvokeFunction: public HBinaryCall { 2391 class HInvokeFunction: public HBinaryCall {
2263 public: 2392 public:
2264 HInvokeFunction(HValue* context, HValue* function, int argument_count) 2393 HInvokeFunction(HValue* context, HValue* function, int argument_count)
2265 : HBinaryCall(context, function, argument_count) { 2394 : HBinaryCall(context, function, argument_count) {
2266 } 2395 }
2267 2396
2397 static HInvokeFunction* New(Zone* zone,
2398 HValue* context,
2399 HValue* function,
2400 int argument_count) {
2401 return new(zone) HInvokeFunction(context, function, argument_count);
2402 }
2403
2268 HInvokeFunction(HValue* context, 2404 HInvokeFunction(HValue* context,
2269 HValue* function, 2405 HValue* function,
2270 Handle<JSFunction> known_function, 2406 Handle<JSFunction> known_function,
2271 int argument_count) 2407 int argument_count)
2272 : HBinaryCall(context, function, argument_count), 2408 : HBinaryCall(context, function, argument_count),
2273 known_function_(known_function) { 2409 known_function_(known_function) {
2274 formal_parameter_count_ = known_function.is_null() 2410 formal_parameter_count_ = known_function.is_null()
2275 ? 0 : known_function->shared()->formal_parameter_count(); 2411 ? 0 : known_function->shared()->formal_parameter_count();
2276 } 2412 }
2277 2413
2414 static HInvokeFunction* New(Zone* zone,
2415 HValue* context,
2416 HValue* function,
2417 Handle<JSFunction> known_function,
2418 int argument_count) {
2419 return new(zone) HInvokeFunction(context, function,
2420 known_function, argument_count);
2421 }
2422
2278 virtual Representation RequiredInputRepresentation(int index) { 2423 virtual Representation RequiredInputRepresentation(int index) {
2279 return Representation::Tagged(); 2424 return Representation::Tagged();
2280 } 2425 }
2281 2426
2282 HValue* context() { return first(); } 2427 HValue* context() { return first(); }
2283 HValue* function() { return second(); } 2428 HValue* function() { return second(); }
2284 Handle<JSFunction> known_function() { return known_function_; } 2429 Handle<JSFunction> known_function() { return known_function_; }
2285 int formal_parameter_count() const { return formal_parameter_count_; } 2430 int formal_parameter_count() const { return formal_parameter_count_; }
2286 2431
2287 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) 2432 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2359 Handle<String> name_; 2504 Handle<String> name_;
2360 }; 2505 };
2361 2506
2362 2507
2363 class HCallFunction: public HBinaryCall { 2508 class HCallFunction: public HBinaryCall {
2364 public: 2509 public:
2365 HCallFunction(HValue* context, HValue* function, int argument_count) 2510 HCallFunction(HValue* context, HValue* function, int argument_count)
2366 : HBinaryCall(context, function, argument_count) { 2511 : HBinaryCall(context, function, argument_count) {
2367 } 2512 }
2368 2513
2514 static HCallFunction* New(Zone* zone,
2515 HValue* context,
2516 HValue* function,
2517 int argument_count) {
2518 return new(zone) HCallFunction(context, function, argument_count);
2519 }
2520
2369 HValue* context() { return first(); } 2521 HValue* context() { return first(); }
2370 HValue* function() { return second(); } 2522 HValue* function() { return second(); }
2371 2523
2372 virtual Representation RequiredInputRepresentation(int index) { 2524 virtual Representation RequiredInputRepresentation(int index) {
2373 return Representation::Tagged(); 2525 return Representation::Tagged();
2374 } 2526 }
2375 2527
2376 DECLARE_CONCRETE_INSTRUCTION(CallFunction) 2528 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
2377 }; 2529 };
2378 2530
2379 2531
2380 class HCallGlobal: public HUnaryCall { 2532 class HCallGlobal: public HUnaryCall {
2381 public: 2533 public:
2382 HCallGlobal(HValue* context, Handle<String> name, int argument_count) 2534 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
2383 : HUnaryCall(context, argument_count), name_(name) { 2535 : HUnaryCall(context, argument_count), name_(name) {
2384 } 2536 }
2385 2537
2538 static HCallGlobal* New(Zone* zone,
2539 HValue* context,
2540 Handle<String> name,
2541 int argument_count) {
2542 return new(zone) HCallGlobal(context, name, argument_count);
2543 }
2544
2386 virtual void PrintDataTo(StringStream* stream); 2545 virtual void PrintDataTo(StringStream* stream);
2387 2546
2388 HValue* context() { return value(); } 2547 HValue* context() { return value(); }
2389 Handle<String> name() const { return name_; } 2548 Handle<String> name() const { return name_; }
2390 2549
2391 virtual Representation RequiredInputRepresentation(int index) { 2550 virtual Representation RequiredInputRepresentation(int index) {
2392 return Representation::Tagged(); 2551 return Representation::Tagged();
2393 } 2552 }
2394 2553
2395 DECLARE_CONCRETE_INSTRUCTION(CallGlobal) 2554 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 DECLARE_CONCRETE_INSTRUCTION(CallNewArray) 2618 DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
2460 2619
2461 private: 2620 private:
2462 ElementsKind elements_kind_; 2621 ElementsKind elements_kind_;
2463 Handle<Cell> type_cell_; 2622 Handle<Cell> type_cell_;
2464 }; 2623 };
2465 2624
2466 2625
2467 class HCallRuntime: public HCall<1> { 2626 class HCallRuntime: public HCall<1> {
2468 public: 2627 public:
2469 HCallRuntime(HValue* context, 2628 static HCallRuntime* New(Zone* zone,
2470 Handle<String> name, 2629 HValue* context,
2471 const Runtime::Function* c_function, 2630 Handle<String> name,
2472 int argument_count) 2631 const Runtime::Function* c_function,
2473 : HCall<1>(argument_count), c_function_(c_function), name_(name) { 2632 int argument_count) {
2474 SetOperandAt(0, context); 2633 return new(zone) HCallRuntime(context, name, c_function, argument_count);
2475 } 2634 }
2476 2635
2477 virtual void PrintDataTo(StringStream* stream); 2636 virtual void PrintDataTo(StringStream* stream);
2478 2637
2479 HValue* context() { return OperandAt(0); } 2638 HValue* context() { return OperandAt(0); }
2480 const Runtime::Function* function() const { return c_function_; } 2639 const Runtime::Function* function() const { return c_function_; }
2481 Handle<String> name() const { return name_; } 2640 Handle<String> name() const { return name_; }
2482 2641
2483 virtual Representation RequiredInputRepresentation(int index) { 2642 virtual Representation RequiredInputRepresentation(int index) {
2484 return Representation::Tagged(); 2643 return Representation::Tagged();
2485 } 2644 }
2486 2645
2487 DECLARE_CONCRETE_INSTRUCTION(CallRuntime) 2646 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
2488 2647
2489 private: 2648 private:
2649 HCallRuntime(HValue* context,
2650 Handle<String> name,
2651 const Runtime::Function* c_function,
2652 int argument_count)
2653 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
2654 SetOperandAt(0, context);
2655 }
2656
2490 const Runtime::Function* c_function_; 2657 const Runtime::Function* c_function_;
2491 Handle<String> name_; 2658 Handle<String> name_;
2492 }; 2659 };
2493 2660
2494 2661
2495 class HMapEnumLength: public HUnaryOperation { 2662 class HMapEnumLength: public HUnaryOperation {
2496 public: 2663 public:
2497 explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) { 2664 DECLARE_INSTRUCTION_FACTORY_P1(HMapEnumLength, HValue*);
2498 set_type(HType::Smi());
2499 set_representation(Representation::Smi());
2500 SetFlag(kUseGVN);
2501 SetGVNFlag(kDependsOnMaps);
2502 }
2503 2665
2504 virtual Representation RequiredInputRepresentation(int index) { 2666 virtual Representation RequiredInputRepresentation(int index) {
2505 return Representation::Tagged(); 2667 return Representation::Tagged();
2506 } 2668 }
2507 2669
2508 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength) 2670 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
2509 2671
2510 protected: 2672 protected:
2511 virtual bool DataEquals(HValue* other) { return true; } 2673 virtual bool DataEquals(HValue* other) { return true; }
2512 2674
2513 private: 2675 private:
2676 explicit HMapEnumLength(HValue* value)
2677 : HUnaryOperation(value, HType::Smi()) {
2678 set_representation(Representation::Smi());
2679 SetFlag(kUseGVN);
2680 SetGVNFlag(kDependsOnMaps);
2681 }
2682
2514 virtual bool IsDeletable() const { return true; } 2683 virtual bool IsDeletable() const { return true; }
2515 }; 2684 };
2516 2685
2517 2686
2518 class HElementsKind: public HUnaryOperation { 2687 class HElementsKind: public HUnaryOperation {
2519 public: 2688 public:
2520 explicit HElementsKind(HValue* value) : HUnaryOperation(value) { 2689 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
2521 set_representation(Representation::Integer32()); 2690 set_representation(Representation::Integer32());
2522 SetFlag(kUseGVN); 2691 SetFlag(kUseGVN);
2523 SetGVNFlag(kDependsOnElementsKind); 2692 SetGVNFlag(kDependsOnElementsKind);
2524 } 2693 }
2525 2694
2526 virtual Representation RequiredInputRepresentation(int index) { 2695 virtual Representation RequiredInputRepresentation(int index) {
2527 return Representation::Tagged(); 2696 return Representation::Tagged();
2528 } 2697 }
2529 2698
2530 DECLARE_CONCRETE_INSTRUCTION(ElementsKind) 2699 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
2531 2700
2532 protected: 2701 protected:
2533 virtual bool DataEquals(HValue* other) { return true; } 2702 virtual bool DataEquals(HValue* other) { return true; }
2534 2703
2535 private: 2704 private:
2536 virtual bool IsDeletable() const { return true; } 2705 virtual bool IsDeletable() const { return true; }
2537 }; 2706 };
2538 2707
2539 2708
2540 class HBitNot: public HUnaryOperation { 2709 class HBitNot: public HUnaryOperation {
2541 public: 2710 public:
2542 explicit HBitNot(HValue* value) : HUnaryOperation(value) { 2711 DECLARE_INSTRUCTION_FACTORY_P1(HBitNot, HValue*);
2543 set_representation(Representation::Integer32());
2544 SetFlag(kUseGVN);
2545 SetFlag(kTruncatingToInt32);
2546 SetFlag(kAllowUndefinedAsNaN);
2547 }
2548 2712
2549 virtual Representation RequiredInputRepresentation(int index) { 2713 virtual Representation RequiredInputRepresentation(int index) {
2550 return Representation::Integer32(); 2714 return Representation::Integer32();
2551 } 2715 }
2552 virtual Representation observed_input_representation(int index) { 2716 virtual Representation observed_input_representation(int index) {
2553 return Representation::Integer32(); 2717 return Representation::Integer32();
2554 } 2718 }
2555 virtual HType CalculateInferredType();
2556 2719
2557 virtual HValue* Canonicalize(); 2720 virtual HValue* Canonicalize();
2558 2721
2559 DECLARE_CONCRETE_INSTRUCTION(BitNot) 2722 DECLARE_CONCRETE_INSTRUCTION(BitNot)
2560 2723
2561 protected: 2724 protected:
2562 virtual bool DataEquals(HValue* other) { return true; } 2725 virtual bool DataEquals(HValue* other) { return true; }
2563 2726
2564 private: 2727 private:
2728 explicit HBitNot(HValue* value)
2729 : HUnaryOperation(value, HType::TaggedNumber()) {
2730 set_representation(Representation::Integer32());
2731 SetFlag(kUseGVN);
2732 SetFlag(kTruncatingToInt32);
2733 SetFlag(kAllowUndefinedAsNaN);
2734 }
2735
2565 virtual bool IsDeletable() const { return true; } 2736 virtual bool IsDeletable() const { return true; }
2566 }; 2737 };
2567 2738
2568 2739
2569 class HUnaryMathOperation: public HTemplateInstruction<2> { 2740 class HUnaryMathOperation: public HTemplateInstruction<2> {
2570 public: 2741 public:
2571 static HInstruction* New(Zone* zone, 2742 static HInstruction* New(Zone* zone,
2572 HValue* context, 2743 HValue* context,
2573 HValue* value, 2744 HValue* value,
2574 BuiltinFunctionId op); 2745 BuiltinFunctionId op);
2575 2746
2576 HValue* context() { return OperandAt(0); } 2747 HValue* context() { return OperandAt(0); }
2577 HValue* value() { return OperandAt(1); } 2748 HValue* value() { return OperandAt(1); }
2578 2749
2579 virtual void PrintDataTo(StringStream* stream); 2750 virtual void PrintDataTo(StringStream* stream);
2580 2751
2581 virtual HType CalculateInferredType();
2582
2583 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 2752 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2584 2753
2585 virtual Representation RequiredInputRepresentation(int index) { 2754 virtual Representation RequiredInputRepresentation(int index) {
2586 if (index == 0) { 2755 if (index == 0) {
2587 return Representation::Tagged(); 2756 return Representation::Tagged();
2588 } else { 2757 } else {
2589 switch (op_) { 2758 switch (op_) {
2590 case kMathFloor: 2759 case kMathFloor:
2591 case kMathRound: 2760 case kMathRound:
2592 case kMathSqrt: 2761 case kMathSqrt:
(...skipping 24 matching lines...) Expand all
2617 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation) 2786 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
2618 2787
2619 protected: 2788 protected:
2620 virtual bool DataEquals(HValue* other) { 2789 virtual bool DataEquals(HValue* other) {
2621 HUnaryMathOperation* b = HUnaryMathOperation::cast(other); 2790 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
2622 return op_ == b->op(); 2791 return op_ == b->op();
2623 } 2792 }
2624 2793
2625 private: 2794 private:
2626 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) 2795 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2627 : op_(op) { 2796 : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
2628 SetOperandAt(0, context); 2797 SetOperandAt(0, context);
2629 SetOperandAt(1, value); 2798 SetOperandAt(1, value);
2630 switch (op) { 2799 switch (op) {
2631 case kMathFloor: 2800 case kMathFloor:
2632 case kMathRound: 2801 case kMathRound:
2633 // TODO(verwaest): Set representation to flexible int starting as smi. 2802 // TODO(verwaest): Set representation to flexible int starting as smi.
2634 set_representation(Representation::Integer32()); 2803 set_representation(Representation::Integer32());
2635 break; 2804 break;
2636 case kMathAbs: 2805 case kMathAbs:
2637 // Not setting representation here: it is None intentionally. 2806 // Not setting representation here: it is None intentionally.
(...skipping 23 matching lines...) Expand all
2661 } 2830 }
2662 2831
2663 virtual bool IsDeletable() const { return true; } 2832 virtual bool IsDeletable() const { return true; }
2664 2833
2665 BuiltinFunctionId op_; 2834 BuiltinFunctionId op_;
2666 }; 2835 };
2667 2836
2668 2837
2669 class HLoadExternalArrayPointer: public HUnaryOperation { 2838 class HLoadExternalArrayPointer: public HUnaryOperation {
2670 public: 2839 public:
2840 DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*);
2841
2842 virtual Representation RequiredInputRepresentation(int index) {
2843 return Representation::Tagged();
2844 }
2845
2846 virtual HType CalculateInferredType() {
2847 return HType::None();
2848 }
2849
2850 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
2851
2852 protected:
2853 virtual bool DataEquals(HValue* other) { return true; }
2854
2855 private:
2671 explicit HLoadExternalArrayPointer(HValue* value) 2856 explicit HLoadExternalArrayPointer(HValue* value)
2672 : HUnaryOperation(value) { 2857 : HUnaryOperation(value) {
2673 set_representation(Representation::External()); 2858 set_representation(Representation::External());
2674 // The result of this instruction is idempotent as long as its inputs don't 2859 // The result of this instruction is idempotent as long as its inputs don't
2675 // change. The external array of a specialized array elements object cannot 2860 // change. The external array of a specialized array elements object cannot
2676 // change once set, so it's no necessary to introduce any additional 2861 // change once set, so it's no necessary to introduce any additional
2677 // dependencies on top of the inputs. 2862 // dependencies on top of the inputs.
2678 SetFlag(kUseGVN); 2863 SetFlag(kUseGVN);
2679 } 2864 }
2680 2865
2681 virtual Representation RequiredInputRepresentation(int index) {
2682 return Representation::Tagged();
2683 }
2684
2685 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
2686
2687 protected:
2688 virtual bool DataEquals(HValue* other) { return true; }
2689
2690 private:
2691 virtual bool IsDeletable() const { return true; } 2866 virtual bool IsDeletable() const { return true; }
2692 }; 2867 };
2693 2868
2694 2869
2695 class HCheckMaps: public HTemplateInstruction<2> { 2870 class HCheckMaps: public HTemplateInstruction<2> {
2696 public: 2871 public:
2697 static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone, 2872 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
2698 CompilationInfo* info, HValue *typecheck = NULL); 2873 Handle<Map> map, CompilationInfo* info,
2699 static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone, 2874 HValue *typecheck = NULL);
2875 static HCheckMaps* New(Zone* zone, HValue* context,
2876 HValue* value, SmallMapList* maps,
2700 HValue *typecheck = NULL) { 2877 HValue *typecheck = NULL) {
2701 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); 2878 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2702 for (int i = 0; i < maps->length(); i++) { 2879 for (int i = 0; i < maps->length(); i++) {
2703 check_map->map_set_.Add(maps->at(i), zone); 2880 check_map->map_set_.Add(maps->at(i), zone);
2704 } 2881 }
2705 check_map->map_set_.Sort(); 2882 check_map->map_set_.Sort();
2706 return check_map; 2883 return check_map;
2707 } 2884 }
2708 2885
2709 static HCheckMaps* NewWithTransitions(HValue* value, Handle<Map> map,
2710 Zone* zone, CompilationInfo* info);
2711
2712 bool CanOmitMapChecks() { return omit_; } 2886 bool CanOmitMapChecks() { return omit_; }
2713 2887
2714 virtual bool HasEscapingOperandAt(int index) { return false; } 2888 virtual bool HasEscapingOperandAt(int index) { return false; }
2715 virtual Representation RequiredInputRepresentation(int index) { 2889 virtual Representation RequiredInputRepresentation(int index) {
2716 return Representation::Tagged(); 2890 return Representation::Tagged();
2717 } 2891 }
2718 virtual void HandleSideEffectDominator(GVNFlag side_effect, 2892 virtual void HandleSideEffectDominator(GVNFlag side_effect,
2719 HValue* dominator); 2893 HValue* dominator);
2720 virtual void PrintDataTo(StringStream* stream); 2894 virtual void PrintDataTo(StringStream* stream);
2721 virtual HType CalculateInferredType();
2722 2895
2723 HValue* value() { return OperandAt(0); } 2896 HValue* value() { return OperandAt(0); }
2724 SmallMapList* map_set() { return &map_set_; } 2897 SmallMapList* map_set() { return &map_set_; }
2725 2898
2726 virtual void FinalizeUniqueValueId(); 2899 virtual void FinalizeUniqueValueId();
2727 2900
2728 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) 2901 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2729 2902
2730 protected: 2903 protected:
2731 virtual bool DataEquals(HValue* other) { 2904 virtual bool DataEquals(HValue* other) {
2732 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); 2905 ASSERT_EQ(map_set_.length(), map_unique_ids_.length());
2733 HCheckMaps* b = HCheckMaps::cast(other); 2906 HCheckMaps* b = HCheckMaps::cast(other);
2734 // Relies on the fact that map_set has been sorted before. 2907 // Relies on the fact that map_set has been sorted before.
2735 if (map_unique_ids_.length() != b->map_unique_ids_.length()) { 2908 if (map_unique_ids_.length() != b->map_unique_ids_.length()) {
2736 return false; 2909 return false;
2737 } 2910 }
2738 for (int i = 0; i < map_unique_ids_.length(); i++) { 2911 for (int i = 0; i < map_unique_ids_.length(); i++) {
2739 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { 2912 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) {
2740 return false; 2913 return false;
2741 } 2914 }
2742 } 2915 }
2743 return true; 2916 return true;
2744 } 2917 }
2745 2918
2746 private: 2919 private:
2747 // Clients should use one of the static New* methods above. 2920 // Clients should use one of the static New* methods above.
2748 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) 2921 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
2749 : omit_(false), map_unique_ids_(0, zone) { 2922 : HTemplateInstruction<2>(value->type()),
2923 omit_(false), map_unique_ids_(0, zone) {
2750 SetOperandAt(0, value); 2924 SetOperandAt(0, value);
2751 // Use the object value for the dependency if NULL is passed. 2925 // Use the object value for the dependency if NULL is passed.
2752 // TODO(titzer): do GVN flags already express this dependency? 2926 // TODO(titzer): do GVN flags already express this dependency?
2753 SetOperandAt(1, typecheck != NULL ? typecheck : value); 2927 SetOperandAt(1, typecheck != NULL ? typecheck : value);
2754 set_representation(Representation::Tagged()); 2928 set_representation(Representation::Tagged());
2755 SetFlag(kUseGVN); 2929 SetFlag(kUseGVN);
2756 SetFlag(kTrackSideEffectDominators); 2930 SetFlag(kTrackSideEffectDominators);
2757 SetGVNFlag(kDependsOnMaps); 2931 SetGVNFlag(kDependsOnMaps);
2758 SetGVNFlag(kDependsOnElementsKind); 2932 SetGVNFlag(kDependsOnElementsKind);
2759 } 2933 }
2760 2934
2761 void omit(CompilationInfo* info) { 2935 void omit(CompilationInfo* info) {
2762 omit_ = true; 2936 omit_ = true;
2763 for (int i = 0; i < map_set_.length(); i++) { 2937 for (int i = 0; i < map_set_.length(); i++) {
2764 Handle<Map> map = map_set_.at(i); 2938 Handle<Map> map = map_set_.at(i);
2765 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, 2939 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
2766 info); 2940 info);
2767 } 2941 }
2768 } 2942 }
2769 2943
2770 bool omit_; 2944 bool omit_;
2771 SmallMapList map_set_; 2945 SmallMapList map_set_;
2772 ZoneList<UniqueValueId> map_unique_ids_; 2946 ZoneList<UniqueValueId> map_unique_ids_;
2773 }; 2947 };
2774 2948
2775 2949
2776 class HCheckFunction: public HUnaryOperation { 2950 class HCheckFunction: public HUnaryOperation {
2777 public: 2951 public:
2778 HCheckFunction(HValue* value, Handle<JSFunction> function) 2952 DECLARE_INSTRUCTION_FACTORY_P2(HCheckFunction, HValue*, Handle<JSFunction>);
2779 : HUnaryOperation(value), target_(function), target_unique_id_() {
2780 set_representation(Representation::Tagged());
2781 SetFlag(kUseGVN);
2782 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
2783 }
2784 2953
2785 virtual Representation RequiredInputRepresentation(int index) { 2954 virtual Representation RequiredInputRepresentation(int index) {
2786 return Representation::Tagged(); 2955 return Representation::Tagged();
2787 } 2956 }
2788 virtual void PrintDataTo(StringStream* stream); 2957 virtual void PrintDataTo(StringStream* stream);
2789 virtual HType CalculateInferredType();
2790 2958
2791 virtual HValue* Canonicalize(); 2959 virtual HValue* Canonicalize();
2792 2960
2793 #ifdef DEBUG 2961 #ifdef DEBUG
2794 virtual void Verify(); 2962 virtual void Verify();
2795 #endif 2963 #endif
2796 2964
2797 virtual void FinalizeUniqueValueId() { 2965 virtual void FinalizeUniqueValueId() {
2798 target_unique_id_ = UniqueValueId(target_); 2966 target_unique_id_ = UniqueValueId(target_);
2799 } 2967 }
2800 2968
2801 Handle<JSFunction> target() const { return target_; } 2969 Handle<JSFunction> target() const { return target_; }
2802 bool target_in_new_space() const { return target_in_new_space_; } 2970 bool target_in_new_space() const { return target_in_new_space_; }
2803 2971
2804 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) 2972 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
2805 2973
2806 protected: 2974 protected:
2807 virtual bool DataEquals(HValue* other) { 2975 virtual bool DataEquals(HValue* other) {
2808 HCheckFunction* b = HCheckFunction::cast(other); 2976 HCheckFunction* b = HCheckFunction::cast(other);
2809 return target_unique_id_ == b->target_unique_id_; 2977 return target_unique_id_ == b->target_unique_id_;
2810 } 2978 }
2811 2979
2812 private: 2980 private:
2981 HCheckFunction(HValue* value, Handle<JSFunction> function)
2982 : HUnaryOperation(value, value->type()),
2983 target_(function), target_unique_id_() {
2984 set_representation(Representation::Tagged());
2985 SetFlag(kUseGVN);
2986 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
2987 }
2988
2813 Handle<JSFunction> target_; 2989 Handle<JSFunction> target_;
2814 UniqueValueId target_unique_id_; 2990 UniqueValueId target_unique_id_;
2815 bool target_in_new_space_; 2991 bool target_in_new_space_;
2816 }; 2992 };
2817 2993
2818 2994
2819 class HCheckInstanceType: public HUnaryOperation { 2995 class HCheckInstanceType: public HUnaryOperation {
2820 public: 2996 public:
2821 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { 2997 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) {
2822 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); 2998 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2871 set_representation(Representation::Tagged()); 3047 set_representation(Representation::Tagged());
2872 SetFlag(kUseGVN); 3048 SetFlag(kUseGVN);
2873 } 3049 }
2874 3050
2875 const Check check_; 3051 const Check check_;
2876 }; 3052 };
2877 3053
2878 3054
2879 class HCheckSmi: public HUnaryOperation { 3055 class HCheckSmi: public HUnaryOperation {
2880 public: 3056 public:
2881 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { 3057 DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*);
2882 set_representation(Representation::Smi());
2883 SetFlag(kUseGVN);
2884 }
2885 3058
2886 virtual Representation RequiredInputRepresentation(int index) { 3059 virtual Representation RequiredInputRepresentation(int index) {
2887 return Representation::Tagged(); 3060 return Representation::Tagged();
2888 } 3061 }
2889 3062
2890 virtual HType CalculateInferredType();
2891
2892 virtual HValue* Canonicalize() { 3063 virtual HValue* Canonicalize() {
2893 HType value_type = value()->type(); 3064 HType value_type = value()->type();
2894 if (value_type.IsSmi()) { 3065 if (value_type.IsSmi()) {
2895 return NULL; 3066 return NULL;
2896 } 3067 }
2897 return this; 3068 return this;
2898 } 3069 }
2899 3070
2900 DECLARE_CONCRETE_INSTRUCTION(CheckSmi) 3071 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
2901 3072
2902 protected: 3073 protected:
2903 virtual bool DataEquals(HValue* other) { return true; } 3074 virtual bool DataEquals(HValue* other) { return true; }
3075
3076 private:
3077 explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) {
3078 set_representation(Representation::Smi());
3079 SetFlag(kUseGVN);
3080 }
2904 }; 3081 };
2905 3082
2906 3083
2907 class HIsNumberAndBranch: public HUnaryControlInstruction { 3084 class HIsNumberAndBranch: public HUnaryControlInstruction {
2908 public: 3085 public:
2909 explicit HIsNumberAndBranch(HValue* value) 3086 explicit HIsNumberAndBranch(HValue* value)
2910 : HUnaryControlInstruction(value, NULL, NULL) { 3087 : HUnaryControlInstruction(value, NULL, NULL) {
2911 SetFlag(kFlexibleRepresentation); 3088 SetFlag(kFlexibleRepresentation);
2912 } 3089 }
2913 3090
2914 virtual Representation RequiredInputRepresentation(int index) { 3091 virtual Representation RequiredInputRepresentation(int index) {
2915 return Representation::None(); 3092 return Representation::None();
2916 } 3093 }
2917 3094
2918 DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch) 3095 DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch)
2919 }; 3096 };
2920 3097
2921 3098
2922 class HCheckHeapObject: public HUnaryOperation { 3099 class HCheckHeapObject: public HUnaryOperation {
2923 public: 3100 public:
2924 explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) { 3101 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
2925 set_representation(Representation::Tagged());
2926 SetFlag(kUseGVN);
2927 }
2928 3102
2929 virtual Representation RequiredInputRepresentation(int index) { 3103 virtual Representation RequiredInputRepresentation(int index) {
2930 return Representation::Tagged(); 3104 return Representation::Tagged();
2931 } 3105 }
2932 3106
2933 virtual HType CalculateInferredType();
2934
2935 #ifdef DEBUG 3107 #ifdef DEBUG
2936 virtual void Verify(); 3108 virtual void Verify();
2937 #endif 3109 #endif
2938 3110
2939 virtual HValue* Canonicalize() { 3111 virtual HValue* Canonicalize() {
2940 HType value_type = value()->type(); 3112 return value()->type().IsHeapObject() ? NULL : this;
2941 if (!value_type.IsUninitialized() && value_type.IsHeapObject()) {
2942 return NULL;
2943 }
2944 return this;
2945 } 3113 }
2946 3114
2947 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) 3115 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
2948 3116
2949 protected: 3117 protected:
2950 virtual bool DataEquals(HValue* other) { return true; } 3118 virtual bool DataEquals(HValue* other) { return true; }
3119
3120 private:
3121 explicit HCheckHeapObject(HValue* value)
3122 : HUnaryOperation(value, HType::NonPrimitive()) {
3123 set_representation(Representation::Tagged());
3124 SetFlag(kUseGVN);
3125 }
2951 }; 3126 };
2952 3127
2953 3128
2954 class HCheckPrototypeMaps: public HTemplateInstruction<0> { 3129 class HCheckPrototypeMaps: public HTemplateInstruction<0> {
2955 public: 3130 public:
2956 HCheckPrototypeMaps(Handle<JSObject> prototype, 3131 static HCheckPrototypeMaps* New(Zone* zone,
2957 Handle<JSObject> holder, 3132 HValue* context,
2958 Zone* zone, 3133 Handle<JSObject> prototype,
2959 CompilationInfo* info) 3134 Handle<JSObject> holder,
2960 : prototypes_(2, zone), 3135 CompilationInfo* info) {
2961 maps_(2, zone), 3136 return new(zone) HCheckPrototypeMaps(prototype, holder, zone, info);
2962 first_prototype_unique_id_(),
2963 last_prototype_unique_id_(),
2964 can_omit_prototype_maps_(true) {
2965 SetFlag(kUseGVN);
2966 SetGVNFlag(kDependsOnMaps);
2967 // Keep a list of all objects on the prototype chain up to the holder
2968 // and the expected maps.
2969 while (true) {
2970 prototypes_.Add(prototype, zone);
2971 Handle<Map> map(prototype->map());
2972 maps_.Add(map, zone);
2973 can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks();
2974 if (prototype.is_identical_to(holder)) break;
2975 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
2976 }
2977 if (can_omit_prototype_maps_) {
2978 // Mark in-flight compilation as dependent on those maps.
2979 for (int i = 0; i < maps()->length(); i++) {
2980 Handle<Map> map = maps()->at(i);
2981 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
2982 info);
2983 }
2984 }
2985 } 3137 }
2986 3138
2987 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } 3139 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
2988 3140
2989 ZoneList<Handle<Map> >* maps() { return &maps_; } 3141 ZoneList<Handle<Map> >* maps() { return &maps_; }
2990 3142
2991 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) 3143 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
2992 3144
2993 virtual Representation RequiredInputRepresentation(int index) { 3145 virtual Representation RequiredInputRepresentation(int index) {
2994 return Representation::None(); 3146 return Representation::None();
(...skipping 14 matching lines...) Expand all
3009 bool CanOmitPrototypeChecks() { return can_omit_prototype_maps_; } 3161 bool CanOmitPrototypeChecks() { return can_omit_prototype_maps_; }
3010 3162
3011 protected: 3163 protected:
3012 virtual bool DataEquals(HValue* other) { 3164 virtual bool DataEquals(HValue* other) {
3013 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); 3165 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
3014 return first_prototype_unique_id_ == b->first_prototype_unique_id_ && 3166 return first_prototype_unique_id_ == b->first_prototype_unique_id_ &&
3015 last_prototype_unique_id_ == b->last_prototype_unique_id_; 3167 last_prototype_unique_id_ == b->last_prototype_unique_id_;
3016 } 3168 }
3017 3169
3018 private: 3170 private:
3171 HCheckPrototypeMaps(Handle<JSObject> prototype,
3172 Handle<JSObject> holder,
3173 Zone* zone,
3174 CompilationInfo* info)
3175 : prototypes_(2, zone),
3176 maps_(2, zone),
3177 first_prototype_unique_id_(),
3178 last_prototype_unique_id_(),
3179 can_omit_prototype_maps_(true) {
3180 SetFlag(kUseGVN);
3181 SetGVNFlag(kDependsOnMaps);
3182 // Keep a list of all objects on the prototype chain up to the holder
3183 // and the expected maps.
3184 while (true) {
3185 prototypes_.Add(prototype, zone);
3186 Handle<Map> map(prototype->map());
3187 maps_.Add(map, zone);
3188 can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks();
3189 if (prototype.is_identical_to(holder)) break;
3190 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
3191 }
3192 if (can_omit_prototype_maps_) {
3193 // Mark in-flight compilation as dependent on those maps.
3194 for (int i = 0; i < maps()->length(); i++) {
3195 Handle<Map> map = maps()->at(i);
3196 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
3197 info);
3198 }
3199 }
3200 }
3201
3019 ZoneList<Handle<JSObject> > prototypes_; 3202 ZoneList<Handle<JSObject> > prototypes_;
3020 ZoneList<Handle<Map> > maps_; 3203 ZoneList<Handle<Map> > maps_;
3021 UniqueValueId first_prototype_unique_id_; 3204 UniqueValueId first_prototype_unique_id_;
3022 UniqueValueId last_prototype_unique_id_; 3205 UniqueValueId last_prototype_unique_id_;
3023 bool can_omit_prototype_maps_; 3206 bool can_omit_prototype_maps_;
3024 }; 3207 };
3025 3208
3026 3209
3027 class InductionVariableData; 3210 class InductionVariableData;
3028 3211
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
3336 int phi_id() { return phi_id_; } 3519 int phi_id() { return phi_id_; }
3337 3520
3338 static HPhi* cast(HValue* value) { 3521 static HPhi* cast(HValue* value) {
3339 ASSERT(value->IsPhi()); 3522 ASSERT(value->IsPhi());
3340 return reinterpret_cast<HPhi*>(value); 3523 return reinterpret_cast<HPhi*>(value);
3341 } 3524 }
3342 virtual Opcode opcode() const { return HValue::kPhi; } 3525 virtual Opcode opcode() const { return HValue::kPhi; }
3343 3526
3344 void SimplifyConstantInputs(); 3527 void SimplifyConstantInputs();
3345 3528
3346 // TODO(titzer): we can't eliminate the receiver for generating backtraces
3347 virtual bool IsDeletable() const { return !IsReceiver(); }
3348
3349 protected: 3529 protected:
3350 virtual void DeleteFromGraph(); 3530 virtual void DeleteFromGraph();
3351 virtual void InternalSetOperandAt(int index, HValue* value) { 3531 virtual void InternalSetOperandAt(int index, HValue* value) {
3352 inputs_[index] = value; 3532 inputs_[index] = value;
3353 } 3533 }
3354 3534
3355 virtual bool IsRelationTrueInternal(NumericRelation relation, 3535 virtual bool IsRelationTrueInternal(NumericRelation relation,
3356 HValue* other, 3536 HValue* other,
3357 int offset = 0, 3537 int offset = 0,
3358 int scale = 0); 3538 int scale = 0);
3359 3539
3360 private: 3540 private:
3361 ZoneList<HValue*> inputs_; 3541 ZoneList<HValue*> inputs_;
3362 int merged_index_; 3542 int merged_index_;
3363 3543
3364 int non_phi_uses_[Representation::kNumRepresentations]; 3544 int non_phi_uses_[Representation::kNumRepresentations];
3365 int indirect_uses_[Representation::kNumRepresentations]; 3545 int indirect_uses_[Representation::kNumRepresentations];
3366 int phi_id_; 3546 int phi_id_;
3367 InductionVariableData* induction_variable_data_; 3547 InductionVariableData* induction_variable_data_;
3548
3549 // TODO(titzer): we can't eliminate the receiver for generating backtraces
3550 virtual bool IsDeletable() const { return !IsReceiver(); }
3368 }; 3551 };
3369 3552
3370 3553
3371 class HInductionVariableAnnotation : public HUnaryOperation { 3554 class HInductionVariableAnnotation : public HUnaryOperation {
3372 public: 3555 public:
3373 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, 3556 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3374 NumericRelation relation, 3557 NumericRelation relation,
3375 int operand_index); 3558 int operand_index);
3376 3559
3377 NumericRelation relation() { return relation_; } 3560 NumericRelation relation() { return relation_; }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3410 // the operand can change if a new idef of the phi is added between the phi 3593 // the operand can change if a new idef of the phi is added between the phi
3411 // and this instruction (inserting an idef updates every use). 3594 // and this instruction (inserting an idef updates every use).
3412 HPhi* phi_; 3595 HPhi* phi_;
3413 NumericRelation relation_; 3596 NumericRelation relation_;
3414 int operand_index_; 3597 int operand_index_;
3415 }; 3598 };
3416 3599
3417 3600
3418 class HArgumentsObject: public HTemplateInstruction<0> { 3601 class HArgumentsObject: public HTemplateInstruction<0> {
3419 public: 3602 public:
3420 HArgumentsObject(int count, Zone* zone) : values_(count, zone) { 3603 static HArgumentsObject* New(Zone* zone,
3421 set_representation(Representation::Tagged()); 3604 HValue* context,
3422 SetFlag(kIsArguments); 3605 int count) {
3606 return new(zone) HArgumentsObject(count, zone);
3423 } 3607 }
3424 3608
3425 const ZoneList<HValue*>* arguments_values() const { return &values_; } 3609 const ZoneList<HValue*>* arguments_values() const { return &values_; }
3426 int arguments_count() const { return values_.length(); } 3610 int arguments_count() const { return values_.length(); }
3427 3611
3428 void AddArgument(HValue* argument, Zone* zone) { 3612 void AddArgument(HValue* argument, Zone* zone) {
3429 values_.Add(NULL, zone); // Resize list. 3613 values_.Add(NULL, zone); // Resize list.
3430 SetOperandAt(values_.length() - 1, argument); 3614 SetOperandAt(values_.length() - 1, argument);
3431 } 3615 }
3432 3616
3433 virtual int OperandCount() { return values_.length(); } 3617 virtual int OperandCount() { return values_.length(); }
3434 virtual HValue* OperandAt(int index) const { return values_[index]; } 3618 virtual HValue* OperandAt(int index) const { return values_[index]; }
3435 3619
3436 virtual bool HasEscapingOperandAt(int index) { return false; } 3620 virtual bool HasEscapingOperandAt(int index) { return false; }
3437 virtual Representation RequiredInputRepresentation(int index) { 3621 virtual Representation RequiredInputRepresentation(int index) {
3438 return Representation::None(); 3622 return Representation::None();
3439 } 3623 }
3440 3624
3441 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) 3625 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
3442 3626
3443 protected: 3627 protected:
3444 virtual void InternalSetOperandAt(int index, HValue* value) { 3628 virtual void InternalSetOperandAt(int index, HValue* value) {
3445 values_[index] = value; 3629 values_[index] = value;
3446 } 3630 }
3447 3631
3448 private: 3632 private:
3633 HArgumentsObject(int count, Zone* zone) : values_(count, zone) {
3634 set_representation(Representation::Tagged());
3635 SetFlag(kIsArguments);
3636 }
3637
3449 virtual bool IsDeletable() const { return true; } 3638 virtual bool IsDeletable() const { return true; }
3450 3639
3451 ZoneList<HValue*> values_; 3640 ZoneList<HValue*> values_;
3452 }; 3641 };
3453 3642
3454 3643
3455 class HConstant: public HTemplateInstruction<0> { 3644 class HConstant: public HTemplateInstruction<0> {
3456 public: 3645 public:
3457 HConstant(Handle<Object> handle, Representation r = Representation::None()); 3646 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t);
3458 HConstant(int32_t value, 3647 DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
3459 Representation r = Representation::None(), 3648 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
3460 bool is_not_in_new_space = true, 3649 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
3461 Handle<Object> optional_handle = Handle<Object>::null()); 3650 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
3462 HConstant(double value,
3463 Representation r = Representation::None(),
3464 bool is_not_in_new_space = true,
3465 Handle<Object> optional_handle = Handle<Object>::null());
3466 HConstant(Handle<Object> handle,
3467 UniqueValueId unique_id,
3468 Representation r,
3469 HType type,
3470 bool is_internalized_string,
3471 bool is_not_in_new_space,
3472 bool is_cell,
3473 bool boolean_value);
3474 3651
3475 Handle<Object> handle() { 3652 Handle<Object> handle() {
3476 if (handle_.is_null()) { 3653 if (handle_.is_null()) {
3477 Factory* factory = Isolate::Current()->factory(); 3654 Factory* factory = Isolate::Current()->factory();
3478 // Default arguments to is_not_in_new_space depend on this heap number 3655 // Default arguments to is_not_in_new_space depend on this heap number
3479 // to be tenured so that it's guaranteed not be be located in new space. 3656 // to be tenured so that it's guaranteed not be be located in new space.
3480 handle_ = factory->NewNumber(double_value_, TENURED); 3657 handle_ = factory->NewNumber(double_value_, TENURED);
3481 } 3658 }
3482 AllowDeferredHandleDereference smi_check; 3659 AllowDeferredHandleDereference smi_check;
3483 ASSERT(has_int32_value_ || !handle_->IsSmi()); 3660 ASSERT(has_int32_value_ || !handle_->IsSmi());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3528 } 3705 }
3529 3706
3530 virtual Representation RequiredInputRepresentation(int index) { 3707 virtual Representation RequiredInputRepresentation(int index) {
3531 return Representation::None(); 3708 return Representation::None();
3532 } 3709 }
3533 3710
3534 virtual Representation KnownOptimalRepresentation() { 3711 virtual Representation KnownOptimalRepresentation() {
3535 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); 3712 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
3536 if (HasInteger32Value()) return Representation::Integer32(); 3713 if (HasInteger32Value()) return Representation::Integer32();
3537 if (HasNumberValue()) return Representation::Double(); 3714 if (HasNumberValue()) return Representation::Double();
3715 if (HasExternalReferenceValue()) return Representation::External();
3538 return Representation::Tagged(); 3716 return Representation::Tagged();
3539 } 3717 }
3540 3718
3541 virtual bool EmitAtUses(); 3719 virtual bool EmitAtUses();
3542 virtual void PrintDataTo(StringStream* stream); 3720 virtual void PrintDataTo(StringStream* stream);
3543 virtual HType CalculateInferredType();
3544 bool IsInteger() { return handle()->IsSmi(); } 3721 bool IsInteger() { return handle()->IsSmi(); }
3545 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 3722 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3546 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); 3723 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
3547 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); 3724 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
3548 bool HasInteger32Value() const { return has_int32_value_; } 3725 bool HasInteger32Value() const { return has_int32_value_; }
3549 int32_t Integer32Value() const { 3726 int32_t Integer32Value() const {
3550 ASSERT(HasInteger32Value()); 3727 ASSERT(HasInteger32Value());
3551 return int32_value_; 3728 return int32_value_;
3552 } 3729 }
3553 bool HasSmiValue() const { return has_smi_value_; } 3730 bool HasSmiValue() const { return has_smi_value_; }
(...skipping 16 matching lines...) Expand all
3570 int32_t NumberValueAsInteger32() const { 3747 int32_t NumberValueAsInteger32() const {
3571 ASSERT(HasNumberValue()); 3748 ASSERT(HasNumberValue());
3572 // Irrespective of whether a numeric HConstant can be safely 3749 // Irrespective of whether a numeric HConstant can be safely
3573 // represented as an int32, we store the (in some cases lossy) 3750 // represented as an int32, we store the (in some cases lossy)
3574 // representation of the number in int32_value_. 3751 // representation of the number in int32_value_.
3575 return int32_value_; 3752 return int32_value_;
3576 } 3753 }
3577 bool HasStringValue() const { 3754 bool HasStringValue() const {
3578 if (has_double_value_ || has_int32_value_) return false; 3755 if (has_double_value_ || has_int32_value_) return false;
3579 ASSERT(!handle_.is_null()); 3756 ASSERT(!handle_.is_null());
3580 return type_from_value_.IsString(); 3757 return type_.IsString();
3581 } 3758 }
3582 Handle<String> StringValue() const { 3759 Handle<String> StringValue() const {
3583 ASSERT(HasStringValue()); 3760 ASSERT(HasStringValue());
3584 return Handle<String>::cast(handle_); 3761 return Handle<String>::cast(handle_);
3585 } 3762 }
3586 bool HasInternalizedStringValue() const { 3763 bool HasInternalizedStringValue() const {
3587 return HasStringValue() && is_internalized_string_; 3764 return HasStringValue() && is_internalized_string_;
3588 } 3765 }
3589 3766
3767 bool HasExternalReferenceValue() const {
3768 return has_external_reference_value_;
3769 }
3770 ExternalReference ExternalReferenceValue() const {
3771 return external_reference_value_;
3772 }
3773
3590 bool BooleanValue() const { return boolean_value_; } 3774 bool BooleanValue() const { return boolean_value_; }
3591 3775
3592 virtual intptr_t Hashcode() { 3776 virtual intptr_t Hashcode() {
3593 if (has_int32_value_) { 3777 if (has_int32_value_) {
3594 return static_cast<intptr_t>(int32_value_); 3778 return static_cast<intptr_t>(int32_value_);
3595 } else if (has_double_value_) { 3779 } else if (has_double_value_) {
3596 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3780 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3781 } else if (has_external_reference_value_) {
3782 return reinterpret_cast<intptr_t>(external_reference_value_.address());
3597 } else { 3783 } else {
3598 ASSERT(!handle_.is_null()); 3784 ASSERT(!handle_.is_null());
3599 return unique_id_.Hashcode(); 3785 return unique_id_.Hashcode();
3600 } 3786 }
3601 } 3787 }
3602 3788
3603 virtual void FinalizeUniqueValueId() { 3789 virtual void FinalizeUniqueValueId() {
3604 if (!has_double_value_) { 3790 if (!has_double_value_ && !has_external_reference_value_) {
3605 ASSERT(!handle_.is_null()); 3791 ASSERT(!handle_.is_null());
3606 unique_id_ = UniqueValueId(handle_); 3792 unique_id_ = UniqueValueId(handle_);
3607 } 3793 }
3608 } 3794 }
3609 3795
3610 bool UniqueValueIdsMatch(UniqueValueId other) { 3796 bool UniqueValueIdsMatch(UniqueValueId other) {
3611 return !has_double_value_ && unique_id_ == other; 3797 return !has_double_value_ && !has_external_reference_value_ &&
3798 unique_id_ == other;
3612 } 3799 }
3613 3800
3614 #ifdef DEBUG 3801 #ifdef DEBUG
3615 virtual void Verify() { } 3802 virtual void Verify() { }
3616 #endif 3803 #endif
3617 3804
3618 DECLARE_CONCRETE_INSTRUCTION(Constant) 3805 DECLARE_CONCRETE_INSTRUCTION(Constant)
3619 3806
3620 protected: 3807 protected:
3621 virtual Range* InferRange(Zone* zone); 3808 virtual Range* InferRange(Zone* zone);
3622 3809
3623 virtual bool DataEquals(HValue* other) { 3810 virtual bool DataEquals(HValue* other) {
3624 HConstant* other_constant = HConstant::cast(other); 3811 HConstant* other_constant = HConstant::cast(other);
3625 if (has_int32_value_) { 3812 if (has_int32_value_) {
3626 return other_constant->has_int32_value_ && 3813 return other_constant->has_int32_value_ &&
3627 int32_value_ == other_constant->int32_value_; 3814 int32_value_ == other_constant->int32_value_;
3628 } else if (has_double_value_) { 3815 } else if (has_double_value_) {
3629 return other_constant->has_double_value_ && 3816 return other_constant->has_double_value_ &&
3630 BitCast<int64_t>(double_value_) == 3817 BitCast<int64_t>(double_value_) ==
3631 BitCast<int64_t>(other_constant->double_value_); 3818 BitCast<int64_t>(other_constant->double_value_);
3819 } else if (has_external_reference_value_) {
3820 return other_constant->has_external_reference_value_ &&
3821 external_reference_value_ ==
3822 other_constant->external_reference_value_;
3632 } else { 3823 } else {
3633 ASSERT(!handle_.is_null()); 3824 ASSERT(!handle_.is_null());
3634 return !other_constant->handle_.is_null() && 3825 return !other_constant->handle_.is_null() &&
3635 unique_id_ == other_constant->unique_id_; 3826 unique_id_ == other_constant->unique_id_;
3636 } 3827 }
3637 } 3828 }
3638 3829
3639 private: 3830 private:
3831 friend class HGraph;
3832 HConstant(Handle<Object> handle, Representation r = Representation::None());
3833 HConstant(int32_t value,
3834 Representation r = Representation::None(),
3835 bool is_not_in_new_space = true,
3836 Handle<Object> optional_handle = Handle<Object>::null());
3837 HConstant(double value,
3838 Representation r = Representation::None(),
3839 bool is_not_in_new_space = true,
3840 Handle<Object> optional_handle = Handle<Object>::null());
3841 HConstant(Handle<Object> handle,
3842 UniqueValueId unique_id,
3843 Representation r,
3844 HType type,
3845 bool is_internalized_string,
3846 bool is_not_in_new_space,
3847 bool is_cell,
3848 bool boolean_value);
3849 explicit HConstant(ExternalReference reference);
3850
3640 void Initialize(Representation r); 3851 void Initialize(Representation r);
3641 3852
3642 virtual bool IsDeletable() const { return true; } 3853 virtual bool IsDeletable() const { return true; }
3643 3854
3644 // If this is a numerical constant, handle_ either points to to the 3855 // If this is a numerical constant, handle_ either points to to the
3645 // HeapObject the constant originated from or is null. If the 3856 // HeapObject the constant originated from or is null. If the
3646 // constant is non-numeric, handle_ always points to a valid 3857 // constant is non-numeric, handle_ always points to a valid
3647 // constant HeapObject. 3858 // constant HeapObject.
3648 Handle<Object> handle_; 3859 Handle<Object> handle_;
3649 UniqueValueId unique_id_; 3860 UniqueValueId unique_id_;
3650 3861
3651 // We store the HConstant in the most specific form safely possible. 3862 // We store the HConstant in the most specific form safely possible.
3652 // The two flags, has_int32_value_ and has_double_value_ tell us if 3863 // The two flags, has_int32_value_ and has_double_value_ tell us if
3653 // int32_value_ and double_value_ hold valid, safe representations 3864 // int32_value_ and double_value_ hold valid, safe representations
3654 // of the constant. has_int32_value_ implies has_double_value_ but 3865 // of the constant. has_int32_value_ implies has_double_value_ but
3655 // not the converse. 3866 // not the converse.
3656 bool has_smi_value_ : 1; 3867 bool has_smi_value_ : 1;
3657 bool has_int32_value_ : 1; 3868 bool has_int32_value_ : 1;
3658 bool has_double_value_ : 1; 3869 bool has_double_value_ : 1;
3870 bool has_external_reference_value_ : 1;
3659 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. 3871 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
3660 bool is_not_in_new_space_ : 1; 3872 bool is_not_in_new_space_ : 1;
3661 bool is_cell_ : 1; 3873 bool is_cell_ : 1;
3662 bool boolean_value_ : 1; 3874 bool boolean_value_ : 1;
3663 int32_t int32_value_; 3875 int32_t int32_value_;
3664 double double_value_; 3876 double double_value_;
3665 HType type_from_value_; 3877 ExternalReference external_reference_value_;
3666 }; 3878 };
3667 3879
3668 3880
3669 class HBinaryOperation: public HTemplateInstruction<3> { 3881 class HBinaryOperation: public HTemplateInstruction<3> {
3670 public: 3882 public:
3671 HBinaryOperation(HValue* context, HValue* left, HValue* right) 3883 HBinaryOperation(HValue* context, HValue* left, HValue* right,
3672 : observed_output_representation_(Representation::None()) { 3884 HType type = HType::Tagged())
3885 : HTemplateInstruction<3>(type),
3886 observed_output_representation_(Representation::None()) {
3673 ASSERT(left != NULL && right != NULL); 3887 ASSERT(left != NULL && right != NULL);
3674 SetOperandAt(0, context); 3888 SetOperandAt(0, context);
3675 SetOperandAt(1, left); 3889 SetOperandAt(1, left);
3676 SetOperandAt(2, right); 3890 SetOperandAt(2, right);
3677 observed_input_representation_[0] = Representation::None(); 3891 observed_input_representation_[0] = Representation::None();
3678 observed_input_representation_[1] = Representation::None(); 3892 observed_input_representation_[1] = Representation::None();
3679 } 3893 }
3680 3894
3681 HValue* context() { return OperandAt(0); } 3895 HValue* context() const { return OperandAt(0); }
3682 HValue* left() { return OperandAt(1); } 3896 HValue* left() const { return OperandAt(1); }
3683 HValue* right() { return OperandAt(2); } 3897 HValue* right() const { return OperandAt(2); }
3684 3898
3685 // True if switching left and right operands likely generates better code. 3899 // True if switching left and right operands likely generates better code.
3686 bool AreOperandsBetterSwitched() { 3900 bool AreOperandsBetterSwitched() {
3687 if (!IsCommutative()) return false; 3901 if (!IsCommutative()) return false;
3688 3902
3689 // Constant operands are better off on the right, they can be inlined in 3903 // Constant operands are better off on the right, they can be inlined in
3690 // many situations on most platforms. 3904 // many situations on most platforms.
3691 if (left()->IsConstant()) return true; 3905 if (left()->IsConstant()) return true;
3692 if (right()->IsConstant()) return false; 3906 if (right()->IsConstant()) return false;
3693 3907
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3746 private: 3960 private:
3747 bool IgnoreObservedOutputRepresentation(Representation current_rep); 3961 bool IgnoreObservedOutputRepresentation(Representation current_rep);
3748 3962
3749 Representation observed_input_representation_[2]; 3963 Representation observed_input_representation_[2];
3750 Representation observed_output_representation_; 3964 Representation observed_output_representation_;
3751 }; 3965 };
3752 3966
3753 3967
3754 class HWrapReceiver: public HTemplateInstruction<2> { 3968 class HWrapReceiver: public HTemplateInstruction<2> {
3755 public: 3969 public:
3756 HWrapReceiver(HValue* receiver, HValue* function) { 3970 DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
3757 set_representation(Representation::Tagged());
3758 SetOperandAt(0, receiver);
3759 SetOperandAt(1, function);
3760 }
3761 3971
3762 virtual Representation RequiredInputRepresentation(int index) { 3972 virtual Representation RequiredInputRepresentation(int index) {
3763 return Representation::Tagged(); 3973 return Representation::Tagged();
3764 } 3974 }
3765 3975
3766 HValue* receiver() { return OperandAt(0); } 3976 HValue* receiver() { return OperandAt(0); }
3767 HValue* function() { return OperandAt(1); } 3977 HValue* function() { return OperandAt(1); }
3768 3978
3769 virtual HValue* Canonicalize(); 3979 virtual HValue* Canonicalize();
3770 3980
3771 virtual void PrintDataTo(StringStream* stream); 3981 virtual void PrintDataTo(StringStream* stream);
3772 3982
3773 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) 3983 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
3984
3985 private:
3986 HWrapReceiver(HValue* receiver, HValue* function) {
3987 set_representation(Representation::Tagged());
3988 SetOperandAt(0, receiver);
3989 SetOperandAt(1, function);
3990 }
3774 }; 3991 };
3775 3992
3776 3993
3777 class HApplyArguments: public HTemplateInstruction<4> { 3994 class HApplyArguments: public HTemplateInstruction<4> {
3778 public: 3995 public:
3779 HApplyArguments(HValue* function, 3996 HApplyArguments(HValue* function,
3780 HValue* receiver, 3997 HValue* receiver,
3781 HValue* length, 3998 HValue* length,
3782 HValue* elements) { 3999 HValue* elements) {
3783 set_representation(Representation::Tagged()); 4000 set_representation(Representation::Tagged());
(...skipping 15 matching lines...) Expand all
3799 HValue* receiver() { return OperandAt(1); } 4016 HValue* receiver() { return OperandAt(1); }
3800 HValue* length() { return OperandAt(2); } 4017 HValue* length() { return OperandAt(2); }
3801 HValue* elements() { return OperandAt(3); } 4018 HValue* elements() { return OperandAt(3); }
3802 4019
3803 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments) 4020 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
3804 }; 4021 };
3805 4022
3806 4023
3807 class HArgumentsElements: public HTemplateInstruction<0> { 4024 class HArgumentsElements: public HTemplateInstruction<0> {
3808 public: 4025 public:
3809 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) { 4026 DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsElements, bool);
3810 // The value produced by this instruction is a pointer into the stack
3811 // that looks as if it was a smi because of alignment.
3812 set_representation(Representation::Tagged());
3813 SetFlag(kUseGVN);
3814 }
3815 4027
3816 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements) 4028 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
3817 4029
3818 virtual Representation RequiredInputRepresentation(int index) { 4030 virtual Representation RequiredInputRepresentation(int index) {
3819 return Representation::None(); 4031 return Representation::None();
3820 } 4032 }
3821 4033
3822 bool from_inlined() const { return from_inlined_; } 4034 bool from_inlined() const { return from_inlined_; }
3823 4035
3824 protected: 4036 protected:
3825 virtual bool DataEquals(HValue* other) { return true; } 4037 virtual bool DataEquals(HValue* other) { return true; }
3826 4038
3827 private: 4039 private:
4040 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
4041 // The value produced by this instruction is a pointer into the stack
4042 // that looks as if it was a smi because of alignment.
4043 set_representation(Representation::Tagged());
4044 SetFlag(kUseGVN);
4045 }
4046
3828 virtual bool IsDeletable() const { return true; } 4047 virtual bool IsDeletable() const { return true; }
3829 4048
3830 bool from_inlined_; 4049 bool from_inlined_;
3831 }; 4050 };
3832 4051
3833 4052
3834 class HArgumentsLength: public HUnaryOperation { 4053 class HArgumentsLength: public HUnaryOperation {
3835 public: 4054 public:
3836 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) { 4055 DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*);
3837 set_representation(Representation::Integer32());
3838 SetFlag(kUseGVN);
3839 }
3840 4056
3841 virtual Representation RequiredInputRepresentation(int index) { 4057 virtual Representation RequiredInputRepresentation(int index) {
3842 return Representation::Tagged(); 4058 return Representation::Tagged();
3843 } 4059 }
3844 4060
3845 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) 4061 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
3846 4062
3847 protected: 4063 protected:
3848 virtual bool DataEquals(HValue* other) { return true; } 4064 virtual bool DataEquals(HValue* other) { return true; }
3849 4065
3850 private: 4066 private:
4067 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
4068 set_representation(Representation::Integer32());
4069 SetFlag(kUseGVN);
4070 }
4071
3851 virtual bool IsDeletable() const { return true; } 4072 virtual bool IsDeletable() const { return true; }
3852 }; 4073 };
3853 4074
3854 4075
3855 class HAccessArgumentsAt: public HTemplateInstruction<3> { 4076 class HAccessArgumentsAt: public HTemplateInstruction<3> {
3856 public: 4077 public:
3857 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { 4078 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3858 set_representation(Representation::Tagged()); 4079 set_representation(Representation::Tagged());
3859 SetFlag(kUseGVN); 4080 SetFlag(kUseGVN);
3860 SetOperandAt(0, arguments); 4081 SetOperandAt(0, arguments);
(...skipping 18 matching lines...) Expand all
3879 4100
3880 virtual bool DataEquals(HValue* other) { return true; } 4101 virtual bool DataEquals(HValue* other) { return true; }
3881 }; 4102 };
3882 4103
3883 4104
3884 class HBoundsCheckBaseIndexInformation; 4105 class HBoundsCheckBaseIndexInformation;
3885 4106
3886 4107
3887 class HBoundsCheck: public HTemplateInstruction<2> { 4108 class HBoundsCheck: public HTemplateInstruction<2> {
3888 public: 4109 public:
3889 // Normally HBoundsCheck should be created using the 4110 DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*);
3890 // HGraphBuilder::AddBoundsCheck() helper.
3891 // However when building stubs, where we know that the arguments are Int32,
3892 // it makes sense to invoke this constructor directly.
3893 HBoundsCheck(HValue* index, HValue* length)
3894 : skip_check_(false),
3895 base_(NULL), offset_(0), scale_(0),
3896 responsibility_direction_(DIRECTION_NONE),
3897 allow_equality_(false) {
3898 SetOperandAt(0, index);
3899 SetOperandAt(1, length);
3900 SetFlag(kFlexibleRepresentation);
3901 SetFlag(kUseGVN);
3902 }
3903 4111
3904 bool skip_check() const { return skip_check_; } 4112 bool skip_check() const { return skip_check_; }
3905 void set_skip_check() { skip_check_ = true; } 4113 void set_skip_check() { skip_check_ = true; }
4114
3906 HValue* base() { return base_; } 4115 HValue* base() { return base_; }
3907 int offset() { return offset_; } 4116 int offset() { return offset_; }
3908 int scale() { return scale_; } 4117 int scale() { return scale_; }
3909 bool index_can_increase() { 4118 bool index_can_increase() {
3910 return (responsibility_direction_ & DIRECTION_LOWER) == 0; 4119 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3911 } 4120 }
3912 bool index_can_decrease() { 4121 bool index_can_decrease() {
3913 return (responsibility_direction_ & DIRECTION_UPPER) == 0; 4122 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3914 } 4123 }
3915 4124
(...skipping 11 matching lines...) Expand all
3927 base_ = index(); 4136 base_ = index();
3928 offset_ = 0; 4137 offset_ = 0;
3929 scale_ = 0; 4138 scale_ = 0;
3930 return false; 4139 return false;
3931 } 4140 }
3932 } 4141 }
3933 4142
3934 virtual Representation RequiredInputRepresentation(int arg_index) { 4143 virtual Representation RequiredInputRepresentation(int arg_index) {
3935 return representation(); 4144 return representation();
3936 } 4145 }
3937 virtual bool IsDeletable() const {
3938 return skip_check() && !FLAG_debug_code;
3939 }
3940 4146
3941 virtual bool IsRelationTrueInternal(NumericRelation relation, 4147 virtual bool IsRelationTrueInternal(NumericRelation relation,
3942 HValue* related_value, 4148 HValue* related_value,
3943 int offset = 0, 4149 int offset = 0,
3944 int scale = 0); 4150 int scale = 0);
3945 4151
3946 virtual void PrintDataTo(StringStream* stream); 4152 virtual void PrintDataTo(StringStream* stream);
3947 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 4153 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
3948 4154
3949 HValue* index() { return OperandAt(0); } 4155 HValue* index() { return OperandAt(0); }
(...skipping 16 matching lines...) Expand all
3966 } 4172 }
3967 4173
3968 virtual bool DataEquals(HValue* other) { return true; } 4174 virtual bool DataEquals(HValue* other) { return true; }
3969 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); 4175 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3970 bool skip_check_; 4176 bool skip_check_;
3971 HValue* base_; 4177 HValue* base_;
3972 int offset_; 4178 int offset_;
3973 int scale_; 4179 int scale_;
3974 RangeGuaranteeDirection responsibility_direction_; 4180 RangeGuaranteeDirection responsibility_direction_;
3975 bool allow_equality_; 4181 bool allow_equality_;
4182
4183 private:
4184 // Normally HBoundsCheck should be created using the
4185 // HGraphBuilder::AddBoundsCheck() helper.
4186 // However when building stubs, where we know that the arguments are Int32,
4187 // it makes sense to invoke this constructor directly.
4188 HBoundsCheck(HValue* index, HValue* length)
4189 : skip_check_(false),
4190 base_(NULL), offset_(0), scale_(0),
4191 responsibility_direction_(DIRECTION_NONE),
4192 allow_equality_(false) {
4193 SetOperandAt(0, index);
4194 SetOperandAt(1, length);
4195 SetFlag(kFlexibleRepresentation);
4196 SetFlag(kUseGVN);
4197 }
4198
4199 virtual bool IsDeletable() const {
4200 return skip_check() && !FLAG_debug_code;
4201 }
3976 }; 4202 };
3977 4203
3978 4204
3979 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { 4205 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3980 public: 4206 public:
3981 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { 4207 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3982 DecompositionResult decomposition; 4208 DecompositionResult decomposition;
3983 if (check->index()->TryDecompose(&decomposition)) { 4209 if (check->index()->TryDecompose(&decomposition)) {
3984 SetOperandAt(0, decomposition.base()); 4210 SetOperandAt(0, decomposition.base());
3985 SetOperandAt(1, check); 4211 SetOperandAt(1, check);
(...skipping 25 matching lines...) Expand all
4011 bounds_check()->SetResponsibilityForRange(direction); 4237 bounds_check()->SetResponsibilityForRange(direction);
4012 } 4238 }
4013 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) { 4239 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
4014 bounds_check()->TryGuaranteeRangeChanging(context); 4240 bounds_check()->TryGuaranteeRangeChanging(context);
4015 } 4241 }
4016 }; 4242 };
4017 4243
4018 4244
4019 class HBitwiseBinaryOperation: public HBinaryOperation { 4245 class HBitwiseBinaryOperation: public HBinaryOperation {
4020 public: 4246 public:
4021 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 4247 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
4022 : HBinaryOperation(context, left, right) { 4248 HType type = HType::Tagged())
4249 : HBinaryOperation(context, left, right, type) {
4023 SetFlag(kFlexibleRepresentation); 4250 SetFlag(kFlexibleRepresentation);
4024 SetFlag(kTruncatingToInt32); 4251 SetFlag(kTruncatingToInt32);
4025 SetFlag(kAllowUndefinedAsNaN); 4252 SetFlag(kAllowUndefinedAsNaN);
4026 SetAllSideEffects(); 4253 SetAllSideEffects();
4027 } 4254 }
4028 4255
4029 virtual void RepresentationChanged(Representation to) { 4256 virtual void RepresentationChanged(Representation to) {
4030 if (!to.IsTagged()) { 4257 if (!to.IsTagged()) {
4031 ASSERT(to.IsSmiOrInteger32()); 4258 ASSERT(to.IsSmiOrInteger32());
4032 ClearAllSideEffects(); 4259 ClearAllSideEffects();
(...skipping 16 matching lines...) Expand all
4049 Representation r = HBinaryOperation::observed_input_representation(index); 4276 Representation r = HBinaryOperation::observed_input_representation(index);
4050 if (r.IsDouble()) return Representation::Integer32(); 4277 if (r.IsDouble()) return Representation::Integer32();
4051 return r; 4278 return r;
4052 } 4279 }
4053 4280
4054 virtual void initialize_output_representation(Representation observed) { 4281 virtual void initialize_output_representation(Representation observed) {
4055 if (observed.IsDouble()) observed = Representation::Integer32(); 4282 if (observed.IsDouble()) observed = Representation::Integer32();
4056 HBinaryOperation::initialize_output_representation(observed); 4283 HBinaryOperation::initialize_output_representation(observed);
4057 } 4284 }
4058 4285
4059 virtual HType CalculateInferredType();
4060
4061 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) 4286 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
4062 4287
4063 private: 4288 private:
4064 virtual bool IsDeletable() const { return true; } 4289 virtual bool IsDeletable() const { return true; }
4065 }; 4290 };
4066 4291
4067 4292
4068 class HMathFloorOfDiv: public HBinaryOperation { 4293 class HMathFloorOfDiv: public HBinaryOperation {
4069 public: 4294 public:
4070 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) 4295 static HMathFloorOfDiv* New(Zone* zone,
4071 : HBinaryOperation(context, left, right) { 4296 HValue* context,
4072 set_representation(Representation::Integer32()); 4297 HValue* left,
4073 SetFlag(kUseGVN); 4298 HValue* right) {
4074 SetFlag(kCanOverflow); 4299 return new(zone) HMathFloorOfDiv(context, left, right);
4075 if (!right->IsConstant()) {
4076 SetFlag(kCanBeDivByZero);
4077 }
4078 SetFlag(kAllowUndefinedAsNaN);
4079 } 4300 }
4080 4301
4081 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4302 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4082 4303
4083 virtual Representation RequiredInputRepresentation(int index) { 4304 virtual Representation RequiredInputRepresentation(int index) {
4084 return Representation::Integer32(); 4305 return Representation::Integer32();
4085 } 4306 }
4086 4307
4087 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv) 4308 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
4088 4309
4089 protected: 4310 protected:
4090 virtual bool DataEquals(HValue* other) { return true; } 4311 virtual bool DataEquals(HValue* other) { return true; }
4091 4312
4092 private: 4313 private:
4314 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
4315 : HBinaryOperation(context, left, right) {
4316 set_representation(Representation::Integer32());
4317 SetFlag(kUseGVN);
4318 SetFlag(kCanOverflow);
4319 if (!right->IsConstant()) {
4320 SetFlag(kCanBeDivByZero);
4321 }
4322 SetFlag(kAllowUndefinedAsNaN);
4323 }
4324
4093 virtual bool IsDeletable() const { return true; } 4325 virtual bool IsDeletable() const { return true; }
4094 }; 4326 };
4095 4327
4096 4328
4097 class HArithmeticBinaryOperation: public HBinaryOperation { 4329 class HArithmeticBinaryOperation: public HBinaryOperation {
4098 public: 4330 public:
4099 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) 4331 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
4100 : HBinaryOperation(context, left, right) { 4332 : HBinaryOperation(context, left, right, HType::TaggedNumber()) {
4101 SetAllSideEffects(); 4333 SetAllSideEffects();
4102 SetFlag(kFlexibleRepresentation); 4334 SetFlag(kFlexibleRepresentation);
4103 SetFlag(kAllowUndefinedAsNaN); 4335 SetFlag(kAllowUndefinedAsNaN);
4104 } 4336 }
4105 4337
4106 virtual void RepresentationChanged(Representation to) { 4338 virtual void RepresentationChanged(Representation to) {
4107 if (to.IsTagged()) { 4339 if (to.IsTagged()) {
4108 SetAllSideEffects(); 4340 SetAllSideEffects();
4109 ClearFlag(kUseGVN); 4341 ClearFlag(kUseGVN);
4110 } else { 4342 } else {
4111 ClearAllSideEffects(); 4343 ClearAllSideEffects();
4112 SetFlag(kUseGVN); 4344 SetFlag(kUseGVN);
4113 } 4345 }
4114 } 4346 }
4115 4347
4116 virtual HType CalculateInferredType();
4117
4118 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) 4348 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
4119 4349
4120 private: 4350 private:
4121 virtual bool IsDeletable() const { return true; } 4351 virtual bool IsDeletable() const { return true; }
4122 }; 4352 };
4123 4353
4124 4354
4125 class HCompareGeneric: public HBinaryOperation { 4355 class HCompareGeneric: public HBinaryOperation {
4126 public: 4356 public:
4127 HCompareGeneric(HValue* context, 4357 HCompareGeneric(HValue* context,
4128 HValue* left, 4358 HValue* left,
4129 HValue* right, 4359 HValue* right,
4130 Token::Value token) 4360 Token::Value token)
4131 : HBinaryOperation(context, left, right), token_(token) { 4361 : HBinaryOperation(context, left, right, HType::Boolean()),
4362 token_(token) {
4132 ASSERT(Token::IsCompareOp(token)); 4363 ASSERT(Token::IsCompareOp(token));
4133 set_representation(Representation::Tagged()); 4364 set_representation(Representation::Tagged());
4134 SetAllSideEffects(); 4365 SetAllSideEffects();
4135 } 4366 }
4136 4367
4137 virtual Representation RequiredInputRepresentation(int index) { 4368 virtual Representation RequiredInputRepresentation(int index) {
4138 return index == 0 4369 return index == 0
4139 ? Representation::Tagged() 4370 ? Representation::Tagged()
4140 : representation(); 4371 : representation();
4141 } 4372 }
4142 4373
4143 Token::Value token() const { return token_; } 4374 Token::Value token() const { return token_; }
4144 virtual void PrintDataTo(StringStream* stream); 4375 virtual void PrintDataTo(StringStream* stream);
4145 4376
4146 virtual HType CalculateInferredType();
4147
4148 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) 4377 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
4149 4378
4150 private: 4379 private:
4151 Token::Value token_; 4380 Token::Value token_;
4152 }; 4381 };
4153 4382
4154 4383
4155 class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> { 4384 class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> {
4156 public: 4385 public:
4157 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token) 4386 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token)
(...skipping 29 matching lines...) Expand all
4187 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) 4416 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
4188 4417
4189 private: 4418 private:
4190 Representation observed_input_representation_[2]; 4419 Representation observed_input_representation_[2];
4191 Token::Value token_; 4420 Token::Value token_;
4192 }; 4421 };
4193 4422
4194 4423
4195 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { 4424 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
4196 public: 4425 public:
4197 HCompareObjectEqAndBranch(HValue* left, HValue* right) { 4426 // TODO(danno): make this private when the IfBuilder properly constructs
4427 // control flow instructions.
4428 HCompareObjectEqAndBranch(HValue* left,
4429 HValue* right) {
4198 SetOperandAt(0, left); 4430 SetOperandAt(0, left);
4199 SetOperandAt(1, right); 4431 SetOperandAt(1, right);
4200 } 4432 }
4201 4433
4434 DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*);
4435
4202 HValue* left() { return OperandAt(0); } 4436 HValue* left() { return OperandAt(0); }
4203 HValue* right() { return OperandAt(1); } 4437 HValue* right() { return OperandAt(1); }
4204 4438
4205 virtual void PrintDataTo(StringStream* stream); 4439 virtual void PrintDataTo(StringStream* stream);
4206 4440
4207 virtual Representation RequiredInputRepresentation(int index) { 4441 virtual Representation RequiredInputRepresentation(int index) {
4208 return Representation::Tagged(); 4442 return Representation::Tagged();
4209 } 4443 }
4210 4444
4211 virtual Representation observed_input_representation(int index) { 4445 virtual Representation observed_input_representation(int index) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
4413 } 4647 }
4414 4648
4415 private: 4649 private:
4416 Handle<String> type_literal_; 4650 Handle<String> type_literal_;
4417 }; 4651 };
4418 4652
4419 4653
4420 class HInstanceOf: public HBinaryOperation { 4654 class HInstanceOf: public HBinaryOperation {
4421 public: 4655 public:
4422 HInstanceOf(HValue* context, HValue* left, HValue* right) 4656 HInstanceOf(HValue* context, HValue* left, HValue* right)
4423 : HBinaryOperation(context, left, right) { 4657 : HBinaryOperation(context, left, right, HType::Boolean()) {
4424 set_representation(Representation::Tagged()); 4658 set_representation(Representation::Tagged());
4425 SetAllSideEffects(); 4659 SetAllSideEffects();
4426 } 4660 }
4427 4661
4428 virtual Representation RequiredInputRepresentation(int index) { 4662 virtual Representation RequiredInputRepresentation(int index) {
4429 return Representation::Tagged(); 4663 return Representation::Tagged();
4430 } 4664 }
4431 4665
4432 virtual HType CalculateInferredType();
4433
4434 virtual void PrintDataTo(StringStream* stream); 4666 virtual void PrintDataTo(StringStream* stream);
4435 4667
4436 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) 4668 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
4437 }; 4669 };
4438 4670
4439 4671
4440 class HInstanceOfKnownGlobal: public HTemplateInstruction<2> { 4672 class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
4441 public: 4673 public:
4442 HInstanceOfKnownGlobal(HValue* context, 4674 HInstanceOfKnownGlobal(HValue* context,
4443 HValue* left, 4675 HValue* left,
4444 Handle<JSFunction> right) 4676 Handle<JSFunction> right)
4445 : function_(right) { 4677 : HTemplateInstruction<2>(HType::Boolean()), function_(right) {
4446 SetOperandAt(0, context); 4678 SetOperandAt(0, context);
4447 SetOperandAt(1, left); 4679 SetOperandAt(1, left);
4448 set_representation(Representation::Tagged()); 4680 set_representation(Representation::Tagged());
4449 SetAllSideEffects(); 4681 SetAllSideEffects();
4450 } 4682 }
4451 4683
4452 HValue* context() { return OperandAt(0); } 4684 HValue* context() { return OperandAt(0); }
4453 HValue* left() { return OperandAt(1); } 4685 HValue* left() { return OperandAt(1); }
4454 Handle<JSFunction> function() { return function_; } 4686 Handle<JSFunction> function() { return function_; }
4455 4687
4456 virtual Representation RequiredInputRepresentation(int index) { 4688 virtual Representation RequiredInputRepresentation(int index) {
4457 return Representation::Tagged(); 4689 return Representation::Tagged();
4458 } 4690 }
4459 4691
4460 virtual HType CalculateInferredType();
4461
4462 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) 4692 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
4463 4693
4464 private: 4694 private:
4465 Handle<JSFunction> function_; 4695 Handle<JSFunction> function_;
4466 }; 4696 };
4467 4697
4468 4698
4469 // TODO(mstarzinger): This instruction should be modeled as a load of the map 4699 // TODO(mstarzinger): This instruction should be modeled as a load of the map
4470 // field followed by a load of the instance size field once HLoadNamedField is 4700 // field followed by a load of the instance size field once HLoadNamedField is
4471 // flexible enough to accommodate byte-field loads. 4701 // flexible enough to accommodate byte-field loads.
4472 class HInstanceSize: public HTemplateInstruction<1> { 4702 class HInstanceSize: public HTemplateInstruction<1> {
4473 public: 4703 public:
4474 explicit HInstanceSize(HValue* object) { 4704 explicit HInstanceSize(HValue* object) {
4475 SetOperandAt(0, object); 4705 SetOperandAt(0, object);
4476 set_representation(Representation::Integer32()); 4706 set_representation(Representation::Integer32());
4477 } 4707 }
4478 4708
4479 HValue* object() { return OperandAt(0); } 4709 HValue* object() { return OperandAt(0); }
4480 4710
4481 virtual Representation RequiredInputRepresentation(int index) { 4711 virtual Representation RequiredInputRepresentation(int index) {
4482 return Representation::Tagged(); 4712 return Representation::Tagged();
4483 } 4713 }
4484 4714
4485 DECLARE_CONCRETE_INSTRUCTION(InstanceSize) 4715 DECLARE_CONCRETE_INSTRUCTION(InstanceSize)
4486 }; 4716 };
4487 4717
4488 4718
4489 class HPower: public HTemplateInstruction<2> { 4719 class HPower: public HTemplateInstruction<2> {
4490 public: 4720 public:
4491 static HInstruction* New(Zone* zone, HValue* left, HValue* right); 4721 static HInstruction* New(Zone* zone,
4722 HValue* context,
4723 HValue* left,
4724 HValue* right);
4492 4725
4493 HValue* left() { return OperandAt(0); } 4726 HValue* left() { return OperandAt(0); }
4494 HValue* right() const { return OperandAt(1); } 4727 HValue* right() const { return OperandAt(1); }
4495 4728
4496 virtual Representation RequiredInputRepresentation(int index) { 4729 virtual Representation RequiredInputRepresentation(int index) {
4497 return index == 0 4730 return index == 0
4498 ? Representation::Double() 4731 ? Representation::Double()
4499 : Representation::None(); 4732 : Representation::None();
4500 } 4733 }
4501 virtual Representation observed_input_representation(int index) { 4734 virtual Representation observed_input_representation(int index) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4550 HValue* right); 4783 HValue* right);
4551 4784
4552 // Add is only commutative if two integer values are added and not if two 4785 // Add is only commutative if two integer values are added and not if two
4553 // tagged values are added (because it might be a String concatenation). 4786 // tagged values are added (because it might be a String concatenation).
4554 virtual bool IsCommutative() const { 4787 virtual bool IsCommutative() const {
4555 return !representation().IsTagged(); 4788 return !representation().IsTagged();
4556 } 4789 }
4557 4790
4558 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4791 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4559 4792
4560 virtual HType CalculateInferredType();
4561
4562 virtual HValue* Canonicalize(); 4793 virtual HValue* Canonicalize();
4563 4794
4564 virtual bool TryDecompose(DecompositionResult* decomposition) { 4795 virtual bool TryDecompose(DecompositionResult* decomposition) {
4565 if (left()->IsInteger32Constant()) { 4796 if (left()->IsInteger32Constant()) {
4566 decomposition->Apply(right(), left()->GetInteger32Constant()); 4797 decomposition->Apply(right(), left()->GetInteger32Constant());
4567 return true; 4798 return true;
4568 } else if (right()->IsInteger32Constant()) { 4799 } else if (right()->IsInteger32Constant()) {
4569 decomposition->Apply(left(), right()->GetInteger32Constant()); 4800 decomposition->Apply(left(), right()->GetInteger32Constant());
4570 return true; 4801 return true;
4571 } else { 4802 } else {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4818 : HArithmeticBinaryOperation(context, left, right), 5049 : HArithmeticBinaryOperation(context, left, right),
4819 operation_(op) { } 5050 operation_(op) { }
4820 5051
4821 Operation operation_; 5052 Operation operation_;
4822 }; 5053 };
4823 5054
4824 5055
4825 class HBitwise: public HBitwiseBinaryOperation { 5056 class HBitwise: public HBitwiseBinaryOperation {
4826 public: 5057 public:
4827 static HInstruction* New(Zone* zone, 5058 static HInstruction* New(Zone* zone,
5059 HValue* context,
4828 Token::Value op, 5060 Token::Value op,
4829 HValue* context,
4830 HValue* left, 5061 HValue* left,
4831 HValue* right); 5062 HValue* right);
4832 5063
4833 Token::Value op() const { return op_; } 5064 Token::Value op() const { return op_; }
4834 5065
4835 virtual bool IsCommutative() const { return true; } 5066 virtual bool IsCommutative() const { return true; }
4836 5067
4837 virtual HValue* Canonicalize(); 5068 virtual HValue* Canonicalize();
4838 5069
4839 virtual void PrintDataTo(StringStream* stream); 5070 virtual void PrintDataTo(StringStream* stream);
4840 5071
4841 DECLARE_CONCRETE_INSTRUCTION(Bitwise) 5072 DECLARE_CONCRETE_INSTRUCTION(Bitwise)
4842 5073
4843 protected: 5074 protected:
4844 virtual bool DataEquals(HValue* other) { 5075 virtual bool DataEquals(HValue* other) {
4845 return op() == HBitwise::cast(other)->op(); 5076 return op() == HBitwise::cast(other)->op();
4846 } 5077 }
4847 5078
4848 virtual Range* InferRange(Zone* zone); 5079 virtual Range* InferRange(Zone* zone);
4849 5080
4850 private: 5081 private:
4851 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) 5082 HBitwise(HValue* context,
4852 : HBitwiseBinaryOperation(context, left, right), op_(op) { 5083 Token::Value op,
5084 HValue* left,
5085 HValue* right)
5086 : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()),
5087 op_(op) {
4853 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); 5088 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
4854 // BIT_AND with a smi-range positive value will always unset the 5089 // BIT_AND with a smi-range positive value will always unset the
4855 // entire sign-extension of the smi-sign. 5090 // entire sign-extension of the smi-sign.
4856 if (op == Token::BIT_AND && 5091 if (op == Token::BIT_AND &&
4857 ((left->IsConstant() && 5092 ((left->IsConstant() &&
4858 left->representation().IsSmi() && 5093 left->representation().IsSmi() &&
4859 HConstant::cast(left)->Integer32Value() >= 0) || 5094 HConstant::cast(left)->Integer32Value() >= 0) ||
4860 (right->IsConstant() && 5095 (right->IsConstant() &&
4861 right->representation().IsSmi() && 5096 right->representation().IsSmi() &&
4862 HConstant::cast(right)->Integer32Value() >= 0))) { 5097 HConstant::cast(right)->Integer32Value() >= 0))) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
5003 5238
5004 DECLARE_CONCRETE_INSTRUCTION(Ror) 5239 DECLARE_CONCRETE_INSTRUCTION(Ror)
5005 5240
5006 protected: 5241 protected:
5007 virtual bool DataEquals(HValue* other) { return true; } 5242 virtual bool DataEquals(HValue* other) { return true; }
5008 }; 5243 };
5009 5244
5010 5245
5011 class HOsrEntry: public HTemplateInstruction<0> { 5246 class HOsrEntry: public HTemplateInstruction<0> {
5012 public: 5247 public:
5013 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { 5248 DECLARE_INSTRUCTION_FACTORY_P1(HOsrEntry, BailoutId);
5014 SetGVNFlag(kChangesOsrEntries);
5015 SetGVNFlag(kChangesNewSpacePromotion);
5016 }
5017 5249
5018 BailoutId ast_id() const { return ast_id_; } 5250 BailoutId ast_id() const { return ast_id_; }
5019 5251
5020 virtual Representation RequiredInputRepresentation(int index) { 5252 virtual Representation RequiredInputRepresentation(int index) {
5021 return Representation::None(); 5253 return Representation::None();
5022 } 5254 }
5023 5255
5024 DECLARE_CONCRETE_INSTRUCTION(OsrEntry) 5256 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
5025 5257
5026 private: 5258 private:
5259 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
5260 SetGVNFlag(kChangesOsrEntries);
5261 SetGVNFlag(kChangesNewSpacePromotion);
5262 }
5263
5027 BailoutId ast_id_; 5264 BailoutId ast_id_;
5028 }; 5265 };
5029 5266
5030 5267
5031 class HParameter: public HTemplateInstruction<0> { 5268 class HParameter: public HTemplateInstruction<0> {
5032 public: 5269 public:
5033 enum ParameterKind { 5270 enum ParameterKind {
5034 STACK_PARAMETER, 5271 STACK_PARAMETER,
5035 REGISTER_PARAMETER 5272 REGISTER_PARAMETER
5036 }; 5273 };
5037 5274
5275 DECLARE_INSTRUCTION_FACTORY_P1(HParameter, unsigned);
5276 DECLARE_INSTRUCTION_FACTORY_P2(HParameter, unsigned, ParameterKind);
5277 DECLARE_INSTRUCTION_FACTORY_P3(HParameter, unsigned, ParameterKind,
5278 Representation);
5279
5280 unsigned index() const { return index_; }
5281 ParameterKind kind() const { return kind_; }
5282
5283 virtual void PrintDataTo(StringStream* stream);
5284
5285 virtual Representation RequiredInputRepresentation(int index) {
5286 return Representation::None();
5287 }
5288
5289 DECLARE_CONCRETE_INSTRUCTION(Parameter)
5290
5291 private:
5038 explicit HParameter(unsigned index, 5292 explicit HParameter(unsigned index,
5039 ParameterKind kind = STACK_PARAMETER) 5293 ParameterKind kind = STACK_PARAMETER)
5040 : index_(index), 5294 : index_(index),
5041 kind_(kind) { 5295 kind_(kind) {
5042 set_representation(Representation::Tagged()); 5296 set_representation(Representation::Tagged());
5043 } 5297 }
5044 5298
5045 explicit HParameter(unsigned index, 5299 explicit HParameter(unsigned index,
5046 ParameterKind kind, 5300 ParameterKind kind,
5047 Representation r) 5301 Representation r)
5048 : index_(index), 5302 : index_(index),
5049 kind_(kind) { 5303 kind_(kind) {
5050 set_representation(r); 5304 set_representation(r);
5051 } 5305 }
5052 5306
5053 unsigned index() const { return index_; }
5054 ParameterKind kind() const { return kind_; }
5055
5056 virtual void PrintDataTo(StringStream* stream);
5057
5058 virtual Representation RequiredInputRepresentation(int index) {
5059 return Representation::None();
5060 }
5061
5062 DECLARE_CONCRETE_INSTRUCTION(Parameter)
5063
5064 private:
5065 unsigned index_; 5307 unsigned index_;
5066 ParameterKind kind_; 5308 ParameterKind kind_;
5067 }; 5309 };
5068 5310
5069 5311
5070 class HCallStub: public HUnaryCall { 5312 class HCallStub: public HUnaryCall {
5071 public: 5313 public:
5072 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) 5314 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
5073 : HUnaryCall(context, argument_count), 5315 : HUnaryCall(context, argument_count),
5074 major_key_(major_key), 5316 major_key_(major_key),
(...skipping 20 matching lines...) Expand all
5095 DECLARE_CONCRETE_INSTRUCTION(CallStub) 5337 DECLARE_CONCRETE_INSTRUCTION(CallStub)
5096 5338
5097 private: 5339 private:
5098 CodeStub::Major major_key_; 5340 CodeStub::Major major_key_;
5099 TranscendentalCache::Type transcendental_type_; 5341 TranscendentalCache::Type transcendental_type_;
5100 }; 5342 };
5101 5343
5102 5344
5103 class HUnknownOSRValue: public HTemplateInstruction<0> { 5345 class HUnknownOSRValue: public HTemplateInstruction<0> {
5104 public: 5346 public:
5105 HUnknownOSRValue() 5347 DECLARE_INSTRUCTION_FACTORY_P0(HUnknownOSRValue)
5106 : incoming_value_(NULL) {
5107 set_representation(Representation::Tagged());
5108 }
5109 5348
5110 virtual Representation RequiredInputRepresentation(int index) { 5349 virtual Representation RequiredInputRepresentation(int index) {
5111 return Representation::None(); 5350 return Representation::None();
5112 } 5351 }
5113 5352
5114 void set_incoming_value(HPhi* value) { 5353 void set_incoming_value(HPhi* value) {
5115 incoming_value_ = value; 5354 incoming_value_ = value;
5116 } 5355 }
5117 5356
5118 HPhi* incoming_value() { 5357 HPhi* incoming_value() {
5119 return incoming_value_; 5358 return incoming_value_;
5120 } 5359 }
5121 5360
5122 virtual Representation KnownOptimalRepresentation() { 5361 virtual Representation KnownOptimalRepresentation() {
5123 if (incoming_value_ == NULL) return Representation::None(); 5362 if (incoming_value_ == NULL) return Representation::None();
5124 return incoming_value_->KnownOptimalRepresentation(); 5363 return incoming_value_->KnownOptimalRepresentation();
5125 } 5364 }
5126 5365
5127 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) 5366 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
5128 5367
5129 private: 5368 private:
5369 HUnknownOSRValue()
5370 : incoming_value_(NULL) {
5371 set_representation(Representation::Tagged());
5372 }
5373
5130 HPhi* incoming_value_; 5374 HPhi* incoming_value_;
5131 }; 5375 };
5132 5376
5133 5377
5134 class HLoadGlobalCell: public HTemplateInstruction<0> { 5378 class HLoadGlobalCell: public HTemplateInstruction<0> {
5135 public: 5379 public:
5136 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) 5380 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details)
5137 : cell_(cell), details_(details), unique_id_() { 5381 : cell_(cell), details_(details), unique_id_() {
5138 set_representation(Representation::Tagged()); 5382 set_representation(Representation::Tagged());
5139 SetFlag(kUseGVN); 5383 SetFlag(kUseGVN);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5202 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) 5446 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
5203 5447
5204 private: 5448 private:
5205 Handle<Object> name_; 5449 Handle<Object> name_;
5206 bool for_typeof_; 5450 bool for_typeof_;
5207 }; 5451 };
5208 5452
5209 5453
5210 class HAllocate: public HTemplateInstruction<2> { 5454 class HAllocate: public HTemplateInstruction<2> {
5211 public: 5455 public:
5212 enum Flags { 5456 static HAllocate* New(Zone* zone,
5213 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, 5457 HValue* context,
5214 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, 5458 HValue* size,
5215 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, 5459 HType type,
5216 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, 5460 PretenureFlag pretenure_flag,
5217 PREFILL_WITH_FILLER = 1 << 4 5461 InstanceType instance_type) {
5218 }; 5462 return new(zone) HAllocate(context, size, type, pretenure_flag,
5219 5463 instance_type);
5220 HAllocate(HValue* context, HValue* size, HType type, Flags flags)
5221 : flags_(flags) {
5222 SetOperandAt(0, context);
5223 SetOperandAt(1, size);
5224 set_type(type);
5225 set_representation(Representation::Tagged());
5226 SetFlag(kTrackSideEffectDominators);
5227 SetGVNFlag(kChangesNewSpacePromotion);
5228 SetGVNFlag(kDependsOnNewSpacePromotion);
5229 } 5464 }
5230 5465
5231 // Maximum instance size for which allocations will be inlined. 5466 // Maximum instance size for which allocations will be inlined.
5232 static const int kMaxInlineSize = 64 * kPointerSize; 5467 static const int kMaxInlineSize = 64 * kPointerSize;
5233 5468
5234 static Flags DefaultFlags() {
5235 return CAN_ALLOCATE_IN_NEW_SPACE;
5236 }
5237
5238 static Flags DefaultFlags(ElementsKind kind) {
5239 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE;
5240 if (IsFastDoubleElementsKind(kind)) {
5241 flags = static_cast<HAllocate::Flags>(
5242 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
5243 }
5244 return flags;
5245 }
5246
5247 HValue* context() { return OperandAt(0); } 5469 HValue* context() { return OperandAt(0); }
5248 HValue* size() { return OperandAt(1); } 5470 HValue* size() { return OperandAt(1); }
5249 5471
5250 virtual Representation RequiredInputRepresentation(int index) { 5472 virtual Representation RequiredInputRepresentation(int index) {
5251 if (index == 0) { 5473 if (index == 0) {
5252 return Representation::Tagged(); 5474 return Representation::Tagged();
5253 } else { 5475 } else {
5254 return Representation::Integer32(); 5476 return Representation::Integer32();
5255 } 5477 }
5256 } 5478 }
5257 5479
5258 virtual Handle<Map> GetMonomorphicJSObjectMap() { 5480 virtual Handle<Map> GetMonomorphicJSObjectMap() {
5259 return known_initial_map_; 5481 return known_initial_map_;
5260 } 5482 }
5261 5483
5262 void set_known_initial_map(Handle<Map> known_initial_map) { 5484 void set_known_initial_map(Handle<Map> known_initial_map) {
5263 known_initial_map_ = known_initial_map; 5485 known_initial_map_ = known_initial_map;
5264 } 5486 }
5265 5487
5266 bool CanAllocateInNewSpace() const { 5488 bool IsNewSpaceAllocation() const {
5267 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; 5489 return (flags_ & ALLOCATE_IN_NEW_SPACE) != 0;
5268 } 5490 }
5269 5491
5270 bool CanAllocateInOldDataSpace() const { 5492 bool IsOldDataSpaceAllocation() const {
5271 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; 5493 return (flags_ & ALLOCATE_IN_OLD_DATA_SPACE) != 0;
5272 } 5494 }
5273 5495
5274 bool CanAllocateInOldPointerSpace() const { 5496 bool IsOldPointerSpaceAllocation() const {
5275 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0; 5497 return (flags_ & ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
5276 }
5277
5278 bool CanAllocateInOldSpace() const {
5279 return CanAllocateInOldDataSpace() ||
5280 CanAllocateInOldPointerSpace();
5281 }
5282
5283 bool GuaranteedInNewSpace() const {
5284 return CanAllocateInNewSpace() && !CanAllocateInOldSpace();
5285 } 5498 }
5286 5499
5287 bool MustAllocateDoubleAligned() const { 5500 bool MustAllocateDoubleAligned() const {
5288 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; 5501 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
5289 } 5502 }
5290 5503
5291 bool MustPrefillWithFiller() const { 5504 bool MustPrefillWithFiller() const {
5292 return (flags_ & PREFILL_WITH_FILLER) != 0; 5505 return (flags_ & PREFILL_WITH_FILLER) != 0;
5293 } 5506 }
5294 5507
5295 void SetFlags(Flags flags) { 5508 void MakePrefillWithFiller() {
5296 flags_ = static_cast<HAllocate::Flags>(flags_ | flags); 5509 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
5510 }
5511
5512 void MakeDoubleAligned() {
5513 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
5297 } 5514 }
5298 5515
5299 void UpdateSize(HValue* size) { 5516 void UpdateSize(HValue* size) {
5300 SetOperandAt(1, size); 5517 SetOperandAt(1, size);
5301 } 5518 }
5302 5519
5303 virtual void HandleSideEffectDominator(GVNFlag side_effect, 5520 virtual void HandleSideEffectDominator(GVNFlag side_effect,
5304 HValue* dominator); 5521 HValue* dominator);
5305 5522
5306 virtual void PrintDataTo(StringStream* stream); 5523 virtual void PrintDataTo(StringStream* stream);
5307 5524
5308 DECLARE_CONCRETE_INSTRUCTION(Allocate) 5525 DECLARE_CONCRETE_INSTRUCTION(Allocate)
5309 5526
5310 private: 5527 private:
5528 enum Flags {
5529 ALLOCATE_IN_NEW_SPACE = 1 << 0,
5530 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
5531 ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
5532 ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
5533 PREFILL_WITH_FILLER = 1 << 4
5534 };
5535
5536 HAllocate(HValue* context,
5537 HValue* size,
5538 HType type,
5539 PretenureFlag pretenure_flag,
5540 InstanceType instance_type)
5541 : HTemplateInstruction<2>(type) {
5542 SetOperandAt(0, context);
5543 SetOperandAt(1, size);
5544 set_representation(Representation::Tagged());
5545 SetFlag(kTrackSideEffectDominators);
5546 SetGVNFlag(kChangesNewSpacePromotion);
5547 SetGVNFlag(kDependsOnNewSpacePromotion);
5548 flags_ = pretenure_flag == TENURED
5549 ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE
5550 ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE)
5551 : ALLOCATE_IN_NEW_SPACE;
5552 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
5553 flags_ = static_cast<HAllocate::Flags>(flags_ |
5554 ALLOCATE_DOUBLE_ALIGNED);
5555 }
5556 }
5557
5311 Flags flags_; 5558 Flags flags_;
5312 Handle<Map> known_initial_map_; 5559 Handle<Map> known_initial_map_;
5313 }; 5560 };
5314 5561
5315 5562
5316 class HInnerAllocatedObject: public HTemplateInstruction<1> { 5563 class HInnerAllocatedObject: public HTemplateInstruction<1> {
5317 public: 5564 public:
5318 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) 5565 static HInnerAllocatedObject* New(Zone* zone,
5319 : offset_(offset) { 5566 HValue* context,
5320 ASSERT(value->IsAllocate()); 5567 HValue* value,
5321 SetOperandAt(0, value); 5568 int offset,
5322 set_type(type); 5569 HType type = HType::Tagged()) {
5323 set_representation(Representation::Tagged()); 5570 return new(zone) HInnerAllocatedObject(value, offset, type);
5324 } 5571 }
5325 5572
5326 HValue* base_object() { return OperandAt(0); } 5573 HValue* base_object() { return OperandAt(0); }
5327 int offset() { return offset_; } 5574 int offset() { return offset_; }
5328 5575
5329 virtual Representation RequiredInputRepresentation(int index) { 5576 virtual Representation RequiredInputRepresentation(int index) {
5330 return Representation::Tagged(); 5577 return Representation::Tagged();
5331 } 5578 }
5332 5579
5333 virtual void PrintDataTo(StringStream* stream); 5580 virtual void PrintDataTo(StringStream* stream);
5334 5581
5335 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) 5582 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
5336 5583
5337 private: 5584 private:
5585 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged())
5586 : HTemplateInstruction<1>(type), offset_(offset) {
5587 ASSERT(value->IsAllocate());
5588 SetOperandAt(0, value);
5589 set_type(type);
5590 set_representation(Representation::Tagged());
5591 }
5592
5338 int offset_; 5593 int offset_;
5339 }; 5594 };
5340 5595
5341 5596
5342 inline bool StoringValueNeedsWriteBarrier(HValue* value) { 5597 inline bool StoringValueNeedsWriteBarrier(HValue* value) {
5343 return !value->type().IsBoolean() 5598 return !value->type().IsBoolean()
5344 && !value->type().IsSmi() 5599 && !value->type().IsSmi()
5345 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); 5600 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
5346 } 5601 }
5347 5602
5348 5603
5349 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, 5604 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
5350 HValue* new_space_dominator) { 5605 HValue* new_space_dominator) {
5351 if (object->IsInnerAllocatedObject()) { 5606 if (object->IsInnerAllocatedObject()) {
5352 return ReceiverObjectNeedsWriteBarrier( 5607 return ReceiverObjectNeedsWriteBarrier(
5353 HInnerAllocatedObject::cast(object)->base_object(), 5608 HInnerAllocatedObject::cast(object)->base_object(),
5354 new_space_dominator); 5609 new_space_dominator);
5355 } 5610 }
5356 if (object->IsConstant() && HConstant::cast(object)->IsCell()) { 5611 if (object->IsConstant() && HConstant::cast(object)->IsCell()) {
5357 return false; 5612 return false;
5358 } 5613 }
5614 if (object->IsConstant() &&
5615 HConstant::cast(object)->HasExternalReferenceValue()) {
5616 // Stores to external references require no write barriers
5617 return false;
5618 }
5359 if (object != new_space_dominator) return true; 5619 if (object != new_space_dominator) return true;
5360 if (object->IsAllocate()) { 5620 if (object->IsAllocate()) {
5361 return !HAllocate::cast(object)->GuaranteedInNewSpace(); 5621 return !HAllocate::cast(object)->IsNewSpaceAllocation();
5362 } 5622 }
5363 return true; 5623 return true;
5364 } 5624 }
5365 5625
5366 5626
5367 class HStoreGlobalCell: public HUnaryOperation { 5627 class HStoreGlobalCell: public HUnaryOperation {
5368 public: 5628 public:
5369 HStoreGlobalCell(HValue* value, 5629 DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*,
5370 Handle<PropertyCell> cell, 5630 Handle<PropertyCell>, PropertyDetails);
5371 PropertyDetails details)
5372 : HUnaryOperation(value),
5373 cell_(cell),
5374 details_(details) {
5375 SetGVNFlag(kChangesGlobalVars);
5376 }
5377 5631
5378 Handle<PropertyCell> cell() const { return cell_; } 5632 Handle<PropertyCell> cell() const { return cell_; }
5379 bool RequiresHoleCheck() { 5633 bool RequiresHoleCheck() {
5380 return !details_.IsDontDelete() || details_.IsReadOnly(); 5634 return !details_.IsDontDelete() || details_.IsReadOnly();
5381 } 5635 }
5382 bool NeedsWriteBarrier() { 5636 bool NeedsWriteBarrier() {
5383 return StoringValueNeedsWriteBarrier(value()); 5637 return StoringValueNeedsWriteBarrier(value());
5384 } 5638 }
5385 5639
5386 virtual Representation RequiredInputRepresentation(int index) { 5640 virtual Representation RequiredInputRepresentation(int index) {
5387 return Representation::Tagged(); 5641 return Representation::Tagged();
5388 } 5642 }
5389 virtual void PrintDataTo(StringStream* stream); 5643 virtual void PrintDataTo(StringStream* stream);
5390 5644
5391 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell) 5645 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
5392 5646
5393 private: 5647 private:
5648 HStoreGlobalCell(HValue* value,
5649 Handle<PropertyCell> cell,
5650 PropertyDetails details)
5651 : HUnaryOperation(value),
5652 cell_(cell),
5653 details_(details) {
5654 SetGVNFlag(kChangesGlobalVars);
5655 }
5656
5394 Handle<PropertyCell> cell_; 5657 Handle<PropertyCell> cell_;
5395 PropertyDetails details_; 5658 PropertyDetails details_;
5396 }; 5659 };
5397 5660
5398 5661
5399 class HStoreGlobalGeneric: public HTemplateInstruction<3> { 5662 class HStoreGlobalGeneric: public HTemplateInstruction<3> {
5400 public: 5663 public:
5401 HStoreGlobalGeneric(HValue* context, 5664 inline static HStoreGlobalGeneric* New(Zone* zone,
5402 HValue* global_object, 5665 HValue* context,
5403 Handle<Object> name, 5666 HValue* global_object,
5404 HValue* value, 5667 Handle<Object> name,
5405 StrictModeFlag strict_mode_flag) 5668 HValue* value,
5406 : name_(name), 5669 StrictModeFlag strict_mode_flag) {
5407 strict_mode_flag_(strict_mode_flag) { 5670 return new(zone) HStoreGlobalGeneric(context, global_object,
5408 SetOperandAt(0, context); 5671 name, value, strict_mode_flag);
5409 SetOperandAt(1, global_object);
5410 SetOperandAt(2, value);
5411 set_representation(Representation::Tagged());
5412 SetAllSideEffects();
5413 } 5672 }
5414 5673
5415 HValue* context() { return OperandAt(0); } 5674 HValue* context() { return OperandAt(0); }
5416 HValue* global_object() { return OperandAt(1); } 5675 HValue* global_object() { return OperandAt(1); }
5417 Handle<Object> name() const { return name_; } 5676 Handle<Object> name() const { return name_; }
5418 HValue* value() { return OperandAt(2); } 5677 HValue* value() { return OperandAt(2); }
5419 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } 5678 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
5420 5679
5421 virtual void PrintDataTo(StringStream* stream); 5680 virtual void PrintDataTo(StringStream* stream);
5422 5681
5423 virtual Representation RequiredInputRepresentation(int index) { 5682 virtual Representation RequiredInputRepresentation(int index) {
5424 return Representation::Tagged(); 5683 return Representation::Tagged();
5425 } 5684 }
5426 5685
5427 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric) 5686 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
5428 5687
5429 private: 5688 private:
5689 HStoreGlobalGeneric(HValue* context,
5690 HValue* global_object,
5691 Handle<Object> name,
5692 HValue* value,
5693 StrictModeFlag strict_mode_flag)
5694 : name_(name),
5695 strict_mode_flag_(strict_mode_flag) {
5696 SetOperandAt(0, context);
5697 SetOperandAt(1, global_object);
5698 SetOperandAt(2, value);
5699 set_representation(Representation::Tagged());
5700 SetAllSideEffects();
5701 }
5702
5430 Handle<Object> name_; 5703 Handle<Object> name_;
5431 StrictModeFlag strict_mode_flag_; 5704 StrictModeFlag strict_mode_flag_;
5432 }; 5705 };
5433 5706
5434 5707
5435 class HLoadContextSlot: public HUnaryOperation { 5708 class HLoadContextSlot: public HUnaryOperation {
5436 public: 5709 public:
5437 enum Mode { 5710 enum Mode {
5438 // Perform a normal load of the context slot without checking its value. 5711 // Perform a normal load of the context slot without checking its value.
5439 kNoCheck, 5712 kNoCheck,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
5507 kNoCheck, 5780 kNoCheck,
5508 // Check the previous value of the context slot and deoptimize if it's the 5781 // Check the previous value of the context slot and deoptimize if it's the
5509 // hole value. This is used for checking for assignments to uninitialized 5782 // hole value. This is used for checking for assignments to uninitialized
5510 // harmony bindings where we deoptimize into full-codegen generated code 5783 // harmony bindings where we deoptimize into full-codegen generated code
5511 // which will subsequently throw a reference error. 5784 // which will subsequently throw a reference error.
5512 kCheckDeoptimize, 5785 kCheckDeoptimize,
5513 // Check the previous value and ignore assignment if it isn't a hole value 5786 // Check the previous value and ignore assignment if it isn't a hole value
5514 kCheckIgnoreAssignment 5787 kCheckIgnoreAssignment
5515 }; 5788 };
5516 5789
5517 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) 5790 DECLARE_INSTRUCTION_FACTORY_P4(HStoreContextSlot, HValue*, int,
5518 : slot_index_(slot_index), mode_(mode) { 5791 Mode, HValue*);
5519 SetOperandAt(0, context);
5520 SetOperandAt(1, value);
5521 SetGVNFlag(kChangesContextSlots);
5522 }
5523 5792
5524 HValue* context() { return OperandAt(0); } 5793 HValue* context() { return OperandAt(0); }
5525 HValue* value() { return OperandAt(1); } 5794 HValue* value() { return OperandAt(1); }
5526 int slot_index() const { return slot_index_; } 5795 int slot_index() const { return slot_index_; }
5527 Mode mode() const { return mode_; } 5796 Mode mode() const { return mode_; }
5528 5797
5529 bool NeedsWriteBarrier() { 5798 bool NeedsWriteBarrier() {
5530 return StoringValueNeedsWriteBarrier(value()); 5799 return StoringValueNeedsWriteBarrier(value());
5531 } 5800 }
5532 5801
5533 bool DeoptimizesOnHole() { 5802 bool DeoptimizesOnHole() {
5534 return mode_ == kCheckDeoptimize; 5803 return mode_ == kCheckDeoptimize;
5535 } 5804 }
5536 5805
5537 bool RequiresHoleCheck() { 5806 bool RequiresHoleCheck() {
5538 return mode_ != kNoCheck; 5807 return mode_ != kNoCheck;
5539 } 5808 }
5540 5809
5541 virtual Representation RequiredInputRepresentation(int index) { 5810 virtual Representation RequiredInputRepresentation(int index) {
5542 return Representation::Tagged(); 5811 return Representation::Tagged();
5543 } 5812 }
5544 5813
5545 virtual void PrintDataTo(StringStream* stream); 5814 virtual void PrintDataTo(StringStream* stream);
5546 5815
5547 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) 5816 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
5548 5817
5549 private: 5818 private:
5819 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
5820 : slot_index_(slot_index), mode_(mode) {
5821 SetOperandAt(0, context);
5822 SetOperandAt(1, value);
5823 SetGVNFlag(kChangesContextSlots);
5824 }
5825
5550 int slot_index_; 5826 int slot_index_;
5551 Mode mode_; 5827 Mode mode_;
5552 }; 5828 };
5553 5829
5554 5830
5555 // Represents an access to a portion of an object, such as the map pointer, 5831 // Represents an access to a portion of an object, such as the map pointer,
5556 // array elements pointer, etc, but not accesses to array elements themselves. 5832 // array elements pointer, etc, but not accesses to array elements themselves.
5557 class HObjectAccess { 5833 class HObjectAccess {
5558 public: 5834 public:
5559 inline bool IsInobject() const { 5835 inline bool IsInobject() const {
5560 return portion() != kBackingStore; 5836 return portion() != kBackingStore && portion() != kExternalMemory;
5837 }
5838
5839 inline bool IsExternalMemory() const {
5840 return portion() == kExternalMemory;
5841 }
5842
5843 inline bool IsStringLength() const {
5844 return portion() == kStringLengths;
5561 } 5845 }
5562 5846
5563 inline int offset() const { 5847 inline int offset() const {
5564 return OffsetField::decode(value_); 5848 return OffsetField::decode(value_);
5565 } 5849 }
5566 5850
5567 inline Representation representation() const { 5851 inline Representation representation() const {
5568 return Representation::FromKind(RepresentationField::decode(value_)); 5852 return Representation::FromKind(RepresentationField::decode(value_));
5569 } 5853 }
5570 5854
5571 inline Handle<String> name() const { 5855 inline Handle<String> name() const {
5572 return name_; 5856 return name_;
5573 } 5857 }
5574 5858
5575 inline HObjectAccess WithRepresentation(Representation representation) { 5859 inline HObjectAccess WithRepresentation(Representation representation) {
5576 return HObjectAccess(portion(), offset(), representation, name()); 5860 return HObjectAccess(portion(), offset(), representation, name());
5577 } 5861 }
5578 5862
5579 static HObjectAccess ForHeapNumberValue() { 5863 static HObjectAccess ForHeapNumberValue() {
5580 return HObjectAccess( 5864 return HObjectAccess(
5581 kDouble, HeapNumber::kValueOffset, Representation::Double()); 5865 kDouble, HeapNumber::kValueOffset, Representation::Double());
5582 } 5866 }
5583 5867
5584 static HObjectAccess ForElementsPointer() { 5868 static HObjectAccess ForElementsPointer() {
5585 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); 5869 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
5586 } 5870 }
5587 5871
5588 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { 5872 static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
5589 return HObjectAccess( 5873 return HObjectAccess(
5590 kArrayLengths, JSArray::kLengthOffset, 5874 kArrayLengths,
5591 IsFastElementsKind(elements_kind) && FLAG_track_fields ? 5875 JSArray::kLengthOffset,
5592 Representation::Smi() : Representation::Tagged()); 5876 IsFastElementsKind(elements_kind) &&
5877 FLAG_track_fields
5878 ? Representation::Smi() : Representation::Tagged());
5593 } 5879 }
5594 5880
5595 static HObjectAccess ForAllocationSiteTransitionInfo() { 5881 static HObjectAccess ForAllocationSiteTransitionInfo() {
5596 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); 5882 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset);
5597 } 5883 }
5598 5884
5599 static HObjectAccess ForAllocationSiteWeakNext() { 5885 static HObjectAccess ForAllocationSiteWeakNext() {
5600 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); 5886 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset);
5601 } 5887 }
5602 5888
5889 static HObjectAccess ForAllocationSiteList() {
5890 return HObjectAccess(kExternalMemory, 0, Representation::Tagged());
5891 }
5892
5603 static HObjectAccess ForFixedArrayLength() { 5893 static HObjectAccess ForFixedArrayLength() {
5604 return HObjectAccess( 5894 return HObjectAccess(
5605 kArrayLengths, FixedArray::kLengthOffset, 5895 kArrayLengths,
5606 FLAG_track_fields ? 5896 FixedArray::kLengthOffset,
5607 Representation::Smi() : Representation::Tagged()); 5897 FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
5898 }
5899
5900 static HObjectAccess ForStringLength() {
5901 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
5902 return HObjectAccess(
5903 kStringLengths,
5904 String::kLengthOffset,
5905 FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
5608 } 5906 }
5609 5907
5610 static HObjectAccess ForPropertiesPointer() { 5908 static HObjectAccess ForPropertiesPointer() {
5611 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); 5909 return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
5612 } 5910 }
5613 5911
5614 static HObjectAccess ForPrototypeOrInitialMap() { 5912 static HObjectAccess ForPrototypeOrInitialMap() {
5615 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); 5913 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
5616 } 5914 }
5617 5915
5618 static HObjectAccess ForMap() { 5916 static HObjectAccess ForMap() {
5619 return HObjectAccess(kMaps, JSObject::kMapOffset); 5917 return HObjectAccess(kMaps, JSObject::kMapOffset);
5620 } 5918 }
5621 5919
5622 static HObjectAccess ForPropertyCellValue() { 5920 static HObjectAccess ForPropertyCellValue() {
5623 return HObjectAccess(kInobject, PropertyCell::kValueOffset); 5921 return HObjectAccess(kInobject, PropertyCell::kValueOffset);
5624 } 5922 }
5625 5923
5626 static HObjectAccess ForCellValue() { 5924 static HObjectAccess ForCellValue() {
5627 return HObjectAccess(kInobject, Cell::kValueOffset); 5925 return HObjectAccess(kInobject, Cell::kValueOffset);
5628 } 5926 }
5629 5927
5630 static HObjectAccess ForAllocationMementoSite() { 5928 static HObjectAccess ForAllocationMementoSite() {
5631 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); 5929 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
5632 } 5930 }
5633 5931
5932 static HObjectAccess ForCounter() {
5933 return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
5934 }
5935
5634 // Create an access to an offset in a fixed array header. 5936 // Create an access to an offset in a fixed array header.
5635 static HObjectAccess ForFixedArrayHeader(int offset); 5937 static HObjectAccess ForFixedArrayHeader(int offset);
5636 5938
5637 // Create an access to an in-object property in a JSObject. 5939 // Create an access to an in-object property in a JSObject.
5638 static HObjectAccess ForJSObjectOffset(int offset, 5940 static HObjectAccess ForJSObjectOffset(int offset,
5639 Representation representation = Representation::Tagged()); 5941 Representation representation = Representation::Tagged());
5640 5942
5641 // Create an access to an in-object property in a JSArray. 5943 // Create an access to an in-object property in a JSArray.
5642 static HObjectAccess ForJSArrayOffset(int offset); 5944 static HObjectAccess ForJSArrayOffset(int offset);
5643 5945
(...skipping 15 matching lines...) Expand all
5659 } 5961 }
5660 5962
5661 protected: 5963 protected:
5662 void SetGVNFlags(HValue *instr, bool is_store); 5964 void SetGVNFlags(HValue *instr, bool is_store);
5663 5965
5664 private: 5966 private:
5665 // internal use only; different parts of an object or array 5967 // internal use only; different parts of an object or array
5666 enum Portion { 5968 enum Portion {
5667 kMaps, // map of an object 5969 kMaps, // map of an object
5668 kArrayLengths, // the length of an array 5970 kArrayLengths, // the length of an array
5971 kStringLengths, // the length of a string
5669 kElementsPointer, // elements pointer 5972 kElementsPointer, // elements pointer
5670 kBackingStore, // some field in the backing store 5973 kBackingStore, // some field in the backing store
5671 kDouble, // some double field 5974 kDouble, // some double field
5672 kInobject // some other in-object field 5975 kInobject, // some other in-object field
5976 kExternalMemory // some field in external memory
5673 }; 5977 };
5674 5978
5675 HObjectAccess(Portion portion, int offset, 5979 HObjectAccess(Portion portion, int offset,
5676 Representation representation = Representation::Tagged(), 5980 Representation representation = Representation::Tagged(),
5677 Handle<String> name = Handle<String>::null()) 5981 Handle<String> name = Handle<String>::null())
5678 : value_(PortionField::encode(portion) | 5982 : value_(PortionField::encode(portion) |
5679 RepresentationField::encode(representation.kind()) | 5983 RepresentationField::encode(representation.kind()) |
5680 OffsetField::encode(offset)), 5984 OffsetField::encode(offset)),
5681 name_(name) { 5985 name_(name) {
5682 // assert that the fields decode correctly 5986 // assert that the fields decode correctly
(...skipping 11 matching lines...) Expand all
5694 5998
5695 friend class HLoadNamedField; 5999 friend class HLoadNamedField;
5696 friend class HStoreNamedField; 6000 friend class HStoreNamedField;
5697 6001
5698 inline Portion portion() const { 6002 inline Portion portion() const {
5699 return PortionField::decode(value_); 6003 return PortionField::decode(value_);
5700 } 6004 }
5701 }; 6005 };
5702 6006
5703 6007
5704 class HLinkObjectInList: public HUnaryOperation {
5705 public:
5706 // There needs to be a mapping from every KnownList to an external reference
5707 enum KnownList {
5708 ALLOCATION_SITE_LIST
5709 };
5710
5711 HLinkObjectInList(HValue* object, HObjectAccess store_field,
5712 KnownList known_list)
5713 : HUnaryOperation(object),
5714 store_field_(store_field),
5715 known_list_(known_list) {
5716 set_representation(Representation::Tagged());
5717 }
5718
5719 HObjectAccess store_field() const { return store_field_; }
5720 KnownList known_list() const { return known_list_; }
5721
5722 virtual Representation RequiredInputRepresentation(int index) {
5723 return Representation::Tagged();
5724 }
5725
5726 virtual void PrintDataTo(StringStream* stream);
5727
5728 DECLARE_CONCRETE_INSTRUCTION(LinkObjectInList)
5729
5730 private:
5731 HObjectAccess store_field_;
5732 KnownList known_list_;
5733 };
5734
5735
5736 class HLoadNamedField: public HTemplateInstruction<2> { 6008 class HLoadNamedField: public HTemplateInstruction<2> {
5737 public: 6009 public:
6010 DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess);
6011 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess,
6012 HValue*);
6013
6014 HValue* object() { return OperandAt(0); }
6015 HValue* typecheck() {
6016 ASSERT(HasTypeCheck());
6017 return OperandAt(1);
6018 }
6019
6020 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
6021 HObjectAccess access() const { return access_; }
6022 Representation field_representation() const {
6023 return access_.representation();
6024 }
6025
6026 virtual bool HasEscapingOperandAt(int index) { return false; }
6027 virtual Representation RequiredInputRepresentation(int index) {
6028 if (index == 0 && access().IsExternalMemory()) {
6029 // object must be external in case of external memory access
6030 return Representation::External();
6031 }
6032 return Representation::Tagged();
6033 }
6034 virtual Range* InferRange(Zone* zone);
6035 virtual void PrintDataTo(StringStream* stream);
6036
6037 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
6038
6039 protected:
6040 virtual bool DataEquals(HValue* other) {
6041 HLoadNamedField* b = HLoadNamedField::cast(other);
6042 return access_.Equals(b->access_);
6043 }
6044
6045 private:
5738 HLoadNamedField(HValue* object, 6046 HLoadNamedField(HValue* object,
5739 HObjectAccess access, 6047 HObjectAccess access,
5740 HValue* typecheck = NULL) 6048 HValue* typecheck = NULL)
5741 : access_(access) { 6049 : access_(access) {
5742 ASSERT(object != NULL); 6050 ASSERT(object != NULL);
5743 SetOperandAt(0, object); 6051 SetOperandAt(0, object);
5744 SetOperandAt(1, typecheck != NULL ? typecheck : object); 6052 SetOperandAt(1, typecheck != NULL ? typecheck : object);
5745 6053
5746 Representation representation = access.representation(); 6054 Representation representation = access.representation();
5747 if (representation.IsSmi()) { 6055 if (representation.IsSmi()) {
5748 set_type(HType::Smi()); 6056 set_type(HType::Smi());
5749 set_representation(representation); 6057 set_representation(representation);
5750 } else if (representation.IsDouble()) { 6058 } else if (representation.IsDouble() ||
6059 representation.IsExternal() ||
6060 representation.IsInteger32()) {
5751 set_representation(representation); 6061 set_representation(representation);
5752 } else if (FLAG_track_heap_object_fields && 6062 } else if (FLAG_track_heap_object_fields &&
5753 representation.IsHeapObject()) { 6063 representation.IsHeapObject()) {
5754 set_type(HType::NonPrimitive()); 6064 set_type(HType::NonPrimitive());
5755 set_representation(Representation::Tagged()); 6065 set_representation(Representation::Tagged());
5756 } else { 6066 } else {
5757 set_representation(Representation::Tagged()); 6067 set_representation(Representation::Tagged());
5758 } 6068 }
5759 access.SetGVNFlags(this, false); 6069 access.SetGVNFlags(this, false);
5760 } 6070 }
5761 6071
5762 HValue* object() { return OperandAt(0); }
5763 HValue* typecheck() {
5764 ASSERT(HasTypeCheck());
5765 return OperandAt(1);
5766 }
5767
5768 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
5769 HObjectAccess access() const { return access_; }
5770 Representation field_representation() const {
5771 return access_.representation();
5772 }
5773
5774 virtual bool HasEscapingOperandAt(int index) { return false; }
5775 virtual Representation RequiredInputRepresentation(int index) {
5776 return Representation::Tagged();
5777 }
5778 virtual void PrintDataTo(StringStream* stream);
5779
5780 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5781
5782 protected:
5783 virtual bool DataEquals(HValue* other) {
5784 HLoadNamedField* b = HLoadNamedField::cast(other);
5785 return access_.Equals(b->access_);
5786 }
5787
5788 private:
5789 virtual bool IsDeletable() const { return true; } 6072 virtual bool IsDeletable() const { return true; }
5790 6073
5791 HObjectAccess access_; 6074 HObjectAccess access_;
5792 }; 6075 };
5793 6076
5794 6077
5795 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { 6078 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
5796 public: 6079 public:
5797 HLoadNamedFieldPolymorphic(HValue* context, 6080 HLoadNamedFieldPolymorphic(HValue* context,
5798 HValue* object, 6081 HValue* object,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
5897 6180
5898 enum LoadKeyedHoleMode { 6181 enum LoadKeyedHoleMode {
5899 NEVER_RETURN_HOLE, 6182 NEVER_RETURN_HOLE,
5900 ALLOW_RETURN_HOLE 6183 ALLOW_RETURN_HOLE
5901 }; 6184 };
5902 6185
5903 6186
5904 class HLoadKeyed 6187 class HLoadKeyed
5905 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 6188 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
5906 public: 6189 public:
5907 HLoadKeyed(HValue* obj, 6190 DECLARE_INSTRUCTION_FACTORY_P4(HLoadKeyed, HValue*, HValue*, HValue*,
5908 HValue* key, 6191 ElementsKind);
5909 HValue* dependency, 6192 DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*,
5910 ElementsKind elements_kind, 6193 ElementsKind, LoadKeyedHoleMode);
5911 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
5912 : bit_field_(0) {
5913 bit_field_ = ElementsKindField::encode(elements_kind) |
5914 HoleModeField::encode(mode);
5915
5916 SetOperandAt(0, obj);
5917 SetOperandAt(1, key);
5918 SetOperandAt(2, dependency != NULL ? dependency : obj);
5919
5920 if (!is_external()) {
5921 // I can detect the case between storing double (holey and fast) and
5922 // smi/object by looking at elements_kind_.
5923 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5924 IsFastDoubleElementsKind(elements_kind));
5925
5926 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
5927 if (IsFastSmiElementsKind(elements_kind) &&
5928 (!IsHoleyElementsKind(elements_kind) ||
5929 mode == NEVER_RETURN_HOLE)) {
5930 set_type(HType::Smi());
5931 set_representation(Representation::Smi());
5932 } else {
5933 set_representation(Representation::Tagged());
5934 }
5935
5936 SetGVNFlag(kDependsOnArrayElements);
5937 } else {
5938 set_representation(Representation::Double());
5939 SetGVNFlag(kDependsOnDoubleArrayElements);
5940 }
5941 } else {
5942 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
5943 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
5944 set_representation(Representation::Double());
5945 } else {
5946 set_representation(Representation::Integer32());
5947 }
5948
5949 SetGVNFlag(kDependsOnSpecializedArrayElements);
5950 // Native code could change the specialized array.
5951 SetGVNFlag(kDependsOnCalls);
5952 }
5953
5954 SetFlag(kUseGVN);
5955 }
5956 6194
5957 bool is_external() const { 6195 bool is_external() const {
5958 return IsExternalArrayElementsKind(elements_kind()); 6196 return IsExternalArrayElementsKind(elements_kind());
5959 } 6197 }
5960 HValue* elements() { return OperandAt(0); } 6198 HValue* elements() { return OperandAt(0); }
5961 HValue* key() { return OperandAt(1); } 6199 HValue* key() { return OperandAt(1); }
5962 HValue* dependency() { 6200 HValue* dependency() {
5963 ASSERT(HasDependency()); 6201 ASSERT(HasDependency());
5964 return OperandAt(2); 6202 return OperandAt(2);
5965 } 6203 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
6014 virtual bool DataEquals(HValue* other) { 6252 virtual bool DataEquals(HValue* other) {
6015 if (!other->IsLoadKeyed()) return false; 6253 if (!other->IsLoadKeyed()) return false;
6016 HLoadKeyed* other_load = HLoadKeyed::cast(other); 6254 HLoadKeyed* other_load = HLoadKeyed::cast(other);
6017 6255
6018 if (IsDehoisted() && index_offset() != other_load->index_offset()) 6256 if (IsDehoisted() && index_offset() != other_load->index_offset())
6019 return false; 6257 return false;
6020 return elements_kind() == other_load->elements_kind(); 6258 return elements_kind() == other_load->elements_kind();
6021 } 6259 }
6022 6260
6023 private: 6261 private:
6262 HLoadKeyed(HValue* obj,
6263 HValue* key,
6264 HValue* dependency,
6265 ElementsKind elements_kind,
6266 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
6267 : bit_field_(0) {
6268 bit_field_ = ElementsKindField::encode(elements_kind) |
6269 HoleModeField::encode(mode);
6270
6271 SetOperandAt(0, obj);
6272 SetOperandAt(1, key);
6273 SetOperandAt(2, dependency != NULL ? dependency : obj);
6274
6275 if (!is_external()) {
6276 // I can detect the case between storing double (holey and fast) and
6277 // smi/object by looking at elements_kind_.
6278 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
6279 IsFastDoubleElementsKind(elements_kind));
6280
6281 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
6282 if (IsFastSmiElementsKind(elements_kind) &&
6283 (!IsHoleyElementsKind(elements_kind) ||
6284 mode == NEVER_RETURN_HOLE)) {
6285 set_type(HType::Smi());
6286 set_representation(Representation::Smi());
6287 } else {
6288 set_representation(Representation::Tagged());
6289 }
6290
6291 SetGVNFlag(kDependsOnArrayElements);
6292 } else {
6293 set_representation(Representation::Double());
6294 SetGVNFlag(kDependsOnDoubleArrayElements);
6295 }
6296 } else {
6297 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
6298 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
6299 set_representation(Representation::Double());
6300 } else {
6301 set_representation(Representation::Integer32());
6302 }
6303
6304 SetGVNFlag(kDependsOnExternalMemory);
6305 // Native code could change the specialized array.
6306 SetGVNFlag(kDependsOnCalls);
6307 }
6308
6309 SetFlag(kUseGVN);
6310 }
6311
6024 virtual bool IsDeletable() const { 6312 virtual bool IsDeletable() const {
6025 return !RequiresHoleCheck(); 6313 return !RequiresHoleCheck();
6026 } 6314 }
6027 6315
6028 // Establish some checks around our packed fields 6316 // Establish some checks around our packed fields
6029 enum LoadKeyedBits { 6317 enum LoadKeyedBits {
6030 kBitsForElementsKind = 5, 6318 kBitsForElementsKind = 5,
6031 kBitsForHoleMode = 1, 6319 kBitsForHoleMode = 1,
6032 kBitsForIndexOffset = 25, 6320 kBitsForIndexOffset = 25,
6033 kBitsForIsDehoisted = 1, 6321 kBitsForIsDehoisted = 1,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
6079 } 6367 }
6080 6368
6081 virtual HValue* Canonicalize(); 6369 virtual HValue* Canonicalize();
6082 6370
6083 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) 6371 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
6084 }; 6372 };
6085 6373
6086 6374
6087 class HStoreNamedField: public HTemplateInstruction<2> { 6375 class HStoreNamedField: public HTemplateInstruction<2> {
6088 public: 6376 public:
6089 HStoreNamedField(HValue* obj, 6377 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
6090 HObjectAccess access, 6378 HObjectAccess, HValue*);
6091 HValue* val)
6092 : access_(access),
6093 transition_(),
6094 transition_unique_id_(),
6095 new_space_dominator_(NULL),
6096 write_barrier_mode_(UPDATE_WRITE_BARRIER) {
6097 SetOperandAt(0, obj);
6098 SetOperandAt(1, val);
6099 access.SetGVNFlags(this, true);
6100 }
6101 6379
6102 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 6380 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
6103 6381
6104 virtual bool HasEscapingOperandAt(int index) { return index == 1; } 6382 virtual bool HasEscapingOperandAt(int index) { return index == 1; }
6105 virtual Representation RequiredInputRepresentation(int index) { 6383 virtual Representation RequiredInputRepresentation(int index) {
6106 if (index == 1 && field_representation().IsDouble()) { 6384 if (index == 0 && access().IsExternalMemory()) {
6107 return field_representation(); 6385 // object must be external in case of external memory access
6108 } else if (index == 1 && field_representation().IsSmi()) { 6386 return Representation::External();
6387 } else if (index == 1 &&
6388 (field_representation().IsDouble() ||
6389 field_representation().IsSmi() ||
6390 field_representation().IsInteger32())) {
6109 return field_representation(); 6391 return field_representation();
6110 } 6392 }
6111 return Representation::Tagged(); 6393 return Representation::Tagged();
6112 } 6394 }
6113 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6395 virtual void HandleSideEffectDominator(GVNFlag side_effect,
6114 HValue* dominator) { 6396 HValue* dominator) {
6115 ASSERT(side_effect == kChangesNewSpacePromotion); 6397 ASSERT(side_effect == kChangesNewSpacePromotion);
6116 new_space_dominator_ = dominator; 6398 new_space_dominator_ = dominator;
6117 } 6399 }
6118 virtual void PrintDataTo(StringStream* stream); 6400 virtual void PrintDataTo(StringStream* stream);
(...skipping 17 matching lines...) Expand all
6136 transition_ = map; 6418 transition_ = map;
6137 } 6419 }
6138 HValue* new_space_dominator() const { return new_space_dominator_; } 6420 HValue* new_space_dominator() const { return new_space_dominator_; }
6139 6421
6140 bool NeedsWriteBarrier() { 6422 bool NeedsWriteBarrier() {
6141 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || 6423 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
6142 transition_.is_null()); 6424 transition_.is_null());
6143 if (IsSkipWriteBarrier()) return false; 6425 if (IsSkipWriteBarrier()) return false;
6144 if (field_representation().IsDouble()) return false; 6426 if (field_representation().IsDouble()) return false;
6145 if (field_representation().IsSmi()) return false; 6427 if (field_representation().IsSmi()) return false;
6428 if (field_representation().IsInteger32()) return false;
6429 if (field_representation().IsExternal()) return false;
6146 return StoringValueNeedsWriteBarrier(value()) && 6430 return StoringValueNeedsWriteBarrier(value()) &&
6147 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6431 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
6148 } 6432 }
6149 6433
6150 bool NeedsWriteBarrierForMap() { 6434 bool NeedsWriteBarrierForMap() {
6151 if (IsSkipWriteBarrier()) return false; 6435 if (IsSkipWriteBarrier()) return false;
6152 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6436 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
6153 } 6437 }
6154 6438
6155 virtual void FinalizeUniqueValueId() { 6439 virtual void FinalizeUniqueValueId() {
6156 transition_unique_id_ = UniqueValueId(transition_); 6440 transition_unique_id_ = UniqueValueId(transition_);
6157 } 6441 }
6158 6442
6159 Representation field_representation() const { 6443 Representation field_representation() const {
6160 return access_.representation(); 6444 return access_.representation();
6161 } 6445 }
6162 6446
6163 private: 6447 private:
6448 HStoreNamedField(HValue* obj,
6449 HObjectAccess access,
6450 HValue* val)
6451 : access_(access),
6452 transition_(),
6453 transition_unique_id_(),
6454 new_space_dominator_(NULL),
6455 write_barrier_mode_(UPDATE_WRITE_BARRIER) {
6456 SetOperandAt(0, obj);
6457 SetOperandAt(1, val);
6458 access.SetGVNFlags(this, true);
6459 }
6460
6164 HObjectAccess access_; 6461 HObjectAccess access_;
6165 Handle<Map> transition_; 6462 Handle<Map> transition_;
6166 UniqueValueId transition_unique_id_; 6463 UniqueValueId transition_unique_id_;
6167 HValue* new_space_dominator_; 6464 HValue* new_space_dominator_;
6168 WriteBarrierMode write_barrier_mode_; 6465 WriteBarrierMode write_barrier_mode_;
6169 }; 6466 };
6170 6467
6171 6468
6172 class HStoreNamedGeneric: public HTemplateInstruction<3> { 6469 class HStoreNamedGeneric: public HTemplateInstruction<3> {
6173 public: 6470 public:
(...skipping 26 matching lines...) Expand all
6200 6497
6201 private: 6498 private:
6202 Handle<String> name_; 6499 Handle<String> name_;
6203 StrictModeFlag strict_mode_flag_; 6500 StrictModeFlag strict_mode_flag_;
6204 }; 6501 };
6205 6502
6206 6503
6207 class HStoreKeyed 6504 class HStoreKeyed
6208 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 6505 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
6209 public: 6506 public:
6210 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 6507 DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
6211 ElementsKind elements_kind) 6508 ElementsKind);
6212 : elements_kind_(elements_kind),
6213 index_offset_(0),
6214 is_dehoisted_(false),
6215 is_uninitialized_(false),
6216 new_space_dominator_(NULL) {
6217 SetOperandAt(0, obj);
6218 SetOperandAt(1, key);
6219 SetOperandAt(2, val);
6220
6221 if (IsFastObjectElementsKind(elements_kind)) {
6222 SetFlag(kTrackSideEffectDominators);
6223 SetGVNFlag(kDependsOnNewSpacePromotion);
6224 }
6225 if (is_external()) {
6226 SetGVNFlag(kChangesSpecializedArrayElements);
6227 SetFlag(kAllowUndefinedAsNaN);
6228 } else if (IsFastDoubleElementsKind(elements_kind)) {
6229 SetGVNFlag(kChangesDoubleArrayElements);
6230 } else if (IsFastSmiElementsKind(elements_kind)) {
6231 SetGVNFlag(kChangesArrayElements);
6232 } else {
6233 SetGVNFlag(kChangesArrayElements);
6234 }
6235
6236 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
6237 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
6238 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
6239 SetFlag(kTruncatingToInt32);
6240 }
6241 }
6242 6509
6243 virtual bool HasEscapingOperandAt(int index) { return index != 0; } 6510 virtual bool HasEscapingOperandAt(int index) { return index != 0; }
6244 virtual Representation RequiredInputRepresentation(int index) { 6511 virtual Representation RequiredInputRepresentation(int index) {
6245 // kind_fast: tagged[int32] = tagged 6512 // kind_fast: tagged[int32] = tagged
6246 // kind_double: tagged[int32] = double 6513 // kind_double: tagged[int32] = double
6247 // kind_smi : tagged[int32] = smi 6514 // kind_smi : tagged[int32] = smi
6248 // kind_external: external[int32] = (double | int32) 6515 // kind_external: external[int32] = (double | int32)
6249 if (index == 0) { 6516 if (index == 0) {
6250 return is_external() ? Representation::External() 6517 return is_external() ? Representation::External()
6251 : Representation::Tagged(); 6518 : Representation::Tagged();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
6328 } 6595 }
6329 } 6596 }
6330 6597
6331 bool NeedsCanonicalization(); 6598 bool NeedsCanonicalization();
6332 6599
6333 virtual void PrintDataTo(StringStream* stream); 6600 virtual void PrintDataTo(StringStream* stream);
6334 6601
6335 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) 6602 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
6336 6603
6337 private: 6604 private:
6605 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
6606 ElementsKind elements_kind)
6607 : elements_kind_(elements_kind),
6608 index_offset_(0),
6609 is_dehoisted_(false),
6610 is_uninitialized_(false),
6611 new_space_dominator_(NULL) {
6612 SetOperandAt(0, obj);
6613 SetOperandAt(1, key);
6614 SetOperandAt(2, val);
6615
6616 if (IsFastObjectElementsKind(elements_kind)) {
6617 SetFlag(kTrackSideEffectDominators);
6618 SetGVNFlag(kDependsOnNewSpacePromotion);
6619 }
6620 if (is_external()) {
6621 SetGVNFlag(kChangesExternalMemory);
6622 SetFlag(kAllowUndefinedAsNaN);
6623 } else if (IsFastDoubleElementsKind(elements_kind)) {
6624 SetGVNFlag(kChangesDoubleArrayElements);
6625 } else if (IsFastSmiElementsKind(elements_kind)) {
6626 SetGVNFlag(kChangesArrayElements);
6627 } else {
6628 SetGVNFlag(kChangesArrayElements);
6629 }
6630
6631 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
6632 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
6633 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
6634 SetFlag(kTruncatingToInt32);
6635 }
6636 }
6637
6338 ElementsKind elements_kind_; 6638 ElementsKind elements_kind_;
6339 uint32_t index_offset_; 6639 uint32_t index_offset_;
6340 bool is_dehoisted_ : 1; 6640 bool is_dehoisted_ : 1;
6341 bool is_uninitialized_ : 1; 6641 bool is_uninitialized_ : 1;
6342 HValue* new_space_dominator_; 6642 HValue* new_space_dominator_;
6343 }; 6643 };
6344 6644
6345 6645
6346 class HStoreKeyedGeneric: public HTemplateInstruction<4> { 6646 class HStoreKeyedGeneric: public HTemplateInstruction<4> {
6347 public: 6647 public:
(...skipping 25 matching lines...) Expand all
6373 6673
6374 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) 6674 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
6375 6675
6376 private: 6676 private:
6377 StrictModeFlag strict_mode_flag_; 6677 StrictModeFlag strict_mode_flag_;
6378 }; 6678 };
6379 6679
6380 6680
6381 class HTransitionElementsKind: public HTemplateInstruction<2> { 6681 class HTransitionElementsKind: public HTemplateInstruction<2> {
6382 public: 6682 public:
6383 HTransitionElementsKind(HValue* context, 6683 inline static HTransitionElementsKind* New(Zone* zone,
6384 HValue* object, 6684 HValue* context,
6385 Handle<Map> original_map, 6685 HValue* object,
6386 Handle<Map> transitioned_map) 6686 Handle<Map> original_map,
6387 : original_map_(original_map), 6687 Handle<Map> transitioned_map) {
6388 transitioned_map_(transitioned_map), 6688 return new(zone) HTransitionElementsKind(context, object,
6389 original_map_unique_id_(), 6689 original_map, transitioned_map);
6390 transitioned_map_unique_id_(),
6391 from_kind_(original_map->elements_kind()),
6392 to_kind_(transitioned_map->elements_kind()) {
6393 SetOperandAt(0, object);
6394 SetOperandAt(1, context);
6395 SetFlag(kUseGVN);
6396 SetGVNFlag(kChangesElementsKind);
6397 if (original_map->has_fast_double_elements()) {
6398 SetGVNFlag(kChangesElementsPointer);
6399 SetGVNFlag(kChangesNewSpacePromotion);
6400 }
6401 if (transitioned_map->has_fast_double_elements()) {
6402 SetGVNFlag(kChangesElementsPointer);
6403 SetGVNFlag(kChangesNewSpacePromotion);
6404 }
6405 set_representation(Representation::Tagged());
6406 } 6690 }
6407 6691
6408 virtual Representation RequiredInputRepresentation(int index) { 6692 virtual Representation RequiredInputRepresentation(int index) {
6409 return Representation::Tagged(); 6693 return Representation::Tagged();
6410 } 6694 }
6411 6695
6412 HValue* object() { return OperandAt(0); } 6696 HValue* object() { return OperandAt(0); }
6413 HValue* context() { return OperandAt(1); } 6697 HValue* context() { return OperandAt(1); }
6414 Handle<Map> original_map() { return original_map_; } 6698 Handle<Map> original_map() { return original_map_; }
6415 Handle<Map> transitioned_map() { return transitioned_map_; } 6699 Handle<Map> transitioned_map() { return transitioned_map_; }
(...skipping 10 matching lines...) Expand all
6426 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) 6710 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
6427 6711
6428 protected: 6712 protected:
6429 virtual bool DataEquals(HValue* other) { 6713 virtual bool DataEquals(HValue* other) {
6430 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); 6714 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
6431 return original_map_unique_id_ == instr->original_map_unique_id_ && 6715 return original_map_unique_id_ == instr->original_map_unique_id_ &&
6432 transitioned_map_unique_id_ == instr->transitioned_map_unique_id_; 6716 transitioned_map_unique_id_ == instr->transitioned_map_unique_id_;
6433 } 6717 }
6434 6718
6435 private: 6719 private:
6720 HTransitionElementsKind(HValue* context,
6721 HValue* object,
6722 Handle<Map> original_map,
6723 Handle<Map> transitioned_map)
6724 : original_map_(original_map),
6725 transitioned_map_(transitioned_map),
6726 original_map_unique_id_(),
6727 transitioned_map_unique_id_(),
6728 from_kind_(original_map->elements_kind()),
6729 to_kind_(transitioned_map->elements_kind()) {
6730 SetOperandAt(0, object);
6731 SetOperandAt(1, context);
6732 SetFlag(kUseGVN);
6733 SetGVNFlag(kChangesElementsKind);
6734 if (original_map->has_fast_double_elements()) {
6735 SetGVNFlag(kChangesElementsPointer);
6736 SetGVNFlag(kChangesNewSpacePromotion);
6737 }
6738 if (transitioned_map->has_fast_double_elements()) {
6739 SetGVNFlag(kChangesElementsPointer);
6740 SetGVNFlag(kChangesNewSpacePromotion);
6741 }
6742 set_representation(Representation::Tagged());
6743 }
6744
6436 Handle<Map> original_map_; 6745 Handle<Map> original_map_;
6437 Handle<Map> transitioned_map_; 6746 Handle<Map> transitioned_map_;
6438 UniqueValueId original_map_unique_id_; 6747 UniqueValueId original_map_unique_id_;
6439 UniqueValueId transitioned_map_unique_id_; 6748 UniqueValueId transitioned_map_unique_id_;
6440 ElementsKind from_kind_; 6749 ElementsKind from_kind_;
6441 ElementsKind to_kind_; 6750 ElementsKind to_kind_;
6442 }; 6751 };
6443 6752
6444 6753
6445 class HStringAdd: public HBinaryOperation { 6754 class HStringAdd: public HBinaryOperation {
6446 public: 6755 public:
6447 static HInstruction* New(Zone* zone, 6756 static HInstruction* New(Zone* zone,
6448 HValue* context, 6757 HValue* context,
6449 HValue* left, 6758 HValue* left,
6450 HValue* right, 6759 HValue* right,
6451 StringAddFlags flags = STRING_ADD_CHECK_NONE); 6760 StringAddFlags flags = STRING_ADD_CHECK_NONE);
6452 6761
6453 StringAddFlags flags() const { return flags_; } 6762 StringAddFlags flags() const { return flags_; }
6454 6763
6455 virtual Representation RequiredInputRepresentation(int index) { 6764 virtual Representation RequiredInputRepresentation(int index) {
6456 return Representation::Tagged(); 6765 return Representation::Tagged();
6457 } 6766 }
6458 6767
6459 virtual HType CalculateInferredType() {
6460 return HType::String();
6461 }
6462
6463 DECLARE_CONCRETE_INSTRUCTION(StringAdd) 6768 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
6464 6769
6465 protected: 6770 protected:
6466 virtual bool DataEquals(HValue* other) { return true; } 6771 virtual bool DataEquals(HValue* other) { return true; }
6467 6772
6468 private: 6773 private:
6469 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) 6774 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags)
6470 : HBinaryOperation(context, left, right), flags_(flags) { 6775 : HBinaryOperation(context, left, right, HType::String()), flags_(flags) {
6471 set_representation(Representation::Tagged()); 6776 set_representation(Representation::Tagged());
6472 SetFlag(kUseGVN); 6777 SetFlag(kUseGVN);
6473 SetGVNFlag(kDependsOnMaps); 6778 SetGVNFlag(kDependsOnMaps);
6474 SetGVNFlag(kChangesNewSpacePromotion); 6779 SetGVNFlag(kChangesNewSpacePromotion);
6475 } 6780 }
6476 6781
6477 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. 6782 // No side-effects except possible allocation.
6478 // virtual bool IsDeletable() const { return true; } 6783 // NOTE: this instruction _does not_ call ToString() on its inputs.
6784 virtual bool IsDeletable() const { return true; }
6479 6785
6480 const StringAddFlags flags_; 6786 const StringAddFlags flags_;
6481 }; 6787 };
6482 6788
6483 6789
6484 class HStringCharCodeAt: public HTemplateInstruction<3> { 6790 class HStringCharCodeAt: public HTemplateInstruction<3> {
6485 public: 6791 public:
6486 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { 6792 static HStringCharCodeAt* New(Zone* zone,
6487 SetOperandAt(0, context); 6793 HValue* context,
6488 SetOperandAt(1, string); 6794 HValue* string,
6489 SetOperandAt(2, index); 6795 HValue* index) {
6490 set_representation(Representation::Integer32()); 6796 return new(zone) HStringCharCodeAt(context, string, index);
6491 SetFlag(kUseGVN);
6492 SetGVNFlag(kDependsOnMaps);
6493 SetGVNFlag(kChangesNewSpacePromotion);
6494 } 6797 }
6495 6798
6496 virtual Representation RequiredInputRepresentation(int index) { 6799 virtual Representation RequiredInputRepresentation(int index) {
6497 // The index is supposed to be Integer32. 6800 // The index is supposed to be Integer32.
6498 return index == 2 6801 return index == 2
6499 ? Representation::Integer32() 6802 ? Representation::Integer32()
6500 : Representation::Tagged(); 6803 : Representation::Tagged();
6501 } 6804 }
6502 6805
6503 HValue* context() { return OperandAt(0); } 6806 HValue* context() const { return OperandAt(0); }
6504 HValue* string() { return OperandAt(1); } 6807 HValue* string() const { return OperandAt(1); }
6505 HValue* index() { return OperandAt(2); } 6808 HValue* index() const { return OperandAt(2); }
6506 6809
6507 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) 6810 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
6508 6811
6509 protected: 6812 protected:
6510 virtual bool DataEquals(HValue* other) { return true; } 6813 virtual bool DataEquals(HValue* other) { return true; }
6511 6814
6512 virtual Range* InferRange(Zone* zone) { 6815 virtual Range* InferRange(Zone* zone) {
6513 return new(zone) Range(0, String::kMaxUtf16CodeUnit); 6816 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
6514 } 6817 }
6515 6818
6516 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. 6819 private:
6517 // private: 6820 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
6518 // virtual bool IsDeletable() const { return true; } 6821 SetOperandAt(0, context);
6822 SetOperandAt(1, string);
6823 SetOperandAt(2, index);
6824 set_representation(Representation::Integer32());
6825 SetFlag(kUseGVN);
6826 SetGVNFlag(kDependsOnMaps);
6827 SetGVNFlag(kChangesNewSpacePromotion);
6828 }
6829
6830 // No side effects: runtime function assumes string + number inputs.
6831 virtual bool IsDeletable() const { return true; }
6519 }; 6832 };
6520 6833
6521 6834
6522 class HStringCharFromCode: public HTemplateInstruction<2> { 6835 class HStringCharFromCode: public HTemplateInstruction<2> {
6523 public: 6836 public:
6524 static HInstruction* New(Zone* zone, 6837 static HInstruction* New(Zone* zone,
6525 HValue* context, 6838 HValue* context,
6526 HValue* char_code); 6839 HValue* char_code);
6527 6840
6528 virtual Representation RequiredInputRepresentation(int index) { 6841 virtual Representation RequiredInputRepresentation(int index) {
6529 return index == 0 6842 return index == 0
6530 ? Representation::Tagged() 6843 ? Representation::Tagged()
6531 : Representation::Integer32(); 6844 : Representation::Integer32();
6532 } 6845 }
6533 virtual HType CalculateInferredType();
6534 6846
6535 HValue* context() { return OperandAt(0); } 6847 HValue* context() const { return OperandAt(0); }
6536 HValue* value() { return OperandAt(1); } 6848 HValue* value() const { return OperandAt(1); }
6537 6849
6538 virtual bool DataEquals(HValue* other) { return true; } 6850 virtual bool DataEquals(HValue* other) { return true; }
6539 6851
6540 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) 6852 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
6541 6853
6542 private: 6854 private:
6543 HStringCharFromCode(HValue* context, HValue* char_code) { 6855 HStringCharFromCode(HValue* context, HValue* char_code)
6856 : HTemplateInstruction<2>(HType::String()) {
6544 SetOperandAt(0, context); 6857 SetOperandAt(0, context);
6545 SetOperandAt(1, char_code); 6858 SetOperandAt(1, char_code);
6546 set_representation(Representation::Tagged()); 6859 set_representation(Representation::Tagged());
6547 SetFlag(kUseGVN); 6860 SetFlag(kUseGVN);
6548 SetGVNFlag(kChangesNewSpacePromotion); 6861 SetGVNFlag(kChangesNewSpacePromotion);
6549 } 6862 }
6550 6863
6551 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. 6864 virtual bool IsDeletable() const {
6552 // virtual bool IsDeletable() const { return true; } 6865 return !value()->ToNumberCanBeObserved();
6866 }
6553 }; 6867 };
6554 6868
6555 6869
6556 class HStringLength: public HUnaryOperation {
6557 public:
6558 static HInstruction* New(Zone* zone, HValue* string);
6559
6560 virtual Representation RequiredInputRepresentation(int index) {
6561 return Representation::Tagged();
6562 }
6563
6564 virtual HType CalculateInferredType() {
6565 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
6566 return HType::Smi();
6567 }
6568
6569 DECLARE_CONCRETE_INSTRUCTION(StringLength)
6570
6571 protected:
6572 virtual bool DataEquals(HValue* other) { return true; }
6573
6574 virtual Range* InferRange(Zone* zone) {
6575 return new(zone) Range(0, String::kMaxLength);
6576 }
6577
6578 private:
6579 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
6580 set_representation(Representation::Tagged());
6581 SetFlag(kUseGVN);
6582 SetGVNFlag(kDependsOnMaps);
6583 }
6584
6585 virtual bool IsDeletable() const { return true; }
6586 };
6587
6588
6589 template <int V> 6870 template <int V>
6590 class HMaterializedLiteral: public HTemplateInstruction<V> { 6871 class HMaterializedLiteral: public HTemplateInstruction<V> {
6591 public: 6872 public:
6592 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) 6873 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode)
6593 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { 6874 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) {
6594 this->set_representation(Representation::Tagged()); 6875 this->set_representation(Representation::Tagged());
6595 } 6876 }
6596 6877
6597 HMaterializedLiteral<V>(int index, int depth) 6878 HMaterializedLiteral<V>(int index, int depth)
6598 : literal_index_(index), depth_(depth), 6879 : literal_index_(index), depth_(depth),
(...skipping 22 matching lines...) Expand all
6621 Handle<FixedArray> literals, 6902 Handle<FixedArray> literals,
6622 Handle<String> pattern, 6903 Handle<String> pattern,
6623 Handle<String> flags, 6904 Handle<String> flags,
6624 int literal_index) 6905 int literal_index)
6625 : HMaterializedLiteral<1>(literal_index, 0), 6906 : HMaterializedLiteral<1>(literal_index, 0),
6626 literals_(literals), 6907 literals_(literals),
6627 pattern_(pattern), 6908 pattern_(pattern),
6628 flags_(flags) { 6909 flags_(flags) {
6629 SetOperandAt(0, context); 6910 SetOperandAt(0, context);
6630 SetAllSideEffects(); 6911 SetAllSideEffects();
6912 set_type(HType::JSObject());
6631 } 6913 }
6632 6914
6633 HValue* context() { return OperandAt(0); } 6915 HValue* context() { return OperandAt(0); }
6634 Handle<FixedArray> literals() { return literals_; } 6916 Handle<FixedArray> literals() { return literals_; }
6635 Handle<String> pattern() { return pattern_; } 6917 Handle<String> pattern() { return pattern_; }
6636 Handle<String> flags() { return flags_; } 6918 Handle<String> flags() { return flags_; }
6637 6919
6638 virtual Representation RequiredInputRepresentation(int index) { 6920 virtual Representation RequiredInputRepresentation(int index) {
6639 return Representation::Tagged(); 6921 return Representation::Tagged();
6640 } 6922 }
6641 virtual HType CalculateInferredType();
6642 6923
6643 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) 6924 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
6644 6925
6645 private: 6926 private:
6646 Handle<FixedArray> literals_; 6927 Handle<FixedArray> literals_;
6647 Handle<String> pattern_; 6928 Handle<String> pattern_;
6648 Handle<String> flags_; 6929 Handle<String> flags_;
6649 }; 6930 };
6650 6931
6651 6932
6652 class HFunctionLiteral: public HTemplateInstruction<1> { 6933 class HFunctionLiteral: public HTemplateInstruction<1> {
6653 public: 6934 public:
6654 HFunctionLiteral(HValue* context, 6935 HFunctionLiteral(HValue* context,
6655 Handle<SharedFunctionInfo> shared, 6936 Handle<SharedFunctionInfo> shared,
6656 bool pretenure) 6937 bool pretenure)
6657 : shared_info_(shared), 6938 : HTemplateInstruction<1>(HType::JSObject()),
6939 shared_info_(shared),
6658 pretenure_(pretenure), 6940 pretenure_(pretenure),
6659 has_no_literals_(shared->num_literals() == 0), 6941 has_no_literals_(shared->num_literals() == 0),
6660 is_generator_(shared->is_generator()), 6942 is_generator_(shared->is_generator()),
6661 language_mode_(shared->language_mode()) { 6943 language_mode_(shared->language_mode()) {
6662 SetOperandAt(0, context); 6944 SetOperandAt(0, context);
6663 set_representation(Representation::Tagged()); 6945 set_representation(Representation::Tagged());
6664 SetGVNFlag(kChangesNewSpacePromotion); 6946 SetGVNFlag(kChangesNewSpacePromotion);
6665 } 6947 }
6666 6948
6667 HValue* context() { return OperandAt(0); } 6949 HValue* context() { return OperandAt(0); }
6668 6950
6669 virtual Representation RequiredInputRepresentation(int index) { 6951 virtual Representation RequiredInputRepresentation(int index) {
6670 return Representation::Tagged(); 6952 return Representation::Tagged();
6671 } 6953 }
6672 virtual HType CalculateInferredType();
6673 6954
6674 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral) 6955 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
6675 6956
6676 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } 6957 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
6677 bool pretenure() const { return pretenure_; } 6958 bool pretenure() const { return pretenure_; }
6678 bool has_no_literals() const { return has_no_literals_; } 6959 bool has_no_literals() const { return has_no_literals_; }
6679 bool is_generator() const { return is_generator_; } 6960 bool is_generator() const { return is_generator_; }
6680 LanguageMode language_mode() const { return language_mode_; } 6961 LanguageMode language_mode() const { return language_mode_; }
6681 6962
6682 private: 6963 private:
(...skipping 26 matching lines...) Expand all
6709 6990
6710 DECLARE_CONCRETE_INSTRUCTION(Typeof) 6991 DECLARE_CONCRETE_INSTRUCTION(Typeof)
6711 6992
6712 private: 6993 private:
6713 virtual bool IsDeletable() const { return true; } 6994 virtual bool IsDeletable() const { return true; }
6714 }; 6995 };
6715 6996
6716 6997
6717 class HTrapAllocationMemento : public HTemplateInstruction<1> { 6998 class HTrapAllocationMemento : public HTemplateInstruction<1> {
6718 public: 6999 public:
6719 explicit HTrapAllocationMemento(HValue* obj) { 7000 DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*);
6720 SetOperandAt(0, obj);
6721 }
6722 7001
6723 virtual Representation RequiredInputRepresentation(int index) { 7002 virtual Representation RequiredInputRepresentation(int index) {
6724 return Representation::Tagged(); 7003 return Representation::Tagged();
6725 } 7004 }
6726 7005
6727 HValue* object() { return OperandAt(0); } 7006 HValue* object() { return OperandAt(0); }
6728 7007
6729 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) 7008 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
7009
7010 private:
7011 explicit HTrapAllocationMemento(HValue* obj) {
7012 SetOperandAt(0, obj);
7013 }
6730 }; 7014 };
6731 7015
6732 7016
6733 class HToFastProperties: public HUnaryOperation { 7017 class HToFastProperties: public HUnaryOperation {
6734 public: 7018 public:
7019 DECLARE_INSTRUCTION_FACTORY_P1(HToFastProperties, HValue*);
7020
7021 virtual Representation RequiredInputRepresentation(int index) {
7022 return Representation::Tagged();
7023 }
7024
7025 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
7026
7027 private:
6735 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { 7028 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
6736 // This instruction is not marked as having side effects, but 7029 // This instruction is not marked as having side effects, but
6737 // changes the map of the input operand. Use it only when creating 7030 // changes the map of the input operand. Use it only when creating
6738 // object literals via a runtime call. 7031 // object literals via a runtime call.
6739 ASSERT(value->IsCallRuntime()); 7032 ASSERT(value->IsCallRuntime());
6740 #ifdef DEBUG 7033 #ifdef DEBUG
6741 const Runtime::Function* function = HCallRuntime::cast(value)->function(); 7034 const Runtime::Function* function = HCallRuntime::cast(value)->function();
6742 ASSERT(function->function_id == Runtime::kCreateObjectLiteral || 7035 ASSERT(function->function_id == Runtime::kCreateObjectLiteral ||
6743 function->function_id == Runtime::kCreateObjectLiteralShallow); 7036 function->function_id == Runtime::kCreateObjectLiteralShallow);
6744 #endif 7037 #endif
6745 set_representation(Representation::Tagged()); 7038 set_representation(Representation::Tagged());
6746 } 7039 }
6747 7040
6748 virtual Representation RequiredInputRepresentation(int index) {
6749 return Representation::Tagged();
6750 }
6751
6752 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
6753
6754 private:
6755 virtual bool IsDeletable() const { return true; } 7041 virtual bool IsDeletable() const { return true; }
6756 }; 7042 };
6757 7043
6758 7044
6759 class HValueOf: public HUnaryOperation { 7045 class HValueOf: public HUnaryOperation {
6760 public: 7046 public:
6761 explicit HValueOf(HValue* value) : HUnaryOperation(value) { 7047 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
6762 set_representation(Representation::Tagged()); 7048 set_representation(Representation::Tagged());
6763 } 7049 }
6764 7050
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
6817 7103
6818 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar) 7104 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar)
6819 7105
6820 private: 7106 private:
6821 String::Encoding encoding_; 7107 String::Encoding encoding_;
6822 }; 7108 };
6823 7109
6824 7110
6825 class HCheckMapValue: public HTemplateInstruction<2> { 7111 class HCheckMapValue: public HTemplateInstruction<2> {
6826 public: 7112 public:
6827 HCheckMapValue(HValue* value, 7113 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
6828 HValue* map) {
6829 SetOperandAt(0, value);
6830 SetOperandAt(1, map);
6831 set_representation(Representation::Tagged());
6832 SetFlag(kUseGVN);
6833 SetGVNFlag(kDependsOnMaps);
6834 SetGVNFlag(kDependsOnElementsKind);
6835 }
6836 7114
6837 virtual Representation RequiredInputRepresentation(int index) { 7115 virtual Representation RequiredInputRepresentation(int index) {
6838 return Representation::Tagged(); 7116 return Representation::Tagged();
6839 } 7117 }
6840 7118
6841 virtual void PrintDataTo(StringStream* stream); 7119 virtual void PrintDataTo(StringStream* stream);
6842 7120
6843 virtual HType CalculateInferredType() { 7121 virtual HType CalculateInferredType() {
6844 return HType::Tagged(); 7122 return HType::Tagged();
6845 } 7123 }
6846 7124
6847 HValue* value() { return OperandAt(0); } 7125 HValue* value() { return OperandAt(0); }
6848 HValue* map() { return OperandAt(1); } 7126 HValue* map() { return OperandAt(1); }
6849 7127
6850 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue) 7128 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
6851 7129
6852 protected: 7130 protected:
6853 virtual bool DataEquals(HValue* other) { 7131 virtual bool DataEquals(HValue* other) {
6854 return true; 7132 return true;
6855 } 7133 }
7134
7135 private:
7136 HCheckMapValue(HValue* value,
7137 HValue* map) {
7138 SetOperandAt(0, value);
7139 SetOperandAt(1, map);
7140 set_representation(Representation::Tagged());
7141 SetFlag(kUseGVN);
7142 SetGVNFlag(kDependsOnMaps);
7143 SetGVNFlag(kDependsOnElementsKind);
7144 }
6856 }; 7145 };
6857 7146
6858 7147
6859 class HForInPrepareMap : public HTemplateInstruction<2> { 7148 class HForInPrepareMap : public HTemplateInstruction<2> {
6860 public: 7149 public:
6861 HForInPrepareMap(HValue* context, 7150 static HForInPrepareMap* New(Zone* zone,
6862 HValue* object) { 7151 HValue* context,
6863 SetOperandAt(0, context); 7152 HValue* object) {
6864 SetOperandAt(1, object); 7153 return new(zone) HForInPrepareMap(context, object);
6865 set_representation(Representation::Tagged());
6866 SetAllSideEffects();
6867 } 7154 }
6868 7155
6869 virtual Representation RequiredInputRepresentation(int index) { 7156 virtual Representation RequiredInputRepresentation(int index) {
6870 return Representation::Tagged(); 7157 return Representation::Tagged();
6871 } 7158 }
6872 7159
6873 HValue* context() { return OperandAt(0); } 7160 HValue* context() { return OperandAt(0); }
6874 HValue* enumerable() { return OperandAt(1); } 7161 HValue* enumerable() { return OperandAt(1); }
6875 7162
6876 virtual void PrintDataTo(StringStream* stream); 7163 virtual void PrintDataTo(StringStream* stream);
6877 7164
6878 virtual HType CalculateInferredType() { 7165 virtual HType CalculateInferredType() {
6879 return HType::Tagged(); 7166 return HType::Tagged();
6880 } 7167 }
6881 7168
6882 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap); 7169 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
7170
7171 private:
7172 HForInPrepareMap(HValue* context,
7173 HValue* object) {
7174 SetOperandAt(0, context);
7175 SetOperandAt(1, object);
7176 set_representation(Representation::Tagged());
7177 SetAllSideEffects();
7178 }
6883 }; 7179 };
6884 7180
6885 7181
6886 class HForInCacheArray : public HTemplateInstruction<2> { 7182 class HForInCacheArray : public HTemplateInstruction<2> {
6887 public: 7183 public:
6888 HForInCacheArray(HValue* enumerable, 7184 DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int);
6889 HValue* keys,
6890 int idx) : idx_(idx) {
6891 SetOperandAt(0, enumerable);
6892 SetOperandAt(1, keys);
6893 set_representation(Representation::Tagged());
6894 }
6895 7185
6896 virtual Representation RequiredInputRepresentation(int index) { 7186 virtual Representation RequiredInputRepresentation(int index) {
6897 return Representation::Tagged(); 7187 return Representation::Tagged();
6898 } 7188 }
6899 7189
6900 HValue* enumerable() { return OperandAt(0); } 7190 HValue* enumerable() { return OperandAt(0); }
6901 HValue* map() { return OperandAt(1); } 7191 HValue* map() { return OperandAt(1); }
6902 int idx() { return idx_; } 7192 int idx() { return idx_; }
6903 7193
6904 HForInCacheArray* index_cache() { 7194 HForInCacheArray* index_cache() {
6905 return index_cache_; 7195 return index_cache_;
6906 } 7196 }
6907 7197
6908 void set_index_cache(HForInCacheArray* index_cache) { 7198 void set_index_cache(HForInCacheArray* index_cache) {
6909 index_cache_ = index_cache; 7199 index_cache_ = index_cache;
6910 } 7200 }
6911 7201
6912 virtual void PrintDataTo(StringStream* stream); 7202 virtual void PrintDataTo(StringStream* stream);
6913 7203
6914 virtual HType CalculateInferredType() { 7204 virtual HType CalculateInferredType() {
6915 return HType::Tagged(); 7205 return HType::Tagged();
6916 } 7206 }
6917 7207
6918 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray); 7208 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
6919 7209
6920 private: 7210 private:
7211 HForInCacheArray(HValue* enumerable,
7212 HValue* keys,
7213 int idx) : idx_(idx) {
7214 SetOperandAt(0, enumerable);
7215 SetOperandAt(1, keys);
7216 set_representation(Representation::Tagged());
7217 }
7218
6921 int idx_; 7219 int idx_;
6922 HForInCacheArray* index_cache_; 7220 HForInCacheArray* index_cache_;
6923 }; 7221 };
6924 7222
6925 7223
6926 class HLoadFieldByIndex : public HTemplateInstruction<2> { 7224 class HLoadFieldByIndex : public HTemplateInstruction<2> {
6927 public: 7225 public:
6928 HLoadFieldByIndex(HValue* object, 7226 HLoadFieldByIndex(HValue* object,
6929 HValue* index) { 7227 HValue* index) {
6930 SetOperandAt(0, object); 7228 SetOperandAt(0, object);
(...skipping 20 matching lines...) Expand all
6951 virtual bool IsDeletable() const { return true; } 7249 virtual bool IsDeletable() const { return true; }
6952 }; 7250 };
6953 7251
6954 7252
6955 #undef DECLARE_INSTRUCTION 7253 #undef DECLARE_INSTRUCTION
6956 #undef DECLARE_CONCRETE_INSTRUCTION 7254 #undef DECLARE_CONCRETE_INSTRUCTION
6957 7255
6958 } } // namespace v8::internal 7256 } } // namespace v8::internal
6959 7257
6960 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7258 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen-bch.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698