Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 3709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3720 static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) { | 3720 static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) { |
| 3721 // Cache the called function in a global property cell. Cache states | 3721 // Cache the called function in a global property cell. Cache states |
| 3722 // are uninitialized, monomorphic (indicated by a JSFunction), and | 3722 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 3723 // megamorphic. | 3723 // megamorphic. |
| 3724 // rbx : cache cell for call target | 3724 // rbx : cache cell for call target |
| 3725 // rdi : the function to call | 3725 // rdi : the function to call |
| 3726 Isolate* isolate = masm->isolate(); | 3726 Isolate* isolate = masm->isolate(); |
| 3727 Label initialize, done; | 3727 Label initialize, done; |
| 3728 | 3728 |
| 3729 // Load the cache state into rcx. | 3729 // Load the cache state into rcx. |
| 3730 __ movq(rcx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 3730 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); |
| 3731 | 3731 |
| 3732 // A monomorphic cache hit or an already megamorphic state: invoke the | 3732 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 3733 // function without changing the state. | 3733 // function without changing the state. |
| 3734 __ cmpq(rcx, rdi); | 3734 __ cmpq(rcx, rdi); |
| 3735 __ j(equal, &done, Label::kNear); | 3735 __ j(equal, &done, Label::kNear); |
| 3736 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); | 3736 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); |
| 3737 __ j(equal, &done, Label::kNear); | 3737 __ j(equal, &done, Label::kNear); |
| 3738 | 3738 |
| 3739 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 3739 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
| 3740 // megamorphic. | 3740 // megamorphic. |
| 3741 __ Cmp(rcx, TypeFeedbackCells::UninitializedSentinel(isolate)); | 3741 __ Cmp(rcx, TypeFeedbackCells::UninitializedSentinel(isolate)); |
| 3742 __ j(equal, &initialize, Label::kNear); | 3742 __ j(equal, &initialize, Label::kNear); |
| 3743 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 3743 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
| 3744 // write-barrier is needed. | 3744 // write-barrier is needed. |
| 3745 __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 3745 __ Move(FieldOperand(rbx, Cell::kValueOffset), |
| 3746 TypeFeedbackCells::MegamorphicSentinel(isolate)); | 3746 TypeFeedbackCells::MegamorphicSentinel(isolate)); |
| 3747 __ jmp(&done, Label::kNear); | 3747 __ jmp(&done, Label::kNear); |
| 3748 | 3748 |
| 3749 // An uninitialized cache is patched with the function. | 3749 // An uninitialized cache is patched with the function. |
| 3750 __ bind(&initialize); | 3750 __ bind(&initialize); |
| 3751 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rdi); | 3751 __ movq(FieldOperand(rbx, Cell::kValueOffset), rdi); |
| 3752 // No need for a write barrier here - cells are rescanned. | 3752 // No need for a write barrier here - cells are rescanned. |
| 3753 | 3753 |
| 3754 __ bind(&done); | 3754 __ bind(&done); |
| 3755 } | 3755 } |
| 3756 | 3756 |
| 3757 | 3757 |
| 3758 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 3758 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 3759 // Cache the called function in a global property cell. Cache states | 3759 // Cache the called function in a global property cell. Cache states |
| 3760 // are uninitialized, monomorphic (indicated by a JSFunction), and | 3760 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 3761 // megamorphic. | 3761 // megamorphic. |
| 3762 // rbx : cache cell for call target | 3762 // rbx : cache cell for call target |
| 3763 // rdi : the function to call | 3763 // rdi : the function to call |
| 3764 ASSERT(FLAG_optimize_constructed_arrays); | 3764 ASSERT(FLAG_optimize_constructed_arrays); |
| 3765 Isolate* isolate = masm->isolate(); | 3765 Isolate* isolate = masm->isolate(); |
| 3766 Label initialize, done, miss, megamorphic, not_array_function; | 3766 Label initialize, done, miss, megamorphic, not_array_function; |
| 3767 | 3767 |
| 3768 // Load the cache state into rcx. | 3768 // Load the cache state into rcx. |
| 3769 __ movq(rcx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 3769 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); |
| 3770 | 3770 |
| 3771 // A monomorphic cache hit or an already megamorphic state: invoke the | 3771 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 3772 // function without changing the state. | 3772 // function without changing the state. |
| 3773 __ cmpq(rcx, rdi); | 3773 __ cmpq(rcx, rdi); |
| 3774 __ j(equal, &done); | 3774 __ j(equal, &done); |
| 3775 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); | 3775 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); |
| 3776 __ j(equal, &done); | 3776 __ j(equal, &done); |
| 3777 | 3777 |
| 3778 // Special handling of the Array() function, which caches not only the | 3778 // Special handling of the Array() function, which caches not only the |
| 3779 // monomorphic Array function but the initial ElementsKind with special | 3779 // monomorphic Array function but the initial ElementsKind with special |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 3792 | 3792 |
| 3793 __ bind(&miss); | 3793 __ bind(&miss); |
| 3794 | 3794 |
| 3795 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 3795 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
| 3796 // megamorphic. | 3796 // megamorphic. |
| 3797 __ Cmp(rcx, TypeFeedbackCells::UninitializedSentinel(isolate)); | 3797 __ Cmp(rcx, TypeFeedbackCells::UninitializedSentinel(isolate)); |
| 3798 __ j(equal, &initialize); | 3798 __ j(equal, &initialize); |
| 3799 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 3799 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
| 3800 // write-barrier is needed. | 3800 // write-barrier is needed. |
| 3801 __ bind(&megamorphic); | 3801 __ bind(&megamorphic); |
| 3802 __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 3802 __ Move(FieldOperand(rbx, Cell::kValueOffset), |
| 3803 TypeFeedbackCells::MegamorphicSentinel(isolate)); | 3803 TypeFeedbackCells::MegamorphicSentinel(isolate)); |
| 3804 __ jmp(&done, Label::kNear); | 3804 __ jmp(&done, Label::kNear); |
| 3805 | 3805 |
| 3806 // An uninitialized cache is patched with the function or sentinel to | 3806 // An uninitialized cache is patched with the function or sentinel to |
| 3807 // indicate the ElementsKind if function is the Array constructor. | 3807 // indicate the ElementsKind if function is the Array constructor. |
| 3808 __ bind(&initialize); | 3808 __ bind(&initialize); |
| 3809 // Make sure the function is the Array() function | 3809 // Make sure the function is the Array() function |
| 3810 __ LoadArrayFunction(rcx); | 3810 __ LoadArrayFunction(rcx); |
| 3811 __ cmpq(rdi, rcx); | 3811 __ cmpq(rdi, rcx); |
| 3812 __ j(not_equal, ¬_array_function); | 3812 __ j(not_equal, ¬_array_function); |
| 3813 | 3813 |
| 3814 // The target function is the Array constructor, install a sentinel value in | 3814 // The target function is the Array constructor, install a sentinel value in |
| 3815 // the constructor's type info cell that will track the initial ElementsKind | 3815 // the constructor's type info cell that will track the initial ElementsKind |
| 3816 // that should be used for the array when its constructed. | 3816 // that should be used for the array when its constructed. |
| 3817 Handle<Object> initial_kind_sentinel = | 3817 Handle<Object> initial_kind_sentinel = |
| 3818 TypeFeedbackCells::MonomorphicArraySentinel(isolate, | 3818 TypeFeedbackCells::MonomorphicArraySentinel(isolate, |
| 3819 GetInitialFastElementsKind()); | 3819 GetInitialFastElementsKind()); |
| 3820 __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 3820 __ Move(FieldOperand(rbx, Cell::kValueOffset), |
| 3821 initial_kind_sentinel); | 3821 initial_kind_sentinel); |
| 3822 __ jmp(&done); | 3822 __ jmp(&done); |
| 3823 | 3823 |
| 3824 __ bind(¬_array_function); | 3824 __ bind(¬_array_function); |
| 3825 __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rdi); | 3825 __ movq(FieldOperand(rbx, Cell::kValueOffset), rdi); |
| 3826 // No need for a write barrier here - cells are rescanned. | 3826 // No need for a write barrier here - cells are rescanned. |
| 3827 | 3827 |
| 3828 __ bind(&done); | 3828 __ bind(&done); |
| 3829 } | 3829 } |
| 3830 | 3830 |
| 3831 | 3831 |
| 3832 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3832 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 3833 // rbx : cache cell for call target | 3833 // rbx : cache cell for call target |
| 3834 // rdi : the function to call | 3834 // rdi : the function to call |
| 3835 Isolate* isolate = masm->isolate(); | 3835 Isolate* isolate = masm->isolate(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3886 JUMP_FUNCTION, | 3886 JUMP_FUNCTION, |
| 3887 NullCallWrapper(), | 3887 NullCallWrapper(), |
| 3888 CALL_AS_FUNCTION); | 3888 CALL_AS_FUNCTION); |
| 3889 | 3889 |
| 3890 // Slow-case: Non-function called. | 3890 // Slow-case: Non-function called. |
| 3891 __ bind(&slow); | 3891 __ bind(&slow); |
| 3892 if (RecordCallTarget()) { | 3892 if (RecordCallTarget()) { |
| 3893 // If there is a call target cache, mark it megamorphic in the | 3893 // If there is a call target cache, mark it megamorphic in the |
| 3894 // non-function case. MegamorphicSentinel is an immortal immovable | 3894 // non-function case. MegamorphicSentinel is an immortal immovable |
| 3895 // object (undefined) so no write barrier is needed. | 3895 // object (undefined) so no write barrier is needed. |
| 3896 __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 3896 __ Move(FieldOperand(rbx, Cell::kValueOffset), |
| 3897 TypeFeedbackCells::MegamorphicSentinel(isolate)); | 3897 TypeFeedbackCells::MegamorphicSentinel(isolate)); |
| 3898 } | 3898 } |
| 3899 // Check for function proxy. | 3899 // Check for function proxy. |
| 3900 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); | 3900 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); |
| 3901 __ j(not_equal, &non_function); | 3901 __ j(not_equal, &non_function); |
| 3902 __ pop(rcx); | 3902 __ pop(rcx); |
| 3903 __ push(rdi); // put proxy as additional argument under return address | 3903 __ push(rdi); // put proxy as additional argument under return address |
| 3904 __ push(rcx); | 3904 __ push(rcx); |
| 3905 __ Set(rax, argc_ + 1); | 3905 __ Set(rax, argc_ + 1); |
| 3906 __ Set(rbx, 0); | 3906 __ Set(rbx, 0); |
| (...skipping 3020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6927 | 6927 |
| 6928 // Initial map for the builtin Array function should be a map. | 6928 // Initial map for the builtin Array function should be a map. |
| 6929 __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); | 6929 __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 6930 // Will both indicate a NULL and a Smi. | 6930 // Will both indicate a NULL and a Smi. |
| 6931 STATIC_ASSERT(kSmiTag == 0); | 6931 STATIC_ASSERT(kSmiTag == 0); |
| 6932 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); | 6932 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); |
| 6933 __ Check(not_smi, "Unexpected initial map for Array function"); | 6933 __ Check(not_smi, "Unexpected initial map for Array function"); |
| 6934 __ CmpObjectType(rcx, MAP_TYPE, rcx); | 6934 __ CmpObjectType(rcx, MAP_TYPE, rcx); |
| 6935 __ Check(equal, "Unexpected initial map for Array function"); | 6935 __ Check(equal, "Unexpected initial map for Array function"); |
| 6936 | 6936 |
| 6937 // We should either have undefined in ebx or a valid jsglobalpropertycell | 6937 // We should either have undefined in ebx or a valid cell |
| 6938 Label okay_here; | 6938 Label okay_here; |
| 6939 Handle<Map> global_property_cell_map( | 6939 Handle<Map> cell_map( |
| 6940 masm->isolate()->heap()->global_property_cell_map()); | 6940 masm->isolate()->heap()->cell_map()); |
|
Michael Starzinger
2013/06/12 13:23:25
See nit for other architecture.
danno
2013/06/12 14:24:28
Done.
| |
| 6941 __ Cmp(rbx, undefined_sentinel); | 6941 __ Cmp(rbx, undefined_sentinel); |
| 6942 __ j(equal, &okay_here); | 6942 __ j(equal, &okay_here); |
| 6943 __ Cmp(FieldOperand(rbx, 0), global_property_cell_map); | 6943 __ Cmp(FieldOperand(rbx, 0), cell_map); |
| 6944 __ Assert(equal, "Expected property cell in register rbx"); | 6944 __ Assert(equal, "Expected property cell in register rbx"); |
| 6945 __ bind(&okay_here); | 6945 __ bind(&okay_here); |
| 6946 } | 6946 } |
| 6947 | 6947 |
| 6948 if (FLAG_optimize_constructed_arrays) { | 6948 if (FLAG_optimize_constructed_arrays) { |
| 6949 Label no_info, switch_ready; | 6949 Label no_info, switch_ready; |
| 6950 // Get the elements kind and case on that. | 6950 // Get the elements kind and case on that. |
| 6951 __ Cmp(rbx, undefined_sentinel); | 6951 __ Cmp(rbx, undefined_sentinel); |
| 6952 __ j(equal, &no_info); | 6952 __ j(equal, &no_info); |
| 6953 __ movq(rdx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 6953 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset)); |
| 6954 __ JumpIfNotSmi(rdx, &no_info); | 6954 __ JumpIfNotSmi(rdx, &no_info); |
| 6955 __ SmiToInteger32(rdx, rdx); | 6955 __ SmiToInteger32(rdx, rdx); |
| 6956 __ jmp(&switch_ready); | 6956 __ jmp(&switch_ready); |
| 6957 __ bind(&no_info); | 6957 __ bind(&no_info); |
| 6958 __ movq(rdx, Immediate(GetInitialFastElementsKind())); | 6958 __ movq(rdx, Immediate(GetInitialFastElementsKind())); |
| 6959 __ bind(&switch_ready); | 6959 __ bind(&switch_ready); |
| 6960 | 6960 |
| 6961 if (argument_count_ == ANY) { | 6961 if (argument_count_ == ANY) { |
| 6962 Label not_zero_case, not_one_case; | 6962 Label not_zero_case, not_one_case; |
| 6963 __ testq(rax, rax); | 6963 __ testq(rax, rax); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7095 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 7095 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 7096 } | 7096 } |
| 7097 } | 7097 } |
| 7098 | 7098 |
| 7099 | 7099 |
| 7100 #undef __ | 7100 #undef __ |
| 7101 | 7101 |
| 7102 } } // namespace v8::internal | 7102 } } // namespace v8::internal |
| 7103 | 7103 |
| 7104 #endif // V8_TARGET_ARCH_X64 | 7104 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |