Revision f230a1cf deps/v8/src/hydrogen-instructions.h

View differences:

deps/v8/src/hydrogen-instructions.h
36 36
#include "deoptimizer.h"
37 37
#include "small-pointer-list.h"
38 38
#include "string-stream.h"
39
#include "unique.h"
39 40
#include "v8conversions.h"
40 41
#include "v8utils.h"
41 42
#include "zone.h"
......
63 64

  
64 65

  
65 66
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)  \
67
  V(AbnormalExit)                              \
66 68
  V(AccessArgumentsAt)                         \
67 69
  V(Add)                                       \
68 70
  V(Allocate)                                  \
......
124 126
  V(InnerAllocatedObject)                      \
125 127
  V(InstanceOf)                                \
126 128
  V(InstanceOfKnownGlobal)                     \
127
  V(InstanceSize)                              \
128 129
  V(InvokeFunction)                            \
129 130
  V(IsConstructCallAndBranch)                  \
130 131
  V(IsObjectAndBranch)                         \
131
  V(IsNumberAndBranch)                         \
132 132
  V(IsStringAndBranch)                         \
133 133
  V(IsSmiAndBranch)                            \
134 134
  V(IsUndetectableAndBranch)                   \
......
143 143
  V(LoadKeyedGeneric)                          \
144 144
  V(LoadNamedField)                            \
145 145
  V(LoadNamedGeneric)                          \
146
  V(LoadRoot)                                  \
146 147
  V(MapEnumLength)                             \
147 148
  V(MathFloorOfDiv)                            \
148 149
  V(MathMinMax)                                \
......
305 306
};
306 307

  
307 308

  
308
class UniqueValueId V8_FINAL {
309
 public:
310
  UniqueValueId() : raw_address_(NULL) { }
311

  
312
  explicit UniqueValueId(Handle<Object> handle) {
313
    ASSERT(!AllowHeapAllocation::IsAllowed());
314
    static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1);
315
    if (handle.is_null()) {
316
      raw_address_ = kEmptyHandleSentinel;
317
    } else {
318
      raw_address_ = reinterpret_cast<Address>(*handle);
319
      ASSERT_NE(kEmptyHandleSentinel, raw_address_);
320
    }
321
    ASSERT(IsInitialized());
322
  }
323

  
324
  bool IsInitialized() const { return raw_address_ != NULL; }
325

  
326
  bool operator==(const UniqueValueId& other) const {
327
    ASSERT(IsInitialized() && other.IsInitialized());
328
    return raw_address_ == other.raw_address_;
329
  }
330

  
331
  bool operator!=(const UniqueValueId& other) const {
332
    ASSERT(IsInitialized() && other.IsInitialized());
333
    return raw_address_ != other.raw_address_;
334
  }
335

  
336
  intptr_t Hashcode() const {
337
    ASSERT(IsInitialized());
338
    return reinterpret_cast<intptr_t>(raw_address_);
339
  }
340

  
341
#define IMMOVABLE_UNIQUE_VALUE_ID(name)   \
342
  static UniqueValueId name(Heap* heap) { return UniqueValueId(heap->name()); }
343

  
344
  IMMOVABLE_UNIQUE_VALUE_ID(free_space_map)
345
  IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value)
346
  IMMOVABLE_UNIQUE_VALUE_ID(nan_value)
347
  IMMOVABLE_UNIQUE_VALUE_ID(undefined_value)
348
  IMMOVABLE_UNIQUE_VALUE_ID(null_value)
349
  IMMOVABLE_UNIQUE_VALUE_ID(true_value)
350
  IMMOVABLE_UNIQUE_VALUE_ID(false_value)
351
  IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value)
352
  IMMOVABLE_UNIQUE_VALUE_ID(empty_string)
353

  
354
#undef IMMOVABLE_UNIQUE_VALUE_ID
355

  
356
 private:
357
  Address raw_address_;
358

  
359
  explicit UniqueValueId(Object* object) {
360
    raw_address_ = reinterpret_cast<Address>(object);
361
    ASSERT(IsInitialized());
362
  }
363
};
364

  
365

  
366 309
class HType V8_FINAL {
367 310
 public:
368 311
  static HType None() { return HType(kNone); }
......
695 638
        flags_(0) {}
696 639
  virtual ~HValue() {}
697 640

  
641
  virtual int position() const { return RelocInfo::kNoPosition; }
642

  
698 643
  HBasicBlock* block() const { return block_; }
699 644
  void SetBlock(HBasicBlock* block);
700 645
  int LoopWeight() const;
......
777 722
    return index == kNoRedefinedOperand ? NULL : OperandAt(index);
778 723
  }
779 724

  
725
  bool CanReplaceWithDummyUses();
726

  
727
  virtual int argument_delta() const { return 0; }
728

  
780 729
  // A purely informative definition is an idef that will not emit code and
781 730
  // should therefore be removed from the graph in the RestoreActualValues
782 731
  // phase (so that live ranges will be shorter).
783 732
  virtual bool IsPurelyInformativeDefinition() { return false; }
784 733

  
785
  // This method must always return the original HValue SSA definition
786
  // (regardless of any iDef of this value).
734
  // This method must always return the original HValue SSA definition,
735
  // regardless of any chain of iDefs of this value.
787 736
  HValue* ActualValue() {
788
    int index = RedefinedOperandIndex();
789
    return index == kNoRedefinedOperand ? this : OperandAt(index);
737
    HValue* value = this;
738
    int index;
739
    while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) {
740
      value = value->OperandAt(index);
741
    }
742
    return value;
790 743
  }
791 744

  
792 745
  bool IsInteger32Constant();
......
815 768
  void SetFlag(Flag f) { flags_ |= (1 << f); }
816 769
  void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
817 770
  bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
771
  void CopyFlag(Flag f, HValue* other) {
772
    if (other->CheckFlag(f)) SetFlag(f);
773
  }
818 774

  
819 775
  // Returns true if the flag specified is set for all uses, false otherwise.
820 776
  bool CheckUsesForFlag(Flag f) const;
......
898 854
  virtual intptr_t Hashcode();
899 855

  
900 856
  // Compute unique ids upfront that is safe wrt GC and concurrent compilation.
901
  virtual void FinalizeUniqueValueId() { }
857
  virtual void FinalizeUniqueness() { }
902 858

  
903 859
  // Printing support.
904 860
  virtual void PrintTo(StringStream* stream) = 0;
......
1104 1060
    return new(zone) I(p1, p2, p3, p4, p5);                                    \
1105 1061
  }
1106 1062

  
1063
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I)                         \
1064
  static I* New(Zone* zone, HValue* context) {                                 \
1065
    return new(zone) I(context);                                               \
1066
  }
1067

  
1068
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(I, P1)                     \
1069
  static I* New(Zone* zone, HValue* context, P1 p1) {                          \
1070
    return new(zone) I(context, p1);                                           \
1071
  }
1072

  
1073
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(I, P1, P2)                 \
1074
  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) {                   \
1075
    return new(zone) I(context, p1, p2);                                       \
1076
  }
1077

  
1078
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(I, P1, P2, P3)             \
1079
  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) {            \
1080
    return new(zone) I(context, p1, p2, p3);                                   \
1081
  }
1082

  
1083
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(I, P1, P2, P3, P4)         \
1084
  static I* New(Zone* zone,                                                    \
1085
                HValue* context,                                               \
1086
                P1 p1,                                                         \
1087
                P2 p2,                                                         \
1088
                P3 p3,                                                         \
1089
                P4 p4) {                                                       \
1090
    return new(zone) I(context, p1, p2, p3, p4);                               \
1091
  }
1092

  
1093
#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(I, P1, P2, P3, P4, P5)     \
1094
  static I* New(Zone* zone,                                                    \
1095
                HValue* context,                                               \
1096
                P1 p1,                                                         \
1097
                P2 p2,                                                         \
1098
                P3 p3,                                                         \
1099
                P4 p4,                                                         \
1100
                P5 p5) {                                                       \
1101
    return new(zone) I(context, p1, p2, p3, p4, p5);                           \
1102
  }
1103

  
1107 1104

  
1108 1105
class HInstruction : public HValue {
1109 1106
 public:
......
1119 1116
  void InsertAfter(HInstruction* previous);
1120 1117

  
1121 1118
  // The position is a write-once variable.
1122
  int position() const { return position_; }
1119
  virtual int position() const V8_OVERRIDE { return position_; }
1123 1120
  bool has_position() const { return position_ != RelocInfo::kNoPosition; }
1124 1121
  void set_position(int position) {
1125 1122
    ASSERT(!has_position());
......
1194 1191

  
1195 1192
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1196 1193

  
1194
  virtual bool KnownSuccessorBlock(HBasicBlock** block) {
1195
    *block = NULL;
1196
    return false;
1197
  }
1198

  
1197 1199
  HBasicBlock* FirstSuccessor() {
1198 1200
    return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
1199 1201
  }
......
1201 1203
    return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
1202 1204
  }
1203 1205

  
1206
  void Not() {
1207
    HBasicBlock* swap = SuccessorAt(0);
1208
    SetSuccessorAt(0, SuccessorAt(1));
1209
    SetSuccessorAt(1, swap);
1210
  }
1211

  
1204 1212
  DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
1205 1213
};
1206 1214

  
......
1277 1285
};
1278 1286

  
1279 1287

  
1280
class HDeoptimize V8_FINAL : public HTemplateInstruction<0> {
1288
// Inserts an int3/stop break instruction for debugging purposes.
1289
class HDebugBreak V8_FINAL : public HTemplateInstruction<0> {
1281 1290
 public:
1282
  DECLARE_INSTRUCTION_FACTORY_P2(HDeoptimize, const char*,
1283
                                 Deoptimizer::BailoutType);
1291
  DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak);
1284 1292

  
1285 1293
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1286 1294
    return Representation::None();
1287 1295
  }
1288 1296

  
1289
  const char* reason() const { return reason_; }
1290
  Deoptimizer::BailoutType type() { return type_; }
1291

  
1292
  DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1293

  
1294
 private:
1295
  explicit HDeoptimize(const char* reason, Deoptimizer::BailoutType type)
1296
      : reason_(reason), type_(type) {}
1297

  
1298
  const char* reason_;
1299
  Deoptimizer::BailoutType type_;
1297
  DECLARE_CONCRETE_INSTRUCTION(DebugBreak)
1300 1298
};
1301 1299

  
1302 1300

  
1303
// Inserts an int3/stop break instruction for debugging purposes.
1304
class HDebugBreak V8_FINAL : public HTemplateInstruction<0> {
1301
class HGoto V8_FINAL : public HTemplateControlInstruction<1, 0> {
1305 1302
 public:
1303
  explicit HGoto(HBasicBlock* target) {
1304
    SetSuccessorAt(0, target);
1305
  }
1306

  
1307
  virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE {
1308
    *block = FirstSuccessor();
1309
    return true;
1310
  }
1311

  
1306 1312
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1307 1313
    return Representation::None();
1308 1314
  }
1309 1315

  
1310
  DECLARE_CONCRETE_INSTRUCTION(DebugBreak)
1316
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1317

  
1318
  DECLARE_CONCRETE_INSTRUCTION(Goto)
1311 1319
};
1312 1320

  
1313 1321

  
1314
class HGoto V8_FINAL : public HTemplateControlInstruction<1, 0> {
1322
class HDeoptimize V8_FINAL : public HTemplateControlInstruction<1, 0> {
1315 1323
 public:
1316
  explicit HGoto(HBasicBlock* target) {
1317
    SetSuccessorAt(0, target);
1324
  static HInstruction* New(Zone* zone,
1325
                           HValue* context,
1326
                           const char* reason,
1327
                           Deoptimizer::BailoutType type,
1328
                           HBasicBlock* unreachable_continuation) {
1329
    return new(zone) HDeoptimize(reason, type, unreachable_continuation);
1330
  }
1331

  
1332
  virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE {
1333
    *block = NULL;
1334
    return true;
1318 1335
  }
1319 1336

  
1320 1337
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1321 1338
    return Representation::None();
1322 1339
  }
1323 1340

  
1324
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1341
  const char* reason() const { return reason_; }
1342
  Deoptimizer::BailoutType type() { return type_; }
1325 1343

  
1326
  DECLARE_CONCRETE_INSTRUCTION(Goto)
1344
  DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1345

  
1346
 private:
1347
  explicit HDeoptimize(const char* reason,
1348
                       Deoptimizer::BailoutType type,
1349
                       HBasicBlock* unreachable_continuation)
1350
      : reason_(reason), type_(type) {
1351
    SetSuccessorAt(0, unreachable_continuation);
1352
  }
1353

  
1354
  const char* reason_;
1355
  Deoptimizer::BailoutType type_;
1327 1356
};
1328 1357

  
1329 1358

  
......
1345 1374

  
1346 1375
class HBranch V8_FINAL : public HUnaryControlInstruction {
1347 1376
 public:
1348
  HBranch(HValue* value,
1349
          ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(),
1350
          HBasicBlock* true_target = NULL,
1351
          HBasicBlock* false_target = NULL)
1352
      : HUnaryControlInstruction(value, true_target, false_target),
1353
        expected_input_types_(expected_input_types) {
1354
    SetFlag(kAllowUndefinedAsNaN);
1355
  }
1377
  DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*);
1378
  DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*,
1379
                                 ToBooleanStub::Types);
1380
  DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*,
1381
                                 ToBooleanStub::Types,
1382
                                 HBasicBlock*, HBasicBlock*);
1356 1383

  
1357 1384
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1358 1385
    return Representation::None();
1359 1386
  }
1360 1387
  virtual Representation observed_input_representation(int index) V8_OVERRIDE;
1361 1388

  
1389
  virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
1390

  
1362 1391
  ToBooleanStub::Types expected_input_types() const {
1363 1392
    return expected_input_types_;
1364 1393
  }
......
1366 1395
  DECLARE_CONCRETE_INSTRUCTION(Branch)
1367 1396

  
1368 1397
 private:
1398
  HBranch(HValue* value,
1399
          ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(),
1400
          HBasicBlock* true_target = NULL,
1401
          HBasicBlock* false_target = NULL)
1402
      : HUnaryControlInstruction(value, true_target, false_target),
1403
        expected_input_types_(expected_input_types) {
1404
    SetFlag(kAllowUndefinedAsNaN);
1405
  }
1406

  
1369 1407
  ToBooleanStub::Types expected_input_types_;
1370 1408
};
1371 1409

  
1372 1410

  
1373 1411
class HCompareMap V8_FINAL : public HUnaryControlInstruction {
1374 1412
 public:
1375
  HCompareMap(HValue* value,
1376
              Handle<Map> map,
1377
              HBasicBlock* true_target = NULL,
1378
              HBasicBlock* false_target = NULL)
1379
      : HUnaryControlInstruction(value, true_target, false_target),
1380
      map_(map) {
1381
    ASSERT(!map.is_null());
1382
  }
1413
  DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>);
1414
  DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
1415
                                 HBasicBlock*, HBasicBlock*);
1383 1416

  
1384 1417
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1385 1418

  
1386
  Handle<Map> map() const { return map_; }
1419
  Unique<Map> map() const { return map_; }
1387 1420

  
1388 1421
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1389 1422
    return Representation::Tagged();
......
1395 1428
  virtual int RedefinedOperandIndex() { return 0; }
1396 1429

  
1397 1430
 private:
1398
  Handle<Map> map_;
1431
  HCompareMap(HValue* value,
1432
              Handle<Map> map,
1433
              HBasicBlock* true_target = NULL,
1434
              HBasicBlock* false_target = NULL)
1435
      : HUnaryControlInstruction(value, true_target, false_target),
1436
        map_(Unique<Map>(map)) {
1437
    ASSERT(!map.is_null());
1438
  }
1439

  
1440
  Unique<Map> map_;
1399 1441
};
1400 1442

  
1401 1443

  
......
1426 1468

  
1427 1469
class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> {
1428 1470
 public:
1429
  static HInstruction* New(Zone* zone,
1430
                           HValue* context,
1431
                           HValue* value,
1432
                           HValue* parameter_count) {
1433
    return new(zone) HReturn(value, context, parameter_count);
1434
  }
1435

  
1436
  static HInstruction* New(Zone* zone,
1437
                           HValue* context,
1438
                           HValue* value) {
1439
    return new(zone) HReturn(value, context, 0);
1440
  }
1471
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*);
1472
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*);
1441 1473

  
1442 1474
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1443 1475
    return Representation::Tagged();
......
1452 1484
  DECLARE_CONCRETE_INSTRUCTION(Return)
1453 1485

  
1454 1486
 private:
1455
  HReturn(HValue* value, HValue* context, HValue* parameter_count) {
1487
  HReturn(HValue* context, HValue* value, HValue* parameter_count = 0) {
1456 1488
    SetOperandAt(0, value);
1457 1489
    SetOperandAt(1, context);
1458 1490
    SetOperandAt(2, parameter_count);
......
1460 1492
};
1461 1493

  
1462 1494

  
1495
class HAbnormalExit V8_FINAL : public HTemplateControlInstruction<0, 0> {
1496
 public:
1497
  DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit);
1498

  
1499
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1500
    return Representation::None();
1501
  }
1502

  
1503
  DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
1504
 private:
1505
  HAbnormalExit() {}
1506
};
1507

  
1508

  
1463 1509
class HUnaryOperation : public HTemplateInstruction<1> {
1464 1510
 public:
1465 1511
  HUnaryOperation(HValue* value, HType type = HType::Tagged())
......
1478 1524

  
1479 1525
class HThrow V8_FINAL : public HTemplateInstruction<2> {
1480 1526
 public:
1481
  static HThrow* New(Zone* zone,
1482
                     HValue* context,
1483
                     HValue* value) {
1484
    return new(zone) HThrow(context, value);
1485
  }
1527
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HThrow, HValue*);
1486 1528

  
1487 1529
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1488 1530
    return Representation::Tagged();
......
1738 1780
 public:
1739 1781
  enum Kind { BIND, LOOKUP };
1740 1782

  
1741
  HEnvironmentMarker(Kind kind, int index)
1742
      : kind_(kind), index_(index), next_simulate_(NULL) { }
1783
  DECLARE_INSTRUCTION_FACTORY_P2(HEnvironmentMarker, Kind, int);
1743 1784

  
1744 1785
  Kind kind() { return kind_; }
1745 1786
  int index() { return index_; }
......
1766 1807
  DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker);
1767 1808

  
1768 1809
 private:
1810
  HEnvironmentMarker(Kind kind, int index)
1811
      : kind_(kind), index_(index), next_simulate_(NULL) { }
1812

  
1769 1813
  Kind kind_;
1770 1814
  int index_;
1771 1815
  HSimulate* next_simulate_;
......
1783 1827
    kBackwardsBranch
1784 1828
  };
1785 1829

  
1786
  DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type);
1830
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HStackCheck, Type);
1787 1831

  
1788 1832
  HValue* context() { return OperandAt(0); }
1789 1833

  
......
1898 1942

  
1899 1943
class HLeaveInlined V8_FINAL : public HTemplateInstruction<0> {
1900 1944
 public:
1901
  HLeaveInlined() { }
1945
  HLeaveInlined(HEnterInlined* entry,
1946
                int drop_count)
1947
      : entry_(entry),
1948
        drop_count_(drop_count) { }
1902 1949

  
1903 1950
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1904 1951
    return Representation::None();
1905 1952
  }
1906 1953

  
1954
  virtual int argument_delta() const V8_OVERRIDE {
1955
    return entry_->arguments_pushed() ? -drop_count_ : 0;
1956
  }
1957

  
1907 1958
  DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
1959

  
1960
 private:
1961
  HEnterInlined* entry_;
1962
  int drop_count_;
1908 1963
};
1909 1964

  
1910 1965

  
......
1916 1971
    return Representation::Tagged();
1917 1972
  }
1918 1973

  
1974
  virtual int argument_delta() const V8_OVERRIDE { return 1; }
1919 1975
  HValue* argument() { return OperandAt(0); }
1920 1976

  
1921 1977
  DECLARE_CONCRETE_INSTRUCTION(PushArgument)
......
1929 1985

  
1930 1986
class HThisFunction V8_FINAL : public HTemplateInstruction<0> {
1931 1987
 public:
1932
  HThisFunction() {
1933
    set_representation(Representation::Tagged());
1934
    SetFlag(kUseGVN);
1935
  }
1988
  DECLARE_INSTRUCTION_FACTORY_P0(HThisFunction);
1936 1989

  
1937 1990
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1938 1991
    return Representation::None();
......
1944 1997
  virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
1945 1998

  
1946 1999
 private:
2000
  HThisFunction() {
2001
    set_representation(Representation::Tagged());
2002
    SetFlag(kUseGVN);
2003
  }
2004

  
1947 2005
  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
1948 2006
};
1949 2007

  
......
1973 2031

  
1974 2032
class HDeclareGlobals V8_FINAL : public HUnaryOperation {
1975 2033
 public:
1976
  HDeclareGlobals(HValue* context,
1977
                  Handle<FixedArray> pairs,
1978
                  int flags)
1979
      : HUnaryOperation(context),
1980
        pairs_(pairs),
1981
        flags_(flags) {
1982
    set_representation(Representation::Tagged());
1983
    SetAllSideEffects();
1984
  }
1985

  
1986
  static HDeclareGlobals* New(Zone* zone,
1987
                              HValue* context,
1988
                              Handle<FixedArray> pairs,
1989
                              int flags) {
1990
    return new(zone) HDeclareGlobals(context, pairs, flags);
1991
  }
2034
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HDeclareGlobals,
2035
                                              Handle<FixedArray>,
2036
                                              int);
1992 2037

  
1993 2038
  HValue* context() { return OperandAt(0); }
1994 2039
  Handle<FixedArray> pairs() const { return pairs_; }
......
2001 2046
  }
2002 2047

  
2003 2048
 private:
2049
  HDeclareGlobals(HValue* context,
2050
                  Handle<FixedArray> pairs,
2051
                  int flags)
2052
      : HUnaryOperation(context),
2053
        pairs_(pairs),
2054
        flags_(flags) {
2055
    set_representation(Representation::Tagged());
2056
    SetAllSideEffects();
2057
  }
2058

  
2004 2059
  Handle<FixedArray> pairs_;
2005 2060
  int flags_;
2006 2061
};
......
2008 2063

  
2009 2064
class HGlobalObject V8_FINAL : public HUnaryOperation {
2010 2065
 public:
2011
  explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
2012
    set_representation(Representation::Tagged());
2013
    SetFlag(kUseGVN);
2014
  }
2015

  
2016
  static HGlobalObject* New(Zone* zone, HValue* context) {
2017
    return new(zone) HGlobalObject(context);
2018
  }
2066
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(HGlobalObject);
2019 2067

  
2020 2068
  DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
2021 2069

  
......
2027 2075
  virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2028 2076

  
2029 2077
 private:
2078
  explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
2079
    set_representation(Representation::Tagged());
2080
    SetFlag(kUseGVN);
2081
  }
2082

  
2030 2083
  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2031 2084
};
2032 2085

  
......
2068 2121
    return HType::Tagged();
2069 2122
  }
2070 2123

  
2071
  virtual int argument_count() const { return argument_count_; }
2124
  virtual int argument_count() const {
2125
    return argument_count_;
2126
  }
2127

  
2128
  virtual int argument_delta() const V8_OVERRIDE {
2129
    return -argument_count();
2130
  }
2072 2131

  
2073 2132
  virtual bool IsCall() V8_FINAL V8_OVERRIDE { return true; }
2074 2133

  
......
2117 2176

  
2118 2177
class HInvokeFunction V8_FINAL : public HBinaryCall {
2119 2178
 public:
2120
  HInvokeFunction(HValue* context, HValue* function, int argument_count)
2121
      : HBinaryCall(context, function, argument_count) {
2122
  }
2123

  
2124
  static HInvokeFunction* New(Zone* zone,
2125
                              HValue* context,
2126
                              HValue* function,
2127
                              int argument_count) {
2128
    return new(zone) HInvokeFunction(context, function, argument_count);
2129
  }
2179
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int);
2130 2180

  
2131 2181
  HInvokeFunction(HValue* context,
2132 2182
                  HValue* function,
......
2155 2205
  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
2156 2206

  
2157 2207
 private:
2208
  HInvokeFunction(HValue* context, HValue* function, int argument_count)
2209
      : HBinaryCall(context, function, argument_count) {
2210
  }
2211

  
2158 2212
  Handle<JSFunction> known_function_;
2159 2213
  int formal_parameter_count_;
2160 2214
};
......
2162 2216

  
2163 2217
class HCallConstantFunction V8_FINAL : public HCall<0> {
2164 2218
 public:
2165
  HCallConstantFunction(Handle<JSFunction> function, int argument_count)
2166
      : HCall<0>(argument_count),
2167
        function_(function),
2168
        formal_parameter_count_(function->shared()->formal_parameter_count()) {}
2219
  DECLARE_INSTRUCTION_FACTORY_P2(HCallConstantFunction,
2220
                                 Handle<JSFunction>,
2221
                                 int);
2169 2222

  
2170 2223
  Handle<JSFunction> function() const { return function_; }
2171 2224
  int formal_parameter_count() const { return formal_parameter_count_; }
......
2184 2237
  DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
2185 2238

  
2186 2239
 private:
2240
  HCallConstantFunction(Handle<JSFunction> function, int argument_count)
2241
      : HCall<0>(argument_count),
2242
        function_(function),
2243
        formal_parameter_count_(function->shared()->formal_parameter_count()) {}
2244

  
2187 2245
  Handle<JSFunction> function_;
2188 2246
  int formal_parameter_count_;
2189 2247
};
......
2191 2249

  
2192 2250
class HCallKeyed V8_FINAL : public HBinaryCall {
2193 2251
 public:
2194
  HCallKeyed(HValue* context, HValue* key, int argument_count)
2195
      : HBinaryCall(context, key, argument_count) {
2196
  }
2252
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallKeyed, HValue*, int);
2197 2253

  
2198 2254
  HValue* context() { return first(); }
2199 2255
  HValue* key() { return second(); }
2200 2256

  
2201 2257
  DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
2258

  
2259
 private:
2260
  HCallKeyed(HValue* context, HValue* key, int argument_count)
2261
      : HBinaryCall(context, key, argument_count) {
2262
  }
2202 2263
};
2203 2264

  
2204 2265

  
2205 2266
class HCallNamed V8_FINAL : public HUnaryCall {
2206 2267
 public:
2207
  HCallNamed(HValue* context, Handle<String> name, int argument_count)
2208
      : HUnaryCall(context, argument_count), name_(name) {
2209
  }
2268
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNamed, Handle<String>, int);
2210 2269

  
2211 2270
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2212 2271

  
......
2216 2275
  DECLARE_CONCRETE_INSTRUCTION(CallNamed)
2217 2276

  
2218 2277
 private:
2278
  HCallNamed(HValue* context, Handle<String> name, int argument_count)
2279
      : HUnaryCall(context, argument_count), name_(name) {
2280
  }
2281

  
2219 2282
  Handle<String> name_;
2220 2283
};
2221 2284

  
2222 2285

  
2223 2286
class HCallFunction V8_FINAL : public HBinaryCall {
2224 2287
 public:
2225
  HCallFunction(HValue* context, HValue* function, int argument_count)
2226
      : HBinaryCall(context, function, argument_count) {
2227
  }
2228

  
2229
  static HCallFunction* New(Zone* zone,
2230
                            HValue* context,
2231
                            HValue* function,
2232
                            int argument_count) {
2233
    return new(zone) HCallFunction(context, function, argument_count);
2234
  }
2288
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallFunction, HValue*, int);
2235 2289

  
2236 2290
  HValue* context() { return first(); }
2237 2291
  HValue* function() { return second(); }
2238 2292

  
2239 2293
  DECLARE_CONCRETE_INSTRUCTION(CallFunction)
2294

  
2295
 private:
2296
  HCallFunction(HValue* context, HValue* function, int argument_count)
2297
      : HBinaryCall(context, function, argument_count) {
2298
  }
2240 2299
};
2241 2300

  
2242 2301

  
2243 2302
class HCallGlobal V8_FINAL : public HUnaryCall {
2244 2303
 public:
2245
  HCallGlobal(HValue* context, Handle<String> name, int argument_count)
2246
      : HUnaryCall(context, argument_count), name_(name) {
2247
  }
2248

  
2249
  static HCallGlobal* New(Zone* zone,
2250
                          HValue* context,
2251
                          Handle<String> name,
2252
                          int argument_count) {
2253
    return new(zone) HCallGlobal(context, name, argument_count);
2254
  }
2304
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallGlobal, Handle<String>, int);
2255 2305

  
2256 2306
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2257 2307

  
......
2261 2311
  DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
2262 2312

  
2263 2313
 private:
2314
  HCallGlobal(HValue* context, Handle<String> name, int argument_count)
2315
      : HUnaryCall(context, argument_count), name_(name) {
2316
  }
2317

  
2264 2318
  Handle<String> name_;
2265 2319
};
2266 2320

  
2267 2321

  
2268 2322
class HCallKnownGlobal V8_FINAL : public HCall<0> {
2269 2323
 public:
2270
  HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
2271
      : HCall<0>(argument_count),
2272
        target_(target),
2273
        formal_parameter_count_(target->shared()->formal_parameter_count()) { }
2324
  DECLARE_INSTRUCTION_FACTORY_P2(HCallKnownGlobal, Handle<JSFunction>, int);
2274 2325

  
2275 2326
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2276 2327

  
......
2284 2335
  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
2285 2336

  
2286 2337
 private:
2338
  HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
2339
      : HCall<0>(argument_count),
2340
        target_(target),
2341
        formal_parameter_count_(target->shared()->formal_parameter_count()) { }
2342

  
2287 2343
  Handle<JSFunction> target_;
2288 2344
  int formal_parameter_count_;
2289 2345
};
......
2291 2347

  
2292 2348
class HCallNew V8_FINAL : public HBinaryCall {
2293 2349
 public:
2294
  HCallNew(HValue* context, HValue* constructor, int argument_count)
2295
      : HBinaryCall(context, constructor, argument_count) {}
2350
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int);
2296 2351

  
2297 2352
  HValue* context() { return first(); }
2298 2353
  HValue* constructor() { return second(); }
2299 2354

  
2300 2355
  DECLARE_CONCRETE_INSTRUCTION(CallNew)
2356

  
2357
 private:
2358
  HCallNew(HValue* context, HValue* constructor, int argument_count)
2359
      : HBinaryCall(context, constructor, argument_count) {}
2301 2360
};
2302 2361

  
2303 2362

  
2304 2363
class HCallNewArray V8_FINAL : public HBinaryCall {
2305 2364
 public:
2306
  HCallNewArray(HValue* context, HValue* constructor, int argument_count,
2307
                Handle<Cell> type_cell, ElementsKind elements_kind)
2308
      : HBinaryCall(context, constructor, argument_count),
2309
        elements_kind_(elements_kind),
2310
        type_cell_(type_cell) {}
2365
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray,
2366
                                              HValue*,
2367
                                              int,
2368
                                              Handle<Cell>,
2369
                                              ElementsKind);
2311 2370

  
2312 2371
  HValue* context() { return first(); }
2313 2372
  HValue* constructor() { return second(); }
......
2323 2382
  DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
2324 2383

  
2325 2384
 private:
2385
  HCallNewArray(HValue* context, HValue* constructor, int argument_count,
2386
                Handle<Cell> type_cell, ElementsKind elements_kind)
2387
      : HBinaryCall(context, constructor, argument_count),
2388
        elements_kind_(elements_kind),
2389
        type_cell_(type_cell) {}
2390

  
2326 2391
  ElementsKind elements_kind_;
2327 2392
  Handle<Cell> type_cell_;
2328 2393
};
......
2330 2395

  
2331 2396
class HCallRuntime V8_FINAL : public HCall<1> {
2332 2397
 public:
2333
  static HCallRuntime* New(Zone* zone,
2334
                           HValue* context,
2335
                           Handle<String> name,
2336
                           const Runtime::Function* c_function,
2337
                           int argument_count) {
2338
    return new(zone) HCallRuntime(context, name, c_function, argument_count);
2339
  }
2398
  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCallRuntime,
2399
                                              Handle<String>,
2400
                                              const Runtime::Function*,
2401
                                              int);
2340 2402

  
2341 2403
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2342 2404

  
2343 2405
  HValue* context() { return OperandAt(0); }
2344 2406
  const Runtime::Function* function() const { return c_function_; }
2345 2407
  Handle<String> name() const { return name_; }
2408
  SaveFPRegsMode save_doubles() const { return save_doubles_; }
2409
  void set_save_doubles(SaveFPRegsMode save_doubles) {
2410
    save_doubles_ = save_doubles;
2411
  }
2346 2412

  
2347 2413
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2348 2414
    return Representation::Tagged();
......
2355 2421
               Handle<String> name,
2356 2422
               const Runtime::Function* c_function,
2357 2423
               int argument_count)
2358
      : HCall<1>(argument_count), c_function_(c_function), name_(name) {
2424
      : HCall<1>(argument_count), c_function_(c_function), name_(name),
2425
        save_doubles_(kDontSaveFPRegs) {
2359 2426
    SetOperandAt(0, context);
2360 2427
  }
2361 2428

  
2362 2429
  const Runtime::Function* c_function_;
2363 2430
  Handle<String> name_;
2431
  SaveFPRegsMode save_doubles_;
2364 2432
};
2365 2433

  
2366 2434

  
......
2509 2577
};
2510 2578

  
2511 2579

  
2580
class HLoadRoot V8_FINAL : public HTemplateInstruction<0> {
2581
 public:
2582
  DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex);
2583
  DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType);
2584

  
2585
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2586
    return Representation::None();
2587
  }
2588

  
2589
  Heap::RootListIndex index() const { return index_; }
2590

  
2591
  DECLARE_CONCRETE_INSTRUCTION(LoadRoot)
2592

  
2593
 protected:
2594
  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2595
    HLoadRoot* b = HLoadRoot::cast(other);
2596
    return index_ == b->index_;
2597
  }
2598

  
2599
 private:
2600
  HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged())
2601
      : HTemplateInstruction<0>(type), index_(index) {
2602
    SetFlag(kUseGVN);
2603
    // TODO(bmeurer): We'll need kDependsOnRoots once we add the
2604
    // corresponding HStoreRoot instruction.
2605
    SetGVNFlag(kDependsOnCalls);
2606
  }
2607

  
2608
  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2609

  
2610
  const Heap::RootListIndex index_;
2611
};
2612

  
2613

  
2512 2614
class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation {
2513 2615
 public:
2514 2616
  DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*);
......
2553 2655
    for (int i = 0; i < maps->length(); i++) {
2554 2656
      check_map->Add(maps->at(i), zone);
2555 2657
    }
2556
    check_map->map_set_.Sort();
2557 2658
    return check_map;
2558 2659
  }
2559 2660

  
......
2568 2669
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2569 2670

  
2570 2671
  HValue* value() { return OperandAt(0); }
2571
  SmallMapList* map_set() { return &map_set_; }
2572
  ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; }
2573 2672

  
2574
  bool has_migration_target() {
2673
  Unique<Map> first_map() const { return map_set_.at(0); }
2674
  UniqueSet<Map> map_set() const { return map_set_; }
2675

  
2676
  bool has_migration_target() const {
2575 2677
    return has_migration_target_;
2576 2678
  }
2577 2679

  
2578
  virtual void FinalizeUniqueValueId() V8_OVERRIDE;
2579

  
2580 2680
  DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2581 2681

  
2582 2682
 protected:
2583 2683
  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2584
    ASSERT_EQ(map_set_.length(), map_unique_ids_.length());
2585
    HCheckMaps* b = HCheckMaps::cast(other);
2586
    // Relies on the fact that map_set has been sorted before.
2587
    if (map_unique_ids_.length() != b->map_unique_ids_.length()) {
2588
      return false;
2589
    }
2590
    for (int i = 0; i < map_unique_ids_.length(); i++) {
2591
      if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) {
2592
        return false;
2593
      }
2594
    }
2595
    return true;
2684
    return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_);
2596 2685
  }
2597 2686

  
2598 2687
  virtual int RedefinedOperandIndex() { return 0; }
2599 2688

  
2600 2689
 private:
2601 2690
  void Add(Handle<Map> map, Zone* zone) {
2602
    map_set_.Add(map, zone);
2691
    map_set_.Add(Unique<Map>(map), zone);
2603 2692
    if (!has_migration_target_ && map->is_migration_target()) {
2604 2693
      has_migration_target_ = true;
2605 2694
      SetGVNFlag(kChangesNewSpacePromotion);
......
2609 2698
  // Clients should use one of the static New* methods above.
2610 2699
  HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
2611 2700
      : HTemplateInstruction<2>(value->type()),
2612
        omit_(false), has_migration_target_(false), map_unique_ids_(0, zone) {
2701
        omit_(false), has_migration_target_(false) {
2613 2702
    SetOperandAt(0, value);
2614 2703
    // Use the object value for the dependency if NULL is passed.
2615
    // TODO(titzer): do GVN flags already express this dependency?
2616 2704
    SetOperandAt(1, typecheck != NULL ? typecheck : value);
2617 2705
    set_representation(Representation::Tagged());
2618 2706
    SetFlag(kUseGVN);
......
2621 2709
    SetGVNFlag(kDependsOnElementsKind);
2622 2710
  }
2623 2711

  
2624
  void omit(CompilationInfo* info) {
2625
    omit_ = true;
2626
    for (int i = 0; i < map_set_.length(); i++) {
2627
      Handle<Map> map = map_set_.at(i);
2628
      if (!map->CanTransition()) continue;
2629
      map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
2630
                                       info);
2631
    }
2632
  }
2633

  
2634 2712
  bool omit_;
2635 2713
  bool has_migration_target_;
2636
  SmallMapList map_set_;
2637
  ZoneList<UniqueValueId> map_unique_ids_;
2714
  UniqueSet<Map> map_set_;
2638 2715
};
2639 2716

  
2640 2717

  
2641 2718
class HCheckValue V8_FINAL : public HUnaryOperation {
2642 2719
 public:
2643 2720
  static HCheckValue* New(Zone* zone, HValue* context,
2644
                          HValue* value, Handle<JSFunction> target) {
2645
    bool in_new_space = zone->isolate()->heap()->InNewSpace(*target);
2721
                          HValue* value, Handle<JSFunction> func) {
2722
    bool in_new_space = zone->isolate()->heap()->InNewSpace(*func);
2723
    // NOTE: We create an uninitialized Unique and initialize it later.
2724
    // This is because a JSFunction can move due to GC during graph creation.
2725
    // TODO(titzer): This is a migration crutch. Replace with some kind of
2726
    // Uniqueness scope later.
2727
    Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func);
2646 2728
    HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space);
2647 2729
    return check;
2648 2730
  }
2649 2731
  static HCheckValue* New(Zone* zone, HValue* context,
2650
                          HValue* value, Handle<Map> map, UniqueValueId id) {
2651
    HCheckValue* check = new(zone) HCheckValue(value, map, false);
2652
    check->object_unique_id_ = id;
2653
    return check;
2732
                          HValue* value, Unique<HeapObject> target,
2733
                          bool object_in_new_space) {
2734
    return new(zone) HCheckValue(value, target, object_in_new_space);
2735
  }
2736

  
2737
  virtual void FinalizeUniqueness() V8_OVERRIDE {
2738
    object_ = Unique<HeapObject>(object_.handle());
2654 2739
  }
2655 2740

  
2656 2741
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
......
2664 2749
  virtual void Verify() V8_OVERRIDE;
2665 2750
#endif
2666 2751

  
2667
  virtual void FinalizeUniqueValueId() V8_OVERRIDE {
2668
    object_unique_id_ = UniqueValueId(object_);
2669
  }
2670

  
2671
  Handle<HeapObject> object() const { return object_; }
2752
  Unique<HeapObject> object() const { return object_; }
2672 2753
  bool object_in_new_space() const { return object_in_new_space_; }
2673 2754

  
2674 2755
  DECLARE_CONCRETE_INSTRUCTION(CheckValue)
......
2676 2757
 protected:
2677 2758
  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2678 2759
    HCheckValue* b = HCheckValue::cast(other);
2679
    return object_unique_id_ == b->object_unique_id_;
2760
    return object_ == b->object_;
2680 2761
  }
2681 2762

  
2682 2763
 private:
2683
  HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space)
2764
  HCheckValue(HValue* value, Unique<HeapObject> object,
2765
               bool object_in_new_space)
2684 2766
      : HUnaryOperation(value, value->type()),
2685
        object_(object), object_in_new_space_(in_new_space) {
2767
        object_(object),
2768
        object_in_new_space_(object_in_new_space) {
2686 2769
    set_representation(Representation::Tagged());
2687 2770
    SetFlag(kUseGVN);
2688 2771
  }
2689 2772

  
2690
  Handle<HeapObject> object_;
2691
  UniqueValueId object_unique_id_;
2773
  Unique<HeapObject> object_;
2692 2774
  bool object_in_new_space_;
2693 2775
};
2694 2776

  
2695 2777

  
2696 2778
class HCheckInstanceType V8_FINAL : public HUnaryOperation {
2697 2779
 public:
2698
  static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) {
2699
    return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
2700
  }
2701
  static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) {
2702
    return new(zone) HCheckInstanceType(value, IS_JS_ARRAY);
2703
  }
2704
  static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) {
2705
    return new(zone) HCheckInstanceType(value, IS_STRING);
2706
  }
