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