OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "double.h" | 7 #include "double.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "hydrogen-infer-representation.h" | 9 #include "hydrogen-infer-representation.h" |
10 #include "property-details-inl.h" | 10 #include "property-details-inl.h" |
(...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1668 } | 1668 } |
1669 } | 1669 } |
1670 | 1670 |
1671 | 1671 |
1672 void HCheckMaps::PrintDataTo(StringStream* stream) { | 1672 void HCheckMaps::PrintDataTo(StringStream* stream) { |
1673 value()->PrintNameTo(stream); | 1673 value()->PrintNameTo(stream); |
1674 stream->Add(" [%p", *maps()->at(0).handle()); | 1674 stream->Add(" [%p", *maps()->at(0).handle()); |
1675 for (int i = 1; i < maps()->size(); ++i) { | 1675 for (int i = 1; i < maps()->size(); ++i) { |
1676 stream->Add(",%p", *maps()->at(i).handle()); | 1676 stream->Add(",%p", *maps()->at(i).handle()); |
1677 } | 1677 } |
1678 stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : ""); | 1678 stream->Add("]%s", IsStabilityCheck() ? "(stability-check)" : ""); |
1679 } | 1679 } |
1680 | 1680 |
1681 | 1681 |
| 1682 HValue* HCheckMaps::Canonicalize() { |
| 1683 if (!IsStabilityCheck() && maps_are_stable() && value()->IsConstant()) { |
| 1684 HConstant* c_value = HConstant::cast(value()); |
| 1685 if (c_value->HasObjectMap() && c_value->ObjectMapIsStable()) { |
| 1686 for (int i = 0; i < maps()->size(); ++i) { |
| 1687 if (c_value->ObjectMap() == maps()->at(i)) { |
| 1688 if (maps()->size() > 1) { |
| 1689 set_maps(new(block()->graph()->zone()) UniqueSet<Map>( |
| 1690 maps()->at(i), block()->graph()->zone())); |
| 1691 } |
| 1692 MarkAsStabilityCheck(); |
| 1693 break; |
| 1694 } |
| 1695 } |
| 1696 } |
| 1697 } |
| 1698 return this; |
| 1699 } |
| 1700 |
| 1701 |
1682 void HCheckValue::PrintDataTo(StringStream* stream) { | 1702 void HCheckValue::PrintDataTo(StringStream* stream) { |
1683 value()->PrintNameTo(stream); | 1703 value()->PrintNameTo(stream); |
1684 stream->Add(" "); | 1704 stream->Add(" "); |
1685 object().handle()->ShortPrint(stream); | 1705 object().handle()->ShortPrint(stream); |
1686 } | 1706 } |
1687 | 1707 |
1688 | 1708 |
1689 HValue* HCheckValue::Canonicalize() { | 1709 HValue* HCheckValue::Canonicalize() { |
1690 return (value()->IsConstant() && | 1710 return (value()->IsConstant() && |
1691 HConstant::cast(value())->EqualsUnique(object_)) ? NULL : this; | 1711 HConstant::cast(value())->EqualsUnique(object_)) ? NULL : this; |
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2654 stream->Add("%s, id=%d", name.get(), function()->id().ToInt()); | 2674 stream->Add("%s, id=%d", name.get(), function()->id().ToInt()); |
2655 } | 2675 } |
2656 | 2676 |
2657 | 2677 |
2658 static bool IsInteger32(double value) { | 2678 static bool IsInteger32(double value) { |
2659 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 2679 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
2660 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 2680 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
2661 } | 2681 } |
2662 | 2682 |
2663 | 2683 |
2664 HConstant::HConstant(Handle<Object> handle, Representation r) | 2684 HConstant::HConstant(Handle<Object> object, Representation r) |
2665 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), | 2685 : HTemplateInstruction<0>(HType::TypeFromValue(object)), |
2666 object_(Unique<Object>::CreateUninitialized(handle)), | 2686 object_(Unique<Object>::CreateUninitialized(object)), |
| 2687 object_map_(Handle<Map>::null()), |
| 2688 object_map_is_stable_(false), |
2667 has_smi_value_(false), | 2689 has_smi_value_(false), |
2668 has_int32_value_(false), | 2690 has_int32_value_(false), |
2669 has_double_value_(false), | 2691 has_double_value_(false), |
2670 has_external_reference_value_(false), | 2692 has_external_reference_value_(false), |
2671 is_not_in_new_space_(true), | 2693 is_not_in_new_space_(true), |
2672 boolean_value_(handle->BooleanValue()), | 2694 boolean_value_(object->BooleanValue()), |
2673 is_undetectable_(false), | 2695 is_undetectable_(false), |
2674 instance_type_(kUnknownInstanceType) { | 2696 instance_type_(kUnknownInstanceType) { |
2675 if (handle->IsHeapObject()) { | 2697 if (object->IsHeapObject()) { |
2676 Handle<HeapObject> heap_obj = Handle<HeapObject>::cast(handle); | 2698 Isolate* isolate = Handle<HeapObject>::cast(object)->GetIsolate(); |
2677 Heap* heap = heap_obj->GetHeap(); | 2699 Handle<Map> map(Handle<HeapObject>::cast(object)->map(), isolate); |
2678 is_not_in_new_space_ = !heap->InNewSpace(*handle); | 2700 is_not_in_new_space_ = !isolate->heap()->InNewSpace(*object); |
2679 instance_type_ = heap_obj->map()->instance_type(); | 2701 instance_type_ = map->instance_type(); |
2680 is_undetectable_ = heap_obj->map()->is_undetectable(); | 2702 is_undetectable_ = map->is_undetectable(); |
| 2703 object_map_ = Unique<Map>::CreateImmovable(map); |
| 2704 object_map_is_stable_ = map->is_stable(); |
2681 } | 2705 } |
2682 if (handle->IsNumber()) { | 2706 if (object->IsNumber()) { |
2683 double n = handle->Number(); | 2707 double n = object->Number(); |
2684 has_int32_value_ = IsInteger32(n); | 2708 has_int32_value_ = IsInteger32(n); |
2685 int32_value_ = DoubleToInt32(n); | 2709 int32_value_ = DoubleToInt32(n); |
2686 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2710 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2687 double_value_ = n; | 2711 double_value_ = n; |
2688 has_double_value_ = true; | 2712 has_double_value_ = true; |
2689 // TODO(titzer): if this heap number is new space, tenure a new one. | 2713 // TODO(titzer): if this heap number is new space, tenure a new one. |
2690 } | 2714 } |
2691 | 2715 |
2692 Initialize(r); | 2716 Initialize(r); |
2693 } | 2717 } |
2694 | 2718 |
2695 | 2719 |
2696 HConstant::HConstant(Unique<Object> unique, | 2720 HConstant::HConstant(Unique<Object> unique, |
2697 Representation r, | 2721 Representation r, |
2698 HType type, | 2722 HType type, |
2699 bool is_not_in_new_space, | 2723 bool is_not_in_new_space, |
2700 bool boolean_value, | 2724 bool boolean_value, |
2701 bool is_undetectable, | 2725 bool is_undetectable, |
2702 InstanceType instance_type) | 2726 InstanceType instance_type) |
2703 : HTemplateInstruction<0>(type), | 2727 : HTemplateInstruction<0>(type), |
2704 object_(unique), | 2728 object_(unique), |
| 2729 object_map_(Handle<Map>::null()), |
| 2730 object_map_is_stable_(false), |
2705 has_smi_value_(false), | 2731 has_smi_value_(false), |
2706 has_int32_value_(false), | 2732 has_int32_value_(false), |
2707 has_double_value_(false), | 2733 has_double_value_(false), |
2708 has_external_reference_value_(false), | 2734 has_external_reference_value_(false), |
2709 is_not_in_new_space_(is_not_in_new_space), | 2735 is_not_in_new_space_(is_not_in_new_space), |
2710 boolean_value_(boolean_value), | 2736 boolean_value_(boolean_value), |
2711 is_undetectable_(is_undetectable), | 2737 is_undetectable_(is_undetectable), |
2712 instance_type_(instance_type) { | 2738 instance_type_(instance_type) { |
2713 ASSERT(!unique.handle().is_null()); | 2739 ASSERT(!unique.handle().is_null()); |
2714 ASSERT(!type.IsTaggedNumber()); | 2740 ASSERT(!type.IsTaggedNumber()); |
2715 Initialize(r); | 2741 Initialize(r); |
2716 } | 2742 } |
2717 | 2743 |
2718 | 2744 |
2719 HConstant::HConstant(int32_t integer_value, | 2745 HConstant::HConstant(int32_t integer_value, |
2720 Representation r, | 2746 Representation r, |
2721 bool is_not_in_new_space, | 2747 bool is_not_in_new_space, |
2722 Unique<Object> object) | 2748 Unique<Object> object) |
2723 : object_(object), | 2749 : object_(object), |
| 2750 object_map_(Handle<Map>::null()), |
| 2751 object_map_is_stable_(false), |
2724 has_smi_value_(Smi::IsValid(integer_value)), | 2752 has_smi_value_(Smi::IsValid(integer_value)), |
2725 has_int32_value_(true), | 2753 has_int32_value_(true), |
2726 has_double_value_(true), | 2754 has_double_value_(true), |
2727 has_external_reference_value_(false), | 2755 has_external_reference_value_(false), |
2728 is_not_in_new_space_(is_not_in_new_space), | 2756 is_not_in_new_space_(is_not_in_new_space), |
2729 boolean_value_(integer_value != 0), | 2757 boolean_value_(integer_value != 0), |
2730 is_undetectable_(false), | 2758 is_undetectable_(false), |
2731 int32_value_(integer_value), | 2759 int32_value_(integer_value), |
2732 double_value_(FastI2D(integer_value)), | 2760 double_value_(FastI2D(integer_value)), |
2733 instance_type_(kUnknownInstanceType) { | 2761 instance_type_(kUnknownInstanceType) { |
2734 // It's possible to create a constant with a value in Smi-range but stored | 2762 // It's possible to create a constant with a value in Smi-range but stored |
2735 // in a (pre-existing) HeapNumber. See crbug.com/349878. | 2763 // in a (pre-existing) HeapNumber. See crbug.com/349878. |
2736 bool could_be_heapobject = r.IsTagged() && !object.handle().is_null(); | 2764 bool could_be_heapobject = r.IsTagged() && !object.handle().is_null(); |
2737 bool is_smi = has_smi_value_ && !could_be_heapobject; | 2765 bool is_smi = has_smi_value_ && !could_be_heapobject; |
2738 set_type(is_smi ? HType::Smi() : HType::TaggedNumber()); | 2766 set_type(is_smi ? HType::Smi() : HType::TaggedNumber()); |
2739 Initialize(r); | 2767 Initialize(r); |
2740 } | 2768 } |
2741 | 2769 |
2742 | 2770 |
2743 HConstant::HConstant(double double_value, | 2771 HConstant::HConstant(double double_value, |
2744 Representation r, | 2772 Representation r, |
2745 bool is_not_in_new_space, | 2773 bool is_not_in_new_space, |
2746 Unique<Object> object) | 2774 Unique<Object> object) |
2747 : object_(object), | 2775 : object_(object), |
| 2776 object_map_(Handle<Map>::null()), |
| 2777 object_map_is_stable_(false), |
2748 has_int32_value_(IsInteger32(double_value)), | 2778 has_int32_value_(IsInteger32(double_value)), |
2749 has_double_value_(true), | 2779 has_double_value_(true), |
2750 has_external_reference_value_(false), | 2780 has_external_reference_value_(false), |
2751 is_not_in_new_space_(is_not_in_new_space), | 2781 is_not_in_new_space_(is_not_in_new_space), |
2752 boolean_value_(double_value != 0 && !std::isnan(double_value)), | 2782 boolean_value_(double_value != 0 && !std::isnan(double_value)), |
2753 is_undetectable_(false), | 2783 is_undetectable_(false), |
2754 int32_value_(DoubleToInt32(double_value)), | 2784 int32_value_(DoubleToInt32(double_value)), |
2755 double_value_(double_value), | 2785 double_value_(double_value), |
2756 instance_type_(kUnknownInstanceType) { | 2786 instance_type_(kUnknownInstanceType) { |
2757 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2787 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2758 // It's possible to create a constant with a value in Smi-range but stored | 2788 // It's possible to create a constant with a value in Smi-range but stored |
2759 // in a (pre-existing) HeapNumber. See crbug.com/349878. | 2789 // in a (pre-existing) HeapNumber. See crbug.com/349878. |
2760 bool could_be_heapobject = r.IsTagged() && !object.handle().is_null(); | 2790 bool could_be_heapobject = r.IsTagged() && !object.handle().is_null(); |
2761 bool is_smi = has_smi_value_ && !could_be_heapobject; | 2791 bool is_smi = has_smi_value_ && !could_be_heapobject; |
2762 set_type(is_smi ? HType::Smi() : HType::TaggedNumber()); | 2792 set_type(is_smi ? HType::Smi() : HType::TaggedNumber()); |
2763 Initialize(r); | 2793 Initialize(r); |
2764 } | 2794 } |
2765 | 2795 |
2766 | 2796 |
2767 HConstant::HConstant(ExternalReference reference) | 2797 HConstant::HConstant(ExternalReference reference) |
2768 : HTemplateInstruction<0>(HType::None()), | 2798 : HTemplateInstruction<0>(HType::None()), |
2769 object_(Unique<Object>(Handle<Object>::null())), | 2799 object_(Unique<Object>(Handle<Object>::null())), |
| 2800 object_map_(Handle<Map>::null()), |
| 2801 object_map_is_stable_(false), |
2770 has_smi_value_(false), | 2802 has_smi_value_(false), |
2771 has_int32_value_(false), | 2803 has_int32_value_(false), |
2772 has_double_value_(false), | 2804 has_double_value_(false), |
2773 has_external_reference_value_(true), | 2805 has_external_reference_value_(true), |
2774 is_not_in_new_space_(true), | 2806 is_not_in_new_space_(true), |
2775 boolean_value_(true), | 2807 boolean_value_(true), |
2776 is_undetectable_(false), | 2808 is_undetectable_(false), |
2777 external_reference_value_(reference), | 2809 external_reference_value_(reference), |
2778 instance_type_(kUnknownInstanceType) { | 2810 instance_type_(kUnknownInstanceType) { |
2779 Initialize(Representation::External()); | 2811 Initialize(Representation::External()); |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3370 stream->Add("]"); | 3402 stream->Add("]"); |
3371 } | 3403 } |
3372 | 3404 |
3373 if (HasDependency()) { | 3405 if (HasDependency()) { |
3374 stream->Add(" "); | 3406 stream->Add(" "); |
3375 dependency()->PrintNameTo(stream); | 3407 dependency()->PrintNameTo(stream); |
3376 } | 3408 } |
3377 } | 3409 } |
3378 | 3410 |
3379 | 3411 |
3380 HCheckMaps* HCheckMaps::New(Zone* zone, | |
3381 HValue* context, | |
3382 HValue* value, | |
3383 Handle<Map> map, | |
3384 CompilationInfo* info, | |
3385 HValue* typecheck) { | |
3386 HCheckMaps* check_map = new(zone) HCheckMaps(value, new(zone) UniqueSet<Map>( | |
3387 Unique<Map>::CreateImmovable(map), zone), typecheck); | |
3388 // TODO(bmeurer): Get rid of this shit! | |
3389 if (map->CanOmitMapChecks() && | |
3390 value->IsConstant() && | |
3391 HConstant::cast(value)->HasMap(map)) { | |
3392 // TODO(titzer): collect dependent map checks into a list. | |
3393 check_map->omit_ = true; | |
3394 if (map->CanTransition()) { | |
3395 Map::AddDependentCompilationInfo( | |
3396 map, DependentCode::kPrototypeCheckGroup, info); | |
3397 } | |
3398 } | |
3399 return check_map; | |
3400 } | |
3401 | |
3402 | |
3403 void HLoadNamedGeneric::PrintDataTo(StringStream* stream) { | 3412 void HLoadNamedGeneric::PrintDataTo(StringStream* stream) { |
3404 object()->PrintNameTo(stream); | 3413 object()->PrintNameTo(stream); |
3405 stream->Add("."); | 3414 stream->Add("."); |
3406 stream->Add(String::cast(*name())->ToCString().get()); | 3415 stream->Add(String::cast(*name())->ToCString().get()); |
3407 } | 3416 } |
3408 | 3417 |
3409 | 3418 |
3410 void HLoadKeyed::PrintDataTo(StringStream* stream) { | 3419 void HLoadKeyed::PrintDataTo(StringStream* stream) { |
3411 if (!is_external()) { | 3420 if (!is_external()) { |
3412 elements()->PrintNameTo(stream); | 3421 elements()->PrintNameTo(stream); |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3907 } | 3916 } |
3908 | 3917 |
3909 | 3918 |
3910 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { | 3919 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { |
3911 ASSERT(filler_free_space_size_ == NULL); | 3920 ASSERT(filler_free_space_size_ == NULL); |
3912 Zone* zone = block()->zone(); | 3921 Zone* zone = block()->zone(); |
3913 HInstruction* free_space_instr = | 3922 HInstruction* free_space_instr = |
3914 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, | 3923 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, |
3915 dominating_allocate_->size(), type()); | 3924 dominating_allocate_->size(), type()); |
3916 free_space_instr->InsertBefore(this); | 3925 free_space_instr->InsertBefore(this); |
3917 HConstant* filler_map = HConstant::New( | 3926 HConstant* filler_map = HConstant::CreateAndInsertAfter( |
3918 zone, | 3927 zone, Unique<Map>::CreateImmovable( |
3919 context(), | 3928 isolate()->factory()->free_space_map()), free_space_instr); |
3920 isolate()->factory()->free_space_map()); | |
3921 filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready | |
3922 filler_map->InsertAfter(free_space_instr); | |
3923 HInstruction* store_map = HStoreNamedField::New(zone, context(), | 3929 HInstruction* store_map = HStoreNamedField::New(zone, context(), |
3924 free_space_instr, HObjectAccess::ForMap(), filler_map); | 3930 free_space_instr, HObjectAccess::ForMap(), filler_map); |
3925 store_map->SetFlag(HValue::kHasNoObservableSideEffects); | 3931 store_map->SetFlag(HValue::kHasNoObservableSideEffects); |
3926 store_map->InsertAfter(filler_map); | 3932 store_map->InsertAfter(filler_map); |
3927 | 3933 |
3928 // We must explicitly force Smi representation here because on x64 we | 3934 // We must explicitly force Smi representation here because on x64 we |
3929 // would otherwise automatically choose int32, but the actual store | 3935 // would otherwise automatically choose int32, but the actual store |
3930 // requires a Smi-tagged value. | 3936 // requires a Smi-tagged value. |
3931 HConstant* filler_size = HConstant::CreateAndInsertAfter( | 3937 HConstant* filler_size = HConstant::CreateAndInsertAfter( |
3932 zone, context(), free_space_size, Representation::Smi(), store_map); | 3938 zone, context(), free_space_size, Representation::Smi(), store_map); |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4746 break; | 4752 break; |
4747 case kExternalMemory: | 4753 case kExternalMemory: |
4748 stream->Add("[external-memory]"); | 4754 stream->Add("[external-memory]"); |
4749 break; | 4755 break; |
4750 } | 4756 } |
4751 | 4757 |
4752 stream->Add("@%d", offset()); | 4758 stream->Add("@%d", offset()); |
4753 } | 4759 } |
4754 | 4760 |
4755 } } // namespace v8::internal | 4761 } } // namespace v8::internal |
OLD | NEW |