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 |