| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2115 __ movp(rax, Immediate(arg_count())); | 2115 __ movp(rax, Immediate(arg_count())); |
| 2116 __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size, | 2116 __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size, |
| 2117 FixedArray::kHeaderSize)); | 2117 FixedArray::kHeaderSize)); |
| 2118 // Verify that ecx contains an AllocationSite | 2118 // Verify that ecx contains an AllocationSite |
| 2119 Factory* factory = masm->isolate()->factory(); | 2119 Factory* factory = masm->isolate()->factory(); |
| 2120 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), | 2120 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), |
| 2121 factory->allocation_site_map()); | 2121 factory->allocation_site_map()); |
| 2122 __ j(not_equal, &miss); | 2122 __ j(not_equal, &miss); |
| 2123 | 2123 |
| 2124 __ movp(rbx, rcx); | 2124 __ movp(rbx, rcx); |
| 2125 __ movp(rdx, rdi); |
| 2125 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2126 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2126 __ TailCallStub(&stub); | 2127 __ TailCallStub(&stub); |
| 2127 | 2128 |
| 2128 __ bind(&miss); | 2129 __ bind(&miss); |
| 2129 GenerateMiss(masm); | 2130 GenerateMiss(masm); |
| 2130 | 2131 |
| 2131 // The slow case, we need this no matter what to complete a call after a miss. | 2132 // The slow case, we need this no matter what to complete a call after a miss. |
| 2132 CallFunctionNoFeedback(masm, | 2133 CallFunctionNoFeedback(masm, |
| 2133 arg_count(), | 2134 arg_count(), |
| 2134 true, | 2135 true, |
| (...skipping 2431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4566 UNREACHABLE(); | 4567 UNREACHABLE(); |
| 4567 } | 4568 } |
| 4568 } | 4569 } |
| 4569 | 4570 |
| 4570 | 4571 |
| 4571 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 4572 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 4572 // ----------- S t a t e ------------- | 4573 // ----------- S t a t e ------------- |
| 4573 // -- rax : argc | 4574 // -- rax : argc |
| 4574 // -- rbx : AllocationSite or undefined | 4575 // -- rbx : AllocationSite or undefined |
| 4575 // -- rdi : constructor | 4576 // -- rdi : constructor |
| 4577 // -- rdx : original constructor |
| 4576 // -- rsp[0] : return address | 4578 // -- rsp[0] : return address |
| 4577 // -- rsp[8] : last argument | 4579 // -- rsp[8] : last argument |
| 4578 // ----------------------------------- | 4580 // ----------------------------------- |
| 4579 if (FLAG_debug_code) { | 4581 if (FLAG_debug_code) { |
| 4580 // The array construct code is only set for the global and natives | 4582 // The array construct code is only set for the global and natives |
| 4581 // builtin Array functions which always have maps. | 4583 // builtin Array functions which always have maps. |
| 4582 | 4584 |
| 4583 // Initial map for the builtin Array function should be a map. | 4585 // Initial map for the builtin Array function should be a map. |
| 4584 __ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); | 4586 __ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4585 // Will both indicate a NULL and a Smi. | 4587 // Will both indicate a NULL and a Smi. |
| 4586 STATIC_ASSERT(kSmiTag == 0); | 4588 STATIC_ASSERT(kSmiTag == 0); |
| 4587 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); | 4589 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); |
| 4588 __ Check(not_smi, kUnexpectedInitialMapForArrayFunction); | 4590 __ Check(not_smi, kUnexpectedInitialMapForArrayFunction); |
| 4589 __ CmpObjectType(rcx, MAP_TYPE, rcx); | 4591 __ CmpObjectType(rcx, MAP_TYPE, rcx); |
| 4590 __ Check(equal, kUnexpectedInitialMapForArrayFunction); | 4592 __ Check(equal, kUnexpectedInitialMapForArrayFunction); |
| 4591 | 4593 |
| 4592 // We should either have undefined in rbx or a valid AllocationSite | 4594 // We should either have undefined in rbx or a valid AllocationSite |
| 4593 __ AssertUndefinedOrAllocationSite(rbx); | 4595 __ AssertUndefinedOrAllocationSite(rbx); |
| 4594 } | 4596 } |
| 4595 | 4597 |
| 4598 Label subclassing; |
| 4599 __ cmpp(rdi, rdx); |
| 4600 __ j(not_equal, &subclassing); |
| 4601 |
| 4596 Label no_info; | 4602 Label no_info; |
| 4597 // If the feedback vector is the undefined value call an array constructor | 4603 // If the feedback vector is the undefined value call an array constructor |
| 4598 // that doesn't use AllocationSites. | 4604 // that doesn't use AllocationSites. |
| 4599 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); | 4605 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); |
| 4600 __ j(equal, &no_info); | 4606 __ j(equal, &no_info); |
| 4601 | 4607 |
| 4602 // Only look at the lower 16 bits of the transition info. | 4608 // Only look at the lower 16 bits of the transition info. |
| 4603 __ movp(rdx, FieldOperand(rbx, AllocationSite::kTransitionInfoOffset)); | 4609 __ movp(rdx, FieldOperand(rbx, AllocationSite::kTransitionInfoOffset)); |
| 4604 __ SmiToInteger32(rdx, rdx); | 4610 __ SmiToInteger32(rdx, rdx); |
| 4605 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 4611 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
| 4606 __ andp(rdx, Immediate(AllocationSite::ElementsKindBits::kMask)); | 4612 __ andp(rdx, Immediate(AllocationSite::ElementsKindBits::kMask)); |
| 4607 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 4613 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| 4608 | 4614 |
| 4609 __ bind(&no_info); | 4615 __ bind(&no_info); |
| 4610 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 4616 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 4617 |
| 4618 __ bind(&subclassing); |
| 4619 __ TailCallRuntime(Runtime::kThrowArrayNotSubclassableError, 0, 1); |
| 4611 } | 4620 } |
| 4612 | 4621 |
| 4613 | 4622 |
| 4614 void InternalArrayConstructorStub::GenerateCase( | 4623 void InternalArrayConstructorStub::GenerateCase( |
| 4615 MacroAssembler* masm, ElementsKind kind) { | 4624 MacroAssembler* masm, ElementsKind kind) { |
| 4616 Label not_zero_case, not_one_case; | 4625 Label not_zero_case, not_one_case; |
| 4617 Label normal_sequence; | 4626 Label normal_sequence; |
| 4618 | 4627 |
| 4619 __ testp(rax, rax); | 4628 __ testp(rax, rax); |
| 4620 __ j(not_zero, ¬_zero_case); | 4629 __ j(not_zero, ¬_zero_case); |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5096 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, | 5105 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, |
| 5097 kStackSpace, nullptr, return_value_operand, NULL); | 5106 kStackSpace, nullptr, return_value_operand, NULL); |
| 5098 } | 5107 } |
| 5099 | 5108 |
| 5100 | 5109 |
| 5101 #undef __ | 5110 #undef __ |
| 5102 | 5111 |
| 5103 } } // namespace v8::internal | 5112 } } // namespace v8::internal |
| 5104 | 5113 |
| 5105 #endif // V8_TARGET_ARCH_X64 | 5114 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |