Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 988653003: Use platform specific stubs for vector-based Load/KeyedLoad. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: slot_count = FLAG_vector_ics ? 2 : 1. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
11 #include "src/codegen.h" 11 #include "src/codegen.h"
12 #include "src/ic/handler-compiler.h" 12 #include "src/ic/handler-compiler.h"
13 #include "src/ic/ic.h" 13 #include "src/ic/ic.h"
14 #include "src/ic/stub-cache.h"
14 #include "src/isolate.h" 15 #include "src/isolate.h"
15 #include "src/jsregexp.h" 16 #include "src/jsregexp.h"
16 #include "src/regexp-macro-assembler.h" 17 #include "src/regexp-macro-assembler.h"
17 #include "src/runtime/runtime.h" 18 #include "src/runtime/runtime.h"
18 19
19 namespace v8 { 20 namespace v8 {
20 namespace internal { 21 namespace internal {
21 22
22 23
23 static void InitializeArrayConstructorDescriptor( 24 static void InitializeArrayConstructorDescriptor(
(...skipping 4420 matching lines...) Expand 10 before | Expand all | Expand 10 after
4444 } 4445 }
4445 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); 4446 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4446 __ Drop(x1); 4447 __ Drop(x1);
4447 // Return to IC Miss stub, continuation still on stack. 4448 // Return to IC Miss stub, continuation still on stack.
4448 __ Ret(); 4449 __ Ret();
4449 } 4450 }
4450 4451
4451 4452
4452 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { 4453 void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
4453 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4454 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4454 VectorLoadStub stub(isolate(), state()); 4455 VectorRawLoadStub stub(isolate(), state());
4455 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4456 stub.GenerateForTrampoline(masm);
4456 } 4457 }
4457 4458
4458 4459
4459 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { 4460 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
4460 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4461 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4461 VectorKeyedLoadStub stub(isolate()); 4462 VectorRawKeyedLoadStub stub(isolate());
4462 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4463 stub.GenerateForTrampoline(masm);
4463 } 4464 }
4464 4465
4465 4466
4466 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4467 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4467 EmitLoadTypeFeedbackVector(masm, x2); 4468 EmitLoadTypeFeedbackVector(masm, x2);
4468 CallICStub stub(isolate(), state()); 4469 CallICStub stub(isolate(), state());
4469 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4470 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
4470 } 4471 }
4471 4472
4472 4473
4473 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { 4474 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
4474 EmitLoadTypeFeedbackVector(masm, x2); 4475 EmitLoadTypeFeedbackVector(masm, x2);
4475 CallIC_ArrayStub stub(isolate(), state()); 4476 CallIC_ArrayStub stub(isolate(), state());
4476 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4477 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
4477 } 4478 }
4478 4479
4479 4480
4481 void VectorRawLoadStub::Generate(MacroAssembler* masm) {
4482 GenerateImpl(masm, false);
4483 }
4484
4485
4486 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4487 GenerateImpl(masm, true);
4488 }
4489
4490
4491 static void HandleArrayCases(MacroAssembler* masm, Register receiver,
4492 Register key, Register vector, Register slot,
4493 Register feedback, Register scratch1,
4494 Register scratch2, Register scratch3,
4495 Label* miss) {
4496 // feedback initially contains the feedback array
4497 Label next, next_loop, prepare_next;
4498 Label load_smi_map, compare_map;
4499
4500 Register receiver_map = scratch1;
4501 Register array_map = scratch2;
4502
4503 // Receiver might not be a heap object.
4504 __ JumpIfSmi(receiver, &load_smi_map);
4505 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4506 __ Bind(&compare_map);
4507 __ Ldr(array_map,
4508 FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4509 __ Ldr(array_map, FieldMemOperand(array_map, WeakCell::kValueOffset));
4510 __ Cmp(receiver_map, array_map);
4511 __ B(ne, &next);
4512 // found, now call handler.
4513 __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4514 __ Add(feedback, feedback, Code::kHeaderSize - kHeapObjectTag);
4515 __ Jump(feedback);
4516
4517 Register length = scratch3;
4518 __ Bind(&next);
4519 __ Ldr(length, FieldMemOperand(feedback, FixedArray::kLengthOffset));
4520 __ Cmp(length, Operand(Smi::FromInt(2)));
4521 Label start_polymorphic;
4522 __ B(ne, &start_polymorphic);
4523 __ jmp(miss);
4524
4525 Register too_far = length;
4526 Register pointer_reg = feedback;
4527
4528 // +-----+------+------+-----+-----+ ... ----+
4529 // | map | len | wm0 | h0 | wm1 | hN |
4530 // +-----+------+------+-----+-----+ ... ----+
4531 // 0 1 2 len-1
4532 // ^ ^
4533 // | |
4534 // pointer_reg too_far
4535 // aka feedback scratch3
4536 // also need receiver_map (aka scratch1)
4537 // use array_map (scratch2) to look in the weak map values.
4538 __ Bind(&start_polymorphic);
4539 __ Add(too_far, feedback,
4540 Operand::UntagSmiAndScale(length, kPointerSizeLog2));
4541 __ Add(too_far, too_far, FixedArray::kHeaderSize - kHeapObjectTag);
4542 __ Add(pointer_reg, feedback,
4543 FixedArray::OffsetOfElementAt(2) - kHeapObjectTag);
4544
4545 __ Bind(&next_loop);
4546 __ Ldr(array_map, MemOperand(pointer_reg));
4547 __ Ldr(array_map, FieldMemOperand(array_map, WeakCell::kValueOffset));
4548 __ Cmp(receiver_map, array_map);
4549 __ B(ne, &prepare_next);
4550 __ Ldr(array_map, MemOperand(pointer_reg, kPointerSize));
4551 __ Add(array_map, array_map, Code::kHeaderSize - kHeapObjectTag);
4552 __ Jump(array_map);
4553
4554 __ Bind(&prepare_next);
4555 __ Add(pointer_reg, pointer_reg, kPointerSize * 2);
4556 __ Cmp(pointer_reg, too_far);
4557 __ B(lt, &next_loop);
4558
4559 // We exhausted our array of map handler pairs.
4560 __ jmp(miss);
4561
4562 __ Bind(&load_smi_map);
4563 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4564 __ jmp(&compare_map);
4565 }
4566
4567
4568 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver,
4569 Register key, Register vector, Register slot,
4570 Register weak_cell, Register scratch,
4571 Label* miss) {
4572 // feedback initially contains the feedback array
4573 Label compare_smi_map;
4574
4575 Register receiver_map = scratch;
4576
4577 // Move the weak map into the weak_cell register.
4578 __ Ldr(weak_cell, FieldMemOperand(weak_cell, WeakCell::kValueOffset));
4579
4580 // Receiver might not be a heap object.
4581 __ JumpIfSmi(receiver, &compare_smi_map);
4582 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4583 __ Cmp(weak_cell, receiver_map);
4584 __ B(ne, miss);
4585 __ Add(weak_cell, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4586 __ Ldr(weak_cell,
4587 FieldMemOperand(weak_cell, FixedArray::kHeaderSize + kPointerSize));
4588 __ Add(weak_cell, weak_cell, Code::kHeaderSize - kHeapObjectTag);
4589 __ Jump(weak_cell);
4590
4591 // In microbenchmarks, it made sense to unroll this code so that the call to
4592 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4593 // TODO(mvstanton): does this hold on ARM?
4594 __ Bind(&compare_smi_map);
4595 __ JumpIfNotRoot(weak_cell, Heap::kHeapNumberMapRootIndex, miss);
4596 __ Add(weak_cell, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4597 __ Ldr(weak_cell,
4598 FieldMemOperand(weak_cell, FixedArray::kHeaderSize + kPointerSize));
4599 __ Add(weak_cell, weak_cell, Code::kHeaderSize - kHeapObjectTag);
4600 __ Jump(weak_cell);
4601 }
4602
4603
4604 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4605 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // x1
4606 Register name = VectorLoadICDescriptor::NameRegister(); // x2
4607 Register vector = VectorLoadICDescriptor::VectorRegister(); // x3
4608 Register slot = VectorLoadICDescriptor::SlotRegister(); // x0
4609 Register feedback = x4;
4610 Register scratch1 = x5;
4611
4612 __ Add(feedback, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4613 __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4614
4615 // Is it a weak cell?
4616 Label try_array;
4617 Label not_array, smi_key, key_okay, miss;
4618 __ Ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4619 __ JumpIfNotRoot(scratch1, Heap::kWeakCellMapRootIndex, &try_array);
4620 HandleMonomorphicCase(masm, receiver, name, vector, slot, feedback, scratch1,
4621 &miss);
4622 __ Unreachable();
4623
4624 // Is it a fixed array?
4625 __ Bind(&try_array);
4626 __ JumpIfNotRoot(scratch1, Heap::kFixedArrayMapRootIndex, &not_array);
4627 HandleArrayCases(masm, receiver, name, vector, slot, feedback, scratch1, x6,
4628 x7, &miss);
4629 __ Unreachable();
4630
4631 __ Bind(&not_array);
4632 __ JumpIfNotRoot(feedback, Heap::kmegamorphic_symbolRootIndex, &miss);
4633 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4634 Code::ComputeHandlerFlags(Code::LOAD_IC));
4635 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, code_flags,
4636 false, receiver, name, feedback,
4637 scratch1, x6, x7);
4638
4639 __ Bind(&miss);
4640 LoadIC::GenerateMiss(masm);
4641 }
4642
4643
4644 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) {
4645 GenerateImpl(masm, false);
4646 }
4647
4648
4649 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4650 GenerateImpl(masm, true);
4651 }
4652
4653
4654 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4655 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // x1
4656 Register key = VectorLoadICDescriptor::NameRegister(); // x2
4657 Register vector = VectorLoadICDescriptor::VectorRegister(); // x3
4658 Register slot = VectorLoadICDescriptor::SlotRegister(); // x0
4659 Register feedback = x4;
4660 Register scratch1 = x5;
4661
4662 __ Add(feedback, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4663 __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4664
4665 // Is it a weak cell?
4666 Label try_array;
4667 Label not_array, smi_key, key_okay, miss;
4668 __ Ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4669 __ JumpIfNotRoot(scratch1, Heap::kWeakCellMapRootIndex, &try_array);
4670 __ JumpIfNotSmi(key, &miss);
4671 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, scratch1,
4672 &miss);
4673 __ Unreachable();
4674
4675 __ Bind(&try_array);
4676 // Is it a fixed array?
4677 __ JumpIfNotRoot(scratch1, Heap::kFixedArrayMapRootIndex, &not_array);
4678 // We have a polymorphic element handler.
4679 __ JumpIfNotSmi(key, &miss);
4680
4681 Label polymorphic, try_poly_name;
4682 __ Bind(&polymorphic);
4683 HandleArrayCases(masm, receiver, key, vector, slot, feedback, scratch1, x6,
4684 x7, &miss);
4685 __ Unreachable();
4686
4687 __ Bind(&not_array);
4688 // Is it generic?
4689 __ JumpIfNotRoot(feedback, Heap::kmegamorphic_symbolRootIndex,
4690 &try_poly_name);
4691 Handle<Code> megamorphic_stub =
4692 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
4693 __ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
4694
4695 __ Bind(&try_poly_name);
4696 // We might have a name in scratch, and a fixed array in the next slot.
4697 __ Cmp(key, scratch1);
4698 __ B(ne, &miss);
4699 // If the name comparison succeeded, we know we have a fixed array with
4700 // at least one map/handler pair.
4701 __ Add(feedback, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4702 __ Ldr(feedback,
4703 FieldMemOperand(feedback, FixedArray::kHeaderSize + kPointerSize));
4704 __ jmp(&polymorphic);
4705
4706 __ Bind(&miss);
4707 KeyedLoadIC::GenerateMiss(masm);
4708 }
4709
4710
4480 // The entry hook is a "BumpSystemStackPointer" instruction (sub), followed by 4711 // The entry hook is a "BumpSystemStackPointer" instruction (sub), followed by
4481 // a "Push lr" instruction, followed by a call. 4712 // a "Push lr" instruction, followed by a call.
4482 static const unsigned int kProfileEntryHookCallSize = 4713 static const unsigned int kProfileEntryHookCallSize =
4483 Assembler::kCallSizeWithRelocation + (2 * kInstructionSize); 4714 Assembler::kCallSizeWithRelocation + (2 * kInstructionSize);
4484 4715
4485 4716
4486 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4717 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4487 if (masm->isolate()->function_entry_hook() != NULL) { 4718 if (masm->isolate()->function_entry_hook() != NULL) {
4488 ProfileEntryHookStub stub(masm->isolate()); 4719 ProfileEntryHookStub stub(masm->isolate());
4489 Assembler::BlockConstPoolScope no_const_pools(masm); 4720 Assembler::BlockConstPoolScope no_const_pools(masm);
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after
5518 kStackUnwindSpace, NULL, spill_offset, 5749 kStackUnwindSpace, NULL, spill_offset,
5519 MemOperand(fp, 6 * kPointerSize), NULL); 5750 MemOperand(fp, 6 * kPointerSize), NULL);
5520 } 5751 }
5521 5752
5522 5753
5523 #undef __ 5754 #undef __
5524 5755
5525 } } // namespace v8::internal 5756 } } // namespace v8::internal
5526 5757
5527 #endif // V8_TARGET_ARCH_ARM64 5758 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/code-stubs.h » ('j') | src/code-stubs-hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698