| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 Isolate* isolate, | 54 Isolate* isolate, |
| 55 CodeStubInterfaceDescriptor* descriptor) { | 55 CodeStubInterfaceDescriptor* descriptor) { |
| 56 static Register registers[] = { a3, a2, a1, a0 }; | 56 static Register registers[] = { a3, a2, a1, a0 }; |
| 57 descriptor->register_param_count_ = 4; | 57 descriptor->register_param_count_ = 4; |
| 58 descriptor->register_params_ = registers; | 58 descriptor->register_params_ = registers; |
| 59 descriptor->deoptimization_handler_ = | 59 descriptor->deoptimization_handler_ = |
| 60 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; | 60 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; |
| 61 } | 61 } |
| 62 | 62 |
| 63 | 63 |
| 64 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
| 65 Isolate* isolate, |
| 66 CodeStubInterfaceDescriptor* descriptor) { |
| 67 static Register registers[] = { a2 }; |
| 68 descriptor->register_param_count_ = 1; |
| 69 descriptor->register_params_ = registers; |
| 70 descriptor->deoptimization_handler_ = NULL; |
| 71 } |
| 72 |
| 73 |
| 64 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( | 74 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( |
| 65 Isolate* isolate, | 75 Isolate* isolate, |
| 66 CodeStubInterfaceDescriptor* descriptor) { | 76 CodeStubInterfaceDescriptor* descriptor) { |
| 67 static Register registers[] = { a1, a0 }; | 77 static Register registers[] = { a1, a0 }; |
| 68 descriptor->register_param_count_ = 2; | 78 descriptor->register_param_count_ = 2; |
| 69 descriptor->register_params_ = registers; | 79 descriptor->register_params_ = registers; |
| 70 descriptor->deoptimization_handler_ = | 80 descriptor->deoptimization_handler_ = |
| 71 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); | 81 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
| 72 } | 82 } |
| 73 | 83 |
| (...skipping 2998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3072 } | 3082 } |
| 3073 | 3083 |
| 3074 | 3084 |
| 3075 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 3085 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 3076 CEntryStub::GenerateAheadOfTime(isolate); | 3086 CEntryStub::GenerateAheadOfTime(isolate); |
| 3077 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); | 3087 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 3078 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 3088 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 3079 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 3089 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
| 3080 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); | 3090 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 3081 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 3091 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
| 3092 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
| 3082 } | 3093 } |
| 3083 | 3094 |
| 3084 | 3095 |
| 3085 void CodeStub::GenerateFPStubs(Isolate* isolate) { | 3096 void CodeStub::GenerateFPStubs(Isolate* isolate) { |
| 3086 SaveFPRegsMode mode = kSaveFPRegs; | 3097 SaveFPRegsMode mode = kSaveFPRegs; |
| 3087 CEntryStub save_doubles(1, mode); | 3098 CEntryStub save_doubles(1, mode); |
| 3088 StoreBufferOverflowStub stub(mode); | 3099 StoreBufferOverflowStub stub(mode); |
| 3089 // These stubs might already be in the snapshot, detect that and don't | 3100 // These stubs might already be in the snapshot, detect that and don't |
| 3090 // regenerate, which would lead to code stub initialization state being messed | 3101 // regenerate, which would lead to code stub initialization state being messed |
| 3091 // up. | 3102 // up. |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3715 // -- a2 : name | 3726 // -- a2 : name |
| 3716 // -- ra : return address | 3727 // -- ra : return address |
| 3717 // -- a0 : receiver | 3728 // -- a0 : receiver |
| 3718 // -- sp[0] : receiver | 3729 // -- sp[0] : receiver |
| 3719 // ----------------------------------- | 3730 // ----------------------------------- |
| 3720 receiver = a0; | 3731 receiver = a0; |
| 3721 } | 3732 } |
| 3722 | 3733 |
| 3723 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3, t0, &miss); | 3734 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3, t0, &miss); |
| 3724 __ bind(&miss); | 3735 __ bind(&miss); |
| 3725 StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind())); | 3736 StubCompiler::TailCallBuiltin( |
| 3737 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); |
| 3726 } | 3738 } |
| 3727 | 3739 |
| 3728 | 3740 |
| 3729 void StringLengthStub::Generate(MacroAssembler* masm) { | 3741 void StringLengthStub::Generate(MacroAssembler* masm) { |
| 3730 Label miss; | 3742 Label miss; |
| 3731 Register receiver; | 3743 Register receiver; |
| 3732 if (kind() == Code::KEYED_LOAD_IC) { | 3744 if (kind() == Code::KEYED_LOAD_IC) { |
| 3733 // ----------- S t a t e ------------- | 3745 // ----------- S t a t e ------------- |
| 3734 // -- ra : return address | 3746 // -- ra : return address |
| 3735 // -- a0 : key | 3747 // -- a0 : key |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3746 // -- a0 : receiver | 3758 // -- a0 : receiver |
| 3747 // -- sp[0] : receiver | 3759 // -- sp[0] : receiver |
| 3748 // ----------------------------------- | 3760 // ----------------------------------- |
| 3749 receiver = a0; | 3761 receiver = a0; |
| 3750 } | 3762 } |
| 3751 | 3763 |
| 3752 StubCompiler::GenerateLoadStringLength(masm, receiver, a3, t0, &miss, | 3764 StubCompiler::GenerateLoadStringLength(masm, receiver, a3, t0, &miss, |
| 3753 support_wrapper_); | 3765 support_wrapper_); |
| 3754 | 3766 |
| 3755 __ bind(&miss); | 3767 __ bind(&miss); |
| 3756 StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind())); | 3768 StubCompiler::TailCallBuiltin( |
| 3769 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); |
| 3757 } | 3770 } |
| 3758 | 3771 |
| 3759 | 3772 |
| 3760 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { | 3773 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { |
| 3761 // This accepts as a receiver anything JSArray::SetElementsLength accepts | 3774 // This accepts as a receiver anything JSArray::SetElementsLength accepts |
| 3762 // (currently anything except for external arrays which means anything with | 3775 // (currently anything except for external arrays which means anything with |
| 3763 // elements of FixedArray type). Value must be a number, but only smis are | 3776 // elements of FixedArray type). Value must be a number, but only smis are |
| 3764 // accepted as the most common case. | 3777 // accepted as the most common case. |
| 3765 Label miss; | 3778 Label miss; |
| 3766 | 3779 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3816 | 3829 |
| 3817 // Prepare tail call to StoreIC_ArrayLength. | 3830 // Prepare tail call to StoreIC_ArrayLength. |
| 3818 __ Push(receiver, value); | 3831 __ Push(receiver, value); |
| 3819 | 3832 |
| 3820 ExternalReference ref = | 3833 ExternalReference ref = |
| 3821 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), masm->isolate()); | 3834 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), masm->isolate()); |
| 3822 __ TailCallExternalReference(ref, 2, 1); | 3835 __ TailCallExternalReference(ref, 2, 1); |
| 3823 | 3836 |
| 3824 __ bind(&miss); | 3837 __ bind(&miss); |
| 3825 | 3838 |
| 3826 StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind())); | 3839 StubCompiler::TailCallBuiltin( |
| 3840 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); |
| 3827 } | 3841 } |
| 3828 | 3842 |
| 3829 | 3843 |
| 3830 Register InstanceofStub::left() { return a0; } | 3844 Register InstanceofStub::left() { return a0; } |
| 3831 | 3845 |
| 3832 | 3846 |
| 3833 Register InstanceofStub::right() { return a1; } | 3847 Register InstanceofStub::right() { return a1; } |
| 3834 | 3848 |
| 3835 | 3849 |
| 3836 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { | 3850 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
| (...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4771 masm->isolate()->heap()->undefined_value()); | 4785 masm->isolate()->heap()->undefined_value()); |
| 4772 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), | 4786 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), |
| 4773 masm->isolate()->heap()->the_hole_value()); | 4787 masm->isolate()->heap()->the_hole_value()); |
| 4774 | 4788 |
| 4775 // Load the cache state into a3. | 4789 // Load the cache state into a3. |
| 4776 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); | 4790 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); |
| 4777 | 4791 |
| 4778 // A monomorphic cache hit or an already megamorphic state: invoke the | 4792 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 4779 // function without changing the state. | 4793 // function without changing the state. |
| 4780 __ Branch(&done, eq, a3, Operand(a1)); | 4794 __ Branch(&done, eq, a3, Operand(a1)); |
| 4781 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | |
| 4782 __ Branch(&done, eq, a3, Operand(at)); | |
| 4783 | 4795 |
| 4784 // Special handling of the Array() function, which caches not only the | 4796 // If we came here, we need to see if we are the array function. |
| 4785 // monomorphic Array function but the initial ElementsKind with special | 4797 // If we didn't have a matching function, and we didn't find the megamorph |
| 4786 // sentinels | 4798 // sentinel, then we have in the cell either some other function or an |
| 4787 __ JumpIfNotSmi(a3, &miss); | 4799 // AllocationSite. Do a map check on the object in a3. |
| 4788 if (FLAG_debug_code) { | 4800 Handle<Map> allocation_site_map( |
| 4789 Handle<Object> terminal_kind_sentinel = | 4801 masm->isolate()->heap()->allocation_site_map(), |
| 4790 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | 4802 masm->isolate()); |
| 4791 LAST_FAST_ELEMENTS_KIND); | 4803 __ lw(t1, FieldMemOperand(a3, 0)); |
| 4792 __ Assert(le, "Array function sentinel is not an ElementsKind", | 4804 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
| 4793 a3, Operand(terminal_kind_sentinel)); | 4805 __ Branch(&miss, ne, t1, Operand(at)); |
| 4794 } | |
| 4795 | 4806 |
| 4796 // Make sure the function is the Array() function | 4807 // Make sure the function is the Array() function |
| 4797 __ LoadArrayFunction(a3); | 4808 __ LoadArrayFunction(a3); |
| 4798 __ Branch(&megamorphic, ne, a1, Operand(a3)); | 4809 __ Branch(&megamorphic, ne, a1, Operand(a3)); |
| 4799 __ jmp(&done); | 4810 __ jmp(&done); |
| 4800 | 4811 |
| 4801 __ bind(&miss); | 4812 __ bind(&miss); |
| 4802 | 4813 |
| 4803 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 4814 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
| 4804 // megamorphic. | 4815 // megamorphic. |
| 4805 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 4816 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 4806 __ Branch(&initialize, eq, a3, Operand(at)); | 4817 __ Branch(&initialize, eq, a3, Operand(at)); |
| 4807 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 4818 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
| 4808 // write-barrier is needed. | 4819 // write-barrier is needed. |
| 4809 __ bind(&megamorphic); | 4820 __ bind(&megamorphic); |
| 4810 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 4821 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 4811 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); | 4822 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); |
| 4812 __ jmp(&done); | 4823 __ jmp(&done); |
| 4813 | 4824 |
| 4814 // An uninitialized cache is patched with the function or sentinel to | 4825 // An uninitialized cache is patched with the function or sentinel to |
| 4815 // indicate the ElementsKind if function is the Array constructor. | 4826 // indicate the ElementsKind if function is the Array constructor. |
| 4816 __ bind(&initialize); | 4827 __ bind(&initialize); |
| 4817 // Make sure the function is the Array() function | 4828 // Make sure the function is the Array() function |
| 4818 __ LoadArrayFunction(a3); | 4829 __ LoadArrayFunction(a3); |
| 4819 __ Branch(¬_array_function, ne, a1, Operand(a3)); | 4830 __ Branch(¬_array_function, ne, a1, Operand(a3)); |
| 4820 | 4831 |
| 4821 // The target function is the Array constructor, install a sentinel value in | 4832 // The target function is the Array constructor. |
| 4822 // the constructor's type info cell that will track the initial ElementsKind | 4833 // Create an AllocationSite if we don't already have it, store it in the cell. |
| 4823 // that should be used for the array when its constructed. | 4834 { |
| 4824 Handle<Object> initial_kind_sentinel = | 4835 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4825 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | 4836 const RegList kSavedRegs = |
| 4826 GetInitialFastElementsKind()); | 4837 1 << 4 | // a0 |
| 4827 __ li(a3, Operand(initial_kind_sentinel)); | 4838 1 << 5 | // a1 |
| 4828 __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset)); | 4839 1 << 6; // a2 |
| 4840 |
| 4841 __ MultiPush(kSavedRegs); |
| 4842 |
| 4843 CreateAllocationSiteStub create_stub; |
| 4844 __ CallStub(&create_stub); |
| 4845 |
| 4846 __ MultiPop(kSavedRegs); |
| 4847 } |
| 4829 __ Branch(&done); | 4848 __ Branch(&done); |
| 4830 | 4849 |
| 4831 __ bind(¬_array_function); | 4850 __ bind(¬_array_function); |
| 4832 __ sw(a1, FieldMemOperand(a2, Cell::kValueOffset)); | 4851 __ sw(a1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 4833 // No need for a write barrier here - cells are rescanned. | 4852 // No need for a write barrier here - cells are rescanned. |
| 4834 | 4853 |
| 4835 __ bind(&done); | 4854 __ bind(&done); |
| 4836 } | 4855 } |
| 4837 | 4856 |
| 4838 | 4857 |
| (...skipping 2098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6937 } | 6956 } |
| 6938 } | 6957 } |
| 6939 return false; | 6958 return false; |
| 6940 } | 6959 } |
| 6941 | 6960 |
| 6942 | 6961 |
| 6943 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( | 6962 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( |
| 6944 Isolate* isolate) { | 6963 Isolate* isolate) { |
| 6945 StoreBufferOverflowStub stub1(kDontSaveFPRegs); | 6964 StoreBufferOverflowStub stub1(kDontSaveFPRegs); |
| 6946 stub1.GetCode(isolate)->set_is_pregenerated(true); | 6965 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 6966 // Hydrogen code stubs need stub2 at snapshot time. |
| 6967 StoreBufferOverflowStub stub2(kSaveFPRegs); |
| 6968 stub2.GetCode(isolate)->set_is_pregenerated(true); |
| 6947 } | 6969 } |
| 6948 | 6970 |
| 6949 | 6971 |
| 6950 void RecordWriteStub::GenerateFixedRegStubsAheadOfTime(Isolate* isolate) { | 6972 void RecordWriteStub::GenerateFixedRegStubsAheadOfTime(Isolate* isolate) { |
| 6951 for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; | 6973 for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; |
| 6952 !entry->object.is(no_reg); | 6974 !entry->object.is(no_reg); |
| 6953 entry++) { | 6975 entry++) { |
| 6954 RecordWriteStub stub(entry->object, | 6976 RecordWriteStub stub(entry->object, |
| 6955 entry->value, | 6977 entry->value, |
| 6956 entry->address, | 6978 entry->address, |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7342 // a0 - number of arguments | 7364 // a0 - number of arguments |
| 7343 // a1 - constructor? | 7365 // a1 - constructor? |
| 7344 // sp[0] - last argument | 7366 // sp[0] - last argument |
| 7345 ASSERT(FAST_SMI_ELEMENTS == 0); | 7367 ASSERT(FAST_SMI_ELEMENTS == 0); |
| 7346 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 7368 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 7347 ASSERT(FAST_ELEMENTS == 2); | 7369 ASSERT(FAST_ELEMENTS == 2); |
| 7348 ASSERT(FAST_HOLEY_ELEMENTS == 3); | 7370 ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 7349 ASSERT(FAST_DOUBLE_ELEMENTS == 4); | 7371 ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
| 7350 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); | 7372 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
| 7351 | 7373 |
| 7352 Handle<Object> undefined_sentinel( | |
| 7353 masm->isolate()->heap()->undefined_value(), | |
| 7354 masm->isolate()); | |
| 7355 | |
| 7356 // is the low bit set? If so, we are holey and that is good. | 7374 // is the low bit set? If so, we are holey and that is good. |
| 7357 Label normal_sequence; | 7375 Label normal_sequence; |
| 7358 __ And(at, a3, Operand(1)); | 7376 __ And(at, a3, Operand(1)); |
| 7359 __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); | 7377 __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); |
| 7360 | 7378 |
| 7361 // look at the first argument | 7379 // look at the first argument |
| 7362 __ lw(t1, MemOperand(sp, 0)); | 7380 __ lw(t1, MemOperand(sp, 0)); |
| 7363 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); | 7381 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); |
| 7364 | 7382 |
| 7365 // We are going to create a holey array, but our kind is non-holey. | 7383 // We are going to create a holey array, but our kind is non-holey. |
| 7366 // Fix kind and retry | 7384 // Fix kind and retry (only if we have an allocation site in the cell). |
| 7367 __ Addu(a3, a3, Operand(1)); | 7385 __ Addu(a3, a3, Operand(1)); |
| 7368 __ Branch(&normal_sequence, eq, a2, Operand(undefined_sentinel)); | 7386 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 7369 | 7387 __ Branch(&normal_sequence, eq, a2, Operand(at)); |
| 7370 // The type cell may have gone megamorphic, don't overwrite if so. | 7388 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7371 __ lw(t1, FieldMemOperand(a2, kPointerSize)); | 7389 __ lw(t1, FieldMemOperand(t1, 0)); |
| 7372 __ JumpIfNotSmi(t1, &normal_sequence); | 7390 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
| 7391 __ Branch(&normal_sequence, ne, t1, Operand(at)); |
| 7373 | 7392 |
| 7374 // Save the resulting elements kind in type info | 7393 // Save the resulting elements kind in type info |
| 7375 __ SmiTag(a3); | 7394 __ SmiTag(a3); |
| 7376 __ sw(a3, FieldMemOperand(a2, kPointerSize)); | 7395 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7396 __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset)); |
| 7377 __ SmiUntag(a3); | 7397 __ SmiUntag(a3); |
| 7378 | 7398 |
| 7379 __ bind(&normal_sequence); | 7399 __ bind(&normal_sequence); |
| 7380 int last_index = GetSequenceIndexFromFastElementsKind( | 7400 int last_index = GetSequenceIndexFromFastElementsKind( |
| 7381 TERMINAL_FAST_ELEMENTS_KIND); | 7401 TERMINAL_FAST_ELEMENTS_KIND); |
| 7382 for (int i = 0; i <= last_index; ++i) { | 7402 for (int i = 0; i <= last_index; ++i) { |
| 7383 Label next; | 7403 Label next; |
| 7384 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7404 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 7385 __ Branch(&next, ne, a3, Operand(kind)); | 7405 __ Branch(&next, ne, a3, Operand(kind)); |
| 7386 ArraySingleArgumentConstructorStub stub(kind); | 7406 ArraySingleArgumentConstructorStub stub(kind); |
| 7387 __ TailCallStub(&stub); | 7407 __ TailCallStub(&stub); |
| 7388 __ bind(&next); | 7408 __ bind(&next); |
| 7389 } | 7409 } |
| 7390 | 7410 |
| 7391 // If we reached this point there is a problem. | 7411 // If we reached this point there is a problem. |
| 7392 __ Abort("Unexpected ElementsKind in array constructor"); | 7412 __ Abort("Unexpected ElementsKind in array constructor"); |
| 7393 } | 7413 } |
| 7394 | 7414 |
| 7395 | 7415 |
| 7396 template<class T> | 7416 template<class T> |
| 7397 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 7417 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
| 7398 int to_index = GetSequenceIndexFromFastElementsKind( | 7418 int to_index = GetSequenceIndexFromFastElementsKind( |
| 7399 TERMINAL_FAST_ELEMENTS_KIND); | 7419 TERMINAL_FAST_ELEMENTS_KIND); |
| 7400 for (int i = 0; i <= to_index; ++i) { | 7420 for (int i = 0; i <= to_index; ++i) { |
| 7401 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7421 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 7402 T stub(kind); | 7422 T stub(kind); |
| 7403 stub.GetCode(isolate)->set_is_pregenerated(true); | 7423 stub.GetCode(isolate)->set_is_pregenerated(true); |
| 7404 if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { | 7424 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { |
| 7405 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); | 7425 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); |
| 7406 stub1.GetCode(isolate)->set_is_pregenerated(true); | 7426 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 7407 } | 7427 } |
| 7408 } | 7428 } |
| 7409 } | 7429 } |
| 7410 | 7430 |
| 7411 | 7431 |
| 7412 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 7432 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 7413 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 7433 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
| 7414 isolate); | 7434 isolate); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7435 | 7455 |
| 7436 | 7456 |
| 7437 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 7457 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 7438 // ----------- S t a t e ------------- | 7458 // ----------- S t a t e ------------- |
| 7439 // -- a0 : argc (only if argument_count_ == ANY) | 7459 // -- a0 : argc (only if argument_count_ == ANY) |
| 7440 // -- a1 : constructor | 7460 // -- a1 : constructor |
| 7441 // -- a2 : type info cell | 7461 // -- a2 : type info cell |
| 7442 // -- sp[0] : return address | 7462 // -- sp[0] : return address |
| 7443 // -- sp[4] : last argument | 7463 // -- sp[4] : last argument |
| 7444 // ----------------------------------- | 7464 // ----------------------------------- |
| 7445 Handle<Object> undefined_sentinel( | |
| 7446 masm->isolate()->heap()->undefined_value(), | |
| 7447 masm->isolate()); | |
| 7448 | |
| 7449 if (FLAG_debug_code) { | 7465 if (FLAG_debug_code) { |
| 7450 // The array construct code is only set for the global and natives | 7466 // The array construct code is only set for the global and natives |
| 7451 // builtin Array functions which always have maps. | 7467 // builtin Array functions which always have maps. |
| 7452 | 7468 |
| 7453 // Initial map for the builtin Array function should be a map. | 7469 // Initial map for the builtin Array function should be a map. |
| 7454 __ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); | 7470 __ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); |
| 7455 // Will both indicate a NULL and a Smi. | 7471 // Will both indicate a NULL and a Smi. |
| 7456 __ And(at, a3, Operand(kSmiTagMask)); | 7472 __ And(at, a3, Operand(kSmiTagMask)); |
| 7457 __ Assert(ne, "Unexpected initial map for Array function", | 7473 __ Assert(ne, "Unexpected initial map for Array function", |
| 7458 at, Operand(zero_reg)); | 7474 at, Operand(zero_reg)); |
| 7459 __ GetObjectType(a3, a3, t0); | 7475 __ GetObjectType(a3, a3, t0); |
| 7460 __ Assert(eq, "Unexpected initial map for Array function", | 7476 __ Assert(eq, "Unexpected initial map for Array function", |
| 7461 t0, Operand(MAP_TYPE)); | 7477 t0, Operand(MAP_TYPE)); |
| 7462 | 7478 |
| 7463 // We should either have undefined in a2 or a valid cell | 7479 // We should either have undefined in a2 or a valid cell. |
| 7464 Label okay_here; | 7480 Label okay_here; |
| 7465 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 7481 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); |
| 7466 __ Branch(&okay_here, eq, a2, Operand(undefined_sentinel)); | 7482 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 7483 __ Branch(&okay_here, eq, a2, Operand(at)); |
| 7467 __ lw(a3, FieldMemOperand(a2, 0)); | 7484 __ lw(a3, FieldMemOperand(a2, 0)); |
| 7468 __ Assert(eq, "Expected property cell in register a2", | 7485 __ Assert(eq, "Expected property cell in register a2", |
| 7469 a3, Operand(cell_map)); | 7486 a3, Operand(cell_map)); |
| 7470 __ bind(&okay_here); | 7487 __ bind(&okay_here); |
| 7471 } | 7488 } |
| 7472 | 7489 |
| 7473 Label no_info, switch_ready; | 7490 Label no_info, switch_ready; |
| 7474 // Get the elements kind and case on that. | 7491 // Get the elements kind and case on that. |
| 7475 __ Branch(&no_info, eq, a2, Operand(undefined_sentinel)); | 7492 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 7493 __ Branch(&no_info, eq, a2, Operand(at)); |
| 7476 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); | 7494 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7477 __ JumpIfNotSmi(a3, &no_info); | 7495 |
| 7496 // The type cell may have undefined in its value. |
| 7497 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 7498 __ Branch(&no_info, eq, a3, Operand(at)); |
| 7499 |
| 7500 // The type cell has either an AllocationSite or a JSFunction. |
| 7501 __ lw(t0, FieldMemOperand(a3, 0)); |
| 7502 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
| 7503 __ Branch(&no_info, ne, t0, Operand(at)); |
| 7504 |
| 7505 __ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset)); |
| 7478 __ SmiUntag(a3); | 7506 __ SmiUntag(a3); |
| 7479 __ jmp(&switch_ready); | 7507 __ jmp(&switch_ready); |
| 7480 __ bind(&no_info); | 7508 __ bind(&no_info); |
| 7481 __ li(a3, Operand(GetInitialFastElementsKind())); | 7509 __ li(a3, Operand(GetInitialFastElementsKind())); |
| 7482 __ bind(&switch_ready); | 7510 __ bind(&switch_ready); |
| 7483 | 7511 |
| 7484 if (argument_count_ == ANY) { | 7512 if (argument_count_ == ANY) { |
| 7485 Label not_zero_case, not_one_case; | 7513 Label not_zero_case, not_one_case; |
| 7486 __ And(at, a0, a0); | 7514 __ And(at, a0, a0); |
| 7487 __ Branch(¬_zero_case, ne, at, Operand(zero_reg)); | 7515 __ Branch(¬_zero_case, ne, at, Operand(zero_reg)); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7586 __ bind(&fast_elements_case); | 7614 __ bind(&fast_elements_case); |
| 7587 GenerateCase(masm, FAST_ELEMENTS); | 7615 GenerateCase(masm, FAST_ELEMENTS); |
| 7588 } | 7616 } |
| 7589 | 7617 |
| 7590 | 7618 |
| 7591 #undef __ | 7619 #undef __ |
| 7592 | 7620 |
| 7593 } } // namespace v8::internal | 7621 } } // namespace v8::internal |
| 7594 | 7622 |
| 7595 #endif // V8_TARGET_ARCH_MIPS | 7623 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |