Chromium Code Reviews| 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 |