| 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 |