1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_FIELD_INDEX_INL_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_FIELD_INDEX_INL_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/field-index.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline FieldIndex FieldIndex::ForInObjectOffset(int offset, Map* map) {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((offset % kPointerSize) == 0);
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = offset / kPointerSize;
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(map == NULL ||
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         index < (map->GetInObjectPropertyOffset(0) / kPointerSize +
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  map->GetInObjectProperties()));
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return FieldIndex(true, index, false, 0, 0, true);
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline FieldIndex FieldIndex::ForPropertyIndex(Map* map,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               int property_index,
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               bool is_double) {
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() >= FIRST_NONSTRING_TYPE);
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int inobject_properties = map->GetInObjectProperties();
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_inobject = property_index < inobject_properties;
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int first_inobject_offset;
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_inobject) {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_inobject_offset = map->GetInObjectPropertyOffset(0);
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_inobject_offset = FixedArray::kHeaderSize;
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    property_index -= inobject_properties;
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FieldIndex(is_inobject,
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    property_index + first_inobject_offset / kPointerSize,
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    is_double, inobject_properties, first_inobject_offset);
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Takes an index as computed by GetLoadByFieldIndex and reconstructs a
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// FieldIndex object from it.
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline FieldIndex FieldIndex::ForLoadByFieldIndex(Map* map, int orig_index) {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int field_index = orig_index;
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int is_inobject = true;
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_double = field_index & 1;
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int first_inobject_offset = 0;
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field_index >>= 1;
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (field_index < 0) {
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    field_index = -(field_index + 1);
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_inobject = false;
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_inobject_offset = FixedArray::kHeaderSize;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    field_index += FixedArray::kHeaderSize / kPointerSize;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_inobject_offset = map->GetInObjectPropertyOffset(0);
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    field_index += JSObject::kHeaderSize / kPointerSize;
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FieldIndex result(is_inobject, field_index, is_double,
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    map->GetInObjectProperties(), first_inobject_offset);
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(result.GetLoadByFieldIndex() == orig_index);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Returns the index format accepted by the HLoadFieldByIndex instruction.
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (In-object: zero-based from (object start + JSObject::kHeaderSize),
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// out-of-object: zero-based from FixedArray::kHeaderSize.)
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline int FieldIndex::GetLoadByFieldIndex() const {
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For efficiency, the LoadByFieldIndex instruction takes an index that is
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // optimized for quick access. If the property is inline, the index is
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // positive. If it's out-of-line, the encoded index is -raw_index - 1 to
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // disambiguate the zero out-of-line index from the zero inobject case.
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The index itself is shifted up by one bit, the lower-most bit
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // signifying if the field is a mutable double box (1) or not (0).
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int result = index();
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_inobject()) {
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result -= JSObject::kHeaderSize / kPointerSize;
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result -= FixedArray::kHeaderSize / kPointerSize;
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = -result - 1;
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result <<= 1;
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return is_double() ? (result | 1) : result;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline FieldIndex FieldIndex::ForDescriptor(Map* map, int descriptor_index) {
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PropertyDetails details =
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      map->instance_descriptors()->GetDetails(descriptor_index);
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int field_index = details.field_index();
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ForPropertyIndex(map, field_index,
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          details.representation().IsDouble());
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline FieldIndex FieldIndex::FromFieldAccessStubKey(int key) {
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FieldIndex(key);
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
103