blob: cae119140a5775c149205ea8aeb18ed8b50cdbc2 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 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_COMPILER_ACCESS_INFO_H_
6#define V8_COMPILER_ACCESS_INFO_H_
7
8#include <iosfwd>
9
10#include "src/field-index.h"
11#include "src/objects.h"
12#include "src/zone-containers.h"
13
14namespace v8 {
15namespace internal {
16
17// Forward declarations.
18class CompilationDependencies;
19class Factory;
20class TypeCache;
21
22
23namespace compiler {
24
25// Whether we are loading a property or storing to a property.
26enum class AccessMode { kLoad, kStore };
27
28std::ostream& operator<<(std::ostream&, AccessMode);
29
30
31// Mapping of transition source to transition target.
32typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
33
34
35// This class encapsulates all information required to access a certain element.
36class ElementAccessInfo final {
37 public:
38 ElementAccessInfo();
39 ElementAccessInfo(Type* receiver_type, ElementsKind elements_kind,
40 MaybeHandle<JSObject> holder);
41
42 MaybeHandle<JSObject> holder() const { return holder_; }
43 ElementsKind elements_kind() const { return elements_kind_; }
44 Type* receiver_type() const { return receiver_type_; }
45 MapTransitionList& transitions() { return transitions_; }
46 MapTransitionList const& transitions() const { return transitions_; }
47
48 private:
49 ElementsKind elements_kind_;
50 MaybeHandle<JSObject> holder_;
51 Type* receiver_type_;
52 MapTransitionList transitions_;
53};
54
55
56// Additional checks that need to be perform for data field accesses.
57enum class FieldCheck : uint8_t {
58 // No additional checking needed.
59 kNone,
60 // Check that the [[ViewedArrayBuffer]] of {JSArrayBufferView}s
61 // was not neutered.
62 kJSArrayBufferViewBufferNotNeutered,
63};
64
65
66// This class encapsulates all information required to access a certain
67// object property, either on the object itself or on the prototype chain.
68class PropertyAccessInfo final {
69 public:
70 enum Kind { kInvalid, kNotFound, kDataConstant, kDataField };
71
72 static PropertyAccessInfo NotFound(Type* receiver_type,
73 MaybeHandle<JSObject> holder);
74 static PropertyAccessInfo DataConstant(Type* receiver_type,
75 Handle<Object> constant,
76 MaybeHandle<JSObject> holder);
77 static PropertyAccessInfo DataField(
78 Type* receiver_type, FieldIndex field_index, Type* field_type,
79 FieldCheck field_check = FieldCheck::kNone,
80 MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
81 MaybeHandle<Map> transition_map = MaybeHandle<Map>());
82
83 PropertyAccessInfo();
84
85 bool IsNotFound() const { return kind() == kNotFound; }
86 bool IsDataConstant() const { return kind() == kDataConstant; }
87 bool IsDataField() const { return kind() == kDataField; }
88
89 bool HasTransitionMap() const { return !transition_map().is_null(); }
90
91 Kind kind() const { return kind_; }
92 MaybeHandle<JSObject> holder() const { return holder_; }
93 MaybeHandle<Map> transition_map() const { return transition_map_; }
94 Handle<Object> constant() const { return constant_; }
95 FieldCheck field_check() const { return field_check_; }
96 FieldIndex field_index() const { return field_index_; }
97 Type* field_type() const { return field_type_; }
98 Type* receiver_type() const { return receiver_type_; }
99
100 private:
101 PropertyAccessInfo(MaybeHandle<JSObject> holder, Type* receiver_type);
102 PropertyAccessInfo(MaybeHandle<JSObject> holder, Handle<Object> constant,
103 Type* receiver_type);
104 PropertyAccessInfo(MaybeHandle<JSObject> holder,
105 MaybeHandle<Map> transition_map, FieldIndex field_index,
106 FieldCheck field_check, Type* field_type,
107 Type* receiver_type);
108
109 Kind kind_;
110 Type* receiver_type_;
111 Handle<Object> constant_;
112 MaybeHandle<Map> transition_map_;
113 MaybeHandle<JSObject> holder_;
114 FieldIndex field_index_;
115 FieldCheck field_check_;
116 Type* field_type_;
117};
118
119
120// Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
121class AccessInfoFactory final {
122 public:
123 AccessInfoFactory(CompilationDependencies* dependencies,
124 Handle<Context> native_context, Zone* zone);
125
126 bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
127 ElementAccessInfo* access_info);
128 bool ComputeElementAccessInfos(MapHandleList const& maps,
129 AccessMode access_mode,
130 ZoneVector<ElementAccessInfo>* access_infos);
131 bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
132 AccessMode access_mode,
133 PropertyAccessInfo* access_info);
134 bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
135 AccessMode access_mode,
136 ZoneVector<PropertyAccessInfo>* access_infos);
137
138 private:
139 bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
140 PropertyAccessInfo* access_info);
141 bool LookupTransition(Handle<Map> map, Handle<Name> name,
142 MaybeHandle<JSObject> holder,
143 PropertyAccessInfo* access_info);
144
145 CompilationDependencies* dependencies() const { return dependencies_; }
146 Factory* factory() const;
147 Isolate* isolate() const { return isolate_; }
148 Handle<Context> native_context() const { return native_context_; }
149 Zone* zone() const { return zone_; }
150
151 CompilationDependencies* const dependencies_;
152 Handle<Context> const native_context_;
153 Isolate* const isolate_;
154 TypeCache const& type_cache_;
155 Zone* const zone_;
156
157 DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
158};
159
160} // namespace compiler
161} // namespace internal
162} // namespace v8
163
164#endif // V8_COMPILER_ACCESS_INFO_H_