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 2137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |