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 4486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4497 GenerateImpl(masm, false); | 4497 GenerateImpl(masm, false); |
4498 } | 4498 } |
4499 | 4499 |
4500 | 4500 |
4501 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4501 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
4502 GenerateImpl(masm, true); | 4502 GenerateImpl(masm, true); |
4503 } | 4503 } |
4504 | 4504 |
4505 | 4505 |
4506 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4506 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
4507 Label miss; | 4507 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // rdx |
| 4508 Register key = VectorStoreICDescriptor::NameRegister(); // rcx |
| 4509 Register vector = VectorStoreICDescriptor::VectorRegister(); // rbx |
| 4510 Register slot = VectorStoreICDescriptor::SlotRegister(); // rdi |
| 4511 DCHECK(VectorStoreICDescriptor::ValueRegister().is(rax)); // rax |
| 4512 Register feedback = r8; |
| 4513 Register integer_slot = r9; |
| 4514 Register receiver_map = r11; |
| 4515 DCHECK(!AreAliased(feedback, integer_slot, vector, slot, receiver_map)); |
4508 | 4516 |
4509 // TODO(mvstanton): Implement. | 4517 __ SmiToInteger32(integer_slot, slot); |
| 4518 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, |
| 4519 FixedArray::kHeaderSize)); |
| 4520 |
| 4521 // Try to quickly handle the monomorphic case without knowing for sure |
| 4522 // if we have a weak cell in feedback. We do know it's safe to look |
| 4523 // at WeakCell::kValueOffset. |
| 4524 Label try_array, load_smi_map, compare_map; |
| 4525 Label not_array, miss; |
| 4526 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, |
| 4527 integer_slot, &compare_map, &load_smi_map, &try_array); |
| 4528 |
| 4529 // Is it a fixed array? |
| 4530 __ bind(&try_array); |
| 4531 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex); |
| 4532 __ j(not_equal, ¬_array); |
| 4533 HandleArrayCases(masm, feedback, receiver_map, integer_slot, r14, r15, true, |
| 4534 &miss); |
| 4535 |
| 4536 __ bind(¬_array); |
| 4537 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); |
| 4538 __ j(not_equal, &miss); |
| 4539 |
| 4540 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags( |
| 4541 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 4542 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, code_flags, |
| 4543 receiver, key, feedback, no_reg); |
| 4544 |
4510 __ bind(&miss); | 4545 __ bind(&miss); |
4511 StoreIC::GenerateMiss(masm); | 4546 StoreIC::GenerateMiss(masm); |
| 4547 |
| 4548 __ bind(&load_smi_map); |
| 4549 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
| 4550 __ jmp(&compare_map); |
4512 } | 4551 } |
4513 | 4552 |
4514 | 4553 |
4515 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { | 4554 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { |
4516 GenerateImpl(masm, false); | 4555 GenerateImpl(masm, false); |
4517 } | 4556 } |
4518 | 4557 |
4519 | 4558 |
4520 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4559 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
4521 GenerateImpl(masm, true); | 4560 GenerateImpl(masm, true); |
4522 } | 4561 } |
4523 | 4562 |
4524 | 4563 |
| 4564 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, |
| 4565 Register receiver_map, |
| 4566 Register feedback, Register scratch, |
| 4567 Register scratch1, |
| 4568 Register scratch2, Label* miss) { |
| 4569 // feedback initially contains the feedback array |
| 4570 Label next, next_loop, prepare_next; |
| 4571 Label transition_call; |
| 4572 |
| 4573 Register cached_map = scratch; |
| 4574 Register counter = scratch1; |
| 4575 Register length = scratch2; |
| 4576 |
| 4577 // Polymorphic, we have to loop from 0 to N - 1 |
| 4578 __ movp(counter, Immediate(0)); |
| 4579 __ movp(length, FieldOperand(feedback, FixedArray::kLengthOffset)); |
| 4580 __ SmiToInteger32(length, length); |
| 4581 |
| 4582 __ bind(&next_loop); |
| 4583 __ movp(cached_map, FieldOperand(feedback, counter, times_pointer_size, |
| 4584 FixedArray::kHeaderSize)); |
| 4585 __ cmpp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4586 __ j(not_equal, &prepare_next); |
| 4587 __ movp(cached_map, FieldOperand(feedback, counter, times_pointer_size, |
| 4588 FixedArray::kHeaderSize + kPointerSize)); |
| 4589 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); |
| 4590 __ j(not_equal, &transition_call); |
| 4591 __ movp(feedback, FieldOperand(feedback, counter, times_pointer_size, |
| 4592 FixedArray::kHeaderSize + 2 * kPointerSize)); |
| 4593 __ leap(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4594 __ jmp(feedback); |
| 4595 |
| 4596 __ bind(&transition_call); |
| 4597 DCHECK(receiver_map.is(VectorStoreTransitionDescriptor::MapRegister())); |
| 4598 __ movp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4599 // The weak cell may have been cleared. |
| 4600 __ JumpIfSmi(receiver_map, miss); |
| 4601 // Get the handler in value. |
| 4602 __ movp(feedback, FieldOperand(feedback, counter, times_pointer_size, |
| 4603 FixedArray::kHeaderSize + 2 * kPointerSize)); |
| 4604 __ leap(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4605 __ jmp(feedback); |
| 4606 |
| 4607 __ bind(&prepare_next); |
| 4608 __ addl(counter, Immediate(3)); |
| 4609 __ cmpl(counter, length); |
| 4610 __ j(less, &next_loop); |
| 4611 |
| 4612 // We exhausted our array of map handler pairs. |
| 4613 __ jmp(miss); |
| 4614 } |
| 4615 |
| 4616 |
4525 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4617 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
4526 Label miss; | 4618 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // rdx |
| 4619 Register key = VectorStoreICDescriptor::NameRegister(); // rcx |
| 4620 Register vector = VectorStoreICDescriptor::VectorRegister(); // rbx |
| 4621 Register slot = VectorStoreICDescriptor::SlotRegister(); // rdi |
| 4622 DCHECK(VectorStoreICDescriptor::ValueRegister().is(rax)); // rax |
| 4623 Register feedback = r8; |
| 4624 Register integer_slot = r9; |
| 4625 Register receiver_map = r11; |
| 4626 DCHECK(!AreAliased(feedback, integer_slot, vector, slot, receiver_map)); |
4527 | 4627 |
4528 // TODO(mvstanton): Implement. | 4628 __ SmiToInteger32(integer_slot, slot); |
| 4629 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, |
| 4630 FixedArray::kHeaderSize)); |
| 4631 |
| 4632 // Try to quickly handle the monomorphic case without knowing for sure |
| 4633 // if we have a weak cell in feedback. We do know it's safe to look |
| 4634 // at WeakCell::kValueOffset. |
| 4635 Label try_array, load_smi_map, compare_map; |
| 4636 Label not_array, miss; |
| 4637 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, |
| 4638 integer_slot, &compare_map, &load_smi_map, &try_array); |
| 4639 |
| 4640 // Is it a fixed array? |
| 4641 __ bind(&try_array); |
| 4642 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex); |
| 4643 __ j(not_equal, ¬_array); |
| 4644 HandlePolymorphicKeyedStoreCase(masm, receiver_map, feedback, integer_slot, |
| 4645 r15, r14, &miss); |
| 4646 |
| 4647 __ bind(¬_array); |
| 4648 Label try_poly_name; |
| 4649 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); |
| 4650 __ j(not_equal, &try_poly_name); |
| 4651 |
| 4652 Handle<Code> megamorphic_stub = |
| 4653 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState()); |
| 4654 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); |
| 4655 |
| 4656 __ bind(&try_poly_name); |
| 4657 // We might have a name in feedback, and a fixed array in the next slot. |
| 4658 __ cmpp(key, feedback); |
| 4659 __ j(not_equal, &miss); |
| 4660 // If the name comparison succeeded, we know we have a fixed array with |
| 4661 // at least one map/handler pair. |
| 4662 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, |
| 4663 FixedArray::kHeaderSize + kPointerSize)); |
| 4664 HandleArrayCases(masm, feedback, receiver_map, integer_slot, r14, r15, false, |
| 4665 &miss); |
| 4666 |
4529 __ bind(&miss); | 4667 __ bind(&miss); |
4530 KeyedStoreIC::GenerateMiss(masm); | 4668 KeyedStoreIC::GenerateMiss(masm); |
| 4669 |
| 4670 __ bind(&load_smi_map); |
| 4671 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
| 4672 __ jmp(&compare_map); |
4531 } | 4673 } |
4532 | 4674 |
4533 | 4675 |
4534 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 4676 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
4535 EmitLoadTypeFeedbackVector(masm, rbx); | 4677 EmitLoadTypeFeedbackVector(masm, rbx); |
4536 CallICStub stub(isolate(), state()); | 4678 CallICStub stub(isolate(), state()); |
4537 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 4679 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
4538 } | 4680 } |
4539 | 4681 |
4540 | 4682 |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5483 kStackSpace, nullptr, return_value_operand, NULL); | 5625 kStackSpace, nullptr, return_value_operand, NULL); |
5484 } | 5626 } |
5485 | 5627 |
5486 | 5628 |
5487 #undef __ | 5629 #undef __ |
5488 | 5630 |
5489 } // namespace internal | 5631 } // namespace internal |
5490 } // namespace v8 | 5632 } // namespace v8 |
5491 | 5633 |
5492 #endif // V8_TARGET_ARCH_X64 | 5634 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |