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 |