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 |