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