| Index: src/arm64/lithium-codegen-arm64.cc
|
| diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
|
| index 76a9b62c9c1c9b25f1e98b688268746462137c27..df9e7b5ae5f54c96e953b9a03844b0970d653eae 100644
|
| --- a/src/arm64/lithium-codegen-arm64.cc
|
| +++ b/src/arm64/lithium-codegen-arm64.cc
|
| @@ -2042,23 +2042,33 @@ void LCodeGen::DoTailCallThroughMegamorphicCache(
|
| DCHECK(name.is(LoadDescriptor::NameRegister()));
|
| DCHECK(receiver.is(x1));
|
| DCHECK(name.is(x2));
|
| -
|
| - Register scratch = x3;
|
| - Register extra = x4;
|
| - Register extra2 = x5;
|
| - Register extra3 = x6;
|
| + Register scratch = x4;
|
| + Register extra = x5;
|
| + Register extra2 = x6;
|
| + Register extra3 = x7;
|
| + DCHECK(!FLAG_vector_ics ||
|
| + !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()),
|
| + scratch, extra, extra2, extra3));
|
|
|
| // Important for the tail-call.
|
| bool must_teardown_frame = NeedsEagerFrame();
|
|
|
| - // The probe will tail call to a handler if found.
|
| - isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
|
| - must_teardown_frame, receiver, name,
|
| - scratch, extra, extra2, extra3);
|
| + if (!instr->hydrogen()->is_just_miss()) {
|
| + DCHECK(!instr->hydrogen()->is_keyed_load());
|
| +
|
| + // The probe will tail call to a handler if found.
|
| + isolate()->stub_cache()->GenerateProbe(
|
| + masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
|
| + receiver, name, scratch, extra, extra2, extra3);
|
| + }
|
|
|
| // Tail call to miss if we ended up here.
|
| if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
|
| - LoadIC::GenerateMiss(masm());
|
| + if (instr->hydrogen()->is_keyed_load()) {
|
| + KeyedLoadIC::GenerateMiss(masm());
|
| + } else {
|
| + LoadIC::GenerateMiss(masm());
|
| + }
|
| }
|
|
|
|
|
| @@ -2066,25 +2076,44 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
|
| DCHECK(instr->IsMarkedAsCall());
|
| DCHECK(ToRegister(instr->result()).Is(x0));
|
|
|
| - LPointerMap* pointers = instr->pointer_map();
|
| - SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
|
| -
|
| - if (instr->target()->IsConstantOperand()) {
|
| - LConstantOperand* target = LConstantOperand::cast(instr->target());
|
| - Handle<Code> code = Handle<Code>::cast(ToHandle(target));
|
| - generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
|
| - // TODO(all): on ARM we use a call descriptor to specify a storage mode
|
| - // but on ARM64 we only have one storage mode so it isn't necessary. Check
|
| - // this understanding is correct.
|
| - __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
|
| + if (instr->hydrogen()->IsTailCall()) {
|
| + if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL);
|
| +
|
| + if (instr->target()->IsConstantOperand()) {
|
| + LConstantOperand* target = LConstantOperand::cast(instr->target());
|
| + Handle<Code> code = Handle<Code>::cast(ToHandle(target));
|
| + // TODO(all): on ARM we use a call descriptor to specify a storage mode
|
| + // but on ARM64 we only have one storage mode so it isn't necessary. Check
|
| + // this understanding is correct.
|
| + __ Jump(code, RelocInfo::CODE_TARGET);
|
| + } else {
|
| + DCHECK(instr->target()->IsRegister());
|
| + Register target = ToRegister(instr->target());
|
| + __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
|
| + __ Br(target);
|
| + }
|
| } else {
|
| - DCHECK(instr->target()->IsRegister());
|
| - Register target = ToRegister(instr->target());
|
| - generator.BeforeCall(__ CallSize(target));
|
| - __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
|
| - __ Call(target);
|
| + LPointerMap* pointers = instr->pointer_map();
|
| + SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
|
| +
|
| + if (instr->target()->IsConstantOperand()) {
|
| + LConstantOperand* target = LConstantOperand::cast(instr->target());
|
| + Handle<Code> code = Handle<Code>::cast(ToHandle(target));
|
| + generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
|
| + // TODO(all): on ARM we use a call descriptor to specify a storage mode
|
| + // but on ARM64 we only have one storage mode so it isn't necessary. Check
|
| + // this understanding is correct.
|
| + __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
|
| + } else {
|
| + DCHECK(instr->target()->IsRegister());
|
| + Register target = ToRegister(instr->target());
|
| + generator.BeforeCall(__ CallSize(target));
|
| + __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
|
| + __ Call(target);
|
| + }
|
| + generator.AfterCall();
|
| }
|
| - generator.AfterCall();
|
| +
|
| after_push_argument_ = false;
|
| }
|
|
|
| @@ -3367,13 +3396,17 @@ template <class T>
|
| void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
| DCHECK(FLAG_vector_ics);
|
| Register vector_register = ToRegister(instr->temp_vector());
|
| + Register slot_register = VectorLoadICDescriptor::SlotRegister();
|
| DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
|
| + DCHECK(slot_register.is(x0));
|
| +
|
| + AllowDeferredHandleDereference vector_structure_check;
|
| Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
|
| __ Mov(vector_register, vector);
|
| // No need to allocate this register.
|
| - DCHECK(VectorLoadICDescriptor::SlotRegister().is(x0));
|
| - int index = vector->GetIndex(instr->hydrogen()->slot());
|
| - __ Mov(VectorLoadICDescriptor::SlotRegister(), Smi::FromInt(index));
|
| + FeedbackVectorICSlot slot = instr->hydrogen()->slot();
|
| + int index = vector->GetIndex(slot);
|
| + __ Mov(slot_register, Smi::FromInt(index));
|
| }
|
|
|
|
|
|
|