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 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 bool Object::IsJSWeakCollection() const { | 701 bool Object::IsJSWeakCollection() const { |
693 return IsJSWeakMap() || IsJSWeakSet(); | 702 return IsJSWeakMap() || IsJSWeakSet(); |
694 } | 703 } |
695 | 704 |
696 | 705 |
697 bool Object::IsDescriptorArray() const { | 706 bool Object::IsDescriptorArray() const { |
698 return IsFixedArray(); | 707 return IsFixedArray(); |
699 } | 708 } |
700 | 709 |
701 | 710 |
| 711 bool Object::IsLayoutDescriptor() const { |
| 712 return IsSmi() || IsFixedTypedArrayBase(); |
| 713 } |
| 714 |
| 715 |
702 bool Object::IsTransitionArray() const { | 716 bool Object::IsTransitionArray() const { |
703 return IsFixedArray(); | 717 return IsFixedArray(); |
704 } | 718 } |
705 | 719 |
706 | 720 |
707 bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); } | 721 bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); } |
708 | 722 |
709 | 723 |
710 bool Object::IsDeoptimizationInputData() const { | 724 bool Object::IsDeoptimizationInputData() const { |
711 // Must be a fixed array. | 725 // Must be a fixed array. |
(...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 void JSObject::SetInternalField(int index, Smi* value) { | 2072 void JSObject::SetInternalField(int index, Smi* value) { |
2059 DCHECK(index < GetInternalFieldCount() && index >= 0); | 2073 DCHECK(index < GetInternalFieldCount() && index >= 0); |
2060 // Internal objects do follow immediately after the header, whereas in-object | 2074 // Internal objects do follow immediately after the header, whereas in-object |
2061 // properties are at the end of the object. Therefore there is no need | 2075 // properties are at the end of the object. Therefore there is no need |
2062 // to adjust the index here. | 2076 // to adjust the index here. |
2063 int offset = GetHeaderSize() + (kPointerSize * index); | 2077 int offset = GetHeaderSize() + (kPointerSize * index); |
2064 WRITE_FIELD(this, offset, value); | 2078 WRITE_FIELD(this, offset, value); |
2065 } | 2079 } |
2066 | 2080 |
2067 | 2081 |
| 2082 bool JSObject::IsUnboxedDoubleField(FieldIndex index) { |
| 2083 if (!FLAG_unbox_double_fields) return false; |
| 2084 return map()->IsUnboxedDoubleField(index); |
| 2085 } |
| 2086 |
| 2087 |
| 2088 bool Map::IsUnboxedDoubleField(FieldIndex index) { |
| 2089 if (!FLAG_unbox_double_fields) return false; |
| 2090 if (index.is_hidden_field() || !index.is_inobject()) return false; |
| 2091 return !layout_descriptor()->IsTagged(index.property_index()); |
| 2092 } |
| 2093 |
| 2094 |
2068 // Access fast-case object properties at index. The use of these routines | 2095 // Access fast-case object properties at index. The use of these routines |
2069 // is needed to correctly distinguish between properties stored in-object and | 2096 // is needed to correctly distinguish between properties stored in-object and |
2070 // properties stored in the properties array. | 2097 // properties stored in the properties array. |
2071 Object* JSObject::RawFastPropertyAt(FieldIndex index) { | 2098 Object* JSObject::RawFastPropertyAt(FieldIndex index) { |
| 2099 DCHECK(!IsUnboxedDoubleField(index)); |
2072 if (index.is_inobject()) { | 2100 if (index.is_inobject()) { |
2073 return READ_FIELD(this, index.offset()); | 2101 return READ_FIELD(this, index.offset()); |
2074 } else { | 2102 } else { |
2075 return properties()->get(index.outobject_array_index()); | 2103 return properties()->get(index.outobject_array_index()); |
2076 } | 2104 } |
2077 } | 2105 } |
2078 | 2106 |
2079 | 2107 |
2080 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { | 2108 double JSObject::RawFastDoublePropertyAt(FieldIndex index) { |
| 2109 DCHECK(IsUnboxedDoubleField(index)); |
| 2110 return READ_DOUBLE_FIELD(this, index.offset()); |
| 2111 } |
| 2112 |
| 2113 |
| 2114 void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) { |
2081 if (index.is_inobject()) { | 2115 if (index.is_inobject()) { |
2082 int offset = index.offset(); | 2116 int offset = index.offset(); |
2083 WRITE_FIELD(this, offset, value); | 2117 WRITE_FIELD(this, offset, value); |
2084 WRITE_BARRIER(GetHeap(), this, offset, value); | 2118 WRITE_BARRIER(GetHeap(), this, offset, value); |
2085 } else { | 2119 } else { |
2086 properties()->set(index.outobject_array_index(), value); | 2120 properties()->set(index.outobject_array_index(), value); |
2087 } | 2121 } |
2088 } | 2122 } |
2089 | 2123 |
2090 | 2124 |
| 2125 void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) { |
| 2126 WRITE_DOUBLE_FIELD(this, index.offset(), value); |
| 2127 } |
| 2128 |
| 2129 |
| 2130 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { |
| 2131 if (IsUnboxedDoubleField(index)) { |
| 2132 DCHECK(value->IsMutableHeapNumber()); |
| 2133 RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value()); |
| 2134 } else { |
| 2135 RawFastPropertyAtPut(index, value); |
| 2136 } |
| 2137 } |
| 2138 |
| 2139 |
2091 int JSObject::GetInObjectPropertyOffset(int index) { | 2140 int JSObject::GetInObjectPropertyOffset(int index) { |
2092 return map()->GetInObjectPropertyOffset(index); | 2141 return map()->GetInObjectPropertyOffset(index); |
2093 } | 2142 } |
2094 | 2143 |
2095 | 2144 |
2096 Object* JSObject::InObjectPropertyAt(int index) { | 2145 Object* JSObject::InObjectPropertyAt(int index) { |
2097 int offset = GetInObjectPropertyOffset(index); | 2146 int offset = GetInObjectPropertyOffset(index); |
2098 return READ_FIELD(this, offset); | 2147 return READ_FIELD(this, offset); |
2099 } | 2148 } |
2100 | 2149 |
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3099 const WhitenessWitness&) { | 3148 const WhitenessWitness&) { |
3100 // Range check. | 3149 // Range check. |
3101 DCHECK(descriptor_number < number_of_descriptors()); | 3150 DCHECK(descriptor_number < number_of_descriptors()); |
3102 | 3151 |
3103 NoIncrementalWriteBarrierSet(this, | 3152 NoIncrementalWriteBarrierSet(this, |
3104 ToKeyIndex(descriptor_number), | 3153 ToKeyIndex(descriptor_number), |
3105 *desc->GetKey()); | 3154 *desc->GetKey()); |
3106 NoIncrementalWriteBarrierSet(this, | 3155 NoIncrementalWriteBarrierSet(this, |
3107 ToValueIndex(descriptor_number), | 3156 ToValueIndex(descriptor_number), |
3108 *desc->GetValue()); | 3157 *desc->GetValue()); |
3109 NoIncrementalWriteBarrierSet(this, | 3158 NoIncrementalWriteBarrierSet(this, ToDetailsIndex(descriptor_number), |
3110 ToDetailsIndex(descriptor_number), | |
3111 desc->GetDetails().AsSmi()); | 3159 desc->GetDetails().AsSmi()); |
3112 } | 3160 } |
3113 | 3161 |
3114 | 3162 |
3115 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { | 3163 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { |
3116 // Range check. | 3164 // Range check. |
3117 DCHECK(descriptor_number < number_of_descriptors()); | 3165 DCHECK(descriptor_number < number_of_descriptors()); |
3118 | 3166 |
3119 set(ToKeyIndex(descriptor_number), *desc->GetKey()); | 3167 set(ToKeyIndex(descriptor_number), *desc->GetKey()); |
3120 set(ToValueIndex(descriptor_number), *desc->GetValue()); | 3168 set(ToValueIndex(descriptor_number), *desc->GetValue()); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3275 CAST_ACCESSOR(JSObject) | 3323 CAST_ACCESSOR(JSObject) |
3276 CAST_ACCESSOR(JSProxy) | 3324 CAST_ACCESSOR(JSProxy) |
3277 CAST_ACCESSOR(JSReceiver) | 3325 CAST_ACCESSOR(JSReceiver) |
3278 CAST_ACCESSOR(JSRegExp) | 3326 CAST_ACCESSOR(JSRegExp) |
3279 CAST_ACCESSOR(JSSet) | 3327 CAST_ACCESSOR(JSSet) |
3280 CAST_ACCESSOR(JSSetIterator) | 3328 CAST_ACCESSOR(JSSetIterator) |
3281 CAST_ACCESSOR(JSTypedArray) | 3329 CAST_ACCESSOR(JSTypedArray) |
3282 CAST_ACCESSOR(JSValue) | 3330 CAST_ACCESSOR(JSValue) |
3283 CAST_ACCESSOR(JSWeakMap) | 3331 CAST_ACCESSOR(JSWeakMap) |
3284 CAST_ACCESSOR(JSWeakSet) | 3332 CAST_ACCESSOR(JSWeakSet) |
| 3333 CAST_ACCESSOR(LayoutDescriptor) |
3285 CAST_ACCESSOR(Map) | 3334 CAST_ACCESSOR(Map) |
3286 CAST_ACCESSOR(Name) | 3335 CAST_ACCESSOR(Name) |
3287 CAST_ACCESSOR(NameDictionary) | 3336 CAST_ACCESSOR(NameDictionary) |
3288 CAST_ACCESSOR(NormalizedMapCache) | 3337 CAST_ACCESSOR(NormalizedMapCache) |
3289 CAST_ACCESSOR(Object) | 3338 CAST_ACCESSOR(Object) |
3290 CAST_ACCESSOR(ObjectHashTable) | 3339 CAST_ACCESSOR(ObjectHashTable) |
3291 CAST_ACCESSOR(Oddball) | 3340 CAST_ACCESSOR(Oddball) |
3292 CAST_ACCESSOR(OrderedHashMap) | 3341 CAST_ACCESSOR(OrderedHashMap) |
3293 CAST_ACCESSOR(OrderedHashSet) | 3342 CAST_ACCESSOR(OrderedHashSet) |
3294 CAST_ACCESSOR(PolymorphicCodeCacheHashTable) | 3343 CAST_ACCESSOR(PolymorphicCodeCacheHashTable) |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4316 | 4365 |
4317 | 4366 |
4318 int Map::GetInObjectPropertyOffset(int index) { | 4367 int Map::GetInObjectPropertyOffset(int index) { |
4319 // Adjust for the number of properties stored in the object. | 4368 // Adjust for the number of properties stored in the object. |
4320 index -= inobject_properties(); | 4369 index -= inobject_properties(); |
4321 DCHECK(index <= 0); | 4370 DCHECK(index <= 0); |
4322 return instance_size() + (index * kPointerSize); | 4371 return instance_size() + (index * kPointerSize); |
4323 } | 4372 } |
4324 | 4373 |
4325 | 4374 |
| 4375 Handle<Map> Map::CopyInstallDescriptorsForTesting( |
| 4376 Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors, |
| 4377 Handle<LayoutDescriptor> layout_descriptor) { |
| 4378 return CopyInstallDescriptors(map, new_descriptor, descriptors, |
| 4379 layout_descriptor); |
| 4380 } |
| 4381 |
| 4382 |
4326 int HeapObject::SizeFromMap(Map* map) { | 4383 int HeapObject::SizeFromMap(Map* map) { |
4327 int instance_size = map->instance_size(); | 4384 int instance_size = map->instance_size(); |
4328 if (instance_size != kVariableSizeSentinel) return instance_size; | 4385 if (instance_size != kVariableSizeSentinel) return instance_size; |
4329 // Only inline the most frequent cases. | 4386 // Only inline the most frequent cases. |
4330 InstanceType instance_type = map->instance_type(); | 4387 InstanceType instance_type = map->instance_type(); |
4331 if (instance_type == FIXED_ARRAY_TYPE) { | 4388 if (instance_type == FIXED_ARRAY_TYPE) { |
4332 return FixedArray::BodyDescriptor::SizeOf(map, this); | 4389 return FixedArray::BodyDescriptor::SizeOf(map, this); |
4333 } | 4390 } |
4334 if (instance_type == ONE_BYTE_STRING_TYPE || | 4391 if (instance_type == ONE_BYTE_STRING_TYPE || |
4335 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) { | 4392 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) { |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5161 transitions->set_back_pointer_storage(map->GetBackPointer()); | 5218 transitions->set_back_pointer_storage(map->GetBackPointer()); |
5162 } else if (!map->transitions()->IsFullTransitionArray()) { | 5219 } else if (!map->transitions()->IsFullTransitionArray()) { |
5163 transitions = TransitionArray::ExtendToFullTransitionArray(map); | 5220 transitions = TransitionArray::ExtendToFullTransitionArray(map); |
5164 } else { | 5221 } else { |
5165 return; | 5222 return; |
5166 } | 5223 } |
5167 map->set_transitions(*transitions); | 5224 map->set_transitions(*transitions); |
5168 } | 5225 } |
5169 | 5226 |
5170 | 5227 |
5171 void Map::InitializeDescriptors(DescriptorArray* descriptors) { | 5228 LayoutDescriptor* Map::layout_descriptor_gc_safe() { |
| 5229 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); |
| 5230 return LayoutDescriptor::cast_gc_safe(layout_desc); |
| 5231 } |
| 5232 |
| 5233 |
| 5234 void Map::UpdateDescriptors(DescriptorArray* descriptors, |
| 5235 LayoutDescriptor* layout_desc) { |
| 5236 set_instance_descriptors(descriptors); |
| 5237 if (FLAG_unbox_double_fields) { |
| 5238 if (layout_descriptor()->IsSlowLayout()) { |
| 5239 set_layout_descriptor(layout_desc); |
| 5240 } |
| 5241 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this)); |
| 5242 DCHECK(visitor_id() == StaticVisitorBase::GetVisitorId(this)); |
| 5243 } |
| 5244 } |
| 5245 |
| 5246 |
| 5247 void Map::InitializeDescriptors(DescriptorArray* descriptors, |
| 5248 LayoutDescriptor* layout_desc) { |
5172 int len = descriptors->number_of_descriptors(); | 5249 int len = descriptors->number_of_descriptors(); |
5173 set_instance_descriptors(descriptors); | 5250 set_instance_descriptors(descriptors); |
5174 SetNumberOfOwnDescriptors(len); | 5251 SetNumberOfOwnDescriptors(len); |
| 5252 |
| 5253 if (FLAG_unbox_double_fields) { |
| 5254 set_layout_descriptor(layout_desc); |
| 5255 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this)); |
| 5256 set_visitor_id(StaticVisitorBase::GetVisitorId(this)); |
| 5257 } |
5175 } | 5258 } |
5176 | 5259 |
5177 | 5260 |
5178 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset) | 5261 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset) |
| 5262 ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset) |
5179 | 5263 |
5180 | 5264 |
5181 void Map::set_bit_field3(uint32_t bits) { | 5265 void Map::set_bit_field3(uint32_t bits) { |
5182 if (kInt32Size != kPointerSize) { | 5266 if (kInt32Size != kPointerSize) { |
5183 WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0); | 5267 WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0); |
5184 } | 5268 } |
5185 WRITE_UINT32_FIELD(this, kBitField3Offset, bits); | 5269 WRITE_UINT32_FIELD(this, kBitField3Offset, bits); |
5186 } | 5270 } |
5187 | 5271 |
5188 | 5272 |
5189 uint32_t Map::bit_field3() { | 5273 uint32_t Map::bit_field3() { |
5190 return READ_UINT32_FIELD(this, kBitField3Offset); | 5274 return READ_UINT32_FIELD(this, kBitField3Offset); |
5191 } | 5275 } |
5192 | 5276 |
5193 | 5277 |
| 5278 LayoutDescriptor* Map::GetLayoutDescriptor() { |
| 5279 return FLAG_unbox_double_fields ? layout_descriptor() |
| 5280 : LayoutDescriptor::FastPointerLayout(); |
| 5281 } |
| 5282 |
| 5283 |
5194 void Map::AppendDescriptor(Descriptor* desc) { | 5284 void Map::AppendDescriptor(Descriptor* desc) { |
5195 DescriptorArray* descriptors = instance_descriptors(); | 5285 DescriptorArray* descriptors = instance_descriptors(); |
5196 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5286 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
5197 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); | 5287 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); |
5198 descriptors->Append(desc); | 5288 descriptors->Append(desc); |
5199 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); | 5289 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); |
| 5290 |
| 5291 // This function does not support appending double field descriptors and |
| 5292 // it should never try to (otherwise, layout descriptor must be updated too). |
| 5293 #ifdef DEBUG |
| 5294 PropertyDetails details = desc->GetDetails(); |
| 5295 CHECK(details.type() != FIELD || !details.representation().IsDouble()); |
| 5296 #endif |
5200 } | 5297 } |
5201 | 5298 |
5202 | 5299 |
5203 Object* Map::GetBackPointer() { | 5300 Object* Map::GetBackPointer() { |
5204 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 5301 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
5205 if (object->IsDescriptorArray()) { | 5302 if (object->IsDescriptorArray()) { |
5206 return TransitionArray::cast(object)->back_pointer_storage(); | 5303 return TransitionArray::cast(object)->back_pointer_storage(); |
5207 } else { | 5304 } else { |
5208 DCHECK(object->IsMap() || object->IsUndefined()); | 5305 DCHECK(object->IsMap() || object->IsUndefined()); |
5209 return object; | 5306 return object; |
(...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7266 | 7363 |
7267 | 7364 |
7268 template<typename StaticVisitor> | 7365 template<typename StaticVisitor> |
7269 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() { | 7366 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() { |
7270 typedef v8::String::ExternalStringResource Resource; | 7367 typedef v8::String::ExternalStringResource Resource; |
7271 StaticVisitor::VisitExternalTwoByteString( | 7368 StaticVisitor::VisitExternalTwoByteString( |
7272 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); | 7369 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); |
7273 } | 7370 } |
7274 | 7371 |
7275 | 7372 |
| 7373 static inline void IterateBodyUsingLayoutDescriptor(HeapObject* object, |
| 7374 int start_offset, |
| 7375 int end_offset, |
| 7376 ObjectVisitor* v) { |
| 7377 DCHECK(FLAG_unbox_double_fields); |
| 7378 DCHECK(IsAligned(start_offset, kPointerSize) && |
| 7379 IsAligned(end_offset, kPointerSize)); |
| 7380 |
| 7381 InobjectPropertiesHelper helper(object->map()); |
| 7382 DCHECK(!helper.all_fields_tagged()); |
| 7383 |
| 7384 for (int offset = start_offset; offset < end_offset; offset += kPointerSize) { |
| 7385 // Visit all tagged fields. |
| 7386 if (helper.IsTagged(offset)) { |
| 7387 v->VisitPointer(HeapObject::RawField(object, offset)); |
| 7388 } |
| 7389 } |
| 7390 } |
| 7391 |
| 7392 |
7276 template<int start_offset, int end_offset, int size> | 7393 template<int start_offset, int end_offset, int size> |
7277 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody( | 7394 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody( |
7278 HeapObject* obj, | 7395 HeapObject* obj, |
7279 ObjectVisitor* v) { | 7396 ObjectVisitor* v) { |
| 7397 if (!FLAG_unbox_double_fields || |
| 7398 obj->map()->layout_descriptor()->IsFastPointerLayout()) { |
7280 v->VisitPointers(HeapObject::RawField(obj, start_offset), | 7399 v->VisitPointers(HeapObject::RawField(obj, start_offset), |
7281 HeapObject::RawField(obj, end_offset)); | 7400 HeapObject::RawField(obj, end_offset)); |
| 7401 } else { |
| 7402 IterateBodyUsingLayoutDescriptor(obj, start_offset, end_offset, v); |
| 7403 } |
7282 } | 7404 } |
7283 | 7405 |
7284 | 7406 |
7285 template<int start_offset> | 7407 template<int start_offset> |
7286 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, | 7408 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, |
7287 int object_size, | 7409 int object_size, |
7288 ObjectVisitor* v) { | 7410 ObjectVisitor* v) { |
7289 v->VisitPointers(HeapObject::RawField(obj, start_offset), | 7411 if (!FLAG_unbox_double_fields || |
7290 HeapObject::RawField(obj, object_size)); | 7412 obj->map()->layout_descriptor()->IsFastPointerLayout()) { |
| 7413 v->VisitPointers(HeapObject::RawField(obj, start_offset), |
| 7414 HeapObject::RawField(obj, object_size)); |
| 7415 } else { |
| 7416 IterateBodyUsingLayoutDescriptor(obj, start_offset, object_size, v); |
| 7417 } |
7291 } | 7418 } |
7292 | 7419 |
7293 | 7420 |
7294 template<class Derived, class TableType> | 7421 template<class Derived, class TableType> |
7295 Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() { | 7422 Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() { |
7296 TableType* table(TableType::cast(this->table())); | 7423 TableType* table(TableType::cast(this->table())); |
7297 int index = Smi::cast(this->index())->value(); | 7424 int index = Smi::cast(this->index())->value(); |
7298 Object* key = table->KeyAt(index); | 7425 Object* key = table->KeyAt(index); |
7299 DCHECK(!key->IsTheHole()); | 7426 DCHECK(!key->IsTheHole()); |
7300 return key; | 7427 return key; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7350 #undef READ_SHORT_FIELD | 7477 #undef READ_SHORT_FIELD |
7351 #undef WRITE_SHORT_FIELD | 7478 #undef WRITE_SHORT_FIELD |
7352 #undef READ_BYTE_FIELD | 7479 #undef READ_BYTE_FIELD |
7353 #undef WRITE_BYTE_FIELD | 7480 #undef WRITE_BYTE_FIELD |
7354 #undef NOBARRIER_READ_BYTE_FIELD | 7481 #undef NOBARRIER_READ_BYTE_FIELD |
7355 #undef NOBARRIER_WRITE_BYTE_FIELD | 7482 #undef NOBARRIER_WRITE_BYTE_FIELD |
7356 | 7483 |
7357 } } // namespace v8::internal | 7484 } } // namespace v8::internal |
7358 | 7485 |
7359 #endif // V8_OBJECTS_INL_H_ | 7486 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |