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

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

Issue 559913002: Rename ascii to one-byte where applicable. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 // (5b) Is subject external? If yes, go to (8). 1073 // (5b) Is subject external? If yes, go to (8).
1074 __ testb(rbx, Immediate(kStringRepresentationMask)); 1074 __ testb(rbx, Immediate(kStringRepresentationMask));
1075 // The underlying external string is never a short external string. 1075 // The underlying external string is never a short external string.
1076 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength); 1076 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
1077 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength); 1077 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
1078 __ j(not_zero, &external_string); // Go to (8) 1078 __ j(not_zero, &external_string); // Go to (8)
1079 1079
1080 // (6) One byte sequential. Load regexp code for one byte. 1080 // (6) One byte sequential. Load regexp code for one byte.
1081 __ bind(&seq_one_byte_string); 1081 __ bind(&seq_one_byte_string);
1082 // rax: RegExp data (FixedArray) 1082 // rax: RegExp data (FixedArray)
1083 __ movp(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset)); 1083 __ movp(r11, FieldOperand(rax, JSRegExp::kDataOneByteCodeOffset));
1084 __ Set(rcx, 1); // Type is one byte. 1084 __ Set(rcx, 1); // Type is one byte.
1085 1085
1086 // (E) Carry on. String handling is done. 1086 // (E) Carry on. String handling is done.
1087 __ bind(&check_code); 1087 __ bind(&check_code);
1088 // r11: irregexp code 1088 // r11: irregexp code
1089 // Check that the irregexp code has been generated for the actual string 1089 // Check that the irregexp code has been generated for the actual string
1090 // encoding. If it has, the field contains a code object otherwise it contains 1090 // encoding. If it has, the field contains a code object otherwise it contains
1091 // smi (code flushing support) 1091 // smi (code flushing support)
1092 __ JumpIfSmi(r11, &runtime); 1092 __ JumpIfSmi(r11, &runtime);
1093 1093
1094 // rdi: sequential subject string (or look-alike, external string) 1094 // rdi: sequential subject string (or look-alike, external string)
1095 // r15: original subject string 1095 // r15: original subject string
1096 // rcx: encoding of subject string (1 if ASCII, 0 if two_byte); 1096 // rcx: encoding of subject string (1 if one_byte, 0 if two_byte);
1097 // r11: code 1097 // r11: code
1098 // Load used arguments before starting to push arguments for call to native 1098 // Load used arguments before starting to push arguments for call to native
1099 // RegExp code to avoid handling changing stack height. 1099 // RegExp code to avoid handling changing stack height.
1100 // We have to use r15 instead of rdi to load the length because rdi might 1100 // We have to use r15 instead of rdi to load the length because rdi might
1101 // have been only made to look like a sequential string when it actually 1101 // have been only made to look like a sequential string when it actually
1102 // is an external string. 1102 // is an external string.
1103 __ movp(rbx, args.GetArgumentOperand(PREVIOUS_INDEX_ARGUMENT_INDEX)); 1103 __ movp(rbx, args.GetArgumentOperand(PREVIOUS_INDEX_ARGUMENT_INDEX));
1104 __ JumpIfNotSmi(rbx, &runtime); 1104 __ JumpIfNotSmi(rbx, &runtime);
1105 __ SmiCompare(rbx, FieldOperand(r15, String::kLengthOffset)); 1105 __ SmiCompare(rbx, FieldOperand(r15, String::kLengthOffset));
1106 __ j(above_equal, &runtime); 1106 __ j(above_equal, &runtime);
1107 __ SmiToInteger64(rbx, rbx); 1107 __ SmiToInteger64(rbx, rbx);
1108 1108
1109 // rdi: subject string 1109 // rdi: subject string
1110 // rbx: previous index 1110 // rbx: previous index
1111 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); 1111 // rcx: encoding of subject string (1 if one_byte 0 if two_byte);
1112 // r11: code 1112 // r11: code
1113 // All checks done. Now push arguments for native regexp code. 1113 // All checks done. Now push arguments for native regexp code.
1114 Counters* counters = isolate()->counters(); 1114 Counters* counters = isolate()->counters();
1115 __ IncrementCounter(counters->regexp_entry_native(), 1); 1115 __ IncrementCounter(counters->regexp_entry_native(), 1);
1116 1116
1117 // Isolates: note we add an additional parameter here (isolate pointer). 1117 // Isolates: note we add an additional parameter here (isolate pointer).
1118 static const int kRegExpExecuteArguments = 9; 1118 static const int kRegExpExecuteArguments = 9;
1119 int argument_slots_on_stack = 1119 int argument_slots_on_stack =
1120 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); 1120 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
1121 __ EnterApiExitFrame(argument_slots_on_stack); 1121 __ EnterApiExitFrame(argument_slots_on_stack);
(...skipping 28 matching lines...) Expand all
1150 // Argument 5: static offsets vector buffer. 1150 // Argument 5: static offsets vector buffer.
1151 __ LoadAddress( 1151 __ LoadAddress(
1152 r8, ExternalReference::address_of_static_offsets_vector(isolate())); 1152 r8, ExternalReference::address_of_static_offsets_vector(isolate()));
1153 // Argument 5 passed in r8 on Linux and on the stack on Windows. 1153 // Argument 5 passed in r8 on Linux and on the stack on Windows.
1154 #ifdef _WIN64 1154 #ifdef _WIN64
1155 __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kRegisterSize), r8); 1155 __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kRegisterSize), r8);
1156 #endif 1156 #endif
1157 1157
1158 // rdi: subject string 1158 // rdi: subject string
1159 // rbx: previous index 1159 // rbx: previous index
1160 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); 1160 // rcx: encoding of subject string (1 if one_byte 0 if two_byte);
1161 // r11: code 1161 // r11: code
1162 // r14: slice offset 1162 // r14: slice offset
1163 // r15: original subject string 1163 // r15: original subject string
1164 1164
1165 // Argument 2: Previous index. 1165 // Argument 2: Previous index.
1166 __ movp(arg_reg_2, rbx); 1166 __ movp(arg_reg_2, rbx);
1167 1167
1168 // Argument 4: End of string data 1168 // Argument 4: End of string data
1169 // Argument 3: Start of string data 1169 // Argument 3: Start of string data
1170 Label setup_two_byte, setup_rest, got_length, length_not_from_slice; 1170 Label setup_two_byte, setup_rest, got_length, length_not_from_slice;
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 masm, &check_for_strings, rdx, kScratchRegister); 1590 masm, &check_for_strings, rdx, kScratchRegister);
1591 1591
1592 // We've already checked for object identity, so if both operands are 1592 // We've already checked for object identity, so if both operands are
1593 // internalized strings they aren't equal. Register rax (not rax) already 1593 // internalized strings they aren't equal. Register rax (not rax) already
1594 // holds a non-zero value, which indicates not equal, so just return. 1594 // holds a non-zero value, which indicates not equal, so just return.
1595 __ ret(0); 1595 __ ret(0);
1596 } 1596 }
1597 1597
1598 __ bind(&check_for_strings); 1598 __ bind(&check_for_strings);
1599 1599
1600 __ JumpIfNotBothSequentialAsciiStrings( 1600 __ JumpIfNotBothSequentialOneByteStrings(rdx, rax, rcx, rbx,
1601 rdx, rax, rcx, rbx, &check_unequal_objects); 1601 &check_unequal_objects);
1602 1602
1603 // Inline comparison of ASCII strings. 1603 // Inline comparison of one-byte strings.
1604 if (cc == equal) { 1604 if (cc == equal) {
1605 StringHelper::GenerateFlatAsciiStringEquals(masm, rdx, rax, rcx, rbx); 1605 StringHelper::GenerateFlatOneByteStringEquals(masm, rdx, rax, rcx, rbx);
1606 } else { 1606 } else {
1607 StringHelper::GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, 1607 StringHelper::GenerateCompareFlatOneByteStrings(masm, rdx, rax, rcx, rbx,
1608 r8); 1608 rdi, r8);
1609 } 1609 }
1610 1610
1611 #ifdef DEBUG 1611 #ifdef DEBUG
1612 __ Abort(kUnexpectedFallThroughFromStringComparison); 1612 __ Abort(kUnexpectedFallThroughFromStringComparison);
1613 #endif 1613 #endif
1614 1614
1615 __ bind(&check_unequal_objects); 1615 __ bind(&check_unequal_objects);
1616 if (cc == equal && !strict()) { 1616 if (cc == equal && !strict()) {
1617 // Not strict equality. Objects are unequal if 1617 // Not strict equality. Objects are unequal if
1618 // they are both JSObjects and not undetectable, 1618 // they are both JSObjects and not undetectable,
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
2667 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) * 2667 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) *
2668 kPointerSize); 2668 kPointerSize);
2669 } 2669 }
2670 } 2670 }
2671 2671
2672 2672
2673 // ------------------------------------------------------------------------- 2673 // -------------------------------------------------------------------------
2674 // StringCharCodeAtGenerator 2674 // StringCharCodeAtGenerator
2675 2675
2676 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2676 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2677 Label flat_string;
2678 Label ascii_string;
2679 Label got_char_code;
2680 Label sliced_string;
2681
2682 // If the receiver is a smi trigger the non-string case. 2677 // If the receiver is a smi trigger the non-string case.
2683 __ JumpIfSmi(object_, receiver_not_string_); 2678 __ JumpIfSmi(object_, receiver_not_string_);
2684 2679
2685 // Fetch the instance type of the receiver into result register. 2680 // Fetch the instance type of the receiver into result register.
2686 __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset)); 2681 __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset));
2687 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 2682 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
2688 // If the receiver is not a string trigger the non-string case. 2683 // If the receiver is not a string trigger the non-string case.
2689 __ testb(result_, Immediate(kIsNotStringMask)); 2684 __ testb(result_, Immediate(kIsNotStringMask));
2690 __ j(not_zero, receiver_not_string_); 2685 __ j(not_zero, receiver_not_string_);
2691 2686
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2940 // Allocate new sliced string. At this point we do not reload the instance 2935 // Allocate new sliced string. At this point we do not reload the instance
2941 // type including the string encoding because we simply rely on the info 2936 // type including the string encoding because we simply rely on the info
2942 // provided by the original string. It does not matter if the original 2937 // provided by the original string. It does not matter if the original
2943 // string's encoding is wrong because we always have to recheck encoding of 2938 // string's encoding is wrong because we always have to recheck encoding of
2944 // the newly created string's parent anyways due to externalized strings. 2939 // the newly created string's parent anyways due to externalized strings.
2945 Label two_byte_slice, set_slice_header; 2940 Label two_byte_slice, set_slice_header;
2946 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 2941 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
2947 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 2942 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
2948 __ testb(rbx, Immediate(kStringEncodingMask)); 2943 __ testb(rbx, Immediate(kStringEncodingMask));
2949 __ j(zero, &two_byte_slice, Label::kNear); 2944 __ j(zero, &two_byte_slice, Label::kNear);
2950 __ AllocateAsciiSlicedString(rax, rbx, r14, &runtime); 2945 __ AllocateOneByteSlicedString(rax, rbx, r14, &runtime);
2951 __ jmp(&set_slice_header, Label::kNear); 2946 __ jmp(&set_slice_header, Label::kNear);
2952 __ bind(&two_byte_slice); 2947 __ bind(&two_byte_slice);
2953 __ AllocateTwoByteSlicedString(rax, rbx, r14, &runtime); 2948 __ AllocateTwoByteSlicedString(rax, rbx, r14, &runtime);
2954 __ bind(&set_slice_header); 2949 __ bind(&set_slice_header);
2955 __ Integer32ToSmi(rcx, rcx); 2950 __ Integer32ToSmi(rcx, rcx);
2956 __ movp(FieldOperand(rax, SlicedString::kLengthOffset), rcx); 2951 __ movp(FieldOperand(rax, SlicedString::kLengthOffset), rcx);
2957 __ movp(FieldOperand(rax, SlicedString::kHashFieldOffset), 2952 __ movp(FieldOperand(rax, SlicedString::kHashFieldOffset),
2958 Immediate(String::kEmptyHashField)); 2953 Immediate(String::kEmptyHashField));
2959 __ movp(FieldOperand(rax, SlicedString::kParentOffset), rdi); 2954 __ movp(FieldOperand(rax, SlicedString::kParentOffset), rdi);
2960 __ movp(FieldOperand(rax, SlicedString::kOffsetOffset), rdx); 2955 __ movp(FieldOperand(rax, SlicedString::kOffsetOffset), rdx);
(...skipping 24 matching lines...) Expand all
2985 // Move the pointer so that offset-wise, it looks like a sequential string. 2980 // Move the pointer so that offset-wise, it looks like a sequential string.
2986 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 2981 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
2987 __ subp(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 2982 __ subp(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
2988 2983
2989 __ bind(&sequential_string); 2984 __ bind(&sequential_string);
2990 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 2985 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
2991 __ testb(rbx, Immediate(kStringEncodingMask)); 2986 __ testb(rbx, Immediate(kStringEncodingMask));
2992 __ j(zero, &two_byte_sequential); 2987 __ j(zero, &two_byte_sequential);
2993 2988
2994 // Allocate the result. 2989 // Allocate the result.
2995 __ AllocateAsciiString(rax, rcx, r11, r14, r15, &runtime); 2990 __ AllocateOneByteString(rax, rcx, r11, r14, r15, &runtime);
2996 2991
2997 // rax: result string 2992 // rax: result string
2998 // rcx: result string length 2993 // rcx: result string length
2999 { // Locate character of sub string start. 2994 { // Locate character of sub string start.
3000 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_1); 2995 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_1);
3001 __ leap(r14, Operand(rdi, smi_as_index.reg, smi_as_index.scale, 2996 __ leap(r14, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
3002 SeqOneByteString::kHeaderSize - kHeapObjectTag)); 2997 SeqOneByteString::kHeaderSize - kHeapObjectTag));
3003 } 2998 }
3004 // Locate first character of result. 2999 // Locate first character of result.
3005 __ leap(rdi, FieldOperand(rax, SeqOneByteString::kHeaderSize)); 3000 __ leap(rdi, FieldOperand(rax, SeqOneByteString::kHeaderSize));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3046 // rcx: sub string length (smi) 3041 // rcx: sub string length (smi)
3047 // rdx: from index (smi) 3042 // rdx: from index (smi)
3048 StringCharAtGenerator generator( 3043 StringCharAtGenerator generator(
3049 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); 3044 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
3050 generator.GenerateFast(masm); 3045 generator.GenerateFast(masm);
3051 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); 3046 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize);
3052 generator.SkipSlow(masm, &runtime); 3047 generator.SkipSlow(masm, &runtime);
3053 } 3048 }
3054 3049
3055 3050
3056 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, 3051 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
3057 Register left, Register right, 3052 Register left,
3058 Register scratch1, 3053 Register right,
3059 Register scratch2) { 3054 Register scratch1,
3055 Register scratch2) {
3060 Register length = scratch1; 3056 Register length = scratch1;
3061 3057
3062 // Compare lengths. 3058 // Compare lengths.
3063 Label check_zero_length; 3059 Label check_zero_length;
3064 __ movp(length, FieldOperand(left, String::kLengthOffset)); 3060 __ movp(length, FieldOperand(left, String::kLengthOffset));
3065 __ SmiCompare(length, FieldOperand(right, String::kLengthOffset)); 3061 __ SmiCompare(length, FieldOperand(right, String::kLengthOffset));
3066 __ j(equal, &check_zero_length, Label::kNear); 3062 __ j(equal, &check_zero_length, Label::kNear);
3067 __ Move(rax, Smi::FromInt(NOT_EQUAL)); 3063 __ Move(rax, Smi::FromInt(NOT_EQUAL));
3068 __ ret(0); 3064 __ ret(0);
3069 3065
3070 // Check if the length is zero. 3066 // Check if the length is zero.
3071 Label compare_chars; 3067 Label compare_chars;
3072 __ bind(&check_zero_length); 3068 __ bind(&check_zero_length);
3073 STATIC_ASSERT(kSmiTag == 0); 3069 STATIC_ASSERT(kSmiTag == 0);
3074 __ SmiTest(length); 3070 __ SmiTest(length);
3075 __ j(not_zero, &compare_chars, Label::kNear); 3071 __ j(not_zero, &compare_chars, Label::kNear);
3076 __ Move(rax, Smi::FromInt(EQUAL)); 3072 __ Move(rax, Smi::FromInt(EQUAL));
3077 __ ret(0); 3073 __ ret(0);
3078 3074
3079 // Compare characters. 3075 // Compare characters.
3080 __ bind(&compare_chars); 3076 __ bind(&compare_chars);
3081 Label strings_not_equal; 3077 Label strings_not_equal;
3082 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, 3078 GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2,
3083 &strings_not_equal, Label::kNear); 3079 &strings_not_equal, Label::kNear);
3084 3080
3085 // Characters are equal. 3081 // Characters are equal.
3086 __ Move(rax, Smi::FromInt(EQUAL)); 3082 __ Move(rax, Smi::FromInt(EQUAL));
3087 __ ret(0); 3083 __ ret(0);
3088 3084
3089 // Characters are not equal. 3085 // Characters are not equal.
3090 __ bind(&strings_not_equal); 3086 __ bind(&strings_not_equal);
3091 __ Move(rax, Smi::FromInt(NOT_EQUAL)); 3087 __ Move(rax, Smi::FromInt(NOT_EQUAL));
3092 __ ret(0); 3088 __ ret(0);
3093 } 3089 }
3094 3090
3095 3091
3096 void StringHelper::GenerateCompareFlatAsciiStrings( 3092 void StringHelper::GenerateCompareFlatOneByteStrings(
3097 MacroAssembler* masm, Register left, Register right, Register scratch1, 3093 MacroAssembler* masm, Register left, Register right, Register scratch1,
3098 Register scratch2, Register scratch3, Register scratch4) { 3094 Register scratch2, Register scratch3, Register scratch4) {
3099 // Ensure that you can always subtract a string length from a non-negative 3095 // Ensure that you can always subtract a string length from a non-negative
3100 // number (e.g. another length). 3096 // number (e.g. another length).
3101 STATIC_ASSERT(String::kMaxLength < 0x7fffffff); 3097 STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
3102 3098
3103 // Find minimum length and length difference. 3099 // Find minimum length and length difference.
3104 __ movp(scratch1, FieldOperand(left, String::kLengthOffset)); 3100 __ movp(scratch1, FieldOperand(left, String::kLengthOffset));
3105 __ movp(scratch4, scratch1); 3101 __ movp(scratch4, scratch1);
3106 __ SmiSub(scratch4, 3102 __ SmiSub(scratch4,
(...skipping 11 matching lines...) Expand all
3118 // Register scratch1 now holds Min(left.length, right.length). 3114 // Register scratch1 now holds Min(left.length, right.length).
3119 const Register min_length = scratch1; 3115 const Register min_length = scratch1;
3120 3116
3121 Label compare_lengths; 3117 Label compare_lengths;
3122 // If min-length is zero, go directly to comparing lengths. 3118 // If min-length is zero, go directly to comparing lengths.
3123 __ SmiTest(min_length); 3119 __ SmiTest(min_length);
3124 __ j(zero, &compare_lengths, Label::kNear); 3120 __ j(zero, &compare_lengths, Label::kNear);
3125 3121
3126 // Compare loop. 3122 // Compare loop.
3127 Label result_not_equal; 3123 Label result_not_equal;
3128 GenerateAsciiCharsCompareLoop(masm, left, right, min_length, scratch2, 3124 GenerateOneByteCharsCompareLoop(
3129 &result_not_equal, 3125 masm, left, right, min_length, scratch2, &result_not_equal,
3130 // In debug-code mode, SmiTest below might push 3126 // In debug-code mode, SmiTest below might push
3131 // the target label outside the near range. 3127 // the target label outside the near range.
3132 Label::kFar); 3128 Label::kFar);
3133 3129
3134 // Completed loop without finding different characters. 3130 // Completed loop without finding different characters.
3135 // Compare lengths (precomputed). 3131 // Compare lengths (precomputed).
3136 __ bind(&compare_lengths); 3132 __ bind(&compare_lengths);
3137 __ SmiTest(length_difference); 3133 __ SmiTest(length_difference);
3138 Label length_not_equal; 3134 Label length_not_equal;
3139 __ j(not_zero, &length_not_equal, Label::kNear); 3135 __ j(not_zero, &length_not_equal, Label::kNear);
3140 3136
3141 // Result is EQUAL. 3137 // Result is EQUAL.
3142 __ Move(rax, Smi::FromInt(EQUAL)); 3138 __ Move(rax, Smi::FromInt(EQUAL));
(...skipping 13 matching lines...) Expand all
3156 __ Move(rax, Smi::FromInt(LESS)); 3152 __ Move(rax, Smi::FromInt(LESS));
3157 __ ret(0); 3153 __ ret(0);
3158 3154
3159 // Result is GREATER. 3155 // Result is GREATER.
3160 __ bind(&result_greater); 3156 __ bind(&result_greater);
3161 __ Move(rax, Smi::FromInt(GREATER)); 3157 __ Move(rax, Smi::FromInt(GREATER));
3162 __ ret(0); 3158 __ ret(0);
3163 } 3159 }
3164 3160
3165 3161
3166 void StringHelper::GenerateAsciiCharsCompareLoop( 3162 void StringHelper::GenerateOneByteCharsCompareLoop(
3167 MacroAssembler* masm, Register left, Register right, Register length, 3163 MacroAssembler* masm, Register left, Register right, Register length,
3168 Register scratch, Label* chars_not_equal, Label::Distance near_jump) { 3164 Register scratch, Label* chars_not_equal, Label::Distance near_jump) {
3169 // Change index to run from -length to -1 by adding length to string 3165 // Change index to run from -length to -1 by adding length to string
3170 // start. This means that loop ends when index reaches zero, which 3166 // start. This means that loop ends when index reaches zero, which
3171 // doesn't need an additional compare. 3167 // doesn't need an additional compare.
3172 __ SmiToInteger32(length, length); 3168 __ SmiToInteger32(length, length);
3173 __ leap(left, 3169 __ leap(left,
3174 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); 3170 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize));
3175 __ leap(right, 3171 __ leap(right,
3176 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); 3172 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize));
(...skipping 27 matching lines...) Expand all
3204 Label not_same; 3200 Label not_same;
3205 __ cmpp(rdx, rax); 3201 __ cmpp(rdx, rax);
3206 __ j(not_equal, &not_same, Label::kNear); 3202 __ j(not_equal, &not_same, Label::kNear);
3207 __ Move(rax, Smi::FromInt(EQUAL)); 3203 __ Move(rax, Smi::FromInt(EQUAL));
3208 Counters* counters = isolate()->counters(); 3204 Counters* counters = isolate()->counters();
3209 __ IncrementCounter(counters->string_compare_native(), 1); 3205 __ IncrementCounter(counters->string_compare_native(), 1);
3210 __ ret(2 * kPointerSize); 3206 __ ret(2 * kPointerSize);
3211 3207
3212 __ bind(&not_same); 3208 __ bind(&not_same);
3213 3209
3214 // Check that both are sequential ASCII strings. 3210 // Check that both are sequential one-byte strings.
3215 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); 3211 __ JumpIfNotBothSequentialOneByteStrings(rdx, rax, rcx, rbx, &runtime);
3216 3212
3217 // Inline comparison of ASCII strings. 3213 // Inline comparison of one-byte strings.
3218 __ IncrementCounter(counters->string_compare_native(), 1); 3214 __ IncrementCounter(counters->string_compare_native(), 1);
3219 // Drop arguments from the stack 3215 // Drop arguments from the stack
3220 __ PopReturnAddressTo(rcx); 3216 __ PopReturnAddressTo(rcx);
3221 __ addp(rsp, Immediate(2 * kPointerSize)); 3217 __ addp(rsp, Immediate(2 * kPointerSize));
3222 __ PushReturnAddressFrom(rcx); 3218 __ PushReturnAddressFrom(rcx);
3223 StringHelper::GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, 3219 StringHelper::GenerateCompareFlatOneByteStrings(masm, rdx, rax, rcx, rbx, rdi,
3224 r8); 3220 r8);
3225 3221
3226 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 3222 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
3227 // tagged as a small integer. 3223 // tagged as a small integer.
3228 __ bind(&runtime); 3224 __ bind(&runtime);
3229 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3225 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3230 } 3226 }
3231 3227
3232 3228
3233 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3229 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3234 // ----------- S t a t e ------------- 3230 // ----------- S t a t e -------------
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
3495 __ orp(tmp1, tmp2); 3491 __ orp(tmp1, tmp2);
3496 __ testb(tmp1, Immediate(kIsNotInternalizedMask)); 3492 __ testb(tmp1, Immediate(kIsNotInternalizedMask));
3497 __ j(not_zero, &do_compare, Label::kNear); 3493 __ j(not_zero, &do_compare, Label::kNear);
3498 // Make sure rax is non-zero. At this point input operands are 3494 // Make sure rax is non-zero. At this point input operands are
3499 // guaranteed to be non-zero. 3495 // guaranteed to be non-zero.
3500 DCHECK(right.is(rax)); 3496 DCHECK(right.is(rax));
3501 __ ret(0); 3497 __ ret(0);
3502 __ bind(&do_compare); 3498 __ bind(&do_compare);
3503 } 3499 }
3504 3500
3505 // Check that both strings are sequential ASCII. 3501 // Check that both strings are sequential one-byte.
3506 Label runtime; 3502 Label runtime;
3507 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); 3503 __ JumpIfNotBothSequentialOneByteStrings(left, right, tmp1, tmp2, &runtime);
3508 3504
3509 // Compare flat ASCII strings. Returns when done. 3505 // Compare flat one-byte strings. Returns when done.
3510 if (equality) { 3506 if (equality) {
3511 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2); 3507 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1,
3508 tmp2);
3512 } else { 3509 } else {
3513 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, 3510 StringHelper::GenerateCompareFlatOneByteStrings(
3514 tmp3, kScratchRegister); 3511 masm, left, right, tmp1, tmp2, tmp3, kScratchRegister);
3515 } 3512 }
3516 3513
3517 // Handle more complex cases in runtime. 3514 // Handle more complex cases in runtime.
3518 __ bind(&runtime); 3515 __ bind(&runtime);
3519 __ PopReturnAddressTo(tmp1); 3516 __ PopReturnAddressTo(tmp1);
3520 __ Push(left); 3517 __ Push(left);
3521 __ Push(right); 3518 __ Push(right);
3522 __ PushReturnAddressFrom(tmp1); 3519 __ PushReturnAddressFrom(tmp1);
3523 if (equality) { 3520 if (equality) {
3524 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); 3521 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
4634 return_value_operand, 4631 return_value_operand,
4635 NULL); 4632 NULL);
4636 } 4633 }
4637 4634
4638 4635
4639 #undef __ 4636 #undef __
4640 4637
4641 } } // namespace v8::internal 4638 } } // namespace v8::internal
4642 4639
4643 #endif // V8_TARGET_ARCH_X64 4640 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/jsregexp.cc ('K') | « src/x64/code-stubs-x64.h ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698