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 3869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3880 __ SmiUntag(ebx); // Previous index from smi. | 3880 __ SmiUntag(ebx); // Previous index from smi. |
3881 | 3881 |
3882 // eax: subject string | 3882 // eax: subject string |
3883 // ebx: previous index | 3883 // ebx: previous index |
3884 // edx: code | 3884 // edx: code |
3885 // edi: encoding of subject string (1 if ascii 0 if two_byte); | 3885 // edi: encoding of subject string (1 if ascii 0 if two_byte); |
3886 // All checks done. Now push arguments for native regexp code. | 3886 // All checks done. Now push arguments for native regexp code. |
3887 __ IncrementCounter(&Counters::regexp_entry_native, 1); | 3887 __ IncrementCounter(&Counters::regexp_entry_native, 1); |
3888 | 3888 |
3889 static const int kRegExpExecuteArguments = 7; | 3889 static const int kRegExpExecuteArguments = 7; |
3890 __ PrepareCallCFunction(kRegExpExecuteArguments, ecx); | 3890 __ EnterApiExitFrame(kRegExpExecuteArguments); |
3891 | 3891 |
3892 // Argument 7: Indicate that this is a direct call from JavaScript. | 3892 // Argument 7: Indicate that this is a direct call from JavaScript. |
3893 __ mov(Operand(esp, 6 * kPointerSize), Immediate(1)); | 3893 __ mov(Operand(esp, 6 * kPointerSize), Immediate(1)); |
3894 | 3894 |
3895 // Argument 6: Start (high end) of backtracking stack memory area. | 3895 // Argument 6: Start (high end) of backtracking stack memory area. |
3896 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); | 3896 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); |
3897 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); | 3897 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); |
3898 __ mov(Operand(esp, 5 * kPointerSize), ecx); | 3898 __ mov(Operand(esp, 5 * kPointerSize), ecx); |
3899 | 3899 |
3900 // Argument 5: static offsets vector buffer. | 3900 // Argument 5: static offsets vector buffer. |
(...skipping 24 matching lines...) Expand all Loading... |
3925 __ bind(&setup_rest); | 3925 __ bind(&setup_rest); |
3926 | 3926 |
3927 // Argument 2: Previous index. | 3927 // Argument 2: Previous index. |
3928 __ mov(Operand(esp, 1 * kPointerSize), ebx); | 3928 __ mov(Operand(esp, 1 * kPointerSize), ebx); |
3929 | 3929 |
3930 // Argument 1: Subject string. | 3930 // Argument 1: Subject string. |
3931 __ mov(Operand(esp, 0 * kPointerSize), eax); | 3931 __ mov(Operand(esp, 0 * kPointerSize), eax); |
3932 | 3932 |
3933 // Locate the code entry and call it. | 3933 // Locate the code entry and call it. |
3934 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); | 3934 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
3935 __ CallCFunction(edx, kRegExpExecuteArguments); | 3935 __ call(Operand(edx)); |
| 3936 |
| 3937 // Drop arguments and come back to JS mode. |
| 3938 __ LeaveApiExitFrame(); |
3936 | 3939 |
3937 // Check the result. | 3940 // Check the result. |
3938 Label success; | 3941 Label success; |
3939 __ cmp(eax, NativeRegExpMacroAssembler::SUCCESS); | 3942 __ cmp(eax, NativeRegExpMacroAssembler::SUCCESS); |
3940 __ j(equal, &success, taken); | 3943 __ j(equal, &success, taken); |
3941 Label failure; | 3944 Label failure; |
3942 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); | 3945 __ cmp(eax, NativeRegExpMacroAssembler::FAILURE); |
3943 __ j(equal, &failure, taken); | 3946 __ j(equal, &failure, taken); |
3944 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); | 3947 __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION); |
3945 // If not exception it can only be retry. Handle that in the runtime system. | 3948 // If not exception it can only be retry. Handle that in the runtime system. |
3946 __ j(not_equal, &runtime); | 3949 __ j(not_equal, &runtime); |
3947 // Result must now be exception. If there is no pending exception already a | 3950 // Result must now be exception. If there is no pending exception already a |
3948 // stack overflow (on the backtrack stack) was detected in RegExp code but | 3951 // stack overflow (on the backtrack stack) was detected in RegExp code but |
3949 // haven't created the exception yet. Handle that in the runtime system. | 3952 // haven't created the exception yet. Handle that in the runtime system. |
3950 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 3953 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
3951 ExternalReference pending_exception(Top::k_pending_exception_address); | 3954 ExternalReference pending_exception(Top::k_pending_exception_address); |
3952 __ mov(eax, | 3955 __ mov(edx, |
3953 Operand::StaticVariable(ExternalReference::the_hole_value_location())); | 3956 Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
3954 __ cmp(eax, Operand::StaticVariable(pending_exception)); | 3957 __ mov(eax, Operand::StaticVariable(pending_exception)); |
| 3958 __ cmp(edx, Operand(eax)); |
3955 __ j(equal, &runtime); | 3959 __ j(equal, &runtime); |
| 3960 // For exception, throw the exception again. |
| 3961 |
| 3962 // Clear the pending exception variable. |
| 3963 __ mov(Operand::StaticVariable(pending_exception), edx); |
| 3964 |
| 3965 // Special handling of termination exceptions which are uncatchable |
| 3966 // by javascript code. |
| 3967 __ cmp(eax, Factory::termination_exception()); |
| 3968 Label throw_termination_exception; |
| 3969 __ j(equal, &throw_termination_exception); |
| 3970 |
| 3971 // Handle normal exception by following handler chain. |
| 3972 __ Throw(eax); |
| 3973 |
| 3974 __ bind(&throw_termination_exception); |
| 3975 __ ThrowUncatchable(TERMINATION, eax); |
| 3976 |
3956 __ bind(&failure); | 3977 __ bind(&failure); |
3957 // For failure and exception return null. | 3978 // For failure to match, return null. |
3958 __ mov(Operand(eax), Factory::null_value()); | 3979 __ mov(Operand(eax), Factory::null_value()); |
3959 __ ret(4 * kPointerSize); | 3980 __ ret(4 * kPointerSize); |
3960 | 3981 |
3961 // Load RegExp data. | 3982 // Load RegExp data. |
3962 __ bind(&success); | 3983 __ bind(&success); |
3963 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 3984 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
3964 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 3985 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
3965 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); | 3986 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); |
3966 // Calculate number of capture registers (number_of_captures + 1) * 2. | 3987 // Calculate number of capture registers (number_of_captures + 1) * 2. |
3967 STATIC_ASSERT(kSmiTag == 0); | 3988 STATIC_ASSERT(kSmiTag == 0); |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4621 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); | 4642 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); |
4622 __ Set(eax, Immediate(argc_)); | 4643 __ Set(eax, Immediate(argc_)); |
4623 __ Set(ebx, Immediate(0)); | 4644 __ Set(ebx, Immediate(0)); |
4624 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 4645 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
4625 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); | 4646 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
4626 __ jmp(adaptor, RelocInfo::CODE_TARGET); | 4647 __ jmp(adaptor, RelocInfo::CODE_TARGET); |
4627 } | 4648 } |
4628 | 4649 |
4629 | 4650 |
4630 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { | 4651 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
4631 // eax holds the exception. | 4652 __ Throw(eax); |
4632 | |
4633 // Adjust this code if not the case. | |
4634 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | |
4635 | |
4636 // Drop the sp to the top of the handler. | |
4637 ExternalReference handler_address(Top::k_handler_address); | |
4638 __ mov(esp, Operand::StaticVariable(handler_address)); | |
4639 | |
4640 // Restore next handler and frame pointer, discard handler state. | |
4641 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
4642 __ pop(Operand::StaticVariable(handler_address)); | |
4643 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | |
4644 __ pop(ebp); | |
4645 __ pop(edx); // Remove state. | |
4646 | |
4647 // Before returning we restore the context from the frame pointer if | |
4648 // not NULL. The frame pointer is NULL in the exception handler of | |
4649 // a JS entry frame. | |
4650 __ Set(esi, Immediate(0)); // Tentatively set context pointer to NULL. | |
4651 NearLabel skip; | |
4652 __ cmp(ebp, 0); | |
4653 __ j(equal, &skip, not_taken); | |
4654 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | |
4655 __ bind(&skip); | |
4656 | |
4657 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
4658 __ ret(0); | |
4659 } | 4653 } |
4660 | 4654 |
4661 | 4655 |
4662 void CEntryStub::GenerateCore(MacroAssembler* masm, | 4656 void CEntryStub::GenerateCore(MacroAssembler* masm, |
4663 Label* throw_normal_exception, | 4657 Label* throw_normal_exception, |
4664 Label* throw_termination_exception, | 4658 Label* throw_termination_exception, |
4665 Label* throw_out_of_memory_exception, | 4659 Label* throw_out_of_memory_exception, |
4666 bool do_gc, | 4660 bool do_gc, |
4667 bool always_allocate_scope) { | 4661 bool always_allocate_scope) { |
4668 // eax: result parameter for PerformGC, if any | 4662 // eax: result parameter for PerformGC, if any |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4771 // Handle normal exception. | 4765 // Handle normal exception. |
4772 __ jmp(throw_normal_exception); | 4766 __ jmp(throw_normal_exception); |
4773 | 4767 |
4774 // Retry. | 4768 // Retry. |
4775 __ bind(&retry); | 4769 __ bind(&retry); |
4776 } | 4770 } |
4777 | 4771 |
4778 | 4772 |
4779 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, | 4773 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, |
4780 UncatchableExceptionType type) { | 4774 UncatchableExceptionType type) { |
4781 // Adjust this code if not the case. | 4775 __ ThrowUncatchable(type, eax); |
4782 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | |
4783 | |
4784 // Drop sp to the top stack handler. | |
4785 ExternalReference handler_address(Top::k_handler_address); | |
4786 __ mov(esp, Operand::StaticVariable(handler_address)); | |
4787 | |
4788 // Unwind the handlers until the ENTRY handler is found. | |
4789 NearLabel loop, done; | |
4790 __ bind(&loop); | |
4791 // Load the type of the current stack handler. | |
4792 const int kStateOffset = StackHandlerConstants::kStateOffset; | |
4793 __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); | |
4794 __ j(equal, &done); | |
4795 // Fetch the next handler in the list. | |
4796 const int kNextOffset = StackHandlerConstants::kNextOffset; | |
4797 __ mov(esp, Operand(esp, kNextOffset)); | |
4798 __ jmp(&loop); | |
4799 __ bind(&done); | |
4800 | |
4801 // Set the top handler address to next handler past the current ENTRY handler. | |
4802 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
4803 __ pop(Operand::StaticVariable(handler_address)); | |
4804 | |
4805 if (type == OUT_OF_MEMORY) { | |
4806 // Set external caught exception to false. | |
4807 ExternalReference external_caught(Top::k_external_caught_exception_address); | |
4808 __ mov(eax, false); | |
4809 __ mov(Operand::StaticVariable(external_caught), eax); | |
4810 | |
4811 // Set pending exception and eax to out of memory exception. | |
4812 ExternalReference pending_exception(Top::k_pending_exception_address); | |
4813 __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); | |
4814 __ mov(Operand::StaticVariable(pending_exception), eax); | |
4815 } | |
4816 | |
4817 // Clear the context pointer. | |
4818 __ Set(esi, Immediate(0)); | |
4819 | |
4820 // Restore fp from handler and discard handler state. | |
4821 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); | |
4822 __ pop(ebp); | |
4823 __ pop(edx); // State. | |
4824 | |
4825 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
4826 __ ret(0); | |
4827 } | 4776 } |
4828 | 4777 |
4829 | 4778 |
4830 void CEntryStub::Generate(MacroAssembler* masm) { | 4779 void CEntryStub::Generate(MacroAssembler* masm) { |
4831 // eax: number of arguments including receiver | 4780 // eax: number of arguments including receiver |
4832 // ebx: pointer to C function (C callee-saved) | 4781 // ebx: pointer to C function (C callee-saved) |
4833 // ebp: frame pointer (restored after C call) | 4782 // ebp: frame pointer (restored after C call) |
4834 // esp: stack pointer (restored after C call) | 4783 // esp: stack pointer (restored after C call) |
4835 // esi: current context (C callee-saved) | 4784 // esi: current context (C callee-saved) |
4836 // edi: JS function of the caller (C callee-saved) | 4785 // edi: JS function of the caller (C callee-saved) |
(...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6573 __ SmiTag(result); | 6522 __ SmiTag(result); |
6574 __ ret(0); | 6523 __ ret(0); |
6575 } | 6524 } |
6576 | 6525 |
6577 | 6526 |
6578 #undef __ | 6527 #undef __ |
6579 | 6528 |
6580 } } // namespace v8::internal | 6529 } } // namespace v8::internal |
6581 | 6530 |
6582 #endif // V8_TARGET_ARCH_IA32 | 6531 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |