5 #include "src/builtins/builtins-utils-gen.h" 6 #include "src/builtins/builtins.h" 7 #include "src/code-stub-assembler.h" 9 #include "src/ic/keyed-store-generic.h" 10 #include "src/objects-inl.h" 21 void Generate_KeyedStoreIC_SloppyArguments();
22 void Generate_KeyedStoreIC_Slow();
23 void Generate_StoreInArrayLiteralIC_Slow();
29 typedef std::function<void(ElementsKind)> ElementsKindSwitchCase;
31 const ElementsKindSwitchCase& case_function);
34 typedef std::function<void(ElementsKind, ElementsKind)>
35 ElementsKindTransitionSwitchCase;
36 void DispatchForElementsKindTransition(
38 const ElementsKindTransitionSwitchCase& case_function);
40 void Generate_ElementsTransitionAndStore(KeyedAccessStoreMode store_mode);
41 void Generate_StoreFastElementIC(KeyedAccessStoreMode store_mode);
45 Node*
string = Parameter(Descriptor::kReceiver);
46 Return(LoadStringLengthAsSmi(
string));
49 TF_BUILTIN(LoadIC_StringWrapperLength, CodeStubAssembler) {
50 Node* value = Parameter(Descriptor::kReceiver);
51 Node*
string = LoadJSValueValue(value);
52 Return(LoadStringLengthAsSmi(
string));
55 TF_BUILTIN(KeyedLoadIC_Slow, CodeStubAssembler) {
56 Node* receiver = Parameter(Descriptor::kReceiver);
57 Node* name = Parameter(Descriptor::kName);
58 Node* context = Parameter(Descriptor::kContext);
60 TailCallRuntime(Runtime::kGetProperty, context, receiver, name);
63 void Builtins::Generate_KeyedStoreIC_Megamorphic(
64 compiler::CodeAssemblerState* state) {
65 KeyedStoreGenericGenerator::Generate(state);
68 void Builtins::Generate_StoreIC_Uninitialized(
69 compiler::CodeAssemblerState* state) {
70 StoreICUninitializedGenerator::Generate(state);
73 void HandlerBuiltinsAssembler::Generate_KeyedStoreIC_Slow() {
74 typedef StoreWithVectorDescriptor Descriptor;
75 Node* receiver = Parameter(Descriptor::kReceiver);
76 Node* name = Parameter(Descriptor::kName);
77 Node* value = Parameter(Descriptor::kValue);
78 Node* slot = Parameter(Descriptor::kSlot);
79 Node* vector = Parameter(Descriptor::kVector);
80 Node* context = Parameter(Descriptor::kContext);
84 TailCallRuntime(Runtime::kKeyedStoreIC_Slow, context, value, slot, vector,
88 TF_BUILTIN(KeyedStoreIC_Slow, HandlerBuiltinsAssembler) {
89 Generate_KeyedStoreIC_Slow();
92 TF_BUILTIN(KeyedStoreIC_Slow_Standard, HandlerBuiltinsAssembler) {
93 Generate_KeyedStoreIC_Slow();
96 TF_BUILTIN(KeyedStoreIC_Slow_GrowNoTransitionHandleCOW,
97 HandlerBuiltinsAssembler) {
98 Generate_KeyedStoreIC_Slow();
101 TF_BUILTIN(KeyedStoreIC_Slow_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
102 Generate_KeyedStoreIC_Slow();
105 TF_BUILTIN(KeyedStoreIC_Slow_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
106 Generate_KeyedStoreIC_Slow();
109 void HandlerBuiltinsAssembler::Generate_StoreInArrayLiteralIC_Slow() {
110 typedef StoreWithVectorDescriptor Descriptor;
111 Node* array = Parameter(Descriptor::kReceiver);
112 Node* index = Parameter(Descriptor::kName);
113 Node* value = Parameter(Descriptor::kValue);
114 Node* context = Parameter(Descriptor::kContext);
115 TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, context, value, array,
119 TF_BUILTIN(StoreInArrayLiteralIC_Slow, HandlerBuiltinsAssembler) {
120 Generate_StoreInArrayLiteralIC_Slow();
123 TF_BUILTIN(StoreInArrayLiteralIC_Slow_Standard, HandlerBuiltinsAssembler) {
124 Generate_StoreInArrayLiteralIC_Slow();
127 TF_BUILTIN(StoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW,
128 HandlerBuiltinsAssembler) {
129 Generate_StoreInArrayLiteralIC_Slow();
132 TF_BUILTIN(StoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB,
133 HandlerBuiltinsAssembler) {
134 Generate_StoreInArrayLiteralIC_Slow();
137 TF_BUILTIN(StoreInArrayLiteralIC_Slow_NoTransitionHandleCOW,
138 HandlerBuiltinsAssembler) {
139 Generate_StoreInArrayLiteralIC_Slow();
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) 158 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));
163 Label next(
this), if_unknown_type(
this, Label::kDeferred);
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 171 #define ELEMENTS_KINDS_CASE(FROM, TO) Label if_##FROM##_##TO(this); 172 ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
173 #undef ELEMENTS_KINDS_CASE 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 180 STATIC_ASSERT(arraysize(combined_elements_kinds) ==
181 arraysize(elements_kind_labels));
183 TNode<Word32T> combined_elements_kind =
184 Word32Or(Word32Shl(from_kind, Int32Constant(kBitsPerByte)), to_kind);
186 Switch(combined_elements_kind, &if_unknown_type, combined_elements_kinds,
187 elements_kind_labels, arraysize(combined_elements_kinds));
189 #define ELEMENTS_KINDS_CASE(FROM, TO) \ 190 BIND(&if_##FROM##_##TO); \ 192 case_function(FROM, TO); \ 195 ELEMENTS_KIND_TRANSITIONS(ELEMENTS_KINDS_CASE)
196 #undef ELEMENTS_KINDS_CASE 198 BIND(&if_unknown_type);
204 #undef ELEMENTS_KIND_TRANSITIONS 206 void HandlerBuiltinsAssembler::Generate_ElementsTransitionAndStore(
207 KeyedAccessStoreMode store_mode) {
208 typedef StoreTransitionDescriptor Descriptor;
209 Node* receiver = Parameter(Descriptor::kReceiver);
210 Node* key = Parameter(Descriptor::kName);
211 Node* value = Parameter(Descriptor::kValue);
212 Node* map = Parameter(Descriptor::kMap);
213 Node* slot = Parameter(Descriptor::kSlot);
214 Node* vector = Parameter(Descriptor::kVector);
215 Node* context = Parameter(Descriptor::kContext);
217 Comment(
"ElementsTransitionAndStore: store_mode=%d", store_mode);
221 if (FLAG_trace_elements_transitions) {
226 DispatchForElementsKindTransition(
227 LoadElementsKind(receiver), LoadMapElementsKind(map),
228 [=, &miss](ElementsKind from_kind, ElementsKind to_kind) {
229 TransitionElementsKind(receiver, map, from_kind, to_kind, &miss);
230 EmitElementStore(receiver, key, value, to_kind, store_mode, &miss,
237 TailCallRuntime(Runtime::kElementsTransitionAndStoreIC_Miss, context,
238 receiver, key, value, map, slot, vector);
241 TF_BUILTIN(ElementsTransitionAndStore_Standard, HandlerBuiltinsAssembler) {
242 Generate_ElementsTransitionAndStore(STANDARD_STORE);
245 TF_BUILTIN(ElementsTransitionAndStore_GrowNoTransitionHandleCOW,
246 HandlerBuiltinsAssembler) {
247 Generate_ElementsTransitionAndStore(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
250 TF_BUILTIN(ElementsTransitionAndStore_NoTransitionIgnoreOOB,
251 HandlerBuiltinsAssembler) {
252 Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
255 TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW,
256 HandlerBuiltinsAssembler) {
257 Generate_ElementsTransitionAndStore(STORE_NO_TRANSITION_HANDLE_COW);
262 #define ELEMENTS_KINDS(V) \ 263 V(PACKED_SMI_ELEMENTS) \ 264 V(HOLEY_SMI_ELEMENTS) \ 267 V(PACKED_DOUBLE_ELEMENTS) \ 268 V(HOLEY_DOUBLE_ELEMENTS) \ 275 V(FLOAT32_ELEMENTS) \ 276 V(FLOAT64_ELEMENTS) \ 277 V(UINT8_CLAMPED_ELEMENTS) \ 278 V(BIGUINT64_ELEMENTS) \ 281 void HandlerBuiltinsAssembler::DispatchByElementsKind(
282 TNode<Int32T> elements_kind,
const ElementsKindSwitchCase& case_function) {
283 Label next(
this), if_unknown_type(
this, Label::kDeferred);
285 int32_t elements_kinds[] = {
286 #define ELEMENTS_KINDS_CASE(KIND) KIND, 287 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
288 #undef ELEMENTS_KINDS_CASE 291 #define ELEMENTS_KINDS_CASE(KIND) Label if_##KIND(this); 292 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
293 #undef ELEMENTS_KINDS_CASE 295 Label* elements_kind_labels[] = {
296 #define ELEMENTS_KINDS_CASE(KIND) &if_##KIND, 297 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
298 #undef ELEMENTS_KINDS_CASE 300 STATIC_ASSERT(arraysize(elements_kinds) == arraysize(elements_kind_labels));
302 Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels,
303 arraysize(elements_kinds));
305 #define ELEMENTS_KINDS_CASE(KIND) \ 308 case_function(KIND); \ 311 ELEMENTS_KINDS(ELEMENTS_KINDS_CASE)
312 #undef ELEMENTS_KINDS_CASE 314 BIND(&if_unknown_type);
320 #undef ELEMENTS_KINDS 322 void HandlerBuiltinsAssembler::Generate_StoreFastElementIC(
323 KeyedAccessStoreMode store_mode) {
324 typedef StoreWithVectorDescriptor Descriptor;
325 Node* receiver = Parameter(Descriptor::kReceiver);
326 Node* key = Parameter(Descriptor::kName);
327 Node* value = Parameter(Descriptor::kValue);
328 Node* slot = Parameter(Descriptor::kSlot);
329 Node* vector = Parameter(Descriptor::kVector);
330 Node* context = Parameter(Descriptor::kContext);
332 Comment(
"StoreFastElementStub: store_mode=%d", store_mode);
337 DispatchByElementsKind(LoadElementsKind(receiver),
338 [=, &miss](ElementsKind elements_kind) {
339 EmitElementStore(receiver, key, value, elements_kind,
340 store_mode, &miss, context);
345 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
349 TF_BUILTIN(StoreFastElementIC_Standard, HandlerBuiltinsAssembler) {
350 Generate_StoreFastElementIC(STANDARD_STORE);
353 TF_BUILTIN(StoreFastElementIC_GrowNoTransitionHandleCOW,
354 HandlerBuiltinsAssembler) {
355 Generate_StoreFastElementIC(STORE_AND_GROW_NO_TRANSITION_HANDLE_COW);
358 TF_BUILTIN(StoreFastElementIC_NoTransitionIgnoreOOB, HandlerBuiltinsAssembler) {
359 Generate_StoreFastElementIC(STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS);
362 TF_BUILTIN(StoreFastElementIC_NoTransitionHandleCOW, HandlerBuiltinsAssembler) {
363 Generate_StoreFastElementIC(STORE_NO_TRANSITION_HANDLE_COW);
366 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);
372 TailCallRuntime(Runtime::kLoadGlobalIC_Slow, context, name, slot, vector);
375 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);
382 Label miss(
this, Label::kDeferred);
383 Return(LoadJSFunctionPrototype(receiver, &miss));
386 TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, slot, vector);
389 TF_BUILTIN(LoadIC_Slow, CodeStubAssembler) {
390 Node* receiver = Parameter(Descriptor::kReceiver);
391 Node* name = Parameter(Descriptor::kName);
392 Node* context = Parameter(Descriptor::kContext);
394 TailCallRuntime(Runtime::kGetProperty, context, receiver, name);
397 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);
407 TailCallRuntime(Runtime::kStoreGlobalIC_Slow, context, value, slot, vector,
411 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);
420 Node* result = LoadKeyedSloppyArguments(receiver, key, &miss);
426 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,
431 void HandlerBuiltinsAssembler::Generate_KeyedStoreIC_SloppyArguments() {
432 typedef StoreWithVectorDescriptor Descriptor;
433 Node* receiver = Parameter(Descriptor::kReceiver);
434 Node* key = Parameter(Descriptor::kName);
435 Node* value = Parameter(Descriptor::kValue);
436 Node* slot = Parameter(Descriptor::kSlot);
437 Node* vector = Parameter(Descriptor::kVector);
438 Node* context = Parameter(Descriptor::kContext);
442 StoreKeyedSloppyArguments(receiver, key, value, &miss);
446 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector,
450 TF_BUILTIN(KeyedStoreIC_SloppyArguments_Standard, HandlerBuiltinsAssembler) {
451 Generate_KeyedStoreIC_SloppyArguments();
454 TF_BUILTIN(KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW,
455 HandlerBuiltinsAssembler) {
456 Generate_KeyedStoreIC_SloppyArguments();
459 TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB,
460 HandlerBuiltinsAssembler) {
461 Generate_KeyedStoreIC_SloppyArguments();
464 TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW,
465 HandlerBuiltinsAssembler) {
466 Generate_KeyedStoreIC_SloppyArguments();
469 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 vector, receiver, name);
480 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);
487 Label if_keyispositivesmi(
this), if_keyisinvalid(
this);
488 Branch(TaggedIsPositiveSmi(key), &if_keyispositivesmi, &if_keyisinvalid);
489 BIND(&if_keyispositivesmi);
490 TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, receiver, key);
492 BIND(&if_keyisinvalid);
493 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, slot,