| 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 #include "src/v8.h" |     5 #include "src/v8.h" | 
|     6  |     6  | 
|     7 #include "src/arm64/lithium-codegen-arm64.h" |     7 #include "src/arm64/lithium-codegen-arm64.h" | 
|     8 #include "src/arm64/lithium-gap-resolver-arm64.h" |     8 #include "src/arm64/lithium-gap-resolver-arm64.h" | 
|     9 #include "src/base/bits.h" |     9 #include "src/base/bits.h" | 
|    10 #include "src/code-factory.h" |    10 #include "src/code-factory.h" | 
| (...skipping 2024 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2035  |  2035  | 
|  2036  |  2036  | 
|  2037 void LCodeGen::DoTailCallThroughMegamorphicCache( |  2037 void LCodeGen::DoTailCallThroughMegamorphicCache( | 
|  2038     LTailCallThroughMegamorphicCache* instr) { |  2038     LTailCallThroughMegamorphicCache* instr) { | 
|  2039   Register receiver = ToRegister(instr->receiver()); |  2039   Register receiver = ToRegister(instr->receiver()); | 
|  2040   Register name = ToRegister(instr->name()); |  2040   Register name = ToRegister(instr->name()); | 
|  2041   DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |  2041   DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 
|  2042   DCHECK(name.is(LoadDescriptor::NameRegister())); |  2042   DCHECK(name.is(LoadDescriptor::NameRegister())); | 
|  2043   DCHECK(receiver.is(x1)); |  2043   DCHECK(receiver.is(x1)); | 
|  2044   DCHECK(name.is(x2)); |  2044   DCHECK(name.is(x2)); | 
|  2045  |  2045   Register scratch = x4; | 
|  2046   Register scratch = x3; |  2046   Register extra = x5; | 
|  2047   Register extra = x4; |  2047   Register extra2 = x6; | 
|  2048   Register extra2 = x5; |  2048   Register extra3 = x7; | 
|  2049   Register extra3 = x6; |  2049   DCHECK(!FLAG_vector_ics || | 
 |  2050          !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()), | 
 |  2051                      scratch, extra, extra2, extra3)); | 
|  2050  |  2052  | 
|  2051   // Important for the tail-call. |  2053   // Important for the tail-call. | 
|  2052   bool must_teardown_frame = NeedsEagerFrame(); |  2054   bool must_teardown_frame = NeedsEagerFrame(); | 
|  2053  |  2055  | 
|  2054   // The probe will tail call to a handler if found. |  2056   if (!instr->hydrogen()->is_just_miss()) { | 
|  2055   isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), |  2057     DCHECK(!instr->hydrogen()->is_keyed_load()); | 
|  2056                                          must_teardown_frame, receiver, name, |  2058  | 
|  2057                                          scratch, extra, extra2, extra3); |  2059     // The probe will tail call to a handler if found. | 
 |  2060     isolate()->stub_cache()->GenerateProbe( | 
 |  2061         masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, | 
 |  2062         receiver, name, scratch, extra, extra2, extra3); | 
 |  2063   } | 
|  2058  |  2064  | 
|  2059   // Tail call to miss if we ended up here. |  2065   // Tail call to miss if we ended up here. | 
|  2060   if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); |  2066   if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL); | 
|  2061   LoadIC::GenerateMiss(masm()); |  2067   if (instr->hydrogen()->is_keyed_load()) { | 
 |  2068     KeyedLoadIC::GenerateMiss(masm()); | 
 |  2069   } else { | 
 |  2070     LoadIC::GenerateMiss(masm()); | 
 |  2071   } | 
|  2062 } |  2072 } | 
|  2063  |  2073  | 
|  2064  |  2074  | 
|  2065 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |  2075 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 
|  2066   DCHECK(instr->IsMarkedAsCall()); |  2076   DCHECK(instr->IsMarkedAsCall()); | 
|  2067   DCHECK(ToRegister(instr->result()).Is(x0)); |  2077   DCHECK(ToRegister(instr->result()).Is(x0)); | 
|  2068  |  2078  | 
|  2069   LPointerMap* pointers = instr->pointer_map(); |  2079   if (instr->hydrogen()->IsTailCall()) { | 
|  2070   SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |  2080     if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); | 
|  2071  |  2081  | 
|  2072   if (instr->target()->IsConstantOperand()) { |  2082     if (instr->target()->IsConstantOperand()) { | 
|  2073     LConstantOperand* target = LConstantOperand::cast(instr->target()); |  2083       LConstantOperand* target = LConstantOperand::cast(instr->target()); | 
|  2074     Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |  2084       Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 
|  2075     generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |  2085       // TODO(all): on ARM we use a call descriptor to specify a storage mode | 
|  2076     // TODO(all): on ARM we use a call descriptor to specify a storage mode |  2086       // but on ARM64 we only have one storage mode so it isn't necessary. Check | 
|  2077     // but on ARM64 we only have one storage mode so it isn't necessary. Check |  2087       // this understanding is correct. | 
|  2078     // this understanding is correct. |  2088       __ Jump(code, RelocInfo::CODE_TARGET); | 
|  2079     __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None()); |  2089     } else { | 
 |  2090       DCHECK(instr->target()->IsRegister()); | 
 |  2091       Register target = ToRegister(instr->target()); | 
 |  2092       __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); | 
 |  2093       __ Br(target); | 
 |  2094     } | 
|  2080   } else { |  2095   } else { | 
|  2081     DCHECK(instr->target()->IsRegister()); |  2096     LPointerMap* pointers = instr->pointer_map(); | 
|  2082     Register target = ToRegister(instr->target()); |  2097     SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 
|  2083     generator.BeforeCall(__ CallSize(target)); |  2098  | 
|  2084     __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); |  2099     if (instr->target()->IsConstantOperand()) { | 
|  2085     __ Call(target); |  2100       LConstantOperand* target = LConstantOperand::cast(instr->target()); | 
 |  2101       Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 
 |  2102       generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 
 |  2103       // TODO(all): on ARM we use a call descriptor to specify a storage mode | 
 |  2104       // but on ARM64 we only have one storage mode so it isn't necessary. Check | 
 |  2105       // this understanding is correct. | 
 |  2106       __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None()); | 
 |  2107     } else { | 
 |  2108       DCHECK(instr->target()->IsRegister()); | 
 |  2109       Register target = ToRegister(instr->target()); | 
 |  2110       generator.BeforeCall(__ CallSize(target)); | 
 |  2111       __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); | 
 |  2112       __ Call(target); | 
 |  2113     } | 
 |  2114     generator.AfterCall(); | 
|  2086   } |  2115   } | 
|  2087   generator.AfterCall(); |  2116  | 
|  2088   after_push_argument_ = false; |  2117   after_push_argument_ = false; | 
|  2089 } |  2118 } | 
|  2090  |  2119  | 
|  2091  |  2120  | 
|  2092 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |  2121 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 
|  2093   DCHECK(instr->IsMarkedAsCall()); |  2122   DCHECK(instr->IsMarkedAsCall()); | 
|  2094   DCHECK(ToRegister(instr->function()).is(x1)); |  2123   DCHECK(ToRegister(instr->function()).is(x1)); | 
|  2095  |  2124  | 
|  2096   if (instr->hydrogen()->pass_argument_count()) { |  2125   if (instr->hydrogen()->pass_argument_count()) { | 
|  2097     __ Mov(x0, Operand(instr->arity())); |  2126     __ Mov(x0, Operand(instr->arity())); | 
| (...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3360   if (instr->hydrogen()->RequiresHoleCheck()) { |  3389   if (instr->hydrogen()->RequiresHoleCheck()) { | 
|  3361     DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole"); |  3390     DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole"); | 
|  3362   } |  3391   } | 
|  3363 } |  3392 } | 
|  3364  |  3393  | 
|  3365  |  3394  | 
|  3366 template <class T> |  3395 template <class T> | 
|  3367 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |  3396 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 
|  3368   DCHECK(FLAG_vector_ics); |  3397   DCHECK(FLAG_vector_ics); | 
|  3369   Register vector_register = ToRegister(instr->temp_vector()); |  3398   Register vector_register = ToRegister(instr->temp_vector()); | 
 |  3399   Register slot_register = VectorLoadICDescriptor::SlotRegister(); | 
|  3370   DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |  3400   DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 
 |  3401   DCHECK(slot_register.is(x0)); | 
 |  3402  | 
 |  3403   AllowDeferredHandleDereference vector_structure_check; | 
|  3371   Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |  3404   Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 
|  3372   __ Mov(vector_register, vector); |  3405   __ Mov(vector_register, vector); | 
|  3373   // No need to allocate this register. |  3406   // No need to allocate this register. | 
|  3374   DCHECK(VectorLoadICDescriptor::SlotRegister().is(x0)); |  3407   FeedbackVectorICSlot slot = instr->hydrogen()->slot(); | 
|  3375   int index = vector->GetIndex(instr->hydrogen()->slot()); |  3408   int index = vector->GetIndex(slot); | 
|  3376   __ Mov(VectorLoadICDescriptor::SlotRegister(), Smi::FromInt(index)); |  3409   __ Mov(slot_register, Smi::FromInt(index)); | 
|  3377 } |  3410 } | 
|  3378  |  3411  | 
|  3379  |  3412  | 
|  3380 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |  3413 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 
|  3381   DCHECK(ToRegister(instr->context()).is(cp)); |  3414   DCHECK(ToRegister(instr->context()).is(cp)); | 
|  3382   DCHECK(ToRegister(instr->global_object()) |  3415   DCHECK(ToRegister(instr->global_object()) | 
|  3383              .is(LoadDescriptor::ReceiverRegister())); |  3416              .is(LoadDescriptor::ReceiverRegister())); | 
|  3384   DCHECK(ToRegister(instr->result()).Is(x0)); |  3417   DCHECK(ToRegister(instr->result()).Is(x0)); | 
|  3385   __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name())); |  3418   __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name())); | 
|  3386   if (FLAG_vector_ics) { |  3419   if (FLAG_vector_ics) { | 
| (...skipping 2656 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6043   Handle<ScopeInfo> scope_info = instr->scope_info(); |  6076   Handle<ScopeInfo> scope_info = instr->scope_info(); | 
|  6044   __ Push(scope_info); |  6077   __ Push(scope_info); | 
|  6045   __ Push(ToRegister(instr->function())); |  6078   __ Push(ToRegister(instr->function())); | 
|  6046   CallRuntime(Runtime::kPushBlockContext, 2, instr); |  6079   CallRuntime(Runtime::kPushBlockContext, 2, instr); | 
|  6047   RecordSafepoint(Safepoint::kNoLazyDeopt); |  6080   RecordSafepoint(Safepoint::kNoLazyDeopt); | 
|  6048 } |  6081 } | 
|  6049  |  6082  | 
|  6050  |  6083  | 
|  6051  |  6084  | 
|  6052 } }  // namespace v8::internal |  6085 } }  // namespace v8::internal | 
| OLD | NEW |