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 #include <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/layout-descriptor.h" | 10 #include "src/layout-descriptor.h" |
11 | 11 |
12 using v8::base::bits::CountTrailingZeros32; | 12 using v8::base::bits::CountTrailingZeros32; |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 | 16 |
17 Handle<LayoutDescriptor> LayoutDescriptor::New( | 17 Handle<LayoutDescriptor> LayoutDescriptor::New( |
18 Handle<Map> map, Handle<DescriptorArray> descriptors, int num_descriptors) { | 18 Handle<Map> map, Handle<DescriptorArray> descriptors, int num_descriptors) { |
19 Isolate* isolate = descriptors->GetIsolate(); | 19 Isolate* isolate = descriptors->GetIsolate(); |
20 if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate); | 20 if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate); |
21 | 21 |
22 int inobject_properties = map->inobject_properties(); | 22 int layout_descriptor_length = |
23 if (inobject_properties == 0) return handle(FastPointerLayout(), isolate); | 23 CalculateCapacity(*map, *descriptors, num_descriptors); |
24 | 24 |
25 DCHECK(num_descriptors <= descriptors->number_of_descriptors()); | 25 if (layout_descriptor_length == 0) { |
26 | 26 // No double fields were found, use fast pointer layout. |
27 int layout_descriptor_length; | 27 return handle(FastPointerLayout(), isolate); |
28 const int kMaxWordsPerField = kDoubleSize / kPointerSize; | |
29 | |
30 if (num_descriptors <= kSmiValueSize / kMaxWordsPerField) { | |
31 // Even in the "worst" case (all fields are doubles) it would fit into | |
32 // a Smi, so no need to calculate length. | |
33 layout_descriptor_length = kSmiValueSize; | |
34 | |
35 } else { | |
36 layout_descriptor_length = 0; | |
37 | |
38 for (int i = 0; i < num_descriptors; i++) { | |
39 PropertyDetails details = descriptors->GetDetails(i); | |
40 if (!InobjectUnboxedField(inobject_properties, details)) continue; | |
41 int field_index = details.field_index(); | |
42 int field_width_in_words = details.field_width_in_words(); | |
43 layout_descriptor_length = | |
44 Max(layout_descriptor_length, field_index + field_width_in_words); | |
45 } | |
46 | |
47 if (layout_descriptor_length == 0) { | |
48 // No double fields were found, use fast pointer layout. | |
49 return handle(FastPointerLayout(), isolate); | |
50 } | |
51 } | 28 } |
52 layout_descriptor_length = Min(layout_descriptor_length, inobject_properties); | |
53 | 29 |
54 // Initially, layout descriptor corresponds to an object with all fields | 30 // Initially, layout descriptor corresponds to an object with all fields |
55 // tagged. | 31 // tagged. |
56 Handle<LayoutDescriptor> layout_descriptor_handle = | 32 Handle<LayoutDescriptor> layout_descriptor_handle = |
57 LayoutDescriptor::New(isolate, layout_descriptor_length); | 33 LayoutDescriptor::New(isolate, layout_descriptor_length); |
58 | 34 |
59 DisallowHeapAllocation no_allocation; | 35 LayoutDescriptor* layout_descriptor = Initialize( |
60 LayoutDescriptor* layout_descriptor = *layout_descriptor_handle; | 36 *layout_descriptor_handle, *map, *descriptors, num_descriptors); |
61 | 37 |
62 for (int i = 0; i < num_descriptors; i++) { | |
63 PropertyDetails details = descriptors->GetDetails(i); | |
64 if (!InobjectUnboxedField(inobject_properties, details)) continue; | |
65 int field_index = details.field_index(); | |
66 layout_descriptor = layout_descriptor->SetRawData(field_index); | |
67 if (details.field_width_in_words() > 1) { | |
68 layout_descriptor = layout_descriptor->SetRawData(field_index + 1); | |
69 } | |
70 } | |
71 return handle(layout_descriptor, isolate); | 38 return handle(layout_descriptor, isolate); |
72 } | 39 } |
73 | 40 |
74 | 41 |
75 Handle<LayoutDescriptor> LayoutDescriptor::ShareAppend( | 42 Handle<LayoutDescriptor> LayoutDescriptor::ShareAppend( |
76 Handle<Map> map, PropertyDetails details) { | 43 Handle<Map> map, PropertyDetails details) { |
77 DCHECK(map->owns_descriptors()); | 44 DCHECK(map->owns_descriptors()); |
78 Isolate* isolate = map->GetIsolate(); | 45 Isolate* isolate = map->GetIsolate(); |
79 Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(), | 46 Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(), |
80 isolate); | 47 isolate); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset); | 218 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset); |
252 return true; | 219 return true; |
253 } | 220 } |
254 *out_end_of_contiguous_region_offset = | 221 *out_end_of_contiguous_region_offset = |
255 offset_in_bytes + sequence_length * kPointerSize; | 222 offset_in_bytes + sequence_length * kPointerSize; |
256 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset); | 223 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset); |
257 return tagged; | 224 return tagged; |
258 } | 225 } |
259 | 226 |
260 | 227 |
261 bool LayoutDescriptor::IsConsistentWithMap(Map* map) { | 228 LayoutDescriptor* LayoutDescriptor::Trim(Heap* heap, Map* map, |
229 DescriptorArray* descriptors, | |
230 int num_descriptors) { | |
231 DisallowHeapAllocation no_allocation; | |
232 // Fast mode descriptors are never shared and therefore always fully | |
233 // correspond to their map. | |
234 if (!IsSlowLayout()) return this; | |
235 | |
236 int layout_descriptor_length = | |
237 CalculateCapacity(map, descriptors, num_descriptors); | |
238 // It must not become fast-mode descriptor here, because otherwise it has to | |
239 // be fast pointer layout descriptor already but it's is slow mode now. | |
240 DCHECK_LT(kSmiValueSize, layout_descriptor_length); | |
241 | |
242 // Trim, clean and reinitialize this slow-mode layout descriptor. | |
243 int array_length = GetSlowModeBackingStoreLength(layout_descriptor_length); | |
244 int current_length = length(); | |
245 if (current_length != array_length) { | |
246 DCHECK_LT(array_length, current_length); | |
247 int delta = current_length - array_length; | |
248 heap->RightTrimFixedArray<Heap::FROM_GC>(this, delta); | |
Toon Verwaest
2015/03/30 16:10:21
I hope DataSize() is updated here? Otherwise you'l
Igor Sheludko
2015/03/30 16:33:27
Yes, sure! It's length() * elements_size, essentia
| |
249 } | |
250 memset(DataPtr(), 0, DataSize()); | |
251 LayoutDescriptor* layout_descriptor = | |
252 Initialize(this, map, descriptors, num_descriptors); | |
253 DCHECK_EQ(this, layout_descriptor); | |
254 return layout_descriptor; | |
255 } | |
256 | |
257 | |
258 bool LayoutDescriptor::IsConsistentWithMap(Map* map, bool check_tail) { | |
262 if (FLAG_unbox_double_fields) { | 259 if (FLAG_unbox_double_fields) { |
263 DescriptorArray* descriptors = map->instance_descriptors(); | 260 DescriptorArray* descriptors = map->instance_descriptors(); |
264 int nof_descriptors = map->NumberOfOwnDescriptors(); | 261 int nof_descriptors = map->NumberOfOwnDescriptors(); |
262 int last_field_index = 0; | |
265 for (int i = 0; i < nof_descriptors; i++) { | 263 for (int i = 0; i < nof_descriptors; i++) { |
266 PropertyDetails details = descriptors->GetDetails(i); | 264 PropertyDetails details = descriptors->GetDetails(i); |
267 if (details.type() != DATA) continue; | 265 if (details.location() != kField) continue; |
268 FieldIndex field_index = FieldIndex::ForDescriptor(map, i); | 266 FieldIndex field_index = FieldIndex::ForDescriptor(map, i); |
269 bool tagged_expected = | 267 bool tagged_expected = |
270 !field_index.is_inobject() || !details.representation().IsDouble(); | 268 !field_index.is_inobject() || !details.representation().IsDouble(); |
271 for (int bit = 0; bit < details.field_width_in_words(); bit++) { | 269 for (int bit = 0; bit < details.field_width_in_words(); bit++) { |
272 bool tagged_actual = IsTagged(details.field_index() + bit); | 270 bool tagged_actual = IsTagged(details.field_index() + bit); |
273 DCHECK_EQ(tagged_expected, tagged_actual); | 271 DCHECK_EQ(tagged_expected, tagged_actual); |
274 if (tagged_actual != tagged_expected) return false; | 272 if (tagged_actual != tagged_expected) return false; |
275 } | 273 } |
274 last_field_index = | |
275 Max(last_field_index, | |
276 details.field_index() + details.field_width_in_words()); | |
277 } | |
278 if (check_tail) { | |
279 int n = capacity(); | |
280 for (int i = last_field_index; i < n; i++) { | |
281 DCHECK(IsTagged(i)); | |
282 } | |
276 } | 283 } |
277 } | 284 } |
278 return true; | 285 return true; |
279 } | 286 } |
280 } | 287 } |
281 } // namespace v8::internal | 288 } // namespace v8::internal |
OLD | NEW |