5 #ifndef V8_LAYOUT_DESCRIPTOR_INL_H_ 6 #define V8_LAYOUT_DESCRIPTOR_INL_H_ 8 #include "src/layout-descriptor.h" 10 #include "src/objects-inl.h" 11 #include "src/objects/descriptor-array.h" 12 #include "src/objects/smi.h" 15 #include "src/objects/object-macros.h" 20 LayoutDescriptor::LayoutDescriptor(Address ptr)
21 : ByteArray(ptr, AllowInlineSmiStorage::kAllowBeingASmi) {
22 SLOW_DCHECK(IsLayoutDescriptor());
24 CAST_ACCESSOR2(LayoutDescriptor)
26 LayoutDescriptor LayoutDescriptor::FromSmi(Smi smi) {
27 return LayoutDescriptor::cast(smi);
30 Handle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate,
int length) {
31 if (length <= kBitsInSmiLayout) {
33 return handle(LayoutDescriptor::FromSmi(Smi::zero()), isolate);
35 int backing_store_length = GetSlowModeBackingStoreLength(length);
36 Handle<LayoutDescriptor> result = Handle<LayoutDescriptor>::cast(
37 isolate->factory()->NewByteArray(backing_store_length, TENURED));
38 memset(reinterpret_cast<void*>(result->GetDataStartAddress()), 0,
44 bool LayoutDescriptor::InobjectUnboxedField(
int inobject_properties,
45 PropertyDetails details) {
46 if (details.location() != kField || !details.representation().IsDouble()) {
50 return details.field_index() < inobject_properties;
53 LayoutDescriptor LayoutDescriptor::FastPointerLayout() {
54 return LayoutDescriptor::FromSmi(Smi::zero());
57 bool LayoutDescriptor::GetIndexes(
int field_index,
int* layout_word_index,
58 int* layout_bit_index) {
59 if (static_cast<unsigned>(field_index) >= static_cast<unsigned>(capacity())) {
63 *layout_word_index = field_index / kBitsPerLayoutWord;
64 CHECK((!IsSmi() && (*layout_word_index < length())) ||
65 (IsSmi() && (*layout_word_index < 1)));
67 *layout_bit_index = field_index % kBitsPerLayoutWord;
71 LayoutDescriptor LayoutDescriptor::SetRawData(
int field_index) {
72 return SetTagged(field_index,
false);
75 LayoutDescriptor LayoutDescriptor::SetTagged(
int field_index,
bool tagged) {
76 int layout_word_index = 0;
77 int layout_bit_index = 0;
79 CHECK(GetIndexes(field_index, &layout_word_index, &layout_bit_index));
83 uint32_t value = get_layout_word(layout_word_index);
85 value &= ~layout_mask;
89 set_layout_word(layout_word_index, value);
94 value &= ~layout_mask;
98 return LayoutDescriptor::FromSmi(Smi::FromInt(static_cast<int>(value)));
102 bool LayoutDescriptor::IsTagged(
int field_index) {
103 if (IsFastPointerLayout())
return true;
105 int layout_word_index;
106 int layout_bit_index;
108 if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
114 if (IsSlowLayout()) {
115 uint32_t value = get_layout_word(layout_word_index);
116 return (value & layout_mask) == 0;
119 return (value & layout_mask) == 0;
124 bool LayoutDescriptor::IsFastPointerLayout() {
125 return *
this == FastPointerLayout();
129 bool LayoutDescriptor::IsFastPointerLayout(Object* layout_descriptor) {
130 return layout_descriptor == FastPointerLayout();
134 bool LayoutDescriptor::IsSlowLayout() {
return !IsSmi(); }
137 int LayoutDescriptor::capacity() {
138 return IsSlowLayout() ? (length() * kBitsPerByte) : kBitsInSmiLayout;
141 LayoutDescriptor LayoutDescriptor::cast_gc_safe(Object*
object) {
146 return LayoutDescriptor::unchecked_cast(
object);
149 int LayoutDescriptor::GetSlowModeBackingStoreLength(
int length) {
150 DCHECK_LT(0, length);
154 return RoundUp(length, kBitsPerByte * kPointerSize) / kBitsPerByte;
157 int LayoutDescriptor::CalculateCapacity(Map map, DescriptorArray* descriptors,
158 int num_descriptors) {
159 int inobject_properties = map->GetInObjectProperties();
160 if (inobject_properties == 0)
return 0;
162 DCHECK_LE(num_descriptors, descriptors->number_of_descriptors());
164 int layout_descriptor_length;
165 const int kMaxWordsPerField = kDoubleSize / kPointerSize;
167 if (num_descriptors <= kBitsInSmiLayout / kMaxWordsPerField) {
170 layout_descriptor_length = kBitsInSmiLayout;
173 layout_descriptor_length = 0;
175 for (
int i = 0;
i < num_descriptors;
i++) {
176 PropertyDetails details = descriptors->GetDetails(
i);
177 if (!InobjectUnboxedField(inobject_properties, details))
continue;
178 int field_index = details.field_index();
179 int field_width_in_words = details.field_width_in_words();
180 layout_descriptor_length =
181 Max(layout_descriptor_length, field_index + field_width_in_words);
184 layout_descriptor_length = Min(layout_descriptor_length, inobject_properties);
185 return layout_descriptor_length;
188 LayoutDescriptor LayoutDescriptor::Initialize(
189 LayoutDescriptor layout_descriptor, Map map, DescriptorArray* descriptors,
190 int num_descriptors) {
191 DisallowHeapAllocation no_allocation;
192 int inobject_properties = map->GetInObjectProperties();
194 for (
int i = 0;
i < num_descriptors;
i++) {
195 PropertyDetails details = descriptors->GetDetails(
i);
196 if (!InobjectUnboxedField(inobject_properties, details)) {
197 DCHECK(details.location() != kField ||
198 layout_descriptor->IsTagged(details.field_index()));
201 int field_index = details.field_index();
202 layout_descriptor = layout_descriptor->SetRawData(field_index);
203 if (details.field_width_in_words() > 1) {
204 layout_descriptor = layout_descriptor->SetRawData(field_index + 1);
207 return layout_descriptor;
210 int LayoutDescriptor::number_of_layout_words() {
211 return length() / kUInt32Size;
214 uint32_t LayoutDescriptor::get_layout_word(
int index)
const {
215 return get_uint32(index);
218 void LayoutDescriptor::set_layout_word(
int index,
uint32_t value) {
219 set_uint32(index, value);
224 LayoutDescriptorHelper::LayoutDescriptorHelper(Map map)
225 : all_fields_tagged_(true),
227 layout_descriptor_(LayoutDescriptor::FastPointerLayout()) {
228 if (!FLAG_unbox_double_fields)
return;
230 layout_descriptor_ = map->layout_descriptor_gc_safe();
231 if (layout_descriptor_->IsFastPointerLayout()) {
235 header_size_ = map->GetInObjectPropertiesStartInWords() * kPointerSize;
236 DCHECK_GE(header_size_, 0);
238 all_fields_tagged_ =
false;
242 bool LayoutDescriptorHelper::IsTagged(
int offset_in_bytes) {
243 DCHECK(IsAligned(offset_in_bytes, kPointerSize));
244 if (all_fields_tagged_)
return true;
246 if (offset_in_bytes < header_size_)
return true;
247 int field_index = (offset_in_bytes - header_size_) / kPointerSize;
249 return layout_descriptor_->IsTagged(field_index);
255 #include "src/objects/object-macros-undef.h" 257 #endif // V8_LAYOUT_DESCRIPTOR_INL_H_