OLD | NEW |
| (Empty) |
1 // Copyright 2016 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_SRC_IC_ACCESSOR_ASSEMBLER_IMPL_H_ | |
6 #define V8_SRC_IC_ACCESSOR_ASSEMBLER_IMPL_H_ | |
7 | |
8 #include "src/code-stub-assembler.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 | |
13 namespace compiler { | |
14 class CodeAssemblerState; | |
15 } | |
16 | |
17 using compiler::Node; | |
18 | |
19 #define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \ | |
20 V(LoadIC) \ | |
21 V(LoadField) \ | |
22 V(LoadICTrampoline) \ | |
23 V(KeyedLoadICTF) \ | |
24 V(KeyedLoadICTrampolineTF) \ | |
25 V(KeyedLoadICMegamorphic) \ | |
26 V(StoreIC) \ | |
27 V(StoreICTrampoline) | |
28 // The other IC entry points need custom handling because of additional | |
29 // parameters like "typeof_mode" or "language_mode". | |
30 | |
31 class AccessorAssemblerImpl : public CodeStubAssembler { | |
32 public: | |
33 explicit AccessorAssemblerImpl(compiler::CodeAssemblerState* state) | |
34 : CodeStubAssembler(state) {} | |
35 | |
36 #define DECLARE_PUBLIC_METHOD(Name) void Generate##Name(); | |
37 | |
38 ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DECLARE_PUBLIC_METHOD) | |
39 #undef DECLARE_PUBLIC_METHOD | |
40 | |
41 void GenerateLoadICProtoArray(bool throw_reference_error_if_nonexistent); | |
42 | |
43 void GenerateLoadGlobalIC(TypeofMode typeof_mode); | |
44 void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode); | |
45 | |
46 void GenerateKeyedStoreICTF(LanguageMode language_mode); | |
47 void GenerateKeyedStoreICTrampolineTF(LanguageMode language_mode); | |
48 | |
49 void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name, | |
50 Label* if_handler, Variable* var_handler, | |
51 Label* if_miss); | |
52 | |
53 Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) { | |
54 return StubCachePrimaryOffset(name, map); | |
55 } | |
56 Node* StubCacheSecondaryOffsetForTesting(Node* name, Node* map) { | |
57 return StubCacheSecondaryOffset(name, map); | |
58 } | |
59 | |
60 protected: | |
61 struct LoadICParameters { | |
62 LoadICParameters(Node* context, Node* receiver, Node* name, Node* slot, | |
63 Node* vector) | |
64 : context(context), | |
65 receiver(receiver), | |
66 name(name), | |
67 slot(slot), | |
68 vector(vector) {} | |
69 | |
70 Node* context; | |
71 Node* receiver; | |
72 Node* name; | |
73 Node* slot; | |
74 Node* vector; | |
75 }; | |
76 | |
77 struct StoreICParameters : public LoadICParameters { | |
78 StoreICParameters(Node* context, Node* receiver, Node* name, Node* value, | |
79 Node* slot, Node* vector) | |
80 : LoadICParameters(context, receiver, name, slot, vector), | |
81 value(value) {} | |
82 Node* value; | |
83 }; | |
84 | |
85 enum ElementSupport { kOnlyProperties, kSupportElements }; | |
86 void HandleStoreICHandlerCase( | |
87 const StoreICParameters* p, Node* handler, Label* miss, | |
88 ElementSupport support_elements = kOnlyProperties); | |
89 | |
90 private: | |
91 // Stub generation entry points. | |
92 | |
93 void LoadIC(const LoadICParameters* p); | |
94 void LoadICProtoArray(const LoadICParameters* p, Node* handler, | |
95 bool throw_reference_error_if_nonexistent); | |
96 void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode); | |
97 void KeyedLoadIC(const LoadICParameters* p); | |
98 void KeyedLoadICGeneric(const LoadICParameters* p); | |
99 void StoreIC(const StoreICParameters* p); | |
100 void KeyedStoreIC(const StoreICParameters* p, LanguageMode language_mode); | |
101 | |
102 // IC dispatcher behavior. | |
103 | |
104 // Checks monomorphic case. Returns {feedback} entry of the vector. | |
105 Node* TryMonomorphicCase(Node* slot, Node* vector, Node* receiver_map, | |
106 Label* if_handler, Variable* var_handler, | |
107 Label* if_miss); | |
108 void HandlePolymorphicCase(Node* receiver_map, Node* feedback, | |
109 Label* if_handler, Variable* var_handler, | |
110 Label* if_miss, int unroll_count); | |
111 void HandleKeyedStorePolymorphicCase(Node* receiver_map, Node* feedback, | |
112 Label* if_handler, Variable* var_handler, | |
113 Label* if_transition_handler, | |
114 Variable* var_transition_map_cell, | |
115 Label* if_miss); | |
116 | |
117 // LoadIC implementation. | |
118 | |
119 void HandleLoadICHandlerCase( | |
120 const LoadICParameters* p, Node* handler, Label* miss, | |
121 ElementSupport support_elements = kOnlyProperties); | |
122 | |
123 void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder, | |
124 Node* smi_handler, Label* miss, | |
125 ElementSupport support_elements); | |
126 | |
127 void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler, | |
128 Variable* var_holder, | |
129 Variable* var_smi_handler, | |
130 Label* if_smi_handler, Label* miss, | |
131 bool throw_reference_error_if_nonexistent); | |
132 | |
133 Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler, | |
134 Node* handler_length, Node* handler_flags, | |
135 Label* miss, | |
136 bool throw_reference_error_if_nonexistent); | |
137 | |
138 // LoadGlobalIC implementation. | |
139 | |
140 void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler, | |
141 Label* miss, | |
142 bool throw_reference_error_if_nonexistent); | |
143 | |
144 // StoreIC implementation. | |
145 | |
146 void HandleStoreICElementHandlerCase(const StoreICParameters* p, | |
147 Node* handler, Label* miss); | |
148 | |
149 void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler, | |
150 Label* miss); | |
151 // If |transition| is nullptr then the normal field store is generated or | |
152 // transitioning store otherwise. | |
153 void HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder, | |
154 Node* value, Node* transition, Label* miss); | |
155 // If |transition| is nullptr then the normal field store is generated or | |
156 // transitioning store otherwise. | |
157 void HandleStoreFieldAndReturn(Node* handler_word, Node* holder, | |
158 Representation representation, Node* value, | |
159 Node* transition, Label* miss); | |
160 | |
161 // Low-level helpers. | |
162 | |
163 Node* PrepareValueForStore(Node* handler_word, Node* holder, | |
164 Representation representation, Node* transition, | |
165 Node* value, Label* bailout); | |
166 | |
167 // Extends properties backing store by JSObject::kFieldsAdded elements. | |
168 void ExtendPropertiesBackingStore(Node* object); | |
169 | |
170 void StoreNamedField(Node* handler_word, Node* object, bool is_inobject, | |
171 Representation representation, Node* value, | |
172 bool transition_to_field); | |
173 | |
174 void EmitFastElementsBoundsCheck(Node* object, Node* elements, | |
175 Node* intptr_index, | |
176 Node* is_jsarray_condition, Label* miss); | |
177 void EmitElementLoad(Node* object, Node* elements, Node* elements_kind, | |
178 Node* key, Node* is_jsarray_condition, Label* if_hole, | |
179 Label* rebox_double, Variable* var_double_value, | |
180 Label* unimplemented_elements_kind, Label* out_of_bounds, | |
181 Label* miss); | |
182 void CheckPrototype(Node* prototype_cell, Node* name, Label* miss); | |
183 void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss); | |
184 | |
185 // Stub cache access helpers. | |
186 | |
187 // This enum is used here as a replacement for StubCache::Table to avoid | |
188 // including stub cache header. | |
189 enum StubCacheTable : int; | |
190 | |
191 Node* StubCachePrimaryOffset(Node* name, Node* map); | |
192 Node* StubCacheSecondaryOffset(Node* name, Node* seed); | |
193 | |
194 void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, | |
195 Node* entry_offset, Node* name, Node* map, | |
196 Label* if_handler, Variable* var_handler, | |
197 Label* if_miss); | |
198 }; | |
199 | |
200 } // namespace internal | |
201 } // namespace v8 | |
202 | |
203 #endif // V8_SRC_IC_ACCESSOR_ASSEMBLER_IMPL_H_ | |
OLD | NEW |