| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/double.h" | 7 #include "src/double.h" |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/hydrogen-infer-representation.h" | 9 #include "src/hydrogen-infer-representation.h" |
| 10 #include "src/property-details-inl.h" | 10 #include "src/property-details-inl.h" |
| (...skipping 3997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4008 | 4008 |
| 4009 // We must explicitly force Smi representation here because on x64 we | 4009 // We must explicitly force Smi representation here because on x64 we |
| 4010 // would otherwise automatically choose int32, but the actual store | 4010 // would otherwise automatically choose int32, but the actual store |
| 4011 // requires a Smi-tagged value. | 4011 // requires a Smi-tagged value. |
| 4012 HConstant* filler_size = HConstant::CreateAndInsertAfter( | 4012 HConstant* filler_size = HConstant::CreateAndInsertAfter( |
| 4013 zone, context(), free_space_size, Representation::Smi(), store_map); | 4013 zone, context(), free_space_size, Representation::Smi(), store_map); |
| 4014 // Must force Smi representation for x64 (see comment above). | 4014 // Must force Smi representation for x64 (see comment above). |
| 4015 HObjectAccess access = | 4015 HObjectAccess access = |
| 4016 HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(), | 4016 HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(), |
| 4017 FreeSpace::kSizeOffset, | 4017 FreeSpace::kSizeOffset, |
| 4018 HObjectAccess::FOR_FIELD, |
| 4018 Representation::Smi()); | 4019 Representation::Smi()); |
| 4019 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), | 4020 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), |
| 4020 free_space_instr, access, filler_size); | 4021 free_space_instr, access, filler_size); |
| 4021 store_size->SetFlag(HValue::kHasNoObservableSideEffects); | 4022 store_size->SetFlag(HValue::kHasNoObservableSideEffects); |
| 4022 store_size->InsertAfter(filler_size); | 4023 store_size->InsertAfter(filler_size); |
| 4023 filler_free_space_size_ = store_size; | 4024 filler_free_space_size_ = store_size; |
| 4024 } | 4025 } |
| 4025 | 4026 |
| 4026 | 4027 |
| 4027 void HAllocate::ClearNextMapWord(int offset) { | 4028 void HAllocate::ClearNextMapWord(int offset) { |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4602 ASSERT(HasNoUses()); | 4603 ASSERT(HasNoUses()); |
| 4603 } | 4604 } |
| 4604 | 4605 |
| 4605 #endif | 4606 #endif |
| 4606 | 4607 |
| 4607 | 4608 |
| 4608 HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { | 4609 HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { |
| 4609 ASSERT(offset >= 0); | 4610 ASSERT(offset >= 0); |
| 4610 ASSERT(offset < FixedArray::kHeaderSize); | 4611 ASSERT(offset < FixedArray::kHeaderSize); |
| 4611 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); | 4612 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); |
| 4612 return HObjectAccess(kInobject, offset); | 4613 return HObjectAccess(kInobject, offset, FOR_FIXED_ARRAY_HEADER); |
| 4613 } | 4614 } |
| 4614 | 4615 |
| 4615 | 4616 |
| 4616 HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset, | 4617 HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset, |
| 4617 Representation representation) { | 4618 Purpose purpose, Representation representation) { |
| 4618 ASSERT(offset >= 0); | 4619 ASSERT(offset >= 0); |
| 4619 Portion portion = kInobject; | 4620 Portion portion = kInobject; |
| 4620 | 4621 |
| 4621 if (offset == JSObject::kElementsOffset) { | 4622 if (offset == JSObject::kElementsOffset && |
| 4623 !map.is_null() && map->IsJSObjectMap()) { |
| 4622 portion = kElementsPointer; | 4624 portion = kElementsPointer; |
| 4625 purpose = FOR_ELEMENTS_POINTER; |
| 4623 } else if (offset == JSObject::kMapOffset) { | 4626 } else if (offset == JSObject::kMapOffset) { |
| 4624 portion = kMaps; | 4627 portion = kMaps; |
| 4628 purpose = FOR_MAP; |
| 4625 } | 4629 } |
| 4626 bool existing_inobject_property = true; | 4630 bool existing_inobject_property = true; |
| 4627 if (!map.is_null()) { | 4631 if (!map.is_null()) { |
| 4628 existing_inobject_property = (offset < | 4632 existing_inobject_property = (offset < |
| 4629 map->instance_size() - map->unused_property_fields() * kPointerSize); | 4633 map->instance_size() - map->unused_property_fields() * kPointerSize); |
| 4630 } | 4634 } |
| 4631 return HObjectAccess(portion, offset, representation, Handle<String>::null(), | 4635 return HObjectAccess(portion, offset, purpose, representation, |
| 4632 false, existing_inobject_property); | 4636 Handle<String>::null(), false, |
| 4637 existing_inobject_property); |
| 4633 } | 4638 } |
| 4634 | 4639 |
| 4635 | 4640 |
| 4636 HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) { | 4641 HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) { |
| 4637 switch (offset) { | 4642 switch (offset) { |
| 4643 case AllocationSite::kDependentCodeOffset: |
| 4644 case AllocationSite::kNestedSiteOffset: |
| 4638 case AllocationSite::kTransitionInfoOffset: | 4645 case AllocationSite::kTransitionInfoOffset: |
| 4639 return HObjectAccess(kInobject, offset, Representation::Tagged()); | 4646 case AllocationSite::kWeakNextOffset: |
| 4640 case AllocationSite::kNestedSiteOffset: | 4647 return HObjectAccess(kInobject, offset, FOR_ALLOCATION_SITE_OFFSET, |
| 4641 return HObjectAccess(kInobject, offset, Representation::Tagged()); | 4648 Representation::Tagged()); |
| 4642 case AllocationSite::kPretenureDataOffset: | 4649 case AllocationSite::kPretenureDataOffset: |
| 4643 return HObjectAccess(kInobject, offset, Representation::Smi()); | |
| 4644 case AllocationSite::kPretenureCreateCountOffset: | 4650 case AllocationSite::kPretenureCreateCountOffset: |
| 4645 return HObjectAccess(kInobject, offset, Representation::Smi()); | 4651 return HObjectAccess(kInobject, offset, FOR_ALLOCATION_SITE_OFFSET, |
| 4646 case AllocationSite::kDependentCodeOffset: | 4652 Representation::Smi()); |
| 4647 return HObjectAccess(kInobject, offset, Representation::Tagged()); | |
| 4648 case AllocationSite::kWeakNextOffset: | |
| 4649 return HObjectAccess(kInobject, offset, Representation::Tagged()); | |
| 4650 default: | 4653 default: |
| 4651 UNREACHABLE(); | 4654 UNREACHABLE(); |
| 4652 } | 4655 } |
| 4653 return HObjectAccess(kInobject, offset); | 4656 return HObjectAccess(kInobject, offset, FOR_ALLOCATION_SITE_OFFSET); |
| 4654 } | 4657 } |
| 4655 | 4658 |
| 4656 | 4659 |
| 4657 HObjectAccess HObjectAccess::ForContextSlot(int index) { | 4660 HObjectAccess HObjectAccess::ForContextSlot(int index) { |
| 4658 ASSERT(index >= 0); | 4661 ASSERT(index >= 0); |
| 4659 Portion portion = kInobject; | 4662 Portion portion = kInobject; |
| 4660 int offset = Context::kHeaderSize + index * kPointerSize; | 4663 int offset = Context::kHeaderSize + index * kPointerSize; |
| 4661 ASSERT_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag); | 4664 ASSERT_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag); |
| 4662 return HObjectAccess(portion, offset, Representation::Tagged()); | 4665 return HObjectAccess(portion, offset, FOR_CONTEXT_SLOT, |
| 4666 Representation::Tagged()); |
| 4663 } | 4667 } |
| 4664 | 4668 |
| 4665 | 4669 |
| 4666 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) { | 4670 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) { |
| 4667 ASSERT(offset >= 0); | 4671 ASSERT(offset >= 0); |
| 4668 Portion portion = kInobject; | 4672 Portion portion = kInobject; |
| 4673 Purpose purpose = FOR_JSARRAY_OFFSET; |
| 4669 | 4674 |
| 4670 if (offset == JSObject::kElementsOffset) { | 4675 if (offset == JSObject::kElementsOffset) { |
| 4671 portion = kElementsPointer; | 4676 portion = kElementsPointer; |
| 4677 purpose = FOR_ELEMENTS_POINTER; |
| 4672 } else if (offset == JSArray::kLengthOffset) { | 4678 } else if (offset == JSArray::kLengthOffset) { |
| 4673 portion = kArrayLengths; | 4679 portion = kArrayLengths; |
| 4680 purpose = FOR_ARRAY_LENGTH; |
| 4674 } else if (offset == JSObject::kMapOffset) { | 4681 } else if (offset == JSObject::kMapOffset) { |
| 4675 portion = kMaps; | 4682 portion = kMaps; |
| 4683 purpose = FOR_MAP; |
| 4676 } | 4684 } |
| 4677 return HObjectAccess(portion, offset); | 4685 return HObjectAccess(portion, offset, purpose); |
| 4678 } | 4686 } |
| 4679 | 4687 |
| 4680 | 4688 |
| 4681 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, | 4689 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, |
| 4682 Representation representation) { | 4690 Representation representation) { |
| 4683 ASSERT(offset >= 0); | 4691 ASSERT(offset >= 0); |
| 4684 return HObjectAccess(kBackingStore, offset, representation, | 4692 return HObjectAccess(kBackingStore, offset, FOR_BACKING_STORE_OFFSET, |
| 4685 Handle<String>::null(), false, false); | 4693 representation, Handle<String>::null(), false, false); |
| 4686 } | 4694 } |
| 4687 | 4695 |
| 4688 | 4696 |
| 4689 HObjectAccess HObjectAccess::ForField(Handle<Map> map, | 4697 HObjectAccess HObjectAccess::ForField(Handle<Map> map, |
| 4690 LookupResult* lookup, | 4698 LookupResult* lookup, |
| 4691 Handle<String> name) { | 4699 Handle<String> name) { |
| 4692 ASSERT(lookup->IsField() || lookup->IsTransitionToField()); | 4700 ASSERT(lookup->IsField() || lookup->IsTransitionToField()); |
| 4693 int index; | 4701 int index; |
| 4694 Representation representation; | 4702 Representation representation; |
| 4695 if (lookup->IsField()) { | 4703 if (lookup->IsField()) { |
| 4696 index = lookup->GetLocalFieldIndexFromMap(*map); | 4704 index = lookup->GetLocalFieldIndexFromMap(*map); |
| 4697 representation = lookup->representation(); | 4705 representation = lookup->representation(); |
| 4698 } else { | 4706 } else { |
| 4699 Map* transition = lookup->GetTransitionTarget(); | 4707 Map* transition = lookup->GetTransitionTarget(); |
| 4700 int descriptor = transition->LastAdded(); | 4708 int descriptor = transition->LastAdded(); |
| 4701 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - | 4709 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - |
| 4702 map->inobject_properties(); | 4710 map->inobject_properties(); |
| 4703 PropertyDetails details = | 4711 PropertyDetails details = |
| 4704 transition->instance_descriptors()->GetDetails(descriptor); | 4712 transition->instance_descriptors()->GetDetails(descriptor); |
| 4705 representation = details.representation(); | 4713 representation = details.representation(); |
| 4706 } | 4714 } |
| 4707 if (index < 0) { | 4715 if (index < 0) { |
| 4708 // Negative property indices are in-object properties, indexed | 4716 // Negative property indices are in-object properties, indexed |
| 4709 // from the end of the fixed part of the object. | 4717 // from the end of the fixed part of the object. |
| 4710 int offset = (index * kPointerSize) + map->instance_size(); | 4718 int offset = (index * kPointerSize) + map->instance_size(); |
| 4711 return HObjectAccess(kInobject, offset, representation, name, false, true); | 4719 return HObjectAccess(kInobject, offset, FOR_FIELD, representation, name, |
| 4720 false, true); |
| 4712 } else { | 4721 } else { |
| 4713 // Non-negative property indices are in the properties array. | 4722 // Non-negative property indices are in the properties array. |
| 4714 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 4723 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
| 4715 return HObjectAccess(kBackingStore, offset, representation, name, | 4724 return HObjectAccess(kBackingStore, offset, FOR_BACKING_STORE_OFFSET, |
| 4716 false, false); | 4725 representation, name, false, false); |
| 4717 } | 4726 } |
| 4718 } | 4727 } |
| 4719 | 4728 |
| 4720 | 4729 |
| 4721 HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) { | 4730 HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) { |
| 4722 return HObjectAccess( | 4731 return HObjectAccess( |
| 4723 kInobject, Cell::kValueOffset, Representation::Tagged(), | 4732 kInobject, Cell::kValueOffset, FOR_CELL_PAYLOAD, Representation::Tagged(), |
| 4724 Handle<String>(isolate->heap()->cell_value_string())); | 4733 Handle<String>(isolate->heap()->cell_value_string())); |
| 4725 } | 4734 } |
| 4726 | 4735 |
| 4727 | 4736 |
| 4728 void HObjectAccess::SetGVNFlags(HValue *instr, PropertyAccessType access_type) { | 4737 void HObjectAccess::SetGVNFlags(HValue *instr, PropertyAccessType access_type) { |
| 4729 // set the appropriate GVN flags for a given load or store instruction | 4738 // set the appropriate GVN flags for a given load or store instruction |
| 4730 if (access_type == STORE) { | 4739 if (access_type == STORE) { |
| 4731 // track dominating allocations in order to eliminate write barriers | 4740 // track dominating allocations in order to eliminate write barriers |
| 4732 instr->SetDependsOnFlag(::v8::internal::kNewSpacePromotion); | 4741 instr->SetDependsOnFlag(::v8::internal::kNewSpacePromotion); |
| 4733 instr->SetFlag(HValue::kTrackSideEffectDominators); | 4742 instr->SetFlag(HValue::kTrackSideEffectDominators); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4827 break; | 4836 break; |
| 4828 case kExternalMemory: | 4837 case kExternalMemory: |
| 4829 stream->Add("[external-memory]"); | 4838 stream->Add("[external-memory]"); |
| 4830 break; | 4839 break; |
| 4831 } | 4840 } |
| 4832 | 4841 |
| 4833 stream->Add("@%d", offset()); | 4842 stream->Add("@%d", offset()); |
| 4834 } | 4843 } |
| 4835 | 4844 |
| 4836 } } // namespace v8::internal | 4845 } } // namespace v8::internal |
| OLD | NEW |