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

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: Included the MIPs port from Paul and Akos. 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
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 bool is_polymorphic, Label* miss) {
4496 // feedback initially contains the feedback array
4497 Label next_loop, prepare_next;
4498 Label load_smi_map, compare_map;
4499 Label start_polymorphic;
4500
4501 Register receiver_map = scratch1;
4502 Register cached_map = scratch2;
4503
4504 // Receiver might not be a heap object.
4505 __ JumpIfSmi(receiver, &load_smi_map);
4506 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4507 __ Bind(&compare_map);
4508 __ Ldr(cached_map,
4509 FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4510 __ Ldr(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset));
4511 __ Cmp(receiver_map, cached_map);
4512 __ B(ne, &start_polymorphic);
4513 // found, now call handler.
4514 Register handler = feedback;
4515 __ Ldr(handler, FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4516 __ Add(handler, handler, Code::kHeaderSize - kHeapObjectTag);
4517 __ Jump(feedback);
4518
4519 Register length = scratch3;
4520 __ Bind(&start_polymorphic);
4521 __ Ldr(length, FieldMemOperand(feedback, FixedArray::kLengthOffset));
4522 if (!is_polymorphic) {
4523 __ Cmp(length, Operand(Smi::FromInt(2)));
4524 __ B(eq, miss);
4525 }
4526
4527 Register too_far = length;
4528 Register pointer_reg = feedback;
4529
4530 // +-----+------+------+-----+-----+ ... ----+
4531 // | map | len | wm0 | h0 | wm1 | hN |
4532 // +-----+------+------+-----+-----+ ... ----+
4533 // 0 1 2 len-1
4534 // ^ ^
4535 // | |
4536 // pointer_reg too_far
4537 // aka feedback scratch3
4538 // also need receiver_map (aka scratch1)
4539 // use cached_map (scratch2) to look in the weak map values.
4540 __ Add(too_far, feedback,
4541 Operand::UntagSmiAndScale(length, kPointerSizeLog2));
4542 __ Add(too_far, too_far, FixedArray::kHeaderSize - kHeapObjectTag);
4543 __ Add(pointer_reg, feedback,
4544 FixedArray::OffsetOfElementAt(2) - kHeapObjectTag);
4545
4546 __ Bind(&next_loop);
4547 __ Ldr(cached_map, MemOperand(pointer_reg));
4548 __ Ldr(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset));
4549 __ Cmp(receiver_map, cached_map);
4550 __ B(ne, &prepare_next);
4551 __ Ldr(handler, MemOperand(pointer_reg, kPointerSize));
4552 __ Add(handler, handler, Code::kHeaderSize - kHeapObjectTag);
4553 __ Jump(handler);
4554
4555 __ Bind(&prepare_next);
4556 __ Add(pointer_reg, pointer_reg, kPointerSize * 2);
4557 __ Cmp(pointer_reg, too_far);
4558 __ B(lt, &next_loop);
4559
4560 // We exhausted our array of map handler pairs.
4561 __ jmp(miss);
4562
4563 __ Bind(&load_smi_map);
4564 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4565 __ jmp(&compare_map);
4566 }
4567
4568
4569 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver,
4570 Register key, Register vector, Register slot,
4571 Register weak_cell, Register scratch,
4572 Label* miss) {
4573 // feedback initially contains the feedback array
4574 Label compare_smi_map;
4575 Register receiver_map = scratch;
4576 Register cached_map = weak_cell;
4577
4578 // Move the weak map into the weak_cell register.
4579 __ Ldr(cached_map, FieldMemOperand(weak_cell, WeakCell::kValueOffset));
4580
4581 // Receiver might not be a heap object.
4582 __ JumpIfSmi(receiver, &compare_smi_map);
4583 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4584 __ Cmp(cached_map, receiver_map);
4585 __ B(ne, miss);
4586
4587 Register handler = weak_cell;
4588 __ Add(handler, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4589 __ Ldr(handler,
4590 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize));
4591 __ Add(handler, handler, Code::kHeaderSize - kHeapObjectTag);
4592 __ Jump(weak_cell);
4593
4594 // In microbenchmarks, it made sense to unroll this code so that the call to
4595 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4596 // TODO(mvstanton): does this hold on ARM?
4597 __ Bind(&compare_smi_map);
4598 __ JumpIfNotRoot(weak_cell, Heap::kHeapNumberMapRootIndex, miss);
4599 __ Add(handler, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4600 __ Ldr(handler,
4601 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize));
4602 __ Add(handler, handler, Code::kHeaderSize - kHeapObjectTag);
4603 __ Jump(handler);
4604 }
4605
4606
4607 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4608 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // x1
4609 Register name = VectorLoadICDescriptor::NameRegister(); // x2
4610 Register vector = VectorLoadICDescriptor::VectorRegister(); // x3
4611 Register slot = VectorLoadICDescriptor::SlotRegister(); // x0
4612 Register feedback = x4;
4613 Register scratch1 = x5;
4614
4615 __ Add(feedback, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4616 __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4617
4618 // Is it a weak cell?
4619 Label try_array;
4620 Label not_array, smi_key, key_okay, miss;
4621 __ Ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4622 __ JumpIfNotRoot(scratch1, Heap::kWeakCellMapRootIndex, &try_array);
4623 HandleMonomorphicCase(masm, receiver, name, vector, slot, feedback, scratch1,
4624 &miss);
4625
4626 // Is it a fixed array?
4627 __ Bind(&try_array);
4628 __ JumpIfNotRoot(scratch1, Heap::kFixedArrayMapRootIndex, &not_array);
4629 HandleArrayCases(masm, receiver, name, vector, slot, feedback, scratch1, x6,
4630 x7, true, &miss);
4631
4632 __ Bind(&not_array);
4633 __ JumpIfNotRoot(feedback, Heap::kmegamorphic_symbolRootIndex, &miss);
4634 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4635 Code::ComputeHandlerFlags(Code::LOAD_IC));
4636 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, code_flags,
4637 false, receiver, name, feedback,
4638 scratch1, x6, x7);
4639
4640 __ Bind(&miss);
4641 LoadIC::GenerateMiss(masm);
4642 }
4643
4644
4645 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) {
4646 GenerateImpl(masm, false);
4647 }
4648
4649
4650 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4651 GenerateImpl(masm, true);
4652 }
4653
4654
4655 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4656 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // x1
4657 Register key = VectorLoadICDescriptor::NameRegister(); // x2
4658 Register vector = VectorLoadICDescriptor::VectorRegister(); // x3
4659 Register slot = VectorLoadICDescriptor::SlotRegister(); // x0
4660 Register feedback = x4;
4661 Register scratch1 = x5;
4662
4663 __ Add(feedback, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4664 __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4665
4666 // Is it a weak cell?
4667 Label try_array;
4668 Label not_array, smi_key, key_okay, miss;
4669 __ Ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4670 __ JumpIfNotRoot(scratch1, Heap::kWeakCellMapRootIndex, &try_array);
4671 __ JumpIfNotSmi(key, &miss);
4672 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, scratch1,
4673 &miss);
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, true, &miss);
4685
4686 __ Bind(&not_array);
4687 // Is it generic?
4688 __ JumpIfNotRoot(feedback, Heap::kmegamorphic_symbolRootIndex,
4689 &try_poly_name);
4690 Handle<Code> megamorphic_stub =
4691 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
4692 __ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
4693
4694 __ Bind(&try_poly_name);
4695 // We might have a name in feedback, and a fixed array in the next slot.
4696 __ Cmp(key, feedback);
4697 __ B(ne, &miss);
4698 // If the name comparison succeeded, we know we have a fixed array with
4699 // at least one map/handler pair.
4700 __ Add(feedback, vector, Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
4701 __ Ldr(feedback,
4702 FieldMemOperand(feedback, FixedArray::kHeaderSize + kPointerSize));
4703 HandleArrayCases(masm, receiver, key, vector, slot, feedback, scratch1, x6,
4704 x7, false, &miss);
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 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
5514 kStackUnwindSpace, NULL, spill_offset, 5745 kStackUnwindSpace, NULL, spill_offset,
5515 MemOperand(fp, 6 * kPointerSize), NULL); 5746 MemOperand(fp, 6 * kPointerSize), NULL);
5516 } 5747 }
5517 5748
5518 5749
5519 #undef __ 5750 #undef __
5520 5751
5521 } } // namespace v8::internal 5752 } } // namespace v8::internal
5522 5753
5523 #endif // V8_TARGET_ARCH_ARM64 5754 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698