1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved.
2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be
3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file.
4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifndef V8_LAYOUT_DESCRIPTOR_INL_H_
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define V8_LAYOUT_DESCRIPTOR_INL_H_
7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/layout-descriptor.h"
9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 {
11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal {
12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierLayoutDescriptor* LayoutDescriptor::FromSmi(Smi* smi) {
14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return LayoutDescriptor::cast(smi);
15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHandle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate, int length) {
19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (length <= kSmiValueSize) {
20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // The whole bit vector fits into a smi.
21c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return handle(LayoutDescriptor::FromSmi(Smi::kZero), isolate);
22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  length = GetSlowModeBackingStoreLength(length);
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Handle<LayoutDescriptor>::cast(isolate->factory()->NewFixedTypedArray(
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      length, kExternalUint32Array, true));
26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptor::InobjectUnboxedField(int inobject_properties,
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                            PropertyDetails details) {
3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (details.location() != kField || !details.representation().IsDouble()) {
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // We care only about in-object properties.
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return details.field_index() < inobject_properties;
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierLayoutDescriptor* LayoutDescriptor::FastPointerLayout() {
40c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return LayoutDescriptor::FromSmi(Smi::kZero);
41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptor::GetIndexes(int field_index, int* layout_word_index,
45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  int* layout_bit_index) {
46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (static_cast<unsigned>(field_index) >= static_cast<unsigned>(capacity())) {
47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  *layout_word_index = field_index / kNumberOfBits;
51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CHECK((!IsSmi() && (*layout_word_index < length())) ||
52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        (IsSmi() && (*layout_word_index < 1)));
53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  *layout_bit_index = field_index % kNumberOfBits;
55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return true;
56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLayoutDescriptor* LayoutDescriptor::SetRawData(int field_index) {
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SetTagged(field_index, false);
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierLayoutDescriptor* LayoutDescriptor::SetTagged(int field_index, bool tagged) {
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int layout_word_index = 0;
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int layout_bit_index = 0;
67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    CHECK(false);
70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return this;
71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsSlowLayout()) {
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t value = get_scalar(layout_word_index);
76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (tagged) {
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      value &= ~layout_mask;
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      value |= layout_mask;
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    set(layout_word_index, value);
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return this;
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (tagged) {
86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      value &= ~layout_mask;
87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      value |= layout_mask;
89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return LayoutDescriptor::FromSmi(Smi::FromInt(static_cast<int>(value)));
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptor::IsTagged(int field_index) {
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsFastPointerLayout()) return true;
97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int layout_word_index;
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int layout_bit_index;
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // All bits after Out of bounds queries
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return true;
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsSlowLayout()) {
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t value = get_scalar(layout_word_index);
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return (value & layout_mask) == 0;
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return (value & layout_mask) == 0;
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptor::IsFastPointerLayout() {
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return this == FastPointerLayout();
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptor::IsFastPointerLayout(Object* layout_descriptor) {
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return layout_descriptor == FastPointerLayout();
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptor::IsSlowLayout() { return !IsSmi(); }
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint LayoutDescriptor::capacity() {
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return IsSlowLayout() ? (length() * kNumberOfBits) : kSmiValueSize;
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierLayoutDescriptor* LayoutDescriptor::cast_gc_safe(Object* object) {
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (object->IsSmi()) {
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Fast mode layout descriptor.
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return reinterpret_cast<LayoutDescriptor*>(object);
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // This is a mixed descriptor which is a fixed typed array.
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MapWord map_word = reinterpret_cast<HeapObject*>(object)->map_word();
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (map_word.IsForwardingAddress()) {
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Mark-compact has already moved layout descriptor.
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    object = map_word.ToForwardingAddress();
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return LayoutDescriptor::cast(object);
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LayoutDescriptor::GetSlowModeBackingStoreLength(int length) {
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  length = (length + kNumberOfBits - 1) / kNumberOfBits;
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(0, length);
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (SmiValuesAre32Bits() && (length & 1)) {
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // On 64-bit systems if the length is odd then the half-word space would be
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // lost anyway (due to alignment and the fact that we are allocating
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // uint32-typed array), so we increase the length of allocated array
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // to utilize that "lost" space which could also help to avoid layout
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // descriptor reallocations.
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ++length;
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return length;
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LayoutDescriptor::CalculateCapacity(Map* map, DescriptorArray* descriptors,
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        int num_descriptors) {
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int inobject_properties = map->GetInObjectProperties();
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (inobject_properties == 0) return 0;
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(num_descriptors, descriptors->number_of_descriptors());
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int layout_descriptor_length;
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int kMaxWordsPerField = kDoubleSize / kPointerSize;
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (num_descriptors <= kSmiValueSize / kMaxWordsPerField) {
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Even in the "worst" case (all fields are doubles) it would fit into
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // a Smi, so no need to calculate length.
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    layout_descriptor_length = kSmiValueSize;
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    layout_descriptor_length = 0;
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < num_descriptors; i++) {
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PropertyDetails details = descriptors->GetDetails(i);
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!InobjectUnboxedField(inobject_properties, details)) continue;
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int field_index = details.field_index();
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int field_width_in_words = details.field_width_in_words();
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      layout_descriptor_length =
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Max(layout_descriptor_length, field_index + field_width_in_words);
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  layout_descriptor_length = Min(layout_descriptor_length, inobject_properties);
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return layout_descriptor_length;
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLayoutDescriptor* LayoutDescriptor::Initialize(
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LayoutDescriptor* layout_descriptor, Map* map, DescriptorArray* descriptors,
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int num_descriptors) {
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int inobject_properties = map->GetInObjectProperties();
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < num_descriptors; i++) {
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PropertyDetails details = descriptors->GetDetails(i);
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!InobjectUnboxedField(inobject_properties, details)) {
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(details.location() != kField ||
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             layout_descriptor->IsTagged(details.field_index()));
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int field_index = details.field_index();
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    layout_descriptor = layout_descriptor->SetRawData(field_index);
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (details.field_width_in_words() > 1) {
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      layout_descriptor = layout_descriptor->SetRawData(field_index + 1);
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return layout_descriptor;
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// LayoutDescriptorHelper is a helper class for querying whether inobject
223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// property at offset is Double or not.
224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierLayoutDescriptorHelper::LayoutDescriptorHelper(Map* map)
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    : all_fields_tagged_(true),
226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      header_size_(0),
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      layout_descriptor_(LayoutDescriptor::FastPointerLayout()) {
228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!FLAG_unbox_double_fields) return;
229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  layout_descriptor_ = map->layout_descriptor_gc_safe();
231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (layout_descriptor_->IsFastPointerLayout()) {
232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int inobject_properties = map->GetInObjectProperties();
236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(inobject_properties > 0);
237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  header_size_ = map->instance_size() - (inobject_properties * kPointerSize);
238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(header_size_ >= 0);
239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  all_fields_tagged_ = false;
241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool LayoutDescriptorHelper::IsTagged(int offset_in_bytes) {
245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(IsAligned(offset_in_bytes, kPointerSize));
246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (all_fields_tagged_) return true;
247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Object headers do not contain non-tagged fields.
248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (offset_in_bytes < header_size_) return true;
249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int field_index = (offset_in_bytes - header_size_) / kPointerSize;
250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return layout_descriptor_->IsTagged(field_index);
252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif  // V8_LAYOUT_DESCRIPTOR_INL_H_
257