2707
  static HCheckInstanceType* NewIsInternalizedString(
2708
      HValue* value, Zone* zone) {
2709
    return new(zone) HCheckInstanceType(value, IS_INTERNALIZED_STRING);
2710
  }
2780
  enum Check {
2781
    IS_SPEC_OBJECT,
2782
    IS_JS_ARRAY,
2783
    IS_STRING,
2784
    IS_INTERNALIZED_STRING,
2785
    LAST_INTERVAL_CHECK = IS_JS_ARRAY
2786
  };
2787

  
2788
  DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check);
2711 2789

  
2712 2790
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2713 2791

  
......
2735 2813
  virtual int RedefinedOperandIndex() { return 0; }
2736 2814

  
2737 2815
 private:
2738
  enum Check {
2739
    IS_SPEC_OBJECT,
2740
    IS_JS_ARRAY,
2741
    IS_STRING,
2742
    IS_INTERNALIZED_STRING,
2743
    LAST_INTERVAL_CHECK = IS_JS_ARRAY
2744
  };
2745

  
2746 2816
  const char* GetCheckName();
2747 2817

  
2748 2818
  HCheckInstanceType(HValue* value, Check check)
......
2784 2854
};
2785 2855

  
2786 2856

  
2787
class HIsNumberAndBranch V8_FINAL : public HUnaryControlInstruction {
2788
 public:
2789
  explicit HIsNumberAndBranch(HValue* value)
2790
    : HUnaryControlInstruction(value, NULL, NULL) {
2791
    SetFlag(kFlexibleRepresentation);
2792
  }
2793

  
2794
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2795
    return Representation::None();
2796
  }
2797

  
2798
  DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch)
2799
};
2800

  
2801

  
2802 2857
class HCheckHeapObject V8_FINAL : public HUnaryOperation {
2803 2858
 public:
2804 2859
  DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
......
3090 3145
  bool IsReceiver() const { return merged_index_ == 0; }
3091 3146
  bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; }
3092 3147

  
3148
  virtual int position() const V8_OVERRIDE;
3149

  
3093 3150
  int merged_index() const { return merged_index_; }
3094 3151

  
3095 3152
  InductionVariableData* induction_variable_data() {
......
3260 3317
  // Replay effects of this instruction on the given environment.
3261 3318
  void ReplayEnvironment(HEnvironment* env);
3262 3319

  
3320
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3321

  
3263 3322
  DECLARE_CONCRETE_INSTRUCTION(CapturedObject)
3264 3323

  
3265 3324
 private:
......
3273 3332
  DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
3274 3333
  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
3275 3334
  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
3276
  DECLARE_INSTRUCTION_FACTORY_P2(HConstant, Handle<Map>, UniqueValueId);
3277 3335
  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
3278 3336

  
3279 3337
  static HConstant* CreateAndInsertAfter(Zone* zone,
......
3298 3356
    return new_constant;
3299 3357
  }
3300 3358

  
3359
  static HConstant* CreateAndInsertBefore(Zone* zone,
3360
                                          Unique<Object> unique,
3361
                                          bool is_not_in_new_space,
3362
                                          HInstruction* instruction) {
3363
    HConstant* new_constant = new(zone) HConstant(unique,
3364
        Representation::Tagged(), HType::Tagged(), false, is_not_in_new_space,
3365
        false, false);
3366
    new_constant->InsertBefore(instruction);
3367
    return new_constant;
3368
  }
3369

  
3301 3370
  Handle<Object> handle(Isolate* isolate) {
3302
    if (handle_.is_null()) {
3303
      Factory* factory = isolate->factory();
3371
    if (object_.handle().is_null()) {
3304 3372
      // Default arguments to is_not_in_new_space depend on this heap number
3305
      // to be tenured so that it's guaranteed not be be located in new space.
3306
      handle_ = factory->NewNumber(double_value_, TENURED);
3373
      // to be tenured so that it's guaranteed not to be located in new space.
3374
      object_ = Unique<Object>::CreateUninitialized(
3375
          isolate->factory()->NewNumber(double_value_, TENURED));
3307 3376
    }
3308 3377
    AllowDeferredHandleDereference smi_check;
3309
    ASSERT(has_int32_value_ || !handle_->IsSmi());
3310
    return handle_;
3378
    ASSERT(has_int32_value_ || !object_.handle()->IsSmi());
3379
    return object_.handle();
3311 3380
  }
3312 3381

  
3313 3382
  bool HasMap(Handle<Map> map) {
......
3341 3410
      return false;
3342 3411
    }
3343 3412

  
3344
    ASSERT(!handle_.is_null());
3413
    ASSERT(!object_.handle().is_null());
3345 3414
    Heap* heap = isolate()->heap();
3346
    ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap));
3347
    ASSERT(unique_id_ != UniqueValueId::nan_value(heap));
3348
    return unique_id_ == UniqueValueId::undefined_value(heap) ||
3349
           unique_id_ == UniqueValueId::null_value(heap) ||
3350
           unique_id_ == UniqueValueId::true_value(heap) ||
3351
           unique_id_ == UniqueValueId::false_value(heap) ||
3352
           unique_id_ == UniqueValueId::the_hole_value(heap) ||
3353
           unique_id_ == UniqueValueId::empty_string(heap);
3415
    ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value()));
3416
    ASSERT(!object_.IsKnownGlobal(heap->nan_value()));
3417
    return
3418
        object_.IsKnownGlobal(heap->undefined_value()) ||
3419
        object_.IsKnownGlobal(heap->null_value()) ||
3420
        object_.IsKnownGlobal(heap->true_value()) ||
3421
        object_.IsKnownGlobal(heap->false_value()) ||
3422
        object_.IsKnownGlobal(heap->the_hole_value()) ||
3423
        object_.IsKnownGlobal(heap->empty_string()) ||
3424
        object_.IsKnownGlobal(heap->empty_fixed_array());
3354 3425
  }
3355 3426

  
3356 3427
  bool IsCell() const {
......
3389 3460
    if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) {
3390 3461
      return true;
3391 3462
    }
3392
    Heap* heap = isolate()->heap();
3393
    if (!handle_.is_null() && *handle_ == heap->the_hole_value()) {
3394
      return true;
3395
    }
3396
    return false;
3463
    return object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
3397 3464
  }
3398 3465
  bool HasNumberValue() const { return has_double_value_; }
3399 3466
  int32_t NumberValueAsInteger32() const {
......
3405 3472
  }
3406 3473
  bool HasStringValue() const {
3407 3474
    if (has_double_value_ || has_int32_value_) return false;
3408
    ASSERT(!handle_.is_null());
3475
    ASSERT(!object_.handle().is_null());
3409 3476
    return type_.IsString();
3410 3477
  }
3411 3478
  Handle<String> StringValue() const {
3412 3479
    ASSERT(HasStringValue());
3413
    return Handle<String>::cast(handle_);
3480
    return Handle<String>::cast(object_.handle());
3414 3481
  }
3415 3482
  bool HasInternalizedStringValue() const {
3416 3483
    return HasStringValue() && is_internalized_string_;
......
3434 3501
    } else if (has_external_reference_value_) {
3435 3502
      return reinterpret_cast<intptr_t>(external_reference_value_.address());
3436 3503
    } else {
3437
      ASSERT(!handle_.is_null());
3438
      return unique_id_.Hashcode();
3504
      ASSERT(!object_.handle().is_null());
3505
      return object_.Hashcode();
3439 3506
    }
3440 3507
  }
3441 3508

  
3442
  virtual void FinalizeUniqueValueId() V8_OVERRIDE {
3509
  virtual void FinalizeUniqueness() V8_OVERRIDE {
3443 3510
    if (!has_double_value_ && !has_external_reference_value_) {
3444
      ASSERT(!handle_.is_null());
3445
      unique_id_ = UniqueValueId(handle_);
3511
      ASSERT(!object_.handle().is_null());
3512
      object_ = Unique<Object>(object_.handle());
3446 3513
    }
3447 3514
  }
3448 3515

  
3449
  bool UniqueValueIdsMatch(UniqueValueId other) {
3450
    return !has_double_value_ && !has_external_reference_value_ &&
3451
        unique_id_ == other;
3516
  Unique<Object> GetUnique() const {
3517
    return object_;
3452 3518
  }
3453 3519

  
3454 3520
#ifdef DEBUG
......
3474 3540
          external_reference_value_ ==
3475 3541
          other_constant->external_reference_value_;
3476 3542
    } else {
3477
      ASSERT(!handle_.is_null());
3478
      return !other_constant->handle_.is_null() &&
3479
             unique_id_ == other_constant->unique_id_;
3543
      if (other_constant->has_int32_value_ ||
3544
          other_constant->has_double_value_ ||
3545
          other_constant->has_external_reference_value_) {
3546
        return false;
3547
      }
3548
      ASSERT(!object_.handle().is_null());
3549
      return other_constant->object_ == object_;
3480 3550
    }
3481 3551
  }
3482 3552

  
......
3486 3556
  HConstant(int32_t value,
3487 3557
            Representation r = Representation::None(),
3488 3558
            bool is_not_in_new_space = true,
3489
            Handle<Object> optional_handle = Handle<Object>::null());
3559
            Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
3490 3560
  HConstant(double value,
3491 3561
            Representation r = Representation::None(),
3492 3562
            bool is_not_in_new_space = true,
3493
            Handle<Object> optional_handle = Handle<Object>::null());
3494
  HConstant(Handle<Object> handle,
3495
            UniqueValueId unique_id,
3563
            Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
3564
  HConstant(Unique<Object> unique,
3496 3565
            Representation r,
3497 3566
            HType type,
3498 3567
            bool is_internalized_string,
3499 3568
            bool is_not_in_new_space,
3500 3569
            bool is_cell,
3501 3570
            bool boolean_value);
3502
  HConstant(Handle<Map> handle,
3503
            UniqueValueId unique_id);
3571

  
3504 3572
  explicit HConstant(ExternalReference reference);
3505 3573

  
3506 3574
  void Initialize(Representation r);
3507 3575

  
3508 3576
  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
3509 3577

  
3510
  // If this is a numerical constant, handle_ either points to to the
3578
  // If this is a numerical constant, object_ either points to the
3511 3579
  // HeapObject the constant originated from or is null.  If the
3512
  // constant is non-numeric, handle_ always points to a valid
3580
  // constant is non-numeric, object_ always points to a valid
3513 3581
  // constant HeapObject.
3514
  Handle<Object> handle_;
3515
  UniqueValueId unique_id_;
3582
  Unique<Object> object_;
3516 3583

  
3517 3584
  // We store the HConstant in the most specific form safely possible.
3518 3585
  // The two flags, has_int32_value_ and has_double_value_ tell us if
......
3649 3716

  
3650 3717
class HApplyArguments V8_FINAL : public HTemplateInstruction<4> {
3651 3718
 public:
3652
  HApplyArguments(HValue* function,
3653
                  HValue* receiver,
3654
                  HValue* length,
3655
                  HValue* elements) {
3656
    set_representation(Representation::Tagged());
3657
    SetOperandAt(0, function);
3658
    SetOperandAt(1, receiver);
3659
    SetOperandAt(2, length);
3660
    SetOperandAt(3, elements);
3661
    SetAllSideEffects();
3662
  }
3719
  DECLARE_INSTRUCTION_FACTORY_P4(HApplyArguments, HValue*, HValue*, HValue*,
3720
                                 HValue*);
3663 3721

  
3664 3722
  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3665 3723
    // The length is untagged, all other inputs are tagged.
......
3674 3732
  HValue* elements() { return OperandAt(3); }
3675 3733

  
3676 3734
  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
3735

  
3736
 private:
3737
  HApplyArguments(HValue* function,
3738
                  HValue* receiver,
3739
                  HValue* length,
3740
                  HValue* elements) {
3741
    set_representation(Representation::Tagged());
3742
    SetOperandAt(0, function);
3743
    SetOperandAt(1, receiver);
3744
    SetOperandAt(2, length);
3745
    SetOperandAt(3, elements);
3746
    SetAllSideEffects();
3747
  }
3677 3748
};
3678 3749

  
3679 3750

  
......
3731 3802

  
3732 3803
class HAccessArgumentsAt V8_FINAL : public HTemplateInstruction<3> {
3733 3804
 public:
3734
  HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3735
    set_representation(Representation::Tagged());
3736
    SetFlag(kUseGVN);
3737
    SetOperandAt(0, arguments);
3738
    SetOperandAt(1, length);
3739
    SetOperandAt(2, index);
3740
  }
3805
  DECLARE_INSTRUCTION_FACTORY_P3(HAccessArgumentsAt, HValue*, HValue*, HValue*);
3741 3806

  
3742 3807
  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3743 3808

  
......
3754 3819

  
3755 3820
  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
3756 3821

  
3822
 private:
3823
  HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3824
    set_representation(Representation::Tagged());
3825
    SetFlag(kUseGVN);
3826
    SetOperandAt(0, arguments);
3827
    SetOperandAt(1, length);
3828
    SetOperandAt(2, index);
3829
  }
3830

  
3757 3831
  virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
3758 3832
};
3759 3833

  
......
3882 3956
  }
3883 3957

  
3884 3958
  virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
3885
    if (!to.IsTagged()) {
3886
      ASSERT(to.IsSmiOrInteger32());
3887
      ClearAllSideEffects();
3888
      SetFlag(kUseGVN);
3889
    } else {
3959
    if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
3960
    if (to.IsTagged() &&
3961
        (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
3890 3962
      SetAllSideEffects();
3891 3963
      ClearFlag(kUseGVN);
3964
    } else {
3965
      ClearAllSideEffects();
3966
      SetFlag(kUseGVN);
3892 3967
    }
3893 3968
  }
3894 3969

  
......
3920 3995

  
3921 3996
class HMathFloorOfDiv V8_FINAL : public HBinaryOperation {
3922 3997
 public:
3923
  static HMathFloorOfDiv* New(Zone* zone,
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff