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 : 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 : // 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 168 : TF_BUILTIN(KeyedStoreIC_Slow, HandlerBuiltinsAssembler) {
88 56 : Generate_KeyedStoreIC_Slow();
89 0 : }
90 :
91 168 : TF_BUILTIN(KeyedStoreIC_Slow_Standard, HandlerBuiltinsAssembler) {
92 56 : Generate_KeyedStoreIC_Slow();
93 0 : }
94 :
95 168 : TF_BUILTIN(KeyedStoreIC_Slow_GrowNoTransitionHandleCOW,
96 : HandlerBuiltinsAssembler) {
97 56 : Generate_KeyedStoreIC_Slow();
98 0 : }
99 :
100 168 : TF_BUILTIN(KeyedStoreIC_Slow_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
101 56 : Generate_KeyedStoreIC_Slow();
102 0 : }
103 :
104 168 : TF_BUILTIN(KeyedStoreIC_Slow_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
105 56 : Generate_KeyedStoreIC_Slow();
106 0 : }
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 280 : TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, context, value, array,
115 280 : index);
116 280 : }
117 :
118 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow, HandlerBuiltinsAssembler) {
119 56 : Generate_StoreInArrayLiteralIC_Slow();
120 0 : }
121 :
122 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_Standard, HandlerBuiltinsAssembler) {
123 56 : Generate_StoreInArrayLiteralIC_Slow();
124 0 : }
125 :
126 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW,
127 : HandlerBuiltinsAssembler) {
128 56 : Generate_StoreInArrayLiteralIC_Slow();
129 0 : }
130 :
131 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB,
132 : HandlerBuiltinsAssembler) {
133 56 : Generate_StoreInArrayLiteralIC_Slow();
134 0 : }
135 :
136 168 : TF_BUILTIN(StoreInArrayLiteralIC_Slow_NoTransitionHandleCOW,
137 : HandlerBuiltinsAssembler) {
138 56 : Generate_StoreInArrayLiteralIC_Slow();
139 0 : }
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 224 : 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 672 : Word32Or(Word32Shl(from_kind, Int32Constant(kBitsPerByte)), to_kind);
184 :
185 : 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 2912 : 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 224 : 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 1120 : 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 224 : TailCallRuntime(Runtime::kElementsTransitionAndStoreIC_Miss, context,
237 224 : receiver, key, value, map, slot, vector);
238 224 : }
239 :
240 168 : TF_BUILTIN(ElementsTransitionAndStore_Standard, HandlerBuiltinsAssembler) {
241 56 : Generate_ElementsTransitionAndStore(STANDARD_STORE);
242 0 : }
243 :
244 168 : TF_BUILTIN(ElementsTransitionAndStore_GrowNoTransitionHandleCOW,
245 : HandlerBuiltinsAssembler) {
246 56 : Generate_ElementsTransitionAndStore(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
247 0 : }
248 :
249 168 : TF_BUILTIN(ElementsTransitionAndStore_NoTransitionIgnoreOOB,
250 : HandlerBuiltinsAssembler) {
251 56 : Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
252 0 : }
253 :
254 168 : TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW,
255 : HandlerBuiltinsAssembler) {
256 56 : Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_HANDLE_COW);
257 0 : }
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(PACKED_SEALED_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 4256 : ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
312 : #undef ELEMENTS_KINDS_CASE
313 :
314 224 : BIND(&if_unknown_type);
315 224 : Unreachable();
316 :
317 224 : 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 224 : Label miss(this);
335 :
336 : // TODO(v8:8481): Pass elements_kind in feedback vector slots.
337 896 : DispatchByElementsKind(LoadElementsKind(receiver),
338 8064 : [=, &miss](ElementsKind elements_kind) {
339 8064 : EmitElementStore(receiver, key, value, elements_kind,
340 16128 : store_mode, &miss, context);
341 4256 : });
342 224 : Return(value);
343 :
344 224 : BIND(&miss);
345 224 : 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 56 : 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 56 : 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 56 : 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 56 : TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
427 56 : vector);
428 : }
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 224 : Label miss(this);
441 :
442 224 : StoreKeyedSloppyArguments(receiver, key, value, &miss);
443 224 : Return(value);
444 :
445 224 : BIND(&miss);
446 224 : 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 56 : 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 56 : TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
494 56 : vector);
495 56 : }
496 :
497 168 : TF_BUILTIN(KeyedHasIC_SloppyArguments, CodeStubAssembler) {
498 : Node* receiver = Parameter(Descriptor::kReceiver);
499 : Node* key = Parameter(Descriptor::kName);
500 : Node* slot = Parameter(Descriptor::kSlot);
501 : Node* vector = Parameter(Descriptor::kVector);
502 : Node* context = Parameter(Descriptor::kContext);
503 :
504 56 : Label miss(this);
505 :
506 56 : Node* result = HasKeyedSloppyArguments(receiver, key, &miss);
507 56 : Return(result);
508 :
509 56 : BIND(&miss);
510 : {
511 56 : Comment("Miss");
512 56 : TailCallRuntime(Runtime::kKeyedHasIC_Miss, context, receiver, key, slot,
513 56 : vector);
514 : }
515 56 : }
516 :
517 168 : TF_BUILTIN(HasIndexedInterceptorIC, CodeStubAssembler) {
518 : Node* receiver = Parameter(Descriptor::kReceiver);
519 : Node* key = Parameter(Descriptor::kName);
520 : Node* slot = Parameter(Descriptor::kSlot);
521 : Node* vector = Parameter(Descriptor::kVector);
522 : Node* context = Parameter(Descriptor::kContext);
523 :
524 56 : Label if_keyispositivesmi(this), if_keyisinvalid(this);
525 112 : Branch(TaggedIsPositiveSmi(key), &if_keyispositivesmi, &if_keyisinvalid);
526 56 : BIND(&if_keyispositivesmi);
527 56 : TailCallRuntime(Runtime::kHasElementWithInterceptor, context, receiver, key);
528 :
529 56 : BIND(&if_keyisinvalid);
530 56 : TailCallRuntime(Runtime::kKeyedHasIC_Miss, context, receiver, key, slot,
531 56 : vector);
532 56 : }
533 :
534 168 : TF_BUILTIN(HasIC_Slow, CodeStubAssembler) {
535 : Node* receiver = Parameter(Descriptor::kReceiver);
536 : Node* name = Parameter(Descriptor::kName);
537 : Node* context = Parameter(Descriptor::kContext);
538 :
539 56 : TailCallRuntime(Runtime::kHasProperty, context, receiver, name);
540 56 : }
541 :
542 : } // namespace internal
543 59480 : } // namespace v8
|