Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: src/objects-inl.h

Issue 1846963002: Use a dictionary-mode code cache on the map rather than a dual system. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // Review notes: 5 // Review notes:
6 // 6 //
7 // - The use of macros in these inline functions may seem superfluous 7 // - The use of macros in these inline functions may seem superfluous
8 // but it is absolutely needed to make sure gcc generates optimal 8 // but it is absolutely needed to make sure gcc generates optimal
9 // code. gcc is not happy when attempting to inline too deep. 9 // code. gcc is not happy when attempting to inline too deep.
10 // 10 //
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 ->NormalizedMapCacheVerify(); 866 ->NormalizedMapCacheVerify();
867 } 867 }
868 #endif 868 #endif
869 return true; 869 return true;
870 } 870 }
871 871
872 bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); } 872 bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); }
873 873
874 bool HeapObject::IsCodeCacheHashTable() const { return IsHashTable(); } 874 bool HeapObject::IsCodeCacheHashTable() const { return IsHashTable(); }
875 875
876 bool HeapObject::IsPolymorphicCodeCacheHashTable() const {
877 return IsHashTable();
878 }
879
880 bool HeapObject::IsMapCache() const { return IsHashTable(); } 876 bool HeapObject::IsMapCache() const { return IsHashTable(); }
881 877
882 bool HeapObject::IsObjectHashTable() const { return IsHashTable(); } 878 bool HeapObject::IsObjectHashTable() const { return IsHashTable(); }
883 879
884 bool HeapObject::IsOrderedHashTable() const { 880 bool HeapObject::IsOrderedHashTable() const {
885 return map() == GetHeap()->ordered_hash_table_map(); 881 return map() == GetHeap()->ordered_hash_table_map();
886 } 882 }
887 883
888 884
889 bool Object::IsOrderedHashSet() const { 885 bool Object::IsOrderedHashSet() const {
(...skipping 2137 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 3023
3028 3024
3029 // Find entry for key otherwise return kNotFound. 3025 // Find entry for key otherwise return kNotFound.
3030 template <typename Derived, typename Shape, typename Key> 3026 template <typename Derived, typename Shape, typename Key>
3031 int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key, 3027 int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key,
3032 int32_t hash) { 3028 int32_t hash) {
3033 uint32_t capacity = Capacity(); 3029 uint32_t capacity = Capacity();
3034 uint32_t entry = FirstProbe(hash, capacity); 3030 uint32_t entry = FirstProbe(hash, capacity);
3035 uint32_t count = 1; 3031 uint32_t count = 1;
3036 // EnsureCapacity will guarantee the hash table is never full. 3032 // EnsureCapacity will guarantee the hash table is never full.
3033 Object* undefined = isolate->heap()->undefined_value();
3034 Object* the_hole = isolate->heap()->the_hole_value();
3037 while (true) { 3035 while (true) {
3038 Object* element = KeyAt(entry); 3036 Object* element = KeyAt(entry);
3039 // Empty entry. Uses raw unchecked accessors because it is called by the 3037 // Empty entry. Uses raw unchecked accessors because it is called by the
3040 // string table during bootstrapping. 3038 // string table during bootstrapping.
3041 if (element == isolate->heap()->root(Heap::kUndefinedValueRootIndex)) break; 3039 if (element == undefined) break;
3042 if (element != isolate->heap()->root(Heap::kTheHoleValueRootIndex) && 3040 if (element != the_hole && Shape::IsMatch(key, element)) return entry;
3043 Shape::IsMatch(key, element)) return entry;
3044 entry = NextProbe(entry, count++, capacity); 3041 entry = NextProbe(entry, count++, capacity);
3045 } 3042 }
3046 return kNotFound; 3043 return kNotFound;
3047 } 3044 }
3048 3045
3049 bool StringSetShape::IsMatch(String* key, Object* value) { 3046 bool StringSetShape::IsMatch(String* key, Object* value) {
3050 return value->IsString() && key->Equals(String::cast(value)); 3047 return value->IsString() && key->Equals(String::cast(value));
3051 } 3048 }
3052 3049
3053 uint32_t StringSetShape::Hash(String* key) { return key->Hash(); } 3050 uint32_t StringSetShape::Hash(String* key) { return key->Hash(); }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
3139 CAST_ACCESSOR(LayoutDescriptor) 3136 CAST_ACCESSOR(LayoutDescriptor)
3140 CAST_ACCESSOR(Map) 3137 CAST_ACCESSOR(Map)
3141 CAST_ACCESSOR(Name) 3138 CAST_ACCESSOR(Name)
3142 CAST_ACCESSOR(NameDictionary) 3139 CAST_ACCESSOR(NameDictionary)
3143 CAST_ACCESSOR(NormalizedMapCache) 3140 CAST_ACCESSOR(NormalizedMapCache)
3144 CAST_ACCESSOR(Object) 3141 CAST_ACCESSOR(Object)
3145 CAST_ACCESSOR(ObjectHashTable) 3142 CAST_ACCESSOR(ObjectHashTable)
3146 CAST_ACCESSOR(Oddball) 3143 CAST_ACCESSOR(Oddball)
3147 CAST_ACCESSOR(OrderedHashMap) 3144 CAST_ACCESSOR(OrderedHashMap)
3148 CAST_ACCESSOR(OrderedHashSet) 3145 CAST_ACCESSOR(OrderedHashSet)
3149 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
3150 CAST_ACCESSOR(PropertyCell) 3146 CAST_ACCESSOR(PropertyCell)
3151 CAST_ACCESSOR(ScopeInfo) 3147 CAST_ACCESSOR(ScopeInfo)
3152 CAST_ACCESSOR(SeededNumberDictionary) 3148 CAST_ACCESSOR(SeededNumberDictionary)
3153 CAST_ACCESSOR(SeqOneByteString) 3149 CAST_ACCESSOR(SeqOneByteString)
3154 CAST_ACCESSOR(SeqString) 3150 CAST_ACCESSOR(SeqString)
3155 CAST_ACCESSOR(SeqTwoByteString) 3151 CAST_ACCESSOR(SeqTwoByteString)
3156 CAST_ACCESSOR(SharedFunctionInfo) 3152 CAST_ACCESSOR(SharedFunctionInfo)
3157 CAST_ACCESSOR(Simd128Value) 3153 CAST_ACCESSOR(Simd128Value)
3158 CAST_ACCESSOR(SlicedString) 3154 CAST_ACCESSOR(SlicedString)
3159 CAST_ACCESSOR(Smi) 3155 CAST_ACCESSOR(Smi)
(...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 set_bit_field3(IsUnstable::update(bit_field3(), true)); 4610 set_bit_field3(IsUnstable::update(bit_field3(), true));
4615 } 4611 }
4616 4612
4617 4613
4618 bool Map::is_stable() { 4614 bool Map::is_stable() {
4619 return !IsUnstable::decode(bit_field3()); 4615 return !IsUnstable::decode(bit_field3());
4620 } 4616 }
4621 4617
4622 4618
4623 bool Map::has_code_cache() { 4619 bool Map::has_code_cache() {
4624 return code_cache() != GetIsolate()->heap()->empty_fixed_array(); 4620 // Code caches are always fixed arrays. The empty fixed array is used as a
4621 // sentinel for an absent code cache.
4622 return FixedArray::cast(code_cache())->length() != 0;
4625 } 4623 }
4626 4624
4627 4625
4628 bool Map::CanBeDeprecated() { 4626 bool Map::CanBeDeprecated() {
4629 int descriptor = LastAdded(); 4627 int descriptor = LastAdded();
4630 for (int i = 0; i <= descriptor; i++) { 4628 for (int i = 0; i <= descriptor; i++) {
4631 PropertyDetails details = instance_descriptors()->GetDetails(i); 4629 PropertyDetails details = instance_descriptors()->GetDetails(i);
4632 if (details.representation().IsNone()) return true; 4630 if (details.representation().IsNone()) return true;
4633 if (details.representation().IsSmi()) return true; 4631 if (details.representation().IsSmi()) return true;
4634 if (details.representation().IsDouble()) return true; 4632 if (details.representation().IsDouble()) return true;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4779 return result; 4777 return result;
4780 } 4778 }
4781 4779
4782 4780
4783 ExtraICState Code::extra_ic_state() { 4781 ExtraICState Code::extra_ic_state() {
4784 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB); 4782 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
4785 return ExtractExtraICStateFromFlags(flags()); 4783 return ExtractExtraICStateFromFlags(flags());
4786 } 4784 }
4787 4785
4788 4786
4789 Code::StubType Code::type() {
4790 return ExtractTypeFromFlags(flags());
4791 }
4792
4793 // For initialization. 4787 // For initialization.
4794 void Code::set_raw_kind_specific_flags1(int value) { 4788 void Code::set_raw_kind_specific_flags1(int value) {
4795 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value); 4789 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value);
4796 } 4790 }
4797 4791
4798 4792
4799 void Code::set_raw_kind_specific_flags2(int value) { 4793 void Code::set_raw_kind_specific_flags2(int value) {
4800 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value); 4794 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value);
4801 } 4795 }
4802 4796
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
5060 if (FLAG_enable_embedded_constant_pool) { 5054 if (FLAG_enable_embedded_constant_pool) {
5061 int offset = constant_pool_offset(); 5055 int offset = constant_pool_offset();
5062 if (offset < instruction_size()) { 5056 if (offset < instruction_size()) {
5063 constant_pool = FIELD_ADDR(this, kHeaderSize + offset); 5057 constant_pool = FIELD_ADDR(this, kHeaderSize + offset);
5064 } 5058 }
5065 } 5059 }
5066 return constant_pool; 5060 return constant_pool;
5067 } 5061 }
5068 5062
5069 Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state, 5063 Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state,
5070 ExtraICState extra_ic_state, StubType type, 5064 ExtraICState extra_ic_state,
5071 CacheHolderFlag holder) { 5065 CacheHolderFlag holder) {
5072 // Compute the bit mask. 5066 // Compute the bit mask.
5073 unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) | 5067 unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) |
5074 TypeField::encode(type) |
5075 ExtraICStateField::encode(extra_ic_state) | 5068 ExtraICStateField::encode(extra_ic_state) |
5076 CacheHolderField::encode(holder); 5069 CacheHolderField::encode(holder);
5077 return static_cast<Flags>(bits); 5070 return static_cast<Flags>(bits);
5078 } 5071 }
5079 5072
5080 Code::Flags Code::ComputeMonomorphicFlags(Kind kind, 5073 Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
5081 ExtraICState extra_ic_state, 5074 ExtraICState extra_ic_state,
5082 CacheHolderFlag holder, 5075 CacheHolderFlag holder) {
5083 StubType type) { 5076 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, holder);
5084 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder); 5077 }
5078
5079 Code::Flags Code::ComputeHandlerFlags(Kind handler_kind,
5080 CacheHolderFlag holder) {
5081 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, holder);
5085 } 5082 }
5086 5083
5087 5084
5088 Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type,
5089 CacheHolderFlag holder) {
5090 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder);
5091 }
5092
5093
5094 Code::Kind Code::ExtractKindFromFlags(Flags flags) { 5085 Code::Kind Code::ExtractKindFromFlags(Flags flags) {
5095 return KindField::decode(flags); 5086 return KindField::decode(flags);
5096 } 5087 }
5097 5088
5098 5089
5099 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) { 5090 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
5100 return ICStateField::decode(flags); 5091 return ICStateField::decode(flags);
5101 } 5092 }
5102 5093
5103 5094
5104 ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) { 5095 ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
5105 return ExtraICStateField::decode(flags); 5096 return ExtraICStateField::decode(flags);
5106 } 5097 }
5107 5098
5108 5099
5109 Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
5110 return TypeField::decode(flags);
5111 }
5112
5113 CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) { 5100 CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
5114 return CacheHolderField::decode(flags); 5101 return CacheHolderField::decode(flags);
5115 } 5102 }
5116 5103
5117 5104 Code::Flags Code::RemoveHolderFromFlags(Flags flags) {
5118 Code::Flags Code::RemoveTypeFromFlags(Flags flags) { 5105 int bits = flags & ~CacheHolderField::kMask;
5119 int bits = flags & ~TypeField::kMask;
5120 return static_cast<Flags>(bits); 5106 return static_cast<Flags>(bits);
5121 } 5107 }
5122 5108
5123
5124 Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) {
5125 int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask;
5126 return static_cast<Flags>(bits);
5127 }
5128
5129 5109
5130 Code* Code::GetCodeFromTargetAddress(Address address) { 5110 Code* Code::GetCodeFromTargetAddress(Address address) {
5131 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize); 5111 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
5132 // GetCodeFromTargetAddress might be called when marking objects during mark 5112 // GetCodeFromTargetAddress might be called when marking objects during mark
5133 // sweep. reinterpret_cast is therefore used instead of the more appropriate 5113 // sweep. reinterpret_cast is therefore used instead of the more appropriate
5134 // Code::cast. Code::cast does not work when the object's map is 5114 // Code::cast. Code::cast does not work when the object's map is
5135 // marked. 5115 // marked.
5136 Code* result = reinterpret_cast<Code*>(code); 5116 Code* result = reinterpret_cast<Code*>(code);
5137 return result; 5117 return result;
5138 } 5118 }
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
5793 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator) 5773 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
5794 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method, 5774 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
5795 kIsConciseMethod) 5775 kIsConciseMethod)
5796 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function, 5776 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function,
5797 kIsGetterFunction) 5777 kIsGetterFunction)
5798 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function, 5778 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function,
5799 kIsSetterFunction) 5779 kIsSetterFunction)
5800 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor, 5780 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor,
5801 kIsDefaultConstructor) 5781 kIsDefaultConstructor)
5802 5782
5803 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
5804 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
5805
5806 ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
5807
5808 bool Script::HasValidSource() { 5783 bool Script::HasValidSource() {
5809 Object* src = this->source(); 5784 Object* src = this->source();
5810 if (!src->IsString()) return true; 5785 if (!src->IsString()) return true;
5811 String* src_str = String::cast(src); 5786 String* src_str = String::cast(src);
5812 if (!StringShape(src_str).IsExternal()) return true; 5787 if (!StringShape(src_str).IsExternal()) return true;
5813 if (src_str->IsOneByteRepresentation()) { 5788 if (src_str->IsOneByteRepresentation()) {
5814 return ExternalOneByteString::cast(src)->resource() != NULL; 5789 return ExternalOneByteString::cast(src)->resource() != NULL;
5815 } else if (src_str->IsTwoByteRepresentation()) { 5790 } else if (src_str->IsTwoByteRepresentation()) {
5816 return ExternalTwoByteString::cast(src)->resource() != NULL; 5791 return ExternalTwoByteString::cast(src)->resource() != NULL;
5817 } 5792 }
(...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after
7509 } 7484 }
7510 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS) 7485 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS)
7511 #undef SCOPE_INFO_FIELD_ACCESSORS 7486 #undef SCOPE_INFO_FIELD_ACCESSORS
7512 7487
7513 7488
7514 void Map::ClearCodeCache(Heap* heap) { 7489 void Map::ClearCodeCache(Heap* heap) {
7515 // No write barrier is needed since empty_fixed_array is not in new space. 7490 // No write barrier is needed since empty_fixed_array is not in new space.
7516 // Please note this function is used during marking: 7491 // Please note this function is used during marking:
7517 // - MarkCompactCollector::MarkUnmarkedObject 7492 // - MarkCompactCollector::MarkUnmarkedObject
7518 // - IncrementalMarking::Step 7493 // - IncrementalMarking::Step
7519 DCHECK(!heap->InNewSpace(heap->empty_fixed_array()));
7520 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array()); 7494 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
7521 } 7495 }
7522 7496
7523 7497
7524 int Map::SlackForArraySize(int old_size, int size_limit) { 7498 int Map::SlackForArraySize(int old_size, int size_limit) {
7525 const int max_slack = size_limit - old_size; 7499 const int max_slack = size_limit - old_size;
7526 CHECK_LE(0, max_slack); 7500 CHECK_LE(0, max_slack);
7527 if (old_size < 4) { 7501 if (old_size < 4) {
7528 DCHECK_LE(1, max_slack); 7502 DCHECK_LE(1, max_slack);
7529 return 1; 7503 return 1;
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
7835 #undef WRITE_INT64_FIELD 7809 #undef WRITE_INT64_FIELD
7836 #undef READ_BYTE_FIELD 7810 #undef READ_BYTE_FIELD
7837 #undef WRITE_BYTE_FIELD 7811 #undef WRITE_BYTE_FIELD
7838 #undef NOBARRIER_READ_BYTE_FIELD 7812 #undef NOBARRIER_READ_BYTE_FIELD
7839 #undef NOBARRIER_WRITE_BYTE_FIELD 7813 #undef NOBARRIER_WRITE_BYTE_FIELD
7840 7814
7841 } // namespace internal 7815 } // namespace internal
7842 } // namespace v8 7816 } // namespace v8
7843 7817
7844 #endif // V8_OBJECTS_INL_H_ 7818 #endif // V8_OBJECTS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698