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