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 |