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 |
3 | // found in the LICENSE file. |
4 | |
5 | #ifndef V8_FIELD_INDEX_INL_H_ |
6 | #define V8_FIELD_INDEX_INL_H_ |
7 | |
8 | #include "src/field-index.h" |
9 | #include "src/objects-inl.h" |
10 | #include "src/objects/descriptor-array-inl.h" |
11 | |
12 | namespace v8 { |
13 | namespace internal { |
14 | |
15 | FieldIndex FieldIndex::ForInObjectOffset(int offset, Encoding encoding) { |
16 | DCHECK_IMPLIES(encoding == kWord32, IsAligned(offset, kInt32Size)); |
17 | DCHECK_IMPLIES(encoding == kTagged, IsAligned(offset, kTaggedSize)); |
18 | DCHECK_IMPLIES(encoding == kDouble, IsAligned(offset, kDoubleSize)); |
19 | return FieldIndex(true, offset, encoding, 0, 0); |
20 | } |
21 | |
22 | FieldIndex FieldIndex::ForPropertyIndex(const Map map, int property_index, |
23 | Representation representation) { |
24 | DCHECK(map->instance_type() >= FIRST_NONSTRING_TYPE); |
25 | int inobject_properties = map->GetInObjectProperties(); |
26 | bool is_inobject = property_index < inobject_properties; |
27 | int first_inobject_offset; |
28 | int offset; |
29 | if (is_inobject) { |
30 | first_inobject_offset = map->GetInObjectPropertyOffset(0); |
31 | offset = map->GetInObjectPropertyOffset(property_index); |
32 | } else { |
33 | first_inobject_offset = FixedArray::kHeaderSize; |
34 | property_index -= inobject_properties; |
35 | offset = PropertyArray::OffsetOfElementAt(property_index); |
36 | } |
37 | Encoding encoding = FieldEncoding(representation); |
38 | return FieldIndex(is_inobject, offset, encoding, inobject_properties, |
39 | first_inobject_offset); |
40 | } |
41 | |
42 | // Returns the index format accepted by the HLoadFieldByIndex instruction. |
43 | // (In-object: zero-based from (object start + JSObject::kHeaderSize), |
44 | // out-of-object: zero-based from FixedArray::kHeaderSize.) |
45 | int FieldIndex::GetLoadByFieldIndex() const { |
46 | // For efficiency, the LoadByFieldIndex instruction takes an index that is |
47 | // optimized for quick access. If the property is inline, the index is |
48 | // positive. If it's out-of-line, the encoded index is -raw_index - 1 to |
49 | // disambiguate the zero out-of-line index from the zero inobject case. |
50 | // The index itself is shifted up by one bit, the lower-most bit |
51 | // signifying if the field is a mutable double box (1) or not (0). |
52 | int result = index(); |
53 | if (is_inobject()) { |
54 | result -= JSObject::kHeaderSize / kTaggedSize; |
55 | } else { |
56 | result -= FixedArray::kHeaderSize / kTaggedSize; |
57 | result = -result - 1; |
58 | } |
59 | result = static_cast<uint32_t>(result) << 1; |
60 | return is_double() ? (result | 1) : result; |
61 | } |
62 | |
63 | FieldIndex FieldIndex::ForDescriptor(const Map map, int descriptor_index) { |
64 | PropertyDetails details = |
65 | map->instance_descriptors()->GetDetails(descriptor_index); |
66 | int field_index = details.field_index(); |
67 | return ForPropertyIndex(map, field_index, details.representation()); |
68 | } |
69 | |
70 | } // namespace internal |
71 | } // namespace v8 |
72 | |
73 | #endif // V8_FIELD_INDEX_INL_H_ |
74 | |