| 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 // |
| 11 | 11 |
| 12 #ifndef V8_OBJECTS_INL_H_ | 12 #ifndef V8_OBJECTS_INL_H_ |
| 13 #define V8_OBJECTS_INL_H_ | 13 #define V8_OBJECTS_INL_H_ |
| 14 | 14 |
| 15 #include "src/base/atomicops.h" | 15 #include "src/base/atomicops.h" |
| 16 #include "src/base/bits.h" | 16 #include "src/base/bits.h" |
| 17 #include "src/contexts.h" | 17 #include "src/contexts.h" |
| 18 #include "src/conversions-inl.h" | 18 #include "src/conversions-inl.h" |
| 19 #include "src/elements.h" | 19 #include "src/elements.h" |
| 20 #include "src/factory.h" | 20 #include "src/factory.h" |
| 21 #include "src/field-index-inl.h" | 21 #include "src/field-index-inl.h" |
| 22 #include "src/heap/heap-inl.h" | 22 #include "src/heap/heap-inl.h" |
| 23 #include "src/heap/heap.h" | 23 #include "src/heap/heap.h" |
| 24 #include "src/heap/incremental-marking.h" | 24 #include "src/heap/incremental-marking.h" |
| 25 #include "src/heap/objects-visiting.h" | 25 #include "src/heap/objects-visiting.h" |
| 26 #include "src/heap/spaces.h" | 26 #include "src/heap/spaces.h" |
| 27 #include "src/heap/store-buffer.h" | 27 #include "src/heap/store-buffer.h" |
| 28 #include "src/isolate.h" | 28 #include "src/isolate.h" |
| 29 #include "src/layout-descriptor-inl.h" |
| 29 #include "src/lookup.h" | 30 #include "src/lookup.h" |
| 30 #include "src/objects.h" | 31 #include "src/objects.h" |
| 31 #include "src/property.h" | 32 #include "src/property.h" |
| 32 #include "src/prototype.h" | 33 #include "src/prototype.h" |
| 33 #include "src/transitions-inl.h" | 34 #include "src/transitions-inl.h" |
| 34 #include "src/type-feedback-vector-inl.h" | 35 #include "src/type-feedback-vector-inl.h" |
| 35 #include "src/v8memory.h" | 36 #include "src/v8memory.h" |
| 36 | 37 |
| 37 namespace v8 { | 38 namespace v8 { |
| 38 namespace internal { | 39 namespace internal { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 49 return Smi::FromInt(value >> 1); | 50 return Smi::FromInt(value >> 1); |
| 50 } | 51 } |
| 51 | 52 |
| 52 | 53 |
| 53 PropertyDetails PropertyDetails::AsDeleted() const { | 54 PropertyDetails PropertyDetails::AsDeleted() const { |
| 54 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); | 55 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); |
| 55 return PropertyDetails(smi); | 56 return PropertyDetails(smi); |
| 56 } | 57 } |
| 57 | 58 |
| 58 | 59 |
| 60 int PropertyDetails::field_width_in_words() const { |
| 61 DCHECK(type() == FIELD); |
| 62 if (!FLAG_unbox_double_fields) return 1; |
| 63 if (kDoubleSize == kPointerSize) return 1; |
| 64 return representation().IsDouble() ? kDoubleSize / kPointerSize : 1; |
| 65 } |
| 66 |
| 67 |
| 59 #define TYPE_CHECKER(type, instancetype) \ | 68 #define TYPE_CHECKER(type, instancetype) \ |
| 60 bool Object::Is##type() const { \ | 69 bool Object::Is##type() const { \ |
| 61 return Object::IsHeapObject() && \ | 70 return Object::IsHeapObject() && \ |
| 62 HeapObject::cast(this)->map()->instance_type() == instancetype; \ | 71 HeapObject::cast(this)->map()->instance_type() == instancetype; \ |
| 63 } | 72 } |
| 64 | 73 |
| 65 | 74 |
| 66 #define CAST_ACCESSOR(type) \ | 75 #define CAST_ACCESSOR(type) \ |
| 67 type* type::cast(Object* object) { \ | 76 type* type::cast(Object* object) { \ |
| 68 SLOW_DCHECK(object->Is##type()); \ | 77 SLOW_DCHECK(object->Is##type()); \ |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 bool Object::IsJSWeakCollection() const { | 706 bool Object::IsJSWeakCollection() const { |
| 698 return IsJSWeakMap() || IsJSWeakSet(); | 707 return IsJSWeakMap() || IsJSWeakSet(); |
| 699 } | 708 } |
| 700 | 709 |
| 701 | 710 |
| 702 bool Object::IsDescriptorArray() const { | 711 bool Object::IsDescriptorArray() const { |
| 703 return IsFixedArray(); | 712 return IsFixedArray(); |
| 704 } | 713 } |
| 705 | 714 |
| 706 | 715 |
| 716 bool Object::IsLayoutDescriptor() const { |
| 717 return IsSmi() || IsFixedTypedArrayBase(); |
| 718 } |
| 719 |
| 720 |
| 707 bool Object::IsTransitionArray() const { | 721 bool Object::IsTransitionArray() const { |
| 708 return IsFixedArray(); | 722 return IsFixedArray(); |
| 709 } | 723 } |
| 710 | 724 |
| 711 | 725 |
| 712 bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); } | 726 bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); } |
| 713 | 727 |
| 714 | 728 |
| 715 bool Object::IsDeoptimizationInputData() const { | 729 bool Object::IsDeoptimizationInputData() const { |
| 716 // Must be a fixed array. | 730 // Must be a fixed array. |
| (...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2063 void JSObject::SetInternalField(int index, Smi* value) { | 2077 void JSObject::SetInternalField(int index, Smi* value) { |
| 2064 DCHECK(index < GetInternalFieldCount() && index >= 0); | 2078 DCHECK(index < GetInternalFieldCount() && index >= 0); |
| 2065 // Internal objects do follow immediately after the header, whereas in-object | 2079 // Internal objects do follow immediately after the header, whereas in-object |
| 2066 // properties are at the end of the object. Therefore there is no need | 2080 // properties are at the end of the object. Therefore there is no need |
| 2067 // to adjust the index here. | 2081 // to adjust the index here. |
| 2068 int offset = GetHeaderSize() + (kPointerSize * index); | 2082 int offset = GetHeaderSize() + (kPointerSize * index); |
| 2069 WRITE_FIELD(this, offset, value); | 2083 WRITE_FIELD(this, offset, value); |
| 2070 } | 2084 } |
| 2071 | 2085 |
| 2072 | 2086 |
| 2087 bool JSObject::IsUnboxedDoubleField(FieldIndex index) { |
| 2088 if (!FLAG_unbox_double_fields) return false; |
| 2089 return map()->IsUnboxedDoubleField(index); |
| 2090 } |
| 2091 |
| 2092 |
| 2093 bool Map::IsUnboxedDoubleField(FieldIndex index) { |
| 2094 if (!FLAG_unbox_double_fields) return false; |
| 2095 if (index.is_hidden_field() || !index.is_inobject()) return false; |
| 2096 return !layout_descriptor()->IsTagged(index.property_index()); |
| 2097 } |
| 2098 |
| 2099 |
| 2073 // Access fast-case object properties at index. The use of these routines | 2100 // Access fast-case object properties at index. The use of these routines |
| 2074 // is needed to correctly distinguish between properties stored in-object and | 2101 // is needed to correctly distinguish between properties stored in-object and |
| 2075 // properties stored in the properties array. | 2102 // properties stored in the properties array. |
| 2076 Object* JSObject::RawFastPropertyAt(FieldIndex index) { | 2103 Object* JSObject::RawFastPropertyAt(FieldIndex index) { |
| 2104 DCHECK(!IsUnboxedDoubleField(index)); |
| 2077 if (index.is_inobject()) { | 2105 if (index.is_inobject()) { |
| 2078 return READ_FIELD(this, index.offset()); | 2106 return READ_FIELD(this, index.offset()); |
| 2079 } else { | 2107 } else { |
| 2080 return properties()->get(index.outobject_array_index()); | 2108 return properties()->get(index.outobject_array_index()); |
| 2081 } | 2109 } |
| 2082 } | 2110 } |
| 2083 | 2111 |
| 2084 | 2112 |
| 2085 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { | 2113 double JSObject::RawFastDoublePropertyAt(FieldIndex index) { |
| 2114 DCHECK(IsUnboxedDoubleField(index)); |
| 2115 return READ_DOUBLE_FIELD(this, index.offset()); |
| 2116 } |
| 2117 |
| 2118 |
| 2119 void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) { |
| 2086 if (index.is_inobject()) { | 2120 if (index.is_inobject()) { |
| 2087 int offset = index.offset(); | 2121 int offset = index.offset(); |
| 2088 WRITE_FIELD(this, offset, value); | 2122 WRITE_FIELD(this, offset, value); |
| 2089 WRITE_BARRIER(GetHeap(), this, offset, value); | 2123 WRITE_BARRIER(GetHeap(), this, offset, value); |
| 2090 } else { | 2124 } else { |
| 2091 properties()->set(index.outobject_array_index(), value); | 2125 properties()->set(index.outobject_array_index(), value); |
| 2092 } | 2126 } |
| 2093 } | 2127 } |
| 2094 | 2128 |
| 2095 | 2129 |
| 2130 void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) { |
| 2131 WRITE_DOUBLE_FIELD(this, index.offset(), value); |
| 2132 } |
| 2133 |
| 2134 |
| 2135 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { |
| 2136 if (IsUnboxedDoubleField(index)) { |
| 2137 DCHECK(value->IsMutableHeapNumber()); |
| 2138 RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value()); |
| 2139 } else { |
| 2140 RawFastPropertyAtPut(index, value); |
| 2141 } |
| 2142 } |
| 2143 |
| 2144 |
| 2096 int JSObject::GetInObjectPropertyOffset(int index) { | 2145 int JSObject::GetInObjectPropertyOffset(int index) { |
| 2097 return map()->GetInObjectPropertyOffset(index); | 2146 return map()->GetInObjectPropertyOffset(index); |
| 2098 } | 2147 } |
| 2099 | 2148 |
| 2100 | 2149 |
| 2101 Object* JSObject::InObjectPropertyAt(int index) { | 2150 Object* JSObject::InObjectPropertyAt(int index) { |
| 2102 int offset = GetInObjectPropertyOffset(index); | 2151 int offset = GetInObjectPropertyOffset(index); |
| 2103 return READ_FIELD(this, offset); | 2152 return READ_FIELD(this, offset); |
| 2104 } | 2153 } |
| 2105 | 2154 |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3104 const WhitenessWitness&) { | 3153 const WhitenessWitness&) { |
| 3105 // Range check. | 3154 // Range check. |
| 3106 DCHECK(descriptor_number < number_of_descriptors()); | 3155 DCHECK(descriptor_number < number_of_descriptors()); |
| 3107 | 3156 |
| 3108 NoIncrementalWriteBarrierSet(this, | 3157 NoIncrementalWriteBarrierSet(this, |
| 3109 ToKeyIndex(descriptor_number), | 3158 ToKeyIndex(descriptor_number), |
| 3110 *desc->GetKey()); | 3159 *desc->GetKey()); |
| 3111 NoIncrementalWriteBarrierSet(this, | 3160 NoIncrementalWriteBarrierSet(this, |
| 3112 ToValueIndex(descriptor_number), | 3161 ToValueIndex(descriptor_number), |
| 3113 *desc->GetValue()); | 3162 *desc->GetValue()); |
| 3114 NoIncrementalWriteBarrierSet(this, | 3163 NoIncrementalWriteBarrierSet(this, ToDetailsIndex(descriptor_number), |
| 3115 ToDetailsIndex(descriptor_number), | |
| 3116 desc->GetDetails().AsSmi()); | 3164 desc->GetDetails().AsSmi()); |
| 3117 } | 3165 } |
| 3118 | 3166 |
| 3119 | 3167 |
| 3120 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { | 3168 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { |
| 3121 // Range check. | 3169 // Range check. |
| 3122 DCHECK(descriptor_number < number_of_descriptors()); | 3170 DCHECK(descriptor_number < number_of_descriptors()); |
| 3123 | 3171 |
| 3124 set(ToKeyIndex(descriptor_number), *desc->GetKey()); | 3172 set(ToKeyIndex(descriptor_number), *desc->GetKey()); |
| 3125 set(ToValueIndex(descriptor_number), *desc->GetValue()); | 3173 set(ToValueIndex(descriptor_number), *desc->GetValue()); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3280 CAST_ACCESSOR(JSObject) | 3328 CAST_ACCESSOR(JSObject) |
| 3281 CAST_ACCESSOR(JSProxy) | 3329 CAST_ACCESSOR(JSProxy) |
| 3282 CAST_ACCESSOR(JSReceiver) | 3330 CAST_ACCESSOR(JSReceiver) |
| 3283 CAST_ACCESSOR(JSRegExp) | 3331 CAST_ACCESSOR(JSRegExp) |
| 3284 CAST_ACCESSOR(JSSet) | 3332 CAST_ACCESSOR(JSSet) |
| 3285 CAST_ACCESSOR(JSSetIterator) | 3333 CAST_ACCESSOR(JSSetIterator) |
| 3286 CAST_ACCESSOR(JSTypedArray) | 3334 CAST_ACCESSOR(JSTypedArray) |
| 3287 CAST_ACCESSOR(JSValue) | 3335 CAST_ACCESSOR(JSValue) |
| 3288 CAST_ACCESSOR(JSWeakMap) | 3336 CAST_ACCESSOR(JSWeakMap) |
| 3289 CAST_ACCESSOR(JSWeakSet) | 3337 CAST_ACCESSOR(JSWeakSet) |
| 3338 CAST_ACCESSOR(LayoutDescriptor) |
| 3290 CAST_ACCESSOR(Map) | 3339 CAST_ACCESSOR(Map) |
| 3291 CAST_ACCESSOR(MapCache) | 3340 CAST_ACCESSOR(MapCache) |
| 3292 CAST_ACCESSOR(Name) | 3341 CAST_ACCESSOR(Name) |
| 3293 CAST_ACCESSOR(NameDictionary) | 3342 CAST_ACCESSOR(NameDictionary) |
| 3294 CAST_ACCESSOR(NormalizedMapCache) | 3343 CAST_ACCESSOR(NormalizedMapCache) |
| 3295 CAST_ACCESSOR(Object) | 3344 CAST_ACCESSOR(Object) |
| 3296 CAST_ACCESSOR(ObjectHashTable) | 3345 CAST_ACCESSOR(ObjectHashTable) |
| 3297 CAST_ACCESSOR(Oddball) | 3346 CAST_ACCESSOR(Oddball) |
| 3298 CAST_ACCESSOR(OrderedHashMap) | 3347 CAST_ACCESSOR(OrderedHashMap) |
| 3299 CAST_ACCESSOR(OrderedHashSet) | 3348 CAST_ACCESSOR(OrderedHashSet) |
| (...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4322 | 4371 |
| 4323 | 4372 |
| 4324 int Map::GetInObjectPropertyOffset(int index) { | 4373 int Map::GetInObjectPropertyOffset(int index) { |
| 4325 // Adjust for the number of properties stored in the object. | 4374 // Adjust for the number of properties stored in the object. |
| 4326 index -= inobject_properties(); | 4375 index -= inobject_properties(); |
| 4327 DCHECK(index <= 0); | 4376 DCHECK(index <= 0); |
| 4328 return instance_size() + (index * kPointerSize); | 4377 return instance_size() + (index * kPointerSize); |
| 4329 } | 4378 } |
| 4330 | 4379 |
| 4331 | 4380 |
| 4381 Handle<Map> Map::CopyInstallDescriptorsForTesting( |
| 4382 Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors, |
| 4383 Handle<LayoutDescriptor> layout_descriptor) { |
| 4384 return CopyInstallDescriptors(map, new_descriptor, descriptors, |
| 4385 layout_descriptor); |
| 4386 } |
| 4387 |
| 4388 |
| 4332 int HeapObject::SizeFromMap(Map* map) { | 4389 int HeapObject::SizeFromMap(Map* map) { |
| 4333 int instance_size = map->instance_size(); | 4390 int instance_size = map->instance_size(); |
| 4334 if (instance_size != kVariableSizeSentinel) return instance_size; | 4391 if (instance_size != kVariableSizeSentinel) return instance_size; |
| 4335 // Only inline the most frequent cases. | 4392 // Only inline the most frequent cases. |
| 4336 InstanceType instance_type = map->instance_type(); | 4393 InstanceType instance_type = map->instance_type(); |
| 4337 if (instance_type == FIXED_ARRAY_TYPE) { | 4394 if (instance_type == FIXED_ARRAY_TYPE) { |
| 4338 return FixedArray::BodyDescriptor::SizeOf(map, this); | 4395 return FixedArray::BodyDescriptor::SizeOf(map, this); |
| 4339 } | 4396 } |
| 4340 if (instance_type == ONE_BYTE_STRING_TYPE || | 4397 if (instance_type == ONE_BYTE_STRING_TYPE || |
| 4341 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) { | 4398 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) { |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5167 transitions->set_back_pointer_storage(map->GetBackPointer()); | 5224 transitions->set_back_pointer_storage(map->GetBackPointer()); |
| 5168 } else if (!map->transitions()->IsFullTransitionArray()) { | 5225 } else if (!map->transitions()->IsFullTransitionArray()) { |
| 5169 transitions = TransitionArray::ExtendToFullTransitionArray(map); | 5226 transitions = TransitionArray::ExtendToFullTransitionArray(map); |
| 5170 } else { | 5227 } else { |
| 5171 return; | 5228 return; |
| 5172 } | 5229 } |
| 5173 map->set_transitions(*transitions); | 5230 map->set_transitions(*transitions); |
| 5174 } | 5231 } |
| 5175 | 5232 |
| 5176 | 5233 |
| 5177 void Map::InitializeDescriptors(DescriptorArray* descriptors) { | 5234 LayoutDescriptor* Map::layout_descriptor_gc_safe() { |
| 5235 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); |
| 5236 return LayoutDescriptor::cast_gc_safe(layout_desc); |
| 5237 } |
| 5238 |
| 5239 |
| 5240 void Map::UpdateDescriptors(DescriptorArray* descriptors, |
| 5241 LayoutDescriptor* layout_desc) { |
| 5242 set_instance_descriptors(descriptors); |
| 5243 if (FLAG_unbox_double_fields) { |
| 5244 if (layout_descriptor()->IsSlowLayout()) { |
| 5245 set_layout_descriptor(layout_desc); |
| 5246 } |
| 5247 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this)); |
| 5248 DCHECK(visitor_id() == StaticVisitorBase::GetVisitorId(this)); |
| 5249 } |
| 5250 } |
| 5251 |
| 5252 |
| 5253 void Map::InitializeDescriptors(DescriptorArray* descriptors, |
| 5254 LayoutDescriptor* layout_desc) { |
| 5178 int len = descriptors->number_of_descriptors(); | 5255 int len = descriptors->number_of_descriptors(); |
| 5179 set_instance_descriptors(descriptors); | 5256 set_instance_descriptors(descriptors); |
| 5180 SetNumberOfOwnDescriptors(len); | 5257 SetNumberOfOwnDescriptors(len); |
| 5258 |
| 5259 if (FLAG_unbox_double_fields) { |
| 5260 set_layout_descriptor(layout_desc); |
| 5261 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this)); |
| 5262 set_visitor_id(StaticVisitorBase::GetVisitorId(this)); |
| 5263 } |
| 5181 } | 5264 } |
| 5182 | 5265 |
| 5183 | 5266 |
| 5184 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset) | 5267 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset) |
| 5268 ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset) |
| 5185 | 5269 |
| 5186 | 5270 |
| 5187 void Map::set_bit_field3(uint32_t bits) { | 5271 void Map::set_bit_field3(uint32_t bits) { |
| 5188 if (kInt32Size != kPointerSize) { | 5272 if (kInt32Size != kPointerSize) { |
| 5189 WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0); | 5273 WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0); |
| 5190 } | 5274 } |
| 5191 WRITE_UINT32_FIELD(this, kBitField3Offset, bits); | 5275 WRITE_UINT32_FIELD(this, kBitField3Offset, bits); |
| 5192 } | 5276 } |
| 5193 | 5277 |
| 5194 | 5278 |
| 5195 uint32_t Map::bit_field3() { | 5279 uint32_t Map::bit_field3() { |
| 5196 return READ_UINT32_FIELD(this, kBitField3Offset); | 5280 return READ_UINT32_FIELD(this, kBitField3Offset); |
| 5197 } | 5281 } |
| 5198 | 5282 |
| 5199 | 5283 |
| 5284 Handle<LayoutDescriptor> Map::GetLayoutDescriptor() { |
| 5285 LayoutDescriptor* layout_desc = FLAG_unbox_double_fields |
| 5286 ? layout_descriptor() |
| 5287 : LayoutDescriptor::FastPointerLayout(); |
| 5288 return handle(layout_desc, GetIsolate()); |
| 5289 } |
| 5290 |
| 5291 |
| 5200 void Map::AppendDescriptor(Descriptor* desc) { | 5292 void Map::AppendDescriptor(Descriptor* desc) { |
| 5201 DescriptorArray* descriptors = instance_descriptors(); | 5293 DescriptorArray* descriptors = instance_descriptors(); |
| 5202 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5294 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 5203 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); | 5295 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); |
| 5204 descriptors->Append(desc); | 5296 descriptors->Append(desc); |
| 5205 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); | 5297 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); |
| 5298 |
| 5299 // This function does not support appending double field descriptors and |
| 5300 // it should never try to (otherwise, layout descriptor must be updated too). |
| 5301 #ifdef DEBUG |
| 5302 PropertyDetails details = desc->GetDetails(); |
| 5303 CHECK(details.type() != FIELD || !details.representation().IsDouble()); |
| 5304 #endif |
| 5206 } | 5305 } |
| 5207 | 5306 |
| 5208 | 5307 |
| 5209 Object* Map::GetBackPointer() { | 5308 Object* Map::GetBackPointer() { |
| 5210 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 5309 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 5211 if (object->IsDescriptorArray()) { | 5310 if (object->IsDescriptorArray()) { |
| 5212 return TransitionArray::cast(object)->back_pointer_storage(); | 5311 return TransitionArray::cast(object)->back_pointer_storage(); |
| 5213 } else { | 5312 } else { |
| 5214 DCHECK(object->IsMap() || object->IsUndefined()); | 5313 DCHECK(object->IsMap() || object->IsUndefined()); |
| 5215 return object; | 5314 return object; |
| (...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7272 | 7371 |
| 7273 | 7372 |
| 7274 template<typename StaticVisitor> | 7373 template<typename StaticVisitor> |
| 7275 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() { | 7374 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() { |
| 7276 typedef v8::String::ExternalStringResource Resource; | 7375 typedef v8::String::ExternalStringResource Resource; |
| 7277 StaticVisitor::VisitExternalTwoByteString( | 7376 StaticVisitor::VisitExternalTwoByteString( |
| 7278 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); | 7377 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); |
| 7279 } | 7378 } |
| 7280 | 7379 |
| 7281 | 7380 |
| 7381 static void IterateBodyUsingLayoutDescriptor(HeapObject* object, |
| 7382 int start_offset, int end_offset, |
| 7383 ObjectVisitor* v) { |
| 7384 DCHECK(FLAG_unbox_double_fields); |
| 7385 DCHECK(IsAligned(start_offset, kPointerSize) && |
| 7386 IsAligned(end_offset, kPointerSize)); |
| 7387 |
| 7388 InobjectPropertiesHelper helper(object->map()); |
| 7389 DCHECK(!helper.all_fields_tagged()); |
| 7390 |
| 7391 for (int offset = start_offset; offset < end_offset; offset += kPointerSize) { |
| 7392 // Visit all tagged fields. |
| 7393 if (helper.IsTagged(offset)) { |
| 7394 v->VisitPointer(HeapObject::RawField(object, offset)); |
| 7395 } |
| 7396 } |
| 7397 } |
| 7398 |
| 7399 |
| 7282 template<int start_offset, int end_offset, int size> | 7400 template<int start_offset, int end_offset, int size> |
| 7283 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody( | 7401 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody( |
| 7284 HeapObject* obj, | 7402 HeapObject* obj, |
| 7285 ObjectVisitor* v) { | 7403 ObjectVisitor* v) { |
| 7404 if (!FLAG_unbox_double_fields || |
| 7405 obj->map()->layout_descriptor()->IsFastPointerLayout()) { |
| 7286 v->VisitPointers(HeapObject::RawField(obj, start_offset), | 7406 v->VisitPointers(HeapObject::RawField(obj, start_offset), |
| 7287 HeapObject::RawField(obj, end_offset)); | 7407 HeapObject::RawField(obj, end_offset)); |
| 7408 } else { |
| 7409 IterateBodyUsingLayoutDescriptor(obj, start_offset, end_offset, v); |
| 7410 } |
| 7288 } | 7411 } |
| 7289 | 7412 |
| 7290 | 7413 |
| 7291 template<int start_offset> | 7414 template<int start_offset> |
| 7292 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, | 7415 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, |
| 7293 int object_size, | 7416 int object_size, |
| 7294 ObjectVisitor* v) { | 7417 ObjectVisitor* v) { |
| 7295 v->VisitPointers(HeapObject::RawField(obj, start_offset), | 7418 if (!FLAG_unbox_double_fields || |
| 7296 HeapObject::RawField(obj, object_size)); | 7419 obj->map()->layout_descriptor()->IsFastPointerLayout()) { |
| 7420 v->VisitPointers(HeapObject::RawField(obj, start_offset), |
| 7421 HeapObject::RawField(obj, object_size)); |
| 7422 } else { |
| 7423 IterateBodyUsingLayoutDescriptor(obj, start_offset, object_size, v); |
| 7424 } |
| 7297 } | 7425 } |
| 7298 | 7426 |
| 7299 | 7427 |
| 7300 template<class Derived, class TableType> | 7428 template<class Derived, class TableType> |
| 7301 Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() { | 7429 Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() { |
| 7302 TableType* table(TableType::cast(this->table())); | 7430 TableType* table(TableType::cast(this->table())); |
| 7303 int index = Smi::cast(this->index())->value(); | 7431 int index = Smi::cast(this->index())->value(); |
| 7304 Object* key = table->KeyAt(index); | 7432 Object* key = table->KeyAt(index); |
| 7305 DCHECK(!key->IsTheHole()); | 7433 DCHECK(!key->IsTheHole()); |
| 7306 return key; | 7434 return key; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7356 #undef READ_SHORT_FIELD | 7484 #undef READ_SHORT_FIELD |
| 7357 #undef WRITE_SHORT_FIELD | 7485 #undef WRITE_SHORT_FIELD |
| 7358 #undef READ_BYTE_FIELD | 7486 #undef READ_BYTE_FIELD |
| 7359 #undef WRITE_BYTE_FIELD | 7487 #undef WRITE_BYTE_FIELD |
| 7360 #undef NOBARRIER_READ_BYTE_FIELD | 7488 #undef NOBARRIER_READ_BYTE_FIELD |
| 7361 #undef NOBARRIER_WRITE_BYTE_FIELD | 7489 #undef NOBARRIER_WRITE_BYTE_FIELD |
| 7362 | 7490 |
| 7363 } } // namespace v8::internal | 7491 } } // namespace v8::internal |
| 7364 | 7492 |
| 7365 #endif // V8_OBJECTS_INL_H_ | 7493 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |