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