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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 4515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 GenerateImpl(masm, false); | 4526 GenerateImpl(masm, false); |
4527 } | 4527 } |
4528 | 4528 |
4529 | 4529 |
4530 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4530 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
4531 GenerateImpl(masm, true); | 4531 GenerateImpl(masm, true); |
4532 } | 4532 } |
4533 | 4533 |
4534 | 4534 |
4535 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4535 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
4536 Label miss; | 4536 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // rdx |
| 4537 Register key = VectorStoreICDescriptor::NameRegister(); // rcx |
| 4538 Register vector = VectorStoreICDescriptor::VectorRegister(); // rbx |
| 4539 Register slot = VectorStoreICDescriptor::SlotRegister(); // rdi |
| 4540 DCHECK(VectorStoreICDescriptor::ValueRegister().is(rax)); // rax |
| 4541 Register feedback = r8; |
| 4542 Register integer_slot = r9; |
| 4543 Register receiver_map = r11; |
| 4544 DCHECK(!AreAliased(feedback, integer_slot, vector, slot, receiver_map)); |
4537 | 4545 |
4538 // TODO(mvstanton): Implement. | 4546 __ SmiToInteger32(integer_slot, slot); |
| 4547 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, |
| 4548 FixedArray::kHeaderSize)); |
| 4549 |
| 4550 // Try to quickly handle the monomorphic case without knowing for sure |
| 4551 // if we have a weak cell in feedback. We do know it's safe to look |
| 4552 // at WeakCell::kValueOffset. |
| 4553 Label try_array, load_smi_map, compare_map; |
| 4554 Label not_array, miss; |
| 4555 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, |
| 4556 integer_slot, &compare_map, &load_smi_map, &try_array); |
| 4557 |
| 4558 // Is it a fixed array? |
| 4559 __ bind(&try_array); |
| 4560 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex); |
| 4561 __ j(not_equal, ¬_array); |
| 4562 HandleArrayCases(masm, receiver, key, vector, slot, feedback, receiver_map, |
| 4563 integer_slot, r14, r15, true, &miss); |
| 4564 |
| 4565 __ bind(¬_array); |
| 4566 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); |
| 4567 __ j(not_equal, &miss); |
| 4568 |
| 4569 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags( |
| 4570 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 4571 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, code_flags, |
| 4572 receiver, key, feedback, no_reg); |
| 4573 |
4539 __ bind(&miss); | 4574 __ bind(&miss); |
4540 StoreIC::GenerateMiss(masm); | 4575 StoreIC::GenerateMiss(masm); |
| 4576 |
| 4577 __ bind(&load_smi_map); |
| 4578 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
| 4579 __ jmp(&compare_map); |
4541 } | 4580 } |
4542 | 4581 |
4543 | 4582 |
4544 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { | 4583 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { |
4545 GenerateImpl(masm, false); | 4584 GenerateImpl(masm, false); |
4546 } | 4585 } |
4547 | 4586 |
4548 | 4587 |
4549 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4588 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
4550 GenerateImpl(masm, true); | 4589 GenerateImpl(masm, true); |
4551 } | 4590 } |
4552 | 4591 |
4553 | 4592 |
| 4593 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, |
| 4594 Register receiver_map, |
| 4595 Register feedback, Register scratch, |
| 4596 Register scratch1, |
| 4597 Register scratch2, Label* miss) { |
| 4598 // feedback initially contains the feedback array |
| 4599 Label next, next_loop, prepare_next; |
| 4600 Label transition_call; |
| 4601 |
| 4602 Register cached_map = scratch; |
| 4603 Register counter = scratch1; |
| 4604 Register length = scratch2; |
| 4605 |
| 4606 // Polymorphic, we have to loop from 0 to N - 1 |
| 4607 __ movp(counter, Immediate(0)); |
| 4608 __ movp(length, FieldOperand(feedback, FixedArray::kLengthOffset)); |
| 4609 __ SmiToInteger32(length, length); |
| 4610 |
| 4611 __ bind(&next_loop); |
| 4612 __ movp(cached_map, FieldOperand(feedback, counter, times_pointer_size, |
| 4613 FixedArray::kHeaderSize)); |
| 4614 __ cmpp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4615 __ j(not_equal, &prepare_next); |
| 4616 __ movp(cached_map, FieldOperand(feedback, counter, times_pointer_size, |
| 4617 FixedArray::kHeaderSize + kPointerSize)); |
| 4618 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); |
| 4619 __ j(not_equal, &transition_call); |
| 4620 __ movp(feedback, FieldOperand(feedback, counter, times_pointer_size, |
| 4621 FixedArray::kHeaderSize + 2 * kPointerSize)); |
| 4622 __ leap(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4623 __ jmp(feedback); |
| 4624 |
| 4625 __ bind(&transition_call); |
| 4626 DCHECK(receiver_map.is(VectorStoreTransitionDescriptor::MapRegister())); |
| 4627 __ movp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4628 // The weak cell may have been cleared. |
| 4629 __ JumpIfSmi(receiver_map, miss); |
| 4630 // Get the handler in value. |
| 4631 __ movp(feedback, FieldOperand(feedback, counter, times_pointer_size, |
| 4632 FixedArray::kHeaderSize + 2 * kPointerSize)); |
| 4633 __ leap(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4634 __ jmp(feedback); |
| 4635 |
| 4636 __ bind(&prepare_next); |
| 4637 __ addl(counter, Immediate(3)); |
| 4638 __ cmpl(counter, length); |
| 4639 __ j(less, &next_loop); |
| 4640 |
| 4641 // We exhausted our array of map handler pairs. |
| 4642 __ jmp(miss); |
| 4643 } |
| 4644 |
| 4645 |
4554 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4646 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
4555 Label miss; | 4647 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // rdx |
| 4648 Register key = VectorStoreICDescriptor::NameRegister(); // rcx |
| 4649 Register vector = VectorStoreICDescriptor::VectorRegister(); // rbx |
| 4650 Register slot = VectorStoreICDescriptor::SlotRegister(); // rdi |
| 4651 DCHECK(VectorStoreICDescriptor::ValueRegister().is(rax)); // rax |
| 4652 Register feedback = r8; |
| 4653 Register integer_slot = r9; |
| 4654 Register receiver_map = r11; |
| 4655 DCHECK(!AreAliased(feedback, integer_slot, vector, slot, receiver_map)); |
4556 | 4656 |
4557 // TODO(mvstanton): Implement. | 4657 __ SmiToInteger32(integer_slot, slot); |
| 4658 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, |
| 4659 FixedArray::kHeaderSize)); |
| 4660 |
| 4661 // Try to quickly handle the monomorphic case without knowing for sure |
| 4662 // if we have a weak cell in feedback. We do know it's safe to look |
| 4663 // at WeakCell::kValueOffset. |
| 4664 Label try_array, load_smi_map, compare_map; |
| 4665 Label not_array, miss; |
| 4666 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, |
| 4667 integer_slot, &compare_map, &load_smi_map, &try_array); |
| 4668 |
| 4669 // Is it a fixed array? |
| 4670 __ bind(&try_array); |
| 4671 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex); |
| 4672 __ j(not_equal, ¬_array); |
| 4673 HandlePolymorphicKeyedStoreCase(masm, receiver_map, feedback, integer_slot, |
| 4674 r15, r14, &miss); |
| 4675 |
| 4676 __ bind(¬_array); |
| 4677 Label try_poly_name; |
| 4678 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); |
| 4679 __ j(not_equal, &try_poly_name); |
| 4680 |
| 4681 Handle<Code> megamorphic_stub = |
| 4682 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState()); |
| 4683 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); |
| 4684 |
| 4685 __ bind(&try_poly_name); |
| 4686 // We might have a name in feedback, and a fixed array in the next slot. |
| 4687 __ cmpp(key, feedback); |
| 4688 __ j(not_equal, &miss); |
| 4689 // If the name comparison succeeded, we know we have a fixed array with |
| 4690 // at least one map/handler pair. |
| 4691 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, |
| 4692 FixedArray::kHeaderSize + kPointerSize)); |
| 4693 HandleArrayCases(masm, receiver, key, vector, slot, feedback, receiver_map, |
| 4694 integer_slot, r14, r15, false, &miss); |
| 4695 |
4558 __ bind(&miss); | 4696 __ bind(&miss); |
4559 KeyedStoreIC::GenerateMiss(masm); | 4697 KeyedStoreIC::GenerateMiss(masm); |
| 4698 |
| 4699 __ bind(&load_smi_map); |
| 4700 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
| 4701 __ jmp(&compare_map); |
4560 } | 4702 } |
4561 | 4703 |
4562 | 4704 |
4563 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 4705 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
4564 EmitLoadTypeFeedbackVector(masm, rbx); | 4706 EmitLoadTypeFeedbackVector(masm, rbx); |
4565 CallICStub stub(isolate(), state()); | 4707 CallICStub stub(isolate(), state()); |
4566 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 4708 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
4567 } | 4709 } |
4568 | 4710 |
4569 | 4711 |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5512 kStackSpace, nullptr, return_value_operand, NULL); | 5654 kStackSpace, nullptr, return_value_operand, NULL); |
5513 } | 5655 } |
5514 | 5656 |
5515 | 5657 |
5516 #undef __ | 5658 #undef __ |
5517 | 5659 |
5518 } // namespace internal | 5660 } // namespace internal |
5519 } // namespace v8 | 5661 } // namespace v8 |
5520 | 5662 |
5521 #endif // V8_TARGET_ARCH_X64 | 5663 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |