| 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 // 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 Loading... |
| 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 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3030 | 3026 |
| 3031 | 3027 |
| 3032 // Find entry for key otherwise return kNotFound. | 3028 // Find entry for key otherwise return kNotFound. |
| 3033 template <typename Derived, typename Shape, typename Key> | 3029 template <typename Derived, typename Shape, typename Key> |
| 3034 int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key, | 3030 int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key, |
| 3035 int32_t hash) { | 3031 int32_t hash) { |
| 3036 uint32_t capacity = Capacity(); | 3032 uint32_t capacity = Capacity(); |
| 3037 uint32_t entry = FirstProbe(hash, capacity); | 3033 uint32_t entry = FirstProbe(hash, capacity); |
| 3038 uint32_t count = 1; | 3034 uint32_t count = 1; |
| 3039 // EnsureCapacity will guarantee the hash table is never full. | 3035 // EnsureCapacity will guarantee the hash table is never full. |
| 3036 Object* undefined = isolate->heap()->undefined_value(); |
| 3037 Object* the_hole = isolate->heap()->the_hole_value(); |
| 3040 while (true) { | 3038 while (true) { |
| 3041 Object* element = KeyAt(entry); | 3039 Object* element = KeyAt(entry); |
| 3042 // Empty entry. Uses raw unchecked accessors because it is called by the | 3040 // Empty entry. Uses raw unchecked accessors because it is called by the |
| 3043 // string table during bootstrapping. | 3041 // string table during bootstrapping. |
| 3044 if (element == isolate->heap()->root(Heap::kUndefinedValueRootIndex)) break; | 3042 if (element == undefined) break; |
| 3045 if (element != isolate->heap()->root(Heap::kTheHoleValueRootIndex) && | 3043 if (element != the_hole && Shape::IsMatch(key, element)) return entry; |
| 3046 Shape::IsMatch(key, element)) return entry; | |
| 3047 entry = NextProbe(entry, count++, capacity); | 3044 entry = NextProbe(entry, count++, capacity); |
| 3048 } | 3045 } |
| 3049 return kNotFound; | 3046 return kNotFound; |
| 3050 } | 3047 } |
| 3051 | 3048 |
| 3052 bool StringSetShape::IsMatch(String* key, Object* value) { | 3049 bool StringSetShape::IsMatch(String* key, Object* value) { |
| 3053 return value->IsString() && key->Equals(String::cast(value)); | 3050 return value->IsString() && key->Equals(String::cast(value)); |
| 3054 } | 3051 } |
| 3055 | 3052 |
| 3056 uint32_t StringSetShape::Hash(String* key) { return key->Hash(); } | 3053 uint32_t StringSetShape::Hash(String* key) { return key->Hash(); } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3142 CAST_ACCESSOR(LayoutDescriptor) | 3139 CAST_ACCESSOR(LayoutDescriptor) |
| 3143 CAST_ACCESSOR(Map) | 3140 CAST_ACCESSOR(Map) |
| 3144 CAST_ACCESSOR(Name) | 3141 CAST_ACCESSOR(Name) |
| 3145 CAST_ACCESSOR(NameDictionary) | 3142 CAST_ACCESSOR(NameDictionary) |
| 3146 CAST_ACCESSOR(NormalizedMapCache) | 3143 CAST_ACCESSOR(NormalizedMapCache) |
| 3147 CAST_ACCESSOR(Object) | 3144 CAST_ACCESSOR(Object) |
| 3148 CAST_ACCESSOR(ObjectHashTable) | 3145 CAST_ACCESSOR(ObjectHashTable) |
| 3149 CAST_ACCESSOR(Oddball) | 3146 CAST_ACCESSOR(Oddball) |
| 3150 CAST_ACCESSOR(OrderedHashMap) | 3147 CAST_ACCESSOR(OrderedHashMap) |
| 3151 CAST_ACCESSOR(OrderedHashSet) | 3148 CAST_ACCESSOR(OrderedHashSet) |
| 3152 CAST_ACCESSOR(PolymorphicCodeCacheHashTable) | |
| 3153 CAST_ACCESSOR(PropertyCell) | 3149 CAST_ACCESSOR(PropertyCell) |
| 3154 CAST_ACCESSOR(ScopeInfo) | 3150 CAST_ACCESSOR(ScopeInfo) |
| 3155 CAST_ACCESSOR(SeededNumberDictionary) | 3151 CAST_ACCESSOR(SeededNumberDictionary) |
| 3156 CAST_ACCESSOR(SeqOneByteString) | 3152 CAST_ACCESSOR(SeqOneByteString) |
| 3157 CAST_ACCESSOR(SeqString) | 3153 CAST_ACCESSOR(SeqString) |
| 3158 CAST_ACCESSOR(SeqTwoByteString) | 3154 CAST_ACCESSOR(SeqTwoByteString) |
| 3159 CAST_ACCESSOR(SharedFunctionInfo) | 3155 CAST_ACCESSOR(SharedFunctionInfo) |
| 3160 CAST_ACCESSOR(Simd128Value) | 3156 CAST_ACCESSOR(Simd128Value) |
| 3161 CAST_ACCESSOR(SlicedString) | 3157 CAST_ACCESSOR(SlicedString) |
| 3162 CAST_ACCESSOR(Smi) | 3158 CAST_ACCESSOR(Smi) |
| (...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4617 set_bit_field3(IsUnstable::update(bit_field3(), true)); | 4613 set_bit_field3(IsUnstable::update(bit_field3(), true)); |
| 4618 } | 4614 } |
| 4619 | 4615 |
| 4620 | 4616 |
| 4621 bool Map::is_stable() { | 4617 bool Map::is_stable() { |
| 4622 return !IsUnstable::decode(bit_field3()); | 4618 return !IsUnstable::decode(bit_field3()); |
| 4623 } | 4619 } |
| 4624 | 4620 |
| 4625 | 4621 |
| 4626 bool Map::has_code_cache() { | 4622 bool Map::has_code_cache() { |
| 4627 return code_cache() != GetIsolate()->heap()->empty_fixed_array(); | 4623 // Code caches are always fixed arrays. The empty fixed array is used as a |
| 4624 // sentinel for an absent code cache. |
| 4625 return FixedArray::cast(code_cache())->length() != 0; |
| 4628 } | 4626 } |
| 4629 | 4627 |
| 4630 | 4628 |
| 4631 bool Map::CanBeDeprecated() { | 4629 bool Map::CanBeDeprecated() { |
| 4632 int descriptor = LastAdded(); | 4630 int descriptor = LastAdded(); |
| 4633 for (int i = 0; i <= descriptor; i++) { | 4631 for (int i = 0; i <= descriptor; i++) { |
| 4634 PropertyDetails details = instance_descriptors()->GetDetails(i); | 4632 PropertyDetails details = instance_descriptors()->GetDetails(i); |
| 4635 if (details.representation().IsNone()) return true; | 4633 if (details.representation().IsNone()) return true; |
| 4636 if (details.representation().IsSmi()) return true; | 4634 if (details.representation().IsSmi()) return true; |
| 4637 if (details.representation().IsDouble()) return true; | 4635 if (details.representation().IsDouble()) return true; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4782 return result; | 4780 return result; |
| 4783 } | 4781 } |
| 4784 | 4782 |
| 4785 | 4783 |
| 4786 ExtraICState Code::extra_ic_state() { | 4784 ExtraICState Code::extra_ic_state() { |
| 4787 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB); | 4785 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB); |
| 4788 return ExtractExtraICStateFromFlags(flags()); | 4786 return ExtractExtraICStateFromFlags(flags()); |
| 4789 } | 4787 } |
| 4790 | 4788 |
| 4791 | 4789 |
| 4792 Code::StubType Code::type() { | |
| 4793 return ExtractTypeFromFlags(flags()); | |
| 4794 } | |
| 4795 | |
| 4796 // For initialization. | 4790 // For initialization. |
| 4797 void Code::set_raw_kind_specific_flags1(int value) { | 4791 void Code::set_raw_kind_specific_flags1(int value) { |
| 4798 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value); | 4792 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value); |
| 4799 } | 4793 } |
| 4800 | 4794 |
| 4801 | 4795 |
| 4802 void Code::set_raw_kind_specific_flags2(int value) { | 4796 void Code::set_raw_kind_specific_flags2(int value) { |
| 4803 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value); | 4797 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value); |
| 4804 } | 4798 } |
| 4805 | 4799 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5063 if (FLAG_enable_embedded_constant_pool) { | 5057 if (FLAG_enable_embedded_constant_pool) { |
| 5064 int offset = constant_pool_offset(); | 5058 int offset = constant_pool_offset(); |
| 5065 if (offset < instruction_size()) { | 5059 if (offset < instruction_size()) { |
| 5066 constant_pool = FIELD_ADDR(this, kHeaderSize + offset); | 5060 constant_pool = FIELD_ADDR(this, kHeaderSize + offset); |
| 5067 } | 5061 } |
| 5068 } | 5062 } |
| 5069 return constant_pool; | 5063 return constant_pool; |
| 5070 } | 5064 } |
| 5071 | 5065 |
| 5072 Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state, | 5066 Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state, |
| 5073 ExtraICState extra_ic_state, StubType type, | 5067 ExtraICState extra_ic_state, |
| 5074 CacheHolderFlag holder) { | 5068 CacheHolderFlag holder) { |
| 5075 // Compute the bit mask. | 5069 // Compute the bit mask. |
| 5076 unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) | | 5070 unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) | |
| 5077 TypeField::encode(type) | | |
| 5078 ExtraICStateField::encode(extra_ic_state) | | 5071 ExtraICStateField::encode(extra_ic_state) | |
| 5079 CacheHolderField::encode(holder); | 5072 CacheHolderField::encode(holder); |
| 5080 return static_cast<Flags>(bits); | 5073 return static_cast<Flags>(bits); |
| 5081 } | 5074 } |
| 5082 | 5075 |
| 5083 Code::Flags Code::ComputeMonomorphicFlags(Kind kind, | 5076 Code::Flags Code::ComputeMonomorphicFlags(Kind kind, |
| 5084 ExtraICState extra_ic_state, | 5077 ExtraICState extra_ic_state, |
| 5085 CacheHolderFlag holder, | 5078 CacheHolderFlag holder) { |
| 5086 StubType type) { | 5079 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, holder); |
| 5087 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder); | 5080 } |
| 5081 |
| 5082 Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, |
| 5083 CacheHolderFlag holder) { |
| 5084 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, holder); |
| 5088 } | 5085 } |
| 5089 | 5086 |
| 5090 | 5087 |
| 5091 Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type, | |
| 5092 CacheHolderFlag holder) { | |
| 5093 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder); | |
| 5094 } | |
| 5095 | |
| 5096 | |
| 5097 Code::Kind Code::ExtractKindFromFlags(Flags flags) { | 5088 Code::Kind Code::ExtractKindFromFlags(Flags flags) { |
| 5098 return KindField::decode(flags); | 5089 return KindField::decode(flags); |
| 5099 } | 5090 } |
| 5100 | 5091 |
| 5101 | 5092 |
| 5102 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) { | 5093 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) { |
| 5103 return ICStateField::decode(flags); | 5094 return ICStateField::decode(flags); |
| 5104 } | 5095 } |
| 5105 | 5096 |
| 5106 | 5097 |
| 5107 ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) { | 5098 ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) { |
| 5108 return ExtraICStateField::decode(flags); | 5099 return ExtraICStateField::decode(flags); |
| 5109 } | 5100 } |
| 5110 | 5101 |
| 5111 | 5102 |
| 5112 Code::StubType Code::ExtractTypeFromFlags(Flags flags) { | |
| 5113 return TypeField::decode(flags); | |
| 5114 } | |
| 5115 | |
| 5116 CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) { | 5103 CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) { |
| 5117 return CacheHolderField::decode(flags); | 5104 return CacheHolderField::decode(flags); |
| 5118 } | 5105 } |
| 5119 | 5106 |
| 5120 | 5107 Code::Flags Code::RemoveHolderFromFlags(Flags flags) { |
| 5121 Code::Flags Code::RemoveTypeFromFlags(Flags flags) { | 5108 int bits = flags & ~CacheHolderField::kMask; |
| 5122 int bits = flags & ~TypeField::kMask; | |
| 5123 return static_cast<Flags>(bits); | 5109 return static_cast<Flags>(bits); |
| 5124 } | 5110 } |
| 5125 | 5111 |
| 5126 | |
| 5127 Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) { | |
| 5128 int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask; | |
| 5129 return static_cast<Flags>(bits); | |
| 5130 } | |
| 5131 | |
| 5132 | 5112 |
| 5133 Code* Code::GetCodeFromTargetAddress(Address address) { | 5113 Code* Code::GetCodeFromTargetAddress(Address address) { |
| 5134 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize); | 5114 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize); |
| 5135 // GetCodeFromTargetAddress might be called when marking objects during mark | 5115 // GetCodeFromTargetAddress might be called when marking objects during mark |
| 5136 // sweep. reinterpret_cast is therefore used instead of the more appropriate | 5116 // sweep. reinterpret_cast is therefore used instead of the more appropriate |
| 5137 // Code::cast. Code::cast does not work when the object's map is | 5117 // Code::cast. Code::cast does not work when the object's map is |
| 5138 // marked. | 5118 // marked. |
| 5139 Code* result = reinterpret_cast<Code*>(code); | 5119 Code* result = reinterpret_cast<Code*>(code); |
| 5140 return result; | 5120 return result; |
| 5141 } | 5121 } |
| (...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5796 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator) | 5776 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator) |
| 5797 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method, | 5777 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method, |
| 5798 kIsConciseMethod) | 5778 kIsConciseMethod) |
| 5799 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function, | 5779 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function, |
| 5800 kIsGetterFunction) | 5780 kIsGetterFunction) |
| 5801 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function, | 5781 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function, |
| 5802 kIsSetterFunction) | 5782 kIsSetterFunction) |
| 5803 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor, | 5783 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor, |
| 5804 kIsDefaultConstructor) | 5784 kIsDefaultConstructor) |
| 5805 | 5785 |
| 5806 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset) | |
| 5807 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset) | |
| 5808 | |
| 5809 ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset) | |
| 5810 | |
| 5811 bool Script::HasValidSource() { | 5786 bool Script::HasValidSource() { |
| 5812 Object* src = this->source(); | 5787 Object* src = this->source(); |
| 5813 if (!src->IsString()) return true; | 5788 if (!src->IsString()) return true; |
| 5814 String* src_str = String::cast(src); | 5789 String* src_str = String::cast(src); |
| 5815 if (!StringShape(src_str).IsExternal()) return true; | 5790 if (!StringShape(src_str).IsExternal()) return true; |
| 5816 if (src_str->IsOneByteRepresentation()) { | 5791 if (src_str->IsOneByteRepresentation()) { |
| 5817 return ExternalOneByteString::cast(src)->resource() != NULL; | 5792 return ExternalOneByteString::cast(src)->resource() != NULL; |
| 5818 } else if (src_str->IsTwoByteRepresentation()) { | 5793 } else if (src_str->IsTwoByteRepresentation()) { |
| 5819 return ExternalTwoByteString::cast(src)->resource() != NULL; | 5794 return ExternalTwoByteString::cast(src)->resource() != NULL; |
| 5820 } | 5795 } |
| (...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7512 } | 7487 } |
| 7513 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS) | 7488 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS) |
| 7514 #undef SCOPE_INFO_FIELD_ACCESSORS | 7489 #undef SCOPE_INFO_FIELD_ACCESSORS |
| 7515 | 7490 |
| 7516 | 7491 |
| 7517 void Map::ClearCodeCache(Heap* heap) { | 7492 void Map::ClearCodeCache(Heap* heap) { |
| 7518 // No write barrier is needed since empty_fixed_array is not in new space. | 7493 // No write barrier is needed since empty_fixed_array is not in new space. |
| 7519 // Please note this function is used during marking: | 7494 // Please note this function is used during marking: |
| 7520 // - MarkCompactCollector::MarkUnmarkedObject | 7495 // - MarkCompactCollector::MarkUnmarkedObject |
| 7521 // - IncrementalMarking::Step | 7496 // - IncrementalMarking::Step |
| 7522 DCHECK(!heap->InNewSpace(heap->empty_fixed_array())); | |
| 7523 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array()); | 7497 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array()); |
| 7524 } | 7498 } |
| 7525 | 7499 |
| 7526 | 7500 |
| 7527 int Map::SlackForArraySize(int old_size, int size_limit) { | 7501 int Map::SlackForArraySize(int old_size, int size_limit) { |
| 7528 const int max_slack = size_limit - old_size; | 7502 const int max_slack = size_limit - old_size; |
| 7529 CHECK_LE(0, max_slack); | 7503 CHECK_LE(0, max_slack); |
| 7530 if (old_size < 4) { | 7504 if (old_size < 4) { |
| 7531 DCHECK_LE(1, max_slack); | 7505 DCHECK_LE(1, max_slack); |
| 7532 return 1; | 7506 return 1; |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7838 #undef WRITE_INT64_FIELD | 7812 #undef WRITE_INT64_FIELD |
| 7839 #undef READ_BYTE_FIELD | 7813 #undef READ_BYTE_FIELD |
| 7840 #undef WRITE_BYTE_FIELD | 7814 #undef WRITE_BYTE_FIELD |
| 7841 #undef NOBARRIER_READ_BYTE_FIELD | 7815 #undef NOBARRIER_READ_BYTE_FIELD |
| 7842 #undef NOBARRIER_WRITE_BYTE_FIELD | 7816 #undef NOBARRIER_WRITE_BYTE_FIELD |
| 7843 | 7817 |
| 7844 } // namespace internal | 7818 } // namespace internal |
| 7845 } // namespace v8 | 7819 } // namespace v8 |
| 7846 | 7820 |
| 7847 #endif // V8_OBJECTS_INL_H_ | 7821 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |