OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_LAYOUT_DESCRIPTOR_INL_H_ | 5 #ifndef V8_LAYOUT_DESCRIPTOR_INL_H_ |
6 #define V8_LAYOUT_DESCRIPTOR_INL_H_ | 6 #define V8_LAYOUT_DESCRIPTOR_INL_H_ |
7 | 7 |
8 #include "src/layout-descriptor.h" | 8 #include "src/layout-descriptor.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
13 LayoutDescriptor* LayoutDescriptor::FromSmi(Smi* smi) { | 13 LayoutDescriptor* LayoutDescriptor::FromSmi(Smi* smi) { |
14 return LayoutDescriptor::cast(smi); | 14 return LayoutDescriptor::cast(smi); |
15 } | 15 } |
16 | 16 |
17 | 17 |
18 Handle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate, int length) { | 18 Handle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate, int length) { |
19 if (length <= kSmiValueSize) { | 19 if (length <= kSmiValueSize) { |
20 // The whole bit vector fits into a smi. | 20 // The whole bit vector fits into a smi. |
21 return handle(LayoutDescriptor::FromSmi(Smi::FromInt(0)), isolate); | 21 return handle(LayoutDescriptor::FromSmi(Smi::FromInt(0)), isolate); |
22 } | 22 } |
23 | 23 length = GetSlowModeBackingStoreLength(length); |
24 length = (length + kNumberOfBits - 1) / kNumberOfBits; | |
25 DCHECK(length > 0); | |
26 | |
27 if (SmiValuesAre32Bits() && (length & 1)) { | |
28 // On 64-bit systems if the length is odd then the half-word space would be | |
29 // lost anyway (due to alignment and the fact that we are allocating | |
30 // uint32-typed array), so we increase the length of allocated array | |
31 // to utilize that "lost" space which could also help to avoid layout | |
32 // descriptor reallocations. | |
33 ++length; | |
34 } | |
35 return Handle<LayoutDescriptor>::cast( | 24 return Handle<LayoutDescriptor>::cast( |
36 isolate->factory()->NewFixedTypedArray(length, kExternalUint32Array)); | 25 isolate->factory()->NewFixedTypedArray(length, kExternalUint32Array)); |
37 } | 26 } |
38 | 27 |
39 | 28 |
40 bool LayoutDescriptor::InobjectUnboxedField(int inobject_properties, | 29 bool LayoutDescriptor::InobjectUnboxedField(int inobject_properties, |
41 PropertyDetails details) { | 30 PropertyDetails details) { |
42 if (details.type() != DATA || !details.representation().IsDouble()) { | 31 if (details.type() != DATA || !details.representation().IsDouble()) { |
43 return false; | 32 return false; |
44 } | 33 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 // This is a mixed descriptor which is a fixed typed array. | 136 // This is a mixed descriptor which is a fixed typed array. |
148 MapWord map_word = reinterpret_cast<HeapObject*>(object)->map_word(); | 137 MapWord map_word = reinterpret_cast<HeapObject*>(object)->map_word(); |
149 if (map_word.IsForwardingAddress()) { | 138 if (map_word.IsForwardingAddress()) { |
150 // Mark-compact has already moved layout descriptor. | 139 // Mark-compact has already moved layout descriptor. |
151 object = map_word.ToForwardingAddress(); | 140 object = map_word.ToForwardingAddress(); |
152 } | 141 } |
153 return LayoutDescriptor::cast(object); | 142 return LayoutDescriptor::cast(object); |
154 } | 143 } |
155 | 144 |
156 | 145 |
| 146 int LayoutDescriptor::GetSlowModeBackingStoreLength(int length) { |
| 147 length = (length + kNumberOfBits - 1) / kNumberOfBits; |
| 148 DCHECK_LT(0, length); |
| 149 |
| 150 if (SmiValuesAre32Bits() && (length & 1)) { |
| 151 // On 64-bit systems if the length is odd then the half-word space would be |
| 152 // lost anyway (due to alignment and the fact that we are allocating |
| 153 // uint32-typed array), so we increase the length of allocated array |
| 154 // to utilize that "lost" space which could also help to avoid layout |
| 155 // descriptor reallocations. |
| 156 ++length; |
| 157 } |
| 158 return length; |
| 159 } |
| 160 |
| 161 |
| 162 int LayoutDescriptor::CalculateCapacity(Map* map, DescriptorArray* descriptors, |
| 163 int num_descriptors) { |
| 164 int inobject_properties = map->inobject_properties(); |
| 165 if (inobject_properties == 0) return 0; |
| 166 |
| 167 DCHECK_LE(num_descriptors, descriptors->number_of_descriptors()); |
| 168 |
| 169 int layout_descriptor_length; |
| 170 const int kMaxWordsPerField = kDoubleSize / kPointerSize; |
| 171 |
| 172 if (num_descriptors <= kSmiValueSize / kMaxWordsPerField) { |
| 173 // Even in the "worst" case (all fields are doubles) it would fit into |
| 174 // a Smi, so no need to calculate length. |
| 175 layout_descriptor_length = kSmiValueSize; |
| 176 |
| 177 } else { |
| 178 layout_descriptor_length = 0; |
| 179 |
| 180 for (int i = 0; i < num_descriptors; i++) { |
| 181 PropertyDetails details = descriptors->GetDetails(i); |
| 182 if (!InobjectUnboxedField(inobject_properties, details)) continue; |
| 183 int field_index = details.field_index(); |
| 184 int field_width_in_words = details.field_width_in_words(); |
| 185 layout_descriptor_length = |
| 186 Max(layout_descriptor_length, field_index + field_width_in_words); |
| 187 } |
| 188 } |
| 189 layout_descriptor_length = Min(layout_descriptor_length, inobject_properties); |
| 190 return layout_descriptor_length; |
| 191 } |
| 192 |
| 193 |
| 194 LayoutDescriptor* LayoutDescriptor::Initialize( |
| 195 LayoutDescriptor* layout_descriptor, Map* map, DescriptorArray* descriptors, |
| 196 int num_descriptors) { |
| 197 DisallowHeapAllocation no_allocation; |
| 198 int inobject_properties = map->inobject_properties(); |
| 199 |
| 200 for (int i = 0; i < num_descriptors; i++) { |
| 201 PropertyDetails details = descriptors->GetDetails(i); |
| 202 if (!InobjectUnboxedField(inobject_properties, details)) { |
| 203 DCHECK(details.location() != kField || |
| 204 layout_descriptor->IsTagged(details.field_index())); |
| 205 continue; |
| 206 } |
| 207 int field_index = details.field_index(); |
| 208 layout_descriptor = layout_descriptor->SetRawData(field_index); |
| 209 if (details.field_width_in_words() > 1) { |
| 210 layout_descriptor = layout_descriptor->SetRawData(field_index + 1); |
| 211 } |
| 212 } |
| 213 return layout_descriptor; |
| 214 } |
| 215 |
| 216 |
157 // InobjectPropertiesHelper is a helper class for querying whether inobject | 217 // InobjectPropertiesHelper is a helper class for querying whether inobject |
158 // property at offset is Double or not. | 218 // property at offset is Double or not. |
159 LayoutDescriptorHelper::LayoutDescriptorHelper(Map* map) | 219 LayoutDescriptorHelper::LayoutDescriptorHelper(Map* map) |
160 : all_fields_tagged_(true), | 220 : all_fields_tagged_(true), |
161 header_size_(0), | 221 header_size_(0), |
162 layout_descriptor_(LayoutDescriptor::FastPointerLayout()) { | 222 layout_descriptor_(LayoutDescriptor::FastPointerLayout()) { |
163 if (!FLAG_unbox_double_fields) return; | 223 if (!FLAG_unbox_double_fields) return; |
164 | 224 |
165 layout_descriptor_ = map->layout_descriptor_gc_safe(); | 225 layout_descriptor_ = map->layout_descriptor_gc_safe(); |
166 if (layout_descriptor_->IsFastPointerLayout()) { | 226 if (layout_descriptor_->IsFastPointerLayout()) { |
(...skipping 15 matching lines...) Expand all Loading... |
182 // Object headers do not contain non-tagged fields. | 242 // Object headers do not contain non-tagged fields. |
183 if (offset_in_bytes < header_size_) return true; | 243 if (offset_in_bytes < header_size_) return true; |
184 int field_index = (offset_in_bytes - header_size_) / kPointerSize; | 244 int field_index = (offset_in_bytes - header_size_) / kPointerSize; |
185 | 245 |
186 return layout_descriptor_->IsTagged(field_index); | 246 return layout_descriptor_->IsTagged(field_index); |
187 } | 247 } |
188 } | 248 } |
189 } // namespace v8::internal | 249 } // namespace v8::internal |
190 | 250 |
191 #endif // V8_LAYOUT_DESCRIPTOR_INL_H_ | 251 #endif // V8_LAYOUT_DESCRIPTOR_INL_H_ |
OLD | NEW |