OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 7487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7498 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 7498 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
7499 __ bind(&skip); | 7499 __ bind(&skip); |
7500 | 7500 |
7501 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 7501 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
7502 __ ret(0); | 7502 __ ret(0); |
7503 } | 7503 } |
7504 | 7504 |
7505 | 7505 |
7506 void CEntryStub::GenerateCore(MacroAssembler* masm, | 7506 void CEntryStub::GenerateCore(MacroAssembler* masm, |
7507 Label* throw_normal_exception, | 7507 Label* throw_normal_exception, |
| 7508 Label* throw_termination_exception, |
7508 Label* throw_out_of_memory_exception, | 7509 Label* throw_out_of_memory_exception, |
7509 StackFrame::Type frame_type, | 7510 StackFrame::Type frame_type, |
7510 bool do_gc, | 7511 bool do_gc, |
7511 bool always_allocate_scope) { | 7512 bool always_allocate_scope) { |
7512 // eax: result parameter for PerformGC, if any | 7513 // eax: result parameter for PerformGC, if any |
7513 // ebx: pointer to C function (C callee-saved) | 7514 // ebx: pointer to C function (C callee-saved) |
7514 // ebp: frame pointer (restored after C call) | 7515 // ebp: frame pointer (restored after C call) |
7515 // esp: stack pointer (restored after C call) | 7516 // esp: stack pointer (restored after C call) |
7516 // edi: number of arguments including receiver (C callee-saved) | 7517 // edi: number of arguments including receiver (C callee-saved) |
7517 // esi: pointer to the first argument (C callee-saved) | 7518 // esi: pointer to the first argument (C callee-saved) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7561 | 7562 |
7562 // Handling of failure. | 7563 // Handling of failure. |
7563 __ bind(&failure_returned); | 7564 __ bind(&failure_returned); |
7564 | 7565 |
7565 Label retry; | 7566 Label retry; |
7566 // If the returned exception is RETRY_AFTER_GC continue at retry label | 7567 // If the returned exception is RETRY_AFTER_GC continue at retry label |
7567 ASSERT(Failure::RETRY_AFTER_GC == 0); | 7568 ASSERT(Failure::RETRY_AFTER_GC == 0); |
7568 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 7569 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
7569 __ j(zero, &retry, taken); | 7570 __ j(zero, &retry, taken); |
7570 | 7571 |
7571 Label continue_exception; | 7572 // Special handling of out of memory exceptions. |
7572 // If the returned failure is EXCEPTION then promote Top::pending_exception(). | 7573 __ cmp(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
7573 __ cmp(eax, reinterpret_cast<int32_t>(Failure::Exception())); | 7574 __ j(equal, throw_out_of_memory_exception); |
7574 __ j(not_equal, &continue_exception); | |
7575 | 7575 |
7576 // Retrieve the pending exception and clear the variable. | 7576 // Retrieve the pending exception and clear the variable. |
7577 ExternalReference pending_exception_address(Top::k_pending_exception_address); | 7577 ExternalReference pending_exception_address(Top::k_pending_exception_address); |
7578 __ mov(eax, Operand::StaticVariable(pending_exception_address)); | 7578 __ mov(eax, Operand::StaticVariable(pending_exception_address)); |
7579 __ mov(edx, | 7579 __ mov(edx, |
7580 Operand::StaticVariable(ExternalReference::the_hole_value_location())); | 7580 Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
7581 __ mov(Operand::StaticVariable(pending_exception_address), edx); | 7581 __ mov(Operand::StaticVariable(pending_exception_address), edx); |
7582 | 7582 |
7583 __ bind(&continue_exception); | 7583 // Special handling of termination exceptions which are uncatchable |
7584 // Special handling of out of memory exception. | 7584 // by javascript code. |
7585 __ cmp(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 7585 __ cmp(eax, Factory::termination_exception()); |
7586 __ j(equal, throw_out_of_memory_exception); | 7586 __ j(equal, throw_termination_exception); |
7587 | 7587 |
7588 // Handle normal exception. | 7588 // Handle normal exception. |
7589 __ jmp(throw_normal_exception); | 7589 __ jmp(throw_normal_exception); |
7590 | 7590 |
7591 // Retry. | 7591 // Retry. |
7592 __ bind(&retry); | 7592 __ bind(&retry); |
7593 } | 7593 } |
7594 | 7594 |
7595 | 7595 |
7596 void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { | 7596 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, |
| 7597 UncatchableExceptionType type) { |
7597 // Adjust this code if not the case. | 7598 // Adjust this code if not the case. |
7598 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 7599 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
7599 | 7600 |
7600 // Drop sp to the top stack handler. | 7601 // Drop sp to the top stack handler. |
7601 ExternalReference handler_address(Top::k_handler_address); | 7602 ExternalReference handler_address(Top::k_handler_address); |
7602 __ mov(esp, Operand::StaticVariable(handler_address)); | 7603 __ mov(esp, Operand::StaticVariable(handler_address)); |
7603 | 7604 |
7604 // Unwind the handlers until the ENTRY handler is found. | 7605 // Unwind the handlers until the ENTRY handler is found. |
7605 Label loop, done; | 7606 Label loop, done; |
7606 __ bind(&loop); | 7607 __ bind(&loop); |
7607 // Load the type of the current stack handler. | 7608 // Load the type of the current stack handler. |
7608 const int kStateOffset = StackHandlerConstants::kStateOffset; | 7609 const int kStateOffset = StackHandlerConstants::kStateOffset; |
7609 __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); | 7610 __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); |
7610 __ j(equal, &done); | 7611 __ j(equal, &done); |
7611 // Fetch the next handler in the list. | 7612 // Fetch the next handler in the list. |
7612 const int kNextOffset = StackHandlerConstants::kNextOffset; | 7613 const int kNextOffset = StackHandlerConstants::kNextOffset; |
7613 __ mov(esp, Operand(esp, kNextOffset)); | 7614 __ mov(esp, Operand(esp, kNextOffset)); |
7614 __ jmp(&loop); | 7615 __ jmp(&loop); |
7615 __ bind(&done); | 7616 __ bind(&done); |
7616 | 7617 |
7617 // Set the top handler address to next handler past the current ENTRY handler. | 7618 // Set the top handler address to next handler past the current ENTRY handler. |
7618 ASSERT(StackHandlerConstants::kNextOffset == 0); | 7619 ASSERT(StackHandlerConstants::kNextOffset == 0); |
7619 __ pop(Operand::StaticVariable(handler_address)); | 7620 __ pop(Operand::StaticVariable(handler_address)); |
7620 | 7621 |
7621 // Set external caught exception to false. | 7622 if (type == OUT_OF_MEMORY) { |
7622 ExternalReference external_caught(Top::k_external_caught_exception_address); | 7623 // Set external caught exception to false. |
7623 __ mov(eax, false); | 7624 ExternalReference external_caught(Top::k_external_caught_exception_address); |
7624 __ mov(Operand::StaticVariable(external_caught), eax); | 7625 __ mov(eax, false); |
| 7626 __ mov(Operand::StaticVariable(external_caught), eax); |
7625 | 7627 |
7626 // Set pending exception and eax to out of memory exception. | 7628 // Set pending exception and eax to out of memory exception. |
7627 ExternalReference pending_exception(Top::k_pending_exception_address); | 7629 ExternalReference pending_exception(Top::k_pending_exception_address); |
7628 __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | 7630 __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
7629 __ mov(Operand::StaticVariable(pending_exception), eax); | 7631 __ mov(Operand::StaticVariable(pending_exception), eax); |
| 7632 } |
7630 | 7633 |
7631 // Clear the context pointer; | 7634 // Clear the context pointer. |
7632 __ xor_(esi, Operand(esi)); | 7635 __ xor_(esi, Operand(esi)); |
7633 | 7636 |
7634 // Restore fp from handler and discard handler state. | 7637 // Restore fp from handler and discard handler state. |
7635 ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | 7638 ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
7636 __ pop(ebp); | 7639 __ pop(ebp); |
7637 __ pop(edx); // State. | 7640 __ pop(edx); // State. |
7638 | 7641 |
7639 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 7642 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
7640 __ ret(0); | 7643 __ ret(0); |
7641 } | 7644 } |
(...skipping 18 matching lines...) Expand all Loading... |
7660 // Enter the exit frame that transitions from JavaScript to C++. | 7663 // Enter the exit frame that transitions from JavaScript to C++. |
7661 __ EnterExitFrame(frame_type); | 7664 __ EnterExitFrame(frame_type); |
7662 | 7665 |
7663 // eax: result parameter for PerformGC, if any (setup below) | 7666 // eax: result parameter for PerformGC, if any (setup below) |
7664 // ebx: pointer to builtin function (C callee-saved) | 7667 // ebx: pointer to builtin function (C callee-saved) |
7665 // ebp: frame pointer (restored after C call) | 7668 // ebp: frame pointer (restored after C call) |
7666 // esp: stack pointer (restored after C call) | 7669 // esp: stack pointer (restored after C call) |
7667 // edi: number of arguments including receiver (C callee-saved) | 7670 // edi: number of arguments including receiver (C callee-saved) |
7668 // esi: argv pointer (C callee-saved) | 7671 // esi: argv pointer (C callee-saved) |
7669 | 7672 |
| 7673 Label throw_normal_exception; |
| 7674 Label throw_termination_exception; |
7670 Label throw_out_of_memory_exception; | 7675 Label throw_out_of_memory_exception; |
7671 Label throw_normal_exception; | |
7672 | 7676 |
7673 // Call into the runtime system. | 7677 // Call into the runtime system. |
7674 GenerateCore(masm, &throw_normal_exception, | 7678 GenerateCore(masm, |
| 7679 &throw_normal_exception, |
| 7680 &throw_termination_exception, |
7675 &throw_out_of_memory_exception, | 7681 &throw_out_of_memory_exception, |
7676 frame_type, | 7682 frame_type, |
7677 false, | 7683 false, |
7678 false); | 7684 false); |
7679 | 7685 |
7680 // Do space-specific GC and retry runtime call. | 7686 // Do space-specific GC and retry runtime call. |
7681 GenerateCore(masm, | 7687 GenerateCore(masm, |
7682 &throw_normal_exception, | 7688 &throw_normal_exception, |
| 7689 &throw_termination_exception, |
7683 &throw_out_of_memory_exception, | 7690 &throw_out_of_memory_exception, |
7684 frame_type, | 7691 frame_type, |
7685 true, | 7692 true, |
7686 false); | 7693 false); |
7687 | 7694 |
7688 // Do full GC and retry runtime call one final time. | 7695 // Do full GC and retry runtime call one final time. |
7689 Failure* failure = Failure::InternalError(); | 7696 Failure* failure = Failure::InternalError(); |
7690 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure))); | 7697 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure))); |
7691 GenerateCore(masm, | 7698 GenerateCore(masm, |
7692 &throw_normal_exception, | 7699 &throw_normal_exception, |
| 7700 &throw_termination_exception, |
7693 &throw_out_of_memory_exception, | 7701 &throw_out_of_memory_exception, |
7694 frame_type, | 7702 frame_type, |
7695 true, | 7703 true, |
7696 true); | 7704 true); |
7697 | 7705 |
7698 __ bind(&throw_out_of_memory_exception); | 7706 __ bind(&throw_out_of_memory_exception); |
7699 GenerateThrowOutOfMemory(masm); | 7707 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
7700 // control flow for generated will not return. | 7708 |
| 7709 __ bind(&throw_termination_exception); |
| 7710 GenerateThrowUncatchable(masm, TERMINATION); |
7701 | 7711 |
7702 __ bind(&throw_normal_exception); | 7712 __ bind(&throw_normal_exception); |
7703 GenerateThrowTOS(masm); | 7713 GenerateThrowTOS(masm); |
7704 } | 7714 } |
7705 | 7715 |
7706 | 7716 |
7707 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { | 7717 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
7708 Label invoke, exit; | 7718 Label invoke, exit; |
7709 #ifdef ENABLE_LOGGING_AND_PROFILING | 7719 #ifdef ENABLE_LOGGING_AND_PROFILING |
7710 Label not_outermost_js, not_outermost_js_2; | 7720 Label not_outermost_js, not_outermost_js_2; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7862 | 7872 |
7863 int CompareStub::MinorKey() { | 7873 int CompareStub::MinorKey() { |
7864 // Encode the two parameters in a unique 16 bit value. | 7874 // Encode the two parameters in a unique 16 bit value. |
7865 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7875 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7866 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7876 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7867 } | 7877 } |
7868 | 7878 |
7869 #undef __ | 7879 #undef __ |
7870 | 7880 |
7871 } } // namespace v8::internal | 7881 } } // namespace v8::internal |
OLD | NEW |