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 7689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7700 __ cmp(ebp, 0); | 7700 __ cmp(ebp, 0); |
7701 __ j(equal, &skip, not_taken); | 7701 __ j(equal, &skip, not_taken); |
7702 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 7702 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
7703 __ bind(&skip); | 7703 __ bind(&skip); |
7704 | 7704 |
7705 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 7705 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
7706 __ ret(0); | 7706 __ ret(0); |
7707 } | 7707 } |
7708 | 7708 |
7709 | 7709 |
7710 // If true, a Handle<T> passed by value is passed and returned by | |
7711 // using the location_ field directly. If false, it is passed and | |
7712 // returned as a pointer to a handle. | |
7713 #ifdef USING_MAC_ABI | |
7714 static const bool kPassHandlesDirectly = true; | |
7715 #else | |
7716 static const bool kPassHandlesDirectly = false; | |
7717 #endif | |
7718 | |
7719 | |
7720 void ApiGetterEntryStub::Generate(MacroAssembler* masm) { | |
7721 Label get_result; | |
7722 Label prologue; | |
7723 Label promote_scheduled_exception; | |
7724 __ EnterApiExitFrame(ExitFrame::MODE_NORMAL, kStackSpace, kArgc); | |
7725 ASSERT_EQ(kArgc, 4); | |
7726 if (kPassHandlesDirectly) { | |
7727 // When handles as passed directly we don't have to allocate extra | |
7728 // space for and pass an out parameter. | |
7729 __ mov(Operand(esp, 0 * kPointerSize), ebx); // name. | |
7730 __ mov(Operand(esp, 1 * kPointerSize), eax); // arguments pointer. | |
7731 } else { | |
7732 // The function expects three arguments to be passed but we allocate | |
7733 // four to get space for the output cell. The argument slots are filled | |
7734 // as follows: | |
7735 // | |
7736 // 3: output cell | |
7737 // 2: arguments pointer | |
7738 // 1: name | |
7739 // 0: pointer to the output cell | |
7740 // | |
7741 // Note that this is one more "argument" than the function expects | |
7742 // so the out cell will have to be popped explicitly after returning | |
7743 // from the function. | |
7744 __ mov(Operand(esp, 1 * kPointerSize), ebx); // name. | |
7745 __ mov(Operand(esp, 2 * kPointerSize), eax); // arguments pointer. | |
7746 __ mov(ebx, esp); | |
7747 __ add(Operand(ebx), Immediate(3 * kPointerSize)); | |
7748 __ mov(Operand(esp, 0 * kPointerSize), ebx); // output | |
7749 __ mov(Operand(esp, 3 * kPointerSize), Immediate(0)); // out cell. | |
7750 } | |
7751 // Call the api function! | |
7752 __ call(fun()->address(), RelocInfo::RUNTIME_ENTRY); | |
7753 // Check if the function scheduled an exception. | |
7754 ExternalReference scheduled_exception_address = | |
7755 ExternalReference::scheduled_exception_address(); | |
7756 __ cmp(Operand::StaticVariable(scheduled_exception_address), | |
7757 Immediate(Factory::the_hole_value())); | |
7758 __ j(not_equal, &promote_scheduled_exception, not_taken); | |
7759 if (!kPassHandlesDirectly) { | |
7760 // The returned value is a pointer to the handle holding the result. | |
7761 // Dereference this to get to the location. | |
7762 __ mov(eax, Operand(eax, 0)); | |
7763 } | |
7764 // Check if the result handle holds 0 | |
7765 __ test(eax, Operand(eax)); | |
7766 __ j(not_zero, &get_result, taken); | |
7767 // It was zero; the result is undefined. | |
7768 __ mov(eax, Factory::undefined_value()); | |
7769 __ jmp(&prologue); | |
7770 // It was non-zero. Dereference to get the result value. | |
7771 __ bind(&get_result); | |
7772 __ mov(eax, Operand(eax, 0)); | |
7773 __ bind(&prologue); | |
7774 __ LeaveExitFrame(ExitFrame::MODE_NORMAL); | |
7775 __ ret(0); | |
7776 __ bind(&promote_scheduled_exception); | |
7777 __ TailCallRuntime(ExternalReference(Runtime::kPromoteScheduledException), | |
7778 0, | |
7779 1); | |
7780 } | |
7781 | |
7782 | |
7783 void CEntryStub::GenerateCore(MacroAssembler* masm, | 7710 void CEntryStub::GenerateCore(MacroAssembler* masm, |
7784 Label* throw_normal_exception, | 7711 Label* throw_normal_exception, |
7785 Label* throw_termination_exception, | 7712 Label* throw_termination_exception, |
7786 Label* throw_out_of_memory_exception, | 7713 Label* throw_out_of_memory_exception, |
7787 ExitFrame::Mode mode, | 7714 StackFrame::Type frame_type, |
7788 bool do_gc, | 7715 bool do_gc, |
7789 bool always_allocate_scope) { | 7716 bool always_allocate_scope) { |
7790 // eax: result parameter for PerformGC, if any | 7717 // eax: result parameter for PerformGC, if any |
7791 // ebx: pointer to C function (C callee-saved) | 7718 // ebx: pointer to C function (C callee-saved) |
7792 // ebp: frame pointer (restored after C call) | 7719 // ebp: frame pointer (restored after C call) |
7793 // esp: stack pointer (restored after C call) | 7720 // esp: stack pointer (restored after C call) |
7794 // edi: number of arguments including receiver (C callee-saved) | 7721 // edi: number of arguments including receiver (C callee-saved) |
7795 // esi: pointer to the first argument (C callee-saved) | 7722 // esi: pointer to the first argument (C callee-saved) |
7796 | 7723 |
7797 if (do_gc) { | 7724 if (do_gc) { |
(...skipping 29 matching lines...) Expand all Loading... |
7827 | 7754 |
7828 // Check for failure result. | 7755 // Check for failure result. |
7829 Label failure_returned; | 7756 Label failure_returned; |
7830 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 7757 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
7831 __ lea(ecx, Operand(eax, 1)); | 7758 __ lea(ecx, Operand(eax, 1)); |
7832 // Lower 2 bits of ecx are 0 iff eax has failure tag. | 7759 // Lower 2 bits of ecx are 0 iff eax has failure tag. |
7833 __ test(ecx, Immediate(kFailureTagMask)); | 7760 __ test(ecx, Immediate(kFailureTagMask)); |
7834 __ j(zero, &failure_returned, not_taken); | 7761 __ j(zero, &failure_returned, not_taken); |
7835 | 7762 |
7836 // Exit the JavaScript to C++ exit frame. | 7763 // Exit the JavaScript to C++ exit frame. |
7837 __ LeaveExitFrame(mode); | 7764 __ LeaveExitFrame(frame_type); |
7838 __ ret(0); | 7765 __ ret(0); |
7839 | 7766 |
7840 // Handling of failure. | 7767 // Handling of failure. |
7841 __ bind(&failure_returned); | 7768 __ bind(&failure_returned); |
7842 | 7769 |
7843 Label retry; | 7770 Label retry; |
7844 // If the returned exception is RETRY_AFTER_GC continue at retry label | 7771 // If the returned exception is RETRY_AFTER_GC continue at retry label |
7845 ASSERT(Failure::RETRY_AFTER_GC == 0); | 7772 ASSERT(Failure::RETRY_AFTER_GC == 0); |
7846 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 7773 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
7847 __ j(zero, &retry, taken); | 7774 __ j(zero, &retry, taken); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7926 // ebx: pointer to C function (C callee-saved) | 7853 // ebx: pointer to C function (C callee-saved) |
7927 // ebp: frame pointer (restored after C call) | 7854 // ebp: frame pointer (restored after C call) |
7928 // esp: stack pointer (restored after C call) | 7855 // esp: stack pointer (restored after C call) |
7929 // esi: current context (C callee-saved) | 7856 // esi: current context (C callee-saved) |
7930 // edi: JS function of the caller (C callee-saved) | 7857 // edi: JS function of the caller (C callee-saved) |
7931 | 7858 |
7932 // NOTE: Invocations of builtins may return failure objects instead | 7859 // NOTE: Invocations of builtins may return failure objects instead |
7933 // of a proper result. The builtin entry handles this by performing | 7860 // of a proper result. The builtin entry handles this by performing |
7934 // a garbage collection and retrying the builtin (twice). | 7861 // a garbage collection and retrying the builtin (twice). |
7935 | 7862 |
7936 ExitFrame::Mode mode = is_debug_break | 7863 StackFrame::Type frame_type = is_debug_break ? |
7937 ? ExitFrame::MODE_DEBUG | 7864 StackFrame::EXIT_DEBUG : |
7938 : ExitFrame::MODE_NORMAL; | 7865 StackFrame::EXIT; |
7939 | 7866 |
7940 // Enter the exit frame that transitions from JavaScript to C++. | 7867 // Enter the exit frame that transitions from JavaScript to C++. |
7941 __ EnterExitFrame(mode); | 7868 __ EnterExitFrame(frame_type); |
7942 | 7869 |
7943 // eax: result parameter for PerformGC, if any (setup below) | 7870 // eax: result parameter for PerformGC, if any (setup below) |
7944 // ebx: pointer to builtin function (C callee-saved) | 7871 // ebx: pointer to builtin function (C callee-saved) |
7945 // ebp: frame pointer (restored after C call) | 7872 // ebp: frame pointer (restored after C call) |
7946 // esp: stack pointer (restored after C call) | 7873 // esp: stack pointer (restored after C call) |
7947 // edi: number of arguments including receiver (C callee-saved) | 7874 // edi: number of arguments including receiver (C callee-saved) |
7948 // esi: argv pointer (C callee-saved) | 7875 // esi: argv pointer (C callee-saved) |
7949 | 7876 |
7950 Label throw_normal_exception; | 7877 Label throw_normal_exception; |
7951 Label throw_termination_exception; | 7878 Label throw_termination_exception; |
7952 Label throw_out_of_memory_exception; | 7879 Label throw_out_of_memory_exception; |
7953 | 7880 |
7954 // Call into the runtime system. | 7881 // Call into the runtime system. |
7955 GenerateCore(masm, | 7882 GenerateCore(masm, |
7956 &throw_normal_exception, | 7883 &throw_normal_exception, |
7957 &throw_termination_exception, | 7884 &throw_termination_exception, |
7958 &throw_out_of_memory_exception, | 7885 &throw_out_of_memory_exception, |
7959 mode, | 7886 frame_type, |
7960 false, | 7887 false, |
7961 false); | 7888 false); |
7962 | 7889 |
7963 // Do space-specific GC and retry runtime call. | 7890 // Do space-specific GC and retry runtime call. |
7964 GenerateCore(masm, | 7891 GenerateCore(masm, |
7965 &throw_normal_exception, | 7892 &throw_normal_exception, |
7966 &throw_termination_exception, | 7893 &throw_termination_exception, |
7967 &throw_out_of_memory_exception, | 7894 &throw_out_of_memory_exception, |
7968 mode, | 7895 frame_type, |
7969 true, | 7896 true, |
7970 false); | 7897 false); |
7971 | 7898 |
7972 // Do full GC and retry runtime call one final time. | 7899 // Do full GC and retry runtime call one final time. |
7973 Failure* failure = Failure::InternalError(); | 7900 Failure* failure = Failure::InternalError(); |
7974 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure))); | 7901 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure))); |
7975 GenerateCore(masm, | 7902 GenerateCore(masm, |
7976 &throw_normal_exception, | 7903 &throw_normal_exception, |
7977 &throw_termination_exception, | 7904 &throw_termination_exception, |
7978 &throw_out_of_memory_exception, | 7905 &throw_out_of_memory_exception, |
7979 mode, | 7906 frame_type, |
7980 true, | 7907 true, |
7981 true); | 7908 true); |
7982 | 7909 |
7983 __ bind(&throw_out_of_memory_exception); | 7910 __ bind(&throw_out_of_memory_exception); |
7984 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); | 7911 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
7985 | 7912 |
7986 __ bind(&throw_termination_exception); | 7913 __ bind(&throw_termination_exception); |
7987 GenerateThrowUncatchable(masm, TERMINATION); | 7914 GenerateThrowUncatchable(masm, TERMINATION); |
7988 | 7915 |
7989 __ bind(&throw_normal_exception); | 7916 __ bind(&throw_normal_exception); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8149 | 8076 |
8150 int CompareStub::MinorKey() { | 8077 int CompareStub::MinorKey() { |
8151 // Encode the two parameters in a unique 16 bit value. | 8078 // Encode the two parameters in a unique 16 bit value. |
8152 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 8079 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
8153 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 8080 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
8154 } | 8081 } |
8155 | 8082 |
8156 #undef __ | 8083 #undef __ |
8157 | 8084 |
8158 } } // namespace v8::internal | 8085 } } // namespace v8::internal |
OLD | NEW |