Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: src/layout-descriptor.cc

Issue 726713003: LayoutDescriptorHelper is now able to calculate the length of contiguous regions of tagged/non-tagg… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/layout-descriptor.h ('k') | src/layout-descriptor-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/layout-descriptor.h" 10 #include "src/layout-descriptor.h"
10 11
12 using v8::base::bits::CountTrailingZeros32;
13
11 namespace v8 { 14 namespace v8 {
12 namespace internal { 15 namespace internal {
13 16
14 Handle<LayoutDescriptor> LayoutDescriptor::New( 17 Handle<LayoutDescriptor> LayoutDescriptor::New(
15 Handle<Map> map, Handle<DescriptorArray> descriptors, int num_descriptors) { 18 Handle<Map> map, Handle<DescriptorArray> descriptors, int num_descriptors) {
16 Isolate* isolate = descriptors->GetIsolate(); 19 Isolate* isolate = descriptors->GetIsolate();
17 if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate); 20 if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate);
18 21
19 int inobject_properties = map->inobject_properties(); 22 int inobject_properties = map->inobject_properties();
20 if (inobject_properties == 0) return handle(FastPointerLayout(), isolate); 23 if (inobject_properties == 0) return handle(FastPointerLayout(), isolate);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 layout_descriptor->DataSize()); 139 layout_descriptor->DataSize());
137 return new_layout_descriptor; 140 return new_layout_descriptor;
138 } else { 141 } else {
139 // Fast layout. 142 // Fast layout.
140 uint32_t value = 143 uint32_t value =
141 static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value()); 144 static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value());
142 new_layout_descriptor->set(0, value); 145 new_layout_descriptor->set(0, value);
143 return new_layout_descriptor; 146 return new_layout_descriptor;
144 } 147 }
145 } 148 }
149
150
151 bool LayoutDescriptor::IsTagged(int field_index, int max_sequence_length,
152 int* out_sequence_length) {
153 DCHECK(max_sequence_length > 0);
154 if (IsFastPointerLayout()) {
155 *out_sequence_length = max_sequence_length;
156 return true;
157 }
158
159 int layout_word_index;
160 int layout_bit_index;
161
162 if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
163 // Out of bounds queries are considered tagged.
164 *out_sequence_length = max_sequence_length;
165 return true;
166 }
167 uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
168
169 uint32_t value = IsSlowLayout()
170 ? get_scalar(layout_word_index)
171 : static_cast<uint32_t>(Smi::cast(this)->value());
172
173 bool is_tagged = (value & layout_mask) == 0;
174 if (!is_tagged) value = ~value; // Count set bits instead of cleared bits.
175 value = value & ~(layout_mask - 1); // Clear bits we are not interested in.
176 int sequence_length = CountTrailingZeros32(value) - layout_bit_index;
177
178 if (layout_bit_index + sequence_length == kNumberOfBits) {
179 // This is a contiguous sequence till the end of current word, proceed
180 // counting in the subsequent words.
181 if (IsSlowLayout()) {
182 int len = length();
183 ++layout_word_index;
184 for (; layout_word_index < len; layout_word_index++) {
185 value = get_scalar(layout_word_index);
186 bool cur_is_tagged = (value & 1) == 0;
187 if (cur_is_tagged != is_tagged) break;
188 if (!is_tagged) value = ~value; // Count set bits instead.
189 int cur_sequence_length = CountTrailingZeros32(value);
190 sequence_length += cur_sequence_length;
191 if (sequence_length >= max_sequence_length) break;
192 if (cur_sequence_length != kNumberOfBits) break;
193 }
194 }
195 if (is_tagged && (field_index + sequence_length == capacity())) {
196 // The contiguous sequence of tagged fields lasts till the end of the
197 // layout descriptor which means that all the fields starting from
198 // field_index are tagged.
199 sequence_length = std::numeric_limits<int>::max();
200 }
201 }
202 *out_sequence_length = Min(sequence_length, max_sequence_length);
203 return is_tagged;
204 }
205
206
207 Handle<LayoutDescriptor> LayoutDescriptor::NewForTesting(Isolate* isolate,
208 int length) {
209 return New(isolate, length);
210 }
211
212
213 LayoutDescriptor* LayoutDescriptor::SetTaggedForTesting(int field_index,
214 bool tagged) {
215 return SetTagged(field_index, tagged);
216 }
217
218
219 bool LayoutDescriptorHelper::IsTagged(
220 int offset_in_bytes, int end_offset,
221 int* out_end_of_contiguous_region_offset) {
222 DCHECK(IsAligned(offset_in_bytes, kPointerSize));
223 DCHECK(IsAligned(end_offset, kPointerSize));
224 DCHECK(offset_in_bytes < end_offset);
225 if (all_fields_tagged_) {
226 *out_end_of_contiguous_region_offset = end_offset;
227 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
228 return true;
229 }
230 int max_sequence_length = (end_offset - offset_in_bytes) / kPointerSize;
231 int field_index = Max(0, (offset_in_bytes - header_size_) / kPointerSize);
232 int sequence_length;
233 bool tagged = layout_descriptor_->IsTagged(field_index, max_sequence_length,
234 &sequence_length);
235 DCHECK(sequence_length > 0);
236 if (offset_in_bytes < header_size_) {
237 // Object headers do not contain non-tagged fields. Check if the contiguous
238 // region continues after the header.
239 if (tagged) {
240 // First field is tagged, calculate end offset from there.
241 *out_end_of_contiguous_region_offset =
242 header_size_ + sequence_length * kPointerSize;
243
244 } else {
245 *out_end_of_contiguous_region_offset = header_size_;
246 }
247 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
248 return true;
249 }
250 *out_end_of_contiguous_region_offset =
251 offset_in_bytes + sequence_length * kPointerSize;
252 DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
253 return tagged;
254 }
146 } 255 }
147 } // namespace v8::internal 256 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/layout-descriptor.h ('k') | src/layout-descriptor-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698