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_IC_HANDLER_CONFIGURATION_INL_H_
6 #define V8_IC_HANDLER_CONFIGURATION_INL_H_
7
8 #include "src/builtins/builtins.h"
9 #include "src/execution/isolate.h"
10 #include "src/handles/handles-inl.h"
11 #include "src/ic/handler-configuration.h"
12 #include "src/objects/data-handler-inl.h"
13 #include "src/objects/field-index-inl.h"
14 #include "src/objects/objects-inl.h"
15 #include "src/objects/smi.h"
16
17 // Has to be the last include (doesn't have include guards):
18 #include "src/objects/object-macros.h"
19
20 namespace v8 {
21 namespace internal {
22
MakeCodeHandler(Isolate * isolate,Builtin builtin)23 inline Handle<Object> MakeCodeHandler(Isolate* isolate, Builtin builtin) {
24 if (V8_EXTERNAL_CODE_SPACE_BOOL) {
25 Code code = isolate->builtins()->code(builtin);
26 return handle(code.code_data_container(kAcquireLoad), isolate);
27 } else {
28 return isolate->builtins()->code_handle(builtin);
29 }
30 }
31
OBJECT_CONSTRUCTORS_IMPL(LoadHandler,DataHandler)32 OBJECT_CONSTRUCTORS_IMPL(LoadHandler, DataHandler)
33
34 CAST_ACCESSOR(LoadHandler)
35
36 // Decodes kind from Smi-handler.
37 LoadHandler::Kind LoadHandler::GetHandlerKind(Smi smi_handler) {
38 return KindBits::decode(smi_handler.value());
39 }
40
LoadNormal(Isolate * isolate)41 Handle<Smi> LoadHandler::LoadNormal(Isolate* isolate) {
42 int config = KindBits::encode(Kind::kNormal);
43 return handle(Smi::FromInt(config), isolate);
44 }
45
LoadGlobal(Isolate * isolate)46 Handle<Smi> LoadHandler::LoadGlobal(Isolate* isolate) {
47 int config = KindBits::encode(Kind::kGlobal);
48 return handle(Smi::FromInt(config), isolate);
49 }
50
LoadInterceptor(Isolate * isolate)51 Handle<Smi> LoadHandler::LoadInterceptor(Isolate* isolate) {
52 int config = KindBits::encode(Kind::kInterceptor);
53 return handle(Smi::FromInt(config), isolate);
54 }
55
LoadSlow(Isolate * isolate)56 Handle<Smi> LoadHandler::LoadSlow(Isolate* isolate) {
57 int config = KindBits::encode(Kind::kSlow);
58 return handle(Smi::FromInt(config), isolate);
59 }
60
LoadField(Isolate * isolate,FieldIndex field_index)61 Handle<Smi> LoadHandler::LoadField(Isolate* isolate, FieldIndex field_index) {
62 int config = KindBits::encode(Kind::kField) |
63 IsInobjectBits::encode(field_index.is_inobject()) |
64 IsDoubleBits::encode(field_index.is_double()) |
65 FieldIndexBits::encode(field_index.index());
66 return handle(Smi::FromInt(config), isolate);
67 }
68
LoadWasmStructField(Isolate * isolate,WasmValueType type,int offset)69 Handle<Smi> LoadHandler::LoadWasmStructField(Isolate* isolate,
70 WasmValueType type, int offset) {
71 int config = KindBits::encode(Kind::kField) | IsWasmStructBits::encode(true) |
72 WasmFieldTypeBits::encode(type) |
73 WasmFieldOffsetBits::encode(offset);
74 return handle(Smi::FromInt(config), isolate);
75 }
76
LoadConstantFromPrototype(Isolate * isolate)77 Handle<Smi> LoadHandler::LoadConstantFromPrototype(Isolate* isolate) {
78 int config = KindBits::encode(Kind::kConstantFromPrototype);
79 return handle(Smi::FromInt(config), isolate);
80 }
81
LoadAccessor(Isolate * isolate,int descriptor)82 Handle<Smi> LoadHandler::LoadAccessor(Isolate* isolate, int descriptor) {
83 int config =
84 KindBits::encode(Kind::kAccessor) | DescriptorBits::encode(descriptor);
85 return handle(Smi::FromInt(config), isolate);
86 }
87
LoadProxy(Isolate * isolate)88 Handle<Smi> LoadHandler::LoadProxy(Isolate* isolate) {
89 int config = KindBits::encode(Kind::kProxy);
90 return handle(Smi::FromInt(config), isolate);
91 }
92
LoadNativeDataProperty(Isolate * isolate,int descriptor)93 Handle<Smi> LoadHandler::LoadNativeDataProperty(Isolate* isolate,
94 int descriptor) {
95 int config = KindBits::encode(Kind::kNativeDataProperty) |
96 DescriptorBits::encode(descriptor);
97 return handle(Smi::FromInt(config), isolate);
98 }
99
LoadApiGetter(Isolate * isolate,bool holder_is_receiver)100 Handle<Smi> LoadHandler::LoadApiGetter(Isolate* isolate,
101 bool holder_is_receiver) {
102 int config =
103 KindBits::encode(holder_is_receiver ? Kind::kApiGetter
104 : Kind::kApiGetterHolderIsPrototype);
105 return handle(Smi::FromInt(config), isolate);
106 }
107
LoadModuleExport(Isolate * isolate,int index)108 Handle<Smi> LoadHandler::LoadModuleExport(Isolate* isolate, int index) {
109 int config =
110 KindBits::encode(Kind::kModuleExport) | ExportsIndexBits::encode(index);
111 return handle(Smi::FromInt(config), isolate);
112 }
113
LoadNonExistent(Isolate * isolate)114 Handle<Smi> LoadHandler::LoadNonExistent(Isolate* isolate) {
115 int config = KindBits::encode(Kind::kNonExistent);
116 return handle(Smi::FromInt(config), isolate);
117 }
118
LoadElement(Isolate * isolate,ElementsKind elements_kind,bool convert_hole_to_undefined,bool is_js_array,KeyedAccessLoadMode load_mode)119 Handle<Smi> LoadHandler::LoadElement(Isolate* isolate,
120 ElementsKind elements_kind,
121 bool convert_hole_to_undefined,
122 bool is_js_array,
123 KeyedAccessLoadMode load_mode) {
124 int config =
125 KindBits::encode(Kind::kElement) |
126 AllowOutOfBoundsBits::encode(load_mode == LOAD_IGNORE_OUT_OF_BOUNDS) |
127 ElementsKindBits::encode(elements_kind) |
128 ConvertHoleBits::encode(convert_hole_to_undefined) |
129 IsJsArrayBits::encode(is_js_array);
130 return handle(Smi::FromInt(config), isolate);
131 }
132
LoadIndexedString(Isolate * isolate,KeyedAccessLoadMode load_mode)133 Handle<Smi> LoadHandler::LoadIndexedString(Isolate* isolate,
134 KeyedAccessLoadMode load_mode) {
135 int config =
136 KindBits::encode(Kind::kIndexedString) |
137 AllowOutOfBoundsBits::encode(load_mode == LOAD_IGNORE_OUT_OF_BOUNDS);
138 return handle(Smi::FromInt(config), isolate);
139 }
140
LoadWasmArrayElement(Isolate * isolate,WasmValueType type)141 Handle<Smi> LoadHandler::LoadWasmArrayElement(Isolate* isolate,
142 WasmValueType type) {
143 int config = KindBits::encode(Kind::kElement) |
144 IsWasmArrayBits::encode(true) | WasmArrayTypeBits::encode(type);
145 return handle(Smi::FromInt(config), isolate);
146 }
147
OBJECT_CONSTRUCTORS_IMPL(StoreHandler,DataHandler)148 OBJECT_CONSTRUCTORS_IMPL(StoreHandler, DataHandler)
149
150 CAST_ACCESSOR(StoreHandler)
151
152 Handle<Smi> StoreHandler::StoreGlobalProxy(Isolate* isolate) {
153 int config = KindBits::encode(Kind::kGlobalProxy);
154 return handle(Smi::FromInt(config), isolate);
155 }
156
StoreNormal(Isolate * isolate)157 Handle<Smi> StoreHandler::StoreNormal(Isolate* isolate) {
158 int config = KindBits::encode(Kind::kNormal);
159 return handle(Smi::FromInt(config), isolate);
160 }
161
StoreInterceptor(Isolate * isolate)162 Handle<Smi> StoreHandler::StoreInterceptor(Isolate* isolate) {
163 int config = KindBits::encode(Kind::kInterceptor);
164 return handle(Smi::FromInt(config), isolate);
165 }
166
StoreSloppyArgumentsBuiltin(KeyedAccessStoreMode mode)167 Builtin StoreHandler::StoreSloppyArgumentsBuiltin(KeyedAccessStoreMode mode) {
168 switch (mode) {
169 case STANDARD_STORE:
170 return Builtin::kKeyedStoreIC_SloppyArguments_Standard;
171 case STORE_AND_GROW_HANDLE_COW:
172 return Builtin::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW;
173 case STORE_IGNORE_OUT_OF_BOUNDS:
174 return Builtin::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB;
175 case STORE_HANDLE_COW:
176 return Builtin::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW;
177 default:
178 UNREACHABLE();
179 }
180 }
181
StoreFastElementBuiltin(KeyedAccessStoreMode mode)182 Builtin StoreHandler::StoreFastElementBuiltin(KeyedAccessStoreMode mode) {
183 switch (mode) {
184 case STANDARD_STORE:
185 return Builtin::kStoreFastElementIC_Standard;
186 case STORE_AND_GROW_HANDLE_COW:
187 return Builtin::kStoreFastElementIC_GrowNoTransitionHandleCOW;
188 case STORE_IGNORE_OUT_OF_BOUNDS:
189 return Builtin::kStoreFastElementIC_NoTransitionIgnoreOOB;
190 case STORE_HANDLE_COW:
191 return Builtin::kStoreFastElementIC_NoTransitionHandleCOW;
192 default:
193 UNREACHABLE();
194 }
195 }
196
ElementsTransitionAndStoreBuiltin(KeyedAccessStoreMode mode)197 Builtin StoreHandler::ElementsTransitionAndStoreBuiltin(
198 KeyedAccessStoreMode mode) {
199 switch (mode) {
200 case STANDARD_STORE:
201 return Builtin::kElementsTransitionAndStore_Standard;
202 case STORE_AND_GROW_HANDLE_COW:
203 return Builtin::kElementsTransitionAndStore_GrowNoTransitionHandleCOW;
204 case STORE_IGNORE_OUT_OF_BOUNDS:
205 return Builtin::kElementsTransitionAndStore_NoTransitionIgnoreOOB;
206 case STORE_HANDLE_COW:
207 return Builtin::kElementsTransitionAndStore_NoTransitionHandleCOW;
208 default:
209 UNREACHABLE();
210 }
211 }
212
StoreSlow(Isolate * isolate,KeyedAccessStoreMode store_mode)213 Handle<Smi> StoreHandler::StoreSlow(Isolate* isolate,
214 KeyedAccessStoreMode store_mode) {
215 int config = KindBits::encode(Kind::kSlow) |
216 KeyedAccessStoreModeBits::encode(store_mode);
217 return handle(Smi::FromInt(config), isolate);
218 }
219
StoreProxy(Isolate * isolate)220 Handle<Smi> StoreHandler::StoreProxy(Isolate* isolate) {
221 return handle(StoreProxy(), isolate);
222 }
223
StoreProxy()224 Smi StoreHandler::StoreProxy() {
225 int config = KindBits::encode(Kind::kProxy);
226 return Smi::FromInt(config);
227 }
228
StoreField(Isolate * isolate,Kind kind,int descriptor,FieldIndex field_index,Representation representation)229 Handle<Smi> StoreHandler::StoreField(Isolate* isolate, Kind kind,
230 int descriptor, FieldIndex field_index,
231 Representation representation) {
232 DCHECK(!representation.IsNone());
233 DCHECK(kind == Kind::kField || kind == Kind::kConstField);
234
235 int config = KindBits::encode(kind) |
236 IsInobjectBits::encode(field_index.is_inobject()) |
237 RepresentationBits::encode(representation.kind()) |
238 DescriptorBits::encode(descriptor) |
239 FieldIndexBits::encode(field_index.index());
240 return handle(Smi::FromInt(config), isolate);
241 }
242
StoreField(Isolate * isolate,int descriptor,FieldIndex field_index,PropertyConstness constness,Representation representation)243 Handle<Smi> StoreHandler::StoreField(Isolate* isolate, int descriptor,
244 FieldIndex field_index,
245 PropertyConstness constness,
246 Representation representation) {
247 Kind kind = constness == PropertyConstness::kMutable ? Kind::kField
248 : Kind::kConstField;
249 return StoreField(isolate, kind, descriptor, field_index, representation);
250 }
251
StoreNativeDataProperty(Isolate * isolate,int descriptor)252 Handle<Smi> StoreHandler::StoreNativeDataProperty(Isolate* isolate,
253 int descriptor) {
254 int config = KindBits::encode(Kind::kNativeDataProperty) |
255 DescriptorBits::encode(descriptor);
256 return handle(Smi::FromInt(config), isolate);
257 }
258
StoreAccessor(Isolate * isolate,int descriptor)259 Handle<Smi> StoreHandler::StoreAccessor(Isolate* isolate, int descriptor) {
260 int config =
261 KindBits::encode(Kind::kAccessor) | DescriptorBits::encode(descriptor);
262 return handle(Smi::FromInt(config), isolate);
263 }
264
StoreApiSetter(Isolate * isolate,bool holder_is_receiver)265 Handle<Smi> StoreHandler::StoreApiSetter(Isolate* isolate,
266 bool holder_is_receiver) {
267 int config =
268 KindBits::encode(holder_is_receiver ? Kind::kApiSetter
269 : Kind::kApiSetterHolderIsPrototype);
270 return handle(Smi::FromInt(config), isolate);
271 }
272
WasmValueType2String(WasmValueType type)273 inline const char* WasmValueType2String(WasmValueType type) {
274 switch (type) {
275 case WasmValueType::kI8:
276 return "i8";
277 case WasmValueType::kI16:
278 return "i16";
279 case WasmValueType::kI32:
280 return "i32";
281 case WasmValueType::kU32:
282 return "u32";
283 case WasmValueType::kI64:
284 return "i64";
285 case WasmValueType::kF32:
286 return "f32";
287 case WasmValueType::kF64:
288 return "f64";
289 case WasmValueType::kS128:
290 return "s128";
291
292 case WasmValueType::kRef:
293 return "Ref";
294 case WasmValueType::kOptRef:
295 return "OptRef";
296
297 case WasmValueType::kNumTypes:
298 return "???";
299 }
300 }
301
302 } // namespace internal
303 } // namespace v8
304
305 #include "src/objects/object-macros-undef.h"
306
307 #endif // V8_IC_HANDLER_CONFIGURATION_INL_H_
308