Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 6538019: Porting of revisions 6639, 6794 and 6805 to the 3.0 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.0
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/version.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1906 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); 1917 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
1918 // Calculate number of capture registers (number_of_captures + 1) * 2. 1918 // Calculate number of capture registers (number_of_captures + 1) * 2.
1919 __ leal(rdx, Operand(rdx, rdx, times_1, 2)); 1919 __ leal(rdx, Operand(rdx, rdx, times_1, 2));
1920 // Check that the static offsets vector buffer is large enough. 1920 // Check that the static offsets vector buffer is large enough.
1921 __ cmpl(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize)); 1921 __ cmpl(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize));
1922 __ j(above, &runtime); 1922 __ j(above, &runtime);
1923 1923
1924 // rcx: RegExp data (FixedArray) 1924 // rcx: RegExp data (FixedArray)
1925 // rdx: Number of capture registers 1925 // rdx: Number of capture registers
1926 // Check that the second argument is a string. 1926 // Check that the second argument is a string.
1927 __ movq(rax, Operand(rsp, kSubjectOffset)); 1927 __ movq(rdi, Operand(rsp, kSubjectOffset));
1928 __ JumpIfSmi(rax, &runtime); 1928 __ JumpIfSmi(rdi, &runtime);
1929 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx); 1929 Condition is_string = masm->IsObjectStringType(rdi, rbx, rbx);
1930 __ j(NegateCondition(is_string), &runtime); 1930 __ j(NegateCondition(is_string), &runtime);
1931 1931
1932 // rax: Subject string. 1932 // rdi: Subject string.
1933 // rcx: RegExp data (FixedArray). 1933 // rax: RegExp data (FixedArray).
1934 // rdx: Number of capture registers. 1934 // rdx: Number of capture registers.
1935 // Check that the third argument is a positive smi less than the string 1935 // Check that the third argument is a positive smi less than the string
1936 // length. A negative value will be greater (unsigned comparison). 1936 // length. A negative value will be greater (unsigned comparison).
1937 __ movq(rbx, Operand(rsp, kPreviousIndexOffset)); 1937 __ movq(rbx, Operand(rsp, kPreviousIndexOffset));
1938 __ JumpIfNotSmi(rbx, &runtime); 1938 __ JumpIfNotSmi(rbx, &runtime);
1939 __ SmiCompare(rbx, FieldOperand(rax, String::kLengthOffset)); 1939 __ SmiCompare(rbx, FieldOperand(rdi, String::kLengthOffset));
1940 __ j(above_equal, &runtime); 1940 __ j(above_equal, &runtime);
1941 1941
1942 // rcx: RegExp data (FixedArray) 1942 // rax: RegExp data (FixedArray)
1943 // rdx: Number of capture registers 1943 // rdx: Number of capture registers
1944 // Check that the fourth object is a JSArray object. 1944 // Check that the fourth object is a JSArray object.
1945 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 1945 __ movq(rdi, Operand(rsp, kLastMatchInfoOffset));
1946 __ JumpIfSmi(rax, &runtime); 1946 __ JumpIfSmi(rdi, &runtime);
1947 __ CmpObjectType(rax, JS_ARRAY_TYPE, kScratchRegister); 1947 __ CmpObjectType(rdi, JS_ARRAY_TYPE, kScratchRegister);
1948 __ j(not_equal, &runtime); 1948 __ j(not_equal, &runtime);
1949 // Check that the JSArray is in fast case. 1949 // Check that the JSArray is in fast case.
1950 __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset)); 1950 __ movq(rbx, FieldOperand(rdi, JSArray::kElementsOffset));
1951 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset)); 1951 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
1952 __ Cmp(rax, Factory::fixed_array_map()); 1952 __ Cmp(rdi, Factory::fixed_array_map());
1953 __ j(not_equal, &runtime); 1953 __ j(not_equal, &runtime);
1954 // Check that the last match info has space for the capture registers and the 1954 // Check that the last match info has space for the capture registers and the
1955 // additional information. Ensure no overflow in add. 1955 // additional information. Ensure no overflow in add.
1956 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); 1956 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
1957 __ SmiToInteger32(rax, FieldOperand(rbx, FixedArray::kLengthOffset)); 1957 __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset));
1958 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead)); 1958 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
1959 __ cmpl(rdx, rax); 1959 __ cmpl(rdx, rdi);
1960 __ j(greater, &runtime); 1960 __ j(greater, &runtime);
1961 1961
1962 // rcx: RegExp data (FixedArray) 1962 // rax: RegExp data (FixedArray)
1963 // Check the representation and encoding of the subject string. 1963 // Check the representation and encoding of the subject string.
1964 NearLabel seq_ascii_string, seq_two_byte_string, check_code; 1964 NearLabel seq_ascii_string, seq_two_byte_string, check_code;
1965 __ movq(rax, Operand(rsp, kSubjectOffset)); 1965 __ movq(rdi, Operand(rsp, kSubjectOffset));
1966 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 1966 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
1967 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 1967 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
1968 // First check for flat two byte string. 1968 // First check for flat two byte string.
1969 __ andb(rbx, Immediate( 1969 __ andb(rbx, Immediate(
1970 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask)); 1970 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
1971 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 1971 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
1972 __ j(zero, &seq_two_byte_string); 1972 __ j(zero, &seq_two_byte_string);
1973 // Any other flat string must be a flat ascii string. 1973 // Any other flat string must be a flat ascii string.
1974 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask)); 1974 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
1975 __ j(zero, &seq_ascii_string); 1975 __ j(zero, &seq_ascii_string);
1976 1976
1977 // Check for flat cons string. 1977 // Check for flat cons string.
1978 // A flat cons string is a cons string where the second part is the empty 1978 // A flat cons string is a cons string where the second part is the empty
1979 // string. In that case the subject string is just the first part of the cons 1979 // string. In that case the subject string is just the first part of the cons
1980 // string. Also in this case the first part of the cons string is known to be 1980 // string. Also in this case the first part of the cons string is known to be
1981 // a sequential string or an external string. 1981 // a sequential string or an external string.
1982 STATIC_ASSERT(kExternalStringTag !=0); 1982 STATIC_ASSERT(kExternalStringTag !=0);
1983 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 1983 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0);
1984 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag)); 1984 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag));
1985 __ j(not_zero, &runtime); 1985 __ j(not_zero, &runtime);
1986 // String is a cons string. 1986 // String is a cons string.
1987 __ movq(rdx, FieldOperand(rax, ConsString::kSecondOffset)); 1987 __ movq(rdx, FieldOperand(rdi, ConsString::kSecondOffset));
1988 __ Cmp(rdx, Factory::empty_string()); 1988 __ Cmp(rdx, Factory::empty_string());
1989 __ j(not_equal, &runtime); 1989 __ j(not_equal, &runtime);
1990 __ movq(rax, FieldOperand(rax, ConsString::kFirstOffset)); 1990 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
1991 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 1991 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
1992 // String is a cons string with empty second part. 1992 // String is a cons string with empty second part.
1993 // rax: first part of cons string. 1993 // rdi: first part of cons string.
1994 // rbx: map of first part of cons string. 1994 // rbx: map of first part of cons string.
1995 // Is first part a flat two byte string? 1995 // Is first part a flat two byte string?
1996 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 1996 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
1997 Immediate(kStringRepresentationMask | kStringEncodingMask)); 1997 Immediate(kStringRepresentationMask | kStringEncodingMask));
1998 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 1998 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
1999 __ j(zero, &seq_two_byte_string); 1999 __ j(zero, &seq_two_byte_string);
2000 // Any other flat string must be ascii. 2000 // Any other flat string must be ascii.
2001 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2001 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2002 Immediate(kStringRepresentationMask)); 2002 Immediate(kStringRepresentationMask));
2003 __ j(not_zero, &runtime); 2003 __ j(not_zero, &runtime);
2004 2004
2005 __ bind(&seq_ascii_string); 2005 __ bind(&seq_ascii_string);
2006 // rax: subject string (sequential ascii) 2006 // rdi: subject string (sequential ascii)
2007 // rcx: RegExp data (FixedArray) 2007 // rax: RegExp data (FixedArray)
2008 __ movq(r11, FieldOperand(rcx, JSRegExp::kDataAsciiCodeOffset)); 2008 __ movq(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset));
2009 __ Set(rdi, 1); // Type is ascii. 2009 __ Set(rcx, 1); // Type is ascii.
2010 __ jmp(&check_code); 2010 __ jmp(&check_code);
2011 2011
2012 __ bind(&seq_two_byte_string); 2012 __ bind(&seq_two_byte_string);
2013 // rax: subject string (flat two-byte) 2013 // rdi: subject string (flat two-byte)
2014 // rcx: RegExp data (FixedArray) 2014 // rax: RegExp data (FixedArray)
2015 __ movq(r11, FieldOperand(rcx, JSRegExp::kDataUC16CodeOffset)); 2015 __ movq(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset));
2016 __ Set(rdi, 0); // Type is two byte. 2016 __ Set(rcx, 0); // Type is two byte.
2017 2017
2018 __ bind(&check_code); 2018 __ bind(&check_code);
2019 // Check that the irregexp code has been generated for the actual string 2019 // Check that the irregexp code has been generated for the actual string
2020 // encoding. If it has, the field contains a code object otherwise it contains 2020 // encoding. If it has, the field contains a code object otherwise it contains
2021 // the hole. 2021 // the hole.
2022 __ CmpObjectType(r11, CODE_TYPE, kScratchRegister); 2022 __ CmpObjectType(r11, CODE_TYPE, kScratchRegister);
2023 __ j(not_equal, &runtime); 2023 __ j(not_equal, &runtime);
2024 2024
2025 // rax: subject string 2025 // rdi: subject string
2026 // rdi: encoding of subject string (1 if ascii, 0 if two_byte); 2026 // rcx: encoding of subject string (1 if ascii, 0 if two_byte);
2027 // r11: code 2027 // r11: code
2028 // Load used arguments before starting to push arguments for call to native 2028 // Load used arguments before starting to push arguments for call to native
2029 // RegExp code to avoid handling changing stack height. 2029 // RegExp code to avoid handling changing stack height.
2030 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); 2030 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset));
2031 2031
2032 // rax: subject string 2032 // rdi: subject string
2033 // rbx: previous index 2033 // rbx: previous index
2034 // rdi: encoding of subject string (1 if ascii 0 if two_byte); 2034 // rcx: encoding of subject string (1 if ascii 0 if two_byte);
2035 // r11: code 2035 // r11: code
2036 // All checks done. Now push arguments for native regexp code. 2036 // All checks done. Now push arguments for native regexp code.
2037 __ IncrementCounter(&Counters::regexp_entry_native, 1); 2037 __ IncrementCounter(&Counters::regexp_entry_native, 1);
2038 2038
2039 // rsi is caller save on Windows and used to pass parameter on Linux.
2040 __ push(rsi);
2041
2042 static const int kRegExpExecuteArguments = 7; 2039 static const int kRegExpExecuteArguments = 7;
2043 __ PrepareCallCFunction(kRegExpExecuteArguments);
2044 int argument_slots_on_stack = 2040 int argument_slots_on_stack =
2045 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); 2041 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
2042 __ EnterApiExitFrame(argument_slots_on_stack); // Clobbers rax!
2046 2043
2047 // Argument 7: Indicate that this is a direct call from JavaScript. 2044 // Argument 7: Indicate that this is a direct call from JavaScript.
2048 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), 2045 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
2049 Immediate(1)); 2046 Immediate(1));
2050 2047
2051 // Argument 6: Start (high end) of backtracking stack memory area. 2048 // Argument 6: Start (high end) of backtracking stack memory area.
2052 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); 2049 __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
2053 __ movq(r9, Operand(kScratchRegister, 0)); 2050 __ movq(r9, Operand(kScratchRegister, 0));
2054 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 2051 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
2055 __ addq(r9, Operand(kScratchRegister, 0)); 2052 __ addq(r9, Operand(kScratchRegister, 0));
(...skipping 16 matching lines...) Expand all
2072 Register arg2 = rdx; 2069 Register arg2 = rdx;
2073 Register arg1 = rcx; 2070 Register arg1 = rcx;
2074 #else 2071 #else
2075 Register arg4 = rcx; 2072 Register arg4 = rcx;
2076 Register arg3 = rdx; 2073 Register arg3 = rdx;
2077 Register arg2 = rsi; 2074 Register arg2 = rsi;
2078 Register arg1 = rdi; 2075 Register arg1 = rdi;
2079 #endif 2076 #endif
2080 2077
2081 // Keep track on aliasing between argX defined above and the registers used. 2078 // Keep track on aliasing between argX defined above and the registers used.
2082 // rax: subject string 2079 // rdi: subject string
2083 // rbx: previous index 2080 // rbx: previous index
2084 // rdi: encoding of subject string (1 if ascii 0 if two_byte); 2081 // rcx: encoding of subject string (1 if ascii 0 if two_byte);
2085 // r11: code 2082 // r11: code
2086 2083
2087 // Argument 4: End of string data 2084 // Argument 4: End of string data
2088 // Argument 3: Start of string data 2085 // Argument 3: Start of string data
2089 NearLabel setup_two_byte, setup_rest; 2086 NearLabel setup_two_byte, setup_rest;
2090 __ testb(rdi, rdi); 2087 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
2091 __ j(zero, &setup_two_byte); 2088 __ j(zero, &setup_two_byte);
2092 __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); 2089 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
2093 __ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize)); 2090 __ lea(arg4, FieldOperand(rdi, rcx, times_1, SeqAsciiString::kHeaderSize));
2094 __ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize)); 2091 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize));
2095 __ jmp(&setup_rest); 2092 __ jmp(&setup_rest);
2096 __ bind(&setup_two_byte); 2093 __ bind(&setup_two_byte);
2097 __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); 2094 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
2098 __ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize)); 2095 __ lea(arg4, FieldOperand(rdi, rcx, times_2, SeqTwoByteString::kHeaderSize));
2099 __ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize)); 2096 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
2100 2097
2101 __ bind(&setup_rest); 2098 __ bind(&setup_rest);
2102 // Argument 2: Previous index. 2099 // Argument 2: Previous index.
2103 __ movq(arg2, rbx); 2100 __ movq(arg2, rbx);
2104 2101
2105 // Argument 1: Subject string. 2102 // Argument 1: Subject string.
2106 __ movq(arg1, rax); 2103 #ifdef WIN64_
2104 __ movq(arg1, rdi);
2105 #else
2106 // Already there in AMD64 calling convention.
2107 ASSERT(arg1.is(rdi));
2108 #endif
2107 2109
2108 // Locate the code entry and call it. 2110 // Locate the code entry and call it.
2109 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); 2111 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
2110 __ CallCFunction(r11, kRegExpExecuteArguments); 2112 __ call(r11);
2111 2113
2112 // rsi is caller save, as it is used to pass parameter. 2114 __ LeaveApiExitFrame();
2113 __ pop(rsi);
2114 2115
2115 // Check the result. 2116 // Check the result.
2116 NearLabel success; 2117 NearLabel success;
2118 Label exception;
2117 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS)); 2119 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS));
2118 __ j(equal, &success); 2120 __ j(equal, &success);
2119 NearLabel failure; 2121 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION));
2122 __ j(equal, &exception);
2120 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE)); 2123 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE));
2121 __ j(equal, &failure); 2124 // If none of the above, it can only be retry.
2122 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION)); 2125 // Handle that in the runtime system.
2123 // If not exception it can only be retry. Handle that in the runtime system.
2124 __ j(not_equal, &runtime); 2126 __ j(not_equal, &runtime);
2125 // Result must now be exception. If there is no pending exception already a 2127
2126 // stack overflow (on the backtrack stack) was detected in RegExp code but 2128 // For failure return null.
2127 // haven't created the exception yet. Handle that in the runtime system. 2129 __ LoadRoot(rax, Heap::kNullValueRootIndex);
2128 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2129 ExternalReference pending_exception_address(Top::k_pending_exception_address);
2130 __ movq(kScratchRegister, pending_exception_address);
2131 __ Cmp(kScratchRegister, Factory::the_hole_value());
2132 __ j(equal, &runtime);
2133 __ bind(&failure);
2134 // For failure and exception return null.
2135 __ Move(rax, Factory::null_value());
2136 __ ret(4 * kPointerSize); 2130 __ ret(4 * kPointerSize);
2137 2131
2138 // Load RegExp data. 2132 // Load RegExp data.
2139 __ bind(&success); 2133 __ bind(&success);
2140 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2134 __ movq(rax, Operand(rsp, kJSRegExpOffset));
2141 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset)); 2135 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
2142 __ SmiToInteger32(rax, 2136 __ SmiToInteger32(rax,
2143 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); 2137 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
2144 // Calculate number of capture registers (number_of_captures + 1) * 2. 2138 // Calculate number of capture registers (number_of_captures + 1) * 2.
2145 __ leal(rdx, Operand(rax, rax, times_1, 2)); 2139 __ leal(rdx, Operand(rax, rax, times_1, 2));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 times_pointer_size, 2180 times_pointer_size,
2187 RegExpImpl::kFirstCaptureOffset), 2181 RegExpImpl::kFirstCaptureOffset),
2188 rdi); 2182 rdi);
2189 __ jmp(&next_capture); 2183 __ jmp(&next_capture);
2190 __ bind(&done); 2184 __ bind(&done);
2191 2185
2192 // Return last match info. 2186 // Return last match info.
2193 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 2187 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
2194 __ ret(4 * kPointerSize); 2188 __ ret(4 * kPointerSize);
2195 2189
2190 __ bind(&exception);
2191 // Result must now be exception. If there is no pending exception already a
2192 // stack overflow (on the backtrack stack) was detected in RegExp code but
2193 // haven't created the exception yet. Handle that in the runtime system.
2194 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2195 ExternalReference pending_exception_address(Top::k_pending_exception_address);
2196 __ movq(rbx, pending_exception_address);
2197 __ movq(rax, Operand(rbx, 0));
2198 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
2199 __ cmpq(rax, rdx);
2200 __ j(equal, &runtime);
2201 __ movq(Operand(rbx, 0), rdx);
2202
2203 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
2204 NearLabel termination_exception;
2205 __ j(equal, &termination_exception);
2206 __ Throw(rax);
2207
2208 __ bind(&termination_exception);
2209 __ ThrowUncatchable(TERMINATION, rax);
2210
2196 // Do the runtime call to execute the regexp. 2211 // Do the runtime call to execute the regexp.
2197 __ bind(&runtime); 2212 __ bind(&runtime);
2198 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 2213 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
2199 #endif // V8_INTERPRETED_REGEXP 2214 #endif // V8_INTERPRETED_REGEXP
2200 } 2215 }
2201 2216
2202 2217
2203 void RegExpConstructResultStub::Generate(MacroAssembler* masm) { 2218 void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
2204 const int kMaxInlineLength = 100; 2219 const int kMaxInlineLength = 100;
2205 Label slowcase; 2220 Label slowcase;
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi); 2749 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
2735 __ Set(rax, argc_); 2750 __ Set(rax, argc_);
2736 __ Set(rbx, 0); 2751 __ Set(rbx, 0);
2737 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); 2752 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
2738 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); 2753 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
2739 __ Jump(adaptor, RelocInfo::CODE_TARGET); 2754 __ Jump(adaptor, RelocInfo::CODE_TARGET);
2740 } 2755 }
2741 2756
2742 2757
2743 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 2758 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
2744 // Check that stack should contain next handler, frame pointer, state and 2759 // Throw exception in eax.
2745 // return address in that order. 2760 __ Throw(rax);
2746 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
2747 StackHandlerConstants::kStateOffset);
2748 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
2749 StackHandlerConstants::kPCOffset);
2750
2751 ExternalReference handler_address(Top::k_handler_address);
2752 __ movq(kScratchRegister, handler_address);
2753 __ movq(rsp, Operand(kScratchRegister, 0));
2754 // get next in chain
2755 __ pop(rcx);
2756 __ movq(Operand(kScratchRegister, 0), rcx);
2757 __ pop(rbp); // pop frame pointer
2758 __ pop(rdx); // remove state
2759
2760 // Before returning we restore the context from the frame pointer if not NULL.
2761 // The frame pointer is NULL in the exception handler of a JS entry frame.
2762 __ Set(rsi, 0); // Tentatively set context pointer to NULL
2763 NearLabel skip;
2764 __ cmpq(rbp, Immediate(0));
2765 __ j(equal, &skip);
2766 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2767 __ bind(&skip);
2768 __ ret(0);
2769 } 2761 }
2770 2762
2771 2763
2772 void CEntryStub::GenerateCore(MacroAssembler* masm, 2764 void CEntryStub::GenerateCore(MacroAssembler* masm,
2773 Label* throw_normal_exception, 2765 Label* throw_normal_exception,
2774 Label* throw_termination_exception, 2766 Label* throw_termination_exception,
2775 Label* throw_out_of_memory_exception, 2767 Label* throw_out_of_memory_exception,
2776 bool do_gc, 2768 bool do_gc,
2777 bool always_allocate_scope) { 2769 bool always_allocate_scope) {
2778 // rax: result parameter for PerformGC, if any. 2770 // rax: result parameter for PerformGC, if any.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2900 // Handle normal exception. 2892 // Handle normal exception.
2901 __ jmp(throw_normal_exception); 2893 __ jmp(throw_normal_exception);
2902 2894
2903 // Retry. 2895 // Retry.
2904 __ bind(&retry); 2896 __ bind(&retry);
2905 } 2897 }
2906 2898
2907 2899
2908 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, 2900 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
2909 UncatchableExceptionType type) { 2901 UncatchableExceptionType type) {
2910 // Fetch top stack handler. 2902 __ ThrowUncatchable(type, rax);
2911 ExternalReference handler_address(Top::k_handler_address);
2912 __ movq(kScratchRegister, handler_address);
2913 __ movq(rsp, Operand(kScratchRegister, 0));
2914
2915 // Unwind the handlers until the ENTRY handler is found.
2916 NearLabel loop, done;
2917 __ bind(&loop);
2918 // Load the type of the current stack handler.
2919 const int kStateOffset = StackHandlerConstants::kStateOffset;
2920 __ cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY));
2921 __ j(equal, &done);
2922 // Fetch the next handler in the list.
2923 const int kNextOffset = StackHandlerConstants::kNextOffset;
2924 __ movq(rsp, Operand(rsp, kNextOffset));
2925 __ jmp(&loop);
2926 __ bind(&done);
2927
2928 // Set the top handler address to next handler past the current ENTRY handler.
2929 __ movq(kScratchRegister, handler_address);
2930 __ pop(Operand(kScratchRegister, 0));
2931
2932 if (type == OUT_OF_MEMORY) {
2933 // Set external caught exception to false.
2934 ExternalReference external_caught(Top::k_external_caught_exception_address);
2935 __ movq(rax, Immediate(false));
2936 __ store_rax(external_caught);
2937
2938 // Set pending exception and rax to out of memory exception.
2939 ExternalReference pending_exception(Top::k_pending_exception_address);
2940 __ movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
2941 __ store_rax(pending_exception);
2942 }
2943
2944 // Clear the context pointer.
2945 __ Set(rsi, 0);
2946
2947 // Restore registers from handler.
2948 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize ==
2949 StackHandlerConstants::kFPOffset);
2950 __ pop(rbp); // FP
2951 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
2952 StackHandlerConstants::kStateOffset);
2953 __ pop(rdx); // State
2954
2955 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
2956 StackHandlerConstants::kPCOffset);
2957 __ ret(0);
2958 } 2903 }
2959 2904
2960 2905
2961 void CEntryStub::Generate(MacroAssembler* masm) { 2906 void CEntryStub::Generate(MacroAssembler* masm) {
2962 // rax: number of arguments including receiver 2907 // rax: number of arguments including receiver
2963 // rbx: pointer to C function (C callee-saved) 2908 // rbx: pointer to C function (C callee-saved)
2964 // rbp: frame pointer of calling JS frame (restored after C call) 2909 // rbp: frame pointer of calling JS frame (restored after C call)
2965 // rsp: stack pointer (restored after C call) 2910 // rsp: stack pointer (restored after C call)
2966 // rsi: current context (restored) 2911 // rsi: current context (restored)
2967 2912
(...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after
4390 4335
4391 // Do a tail call to the rewritten stub. 4336 // Do a tail call to the rewritten stub.
4392 __ jmp(rdi); 4337 __ jmp(rdi);
4393 } 4338 }
4394 4339
4395 #undef __ 4340 #undef __
4396 4341
4397 } } // namespace v8::internal 4342 } } // namespace v8::internal
4398 4343
4399 #endif // V8_TARGET_ARCH_X64 4344 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/version.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698