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