| OLD | NEW |
| 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 18 matching lines...) Expand all Loading... |
| 29 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 29 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
| 30 | 30 |
| 31 #include "v8.h" | 31 #include "v8.h" |
| 32 | 32 |
| 33 #include "allocation.h" | 33 #include "allocation.h" |
| 34 #include "code-stubs.h" | 34 #include "code-stubs.h" |
| 35 #include "data-flow.h" | 35 #include "data-flow.h" |
| 36 #include "deoptimizer.h" | 36 #include "deoptimizer.h" |
| 37 #include "small-pointer-list.h" | 37 #include "small-pointer-list.h" |
| 38 #include "string-stream.h" | 38 #include "string-stream.h" |
| 39 #include "unique.h" |
| 39 #include "v8conversions.h" | 40 #include "v8conversions.h" |
| 40 #include "v8utils.h" | 41 #include "v8utils.h" |
| 41 #include "zone.h" | 42 #include "zone.h" |
| 42 | 43 |
| 43 namespace v8 { | 44 namespace v8 { |
| 44 namespace internal { | 45 namespace internal { |
| 45 | 46 |
| 46 // Forward declarations. | 47 // Forward declarations. |
| 47 class HBasicBlock; | 48 class HBasicBlock; |
| 48 class HEnvironment; | 49 class HEnvironment; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 V(Goto) \ | 122 V(Goto) \ |
| 122 V(HasCachedArrayIndexAndBranch) \ | 123 V(HasCachedArrayIndexAndBranch) \ |
| 123 V(HasInstanceTypeAndBranch) \ | 124 V(HasInstanceTypeAndBranch) \ |
| 124 V(InnerAllocatedObject) \ | 125 V(InnerAllocatedObject) \ |
| 125 V(InstanceOf) \ | 126 V(InstanceOf) \ |
| 126 V(InstanceOfKnownGlobal) \ | 127 V(InstanceOfKnownGlobal) \ |
| 127 V(InstanceSize) \ | 128 V(InstanceSize) \ |
| 128 V(InvokeFunction) \ | 129 V(InvokeFunction) \ |
| 129 V(IsConstructCallAndBranch) \ | 130 V(IsConstructCallAndBranch) \ |
| 130 V(IsObjectAndBranch) \ | 131 V(IsObjectAndBranch) \ |
| 131 V(IsNumberAndBranch) \ | |
| 132 V(IsStringAndBranch) \ | 132 V(IsStringAndBranch) \ |
| 133 V(IsSmiAndBranch) \ | 133 V(IsSmiAndBranch) \ |
| 134 V(IsUndetectableAndBranch) \ | 134 V(IsUndetectableAndBranch) \ |
| 135 V(LeaveInlined) \ | 135 V(LeaveInlined) \ |
| 136 V(LoadContextSlot) \ | 136 V(LoadContextSlot) \ |
| 137 V(LoadExternalArrayPointer) \ | 137 V(LoadExternalArrayPointer) \ |
| 138 V(LoadFieldByIndex) \ | 138 V(LoadFieldByIndex) \ |
| 139 V(LoadFunctionPrototype) \ | 139 V(LoadFunctionPrototype) \ |
| 140 V(LoadGlobalCell) \ | 140 V(LoadGlobalCell) \ |
| 141 V(LoadGlobalGeneric) \ | 141 V(LoadGlobalGeneric) \ |
| 142 V(LoadKeyed) \ | 142 V(LoadKeyed) \ |
| 143 V(LoadKeyedGeneric) \ | 143 V(LoadKeyedGeneric) \ |
| 144 V(LoadNamedField) \ | 144 V(LoadNamedField) \ |
| 145 V(LoadNamedGeneric) \ | 145 V(LoadNamedGeneric) \ |
| 146 V(LoadRoot) \ |
| 146 V(MapEnumLength) \ | 147 V(MapEnumLength) \ |
| 147 V(MathFloorOfDiv) \ | 148 V(MathFloorOfDiv) \ |
| 148 V(MathMinMax) \ | 149 V(MathMinMax) \ |
| 149 V(Mod) \ | 150 V(Mod) \ |
| 150 V(Mul) \ | 151 V(Mul) \ |
| 151 V(OsrEntry) \ | 152 V(OsrEntry) \ |
| 152 V(OuterContext) \ | 153 V(OuterContext) \ |
| 153 V(Parameter) \ | 154 V(Parameter) \ |
| 154 V(Power) \ | 155 V(Power) \ |
| 155 V(PushArgument) \ | 156 V(PushArgument) \ |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 | 344 |
| 344 IMMOVABLE_UNIQUE_VALUE_ID(free_space_map) | 345 IMMOVABLE_UNIQUE_VALUE_ID(free_space_map) |
| 345 IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value) | 346 IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value) |
| 346 IMMOVABLE_UNIQUE_VALUE_ID(nan_value) | 347 IMMOVABLE_UNIQUE_VALUE_ID(nan_value) |
| 347 IMMOVABLE_UNIQUE_VALUE_ID(undefined_value) | 348 IMMOVABLE_UNIQUE_VALUE_ID(undefined_value) |
| 348 IMMOVABLE_UNIQUE_VALUE_ID(null_value) | 349 IMMOVABLE_UNIQUE_VALUE_ID(null_value) |
| 349 IMMOVABLE_UNIQUE_VALUE_ID(true_value) | 350 IMMOVABLE_UNIQUE_VALUE_ID(true_value) |
| 350 IMMOVABLE_UNIQUE_VALUE_ID(false_value) | 351 IMMOVABLE_UNIQUE_VALUE_ID(false_value) |
| 351 IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value) | 352 IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value) |
| 352 IMMOVABLE_UNIQUE_VALUE_ID(empty_string) | 353 IMMOVABLE_UNIQUE_VALUE_ID(empty_string) |
| 354 IMMOVABLE_UNIQUE_VALUE_ID(empty_fixed_array) |
| 353 | 355 |
| 354 #undef IMMOVABLE_UNIQUE_VALUE_ID | 356 #undef IMMOVABLE_UNIQUE_VALUE_ID |
| 355 | 357 |
| 356 private: | 358 private: |
| 357 Address raw_address_; | 359 Address raw_address_; |
| 358 | 360 |
| 359 explicit UniqueValueId(Object* object) { | 361 explicit UniqueValueId(Object* object) { |
| 360 raw_address_ = reinterpret_cast<Address>(object); | 362 raw_address_ = reinterpret_cast<Address>(object); |
| 361 ASSERT(IsInitialized()); | 363 ASSERT(IsInitialized()); |
| 362 } | 364 } |
| (...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 | 1200 |
| 1199 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1201 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 1200 | 1202 |
| 1201 HBasicBlock* FirstSuccessor() { | 1203 HBasicBlock* FirstSuccessor() { |
| 1202 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL; | 1204 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL; |
| 1203 } | 1205 } |
| 1204 HBasicBlock* SecondSuccessor() { | 1206 HBasicBlock* SecondSuccessor() { |
| 1205 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL; | 1207 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL; |
| 1206 } | 1208 } |
| 1207 | 1209 |
| 1210 void Not() { |
| 1211 HBasicBlock* swap = SuccessorAt(0); |
| 1212 SetSuccessorAt(0, SuccessorAt(1)); |
| 1213 SetSuccessorAt(1, swap); |
| 1214 } |
| 1215 |
| 1208 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction) | 1216 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction) |
| 1209 }; | 1217 }; |
| 1210 | 1218 |
| 1211 | 1219 |
| 1212 class HSuccessorIterator V8_FINAL BASE_EMBEDDED { | 1220 class HSuccessorIterator V8_FINAL BASE_EMBEDDED { |
| 1213 public: | 1221 public: |
| 1214 explicit HSuccessorIterator(HControlInstruction* instr) | 1222 explicit HSuccessorIterator(HControlInstruction* instr) |
| 1215 : instr_(instr), current_(0) { } | 1223 : instr_(instr), current_(0) { } |
| 1216 | 1224 |
| 1217 bool Done() { return current_ >= instr_->SuccessorCount(); } | 1225 bool Done() { return current_ >= instr_->SuccessorCount(); } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 } | 1352 } |
| 1345 | 1353 |
| 1346 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1354 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 1347 | 1355 |
| 1348 HValue* value() { return OperandAt(0); } | 1356 HValue* value() { return OperandAt(0); } |
| 1349 }; | 1357 }; |
| 1350 | 1358 |
| 1351 | 1359 |
| 1352 class HBranch V8_FINAL : public HUnaryControlInstruction { | 1360 class HBranch V8_FINAL : public HUnaryControlInstruction { |
| 1353 public: | 1361 public: |
| 1354 HBranch(HValue* value, | 1362 DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*); |
| 1355 ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), | 1363 DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, |
| 1356 HBasicBlock* true_target = NULL, | 1364 ToBooleanStub::Types); |
| 1357 HBasicBlock* false_target = NULL) | 1365 DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, |
| 1358 : HUnaryControlInstruction(value, true_target, false_target), | 1366 ToBooleanStub::Types, |
| 1359 expected_input_types_(expected_input_types) { | 1367 HBasicBlock*, HBasicBlock*); |
| 1360 SetFlag(kAllowUndefinedAsNaN); | |
| 1361 } | |
| 1362 | 1368 |
| 1363 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1369 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 1364 return Representation::None(); | 1370 return Representation::None(); |
| 1365 } | 1371 } |
| 1366 virtual Representation observed_input_representation(int index) V8_OVERRIDE; | 1372 virtual Representation observed_input_representation(int index) V8_OVERRIDE; |
| 1367 | 1373 |
| 1368 ToBooleanStub::Types expected_input_types() const { | 1374 ToBooleanStub::Types expected_input_types() const { |
| 1369 return expected_input_types_; | 1375 return expected_input_types_; |
| 1370 } | 1376 } |
| 1371 | 1377 |
| 1372 DECLARE_CONCRETE_INSTRUCTION(Branch) | 1378 DECLARE_CONCRETE_INSTRUCTION(Branch) |
| 1373 | 1379 |
| 1374 private: | 1380 private: |
| 1381 HBranch(HValue* value, |
| 1382 ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), |
| 1383 HBasicBlock* true_target = NULL, |
| 1384 HBasicBlock* false_target = NULL) |
| 1385 : HUnaryControlInstruction(value, true_target, false_target), |
| 1386 expected_input_types_(expected_input_types) { |
| 1387 SetFlag(kAllowUndefinedAsNaN); |
| 1388 } |
| 1389 |
| 1375 ToBooleanStub::Types expected_input_types_; | 1390 ToBooleanStub::Types expected_input_types_; |
| 1376 }; | 1391 }; |
| 1377 | 1392 |
| 1378 | 1393 |
| 1379 class HCompareMap V8_FINAL : public HUnaryControlInstruction { | 1394 class HCompareMap V8_FINAL : public HUnaryControlInstruction { |
| 1380 public: | 1395 public: |
| 1381 HCompareMap(HValue* value, | 1396 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); |
| 1382 Handle<Map> map, | 1397 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, |
| 1383 HBasicBlock* true_target = NULL, | 1398 HBasicBlock*, HBasicBlock*); |
| 1384 HBasicBlock* false_target = NULL) | |
| 1385 : HUnaryControlInstruction(value, true_target, false_target), | |
| 1386 map_(map) { | |
| 1387 ASSERT(!map.is_null()); | |
| 1388 } | |
| 1389 | 1399 |
| 1390 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1400 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 1391 | 1401 |
| 1392 Handle<Map> map() const { return map_; } | 1402 Unique<Map> map() const { return map_; } |
| 1393 | 1403 |
| 1394 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1404 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 1395 return Representation::Tagged(); | 1405 return Representation::Tagged(); |
| 1396 } | 1406 } |
| 1397 | 1407 |
| 1398 DECLARE_CONCRETE_INSTRUCTION(CompareMap) | 1408 DECLARE_CONCRETE_INSTRUCTION(CompareMap) |
| 1399 | 1409 |
| 1400 protected: | 1410 protected: |
| 1401 virtual int RedefinedOperandIndex() { return 0; } | 1411 virtual int RedefinedOperandIndex() { return 0; } |
| 1402 | 1412 |
| 1403 private: | 1413 private: |
| 1404 Handle<Map> map_; | 1414 HCompareMap(HValue* value, |
| 1415 Handle<Map> map, |
| 1416 HBasicBlock* true_target = NULL, |
| 1417 HBasicBlock* false_target = NULL) |
| 1418 : HUnaryControlInstruction(value, true_target, false_target), |
| 1419 map_(Unique<Map>(map)) { |
| 1420 ASSERT(!map.is_null()); |
| 1421 } |
| 1422 |
| 1423 Unique<Map> map_; |
| 1405 }; | 1424 }; |
| 1406 | 1425 |
| 1407 | 1426 |
| 1408 class HContext V8_FINAL : public HTemplateInstruction<0> { | 1427 class HContext V8_FINAL : public HTemplateInstruction<0> { |
| 1409 public: | 1428 public: |
| 1410 static HContext* New(Zone* zone) { | 1429 static HContext* New(Zone* zone) { |
| 1411 return new(zone) HContext(); | 1430 return new(zone) HContext(); |
| 1412 } | 1431 } |
| 1413 | 1432 |
| 1414 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1433 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| (...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2508 SetFlag(kUseGVN); | 2527 SetFlag(kUseGVN); |
| 2509 SetFlag(kAllowUndefinedAsNaN); | 2528 SetFlag(kAllowUndefinedAsNaN); |
| 2510 } | 2529 } |
| 2511 | 2530 |
| 2512 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 2531 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 2513 | 2532 |
| 2514 BuiltinFunctionId op_; | 2533 BuiltinFunctionId op_; |
| 2515 }; | 2534 }; |
| 2516 | 2535 |
| 2517 | 2536 |
| 2537 class HLoadRoot V8_FINAL : public HTemplateInstruction<0> { |
| 2538 public: |
| 2539 DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex); |
| 2540 DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType); |
| 2541 |
| 2542 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2543 return Representation::None(); |
| 2544 } |
| 2545 |
| 2546 Heap::RootListIndex index() const { return index_; } |
| 2547 |
| 2548 DECLARE_CONCRETE_INSTRUCTION(LoadRoot) |
| 2549 |
| 2550 protected: |
| 2551 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2552 HLoadRoot* b = HLoadRoot::cast(other); |
| 2553 return index_ == b->index_; |
| 2554 } |
| 2555 |
| 2556 private: |
| 2557 HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged()) |
| 2558 : HTemplateInstruction<0>(type), index_(index) { |
| 2559 SetFlag(kUseGVN); |
| 2560 // TODO(bmeurer): We'll need kDependsOnRoots once we add the |
| 2561 // corresponding HStoreRoot instruction. |
| 2562 SetGVNFlag(kDependsOnCalls); |
| 2563 } |
| 2564 |
| 2565 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 2566 |
| 2567 const Heap::RootListIndex index_; |
| 2568 }; |
| 2569 |
| 2570 |
| 2518 class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation { | 2571 class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation { |
| 2519 public: | 2572 public: |
| 2520 DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*); | 2573 DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*); |
| 2521 | 2574 |
| 2522 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2575 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2523 return Representation::Tagged(); | 2576 return Representation::Tagged(); |
| 2524 } | 2577 } |
| 2525 | 2578 |
| 2526 virtual HType CalculateInferredType() V8_OVERRIDE { | 2579 virtual HType CalculateInferredType() V8_OVERRIDE { |
| 2527 return HType::None(); | 2580 return HType::None(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2552 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, | 2605 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, |
| 2553 Handle<Map> map, CompilationInfo* info, | 2606 Handle<Map> map, CompilationInfo* info, |
| 2554 HValue *typecheck = NULL); | 2607 HValue *typecheck = NULL); |
| 2555 static HCheckMaps* New(Zone* zone, HValue* context, | 2608 static HCheckMaps* New(Zone* zone, HValue* context, |
| 2556 HValue* value, SmallMapList* maps, | 2609 HValue* value, SmallMapList* maps, |
| 2557 HValue *typecheck = NULL) { | 2610 HValue *typecheck = NULL) { |
| 2558 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 2611 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
| 2559 for (int i = 0; i < maps->length(); i++) { | 2612 for (int i = 0; i < maps->length(); i++) { |
| 2560 check_map->Add(maps->at(i), zone); | 2613 check_map->Add(maps->at(i), zone); |
| 2561 } | 2614 } |
| 2562 check_map->map_set_.Sort(); | |
| 2563 return check_map; | 2615 return check_map; |
| 2564 } | 2616 } |
| 2565 | 2617 |
| 2566 bool CanOmitMapChecks() { return omit_; } | 2618 bool CanOmitMapChecks() { return omit_; } |
| 2567 | 2619 |
| 2568 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2620 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
| 2569 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2621 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2570 return Representation::Tagged(); | 2622 return Representation::Tagged(); |
| 2571 } | 2623 } |
| 2572 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 2624 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
| 2573 HValue* dominator) V8_OVERRIDE; | 2625 HValue* dominator) V8_OVERRIDE; |
| 2574 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2626 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2575 | 2627 |
| 2576 HValue* value() { return OperandAt(0); } | 2628 HValue* value() { return OperandAt(0); } |
| 2577 SmallMapList* map_set() { return &map_set_; } | |
| 2578 ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; } | |
| 2579 | 2629 |
| 2580 bool has_migration_target() { | 2630 Unique<Map> first_map() const { return map_set_.at(0); } |
| 2631 UniqueSet<Map> map_set() const { return map_set_; } |
| 2632 |
| 2633 bool has_migration_target() const { |
| 2581 return has_migration_target_; | 2634 return has_migration_target_; |
| 2582 } | 2635 } |
| 2583 | 2636 |
| 2584 virtual void FinalizeUniqueValueId() V8_OVERRIDE; | |
| 2585 | |
| 2586 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2637 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
| 2587 | 2638 |
| 2588 protected: | 2639 protected: |
| 2589 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2640 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2590 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); | 2641 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); |
| 2591 HCheckMaps* b = HCheckMaps::cast(other); | |
| 2592 // Relies on the fact that map_set has been sorted before. | |
| 2593 if (map_unique_ids_.length() != b->map_unique_ids_.length()) { | |
| 2594 return false; | |
| 2595 } | |
| 2596 for (int i = 0; i < map_unique_ids_.length(); i++) { | |
| 2597 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { | |
| 2598 return false; | |
| 2599 } | |
| 2600 } | |
| 2601 return true; | |
| 2602 } | 2642 } |
| 2603 | 2643 |
| 2604 virtual int RedefinedOperandIndex() { return 0; } | 2644 virtual int RedefinedOperandIndex() { return 0; } |
| 2605 | 2645 |
| 2606 private: | 2646 private: |
| 2607 void Add(Handle<Map> map, Zone* zone) { | 2647 void Add(Handle<Map> map, Zone* zone) { |
| 2608 map_set_.Add(map, zone); | 2648 map_set_.Add(Unique<Map>(map), zone); |
| 2609 if (!has_migration_target_ && map->is_migration_target()) { | 2649 if (!has_migration_target_ && map->is_migration_target()) { |
| 2610 has_migration_target_ = true; | 2650 has_migration_target_ = true; |
| 2611 SetGVNFlag(kChangesNewSpacePromotion); | 2651 SetGVNFlag(kChangesNewSpacePromotion); |
| 2612 } | 2652 } |
| 2613 } | 2653 } |
| 2614 | 2654 |
| 2615 // Clients should use one of the static New* methods above. | 2655 // Clients should use one of the static New* methods above. |
| 2616 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) | 2656 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) |
| 2617 : HTemplateInstruction<2>(value->type()), | 2657 : HTemplateInstruction<2>(value->type()), |
| 2618 omit_(false), has_migration_target_(false), map_unique_ids_(0, zone) { | 2658 omit_(false), has_migration_target_(false) { |
| 2619 SetOperandAt(0, value); | 2659 SetOperandAt(0, value); |
| 2620 // Use the object value for the dependency if NULL is passed. | 2660 // Use the object value for the dependency if NULL is passed. |
| 2621 // TODO(titzer): do GVN flags already express this dependency? | |
| 2622 SetOperandAt(1, typecheck != NULL ? typecheck : value); | 2661 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
| 2623 set_representation(Representation::Tagged()); | 2662 set_representation(Representation::Tagged()); |
| 2624 SetFlag(kUseGVN); | 2663 SetFlag(kUseGVN); |
| 2625 SetFlag(kTrackSideEffectDominators); | 2664 SetFlag(kTrackSideEffectDominators); |
| 2626 SetGVNFlag(kDependsOnMaps); | 2665 SetGVNFlag(kDependsOnMaps); |
| 2627 SetGVNFlag(kDependsOnElementsKind); | 2666 SetGVNFlag(kDependsOnElementsKind); |
| 2628 } | 2667 } |
| 2629 | 2668 |
| 2630 void omit(CompilationInfo* info) { | |
| 2631 omit_ = true; | |
| 2632 for (int i = 0; i < map_set_.length(); i++) { | |
| 2633 Handle<Map> map = map_set_.at(i); | |
| 2634 if (!map->CanTransition()) continue; | |
| 2635 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, | |
| 2636 info); | |
| 2637 } | |
| 2638 } | |
| 2639 | |
| 2640 bool omit_; | 2669 bool omit_; |
| 2641 bool has_migration_target_; | 2670 bool has_migration_target_; |
| 2642 SmallMapList map_set_; | 2671 UniqueSet<Map> map_set_; |
| 2643 ZoneList<UniqueValueId> map_unique_ids_; | |
| 2644 }; | 2672 }; |
| 2645 | 2673 |
| 2646 | 2674 |
| 2647 class HCheckValue V8_FINAL : public HUnaryOperation { | 2675 class HCheckValue V8_FINAL : public HUnaryOperation { |
| 2648 public: | 2676 public: |
| 2649 static HCheckValue* New(Zone* zone, HValue* context, | 2677 static HCheckValue* New(Zone* zone, HValue* context, |
| 2650 HValue* value, Handle<JSFunction> target) { | 2678 HValue* value, Handle<JSFunction> func) { |
| 2651 bool in_new_space = zone->isolate()->heap()->InNewSpace(*target); | 2679 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); |
| 2680 // NOTE: We create an uninitialized Unique and initialize it later. |
| 2681 // This is because a JSFunction can move due to GC during graph creation. |
| 2682 // TODO(titzer): This is a migration crutch. Replace with some kind of |
| 2683 // Uniqueness scope later. |
| 2684 Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func); |
| 2652 HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); | 2685 HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); |
| 2653 return check; | 2686 return check; |
| 2654 } | 2687 } |
| 2655 static HCheckValue* New(Zone* zone, HValue* context, | 2688 static HCheckValue* New(Zone* zone, HValue* context, |
| 2656 HValue* value, Handle<Map> map, UniqueValueId id) { | 2689 HValue* value, Unique<HeapObject> target, |
| 2657 HCheckValue* check = new(zone) HCheckValue(value, map, false); | 2690 bool object_in_new_space) { |
| 2658 check->object_unique_id_ = id; | 2691 return new(zone) HCheckValue(value, target, object_in_new_space); |
| 2659 return check; | 2692 } |
| 2693 |
| 2694 virtual void FinalizeUniqueValueId() V8_OVERRIDE { |
| 2695 object_ = Unique<HeapObject>(object_.handle()); |
| 2660 } | 2696 } |
| 2661 | 2697 |
| 2662 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2698 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2663 return Representation::Tagged(); | 2699 return Representation::Tagged(); |
| 2664 } | 2700 } |
| 2665 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2701 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2666 | 2702 |
| 2667 virtual HValue* Canonicalize() V8_OVERRIDE; | 2703 virtual HValue* Canonicalize() V8_OVERRIDE; |
| 2668 | 2704 |
| 2669 #ifdef DEBUG | 2705 #ifdef DEBUG |
| 2670 virtual void Verify() V8_OVERRIDE; | 2706 virtual void Verify() V8_OVERRIDE; |
| 2671 #endif | 2707 #endif |
| 2672 | 2708 |
| 2673 virtual void FinalizeUniqueValueId() V8_OVERRIDE { | 2709 Unique<HeapObject> object() const { return object_; } |
| 2674 object_unique_id_ = UniqueValueId(object_); | |
| 2675 } | |
| 2676 | |
| 2677 Handle<HeapObject> object() const { return object_; } | |
| 2678 bool object_in_new_space() const { return object_in_new_space_; } | 2710 bool object_in_new_space() const { return object_in_new_space_; } |
| 2679 | 2711 |
| 2680 DECLARE_CONCRETE_INSTRUCTION(CheckValue) | 2712 DECLARE_CONCRETE_INSTRUCTION(CheckValue) |
| 2681 | 2713 |
| 2682 protected: | 2714 protected: |
| 2683 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2715 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2684 HCheckValue* b = HCheckValue::cast(other); | 2716 HCheckValue* b = HCheckValue::cast(other); |
| 2685 return object_unique_id_ == b->object_unique_id_; | 2717 return object_ == b->object_; |
| 2686 } | 2718 } |
| 2687 | 2719 |
| 2688 private: | 2720 private: |
| 2689 HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space) | 2721 HCheckValue(HValue* value, Unique<HeapObject> object, |
| 2722 bool object_in_new_space) |
| 2690 : HUnaryOperation(value, value->type()), | 2723 : HUnaryOperation(value, value->type()), |
| 2691 object_(object), object_in_new_space_(in_new_space) { | 2724 object_(object), |
| 2725 object_in_new_space_(object_in_new_space) { |
| 2692 set_representation(Representation::Tagged()); | 2726 set_representation(Representation::Tagged()); |
| 2693 SetFlag(kUseGVN); | 2727 SetFlag(kUseGVN); |
| 2694 } | 2728 } |
| 2695 | 2729 |
| 2696 Handle<HeapObject> object_; | 2730 Unique<HeapObject> object_; |
| 2697 UniqueValueId object_unique_id_; | |
| 2698 bool object_in_new_space_; | 2731 bool object_in_new_space_; |
| 2699 }; | 2732 }; |
| 2700 | 2733 |
| 2701 | 2734 |
| 2702 class HCheckInstanceType V8_FINAL : public HUnaryOperation { | 2735 class HCheckInstanceType V8_FINAL : public HUnaryOperation { |
| 2703 public: | 2736 public: |
| 2704 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { | 2737 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { |
| 2705 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); | 2738 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); |
| 2706 } | 2739 } |
| 2707 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { | 2740 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2783 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 2816 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
| 2784 | 2817 |
| 2785 private: | 2818 private: |
| 2786 explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) { | 2819 explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) { |
| 2787 set_representation(Representation::Smi()); | 2820 set_representation(Representation::Smi()); |
| 2788 SetFlag(kUseGVN); | 2821 SetFlag(kUseGVN); |
| 2789 } | 2822 } |
| 2790 }; | 2823 }; |
| 2791 | 2824 |
| 2792 | 2825 |
| 2793 class HIsNumberAndBranch V8_FINAL : public HUnaryControlInstruction { | |
| 2794 public: | |
| 2795 explicit HIsNumberAndBranch(HValue* value) | |
| 2796 : HUnaryControlInstruction(value, NULL, NULL) { | |
| 2797 SetFlag(kFlexibleRepresentation); | |
| 2798 } | |
| 2799 | |
| 2800 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | |
| 2801 return Representation::None(); | |
| 2802 } | |
| 2803 | |
| 2804 DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch) | |
| 2805 }; | |
| 2806 | |
| 2807 | |
| 2808 class HCheckHeapObject V8_FINAL : public HUnaryOperation { | 2826 class HCheckHeapObject V8_FINAL : public HUnaryOperation { |
| 2809 public: | 2827 public: |
| 2810 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); | 2828 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); |
| 2811 | 2829 |
| 2812 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2830 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
| 2813 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2831 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2814 return Representation::Tagged(); | 2832 return Representation::Tagged(); |
| 2815 } | 2833 } |
| 2816 | 2834 |
| 2817 #ifdef DEBUG | 2835 #ifdef DEBUG |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3349 | 3367 |
| 3350 ASSERT(!handle_.is_null()); | 3368 ASSERT(!handle_.is_null()); |
| 3351 Heap* heap = isolate()->heap(); | 3369 Heap* heap = isolate()->heap(); |
| 3352 ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap)); | 3370 ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap)); |
| 3353 ASSERT(unique_id_ != UniqueValueId::nan_value(heap)); | 3371 ASSERT(unique_id_ != UniqueValueId::nan_value(heap)); |
| 3354 return unique_id_ == UniqueValueId::undefined_value(heap) || | 3372 return unique_id_ == UniqueValueId::undefined_value(heap) || |
| 3355 unique_id_ == UniqueValueId::null_value(heap) || | 3373 unique_id_ == UniqueValueId::null_value(heap) || |
| 3356 unique_id_ == UniqueValueId::true_value(heap) || | 3374 unique_id_ == UniqueValueId::true_value(heap) || |
| 3357 unique_id_ == UniqueValueId::false_value(heap) || | 3375 unique_id_ == UniqueValueId::false_value(heap) || |
| 3358 unique_id_ == UniqueValueId::the_hole_value(heap) || | 3376 unique_id_ == UniqueValueId::the_hole_value(heap) || |
| 3359 unique_id_ == UniqueValueId::empty_string(heap); | 3377 unique_id_ == UniqueValueId::empty_string(heap) || |
| 3378 unique_id_ == UniqueValueId::empty_fixed_array(heap); |
| 3360 } | 3379 } |
| 3361 | 3380 |
| 3362 bool IsCell() const { | 3381 bool IsCell() const { |
| 3363 return is_cell_; | 3382 return is_cell_; |
| 3364 } | 3383 } |
| 3365 | 3384 |
| 3366 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 3385 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 3367 return Representation::None(); | 3386 return Representation::None(); |
| 3368 } | 3387 } |
| 3369 | 3388 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3450 ASSERT(!handle_.is_null()); | 3469 ASSERT(!handle_.is_null()); |
| 3451 unique_id_ = UniqueValueId(handle_); | 3470 unique_id_ = UniqueValueId(handle_); |
| 3452 } | 3471 } |
| 3453 } | 3472 } |
| 3454 | 3473 |
| 3455 bool UniqueValueIdsMatch(UniqueValueId other) { | 3474 bool UniqueValueIdsMatch(UniqueValueId other) { |
| 3456 return !has_double_value_ && !has_external_reference_value_ && | 3475 return !has_double_value_ && !has_external_reference_value_ && |
| 3457 unique_id_ == other; | 3476 unique_id_ == other; |
| 3458 } | 3477 } |
| 3459 | 3478 |
| 3479 Unique<Object> GetUnique() const { |
| 3480 // TODO(titzer): store a Unique<HeapObject> inside the HConstant. |
| 3481 Address raw_address = reinterpret_cast<Address>(unique_id_.Hashcode()); |
| 3482 return Unique<Object>(raw_address, handle_); |
| 3483 } |
| 3484 |
| 3460 #ifdef DEBUG | 3485 #ifdef DEBUG |
| 3461 virtual void Verify() V8_OVERRIDE { } | 3486 virtual void Verify() V8_OVERRIDE { } |
| 3462 #endif | 3487 #endif |
| 3463 | 3488 |
| 3464 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3489 DECLARE_CONCRETE_INSTRUCTION(Constant) |
| 3465 | 3490 |
| 3466 protected: | 3491 protected: |
| 3467 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; | 3492 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
| 3468 | 3493 |
| 3469 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 3494 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3881 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, | 3906 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, |
| 3882 HType type = HType::Tagged()) | 3907 HType type = HType::Tagged()) |
| 3883 : HBinaryOperation(context, left, right, type) { | 3908 : HBinaryOperation(context, left, right, type) { |
| 3884 SetFlag(kFlexibleRepresentation); | 3909 SetFlag(kFlexibleRepresentation); |
| 3885 SetFlag(kTruncatingToInt32); | 3910 SetFlag(kTruncatingToInt32); |
| 3886 SetFlag(kAllowUndefinedAsNaN); | 3911 SetFlag(kAllowUndefinedAsNaN); |
| 3887 SetAllSideEffects(); | 3912 SetAllSideEffects(); |
| 3888 } | 3913 } |
| 3889 | 3914 |
| 3890 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { | 3915 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { |
| 3891 if (!to.IsTagged()) { | 3916 if (to.IsTagged()) { |
| 3917 SetAllSideEffects(); |
| 3918 ClearFlag(kUseGVN); |
| 3919 } else { |
| 3892 ASSERT(to.IsSmiOrInteger32()); | 3920 ASSERT(to.IsSmiOrInteger32()); |
| 3893 ClearAllSideEffects(); | 3921 ClearAllSideEffects(); |
| 3894 SetFlag(kUseGVN); | 3922 SetFlag(kUseGVN); |
| 3895 } else { | |
| 3896 SetAllSideEffects(); | |
| 3897 ClearFlag(kUseGVN); | |
| 3898 } | 3923 } |
| 3899 } | 3924 } |
| 3900 | 3925 |
| 3901 virtual void UpdateRepresentation(Representation new_rep, | 3926 virtual void UpdateRepresentation(Representation new_rep, |
| 3902 HInferRepresentationPhase* h_infer, | 3927 HInferRepresentationPhase* h_infer, |
| 3903 const char* reason) V8_OVERRIDE { | 3928 const char* reason) V8_OVERRIDE { |
| 3904 // We only generate either int32 or generic tagged bitwise operations. | 3929 // We only generate either int32 or generic tagged bitwise operations. |
| 3905 if (new_rep.IsDouble()) new_rep = Representation::Integer32(); | 3930 if (new_rep.IsDouble()) new_rep = Representation::Integer32(); |
| 3906 HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | 3931 HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 3907 } | 3932 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4007 | 4032 |
| 4008 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) | 4033 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) |
| 4009 | 4034 |
| 4010 private: | 4035 private: |
| 4011 Token::Value token_; | 4036 Token::Value token_; |
| 4012 }; | 4037 }; |
| 4013 | 4038 |
| 4014 | 4039 |
| 4015 class HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> { | 4040 class HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> { |
| 4016 public: | 4041 public: |
| 4017 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token) | 4042 DECLARE_INSTRUCTION_FACTORY_P3(HCompareNumericAndBranch, |
| 4018 : token_(token) { | 4043 HValue*, HValue*, Token::Value); |
| 4019 SetFlag(kFlexibleRepresentation); | 4044 DECLARE_INSTRUCTION_FACTORY_P5(HCompareNumericAndBranch, |
| 4020 ASSERT(Token::IsCompareOp(token)); | 4045 HValue*, HValue*, Token::Value, |
| 4021 SetOperandAt(0, left); | 4046 HBasicBlock*, HBasicBlock*); |
| 4022 SetOperandAt(1, right); | |
| 4023 } | |
| 4024 | 4047 |
| 4025 HValue* left() { return OperandAt(0); } | 4048 HValue* left() { return OperandAt(0); } |
| 4026 HValue* right() { return OperandAt(1); } | 4049 HValue* right() { return OperandAt(1); } |
| 4027 Token::Value token() const { return token_; } | 4050 Token::Value token() const { return token_; } |
| 4028 | 4051 |
| 4029 void set_observed_input_representation(Representation left, | 4052 void set_observed_input_representation(Representation left, |
| 4030 Representation right) { | 4053 Representation right) { |
| 4031 observed_input_representation_[0] = left; | 4054 observed_input_representation_[0] = left; |
| 4032 observed_input_representation_[1] = right; | 4055 observed_input_representation_[1] = right; |
| 4033 } | 4056 } |
| 4034 | 4057 |
| 4035 virtual void InferRepresentation( | 4058 virtual void InferRepresentation( |
| 4036 HInferRepresentationPhase* h_infer) V8_OVERRIDE; | 4059 HInferRepresentationPhase* h_infer) V8_OVERRIDE; |
| 4037 | 4060 |
| 4038 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4061 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4039 return representation(); | 4062 return representation(); |
| 4040 } | 4063 } |
| 4041 virtual Representation observed_input_representation(int index) V8_OVERRIDE { | 4064 virtual Representation observed_input_representation(int index) V8_OVERRIDE { |
| 4042 return observed_input_representation_[index]; | 4065 return observed_input_representation_[index]; |
| 4043 } | 4066 } |
| 4044 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 4067 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 4045 | 4068 |
| 4046 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) | 4069 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
| 4047 | 4070 |
| 4048 private: | 4071 private: |
| 4072 HCompareNumericAndBranch(HValue* left, |
| 4073 HValue* right, |
| 4074 Token::Value token, |
| 4075 HBasicBlock* true_target = NULL, |
| 4076 HBasicBlock* false_target = NULL) |
| 4077 : token_(token) { |
| 4078 SetFlag(kFlexibleRepresentation); |
| 4079 ASSERT(Token::IsCompareOp(token)); |
| 4080 SetOperandAt(0, left); |
| 4081 SetOperandAt(1, right); |
| 4082 SetSuccessorAt(0, true_target); |
| 4083 SetSuccessorAt(1, false_target); |
| 4084 } |
| 4085 |
| 4049 Representation observed_input_representation_[2]; | 4086 Representation observed_input_representation_[2]; |
| 4050 Token::Value token_; | 4087 Token::Value token_; |
| 4051 }; | 4088 }; |
| 4052 | 4089 |
| 4053 | 4090 |
| 4054 class HCompareHoleAndBranch V8_FINAL | 4091 class HCompareHoleAndBranch V8_FINAL : public HUnaryControlInstruction { |
| 4055 : public HTemplateControlInstruction<2, 1> { | |
| 4056 public: | 4092 public: |
| 4057 // TODO(danno): make this private when the IfBuilder properly constructs | |
| 4058 // control flow instructions. | |
| 4059 explicit HCompareHoleAndBranch(HValue* object) { | |
| 4060 SetFlag(kFlexibleRepresentation); | |
| 4061 SetFlag(kAllowUndefinedAsNaN); | |
| 4062 SetOperandAt(0, object); | |
| 4063 } | |
| 4064 | |
| 4065 DECLARE_INSTRUCTION_FACTORY_P1(HCompareHoleAndBranch, HValue*); | 4093 DECLARE_INSTRUCTION_FACTORY_P1(HCompareHoleAndBranch, HValue*); |
| 4066 | 4094 DECLARE_INSTRUCTION_FACTORY_P3(HCompareHoleAndBranch, HValue*, |
| 4067 HValue* object() { return OperandAt(0); } | 4095 HBasicBlock*, HBasicBlock*); |
| 4068 | 4096 |
| 4069 virtual void InferRepresentation( | 4097 virtual void InferRepresentation( |
| 4070 HInferRepresentationPhase* h_infer) V8_OVERRIDE; | 4098 HInferRepresentationPhase* h_infer) V8_OVERRIDE; |
| 4071 | 4099 |
| 4072 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4100 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4073 return representation(); | 4101 return representation(); |
| 4074 } | 4102 } |
| 4075 | 4103 |
| 4076 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 4104 DECLARE_CONCRETE_INSTRUCTION(CompareHoleAndBranch) |
| 4077 | 4105 |
| 4078 DECLARE_CONCRETE_INSTRUCTION(CompareHoleAndBranch) | 4106 private: |
| 4107 HCompareHoleAndBranch(HValue* value, |
| 4108 HBasicBlock* true_target = NULL, |
| 4109 HBasicBlock* false_target = NULL) |
| 4110 : HUnaryControlInstruction(value, true_target, false_target) { |
| 4111 SetFlag(kFlexibleRepresentation); |
| 4112 SetFlag(kAllowUndefinedAsNaN); |
| 4113 } |
| 4079 }; | 4114 }; |
| 4080 | 4115 |
| 4081 | 4116 |
| 4082 class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> { | 4117 class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> { |
| 4083 public: | 4118 public: |
| 4084 // TODO(danno): make this private when the IfBuilder properly constructs | |
| 4085 // control flow instructions. | |
| 4086 HCompareObjectEqAndBranch(HValue* left, | |
| 4087 HValue* right) { | |
| 4088 SetOperandAt(0, left); | |
| 4089 SetOperandAt(1, right); | |
| 4090 } | |
| 4091 | |
| 4092 DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); | 4119 DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); |
| 4120 DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*, |
| 4121 HBasicBlock*, HBasicBlock*); |
| 4093 | 4122 |
| 4094 HValue* left() { return OperandAt(0); } | 4123 HValue* left() { return OperandAt(0); } |
| 4095 HValue* right() { return OperandAt(1); } | 4124 HValue* right() { return OperandAt(1); } |
| 4096 | 4125 |
| 4097 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 4126 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 4098 | 4127 |
| 4099 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4128 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4100 return Representation::Tagged(); | 4129 return Representation::Tagged(); |
| 4101 } | 4130 } |
| 4102 | 4131 |
| 4103 virtual Representation observed_input_representation(int index) V8_OVERRIDE { | 4132 virtual Representation observed_input_representation(int index) V8_OVERRIDE { |
| 4104 return Representation::Tagged(); | 4133 return Representation::Tagged(); |
| 4105 } | 4134 } |
| 4106 | 4135 |
| 4107 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch) | 4136 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch) |
| 4137 |
| 4138 private: |
| 4139 HCompareObjectEqAndBranch(HValue* left, |
| 4140 HValue* right, |
| 4141 HBasicBlock* true_target = NULL, |
| 4142 HBasicBlock* false_target = NULL) { |
| 4143 SetOperandAt(0, left); |
| 4144 SetOperandAt(1, right); |
| 4145 SetSuccessorAt(0, true_target); |
| 4146 SetSuccessorAt(1, false_target); |
| 4147 } |
| 4108 }; | 4148 }; |
| 4109 | 4149 |
| 4110 | 4150 |
| 4111 class HIsObjectAndBranch V8_FINAL : public HUnaryControlInstruction { | 4151 class HIsObjectAndBranch V8_FINAL : public HUnaryControlInstruction { |
| 4112 public: | 4152 public: |
| 4113 explicit HIsObjectAndBranch(HValue* value) | 4153 DECLARE_INSTRUCTION_FACTORY_P1(HIsObjectAndBranch, HValue*); |
| 4114 : HUnaryControlInstruction(value, NULL, NULL) { } | 4154 DECLARE_INSTRUCTION_FACTORY_P3(HIsObjectAndBranch, HValue*, |
| 4155 HBasicBlock*, HBasicBlock*); |
| 4115 | 4156 |
| 4116 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4157 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4117 return Representation::Tagged(); | 4158 return Representation::Tagged(); |
| 4118 } | 4159 } |
| 4119 | 4160 |
| 4120 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch) | 4161 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch) |
| 4162 |
| 4163 private: |
| 4164 HIsObjectAndBranch(HValue* value, |
| 4165 HBasicBlock* true_target = NULL, |
| 4166 HBasicBlock* false_target = NULL) |
| 4167 : HUnaryControlInstruction(value, true_target, false_target) {} |
| 4121 }; | 4168 }; |
| 4122 | 4169 |
| 4170 |
| 4123 class HIsStringAndBranch V8_FINAL : public HUnaryControlInstruction { | 4171 class HIsStringAndBranch V8_FINAL : public HUnaryControlInstruction { |
| 4124 public: | 4172 public: |
| 4125 explicit HIsStringAndBranch(HValue* value) | 4173 DECLARE_INSTRUCTION_FACTORY_P1(HIsStringAndBranch, HValue*); |
| 4126 : HUnaryControlInstruction(value, NULL, NULL) { } | 4174 DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*, |
| 4175 HBasicBlock*, HBasicBlock*); |
| 4127 | 4176 |
| 4128 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4177 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4129 return Representation::Tagged(); | 4178 return Representation::Tagged(); |
| 4130 } | 4179 } |
| 4131 | 4180 |
| 4132 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch) | 4181 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch) |
| 4182 |
| 4183 private: |
| 4184 HIsStringAndBranch(HValue* value, |
| 4185 HBasicBlock* true_target = NULL, |
| 4186 HBasicBlock* false_target = NULL) |
| 4187 : HUnaryControlInstruction(value, true_target, false_target) {} |
| 4133 }; | 4188 }; |
| 4134 | 4189 |
| 4135 | 4190 |
| 4136 class HIsSmiAndBranch V8_FINAL : public HUnaryControlInstruction { | 4191 class HIsSmiAndBranch V8_FINAL : public HUnaryControlInstruction { |
| 4137 public: | 4192 public: |
| 4138 explicit HIsSmiAndBranch(HValue* value) | 4193 DECLARE_INSTRUCTION_FACTORY_P1(HIsSmiAndBranch, HValue*); |
| 4139 : HUnaryControlInstruction(value, NULL, NULL) { } | 4194 DECLARE_INSTRUCTION_FACTORY_P3(HIsSmiAndBranch, HValue*, |
| 4195 HBasicBlock*, HBasicBlock*); |
| 4140 | 4196 |
| 4141 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch) | 4197 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch) |
| 4142 | 4198 |
| 4143 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4199 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4144 return Representation::Tagged(); | 4200 return Representation::Tagged(); |
| 4145 } | 4201 } |
| 4146 | 4202 |
| 4147 protected: | 4203 protected: |
| 4148 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 4204 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
| 4205 |
| 4206 private: |
| 4207 HIsSmiAndBranch(HValue* value, |
| 4208 HBasicBlock* true_target = NULL, |
| 4209 HBasicBlock* false_target = NULL) |
| 4210 : HUnaryControlInstruction(value, true_target, false_target) {} |
| 4149 }; | 4211 }; |
| 4150 | 4212 |
| 4151 | 4213 |
| 4152 class HIsUndetectableAndBranch V8_FINAL : public HUnaryControlInstruction { | 4214 class HIsUndetectableAndBranch V8_FINAL : public HUnaryControlInstruction { |
| 4153 public: | 4215 public: |
| 4154 explicit HIsUndetectableAndBranch(HValue* value) | 4216 DECLARE_INSTRUCTION_FACTORY_P1(HIsUndetectableAndBranch, HValue*); |
| 4155 : HUnaryControlInstruction(value, NULL, NULL) { } | 4217 DECLARE_INSTRUCTION_FACTORY_P3(HIsUndetectableAndBranch, HValue*, |
| 4218 HBasicBlock*, HBasicBlock*); |
| 4156 | 4219 |
| 4157 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4220 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4158 return Representation::Tagged(); | 4221 return Representation::Tagged(); |
| 4159 } | 4222 } |
| 4160 | 4223 |
| 4161 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch) | 4224 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch) |
| 4225 |
| 4226 private: |
| 4227 HIsUndetectableAndBranch(HValue* value, |
| 4228 HBasicBlock* true_target = NULL, |
| 4229 HBasicBlock* false_target = NULL) |
| 4230 : HUnaryControlInstruction(value, true_target, false_target) {} |
| 4162 }; | 4231 }; |
| 4163 | 4232 |
| 4164 | 4233 |
| 4165 class HStringCompareAndBranch : public HTemplateControlInstruction<2, 3> { | 4234 class HStringCompareAndBranch : public HTemplateControlInstruction<2, 3> { |
| 4166 public: | 4235 public: |
| 4167 HStringCompareAndBranch(HValue* context, | 4236 HStringCompareAndBranch(HValue* context, |
| 4168 HValue* left, | 4237 HValue* left, |
| 4169 HValue* right, | 4238 HValue* right, |
| 4170 Token::Value token) | 4239 Token::Value token) |
| 4171 : token_(token) { | 4240 : token_(token) { |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4521 | 4590 |
| 4522 | 4591 |
| 4523 class HMul V8_FINAL : public HArithmeticBinaryOperation { | 4592 class HMul V8_FINAL : public HArithmeticBinaryOperation { |
| 4524 public: | 4593 public: |
| 4525 static HInstruction* New(Zone* zone, | 4594 static HInstruction* New(Zone* zone, |
| 4526 HValue* context, | 4595 HValue* context, |
| 4527 HValue* left, | 4596 HValue* left, |
| 4528 HValue* right); | 4597 HValue* right); |
| 4529 | 4598 |
| 4530 static HInstruction* NewImul(Zone* zone, | 4599 static HInstruction* NewImul(Zone* zone, |
| 4531 HValue* context, | 4600 HValue* context, |
| 4532 HValue* left, | 4601 HValue* left, |
| 4533 HValue* right) { | 4602 HValue* right) { |
| 4534 HMul* mul = new(zone) HMul(context, left, right); | 4603 HInstruction* instr = HMul::New(zone, context, left, right); |
| 4604 if (!instr->IsMul()) return instr; |
| 4605 HMul* mul = HMul::cast(instr); |
| 4535 // TODO(mstarzinger): Prevent bailout on minus zero for imul. | 4606 // TODO(mstarzinger): Prevent bailout on minus zero for imul. |
| 4536 mul->AssumeRepresentation(Representation::Integer32()); | 4607 mul->AssumeRepresentation(Representation::Integer32()); |
| 4537 mul->ClearFlag(HValue::kCanOverflow); | 4608 mul->ClearFlag(HValue::kCanOverflow); |
| 4538 return mul; | 4609 return mul; |
| 4539 } | 4610 } |
| 4540 | 4611 |
| 4541 virtual HValue* EnsureAndPropagateNotMinusZero( | 4612 virtual HValue* EnsureAndPropagateNotMinusZero( |
| 4542 BitVector* visited) V8_OVERRIDE; | 4613 BitVector* visited) V8_OVERRIDE; |
| 4543 | 4614 |
| 4544 virtual HValue* Canonicalize() V8_OVERRIDE; | 4615 virtual HValue* Canonicalize() V8_OVERRIDE; |
| (...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5600 | 5671 |
| 5601 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { | 5672 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { |
| 5602 return HObjectAccess( | 5673 return HObjectAccess( |
| 5603 kArrayLengths, | 5674 kArrayLengths, |
| 5604 JSArray::kLengthOffset, | 5675 JSArray::kLengthOffset, |
| 5605 IsFastElementsKind(elements_kind) && | 5676 IsFastElementsKind(elements_kind) && |
| 5606 FLAG_track_fields | 5677 FLAG_track_fields |
| 5607 ? Representation::Smi() : Representation::Tagged()); | 5678 ? Representation::Smi() : Representation::Tagged()); |
| 5608 } | 5679 } |
| 5609 | 5680 |
| 5681 static HObjectAccess ForTypedArrayLength() { |
| 5682 return HObjectAccess( |
| 5683 kInobject, |
| 5684 JSTypedArray::kLengthOffset, |
| 5685 Representation::Tagged()); |
| 5686 } |
| 5687 |
| 5610 static HObjectAccess ForAllocationSiteTransitionInfo() { | 5688 static HObjectAccess ForAllocationSiteTransitionInfo() { |
| 5611 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); | 5689 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); |
| 5612 } | 5690 } |
| 5613 | 5691 |
| 5692 static HObjectAccess ForAllocationSiteDependentCode() { |
| 5693 return HObjectAccess(kInobject, AllocationSite::kDependentCodeOffset); |
| 5694 } |
| 5695 |
| 5614 static HObjectAccess ForAllocationSiteWeakNext() { | 5696 static HObjectAccess ForAllocationSiteWeakNext() { |
| 5615 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); | 5697 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); |
| 5616 } | 5698 } |
| 5617 | 5699 |
| 5618 static HObjectAccess ForAllocationSiteList() { | 5700 static HObjectAccess ForAllocationSiteList() { |
| 5619 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); | 5701 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); |
| 5620 } | 5702 } |
| 5621 | 5703 |
| 5622 static HObjectAccess ForFixedArrayLength() { | 5704 static HObjectAccess ForFixedArrayLength() { |
| 5623 return HObjectAccess( | 5705 return HObjectAccess( |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6491 | 6573 |
| 6492 DECLARE_CONCRETE_INSTRUCTION(StringAdd) | 6574 DECLARE_CONCRETE_INSTRUCTION(StringAdd) |
| 6493 | 6575 |
| 6494 protected: | 6576 protected: |
| 6495 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 6577 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
| 6496 | 6578 |
| 6497 private: | 6579 private: |
| 6498 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) | 6580 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) |
| 6499 : HBinaryOperation(context, left, right, HType::String()), flags_(flags) { | 6581 : HBinaryOperation(context, left, right, HType::String()), flags_(flags) { |
| 6500 set_representation(Representation::Tagged()); | 6582 set_representation(Representation::Tagged()); |
| 6501 SetFlag(kUseGVN); | 6583 if (flags_ == STRING_ADD_CHECK_NONE) { |
| 6502 SetGVNFlag(kDependsOnMaps); | 6584 SetFlag(kUseGVN); |
| 6503 SetGVNFlag(kChangesNewSpacePromotion); | 6585 SetGVNFlag(kDependsOnMaps); |
| 6586 SetGVNFlag(kChangesNewSpacePromotion); |
| 6587 } else { |
| 6588 SetAllSideEffects(); |
| 6589 } |
| 6504 } | 6590 } |
| 6505 | 6591 |
| 6506 // No side-effects except possible allocation. | 6592 // No side-effects except possible allocation: |
| 6507 // NOTE: this instruction _does not_ call ToString() on its inputs. | 6593 // NOTE: this instruction does not call ToString() on its inputs, when flags_ |
| 6508 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6594 // is set to STRING_ADD_CHECK_NONE. |
| 6595 virtual bool IsDeletable() const V8_OVERRIDE { |
| 6596 return flags_ == STRING_ADD_CHECK_NONE; |
| 6597 } |
| 6509 | 6598 |
| 6510 const StringAddFlags flags_; | 6599 const StringAddFlags flags_; |
| 6511 }; | 6600 }; |
| 6512 | 6601 |
| 6513 | 6602 |
| 6514 class HStringCharCodeAt V8_FINAL : public HTemplateInstruction<3> { | 6603 class HStringCharCodeAt V8_FINAL : public HTemplateInstruction<3> { |
| 6515 public: | 6604 public: |
| 6516 static HStringCharCodeAt* New(Zone* zone, | 6605 static HStringCharCodeAt* New(Zone* zone, |
| 6517 HValue* context, | 6606 HValue* context, |
| 6518 HValue* string, | 6607 HValue* string, |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6752 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { | 6841 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { |
| 6753 set_representation(Representation::Tagged()); | 6842 set_representation(Representation::Tagged()); |
| 6754 SetGVNFlag(kChangesNewSpacePromotion); | 6843 SetGVNFlag(kChangesNewSpacePromotion); |
| 6755 | 6844 |
| 6756 // This instruction is not marked as kChangesMaps, but does | 6845 // This instruction is not marked as kChangesMaps, but does |
| 6757 // change the map of the input operand. Use it only when creating | 6846 // change the map of the input operand. Use it only when creating |
| 6758 // object literals via a runtime call. | 6847 // object literals via a runtime call. |
| 6759 ASSERT(value->IsCallRuntime()); | 6848 ASSERT(value->IsCallRuntime()); |
| 6760 #ifdef DEBUG | 6849 #ifdef DEBUG |
| 6761 const Runtime::Function* function = HCallRuntime::cast(value)->function(); | 6850 const Runtime::Function* function = HCallRuntime::cast(value)->function(); |
| 6762 ASSERT(function->function_id == Runtime::kCreateObjectLiteral || | 6851 ASSERT(function->function_id == Runtime::kCreateObjectLiteral); |
| 6763 function->function_id == Runtime::kCreateObjectLiteralShallow); | |
| 6764 #endif | 6852 #endif |
| 6765 } | 6853 } |
| 6766 | 6854 |
| 6767 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6855 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 6768 }; | 6856 }; |
| 6769 | 6857 |
| 6770 | 6858 |
| 6771 class HValueOf V8_FINAL : public HUnaryOperation { | 6859 class HValueOf V8_FINAL : public HUnaryOperation { |
| 6772 public: | 6860 public: |
| 6773 explicit HValueOf(HValue* value) : HUnaryOperation(value) { | 6861 explicit HValueOf(HValue* value) : HUnaryOperation(value) { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6975 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7063 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 6976 }; | 7064 }; |
| 6977 | 7065 |
| 6978 | 7066 |
| 6979 #undef DECLARE_INSTRUCTION | 7067 #undef DECLARE_INSTRUCTION |
| 6980 #undef DECLARE_CONCRETE_INSTRUCTION | 7068 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6981 | 7069 |
| 6982 } } // namespace v8::internal | 7070 } } // namespace v8::internal |
| 6983 | 7071 |
| 6984 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7072 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |