OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/api-natives.h" | 9 #include "src/api-natives.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 switch (tail_call_mode) { | 332 switch (tail_call_mode) { |
333 case TailCallMode::kDisallow: | 333 case TailCallMode::kDisallow: |
334 return CallBoundFunction(); | 334 return CallBoundFunction(); |
335 case TailCallMode::kAllow: | 335 case TailCallMode::kAllow: |
336 return TailCallBoundFunction(); | 336 return TailCallBoundFunction(); |
337 } | 337 } |
338 UNREACHABLE(); | 338 UNREACHABLE(); |
339 return Handle<Code>::null(); | 339 return Handle<Code>::null(); |
340 } | 340 } |
341 | 341 |
342 Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { | |
343 switch (hint) { | |
344 case ToPrimitiveHint::kDefault: | |
345 return NonPrimitiveToPrimitive_Default(); | |
346 case ToPrimitiveHint::kNumber: | |
347 return NonPrimitiveToPrimitive_Number(); | |
348 case ToPrimitiveHint::kString: | |
349 return NonPrimitiveToPrimitive_String(); | |
350 } | |
351 UNREACHABLE(); | |
352 return Handle<Code>::null(); | |
353 } | |
354 | |
355 Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { | |
356 switch (hint) { | |
357 case OrdinaryToPrimitiveHint::kNumber: | |
358 return OrdinaryToPrimitive_Number(); | |
359 case OrdinaryToPrimitiveHint::kString: | |
360 return OrdinaryToPrimitive_String(); | |
361 } | |
362 UNREACHABLE(); | |
363 return Handle<Code>::null(); | |
364 } | |
365 | |
366 Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode, | |
367 CallableType function_type) { | |
368 switch (tail_call_mode) { | |
369 case TailCallMode::kDisallow: | |
370 if (function_type == CallableType::kJSFunction) { | |
371 return InterpreterPushArgsAndCallFunction(); | |
372 } else { | |
373 return InterpreterPushArgsAndCall(); | |
374 } | |
375 case TailCallMode::kAllow: | |
376 if (function_type == CallableType::kJSFunction) { | |
377 return InterpreterPushArgsAndTailCallFunction(); | |
378 } else { | |
379 return InterpreterPushArgsAndTailCall(); | |
380 } | |
381 } | |
382 UNREACHABLE(); | |
383 return Handle<Code>::null(); | |
384 } | |
385 | |
386 namespace { | 342 namespace { |
387 | 343 |
388 class RelocatableArguments : public BuiltinArguments, public Relocatable { | 344 class RelocatableArguments : public BuiltinArguments, public Relocatable { |
389 public: | 345 public: |
390 RelocatableArguments(Isolate* isolate, int length, Object** arguments) | 346 RelocatableArguments(Isolate* isolate, int length, Object** arguments) |
391 : BuiltinArguments(length, arguments), Relocatable(isolate) {} | 347 : BuiltinArguments(length, arguments), Relocatable(isolate) {} |
392 | 348 |
393 virtual inline void IterateInstance(ObjectVisitor* v) { | 349 virtual inline void IterateInstance(ObjectVisitor* v) { |
394 if (length() == 0) return; | 350 if (length() == 0) return; |
395 v->VisitPointers(lowest_address(), highest_address() + 1); | 351 v->VisitPointers(lowest_address(), highest_address() + 1); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 BUILTIN(HandleApiCallAsFunction) { | 476 BUILTIN(HandleApiCallAsFunction) { |
521 return HandleApiCallAsFunctionOrConstructor(isolate, false, args); | 477 return HandleApiCallAsFunctionOrConstructor(isolate, false, args); |
522 } | 478 } |
523 | 479 |
524 // Handle calls to non-function objects created through the API. This delegate | 480 // Handle calls to non-function objects created through the API. This delegate |
525 // function is used when the call is a construct call. | 481 // function is used when the call is a construct call. |
526 BUILTIN(HandleApiCallAsConstructor) { | 482 BUILTIN(HandleApiCallAsConstructor) { |
527 return HandleApiCallAsFunctionOrConstructor(isolate, true, args); | 483 return HandleApiCallAsFunctionOrConstructor(isolate, true, args); |
528 } | 484 } |
529 | 485 |
530 void Builtins::Generate_LoadIC_Miss(CodeStubAssembler* assembler) { | |
531 typedef compiler::Node Node; | |
532 | |
533 Node* receiver = assembler->Parameter(0); | |
534 Node* name = assembler->Parameter(1); | |
535 Node* slot = assembler->Parameter(2); | |
536 Node* vector = assembler->Parameter(3); | |
537 Node* context = assembler->Parameter(4); | |
538 | |
539 assembler->TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, | |
540 slot, vector); | |
541 } | |
542 | |
543 void Builtins::Generate_LoadGlobalIC_Miss(CodeStubAssembler* assembler) { | |
544 typedef compiler::Node Node; | |
545 | |
546 Node* slot = assembler->Parameter(0); | |
547 Node* vector = assembler->Parameter(1); | |
548 Node* context = assembler->Parameter(2); | |
549 | |
550 assembler->TailCallRuntime(Runtime::kLoadGlobalIC_Miss, context, slot, | |
551 vector); | |
552 } | |
553 | |
554 void Builtins::Generate_LoadIC_Normal(MacroAssembler* masm) { | |
555 LoadIC::GenerateNormal(masm); | |
556 } | |
557 | |
558 void Builtins::Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) { | |
559 NamedLoadHandlerCompiler::GenerateLoadViaGetterForDeopt(masm); | |
560 } | |
561 | |
562 void Builtins::Generate_LoadIC_Slow(CodeStubAssembler* assembler) { | |
563 typedef compiler::Node Node; | |
564 | |
565 Node* receiver = assembler->Parameter(0); | |
566 Node* name = assembler->Parameter(1); | |
567 // Node* slot = assembler->Parameter(2); | |
568 // Node* vector = assembler->Parameter(3); | |
569 Node* context = assembler->Parameter(4); | |
570 | |
571 assembler->TailCallRuntime(Runtime::kGetProperty, context, receiver, name); | |
572 } | |
573 | |
574 namespace { | |
575 void Generate_LoadGlobalIC_Slow(CodeStubAssembler* assembler, TypeofMode mode) { | |
576 typedef compiler::Node Node; | |
577 | |
578 Node* slot = assembler->Parameter(0); | |
579 Node* vector = assembler->Parameter(1); | |
580 Node* context = assembler->Parameter(2); | |
581 Node* typeof_mode = assembler->SmiConstant(Smi::FromInt(mode)); | |
582 | |
583 assembler->TailCallRuntime(Runtime::kGetGlobal, context, slot, vector, | |
584 typeof_mode); | |
585 } | |
586 } // anonymous namespace | |
587 | |
588 void Builtins::Generate_LoadGlobalIC_SlowInsideTypeof( | |
589 CodeStubAssembler* assembler) { | |
590 Generate_LoadGlobalIC_Slow(assembler, INSIDE_TYPEOF); | |
591 } | |
592 | |
593 void Builtins::Generate_LoadGlobalIC_SlowNotInsideTypeof( | |
594 CodeStubAssembler* assembler) { | |
595 Generate_LoadGlobalIC_Slow(assembler, NOT_INSIDE_TYPEOF); | |
596 } | |
597 | |
598 void Builtins::Generate_KeyedLoadIC_Slow(MacroAssembler* masm) { | |
599 KeyedLoadIC::GenerateRuntimeGetProperty(masm); | |
600 } | |
601 | |
602 void Builtins::Generate_KeyedLoadIC_Miss(MacroAssembler* masm) { | |
603 KeyedLoadIC::GenerateMiss(masm); | |
604 } | |
605 | |
606 void Builtins::Generate_KeyedLoadIC_Megamorphic(MacroAssembler* masm) { | |
607 KeyedLoadIC::GenerateMegamorphic(masm); | |
608 } | |
609 | |
610 void Builtins::Generate_StoreIC_Miss(CodeStubAssembler* assembler) { | |
611 typedef compiler::Node Node; | |
612 | |
613 Node* receiver = assembler->Parameter(0); | |
614 Node* name = assembler->Parameter(1); | |
615 Node* value = assembler->Parameter(2); | |
616 Node* slot = assembler->Parameter(3); | |
617 Node* vector = assembler->Parameter(4); | |
618 Node* context = assembler->Parameter(5); | |
619 | |
620 assembler->TailCallRuntime(Runtime::kStoreIC_Miss, context, receiver, name, | |
621 value, slot, vector); | |
622 } | |
623 | |
624 void Builtins::Generate_StoreIC_Normal(MacroAssembler* masm) { | |
625 StoreIC::GenerateNormal(masm); | |
626 } | |
627 | |
628 namespace { | |
629 void Generate_StoreIC_Slow(CodeStubAssembler* assembler, | |
630 LanguageMode language_mode) { | |
631 typedef compiler::Node Node; | |
632 | |
633 Node* receiver = assembler->Parameter(0); | |
634 Node* name = assembler->Parameter(1); | |
635 Node* value = assembler->Parameter(2); | |
636 // Node* slot = assembler->Parameter(3); | |
637 // Node* vector = assembler->Parameter(4); | |
638 Node* context = assembler->Parameter(5); | |
639 Node* lang_mode = assembler->SmiConstant(Smi::FromInt(language_mode)); | |
640 | |
641 // The slow case calls into the runtime to complete the store without causing | |
642 // an IC miss that would otherwise cause a transition to the generic stub. | |
643 assembler->TailCallRuntime(Runtime::kSetProperty, context, receiver, name, | |
644 value, lang_mode); | |
645 } | |
646 } // anonymous namespace | |
647 | |
648 void Builtins::Generate_StoreIC_SlowSloppy(CodeStubAssembler* assembler) { | |
649 Generate_StoreIC_Slow(assembler, SLOPPY); | |
650 } | |
651 | |
652 void Builtins::Generate_StoreIC_SlowStrict(CodeStubAssembler* assembler) { | |
653 Generate_StoreIC_Slow(assembler, STRICT); | |
654 } | |
655 | |
656 namespace { | |
657 // 7.1.1.1 OrdinaryToPrimitive ( O, hint ) | |
658 void Generate_OrdinaryToPrimitive(CodeStubAssembler* assembler, | |
659 OrdinaryToPrimitiveHint hint) { | |
660 typedef CodeStubAssembler::Label Label; | |
661 typedef compiler::Node Node; | |
662 typedef CodeStubAssembler::Variable Variable; | |
663 | |
664 Node* input = assembler->Parameter(0); | |
665 Node* context = assembler->Parameter(1); | |
666 | |
667 Variable var_result(assembler, MachineRepresentation::kTagged); | |
668 Label return_result(assembler, &var_result); | |
669 | |
670 Handle<String> method_names[2]; | |
671 switch (hint) { | |
672 case OrdinaryToPrimitiveHint::kNumber: | |
673 method_names[0] = assembler->factory()->valueOf_string(); | |
674 method_names[1] = assembler->factory()->toString_string(); | |
675 break; | |
676 case OrdinaryToPrimitiveHint::kString: | |
677 method_names[0] = assembler->factory()->toString_string(); | |
678 method_names[1] = assembler->factory()->valueOf_string(); | |
679 break; | |
680 } | |
681 for (Handle<String> name : method_names) { | |
682 // Lookup the {name} on the {input}. | |
683 Callable callable = CodeFactory::GetProperty(assembler->isolate()); | |
684 Node* name_string = assembler->HeapConstant(name); | |
685 Node* method = assembler->CallStub(callable, context, input, name_string); | |
686 | |
687 // Check if the {method} is callable. | |
688 Label if_methodiscallable(assembler), | |
689 if_methodisnotcallable(assembler, Label::kDeferred); | |
690 assembler->GotoIf(assembler->WordIsSmi(method), &if_methodisnotcallable); | |
691 Node* method_map = assembler->LoadMap(method); | |
692 Node* method_bit_field = assembler->LoadMapBitField(method_map); | |
693 assembler->Branch( | |
694 assembler->Word32Equal( | |
695 assembler->Word32And(method_bit_field, assembler->Int32Constant( | |
696 1 << Map::kIsCallable)), | |
697 assembler->Int32Constant(0)), | |
698 &if_methodisnotcallable, &if_methodiscallable); | |
699 | |
700 assembler->Bind(&if_methodiscallable); | |
701 { | |
702 // Call the {method} on the {input}. | |
703 Callable callable = CodeFactory::Call(assembler->isolate()); | |
704 Node* result = assembler->CallJS(callable, context, method, input); | |
705 var_result.Bind(result); | |
706 | |
707 // Return the {result} if it is a primitive. | |
708 assembler->GotoIf(assembler->WordIsSmi(result), &return_result); | |
709 Node* result_instance_type = assembler->LoadInstanceType(result); | |
710 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); | |
711 assembler->GotoIf(assembler->Int32LessThanOrEqual( | |
712 result_instance_type, | |
713 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), | |
714 &return_result); | |
715 } | |
716 | |
717 // Just continue with the next {name} if the {method} is not callable. | |
718 assembler->Goto(&if_methodisnotcallable); | |
719 assembler->Bind(&if_methodisnotcallable); | |
720 } | |
721 | |
722 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); | |
723 | |
724 assembler->Bind(&return_result); | |
725 assembler->Return(var_result.value()); | |
726 } | |
727 } // anonymous namespace | |
728 | |
729 void Builtins::Generate_OrdinaryToPrimitive_Number( | |
730 CodeStubAssembler* assembler) { | |
731 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kNumber); | |
732 } | |
733 | |
734 void Builtins::Generate_OrdinaryToPrimitive_String( | |
735 CodeStubAssembler* assembler) { | |
736 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kString); | |
737 } | |
738 | |
739 namespace { | |
740 // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] ) | |
741 void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler, | |
742 ToPrimitiveHint hint) { | |
743 typedef CodeStubAssembler::Label Label; | |
744 typedef compiler::Node Node; | |
745 | |
746 Node* input = assembler->Parameter(0); | |
747 Node* context = assembler->Parameter(1); | |
748 | |
749 // Lookup the @@toPrimitive property on the {input}. | |
750 Callable callable = CodeFactory::GetProperty(assembler->isolate()); | |
751 Node* to_primitive_symbol = | |
752 assembler->HeapConstant(assembler->factory()->to_primitive_symbol()); | |
753 Node* exotic_to_prim = | |
754 assembler->CallStub(callable, context, input, to_primitive_symbol); | |
755 | |
756 // Check if {exotic_to_prim} is neither null nor undefined. | |
757 Label ordinary_to_primitive(assembler); | |
758 assembler->GotoIf( | |
759 assembler->WordEqual(exotic_to_prim, assembler->NullConstant()), | |
760 &ordinary_to_primitive); | |
761 assembler->GotoIf( | |
762 assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()), | |
763 &ordinary_to_primitive); | |
764 { | |
765 // Invoke the {exotic_to_prim} method on the {input} with a string | |
766 // representation of the {hint}. | |
767 Callable callable = CodeFactory::Call(assembler->isolate()); | |
768 Node* hint_string = assembler->HeapConstant( | |
769 assembler->factory()->ToPrimitiveHintString(hint)); | |
770 Node* result = assembler->CallJS(callable, context, exotic_to_prim, input, | |
771 hint_string); | |
772 | |
773 // Verify that the {result} is actually a primitive. | |
774 Label if_resultisprimitive(assembler), | |
775 if_resultisnotprimitive(assembler, Label::kDeferred); | |
776 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisprimitive); | |
777 Node* result_instance_type = assembler->LoadInstanceType(result); | |
778 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); | |
779 assembler->Branch(assembler->Int32LessThanOrEqual( | |
780 result_instance_type, | |
781 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), | |
782 &if_resultisprimitive, &if_resultisnotprimitive); | |
783 | |
784 assembler->Bind(&if_resultisprimitive); | |
785 { | |
786 // Just return the {result}. | |
787 assembler->Return(result); | |
788 } | |
789 | |
790 assembler->Bind(&if_resultisnotprimitive); | |
791 { | |
792 // Somehow the @@toPrimitive method on {input} didn't yield a primitive. | |
793 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, | |
794 context); | |
795 } | |
796 } | |
797 | |
798 // Convert using the OrdinaryToPrimitive algorithm instead. | |
799 assembler->Bind(&ordinary_to_primitive); | |
800 { | |
801 Callable callable = CodeFactory::OrdinaryToPrimitive( | |
802 assembler->isolate(), (hint == ToPrimitiveHint::kString) | |
803 ? OrdinaryToPrimitiveHint::kString | |
804 : OrdinaryToPrimitiveHint::kNumber); | |
805 assembler->TailCallStub(callable, context, input); | |
806 } | |
807 } | |
808 } // anonymous namespace | |
809 | |
810 void Builtins::Generate_NonPrimitiveToPrimitive_Default( | |
811 CodeStubAssembler* assembler) { | |
812 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kDefault); | |
813 } | |
814 | |
815 void Builtins::Generate_NonPrimitiveToPrimitive_Number( | |
816 CodeStubAssembler* assembler) { | |
817 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kNumber); | |
818 } | |
819 | |
820 void Builtins::Generate_NonPrimitiveToPrimitive_String( | |
821 CodeStubAssembler* assembler) { | |
822 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kString); | |
823 } | |
824 | |
825 // ES6 section 7.1.3 ToNumber ( argument ) | |
826 void Builtins::Generate_NonNumberToNumber(CodeStubAssembler* assembler) { | |
827 typedef CodeStubAssembler::Label Label; | |
828 typedef compiler::Node Node; | |
829 typedef CodeStubAssembler::Variable Variable; | |
830 | |
831 Node* input = assembler->Parameter(0); | |
832 Node* context = assembler->Parameter(1); | |
833 | |
834 // We might need to loop once here due to ToPrimitive conversions. | |
835 Variable var_input(assembler, MachineRepresentation::kTagged); | |
836 Label loop(assembler, &var_input); | |
837 var_input.Bind(input); | |
838 assembler->Goto(&loop); | |
839 assembler->Bind(&loop); | |
840 { | |
841 // Load the current {input} value (known to be a HeapObject). | |
842 Node* input = var_input.value(); | |
843 | |
844 // Dispatch on the {input} instance type. | |
845 Node* input_instance_type = assembler->LoadInstanceType(input); | |
846 Label if_inputisstring(assembler), if_inputisoddball(assembler), | |
847 if_inputisreceiver(assembler, Label::kDeferred), | |
848 if_inputisother(assembler, Label::kDeferred); | |
849 assembler->GotoIf(assembler->Int32LessThan( | |
850 input_instance_type, | |
851 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | |
852 &if_inputisstring); | |
853 assembler->GotoIf( | |
854 assembler->Word32Equal(input_instance_type, | |
855 assembler->Int32Constant(ODDBALL_TYPE)), | |
856 &if_inputisoddball); | |
857 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
858 assembler->Branch(assembler->Int32GreaterThanOrEqual( | |
859 input_instance_type, | |
860 assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), | |
861 &if_inputisreceiver, &if_inputisother); | |
862 | |
863 assembler->Bind(&if_inputisstring); | |
864 { | |
865 // The {input} is a String, use the fast stub to convert it to a Number. | |
866 // TODO(bmeurer): Consider inlining the StringToNumber logic here. | |
867 Callable callable = CodeFactory::StringToNumber(assembler->isolate()); | |
868 assembler->TailCallStub(callable, context, input); | |
869 } | |
870 | |
871 assembler->Bind(&if_inputisoddball); | |
872 { | |
873 // The {input} is an Oddball, we just need to the Number value of it. | |
874 Node* result = | |
875 assembler->LoadObjectField(input, Oddball::kToNumberOffset); | |
876 assembler->Return(result); | |
877 } | |
878 | |
879 assembler->Bind(&if_inputisreceiver); | |
880 { | |
881 // The {input} is a JSReceiver, we need to convert it to a Primitive first | |
882 // using the ToPrimitive type conversion, preferably yielding a Number. | |
883 Callable callable = CodeFactory::NonPrimitiveToPrimitive( | |
884 assembler->isolate(), ToPrimitiveHint::kNumber); | |
885 Node* result = assembler->CallStub(callable, context, input); | |
886 | |
887 // Check if the {result} is already a Number. | |
888 Label if_resultisnumber(assembler), if_resultisnotnumber(assembler); | |
889 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisnumber); | |
890 Node* result_map = assembler->LoadMap(result); | |
891 assembler->Branch( | |
892 assembler->WordEqual(result_map, assembler->HeapNumberMapConstant()), | |
893 &if_resultisnumber, &if_resultisnotnumber); | |
894 | |
895 assembler->Bind(&if_resultisnumber); | |
896 { | |
897 // The ToPrimitive conversion already gave us a Number, so we're done. | |
898 assembler->Return(result); | |
899 } | |
900 | |
901 assembler->Bind(&if_resultisnotnumber); | |
902 { | |
903 // We now have a Primitive {result}, but it's not yet a Number. | |
904 var_input.Bind(result); | |
905 assembler->Goto(&loop); | |
906 } | |
907 } | |
908 | |
909 assembler->Bind(&if_inputisother); | |
910 { | |
911 // The {input} is something else (i.e. Symbol or Simd128Value), let the | |
912 // runtime figure out the correct exception. | |
913 // Note: We cannot tail call to the runtime here, as js-to-wasm | |
914 // trampolines also use this code currently, and they declare all | |
915 // outgoing parameters as untagged, while we would push a tagged | |
916 // object here. | |
917 Node* result = assembler->CallRuntime(Runtime::kToNumber, context, input); | |
918 assembler->Return(result); | |
919 } | |
920 } | |
921 } | |
922 | |
923 // ES6 section 7.1.2 ToBoolean ( argument ) | |
924 void Builtins::Generate_ToBoolean(CodeStubAssembler* assembler) { | |
925 typedef compiler::Node Node; | |
926 typedef CodeStubAssembler::Label Label; | |
927 | |
928 Node* value = assembler->Parameter(0); | |
929 | |
930 Label return_true(assembler), return_false(assembler); | |
931 assembler->BranchIfToBooleanIsTrue(value, &return_true, &return_false); | |
932 | |
933 assembler->Bind(&return_true); | |
934 assembler->Return(assembler->BooleanConstant(true)); | |
935 | |
936 assembler->Bind(&return_false); | |
937 assembler->Return(assembler->BooleanConstant(false)); | |
938 } | |
939 | |
940 void Builtins::Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { | |
941 ElementHandlerCompiler::GenerateStoreSlow(masm); | |
942 } | |
943 | |
944 void Builtins::Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { | |
945 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); | |
946 } | |
947 | |
948 void Builtins::Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { | |
949 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); | |
950 } | |
951 | |
952 void Builtins::Generate_KeyedStoreIC_Megamorphic_Strict(MacroAssembler* masm) { | |
953 KeyedStoreIC::GenerateMegamorphic(masm, STRICT); | |
954 } | |
955 | |
956 void Builtins::Generate_KeyedStoreIC_Miss(MacroAssembler* masm) { | |
957 KeyedStoreIC::GenerateMiss(masm); | |
958 } | |
959 | |
960 void Builtins::Generate_Return_DebugBreak(MacroAssembler* masm) { | |
961 DebugCodegen::GenerateDebugBreakStub(masm, | |
962 DebugCodegen::SAVE_RESULT_REGISTER); | |
963 } | |
964 | |
965 void Builtins::Generate_Slot_DebugBreak(MacroAssembler* masm) { | |
966 DebugCodegen::GenerateDebugBreakStub(masm, | |
967 DebugCodegen::IGNORE_RESULT_REGISTER); | |
968 } | |
969 | |
970 void Builtins::Generate_FrameDropper_LiveEdit(MacroAssembler* masm) { | |
971 DebugCodegen::GenerateFrameDropperLiveEdit(masm); | |
972 } | |
973 | |
974 Builtins::Builtins() : initialized_(false) { | 486 Builtins::Builtins() : initialized_(false) { |
975 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); | 487 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); |
976 } | 488 } |
977 | 489 |
978 Builtins::~Builtins() {} | 490 Builtins::~Builtins() {} |
979 | 491 |
980 namespace { | 492 namespace { |
981 void PostBuildProfileAndTracing(Isolate* isolate, Code* code, | 493 void PostBuildProfileAndTracing(Isolate* isolate, Code* code, |
982 const char* name) { | 494 const char* name) { |
983 PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG, | 495 PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG, |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 void Builtins::Generate_TailCall_ReceiverIsNotNullOrUndefined( | 735 void Builtins::Generate_TailCall_ReceiverIsNotNullOrUndefined( |
1224 MacroAssembler* masm) { | 736 MacroAssembler* masm) { |
1225 Generate_Call(masm, ConvertReceiverMode::kNotNullOrUndefined, | 737 Generate_Call(masm, ConvertReceiverMode::kNotNullOrUndefined, |
1226 TailCallMode::kAllow); | 738 TailCallMode::kAllow); |
1227 } | 739 } |
1228 | 740 |
1229 void Builtins::Generate_TailCall_ReceiverIsAny(MacroAssembler* masm) { | 741 void Builtins::Generate_TailCall_ReceiverIsAny(MacroAssembler* masm) { |
1230 Generate_Call(masm, ConvertReceiverMode::kAny, TailCallMode::kAllow); | 742 Generate_Call(masm, ConvertReceiverMode::kAny, TailCallMode::kAllow); |
1231 } | 743 } |
1232 | 744 |
1233 void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { | |
1234 return Generate_InterpreterPushArgsAndCallImpl(masm, TailCallMode::kDisallow, | |
1235 CallableType::kAny); | |
1236 } | |
1237 void Builtins::Generate_InterpreterPushArgsAndTailCall(MacroAssembler* masm) { | |
1238 return Generate_InterpreterPushArgsAndCallImpl(masm, TailCallMode::kAllow, | |
1239 CallableType::kAny); | |
1240 } | |
1241 | |
1242 void Builtins::Generate_InterpreterPushArgsAndCallFunction( | |
1243 MacroAssembler* masm) { | |
1244 return Generate_InterpreterPushArgsAndCallImpl(masm, TailCallMode::kDisallow, | |
1245 CallableType::kJSFunction); | |
1246 } | |
1247 | |
1248 void Builtins::Generate_InterpreterPushArgsAndTailCallFunction( | |
1249 MacroAssembler* masm) { | |
1250 return Generate_InterpreterPushArgsAndCallImpl(masm, TailCallMode::kAllow, | |
1251 CallableType::kJSFunction); | |
1252 } | |
1253 | 745 |
1254 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ | 746 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ |
1255 Handle<Code> Builtins::Name() { \ | 747 Handle<Code> Builtins::Name() { \ |
1256 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ | 748 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ |
1257 return Handle<Code>(code_address); \ | 749 return Handle<Code>(code_address); \ |
1258 } | 750 } |
1259 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) | 751 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) |
1260 #undef DEFINE_BUILTIN_ACCESSOR | 752 #undef DEFINE_BUILTIN_ACCESSOR |
1261 | 753 |
1262 } // namespace internal | 754 } // namespace internal |
1263 } // namespace v8 | 755 } // namespace v8 |
OLD | NEW |