OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3423 | 3423 |
3424 | 3424 |
3425 // ----------------------------------------------------------------------------- | 3425 // ----------------------------------------------------------------------------- |
3426 // JavaScript invokes. | 3426 // JavaScript invokes. |
3427 | 3427 |
3428 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 3428 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
3429 const ParameterCount& actual, | 3429 const ParameterCount& actual, |
3430 Handle<Code> code_constant, | 3430 Handle<Code> code_constant, |
3431 Register code_reg, | 3431 Register code_reg, |
3432 Label* done, | 3432 Label* done, |
| 3433 bool* definitely_mismatches, |
3433 InvokeFlag flag, | 3434 InvokeFlag flag, |
3434 const CallWrapper& call_wrapper, | 3435 const CallWrapper& call_wrapper, |
3435 CallKind call_kind) { | 3436 CallKind call_kind) { |
3436 bool definitely_matches = false; | 3437 bool definitely_matches = false; |
| 3438 *definitely_mismatches = false; |
3437 Label regular_invoke; | 3439 Label regular_invoke; |
3438 | 3440 |
3439 // Check whether the expected and actual arguments count match. If not, | 3441 // Check whether the expected and actual arguments count match. If not, |
3440 // setup registers according to contract with ArgumentsAdaptorTrampoline: | 3442 // setup registers according to contract with ArgumentsAdaptorTrampoline: |
3441 // a0: actual arguments count | 3443 // a0: actual arguments count |
3442 // a1: function (passed through to callee) | 3444 // a1: function (passed through to callee) |
3443 // a2: expected arguments count | 3445 // a2: expected arguments count |
3444 // a3: callee code entry | 3446 // a3: callee code entry |
3445 | 3447 |
3446 // The code below is made a lot easier because the calling code already sets | 3448 // The code below is made a lot easier because the calling code already sets |
(...skipping 10 matching lines...) Expand all Loading... |
3457 } else { | 3459 } else { |
3458 li(a0, Operand(actual.immediate())); | 3460 li(a0, Operand(actual.immediate())); |
3459 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3461 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3460 if (expected.immediate() == sentinel) { | 3462 if (expected.immediate() == sentinel) { |
3461 // Don't worry about adapting arguments for builtins that | 3463 // Don't worry about adapting arguments for builtins that |
3462 // don't want that done. Skip adaption code by making it look | 3464 // don't want that done. Skip adaption code by making it look |
3463 // like we have a match between expected and actual number of | 3465 // like we have a match between expected and actual number of |
3464 // arguments. | 3466 // arguments. |
3465 definitely_matches = true; | 3467 definitely_matches = true; |
3466 } else { | 3468 } else { |
| 3469 *definitely_mismatches = true; |
3467 li(a2, Operand(expected.immediate())); | 3470 li(a2, Operand(expected.immediate())); |
3468 } | 3471 } |
3469 } | 3472 } |
3470 } else if (actual.is_immediate()) { | 3473 } else if (actual.is_immediate()) { |
3471 Branch(®ular_invoke, eq, expected.reg(), Operand(actual.immediate())); | 3474 Branch(®ular_invoke, eq, expected.reg(), Operand(actual.immediate())); |
3472 li(a0, Operand(actual.immediate())); | 3475 li(a0, Operand(actual.immediate())); |
3473 } else { | 3476 } else { |
3474 Branch(®ular_invoke, eq, expected.reg(), Operand(actual.reg())); | 3477 Branch(®ular_invoke, eq, expected.reg(), Operand(actual.reg())); |
3475 } | 3478 } |
3476 | 3479 |
3477 if (!definitely_matches) { | 3480 if (!definitely_matches) { |
3478 if (!code_constant.is_null()) { | 3481 if (!code_constant.is_null()) { |
3479 li(a3, Operand(code_constant)); | 3482 li(a3, Operand(code_constant)); |
3480 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); | 3483 addiu(a3, a3, Code::kHeaderSize - kHeapObjectTag); |
3481 } | 3484 } |
3482 | 3485 |
3483 Handle<Code> adaptor = | 3486 Handle<Code> adaptor = |
3484 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3487 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
3485 if (flag == CALL_FUNCTION) { | 3488 if (flag == CALL_FUNCTION) { |
3486 call_wrapper.BeforeCall(CallSize(adaptor)); | 3489 call_wrapper.BeforeCall(CallSize(adaptor)); |
3487 SetCallKind(t1, call_kind); | 3490 SetCallKind(t1, call_kind); |
3488 Call(adaptor); | 3491 Call(adaptor); |
3489 call_wrapper.AfterCall(); | 3492 call_wrapper.AfterCall(); |
3490 jmp(done); | 3493 if (!*definitely_mismatches) { |
| 3494 Branch(done); |
| 3495 } |
3491 } else { | 3496 } else { |
3492 SetCallKind(t1, call_kind); | 3497 SetCallKind(t1, call_kind); |
3493 Jump(adaptor, RelocInfo::CODE_TARGET); | 3498 Jump(adaptor, RelocInfo::CODE_TARGET); |
3494 } | 3499 } |
3495 bind(®ular_invoke); | 3500 bind(®ular_invoke); |
3496 } | 3501 } |
3497 } | 3502 } |
3498 | 3503 |
3499 | 3504 |
3500 void MacroAssembler::InvokeCode(Register code, | 3505 void MacroAssembler::InvokeCode(Register code, |
3501 const ParameterCount& expected, | 3506 const ParameterCount& expected, |
3502 const ParameterCount& actual, | 3507 const ParameterCount& actual, |
3503 InvokeFlag flag, | 3508 InvokeFlag flag, |
3504 const CallWrapper& call_wrapper, | 3509 const CallWrapper& call_wrapper, |
3505 CallKind call_kind) { | 3510 CallKind call_kind) { |
3506 // You can't call a function without a valid frame. | 3511 // You can't call a function without a valid frame. |
3507 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3512 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3508 | 3513 |
3509 Label done; | 3514 Label done; |
3510 | 3515 |
3511 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag, | 3516 bool definitely_mismatches = false; |
| 3517 InvokePrologue(expected, actual, Handle<Code>::null(), code, |
| 3518 &done, &definitely_mismatches, flag, |
3512 call_wrapper, call_kind); | 3519 call_wrapper, call_kind); |
3513 if (flag == CALL_FUNCTION) { | 3520 if (!definitely_mismatches) { |
3514 call_wrapper.BeforeCall(CallSize(code)); | 3521 if (flag == CALL_FUNCTION) { |
3515 SetCallKind(t1, call_kind); | 3522 call_wrapper.BeforeCall(CallSize(code)); |
3516 Call(code); | 3523 SetCallKind(t1, call_kind); |
3517 call_wrapper.AfterCall(); | 3524 Call(code); |
3518 } else { | 3525 call_wrapper.AfterCall(); |
3519 ASSERT(flag == JUMP_FUNCTION); | 3526 } else { |
3520 SetCallKind(t1, call_kind); | 3527 ASSERT(flag == JUMP_FUNCTION); |
3521 Jump(code); | 3528 SetCallKind(t1, call_kind); |
| 3529 Jump(code); |
| 3530 } |
| 3531 // Continue here if InvokePrologue does handle the invocation due to |
| 3532 // mismatched parameter counts. |
| 3533 bind(&done); |
3522 } | 3534 } |
3523 // Continue here if InvokePrologue does handle the invocation due to | |
3524 // mismatched parameter counts. | |
3525 bind(&done); | |
3526 } | 3535 } |
3527 | 3536 |
3528 | 3537 |
3529 void MacroAssembler::InvokeCode(Handle<Code> code, | 3538 void MacroAssembler::InvokeCode(Handle<Code> code, |
3530 const ParameterCount& expected, | 3539 const ParameterCount& expected, |
3531 const ParameterCount& actual, | 3540 const ParameterCount& actual, |
3532 RelocInfo::Mode rmode, | 3541 RelocInfo::Mode rmode, |
3533 InvokeFlag flag, | 3542 InvokeFlag flag, |
3534 CallKind call_kind) { | 3543 CallKind call_kind) { |
3535 // You can't call a function without a valid frame. | 3544 // You can't call a function without a valid frame. |
3536 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3545 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3537 | 3546 |
3538 Label done; | 3547 Label done; |
3539 | 3548 |
3540 InvokePrologue(expected, actual, code, no_reg, &done, flag, | 3549 bool definitely_mismatches = false; |
| 3550 InvokePrologue(expected, actual, code, no_reg, |
| 3551 &done, &definitely_mismatches, flag, |
3541 NullCallWrapper(), call_kind); | 3552 NullCallWrapper(), call_kind); |
3542 if (flag == CALL_FUNCTION) { | 3553 if (!definitely_mismatches) { |
3543 SetCallKind(t1, call_kind); | 3554 if (flag == CALL_FUNCTION) { |
3544 Call(code, rmode); | 3555 SetCallKind(t1, call_kind); |
3545 } else { | 3556 Call(code, rmode); |
3546 SetCallKind(t1, call_kind); | 3557 } else { |
3547 Jump(code, rmode); | 3558 SetCallKind(t1, call_kind); |
| 3559 Jump(code, rmode); |
| 3560 } |
| 3561 // Continue here if InvokePrologue does handle the invocation due to |
| 3562 // mismatched parameter counts. |
| 3563 bind(&done); |
3548 } | 3564 } |
3549 // Continue here if InvokePrologue does handle the invocation due to | |
3550 // mismatched parameter counts. | |
3551 bind(&done); | |
3552 } | 3565 } |
3553 | 3566 |
3554 | 3567 |
3555 void MacroAssembler::InvokeFunction(Register function, | 3568 void MacroAssembler::InvokeFunction(Register function, |
3556 const ParameterCount& actual, | 3569 const ParameterCount& actual, |
3557 InvokeFlag flag, | 3570 InvokeFlag flag, |
3558 const CallWrapper& call_wrapper, | 3571 const CallWrapper& call_wrapper, |
3559 CallKind call_kind) { | 3572 CallKind call_kind) { |
3560 // You can't call a function without a valid frame. | 3573 // You can't call a function without a valid frame. |
3561 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3574 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
(...skipping 12 matching lines...) Expand all Loading... |
3574 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3587 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3575 | 3588 |
3576 ParameterCount expected(expected_reg); | 3589 ParameterCount expected(expected_reg); |
3577 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); | 3590 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); |
3578 } | 3591 } |
3579 | 3592 |
3580 | 3593 |
3581 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 3594 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
3582 const ParameterCount& actual, | 3595 const ParameterCount& actual, |
3583 InvokeFlag flag, | 3596 InvokeFlag flag, |
| 3597 const CallWrapper& call_wrapper, |
3584 CallKind call_kind) { | 3598 CallKind call_kind) { |
3585 // You can't call a function without a valid frame. | 3599 // You can't call a function without a valid frame. |
3586 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3600 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3587 | 3601 |
3588 // Get the function and setup the context. | 3602 // Get the function and setup the context. |
3589 LoadHeapObject(a1, function); | 3603 LoadHeapObject(a1, function); |
3590 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3604 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3591 | 3605 |
3592 ParameterCount expected(function->shared()->formal_parameter_count()); | 3606 ParameterCount expected(function->shared()->formal_parameter_count()); |
3593 // We call indirectly through the code field in the function to | 3607 // We call indirectly through the code field in the function to |
3594 // allow recompilation to take effect without changing any of the | 3608 // allow recompilation to take effect without changing any of the |
3595 // call sites. | 3609 // call sites. |
3596 lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3610 lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3597 InvokeCode(a3, expected, actual, flag, NullCallWrapper(), call_kind); | 3611 InvokeCode(a3, expected, actual, flag, call_wrapper, call_kind); |
3598 } | 3612 } |
3599 | 3613 |
3600 | 3614 |
3601 void MacroAssembler::IsObjectJSObjectType(Register heap_object, | 3615 void MacroAssembler::IsObjectJSObjectType(Register heap_object, |
3602 Register map, | 3616 Register map, |
3603 Register scratch, | 3617 Register scratch, |
3604 Label* fail) { | 3618 Label* fail) { |
3605 lw(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); | 3619 lw(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); |
3606 IsInstanceJSObjectType(map, scratch, fail); | 3620 IsInstanceJSObjectType(map, scratch, fail); |
3607 } | 3621 } |
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5045 opcode == BGTZL); | 5059 opcode == BGTZL); |
5046 opcode = (cond == eq) ? BEQ : BNE; | 5060 opcode = (cond == eq) ? BEQ : BNE; |
5047 instr = (instr & ~kOpcodeMask) | opcode; | 5061 instr = (instr & ~kOpcodeMask) | opcode; |
5048 masm_.emit(instr); | 5062 masm_.emit(instr); |
5049 } | 5063 } |
5050 | 5064 |
5051 | 5065 |
5052 } } // namespace v8::internal | 5066 } } // namespace v8::internal |
5053 | 5067 |
5054 #endif // V8_TARGET_ARCH_MIPS | 5068 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |