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 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2552 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, | 2553 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, |
2553 Handle<Map> map, CompilationInfo* info, | 2554 Handle<Map> map, CompilationInfo* info, |
2554 HValue *typecheck = NULL); | 2555 HValue *typecheck = NULL); |
2555 static HCheckMaps* New(Zone* zone, HValue* context, | 2556 static HCheckMaps* New(Zone* zone, HValue* context, |
2556 HValue* value, SmallMapList* maps, | 2557 HValue* value, SmallMapList* maps, |
2557 HValue *typecheck = NULL) { | 2558 HValue *typecheck = NULL) { |
2558 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 2559 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
2559 for (int i = 0; i < maps->length(); i++) { | 2560 for (int i = 0; i < maps->length(); i++) { |
2560 check_map->Add(maps->at(i), zone); | 2561 check_map->Add(maps->at(i), zone); |
2561 } | 2562 } |
2562 check_map->map_set_.Sort(); | |
2563 return check_map; | 2563 return check_map; |
2564 } | 2564 } |
2565 | 2565 |
2566 bool CanOmitMapChecks() { return omit_; } | 2566 bool CanOmitMapChecks() { return omit_; } |
2567 | 2567 |
2568 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2568 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
2569 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2569 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
2570 return Representation::Tagged(); | 2570 return Representation::Tagged(); |
2571 } | 2571 } |
2572 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 2572 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
2573 HValue* dominator) V8_OVERRIDE; | 2573 HValue* dominator) V8_OVERRIDE; |
2574 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2574 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2575 | 2575 |
2576 HValue* value() { return OperandAt(0); } | 2576 HValue* value() { return OperandAt(0); } |
2577 SmallMapList* map_set() { return &map_set_; } | |
2578 ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; } | |
2579 | 2577 |
2580 bool has_migration_target() { | 2578 Unique<Map> first_map() const { return map_set_.at(0); } |
2579 UniqueSet<Map> map_set() const { return map_set_; } | |
2580 | |
2581 bool has_migration_target() const { | |
2581 return has_migration_target_; | 2582 return has_migration_target_; |
2582 } | 2583 } |
2583 | 2584 |
2584 virtual void FinalizeUniqueValueId() V8_OVERRIDE; | |
2585 | |
2586 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2585 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
2587 | 2586 |
2588 protected: | 2587 protected: |
2589 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2588 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
2590 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); | 2589 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 } | 2590 } |
2603 | 2591 |
2604 virtual int RedefinedOperandIndex() { return 0; } | 2592 virtual int RedefinedOperandIndex() { return 0; } |
2605 | 2593 |
2606 private: | 2594 private: |
2607 void Add(Handle<Map> map, Zone* zone) { | 2595 void Add(Handle<Map> map, Zone* zone) { |
2608 map_set_.Add(map, zone); | 2596 map_set_.Add(Unique<Map>(map), zone); |
2609 if (!has_migration_target_ && map->is_migration_target()) { | 2597 if (!has_migration_target_ && map->is_migration_target()) { |
2610 has_migration_target_ = true; | 2598 has_migration_target_ = true; |
2611 SetGVNFlag(kChangesNewSpacePromotion); | 2599 SetGVNFlag(kChangesNewSpacePromotion); |
2612 } | 2600 } |
2613 } | 2601 } |
2614 | 2602 |
2615 // Clients should use one of the static New* methods above. | 2603 // Clients should use one of the static New* methods above. |
2616 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) | 2604 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) |
2617 : HTemplateInstruction<2>(value->type()), | 2605 : HTemplateInstruction<2>(value->type()), |
2618 omit_(false), has_migration_target_(false), map_unique_ids_(0, zone) { | 2606 omit_(false), has_migration_target_(false) { |
2619 SetOperandAt(0, value); | 2607 SetOperandAt(0, value); |
2620 // Use the object value for the dependency if NULL is passed. | 2608 // 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); | 2609 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
2623 set_representation(Representation::Tagged()); | 2610 set_representation(Representation::Tagged()); |
2624 SetFlag(kUseGVN); | 2611 SetFlag(kUseGVN); |
2625 SetFlag(kTrackSideEffectDominators); | 2612 SetFlag(kTrackSideEffectDominators); |
2626 SetGVNFlag(kDependsOnMaps); | 2613 SetGVNFlag(kDependsOnMaps); |
2627 SetGVNFlag(kDependsOnElementsKind); | 2614 SetGVNFlag(kDependsOnElementsKind); |
2628 } | 2615 } |
2629 | 2616 |
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_; | 2617 bool omit_; |
2641 bool has_migration_target_; | 2618 bool has_migration_target_; |
2642 SmallMapList map_set_; | 2619 UniqueSet<Map> map_set_; |
2643 ZoneList<UniqueValueId> map_unique_ids_; | |
2644 }; | 2620 }; |
2645 | 2621 |
2646 | 2622 |
2647 class HCheckValue V8_FINAL : public HUnaryOperation { | 2623 class HCheckValue V8_FINAL : public HUnaryOperation { |
2648 public: | 2624 public: |
2649 static HCheckValue* New(Zone* zone, HValue* context, | 2625 static HCheckValue* New(Zone* zone, HValue* context, |
2650 HValue* value, Handle<JSFunction> target) { | 2626 HValue* value, Handle<JSFunction> func) { |
2651 bool in_new_space = zone->isolate()->heap()->InNewSpace(*target); | 2627 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); |
2628 Unique<JSFunction> target(func); | |
Toon Verwaest
2013/09/17 10:37:24
Allocating this in the middle of graph-building is
| |
2652 HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); | 2629 HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); |
2653 return check; | 2630 return check; |
2654 } | 2631 } |
2655 static HCheckValue* New(Zone* zone, HValue* context, | 2632 static HCheckValue* New(Zone* zone, HValue* context, |
2656 HValue* value, Handle<Map> map, UniqueValueId id) { | 2633 HValue* value, Unique<HeapObject> target, |
2657 HCheckValue* check = new(zone) HCheckValue(value, map, false); | 2634 bool object_in_new_space) { |
2658 check->object_unique_id_ = id; | 2635 return new(zone) HCheckValue(value, target, object_in_new_space); |
2659 return check; | |
2660 } | 2636 } |
2661 | 2637 |
2662 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2638 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
2663 return Representation::Tagged(); | 2639 return Representation::Tagged(); |
2664 } | 2640 } |
2665 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2641 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2666 | 2642 |
2667 virtual HValue* Canonicalize() V8_OVERRIDE; | 2643 virtual HValue* Canonicalize() V8_OVERRIDE; |
2668 | 2644 |
2669 #ifdef DEBUG | 2645 #ifdef DEBUG |
2670 virtual void Verify() V8_OVERRIDE; | 2646 virtual void Verify() V8_OVERRIDE; |
2671 #endif | 2647 #endif |
2672 | 2648 |
2673 virtual void FinalizeUniqueValueId() V8_OVERRIDE { | 2649 Unique<HeapObject> object() const { return object_; } |
2674 object_unique_id_ = UniqueValueId(object_); | |
Toon Verwaest
2013/09/17 10:37:24
So I guess you'll have to do something like this a
| |
2675 } | |
2676 | |
2677 Handle<HeapObject> object() const { return object_; } | |
2678 bool object_in_new_space() const { return object_in_new_space_; } | 2650 bool object_in_new_space() const { return object_in_new_space_; } |
2679 | 2651 |
2680 DECLARE_CONCRETE_INSTRUCTION(CheckValue) | 2652 DECLARE_CONCRETE_INSTRUCTION(CheckValue) |
2681 | 2653 |
2682 protected: | 2654 protected: |
2683 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2655 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
2684 HCheckValue* b = HCheckValue::cast(other); | 2656 HCheckValue* b = HCheckValue::cast(other); |
2685 return object_unique_id_ == b->object_unique_id_; | 2657 return object_ == b->object_; |
2686 } | 2658 } |
2687 | 2659 |
2688 private: | 2660 private: |
2689 HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space) | 2661 HCheckValue(HValue* value, Unique<HeapObject> object, |
2662 bool object_in_new_space) | |
2690 : HUnaryOperation(value, value->type()), | 2663 : HUnaryOperation(value, value->type()), |
2691 object_(object), object_in_new_space_(in_new_space) { | 2664 object_(object), |
2665 object_in_new_space_(object_in_new_space) { | |
2692 set_representation(Representation::Tagged()); | 2666 set_representation(Representation::Tagged()); |
2693 SetFlag(kUseGVN); | 2667 SetFlag(kUseGVN); |
2694 } | 2668 } |
2695 | 2669 |
2696 Handle<HeapObject> object_; | 2670 Unique<HeapObject> object_; |
2697 UniqueValueId object_unique_id_; | |
2698 bool object_in_new_space_; | 2671 bool object_in_new_space_; |
2699 }; | 2672 }; |
2700 | 2673 |
2701 | 2674 |
2702 class HCheckInstanceType V8_FINAL : public HUnaryOperation { | 2675 class HCheckInstanceType V8_FINAL : public HUnaryOperation { |
2703 public: | 2676 public: |
2704 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { | 2677 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { |
2705 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); | 2678 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); |
2706 } | 2679 } |
2707 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { | 2680 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3450 ASSERT(!handle_.is_null()); | 3423 ASSERT(!handle_.is_null()); |
3451 unique_id_ = UniqueValueId(handle_); | 3424 unique_id_ = UniqueValueId(handle_); |
3452 } | 3425 } |
3453 } | 3426 } |
3454 | 3427 |
3455 bool UniqueValueIdsMatch(UniqueValueId other) { | 3428 bool UniqueValueIdsMatch(UniqueValueId other) { |
3456 return !has_double_value_ && !has_external_reference_value_ && | 3429 return !has_double_value_ && !has_external_reference_value_ && |
3457 unique_id_ == other; | 3430 unique_id_ == other; |
3458 } | 3431 } |
3459 | 3432 |
3433 Unique<Object> GetUnique() const { | |
3434 // TODO(titzer): store a Unique<HeapObject> inside the HConstant. | |
3435 Address raw_address = reinterpret_cast<Address>(unique_id_.Hashcode()); | |
3436 return Unique<Object>(raw_address, handle_); | |
3437 } | |
3438 | |
3460 #ifdef DEBUG | 3439 #ifdef DEBUG |
3461 virtual void Verify() V8_OVERRIDE { } | 3440 virtual void Verify() V8_OVERRIDE { } |
3462 #endif | 3441 #endif |
3463 | 3442 |
3464 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3443 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3465 | 3444 |
3466 protected: | 3445 protected: |
3467 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; | 3446 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
3468 | 3447 |
3469 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 3448 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
(...skipping 3505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6975 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6954 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
6976 }; | 6955 }; |
6977 | 6956 |
6978 | 6957 |
6979 #undef DECLARE_INSTRUCTION | 6958 #undef DECLARE_INSTRUCTION |
6980 #undef DECLARE_CONCRETE_INSTRUCTION | 6959 #undef DECLARE_CONCRETE_INSTRUCTION |
6981 | 6960 |
6982 } } // namespace v8::internal | 6961 } } // namespace v8::internal |
6983 | 6962 |
6984 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6963 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |