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 #include "src/base/optional.h"
6 #include "src/builtins/builtins-utils-gen.h"
7 #include "src/builtins/builtins.h"
8 #include "src/codegen/code-stub-assembler.h"
9 #include "src/ic/ic.h"
10 #include "src/ic/keyed-store-generic.h"
11 #include "src/objects/objects-inl.h"
12 #include "torque-generated/exported-macros-assembler.h"
13
14 namespace v8 {
15 namespace internal {
16
17 class HandlerBuiltinsAssembler : public CodeStubAssembler {
18 public:
HandlerBuiltinsAssembler(compiler::CodeAssemblerState * state)19 explicit HandlerBuiltinsAssembler(compiler::CodeAssemblerState* state)
20 : CodeStubAssembler(state) {}
21
22 protected:
23 void Generate_KeyedStoreIC_SloppyArguments();
24
25 // Essentially turns runtime elements kinds (TNode<Int32T>) into
26 // compile-time types (int) by dispatching over the runtime type and
27 // emitting a specialized copy of the given case function for each elements
28 // kind. Use with caution. This produces a *lot* of code.
29 using ElementsKindSwitchCase = std::function<void(ElementsKind)>;
30 void DispatchByElementsKind(TNode<Int32T> elements_kind,
31 const ElementsKindSwitchCase& case_function,
32 bool handle_typed_elements_kind);
33
34 // Dispatches over all possible combinations of {from,to} elements kinds.
35 using ElementsKindTransitionSwitchCase =
36 std::function<void(ElementsKind, ElementsKind)>;
37 void DispatchForElementsKindTransition(
38 TNode<Int32T> from_kind, TNode<Int32T> to_kind,
39 const ElementsKindTransitionSwitchCase& case_function);
40
41 void Generate_ElementsTransitionAndStore(KeyedAccessStoreMode store_mode);
42 void Generate_StoreFastElementIC(KeyedAccessStoreMode store_mode);
43 };
44
TF_BUILTIN(LoadIC_StringLength,CodeStubAssembler)45 TF_BUILTIN(LoadIC_StringLength, CodeStubAssembler) {
46 auto string = Parameter<String>(Descriptor::kReceiver);
47 Return(LoadStringLengthAsSmi(string));
48 }
49
TF_BUILTIN(LoadIC_StringWrapperLength,CodeStubAssembler)50 TF_BUILTIN(LoadIC_StringWrapperLength, CodeStubAssembler) {
51 auto value = Parameter<JSPrimitiveWrapper>(Descriptor::kReceiver);
52 TNode<String> string = CAST(LoadJSPrimitiveWrapperValue(value));
53 Return(LoadStringLengthAsSmi(string));
54 }
55
Generate_KeyedStoreIC_Megamorphic(compiler::CodeAssemblerState * state)56 void Builtins::Generate_KeyedStoreIC_Megamorphic(
57 compiler::CodeAssemblerState* state) {
58 KeyedStoreGenericGenerator::Generate(state);
59 }
60
Generate_StoreIC_NoFeedback(compiler::CodeAssemblerState * state)61 void Builtins::Generate_StoreIC_NoFeedback(
62 compiler::CodeAssemblerState* state) {
63 StoreICNoFeedbackGenerator::Generate(state);
64 }
65
66 // All possible fast-to-fast transitions. Transitions to dictionary mode are not
67 // handled by ElementsTransitionAndStore.
68 #define ELEMENTS_KIND_TRANSITIONS(V) \
69 V(PACKED_SMI_ELEMENTS, HOLEY_SMI_ELEMENTS) \
70 V(PACKED_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS) \
71 V(PACKED_SMI_ELEMENTS, HOLEY_DOUBLE_ELEMENTS) \
72 V(PACKED_SMI_ELEMENTS, PACKED_ELEMENTS) \
73 V(PACKED_SMI_ELEMENTS, HOLEY_ELEMENTS) \
74 V(HOLEY_SMI_ELEMENTS, HOLEY_DOUBLE_ELEMENTS) \
75 V(HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS) \
76 V(PACKED_DOUBLE_ELEMENTS, HOLEY_DOUBLE_ELEMENTS) \
77 V(PACKED_DOUBLE_ELEMENTS, PACKED_ELEMENTS) \
78 V(PACKED_DOUBLE_ELEMENTS, HOLEY_ELEMENTS) \
79 V(HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS) \
80 V(PACKED_ELEMENTS, HOLEY_ELEMENTS)
81
DispatchForElementsKindTransition(TNode<Int32T> from_kind,TNode<Int32T> to_kind,const ElementsKindTransitionSwitchCase & case_function)82 void HandlerBuiltinsAssembler::DispatchForElementsKindTransition(
83 TNode<Int32T> from_kind, TNode<Int32T> to_kind,
84 const ElementsKindTransitionSwitchCase& case_function) {
85 STATIC_ASSERT(sizeof(ElementsKind) == sizeof(uint8_t));
86
87 Label next(this), if_unknown_type(this, Label::kDeferred);
88
89 int32_t combined_elements_kinds[] = {
90 #define ELEMENTS_KINDS_CASE(FROM, TO) (FROM << kBitsPerByte) | TO,
91 ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
92 #undef ELEMENTS_KINDS_CASE
93 };
94
95 #define ELEMENTS_KINDS_CASE(FROM, TO) Label if_##FROM##_##TO(this);
96 ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
97 #undef ELEMENTS_KINDS_CASE
98
99 Label* elements_kind_labels[] = {
100 #define ELEMENTS_KINDS_CASE(FROM, TO) &if_##FROM##_##TO,
101 ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
102 #undef ELEMENTS_KINDS_CASE
103 };
104 STATIC_ASSERT(arraysize(combined_elements_kinds) ==
105 arraysize(elements_kind_labels));
106
107 TNode<Int32T> combined_elements_kind =
108 Word32Or(Word32Shl(from_kind, Int32Constant(kBitsPerByte)), to_kind);
109
110 Switch(combined_elements_kind, &if_unknown_type, combined_elements_kinds,
111 elements_kind_labels, arraysize(combined_elements_kinds));
112
113 #define ELEMENTS_KINDS_CASE(FROM, TO) \
114 BIND(&if_##FROM##_##TO); \
115 { \
116 case_function(FROM, TO); \
117 Goto(&next); \
118 }
119 ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
120 #undef ELEMENTS_KINDS_CASE
121
122 BIND(&if_unknown_type);
123 Unreachable();
124
125 BIND(&next);
126 }
127
128 #undef ELEMENTS_KIND_TRANSITIONS
129
Generate_ElementsTransitionAndStore(KeyedAccessStoreMode store_mode)130 void HandlerBuiltinsAssembler::Generate_ElementsTransitionAndStore(
131 KeyedAccessStoreMode store_mode) {
132 using Descriptor = StoreTransitionDescriptor;
133 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
134 auto key = Parameter<Object>(Descriptor::kName);
135 auto value = Parameter<Object>(Descriptor::kValue);
136 auto map = Parameter<Map>(Descriptor::kMap);
137 auto slot = Parameter<Smi>(Descriptor::kSlot);
138 auto vector = Parameter<FeedbackVector>(Descriptor::kVector);
139 auto context = Parameter<Context>(Descriptor::kContext);
140
141 Comment("ElementsTransitionAndStore: store_mode=", store_mode);
142
143 Label miss(this);
144
145 if (FLAG_trace_elements_transitions) {
146 // Tracing elements transitions is the job of the runtime.
147 Goto(&miss);
148 } else {
149 // TODO(v8:8481): Pass from_kind and to_kind in feedback vector slots.
150 DispatchForElementsKindTransition(
151 LoadElementsKind(receiver), LoadMapElementsKind(map),
152 [=, &miss](ElementsKind from_kind, ElementsKind to_kind) {
153 TransitionElementsKind(receiver, map, from_kind, to_kind, &miss);
154 EmitElementStore(receiver, key, value, to_kind, store_mode, &miss,
155 context, nullptr);
156 });
157 Return(value);
158 }
159
160 BIND(&miss);
161 TailCallRuntime(Runtime::kElementsTransitionAndStoreIC_Miss, context,
162 receiver, key, value, map, slot, vector);
163 }
164
TF_BUILTIN(ElementsTransitionAndStore_Standard,HandlerBuiltinsAssembler)165 TF_BUILTIN(ElementsTransitionAndStore_Standard, HandlerBuiltinsAssembler) {
166 Generate_ElementsTransitionAndStore(STANDARD_STORE);
167 }
168
TF_BUILTIN(ElementsTransitionAndStore_GrowNoTransitionHandleCOW,HandlerBuiltinsAssembler)169 TF_BUILTIN(ElementsTransitionAndStore_GrowNoTransitionHandleCOW,
170 HandlerBuiltinsAssembler) {
171 Generate_ElementsTransitionAndStore(STORE_AND_GROW_HANDLE_COW);
172 }
173
TF_BUILTIN(ElementsTransitionAndStore_NoTransitionIgnoreOOB,HandlerBuiltinsAssembler)174 TF_BUILTIN(ElementsTransitionAndStore_NoTransitionIgnoreOOB,
175 HandlerBuiltinsAssembler) {
176 Generate_ElementsTransitionAndStore(STORE_IGNORE_OUT_OF_BOUNDS);
177 }
178
TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW,HandlerBuiltinsAssembler)179 TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW,
180 HandlerBuiltinsAssembler) {
181 Generate_ElementsTransitionAndStore(STORE_HANDLE_COW);
182 }
183
184 // All elements kinds handled by EmitElementStore. Specifically, this includes
185 // fast elements and fixed typed array elements.
186 #define ELEMENTS_KINDS(V) \
187 V(PACKED_SMI_ELEMENTS) \
188 V(HOLEY_SMI_ELEMENTS) \
189 V(PACKED_ELEMENTS) \
190 V(PACKED_NONEXTENSIBLE_ELEMENTS) \
191 V(PACKED_SEALED_ELEMENTS) \
192 V(HOLEY_ELEMENTS) \
193 V(HOLEY_NONEXTENSIBLE_ELEMENTS) \
194 V(HOLEY_SEALED_ELEMENTS) \
195 V(PACKED_DOUBLE_ELEMENTS) \
196 V(HOLEY_DOUBLE_ELEMENTS) \
197 V(UINT8_ELEMENTS) \
198 V(INT8_ELEMENTS) \
199 V(UINT16_ELEMENTS) \
200 V(INT16_ELEMENTS) \
201 V(UINT32_ELEMENTS) \
202 V(INT32_ELEMENTS) \
203 V(FLOAT32_ELEMENTS) \
204 V(FLOAT64_ELEMENTS) \
205 V(UINT8_CLAMPED_ELEMENTS) \
206 V(BIGUINT64_ELEMENTS) \
207 V(BIGINT64_ELEMENTS)
208
DispatchByElementsKind(TNode<Int32T> elements_kind,const ElementsKindSwitchCase & case_function,bool handle_typed_elements_kind)209 void HandlerBuiltinsAssembler::DispatchByElementsKind(
210 TNode<Int32T> elements_kind, const ElementsKindSwitchCase& case_function,
211 bool handle_typed_elements_kind) {
212 Label next(this), if_unknown_type(this, Label::kDeferred);
213
214 int32_t elements_kinds[] = {
215 #define ELEMENTS_KINDS_CASE(KIND) KIND,
216 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
217 #undef ELEMENTS_KINDS_CASE
218 };
219
220 #define ELEMENTS_KINDS_CASE(KIND) Label if_##KIND(this);
221 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
222 #undef ELEMENTS_KINDS_CASE
223
224 Label* elements_kind_labels[] = {
225 #define ELEMENTS_KINDS_CASE(KIND) &if_##KIND,
226 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
227 #undef ELEMENTS_KINDS_CASE
228 };
229 STATIC_ASSERT(arraysize(elements_kinds) == arraysize(elements_kind_labels));
230
231 // TODO(mythria): Do not emit cases for typed elements kind when
232 // handle_typed_elements is false to decrease the size of the jump table.
233 Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels,
234 arraysize(elements_kinds));
235
236 #define ELEMENTS_KINDS_CASE(KIND) \
237 BIND(&if_##KIND); \
238 { \
239 if (!FLAG_enable_sealed_frozen_elements_kind && \
240 IsAnyNonextensibleElementsKindUnchecked(KIND)) { \
241 /* Disable support for frozen or sealed elements kinds. */ \
242 Unreachable(); \
243 } else if (!handle_typed_elements_kind && \
244 IsTypedArrayElementsKind(KIND)) { \
245 Unreachable(); \
246 } else { \
247 case_function(KIND); \
248 Goto(&next); \
249 } \
250 }
251 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
252 #undef ELEMENTS_KINDS_CASE
253
254 BIND(&if_unknown_type);
255 Unreachable();
256
257 BIND(&next);
258 }
259
260 #undef ELEMENTS_KINDS
261
Generate_StoreFastElementIC(KeyedAccessStoreMode store_mode)262 void HandlerBuiltinsAssembler::Generate_StoreFastElementIC(
263 KeyedAccessStoreMode store_mode) {
264 using Descriptor = StoreWithVectorDescriptor;
265 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
266 auto key = Parameter<Object>(Descriptor::kName);
267 auto value = Parameter<Object>(Descriptor::kValue);
268 auto slot = Parameter<Smi>(Descriptor::kSlot);
269 auto vector = Parameter<HeapObject>(Descriptor::kVector);
270 auto context = Parameter<Context>(Descriptor::kContext);
271
272 Comment("StoreFastElementStub: store_mode=", store_mode);
273
274 Label miss(this);
275
276 bool handle_typed_elements_kind =
277 store_mode == STANDARD_STORE || store_mode == STORE_IGNORE_OUT_OF_BOUNDS;
278 // For typed arrays maybe_converted_value contains the value obtained after
279 // calling ToNumber. We should pass the converted value to the runtime to
280 // avoid doing the user visible conversion again.
281 TVARIABLE(Object, maybe_converted_value, value);
282 // TODO(v8:8481): Pass elements_kind in feedback vector slots.
283 DispatchByElementsKind(
284 LoadElementsKind(receiver),
285 [=, &miss, &maybe_converted_value](ElementsKind elements_kind) {
286 EmitElementStore(receiver, key, value, elements_kind, store_mode, &miss,
287 context, &maybe_converted_value);
288 },
289 handle_typed_elements_kind);
290 Return(value);
291
292 BIND(&miss);
293 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context,
294 maybe_converted_value.value(), slot, vector, receiver, key);
295 }
296
TF_BUILTIN(StoreFastElementIC_Standard,HandlerBuiltinsAssembler)297 TF_BUILTIN(StoreFastElementIC_Standard, HandlerBuiltinsAssembler) {
298 Generate_StoreFastElementIC(STANDARD_STORE);
299 }
300
TF_BUILTIN(StoreFastElementIC_GrowNoTransitionHandleCOW,HandlerBuiltinsAssembler)301 TF_BUILTIN(StoreFastElementIC_GrowNoTransitionHandleCOW,
302 HandlerBuiltinsAssembler) {
303 Generate_StoreFastElementIC(STORE_AND_GROW_HANDLE_COW);
304 }
305
TF_BUILTIN(StoreFastElementIC_NoTransitionIgnoreOOB,HandlerBuiltinsAssembler)306 TF_BUILTIN(StoreFastElementIC_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
307 Generate_StoreFastElementIC(STORE_IGNORE_OUT_OF_BOUNDS);
308 }
309
TF_BUILTIN(StoreFastElementIC_NoTransitionHandleCOW,HandlerBuiltinsAssembler)310 TF_BUILTIN(StoreFastElementIC_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
311 Generate_StoreFastElementIC(STORE_HANDLE_COW);
312 }
313
TF_BUILTIN(LoadIC_FunctionPrototype,CodeStubAssembler)314 TF_BUILTIN(LoadIC_FunctionPrototype, CodeStubAssembler) {
315 auto receiver = Parameter<JSFunction>(Descriptor::kReceiver);
316 auto name = Parameter<Name>(Descriptor::kName);
317 auto slot = Parameter<Smi>(Descriptor::kSlot);
318 auto vector = Parameter<FeedbackVector>(Descriptor::kVector);
319 auto context = Parameter<Context>(Descriptor::kContext);
320
321 Label miss(this, Label::kDeferred);
322 Return(LoadJSFunctionPrototype(receiver, &miss));
323
324 BIND(&miss);
325 TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, slot, vector);
326 }
327
TF_BUILTIN(StoreGlobalIC_Slow,CodeStubAssembler)328 TF_BUILTIN(StoreGlobalIC_Slow, CodeStubAssembler) {
329 auto receiver = Parameter<Object>(Descriptor::kReceiver);
330 auto name = Parameter<Name>(Descriptor::kName);
331 auto value = Parameter<Object>(Descriptor::kValue);
332 auto slot = Parameter<Smi>(Descriptor::kSlot);
333 auto vector = Parameter<FeedbackVector>(Descriptor::kVector);
334 auto context = Parameter<Context>(Descriptor::kContext);
335
336 // The slow case calls into the runtime to complete the store without causing
337 // an IC miss that would otherwise cause a transition to the generic stub.
338 TailCallRuntime(Runtime::kStoreGlobalIC_Slow, context, value, slot, vector,
339 receiver, name);
340 }
341
TF_BUILTIN(KeyedLoadIC_SloppyArguments,HandlerBuiltinsAssembler)342 TF_BUILTIN(KeyedLoadIC_SloppyArguments, HandlerBuiltinsAssembler) {
343 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
344 auto key = Parameter<Object>(Descriptor::kName);
345 auto slot = Parameter<Smi>(Descriptor::kSlot);
346 auto vector = Parameter<HeapObject>(Descriptor::kVector);
347 auto context = Parameter<Context>(Descriptor::kContext);
348
349 Label miss(this);
350
351 TNode<Object> result = SloppyArgumentsLoad(receiver, key, &miss);
352 Return(result);
353
354 BIND(&miss);
355 {
356 Comment("Miss");
357 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
358 vector);
359 }
360 }
361
Generate_KeyedStoreIC_SloppyArguments()362 void HandlerBuiltinsAssembler::Generate_KeyedStoreIC_SloppyArguments() {
363 using Descriptor = StoreWithVectorDescriptor;
364 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
365 auto key = Parameter<Object>(Descriptor::kName);
366 auto value = Parameter<Object>(Descriptor::kValue);
367 auto slot = Parameter<Smi>(Descriptor::kSlot);
368 auto vector = Parameter<HeapObject>(Descriptor::kVector);
369 auto context = Parameter<Context>(Descriptor::kContext);
370
371 Label miss(this);
372
373 SloppyArgumentsStore(receiver, key, value, &miss);
374 Return(value);
375
376 BIND(&miss);
377 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
378 receiver, key);
379 }
380
TF_BUILTIN(KeyedStoreIC_SloppyArguments_Standard,HandlerBuiltinsAssembler)381 TF_BUILTIN(KeyedStoreIC_SloppyArguments_Standard, HandlerBuiltinsAssembler) {
382 Generate_KeyedStoreIC_SloppyArguments();
383 }
384
TF_BUILTIN(KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW,HandlerBuiltinsAssembler)385 TF_BUILTIN(KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW,
386 HandlerBuiltinsAssembler) {
387 Generate_KeyedStoreIC_SloppyArguments();
388 }
389
TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB,HandlerBuiltinsAssembler)390 TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB,
391 HandlerBuiltinsAssembler) {
392 Generate_KeyedStoreIC_SloppyArguments();
393 }
394
TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW,HandlerBuiltinsAssembler)395 TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW,
396 HandlerBuiltinsAssembler) {
397 Generate_KeyedStoreIC_SloppyArguments();
398 }
399
TF_BUILTIN(LoadIndexedInterceptorIC,CodeStubAssembler)400 TF_BUILTIN(LoadIndexedInterceptorIC, CodeStubAssembler) {
401 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
402 auto key = Parameter<Object>(Descriptor::kName);
403 auto slot = Parameter<Smi>(Descriptor::kSlot);
404 auto vector = Parameter<HeapObject>(Descriptor::kVector);
405 auto context = Parameter<Context>(Descriptor::kContext);
406
407 Label if_keyispositivesmi(this), if_keyisinvalid(this);
408 Branch(TaggedIsPositiveSmi(key), &if_keyispositivesmi, &if_keyisinvalid);
409 BIND(&if_keyispositivesmi);
410 TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, receiver, key);
411
412 BIND(&if_keyisinvalid);
413 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
414 vector);
415 }
416
TF_BUILTIN(KeyedHasIC_SloppyArguments,HandlerBuiltinsAssembler)417 TF_BUILTIN(KeyedHasIC_SloppyArguments, HandlerBuiltinsAssembler) {
418 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
419 auto key = Parameter<Object>(Descriptor::kName);
420 auto slot = Parameter<Smi>(Descriptor::kSlot);
421 auto vector = Parameter<HeapObject>(Descriptor::kVector);
422 auto context = Parameter<Context>(Descriptor::kContext);
423
424 Label miss(this);
425
426 TNode<Object> result = SloppyArgumentsHas(receiver, key, &miss);
427 Return(result);
428
429 BIND(&miss);
430 {
431 Comment("Miss");
432 TailCallRuntime(Runtime::kKeyedHasIC_Miss, context, receiver, key, slot,
433 vector);
434 }
435 }
436
TF_BUILTIN(HasIndexedInterceptorIC,CodeStubAssembler)437 TF_BUILTIN(HasIndexedInterceptorIC, CodeStubAssembler) {
438 auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
439 auto key = Parameter<Object>(Descriptor::kName);
440 auto slot = Parameter<Smi>(Descriptor::kSlot);
441 auto vector = Parameter<HeapObject>(Descriptor::kVector);
442 auto context = Parameter<Context>(Descriptor::kContext);
443
444 Label if_keyispositivesmi(this), if_keyisinvalid(this);
445 Branch(TaggedIsPositiveSmi(key), &if_keyispositivesmi, &if_keyisinvalid);
446 BIND(&if_keyispositivesmi);
447 TailCallRuntime(Runtime::kHasElementWithInterceptor, context, receiver, key);
448
449 BIND(&if_keyisinvalid);
450 TailCallRuntime(Runtime::kKeyedHasIC_Miss, context, receiver, key, slot,
451 vector);
452 }
453
454 } // namespace internal
455 } // namespace v8
456