| 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 2502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2551 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, | 2552 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, |
| 2552 Handle<Map> map, CompilationInfo* info, | 2553 Handle<Map> map, CompilationInfo* info, |
| 2553 HValue *typecheck = NULL); | 2554 HValue *typecheck = NULL); |
| 2554 static HCheckMaps* New(Zone* zone, HValue* context, | 2555 static HCheckMaps* New(Zone* zone, HValue* context, |
| 2555 HValue* value, SmallMapList* maps, | 2556 HValue* value, SmallMapList* maps, |
| 2556 HValue *typecheck = NULL) { | 2557 HValue *typecheck = NULL) { |
| 2557 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 2558 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
| 2558 for (int i = 0; i < maps->length(); i++) { | 2559 for (int i = 0; i < maps->length(); i++) { |
| 2559 check_map->Add(maps->at(i), zone); | 2560 check_map->Add(maps->at(i), zone); |
| 2560 } | 2561 } |
| 2561 check_map->map_set_.Sort(); | |
| 2562 return check_map; | 2562 return check_map; |
| 2563 } | 2563 } |
| 2564 | 2564 |
| 2565 bool CanOmitMapChecks() { return omit_; } | 2565 bool CanOmitMapChecks() { return omit_; } |
| 2566 | 2566 |
| 2567 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2567 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
| 2568 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2568 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2569 return Representation::Tagged(); | 2569 return Representation::Tagged(); |
| 2570 } | 2570 } |
| 2571 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 2571 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
| 2572 HValue* dominator) V8_OVERRIDE; | 2572 HValue* dominator) V8_OVERRIDE; |
| 2573 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2573 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2574 | 2574 |
| 2575 HValue* value() { return OperandAt(0); } | 2575 HValue* value() { return OperandAt(0); } |
| 2576 SmallMapList* map_set() { return &map_set_; } | |
| 2577 ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; } | |
| 2578 | 2576 |
| 2579 bool has_migration_target() { | 2577 Unique<Map> first_map() const { return map_set_.at(0); } |
| 2578 UniqueSet<Map> map_set() const { return map_set_; } |
| 2579 |
| 2580 bool has_migration_target() const { |
| 2580 return has_migration_target_; | 2581 return has_migration_target_; |
| 2581 } | 2582 } |
| 2582 | 2583 |
| 2583 virtual void FinalizeUniqueValueId() V8_OVERRIDE; | |
| 2584 | |
| 2585 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2584 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
| 2586 | 2585 |
| 2587 protected: | 2586 protected: |
| 2588 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2587 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2589 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); | 2588 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); |
| 2590 HCheckMaps* b = HCheckMaps::cast(other); | |
| 2591 // Relies on the fact that map_set has been sorted before. | |
| 2592 if (map_unique_ids_.length() != b->map_unique_ids_.length()) { | |
| 2593 return false; | |
| 2594 } | |
| 2595 for (int i = 0; i < map_unique_ids_.length(); i++) { | |
| 2596 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { | |
| 2597 return false; | |
| 2598 } | |
| 2599 } | |
| 2600 return true; | |
| 2601 } | 2589 } |
| 2602 | 2590 |
| 2603 virtual int RedefinedOperandIndex() { return 0; } | 2591 virtual int RedefinedOperandIndex() { return 0; } |
| 2604 | 2592 |
| 2605 private: | 2593 private: |
| 2606 void Add(Handle<Map> map, Zone* zone) { | 2594 void Add(Handle<Map> map, Zone* zone) { |
| 2607 map_set_.Add(map, zone); | 2595 map_set_.Add(Unique<Map>(map), zone); |
| 2608 if (!has_migration_target_ && map->is_migration_target()) { | 2596 if (!has_migration_target_ && map->is_migration_target()) { |
| 2609 has_migration_target_ = true; | 2597 has_migration_target_ = true; |
| 2610 SetGVNFlag(kChangesNewSpacePromotion); | 2598 SetGVNFlag(kChangesNewSpacePromotion); |
| 2611 } | 2599 } |
| 2612 } | 2600 } |
| 2613 | 2601 |
| 2614 // Clients should use one of the static New* methods above. | 2602 // Clients should use one of the static New* methods above. |
| 2615 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) | 2603 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) |
| 2616 : HTemplateInstruction<2>(value->type()), | 2604 : HTemplateInstruction<2>(value->type()), |
| 2617 omit_(false), has_migration_target_(false), map_unique_ids_(0, zone) { | 2605 omit_(false), has_migration_target_(false) { |
| 2618 SetOperandAt(0, value); | 2606 SetOperandAt(0, value); |
| 2619 // Use the object value for the dependency if NULL is passed. | 2607 // Use the object value for the dependency if NULL is passed. |
| 2620 // TODO(titzer): do GVN flags already express this dependency? | |
| 2621 SetOperandAt(1, typecheck != NULL ? typecheck : value); | 2608 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
| 2622 set_representation(Representation::Tagged()); | 2609 set_representation(Representation::Tagged()); |
| 2623 SetFlag(kUseGVN); | 2610 SetFlag(kUseGVN); |
| 2624 SetFlag(kTrackSideEffectDominators); | 2611 SetFlag(kTrackSideEffectDominators); |
| 2625 SetGVNFlag(kDependsOnMaps); | 2612 SetGVNFlag(kDependsOnMaps); |
| 2626 SetGVNFlag(kDependsOnElementsKind); | 2613 SetGVNFlag(kDependsOnElementsKind); |
| 2627 } | 2614 } |
| 2628 | 2615 |
| 2629 void omit(CompilationInfo* info) { | |
| 2630 omit_ = true; | |
| 2631 for (int i = 0; i < map_set_.length(); i++) { | |
| 2632 Handle<Map> map = map_set_.at(i); | |
| 2633 if (!map->CanTransition()) continue; | |
| 2634 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, | |
| 2635 info); | |
| 2636 } | |
| 2637 } | |
| 2638 | |
| 2639 bool omit_; | 2616 bool omit_; |
| 2640 bool has_migration_target_; | 2617 bool has_migration_target_; |
| 2641 SmallMapList map_set_; | 2618 UniqueSet<Map> map_set_; |
| 2642 ZoneList<UniqueValueId> map_unique_ids_; | |
| 2643 }; | 2619 }; |
| 2644 | 2620 |
| 2645 | 2621 |
| 2646 class HCheckValue V8_FINAL : public HUnaryOperation { | 2622 class HCheckValue V8_FINAL : public HUnaryOperation { |
| 2647 public: | 2623 public: |
| 2648 static HCheckValue* New(Zone* zone, HValue* context, | 2624 static HCheckValue* New(Zone* zone, HValue* context, |
| 2649 HValue* value, Handle<JSFunction> target) { | 2625 HValue* value, Handle<JSFunction> func) { |
| 2650 bool in_new_space = zone->isolate()->heap()->InNewSpace(*target); | 2626 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); |
| 2627 // NOTE: We create an uninitialized Unique and initialize it later. |
| 2628 // This is because a JSFunction can move due to GC during graph creation. |
| 2629 // TODO(titzer): This is a migration crutch. Replace with some kind of |
| 2630 // Uniqueness scope later. |
| 2631 Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func); |
| 2651 HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); | 2632 HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); |
| 2652 return check; | 2633 return check; |
| 2653 } | 2634 } |
| 2654 static HCheckValue* New(Zone* zone, HValue* context, | 2635 static HCheckValue* New(Zone* zone, HValue* context, |
| 2655 HValue* value, Handle<Map> map, UniqueValueId id) { | 2636 HValue* value, Unique<HeapObject> target, |
| 2656 HCheckValue* check = new(zone) HCheckValue(value, map, false); | 2637 bool object_in_new_space) { |
| 2657 check->object_unique_id_ = id; | 2638 return new(zone) HCheckValue(value, target, object_in_new_space); |
| 2658 return check; | 2639 } |
| 2640 |
| 2641 virtual void FinalizeUniqueValueId() V8_OVERRIDE { |
| 2642 object_ = Unique<HeapObject>(object_.handle()); |
| 2659 } | 2643 } |
| 2660 | 2644 |
| 2661 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2645 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2662 return Representation::Tagged(); | 2646 return Representation::Tagged(); |
| 2663 } | 2647 } |
| 2664 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2648 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2665 | 2649 |
| 2666 virtual HValue* Canonicalize() V8_OVERRIDE; | 2650 virtual HValue* Canonicalize() V8_OVERRIDE; |
| 2667 | 2651 |
| 2668 #ifdef DEBUG | 2652 #ifdef DEBUG |
| 2669 virtual void Verify() V8_OVERRIDE; | 2653 virtual void Verify() V8_OVERRIDE; |
| 2670 #endif | 2654 #endif |
| 2671 | 2655 |
| 2672 virtual void FinalizeUniqueValueId() V8_OVERRIDE { | 2656 Unique<HeapObject> object() const { return object_; } |
| 2673 object_unique_id_ = UniqueValueId(object_); | |
| 2674 } | |
| 2675 | |
| 2676 Handle<HeapObject> object() const { return object_; } | |
| 2677 bool object_in_new_space() const { return object_in_new_space_; } | 2657 bool object_in_new_space() const { return object_in_new_space_; } |
| 2678 | 2658 |
| 2679 DECLARE_CONCRETE_INSTRUCTION(CheckValue) | 2659 DECLARE_CONCRETE_INSTRUCTION(CheckValue) |
| 2680 | 2660 |
| 2681 protected: | 2661 protected: |
| 2682 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2662 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2683 HCheckValue* b = HCheckValue::cast(other); | 2663 HCheckValue* b = HCheckValue::cast(other); |
| 2684 return object_unique_id_ == b->object_unique_id_; | 2664 return object_ == b->object_; |
| 2685 } | 2665 } |
| 2686 | 2666 |
| 2687 private: | 2667 private: |
| 2688 HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space) | 2668 HCheckValue(HValue* value, Unique<HeapObject> object, |
| 2669 bool object_in_new_space) |
| 2689 : HUnaryOperation(value, value->type()), | 2670 : HUnaryOperation(value, value->type()), |
| 2690 object_(object), object_in_new_space_(in_new_space) { | 2671 object_(object), |
| 2672 object_in_new_space_(object_in_new_space) { |
| 2691 set_representation(Representation::Tagged()); | 2673 set_representation(Representation::Tagged()); |
| 2692 SetFlag(kUseGVN); | 2674 SetFlag(kUseGVN); |
| 2693 } | 2675 } |
| 2694 | 2676 |
| 2695 Handle<HeapObject> object_; | 2677 Unique<HeapObject> object_; |
| 2696 UniqueValueId object_unique_id_; | |
| 2697 bool object_in_new_space_; | 2678 bool object_in_new_space_; |
| 2698 }; | 2679 }; |
| 2699 | 2680 |
| 2700 | 2681 |
| 2701 class HCheckInstanceType V8_FINAL : public HUnaryOperation { | 2682 class HCheckInstanceType V8_FINAL : public HUnaryOperation { |
| 2702 public: | 2683 public: |
| 2703 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { | 2684 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { |
| 2704 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); | 2685 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); |
| 2705 } | 2686 } |
| 2706 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { | 2687 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3434 ASSERT(!handle_.is_null()); | 3415 ASSERT(!handle_.is_null()); |
| 3435 unique_id_ = UniqueValueId(handle_); | 3416 unique_id_ = UniqueValueId(handle_); |
| 3436 } | 3417 } |
| 3437 } | 3418 } |
| 3438 | 3419 |
| 3439 bool UniqueValueIdsMatch(UniqueValueId other) { | 3420 bool UniqueValueIdsMatch(UniqueValueId other) { |
| 3440 return !has_double_value_ && !has_external_reference_value_ && | 3421 return !has_double_value_ && !has_external_reference_value_ && |
| 3441 unique_id_ == other; | 3422 unique_id_ == other; |
| 3442 } | 3423 } |
| 3443 | 3424 |
| 3425 Unique<Object> GetUnique() const { |
| 3426 // TODO(titzer): store a Unique<HeapObject> inside the HConstant. |
| 3427 Address raw_address = reinterpret_cast<Address>(unique_id_.Hashcode()); |
| 3428 return Unique<Object>(raw_address, handle_); |
| 3429 } |
| 3430 |
| 3444 #ifdef DEBUG | 3431 #ifdef DEBUG |
| 3445 virtual void Verify() V8_OVERRIDE { } | 3432 virtual void Verify() V8_OVERRIDE { } |
| 3446 #endif | 3433 #endif |
| 3447 | 3434 |
| 3448 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3435 DECLARE_CONCRETE_INSTRUCTION(Constant) |
| 3449 | 3436 |
| 3450 protected: | 3437 protected: |
| 3451 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; | 3438 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
| 3452 | 3439 |
| 3453 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 3440 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| (...skipping 3505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6959 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6946 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 6960 }; | 6947 }; |
| 6961 | 6948 |
| 6962 | 6949 |
| 6963 #undef DECLARE_INSTRUCTION | 6950 #undef DECLARE_INSTRUCTION |
| 6964 #undef DECLARE_CONCRETE_INSTRUCTION | 6951 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6965 | 6952 |
| 6966 } } // namespace v8::internal | 6953 } } // namespace v8::internal |
| 6967 | 6954 |
| 6968 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6955 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |