Line data Source code
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/builtins/builtins-utils-gen.h"
6 : #include "src/builtins/builtins.h"
7 : #include "src/code-stub-assembler.h"
8 : #include "src/ic/ic.h"
9 : #include "src/ic/keyed-store-generic.h"
10 : #include "src/objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : class HandlerBuiltinsAssembler : public CodeStubAssembler {
16 : public:
17 : explicit HandlerBuiltinsAssembler(compiler::CodeAssemblerState* state)
18 1232 : : CodeStubAssembler(state) {}
19 :
20 : protected:
21 : void Generate_KeyedStoreIC_SloppyArguments();
22 : void Generate_KeyedStoreIC_Slow();
23 : void Generate_StoreInArrayLiteralIC_Slow();
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 : typedef std::function<void(ElementsKind)> ElementsKindSwitchCase;
30 : void DispatchByElementsKind(TNode<Int32T> elements_kind,
31 : const ElementsKindSwitchCase& case_function);
32 :
33 : // Dispatches over all possible combinations of {from,to} elements kinds.
34 : typedef std::function<void(ElementsKind, ElementsKind)>
35 : ElementsKindTransitionSwitchCase;
36 : void DispatchForElementsKindTransition(
37 : TNode<Int32T> from_kind, TNode<Int32T> to_kind,
38 : const ElementsKindTransitionSwitchCase& case_function);
39 :
40 : void Generate_ElementsTransitionAndStore(KeyedAccessStoreMode store_mode);
41 : void Generate_StoreFastElementIC(KeyedAccessStoreMode store_mode);
42 : };
43 :
44 168 : TF_BUILTIN(LoadIC_StringLength, CodeStubAssembler) {
45 : Node* string = Parameter(Descriptor::kReceiver);
46 112 : Return(LoadStringLengthAsSmi(string));
47 56 : }
48 :
49 168 : TF_BUILTIN(LoadIC_StringWrapperLength, CodeStubAssembler) {
50 : Node* value = Parameter(Descriptor::kReceiver);
51 56 : Node* string = LoadJSValueValue(value);
52 112 : Return(LoadStringLengthAsSmi(string));
53 56 : }
54 :
55 168 : TF_BUILTIN(KeyedLoadIC_Slow, CodeStubAssembler) {
56 : Node* receiver = Parameter(Descriptor::kReceiver);
57 : Node* name = Parameter(Descriptor::kName);
58 : Node* context = Parameter(Descriptor::kContext);
59 :
60 56 : TailCallRuntime(Runtime::kGetProperty, context, receiver, name);
61 56 : }
62 :
63 56 : void Builtins::Generate_KeyedStoreIC_Megamorphic(
64 : compiler::CodeAssemblerState* state) {
65 56 : KeyedStoreGenericGenerator::Generate(state);
66 56 : }
67 :
68 56 : void Builtins::Generate_StoreIC_Uninitialized(
69 : compiler::CodeAssemblerState* state) {
70 56 : StoreICUninitializedGenerator::Generate(state);
71 56 : }
72 :
73 280 : void HandlerBuiltinsAssembler::Generate_KeyedStoreIC_Slow() {
74 : typedef StoreWithVectorDescriptor Descriptor;
75 280 : Node* receiver = Parameter(Descriptor::kReceiver);
76 280 : Node* name = Parameter(Descriptor::kName);
77 280 : Node* value = Parameter(Descriptor::kValue);
78 280 : Node* slot = Parameter(Descriptor::kSlot);
79 280 : Node* vector = Parameter(Descriptor::kVector);
80 280 : Node* context = Parameter(Descriptor::kContext);
81 :
82 : // The slow case calls into the runtime to complete the store without causing
83 : // an IC miss that would otherwise cause a transition to the generic stub.
84 : TailCallRuntime(Runtime::kKeyedStoreIC_Slow, context, value, slot, vector,
85 280 : receiver, name);
86 280 : }
87 :
88 168 : TF_BUILTIN(KeyedStoreIC_Slow, HandlerBuiltinsAssembler) {
89 56 : Generate_KeyedStoreIC_Slow();
90 0 : }
91 :
92 168 : TF_BUILTIN(KeyedStoreIC_Slow_Standard, HandlerBuiltinsAssembler) {
93 56 : Generate_KeyedStoreIC_Slow();
94 0 : }
95 :
96 168 : TF_BUILTIN(KeyedStoreIC_Slow_GrowNoTransitionHandleCOW,
97 : HandlerBuiltinsAssembler) {
98 56 : Generate_KeyedStoreIC_Slow();
99 0 : }
100 :
101 168 : TF_BUILTIN(KeyedStoreIC_Slow_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
102 56 : Generate_KeyedStoreIC_Slow();
103 0 : }
104 :
105 168 : TF_BUILTIN(KeyedStoreIC_Slow_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
106 56 : Generate_KeyedStoreIC_Slow();
107 0 : }
108 :
109 280 : void HandlerBuiltinsAssembler::Generate_StoreInArrayLiteralIC_Slow() {
110 : typedef StoreWithVectorDescriptor Descriptor;
111 280 : Node* array = Parameter(Descriptor::kReceiver);
112 280 : Node* index = Parameter(Descriptor::kName);
113 280 : Node* value = Parameter(Descriptor::kValue);
114 280 : Node* context = Parameter(Descriptor::kContext);
115 : TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, context, value, array,
116 280 : index);
117 280 : }
118 :
119 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow, HandlerBuiltinsAssembler) {
120 56 : Generate_StoreInArrayLiteralIC_Slow();
121 0 : }
122 :
123 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_Standard, HandlerBuiltinsAssembler) {
124 56 : Generate_StoreInArrayLiteralIC_Slow();
125 0 : }
126 :
127 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW,
128 : HandlerBuiltinsAssembler) {
129 56 : Generate_StoreInArrayLiteralIC_Slow();
130 0 : }
131 :
132 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB,
133 : HandlerBuiltinsAssembler) {
134 56 : Generate_StoreInArrayLiteralIC_Slow();
135 0 : }
136 :
137 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_NoTransitionHandleCOW,
138 : HandlerBuiltinsAssembler) {
139 56 : Generate_StoreInArrayLiteralIC_Slow();
140 0 : }
141 :
142 : // All possible fast-to-fast transitions. Transitions to dictionary mode are not
143 : // handled by ElementsTransitionAndStore.
144 : #define ELEMENTS_KIND_TRANSITIONS(V) \
145 : V(PACKED_SMI_ELEMENTS, HOLEY_SMI_ELEMENTS) \
146 : V(PACKED_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS) \
147 : V(PACKED_SMI_ELEMENTS, HOLEY_DOUBLE_ELEMENTS) \
148 : V(PACKED_SMI_ELEMENTS, PACKED_ELEMENTS) \
149 : V(PACKED_SMI_ELEMENTS, HOLEY_ELEMENTS) \
150 : V(HOLEY_SMI_ELEMENTS, HOLEY_DOUBLE_ELEMENTS) \
151 : V(HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS) \
152 : V(PACKED_DOUBLE_ELEMENTS, HOLEY_DOUBLE_ELEMENTS) \
153 : V(PACKED_DOUBLE_ELEMENTS, PACKED_ELEMENTS) \
154 : V(PACKED_DOUBLE_ELEMENTS, HOLEY_ELEMENTS) \
155 : V(HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS) \
156 : V(PACKED_ELEMENTS, HOLEY_ELEMENTS)
157 :
158 224 : void HandlerBuiltinsAssembler::DispatchForElementsKindTransition(
159 : TNode<Int32T> from_kind, TNode<Int32T> to_kind,
160 : const ElementsKindTransitionSwitchCase& case_function) {
161 : STATIC_ASSERT(sizeof(ElementsKind) == sizeof(uint8_t));
162 :
163 448 : Label next(this), if_unknown_type(this, Label::kDeferred);
164 :
165 : int32_t combined_elements_kinds[] = {
166 : #define ELEMENTS_KINDS_CASE(FROM, TO) (FROM << kBitsPerByte) | TO,
167 : ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
168 : #undef ELEMENTS_KINDS_CASE
169 224 : };
170 :
171 : #define ELEMENTS_KINDS_CASE(FROM, TO) Label if_##FROM##_##TO(this);
172 224 : ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
173 : #undef ELEMENTS_KINDS_CASE
174 :
175 : Label* elements_kind_labels[] = {
176 : #define ELEMENTS_KINDS_CASE(FROM, TO) &if_##FROM##_##TO,
177 : ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
178 : #undef ELEMENTS_KINDS_CASE
179 224 : };
180 : STATIC_ASSERT(arraysize(combined_elements_kinds) ==
181 : arraysize(elements_kind_labels));
182 :
183 : TNode<Word32T> combined_elements_kind =
184 672 : Word32Or(Word32Shl(from_kind, Int32Constant(kBitsPerByte)), to_kind);
185 :
186 : Switch(combined_elements_kind, &if_unknown_type, combined_elements_kinds,
187 224 : elements_kind_labels, arraysize(combined_elements_kinds));
188 :
189 : #define ELEMENTS_KINDS_CASE(FROM, TO) \
190 : BIND(&if_##FROM##_##TO); \
191 : { \
192 : case_function(FROM, TO); \
193 : Goto(&next); \
194 : }
195 224 : ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
196 : #undef ELEMENTS_KINDS_CASE
197 :
198 224 : BIND(&if_unknown_type);
199 224 : Unreachable();
200 :
201 448 : BIND(&next);
202 224 : }
203 :
204 : #undef ELEMENTS_KIND_TRANSITIONS
205 :
206 224 : void HandlerBuiltinsAssembler::Generate_ElementsTransitionAndStore(
207 : KeyedAccessStoreMode store_mode) {
208 : typedef StoreTransitionDescriptor Descriptor;
209 224 : Node* receiver = Parameter(Descriptor::kReceiver);
210 224 : Node* key = Parameter(Descriptor::kName);
211 224 : Node* value = Parameter(Descriptor::kValue);
212 224 : Node* map = Parameter(Descriptor::kMap);
213 224 : Node* slot = Parameter(Descriptor::kSlot);
214 224 : Node* vector = Parameter(Descriptor::kVector);
215 224 : Node* context = Parameter(Descriptor::kContext);
216 :
217 224 : Comment("ElementsTransitionAndStore: store_mode=", store_mode);
218 :
219 : Label miss(this);
220 :
221 : if (FLAG_trace_elements_transitions) {
222 : // Tracing elements transitions is the job of the runtime.
223 : Goto(&miss);
224 : } else {
225 : // TODO(v8:8481): Pass from_kind and to_kind in feedback vector slots.
226 : DispatchForElementsKindTransition(
227 : LoadElementsKind(receiver), LoadMapElementsKind(map),
228 2688 : [=, &miss](ElementsKind from_kind, ElementsKind to_kind) {
229 2688 : TransitionElementsKind(receiver, map, from_kind, to_kind, &miss);
230 : EmitElementStore(receiver, key, value, to_kind, store_mode, &miss,
231 2688 : context);
232 3584 : });
233 224 : Return(value);
234 : }
235 :
236 224 : BIND(&miss);
237 : TailCallRuntime(Runtime::kElementsTransitionAndStoreIC_Miss, context,
238 224 : receiver, key, value, map, slot, vector);
239 224 : }
240 :
241 168 : TF_BUILTIN(ElementsTransitionAndStore_Standard, HandlerBuiltinsAssembler) {
242 56 : Generate_ElementsTransitionAndStore(STANDARD_STORE);
243 0 : }
244 :
245 168 : TF_BUILTIN(ElementsTransitionAndStore_GrowNoTransitionHandleCOW,
246 : HandlerBuiltinsAssembler) {
247 56 : Generate_ElementsTransitionAndStore(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
248 0 : }
249 :
250 168 : TF_BUILTIN(ElementsTransitionAndStore_NoTransitionIgnoreOOB,
251 : HandlerBuiltinsAssembler) {
252 56 : Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
253 0 : }
254 :
255 168 : TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW,
256 : HandlerBuiltinsAssembler) {
257 56 : Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_HANDLE_COW);
258 0 : }
259 :
260 : // All elements kinds handled by EmitElementStore. Specifically, this includes
261 : // fast elements and fixed typed array elements.
262 : #define ELEMENTS_KINDS(V) \
263 : V(PACKED_SMI_ELEMENTS) \
264 : V(HOLEY_SMI_ELEMENTS) \
265 : V(PACKED_ELEMENTS) \
266 : V(HOLEY_ELEMENTS) \
267 : V(PACKED_DOUBLE_ELEMENTS) \
268 : V(HOLEY_DOUBLE_ELEMENTS) \
269 : V(UINT8_ELEMENTS) \
270 : V(INT8_ELEMENTS) \
271 : V(UINT16_ELEMENTS) \
272 : V(INT16_ELEMENTS) \
273 : V(UINT32_ELEMENTS) \
274 : V(INT32_ELEMENTS) \
275 : V(FLOAT32_ELEMENTS) \
276 : V(FLOAT64_ELEMENTS) \
277 : V(UINT8_CLAMPED_ELEMENTS) \
278 : V(BIGUINT64_ELEMENTS) \
279 : V(BIGINT64_ELEMENTS)
280 :
281 224 : void HandlerBuiltinsAssembler::DispatchByElementsKind(
282 : TNode<Int32T> elements_kind, const ElementsKindSwitchCase& case_function) {
283 448 : Label next(this), if_unknown_type(this, Label::kDeferred);
284 :
285 : int32_t elements_kinds[] = {
286 : #define ELEMENTS_KINDS_CASE(KIND) KIND,
287 : ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
288 : #undef ELEMENTS_KINDS_CASE
289 224 : };
290 :
291 : #define ELEMENTS_KINDS_CASE(KIND) Label if_##KIND(this);
292 224 : ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
293 : #undef ELEMENTS_KINDS_CASE
294 :
295 : Label* elements_kind_labels[] = {
296 : #define ELEMENTS_KINDS_CASE(KIND) &if_##KIND,
297 : ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
298 : #undef ELEMENTS_KINDS_CASE
299 224 : };
300 : STATIC_ASSERT(arraysize(elements_kinds) == arraysize(elements_kind_labels));
301 :
302 : Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels,
303 224 : arraysize(elements_kinds));
304 :
305 : #define ELEMENTS_KINDS_CASE(KIND) \
306 : BIND(&if_##KIND); \
307 : { \
308 : case_function(KIND); \
309 : Goto(&next); \
310 : }
311 224 : ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
312 : #undef ELEMENTS_KINDS_CASE
313 :
314 224 : BIND(&if_unknown_type);
315 224 : Unreachable();
316 :
317 448 : BIND(&next);
318 224 : }
319 :
320 : #undef ELEMENTS_KINDS
321 :
322 224 : void HandlerBuiltinsAssembler::Generate_StoreFastElementIC(
323 : KeyedAccessStoreMode store_mode) {
324 : typedef StoreWithVectorDescriptor Descriptor;
325 224 : Node* receiver = Parameter(Descriptor::kReceiver);
326 224 : Node* key = Parameter(Descriptor::kName);
327 224 : Node* value = Parameter(Descriptor::kValue);
328 224 : Node* slot = Parameter(Descriptor::kSlot);
329 224 : Node* vector = Parameter(Descriptor::kVector);
330 224 : Node* context = Parameter(Descriptor::kContext);
331 :
332 224 : Comment("StoreFastElementStub: store_mode=", store_mode);
333 :
334 : Label miss(this);
335 :
336 : // TODO(v8:8481): Pass elements_kind in feedback vector slots.
337 : DispatchByElementsKind(LoadElementsKind(receiver),
338 3808 : [=, &miss](ElementsKind elements_kind) {
339 : EmitElementStore(receiver, key, value, elements_kind,
340 3808 : store_mode, &miss, context);
341 4480 : });
342 224 : Return(value);
343 :
344 224 : BIND(&miss);
345 : TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
346 224 : receiver, key);
347 224 : }
348 :
349 168 : TF_BUILTIN(StoreFastElementIC_Standard, HandlerBuiltinsAssembler) {
350 56 : Generate_StoreFastElementIC(STANDARD_STORE);
351 0 : }
352 :
353 168 : TF_BUILTIN(StoreFastElementIC_GrowNoTransitionHandleCOW,
354 : HandlerBuiltinsAssembler) {
355 56 : Generate_StoreFastElementIC(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
356 0 : }
357 :
358 168 : TF_BUILTIN(StoreFastElementIC_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
359 56 : Generate_StoreFastElementIC(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
360 0 : }
361 :
362 168 : TF_BUILTIN(StoreFastElementIC_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
363 56 : Generate_StoreFastElementIC(STORE_NO_TRANSITION_HANDLE_COW);
364 0 : }
365 :
366 168 : TF_BUILTIN(LoadGlobalIC_Slow, CodeStubAssembler) {
367 : Node* name = Parameter(Descriptor::kName);
368 : Node* slot = Parameter(Descriptor::kSlot);
369 : Node* vector = Parameter(Descriptor::kVector);
370 : Node* context = Parameter(Descriptor::kContext);
371 :
372 56 : TailCallRuntime(Runtime::kLoadGlobalIC_Slow, context, name, slot, vector);
373 56 : }
374 :
375 168 : TF_BUILTIN(LoadIC_FunctionPrototype, CodeStubAssembler) {
376 : Node* receiver = Parameter(Descriptor::kReceiver);
377 : Node* name = Parameter(Descriptor::kName);
378 : Node* slot = Parameter(Descriptor::kSlot);
379 : Node* vector = Parameter(Descriptor::kVector);
380 : Node* context = Parameter(Descriptor::kContext);
381 :
382 : Label miss(this, Label::kDeferred);
383 112 : Return(LoadJSFunctionPrototype(receiver, &miss));
384 :
385 56 : BIND(&miss);
386 56 : TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, slot, vector);
387 56 : }
388 :
389 168 : TF_BUILTIN(LoadIC_Slow, CodeStubAssembler) {
390 : Node* receiver = Parameter(Descriptor::kReceiver);
391 : Node* name = Parameter(Descriptor::kName);
392 : Node* context = Parameter(Descriptor::kContext);
393 :
394 56 : TailCallRuntime(Runtime::kGetProperty, context, receiver, name);
395 56 : }
396 :
397 168 : TF_BUILTIN(StoreGlobalIC_Slow, CodeStubAssembler) {
398 : Node* receiver = Parameter(Descriptor::kReceiver);
399 : Node* name = Parameter(Descriptor::kName);
400 : Node* value = Parameter(Descriptor::kValue);
401 : Node* slot = Parameter(Descriptor::kSlot);
402 : Node* vector = Parameter(Descriptor::kVector);
403 : Node* context = Parameter(Descriptor::kContext);
404 :
405 : // The slow case calls into the runtime to complete the store without causing
406 : // an IC miss that would otherwise cause a transition to the generic stub.
407 : TailCallRuntime(Runtime::kStoreGlobalIC_Slow, context, value, slot, vector,
408 56 : receiver, name);
409 56 : }
410 :
411 168 : TF_BUILTIN(KeyedLoadIC_SloppyArguments, CodeStubAssembler) {
412 : Node* receiver = Parameter(Descriptor::kReceiver);
413 : Node* key = Parameter(Descriptor::kName);
414 : Node* slot = Parameter(Descriptor::kSlot);
415 : Node* vector = Parameter(Descriptor::kVector);
416 : Node* context = Parameter(Descriptor::kContext);
417 :
418 : Label miss(this);
419 :
420 56 : Node* result = LoadKeyedSloppyArguments(receiver, key, &miss);
421 56 : Return(result);
422 :
423 56 : BIND(&miss);
424 : {
425 56 : Comment("Miss");
426 : TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
427 56 : vector);
428 56 : }
429 56 : }
430 :
431 224 : void HandlerBuiltinsAssembler::Generate_KeyedStoreIC_SloppyArguments() {
432 : typedef StoreWithVectorDescriptor Descriptor;
433 224 : Node* receiver = Parameter(Descriptor::kReceiver);
434 224 : Node* key = Parameter(Descriptor::kName);
435 224 : Node* value = Parameter(Descriptor::kValue);
436 224 : Node* slot = Parameter(Descriptor::kSlot);
437 224 : Node* vector = Parameter(Descriptor::kVector);
438 224 : Node* context = Parameter(Descriptor::kContext);
439 :
440 : Label miss(this);
441 :
442 224 : StoreKeyedSloppyArguments(receiver, key, value, &miss);
443 224 : Return(value);
444 :
445 224 : BIND(&miss);
446 : TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
447 224 : receiver, key);
448 224 : }
449 :
450 168 : TF_BUILTIN(KeyedStoreIC_SloppyArguments_Standard, HandlerBuiltinsAssembler) {
451 56 : Generate_KeyedStoreIC_SloppyArguments();
452 0 : }
453 :
454 168 : TF_BUILTIN(KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW,
455 : HandlerBuiltinsAssembler) {
456 56 : Generate_KeyedStoreIC_SloppyArguments();
457 0 : }
458 :
459 168 : TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB,
460 : HandlerBuiltinsAssembler) {
461 56 : Generate_KeyedStoreIC_SloppyArguments();
462 0 : }
463 :
464 168 : TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW,
465 : HandlerBuiltinsAssembler) {
466 56 : Generate_KeyedStoreIC_SloppyArguments();
467 0 : }
468 :
469 168 : TF_BUILTIN(StoreInterceptorIC, CodeStubAssembler) {
470 : Node* receiver = Parameter(Descriptor::kReceiver);
471 : Node* name = Parameter(Descriptor::kName);
472 : Node* value = Parameter(Descriptor::kValue);
473 : Node* slot = Parameter(Descriptor::kSlot);
474 : Node* vector = Parameter(Descriptor::kVector);
475 : Node* context = Parameter(Descriptor::kContext);
476 : TailCallRuntime(Runtime::kStorePropertyWithInterceptor, context, value, slot,
477 56 : vector, receiver, name);
478 56 : }
479 :
480 168 : TF_BUILTIN(LoadIndexedInterceptorIC, CodeStubAssembler) {
481 : Node* receiver = Parameter(Descriptor::kReceiver);
482 : Node* key = Parameter(Descriptor::kName);
483 : Node* slot = Parameter(Descriptor::kSlot);
484 : Node* vector = Parameter(Descriptor::kVector);
485 : Node* context = Parameter(Descriptor::kContext);
486 :
487 56 : Label if_keyispositivesmi(this), if_keyisinvalid(this);
488 112 : Branch(TaggedIsPositiveSmi(key), &if_keyispositivesmi, &if_keyisinvalid);
489 56 : BIND(&if_keyispositivesmi);
490 56 : TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, receiver, key);
491 :
492 56 : BIND(&if_keyisinvalid);
493 : TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
494 112 : vector);
495 56 : }
496 :
497 : } // namespace internal
498 94089 : } // namespace v8
|