| 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 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2015 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 2015 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 2016 } else { | 2016 } else { |
| 2017 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 2017 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 2018 ParameterCount count(arity); | 2018 ParameterCount count(arity); |
| 2019 ParameterCount expected(formal_parameter_count); | 2019 ParameterCount expected(formal_parameter_count); |
| 2020 __ InvokeFunction(function_reg, expected, count, CALL_FUNCTION, generator); | 2020 __ InvokeFunction(function_reg, expected, count, CALL_FUNCTION, generator); |
| 2021 } | 2021 } |
| 2022 } | 2022 } |
| 2023 | 2023 |
| 2024 | 2024 |
| 2025 void LCodeGen::DoTailCallThroughMegamorphicCache( | |
| 2026 LTailCallThroughMegamorphicCache* instr) { | |
| 2027 Register receiver = ToRegister(instr->receiver()); | |
| 2028 Register name = ToRegister(instr->name()); | |
| 2029 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | |
| 2030 DCHECK(name.is(LoadDescriptor::NameRegister())); | |
| 2031 DCHECK(receiver.is(x1)); | |
| 2032 DCHECK(name.is(x2)); | |
| 2033 Register scratch = x4; | |
| 2034 Register extra = x5; | |
| 2035 Register extra2 = x6; | |
| 2036 Register extra3 = x7; | |
| 2037 | |
| 2038 // The probe will tail call to a handler if found. | |
| 2039 isolate()->stub_cache()->GenerateProbe( | |
| 2040 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), false, receiver, name, | |
| 2041 scratch, extra, extra2, extra3); | |
| 2042 | |
| 2043 // Tail call to miss if we ended up here. | |
| 2044 LoadIC::GenerateMiss(masm()); | |
| 2045 } | |
| 2046 | |
| 2047 | |
| 2048 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 2025 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 2049 DCHECK(instr->IsMarkedAsCall()); | 2026 DCHECK(instr->IsMarkedAsCall()); |
| 2050 DCHECK(ToRegister(instr->result()).Is(x0)); | 2027 DCHECK(ToRegister(instr->result()).Is(x0)); |
| 2051 | 2028 |
| 2052 if (instr->hydrogen()->IsTailCall()) { | 2029 if (instr->hydrogen()->IsTailCall()) { |
| 2053 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); | 2030 if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL); |
| 2054 | 2031 |
| 2055 if (instr->target()->IsConstantOperand()) { | 2032 if (instr->target()->IsConstantOperand()) { |
| 2056 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 2033 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 2057 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 2034 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| (...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3356 // Get the prototype from the initial map. | 3333 // Get the prototype from the initial map. |
| 3357 __ Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); | 3334 __ Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); |
| 3358 | 3335 |
| 3359 // All done. | 3336 // All done. |
| 3360 __ Bind(&done); | 3337 __ Bind(&done); |
| 3361 } | 3338 } |
| 3362 | 3339 |
| 3363 | 3340 |
| 3364 template <class T> | 3341 template <class T> |
| 3365 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 3342 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 3366 DCHECK(FLAG_vector_ics); | |
| 3367 Register vector_register = ToRegister(instr->temp_vector()); | 3343 Register vector_register = ToRegister(instr->temp_vector()); |
| 3368 Register slot_register = VectorLoadICDescriptor::SlotRegister(); | 3344 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 3369 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 3345 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 3370 DCHECK(slot_register.is(x0)); | 3346 DCHECK(slot_register.is(x0)); |
| 3371 | 3347 |
| 3372 AllowDeferredHandleDereference vector_structure_check; | 3348 AllowDeferredHandleDereference vector_structure_check; |
| 3373 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 3349 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 3374 __ Mov(vector_register, vector); | 3350 __ Mov(vector_register, vector); |
| 3375 // No need to allocate this register. | 3351 // No need to allocate this register. |
| 3376 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); | 3352 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 3377 int index = vector->GetIndex(slot); | 3353 int index = vector->GetIndex(slot); |
| 3378 __ Mov(slot_register, Smi::FromInt(index)); | 3354 __ Mov(slot_register, Smi::FromInt(index)); |
| 3379 } | 3355 } |
| 3380 | 3356 |
| 3381 | 3357 |
| 3382 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 3358 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 3383 DCHECK(ToRegister(instr->context()).is(cp)); | 3359 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3384 DCHECK(ToRegister(instr->global_object()) | 3360 DCHECK(ToRegister(instr->global_object()) |
| 3385 .is(LoadDescriptor::ReceiverRegister())); | 3361 .is(LoadDescriptor::ReceiverRegister())); |
| 3386 DCHECK(ToRegister(instr->result()).Is(x0)); | 3362 DCHECK(ToRegister(instr->result()).Is(x0)); |
| 3387 __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name())); | 3363 __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| 3388 if (FLAG_vector_ics) { | 3364 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); |
| 3389 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); | |
| 3390 } | |
| 3391 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; | 3365 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; |
| 3392 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, | 3366 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, |
| 3393 PREMONOMORPHIC).code(); | 3367 PREMONOMORPHIC).code(); |
| 3394 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3368 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3395 } | 3369 } |
| 3396 | 3370 |
| 3397 | 3371 |
| 3398 MemOperand LCodeGen::PrepareKeyedExternalArrayOperand( | 3372 MemOperand LCodeGen::PrepareKeyedExternalArrayOperand( |
| 3399 Register key, | 3373 Register key, |
| 3400 Register base, | 3374 Register base, |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3707 __ Load(result, FieldMemOperand(source, offset), access.representation()); | 3681 __ Load(result, FieldMemOperand(source, offset), access.representation()); |
| 3708 } | 3682 } |
| 3709 } | 3683 } |
| 3710 | 3684 |
| 3711 | 3685 |
| 3712 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3686 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 3713 DCHECK(ToRegister(instr->context()).is(cp)); | 3687 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3714 // LoadIC expects name and receiver in registers. | 3688 // LoadIC expects name and receiver in registers. |
| 3715 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3689 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3716 __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name())); | 3690 __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| 3717 if (FLAG_vector_ics) { | 3691 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); |
| 3718 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); | |
| 3719 } | |
| 3720 | 3692 |
| 3721 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( | 3693 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( |
| 3722 isolate(), NOT_CONTEXTUAL, | 3694 isolate(), NOT_CONTEXTUAL, |
| 3723 instr->hydrogen()->initialization_state()).code(); | 3695 instr->hydrogen()->initialization_state()).code(); |
| 3724 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3696 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3725 | 3697 |
| 3726 DCHECK(ToRegister(instr->result()).is(x0)); | 3698 DCHECK(ToRegister(instr->result()).is(x0)); |
| 3727 } | 3699 } |
| 3728 | 3700 |
| 3729 | 3701 |
| (...skipping 2401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6131 Handle<ScopeInfo> scope_info = instr->scope_info(); | 6103 Handle<ScopeInfo> scope_info = instr->scope_info(); |
| 6132 __ Push(scope_info); | 6104 __ Push(scope_info); |
| 6133 __ Push(ToRegister(instr->function())); | 6105 __ Push(ToRegister(instr->function())); |
| 6134 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6106 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6135 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6107 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6136 } | 6108 } |
| 6137 | 6109 |
| 6138 | 6110 |
| 6139 | 6111 |
| 6140 } } // namespace v8::internal | 6112 } } // namespace v8::internal |
| OLD | NEW |