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 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // rdx | 4507 Label miss; |
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)); | |
4516 | 4508 |
4517 __ SmiToInteger32(integer_slot, slot); | 4509 // TODO(mvstanton): Implement. |
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 | |
4545 __ bind(&miss); | 4510 __ bind(&miss); |
4546 StoreIC::GenerateMiss(masm); | 4511 StoreIC::GenerateMiss(masm); |
4547 | |
4548 __ bind(&load_smi_map); | |
4549 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | |
4550 __ jmp(&compare_map); | |
4551 } | 4512 } |
4552 | 4513 |
4553 | 4514 |
4554 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { | 4515 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { |
4555 GenerateImpl(masm, false); | 4516 GenerateImpl(masm, false); |
4556 } | 4517 } |
4557 | 4518 |
4558 | 4519 |
4559 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4520 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
4560 GenerateImpl(masm, true); | 4521 GenerateImpl(masm, true); |
4561 } | 4522 } |
4562 | 4523 |
4563 | 4524 |
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 | |
4617 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4525 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
4618 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // rdx | 4526 Label miss; |
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)); | |
4627 | 4527 |
4628 __ SmiToInteger32(integer_slot, slot); | 4528 // TODO(mvstanton): Implement. |
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 | |
4667 __ bind(&miss); | 4529 __ bind(&miss); |
4668 KeyedStoreIC::GenerateMiss(masm); | 4530 KeyedStoreIC::GenerateMiss(masm); |
4669 | |
4670 __ bind(&load_smi_map); | |
4671 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | |
4672 __ jmp(&compare_map); | |
4673 } | 4531 } |
4674 | 4532 |
4675 | 4533 |
4676 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 4534 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
4677 EmitLoadTypeFeedbackVector(masm, rbx); | 4535 EmitLoadTypeFeedbackVector(masm, rbx); |
4678 CallICStub stub(isolate(), state()); | 4536 CallICStub stub(isolate(), state()); |
4679 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 4537 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
4680 } | 4538 } |
4681 | 4539 |
4682 | 4540 |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5625 kStackSpace, nullptr, return_value_operand, NULL); | 5483 kStackSpace, nullptr, return_value_operand, NULL); |
5626 } | 5484 } |
5627 | 5485 |
5628 | 5486 |
5629 #undef __ | 5487 #undef __ |
5630 | 5488 |
5631 } // namespace internal | 5489 } // namespace internal |
5632 } // namespace v8 | 5490 } // namespace v8 |
5633 | 5491 |
5634 #endif // V8_TARGET_ARCH_X64 | 5492 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |