OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 7314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7325 // Arguments adaptor case: Read the arguments length from the | 7325 // Arguments adaptor case: Read the arguments length from the |
7326 // adaptor frame and return it. | 7326 // adaptor frame and return it. |
7327 // Otherwise nothing to do: The number of formal parameters has already been | 7327 // Otherwise nothing to do: The number of formal parameters has already been |
7328 // passed in register eax by calling function. Just return it. | 7328 // passed in register eax by calling function. Just return it. |
7329 __ cmovq(equal, rax, | 7329 __ cmovq(equal, rax, |
7330 Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 7330 Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
7331 __ ret(0); | 7331 __ ret(0); |
7332 } | 7332 } |
7333 | 7333 |
7334 | 7334 |
7335 int CEntryStub::MinorKey() { | |
7336 ASSERT(result_size_ <= 2); | |
7337 #ifdef _WIN64 | |
7338 // Simple results returned in rax (using default code). | |
7339 // Complex results must be written to address passed as first argument. | |
7340 return (result_size_ < 2) ? 0 : 1; | |
7341 #else | |
7342 // Single results returned in rax (both AMD64 and Win64 calling conventions) | |
7343 // and a struct of two pointers in rax+rdx (AMD64 calling convention only) | |
7344 // by default. | |
7345 return 0; | |
7346 #endif | |
7347 } | |
7348 | |
7349 | |
7350 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { | 7335 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
7351 // Check that stack should contain next handler, frame pointer, state and | 7336 // Check that stack should contain next handler, frame pointer, state and |
7352 // return address in that order. | 7337 // return address in that order. |
7353 ASSERT_EQ(StackHandlerConstants::kFPOffset + kPointerSize, | 7338 ASSERT_EQ(StackHandlerConstants::kFPOffset + kPointerSize, |
7354 StackHandlerConstants::kStateOffset); | 7339 StackHandlerConstants::kStateOffset); |
7355 ASSERT_EQ(StackHandlerConstants::kStateOffset + kPointerSize, | 7340 ASSERT_EQ(StackHandlerConstants::kStateOffset + kPointerSize, |
7356 StackHandlerConstants::kPCOffset); | 7341 StackHandlerConstants::kPCOffset); |
7357 | 7342 |
7358 ExternalReference handler_address(Top::k_handler_address); | 7343 ExternalReference handler_address(Top::k_handler_address); |
7359 __ movq(kScratchRegister, handler_address); | 7344 __ movq(kScratchRegister, handler_address); |
(...skipping 13 matching lines...) Expand all Loading... |
7373 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 7358 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
7374 __ bind(&skip); | 7359 __ bind(&skip); |
7375 __ ret(0); | 7360 __ ret(0); |
7376 } | 7361 } |
7377 | 7362 |
7378 | 7363 |
7379 void CEntryStub::GenerateCore(MacroAssembler* masm, | 7364 void CEntryStub::GenerateCore(MacroAssembler* masm, |
7380 Label* throw_normal_exception, | 7365 Label* throw_normal_exception, |
7381 Label* throw_termination_exception, | 7366 Label* throw_termination_exception, |
7382 Label* throw_out_of_memory_exception, | 7367 Label* throw_out_of_memory_exception, |
7383 ExitFrame::Mode mode, | |
7384 bool do_gc, | 7368 bool do_gc, |
7385 bool always_allocate_scope) { | 7369 bool always_allocate_scope) { |
7386 // rax: result parameter for PerformGC, if any. | 7370 // rax: result parameter for PerformGC, if any. |
7387 // rbx: pointer to C function (C callee-saved). | 7371 // rbx: pointer to C function (C callee-saved). |
7388 // rbp: frame pointer (restored after C call). | 7372 // rbp: frame pointer (restored after C call). |
7389 // rsp: stack pointer (restored after C call). | 7373 // rsp: stack pointer (restored after C call). |
7390 // r14: number of arguments including receiver (C callee-saved). | 7374 // r14: number of arguments including receiver (C callee-saved). |
7391 // r15: pointer to the first argument (C callee-saved). | 7375 // r15: pointer to the first argument (C callee-saved). |
7392 // This pointer is reused in LeaveExitFrame(), so it is stored in a | 7376 // This pointer is reused in LeaveExitFrame(), so it is stored in a |
7393 // callee-saved register. | 7377 // callee-saved register. |
7394 | 7378 |
| 7379 // Simple results returned in rax (both AMD64 and Win64 calling conventions). |
| 7380 // Complex results must be written to address passed as first argument. |
| 7381 // AMD64 calling convention: a struct of two pointers in rax+rdx |
| 7382 |
7395 if (do_gc) { | 7383 if (do_gc) { |
7396 // Pass failure code returned from last attempt as first argument to GC. | 7384 // Pass failure code returned from last attempt as first argument to GC. |
7397 #ifdef _WIN64 | 7385 #ifdef _WIN64 |
7398 __ movq(rcx, rax); | 7386 __ movq(rcx, rax); |
7399 #else // ! defined(_WIN64) | 7387 #else // ! defined(_WIN64) |
7400 __ movq(rdi, rax); | 7388 __ movq(rdi, rax); |
7401 #endif | 7389 #endif |
7402 __ movq(kScratchRegister, | 7390 __ movq(kScratchRegister, |
7403 FUNCTION_ADDR(Runtime::PerformGC), | 7391 FUNCTION_ADDR(Runtime::PerformGC), |
7404 RelocInfo::RUNTIME_ENTRY); | 7392 RelocInfo::RUNTIME_ENTRY); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7456 __ movq(rax, Operand(rsp, 6 * kPointerSize)); | 7444 __ movq(rax, Operand(rsp, 6 * kPointerSize)); |
7457 __ movq(rdx, Operand(rsp, 7 * kPointerSize)); | 7445 __ movq(rdx, Operand(rsp, 7 * kPointerSize)); |
7458 } | 7446 } |
7459 #endif | 7447 #endif |
7460 __ lea(rcx, Operand(rax, 1)); | 7448 __ lea(rcx, Operand(rax, 1)); |
7461 // Lower 2 bits of rcx are 0 iff rax has failure tag. | 7449 // Lower 2 bits of rcx are 0 iff rax has failure tag. |
7462 __ testl(rcx, Immediate(kFailureTagMask)); | 7450 __ testl(rcx, Immediate(kFailureTagMask)); |
7463 __ j(zero, &failure_returned); | 7451 __ j(zero, &failure_returned); |
7464 | 7452 |
7465 // Exit the JavaScript to C++ exit frame. | 7453 // Exit the JavaScript to C++ exit frame. |
7466 __ LeaveExitFrame(mode, result_size_); | 7454 __ LeaveExitFrame(mode_, result_size_); |
7467 __ ret(0); | 7455 __ ret(0); |
7468 | 7456 |
7469 // Handling of failure. | 7457 // Handling of failure. |
7470 __ bind(&failure_returned); | 7458 __ bind(&failure_returned); |
7471 | 7459 |
7472 Label retry; | 7460 Label retry; |
7473 // If the returned exception is RETRY_AFTER_GC continue at retry label | 7461 // If the returned exception is RETRY_AFTER_GC continue at retry label |
7474 ASSERT(Failure::RETRY_AFTER_GC == 0); | 7462 ASSERT(Failure::RETRY_AFTER_GC == 0); |
7475 __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 7463 __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
7476 __ j(zero, &retry); | 7464 __ j(zero, &retry); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7600 // Slow-case: Non-function called. | 7588 // Slow-case: Non-function called. |
7601 __ bind(&slow); | 7589 __ bind(&slow); |
7602 __ Set(rax, argc_); | 7590 __ Set(rax, argc_); |
7603 __ Set(rbx, 0); | 7591 __ Set(rbx, 0); |
7604 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); | 7592 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); |
7605 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); | 7593 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
7606 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 7594 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
7607 } | 7595 } |
7608 | 7596 |
7609 | 7597 |
7610 void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { | 7598 void CEntryStub::Generate(MacroAssembler* masm) { |
7611 // rax: number of arguments including receiver | 7599 // rax: number of arguments including receiver |
7612 // rbx: pointer to C function (C callee-saved) | 7600 // rbx: pointer to C function (C callee-saved) |
7613 // rbp: frame pointer of calling JS frame (restored after C call) | 7601 // rbp: frame pointer of calling JS frame (restored after C call) |
7614 // rsp: stack pointer (restored after C call) | 7602 // rsp: stack pointer (restored after C call) |
7615 // rsi: current context (restored) | 7603 // rsi: current context (restored) |
7616 | 7604 |
7617 // NOTE: Invocations of builtins may return failure objects | 7605 // NOTE: Invocations of builtins may return failure objects |
7618 // instead of a proper result. The builtin entry handles | 7606 // instead of a proper result. The builtin entry handles |
7619 // this by performing a garbage collection and retrying the | 7607 // this by performing a garbage collection and retrying the |
7620 // builtin once. | 7608 // builtin once. |
7621 | 7609 |
7622 ExitFrame::Mode mode = is_debug_break ? | |
7623 ExitFrame::MODE_DEBUG : | |
7624 ExitFrame::MODE_NORMAL; | |
7625 | |
7626 // Enter the exit frame that transitions from JavaScript to C++. | 7610 // Enter the exit frame that transitions from JavaScript to C++. |
7627 __ EnterExitFrame(mode, result_size_); | 7611 __ EnterExitFrame(mode_, result_size_); |
7628 | 7612 |
7629 // rax: Holds the context at this point, but should not be used. | 7613 // rax: Holds the context at this point, but should not be used. |
7630 // On entry to code generated by GenerateCore, it must hold | 7614 // On entry to code generated by GenerateCore, it must hold |
7631 // a failure result if the collect_garbage argument to GenerateCore | 7615 // a failure result if the collect_garbage argument to GenerateCore |
7632 // is true. This failure result can be the result of code | 7616 // is true. This failure result can be the result of code |
7633 // generated by a previous call to GenerateCore. The value | 7617 // generated by a previous call to GenerateCore. The value |
7634 // of rax is then passed to Runtime::PerformGC. | 7618 // of rax is then passed to Runtime::PerformGC. |
7635 // rbx: pointer to builtin function (C callee-saved). | 7619 // rbx: pointer to builtin function (C callee-saved). |
7636 // rbp: frame pointer of exit frame (restored after C call). | 7620 // rbp: frame pointer of exit frame (restored after C call). |
7637 // rsp: stack pointer (restored after C call). | 7621 // rsp: stack pointer (restored after C call). |
7638 // r14: number of arguments including receiver (C callee-saved). | 7622 // r14: number of arguments including receiver (C callee-saved). |
7639 // r15: argv pointer (C callee-saved). | 7623 // r15: argv pointer (C callee-saved). |
7640 | 7624 |
7641 Label throw_normal_exception; | 7625 Label throw_normal_exception; |
7642 Label throw_termination_exception; | 7626 Label throw_termination_exception; |
7643 Label throw_out_of_memory_exception; | 7627 Label throw_out_of_memory_exception; |
7644 | 7628 |
7645 // Call into the runtime system. | 7629 // Call into the runtime system. |
7646 GenerateCore(masm, | 7630 GenerateCore(masm, |
7647 &throw_normal_exception, | 7631 &throw_normal_exception, |
7648 &throw_termination_exception, | 7632 &throw_termination_exception, |
7649 &throw_out_of_memory_exception, | 7633 &throw_out_of_memory_exception, |
7650 mode, | |
7651 false, | 7634 false, |
7652 false); | 7635 false); |
7653 | 7636 |
7654 // Do space-specific GC and retry runtime call. | 7637 // Do space-specific GC and retry runtime call. |
7655 GenerateCore(masm, | 7638 GenerateCore(masm, |
7656 &throw_normal_exception, | 7639 &throw_normal_exception, |
7657 &throw_termination_exception, | 7640 &throw_termination_exception, |
7658 &throw_out_of_memory_exception, | 7641 &throw_out_of_memory_exception, |
7659 mode, | |
7660 true, | 7642 true, |
7661 false); | 7643 false); |
7662 | 7644 |
7663 // Do full GC and retry runtime call one final time. | 7645 // Do full GC and retry runtime call one final time. |
7664 Failure* failure = Failure::InternalError(); | 7646 Failure* failure = Failure::InternalError(); |
7665 __ movq(rax, failure, RelocInfo::NONE); | 7647 __ movq(rax, failure, RelocInfo::NONE); |
7666 GenerateCore(masm, | 7648 GenerateCore(masm, |
7667 &throw_normal_exception, | 7649 &throw_normal_exception, |
7668 &throw_termination_exception, | 7650 &throw_termination_exception, |
7669 &throw_out_of_memory_exception, | 7651 &throw_out_of_memory_exception, |
7670 mode, | |
7671 true, | 7652 true, |
7672 true); | 7653 true); |
7673 | 7654 |
7674 __ bind(&throw_out_of_memory_exception); | 7655 __ bind(&throw_out_of_memory_exception); |
7675 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); | 7656 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
7676 | 7657 |
7677 __ bind(&throw_termination_exception); | 7658 __ bind(&throw_termination_exception); |
7678 GenerateThrowUncatchable(masm, TERMINATION); | 7659 GenerateThrowUncatchable(masm, TERMINATION); |
7679 | 7660 |
7680 __ bind(&throw_normal_exception); | 7661 __ bind(&throw_normal_exception); |
(...skipping 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9205 // Call the function from C++. | 9186 // Call the function from C++. |
9206 return FUNCTION_CAST<ModuloFunction>(buffer); | 9187 return FUNCTION_CAST<ModuloFunction>(buffer); |
9207 } | 9188 } |
9208 | 9189 |
9209 #endif | 9190 #endif |
9210 | 9191 |
9211 | 9192 |
9212 #undef __ | 9193 #undef __ |
9213 | 9194 |
9214 } } // namespace v8::internal | 9195 } } // namespace v8::internal |
OLD | NEW |