| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
| 10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
| (...skipping 3342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3353 | 3353 |
| 3354 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { | 3354 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { |
| 3355 __ Ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3355 __ Ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3356 __ Ldr(vector, FieldMemOperand(vector, | 3356 __ Ldr(vector, FieldMemOperand(vector, |
| 3357 JSFunction::kSharedFunctionInfoOffset)); | 3357 JSFunction::kSharedFunctionInfoOffset)); |
| 3358 __ Ldr(vector, FieldMemOperand(vector, | 3358 __ Ldr(vector, FieldMemOperand(vector, |
| 3359 SharedFunctionInfo::kFeedbackVectorOffset)); | 3359 SharedFunctionInfo::kFeedbackVectorOffset)); |
| 3360 } | 3360 } |
| 3361 | 3361 |
| 3362 | 3362 |
| 3363 void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) { | 3363 void CallIC_ArrayStub::Generate(MacroAssembler* masm) { |
| 3364 // x1 - function | 3364 // x1 - function |
| 3365 // x2 - feedback vector | |
| 3366 // x3 - slot id | 3365 // x3 - slot id |
| 3366 Label miss; |
| 3367 Register function = x1; | 3367 Register function = x1; |
| 3368 Register feedback_vector = x2; | 3368 Register feedback_vector = x2; |
| 3369 Register index = x3; | 3369 Register index = x3; |
| 3370 Register scratch = x4; | 3370 Register scratch = x4; |
| 3371 | 3371 |
| 3372 EmitLoadTypeFeedbackVector(masm, feedback_vector); |
| 3373 |
| 3372 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch); | 3374 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch); |
| 3373 __ Cmp(function, scratch); | 3375 __ Cmp(function, scratch); |
| 3374 __ B(ne, miss); | 3376 __ B(ne, &miss); |
| 3375 | 3377 |
| 3376 Register allocation_site = feedback_vector; | 3378 Register allocation_site = feedback_vector; |
| 3377 __ Mov(x0, Operand(arg_count())); | 3379 __ Mov(x0, Operand(arg_count())); |
| 3378 | 3380 |
| 3379 __ Add(scratch, feedback_vector, | 3381 __ Add(scratch, feedback_vector, |
| 3380 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 3382 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 3381 __ Ldr(allocation_site, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 3383 __ Ldr(allocation_site, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
| 3382 | 3384 |
| 3383 // Verify that x2 contains an AllocationSite | 3385 // Verify that x2 contains an AllocationSite |
| 3384 __ AssertUndefinedOrAllocationSite(allocation_site, scratch); | 3386 __ AssertUndefinedOrAllocationSite(allocation_site, scratch); |
| 3385 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 3387 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 3386 __ TailCallStub(&stub); | 3388 __ TailCallStub(&stub); |
| 3387 } | |
| 3388 | |
| 3389 | |
| 3390 void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) { | |
| 3391 // x1 - function | |
| 3392 // x2 - feedback vector | |
| 3393 // x3 - slot id | |
| 3394 Label miss; | |
| 3395 | |
| 3396 if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) { | |
| 3397 Generate_MonomorphicArray(masm, &miss); | |
| 3398 } else { | |
| 3399 // So far there is only one customer for our custom feedback scheme. | |
| 3400 UNREACHABLE(); | |
| 3401 } | |
| 3402 | 3389 |
| 3403 __ bind(&miss); | 3390 __ bind(&miss); |
| 3404 GenerateMiss(masm); | 3391 GenerateMiss(masm, IC::kCallIC_Customization_Miss); |
| 3405 | 3392 |
| 3406 // The slow case, we need this no matter what to complete a call after a miss. | 3393 // The slow case, we need this no matter what to complete a call after a miss. |
| 3407 CallFunctionNoFeedback(masm, | 3394 CallFunctionNoFeedback(masm, |
| 3408 arg_count(), | 3395 arg_count(), |
| 3409 true, | 3396 true, |
| 3410 CallAsMethod()); | 3397 CallAsMethod()); |
| 3411 | 3398 |
| 3412 __ Unreachable(); | 3399 __ Unreachable(); |
| 3413 } | 3400 } |
| 3414 | 3401 |
| 3415 | 3402 |
| 3416 void CallICStub::Generate(MacroAssembler* masm) { | 3403 void CallICStub::Generate(MacroAssembler* masm) { |
| 3417 ASM_LOCATION("CallICStub"); | 3404 ASM_LOCATION("CallICStub"); |
| 3418 | 3405 |
| 3419 // x1 - function | 3406 // x1 - function |
| 3420 // x3 - slot id (Smi) | 3407 // x3 - slot id (Smi) |
| 3421 Label extra_checks_or_miss, slow_start; | 3408 Label extra_checks_or_miss, slow_start; |
| 3422 Label slow, non_function, wrap, cont; | 3409 Label slow, non_function, wrap, cont; |
| 3423 Label have_js_function; | 3410 Label have_js_function; |
| 3424 int argc = state_.arg_count(); | 3411 int argc = state_.arg_count(); |
| 3425 ParameterCount actual(argc); | 3412 ParameterCount actual(argc); |
| 3426 | 3413 |
| 3427 Register function = x1; | 3414 Register function = x1; |
| 3428 Register feedback_vector = x2; | 3415 Register feedback_vector = x2; |
| 3429 Register index = x3; | 3416 Register index = x3; |
| 3430 Register type = x4; | 3417 Register type = x4; |
| 3431 | 3418 |
| 3432 EmitLoadTypeFeedbackVector(masm, feedback_vector); | 3419 EmitLoadTypeFeedbackVector(masm, feedback_vector); |
| 3433 | 3420 |
| 3434 if (state_.stub_type() != CallIC::DEFAULT) { | |
| 3435 Generate_CustomFeedbackCall(masm); | |
| 3436 return; | |
| 3437 } | |
| 3438 | |
| 3439 // The checks. First, does x1 match the recorded monomorphic target? | 3421 // The checks. First, does x1 match the recorded monomorphic target? |
| 3440 __ Add(x4, feedback_vector, | 3422 __ Add(x4, feedback_vector, |
| 3441 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 3423 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 3442 __ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize)); | 3424 __ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
| 3443 | 3425 |
| 3444 __ Cmp(x4, function); | 3426 __ Cmp(x4, function); |
| 3445 __ B(ne, &extra_checks_or_miss); | 3427 __ B(ne, &extra_checks_or_miss); |
| 3446 | 3428 |
| 3447 __ bind(&have_js_function); | 3429 __ bind(&have_js_function); |
| 3448 if (state_.CallAsMethod()) { | 3430 if (state_.CallAsMethod()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3480 // We are going megamorphic, and we don't want to visit the runtime. | 3462 // We are going megamorphic, and we don't want to visit the runtime. |
| 3481 __ Add(x4, feedback_vector, | 3463 __ Add(x4, feedback_vector, |
| 3482 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 3464 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 3483 __ LoadRoot(x5, Heap::kMegamorphicSymbolRootIndex); | 3465 __ LoadRoot(x5, Heap::kMegamorphicSymbolRootIndex); |
| 3484 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); | 3466 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
| 3485 __ B(&slow_start); | 3467 __ B(&slow_start); |
| 3486 } | 3468 } |
| 3487 | 3469 |
| 3488 // We are here because tracing is on or we are going monomorphic. | 3470 // We are here because tracing is on or we are going monomorphic. |
| 3489 __ bind(&miss); | 3471 __ bind(&miss); |
| 3490 GenerateMiss(masm); | 3472 GenerateMiss(masm, IC::kCallIC_Miss); |
| 3491 | 3473 |
| 3492 // the slow case | 3474 // the slow case |
| 3493 __ bind(&slow_start); | 3475 __ bind(&slow_start); |
| 3494 | 3476 |
| 3495 // Check that the function is really a JavaScript function. | 3477 // Check that the function is really a JavaScript function. |
| 3496 __ JumpIfSmi(function, &non_function); | 3478 __ JumpIfSmi(function, &non_function); |
| 3497 | 3479 |
| 3498 // Goto slow case if we do not have a function. | 3480 // Goto slow case if we do not have a function. |
| 3499 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); | 3481 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); |
| 3500 __ B(&have_js_function); | 3482 __ B(&have_js_function); |
| 3501 } | 3483 } |
| 3502 | 3484 |
| 3503 | 3485 |
| 3504 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 3486 void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) { |
| 3505 ASM_LOCATION("CallICStub[Miss]"); | 3487 ASM_LOCATION("CallICStub[Miss]"); |
| 3506 | 3488 |
| 3507 // Get the receiver of the function from the stack; 1 ~ return address. | 3489 // Get the receiver of the function from the stack; 1 ~ return address. |
| 3508 __ Peek(x4, (state_.arg_count() + 1) * kPointerSize); | 3490 __ Peek(x4, (state_.arg_count() + 1) * kPointerSize); |
| 3509 | 3491 |
| 3510 { | 3492 { |
| 3511 FrameScope scope(masm, StackFrame::INTERNAL); | 3493 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3512 | 3494 |
| 3513 // Push the receiver and the function and feedback info. | 3495 // Push the receiver and the function and feedback info. |
| 3514 __ Push(x4, x1, x2, x3); | 3496 __ Push(x4, x1, x2, x3); |
| 3515 | 3497 |
| 3516 // Call the entry. | 3498 // Call the entry. |
| 3517 ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss), | 3499 ExternalReference miss = ExternalReference(IC_Utility(id), |
| 3518 masm->isolate()); | 3500 masm->isolate()); |
| 3519 __ CallExternalReference(miss, 4); | 3501 __ CallExternalReference(miss, 4); |
| 3520 | 3502 |
| 3521 // Move result to edi and exit the internal frame. | 3503 // Move result to edi and exit the internal frame. |
| 3522 __ Mov(x1, x0); | 3504 __ Mov(x1, x0); |
| 3523 } | 3505 } |
| 3524 } | 3506 } |
| 3525 | 3507 |
| 3526 | 3508 |
| 3527 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 3509 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
| (...skipping 2037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5565 MemOperand(fp, 6 * kPointerSize), | 5547 MemOperand(fp, 6 * kPointerSize), |
| 5566 NULL); | 5548 NULL); |
| 5567 } | 5549 } |
| 5568 | 5550 |
| 5569 | 5551 |
| 5570 #undef __ | 5552 #undef __ |
| 5571 | 5553 |
| 5572 } } // namespace v8::internal | 5554 } } // namespace v8::internal |
| 5573 | 5555 |
| 5574 #endif // V8_TARGET_ARCH_ARM64 | 5556 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |