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/layout-descriptor.h" | 9 #include "src/layout-descriptor.h" |
10 | 10 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 layout_descriptor->DataSize()); | 136 layout_descriptor->DataSize()); |
137 return new_layout_descriptor; | 137 return new_layout_descriptor; |
138 } else { | 138 } else { |
139 // Fast layout. | 139 // Fast layout. |
140 uint32_t value = | 140 uint32_t value = |
141 static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value()); | 141 static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value()); |
142 new_layout_descriptor->set(0, value); | 142 new_layout_descriptor->set(0, value); |
143 return new_layout_descriptor; | 143 return new_layout_descriptor; |
144 } | 144 } |
145 } | 145 } |
146 | |
147 | |
148 // Number of trailing zeros, Seal’s algorithm. | |
149 int ntz32(uint32_t x) { | |
Hannes Payer (out of office)
2014/11/25 17:20:13
Can we move this to utils or some global place tha
Igor Sheludko
2014/12/10 18:22:04
I removed it in favor of v8::base::bits::CountTrai
| |
150 const char u = -1; // Unused cell. | |
151 static char table[64] = {32, 0, 1, 12, 2, 6, u, 13, 3, u, 7, u, u, | |
152 u, u, 14, 10, 4, u, u, 8, u, u, 25, u, u, | |
153 u, u, u, 21, 27, 15, 31, 11, 5, u, u, u, u, | |
154 u, 9, u, u, 24, u, u, 20, 26, 30, u, u, u, | |
155 u, 23, u, 19, 29, u, 22, 18, 28, 17, 16, u}; | |
156 x = (x & -x) * 0x0450FBAF; | |
157 return table[x >> 26]; | |
158 } | |
159 | |
160 | |
161 bool LayoutDescriptor::IsTagged(int field_index, int max_sequence_length, | |
162 int* out_sequence_length) { | |
163 DCHECK(max_sequence_length > 0); | |
164 if (IsFastPointerLayout()) { | |
165 *out_sequence_length = max_sequence_length; | |
166 return true; | |
167 } | |
168 | |
169 int layout_word_index; | |
170 int layout_bit_index; | |
171 | |
172 if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) { | |
173 // Out of bounds queries are considered tagged. | |
174 *out_sequence_length = max_sequence_length; | |
175 return true; | |
176 } | |
177 uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index; | |
178 | |
179 uint32_t value = IsSlowLayout() | |
180 ? get_scalar(layout_word_index) | |
181 : static_cast<uint32_t>(Smi::cast(this)->value()); | |
182 | |
183 bool is_tagged = (value & layout_mask) == 0; | |
184 if (!is_tagged) value = ~value; // Count set bits instead of cleared bits. | |
185 value = value & ~(layout_mask - 1); // Clear bits we are not interested in. | |
186 int sequence_length = ntz32(value) - layout_bit_index; | |
187 | |
188 if (layout_bit_index + sequence_length == kNumberOfBits) { | |
189 // This is a contiguous sequence till the end of current word, proceed | |
190 // counting in the subsequent words. | |
191 if (IsSlowLayout()) { | |
192 int len = length(); | |
193 ++layout_word_index; | |
194 for (; layout_word_index < len; layout_word_index++) { | |
195 value = get_scalar(layout_word_index); | |
196 bool cur_is_tagged = (value & 1) == 0; | |
197 if (cur_is_tagged != is_tagged) break; | |
198 if (!is_tagged) value = ~value; // Count set bits instead. | |
199 int cur_sequence_length = ntz32(value); | |
200 sequence_length += cur_sequence_length; | |
201 if (sequence_length >= max_sequence_length) break; | |
202 if (cur_sequence_length != kNumberOfBits) break; | |
203 } | |
204 } | |
205 if (is_tagged && (field_index + sequence_length == capacity())) { | |
206 // The contiguous sequence of tagged fields lasts till the end of the | |
207 // layout descriptor which means that all the fields starting from | |
208 // field_index are tagged. | |
209 sequence_length = std::numeric_limits<int>::max(); | |
210 } | |
211 } | |
212 *out_sequence_length = Min(sequence_length, max_sequence_length); | |
213 return is_tagged; | |
214 } | |
215 | |
216 | |
217 Handle<LayoutDescriptor> LayoutDescriptor::NewForTesting(Isolate* isolate, | |
218 int length) { | |
219 return New(isolate, length); | |
220 } | |
221 | |
222 | |
223 LayoutDescriptor* LayoutDescriptor::SetTaggedForTesting(int field_index, | |
224 bool tagged) { | |
225 return SetTagged(field_index, tagged); | |
226 } | |
227 | |
228 | |
229 bool LayoutDescriptorHelper::IsTagged( | |
230 int offset_in_bytes, int end_offset, | |
231 int* out_end_of_contiguous_region_offset) { | |
232 DCHECK(IsAligned(offset_in_bytes, kPointerSize)); | |
233 DCHECK(IsAligned(end_offset, kPointerSize)); | |
234 DCHECK(offset_in_bytes < end_offset); | |
235 if (all_fields_tagged_) { | |
236 *out_end_of_contiguous_region_offset = end_offset; | |
237 return true; | |
238 } | |
239 int max_sequence_length = (end_offset - offset_in_bytes) / kPointerSize; | |
240 int field_index = Max(0, (offset_in_bytes - header_size_) / kPointerSize); | |
241 int sequence_length; | |
242 bool tagged = layout_descriptor_->IsTagged(field_index, max_sequence_length, | |
243 &sequence_length); | |
244 DCHECK(sequence_length > 0); | |
245 if (offset_in_bytes < header_size_) { | |
246 // Object headers do not contain non-tagged fields. Check if the contiguous | |
247 // region continues after the header. | |
248 if (tagged) { | |
249 // First field is tagged, calculate end offset from there. | |
250 *out_end_of_contiguous_region_offset = | |
251 header_size_ + sequence_length * kPointerSize; | |
252 | |
253 } else { | |
254 *out_end_of_contiguous_region_offset = header_size_; | |
255 } | |
256 return true; | |
257 } | |
258 *out_end_of_contiguous_region_offset = | |
259 offset_in_bytes + sequence_length * kPointerSize; | |
260 return tagged; | |
261 } | |
146 } | 262 } |
147 } // namespace v8::internal | 263 } // namespace v8::internal |
OLD | NEW |