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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2245 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 2245 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
2246 FixedArray::kHeaderSize)); | 2246 FixedArray::kHeaderSize)); |
2247 | 2247 |
2248 // Verify that ecx contains an AllocationSite | 2248 // Verify that ecx contains an AllocationSite |
2249 Factory* factory = masm->isolate()->factory(); | 2249 Factory* factory = masm->isolate()->factory(); |
2250 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), | 2250 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), |
2251 factory->allocation_site_map()); | 2251 factory->allocation_site_map()); |
2252 __ j(not_equal, &miss); | 2252 __ j(not_equal, &miss); |
2253 | 2253 |
2254 __ mov(ebx, ecx); | 2254 __ mov(ebx, ecx); |
2255 __ mov(edx, edi); | |
2256 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2255 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
2257 __ TailCallStub(&stub); | 2256 __ TailCallStub(&stub); |
2258 | 2257 |
2259 __ bind(&miss); | 2258 __ bind(&miss); |
2260 GenerateMiss(masm); | 2259 GenerateMiss(masm); |
2261 | 2260 |
2262 // The slow case, we need this no matter what to complete a call after a miss. | 2261 // The slow case, we need this no matter what to complete a call after a miss. |
2263 CallFunctionNoFeedback(masm, | 2262 CallFunctionNoFeedback(masm, |
2264 arg_count(), | 2263 arg_count(), |
2265 true, | 2264 true, |
(...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4624 UNREACHABLE(); | 4623 UNREACHABLE(); |
4625 } | 4624 } |
4626 } | 4625 } |
4627 | 4626 |
4628 | 4627 |
4629 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 4628 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
4630 // ----------- S t a t e ------------- | 4629 // ----------- S t a t e ------------- |
4631 // -- eax : argc (only if argument_count() == ANY) | 4630 // -- eax : argc (only if argument_count() == ANY) |
4632 // -- ebx : AllocationSite or undefined | 4631 // -- ebx : AllocationSite or undefined |
4633 // -- edi : constructor | 4632 // -- edi : constructor |
4634 // -- edx : Original constructor | |
4635 // -- esp[0] : return address | 4633 // -- esp[0] : return address |
4636 // -- esp[4] : last argument | 4634 // -- esp[4] : last argument |
4637 // ----------------------------------- | 4635 // ----------------------------------- |
4638 if (FLAG_debug_code) { | 4636 if (FLAG_debug_code) { |
4639 // The array construct code is only set for the global and natives | 4637 // The array construct code is only set for the global and natives |
4640 // builtin Array functions which always have maps. | 4638 // builtin Array functions which always have maps. |
4641 | 4639 |
4642 // Initial map for the builtin Array function should be a map. | 4640 // Initial map for the builtin Array function should be a map. |
4643 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 4641 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
4644 // Will both indicate a NULL and a Smi. | 4642 // Will both indicate a NULL and a Smi. |
4645 __ test(ecx, Immediate(kSmiTagMask)); | 4643 __ test(ecx, Immediate(kSmiTagMask)); |
4646 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 4644 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
4647 __ CmpObjectType(ecx, MAP_TYPE, ecx); | 4645 __ CmpObjectType(ecx, MAP_TYPE, ecx); |
4648 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 4646 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
4649 | 4647 |
4650 // We should either have undefined in ebx or a valid AllocationSite | 4648 // We should either have undefined in ebx or a valid AllocationSite |
4651 __ AssertUndefinedOrAllocationSite(ebx); | 4649 __ AssertUndefinedOrAllocationSite(ebx); |
4652 } | 4650 } |
4653 | 4651 |
4654 Label no_info; | 4652 Label no_info; |
4655 Label subclassing; | |
4656 // If the feedback vector is the undefined value call an array constructor | 4653 // If the feedback vector is the undefined value call an array constructor |
4657 // that doesn't use AllocationSites. | 4654 // that doesn't use AllocationSites. |
4658 __ cmp(ebx, isolate()->factory()->undefined_value()); | 4655 __ cmp(ebx, isolate()->factory()->undefined_value()); |
4659 __ j(equal, &no_info); | 4656 __ j(equal, &no_info); |
4660 | 4657 |
4661 __ cmp(edx, edi); | |
4662 __ j(not_equal, &subclassing); | |
4663 | |
4664 // Only look at the lower 16 bits of the transition info. | 4658 // Only look at the lower 16 bits of the transition info. |
4665 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); | 4659 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); |
4666 __ SmiUntag(edx); | 4660 __ SmiUntag(edx); |
4667 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 4661 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
4668 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); | 4662 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); |
4669 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 4663 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
4670 | 4664 |
4671 __ bind(&no_info); | 4665 __ bind(&no_info); |
4672 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 4666 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
4673 | |
4674 __ bind(&subclassing); | |
4675 __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); | |
4676 } | 4667 } |
4677 | 4668 |
4678 | 4669 |
4679 void InternalArrayConstructorStub::GenerateCase( | 4670 void InternalArrayConstructorStub::GenerateCase( |
4680 MacroAssembler* masm, ElementsKind kind) { | 4671 MacroAssembler* masm, ElementsKind kind) { |
4681 Label not_zero_case, not_one_case; | 4672 Label not_zero_case, not_one_case; |
4682 Label normal_sequence; | 4673 Label normal_sequence; |
4683 | 4674 |
4684 __ test(eax, eax); | 4675 __ test(eax, eax); |
4685 __ j(not_zero, ¬_zero_case); | 4676 __ j(not_zero, ¬_zero_case); |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5147 ApiParameterOperand(2), kStackSpace, nullptr, | 5138 ApiParameterOperand(2), kStackSpace, nullptr, |
5148 Operand(ebp, 7 * kPointerSize), NULL); | 5139 Operand(ebp, 7 * kPointerSize), NULL); |
5149 } | 5140 } |
5150 | 5141 |
5151 | 5142 |
5152 #undef __ | 5143 #undef __ |
5153 | 5144 |
5154 } } // namespace v8::internal | 5145 } } // namespace v8::internal |
5155 | 5146 |
5156 #endif // V8_TARGET_ARCH_IA32 | 5147 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |