OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 9623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9634 __ mov(eax, edx); | 9634 __ mov(eax, edx); |
9635 __ IncrementCounter(&Counters::string_add_native, 1); | 9635 __ IncrementCounter(&Counters::string_add_native, 1); |
9636 __ ret(2 * kPointerSize); | 9636 __ ret(2 * kPointerSize); |
9637 | 9637 |
9638 // Both strings are non-empty. | 9638 // Both strings are non-empty. |
9639 // eax: first string | 9639 // eax: first string |
9640 // ebx: length of first string | 9640 // ebx: length of first string |
9641 // ecx: length of second string | 9641 // ecx: length of second string |
9642 // edx: second string | 9642 // edx: second string |
9643 // Look at the length of the result of adding the two strings. | 9643 // Look at the length of the result of adding the two strings. |
9644 Label string_add_flat_result; | 9644 Label string_add_flat_result, longer_than_two; |
9645 __ bind(&both_not_zero_length); | 9645 __ bind(&both_not_zero_length); |
9646 __ add(ebx, Operand(ecx)); | 9646 __ add(ebx, Operand(ecx)); |
9647 // Use the runtime system when adding two one character strings, as it | 9647 // Use the runtime system when adding two one character strings, as it |
9648 // contains optimizations for this specific case using the symbol table. | 9648 // contains optimizations for this specific case using the symbol table. |
9649 __ cmp(ebx, 2); | 9649 __ cmp(ebx, 2); |
9650 __ j(equal, &string_add_runtime); | 9650 __ j(not_equal, &longer_than_two); |
| 9651 |
| 9652 // Check that both strings are non-external ascii strings. |
| 9653 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, |
| 9654 &string_add_runtime); |
| 9655 |
| 9656 // Get the two characters forming the sub string. |
| 9657 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); |
| 9658 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); |
| 9659 |
| 9660 // Try to lookup two character string in symbol table. If it is not found |
| 9661 // just allocate a new one. |
| 9662 Label make_two_character_string, make_flat_ascii_string; |
| 9663 GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi, |
| 9664 &make_two_character_string); |
| 9665 __ ret(2 * kPointerSize); |
| 9666 |
| 9667 __ bind(&make_two_character_string); |
| 9668 __ Set(ebx, Immediate(2)); |
| 9669 __ jmp(&make_flat_ascii_string); |
| 9670 |
| 9671 __ bind(&longer_than_two); |
9651 // Check if resulting string will be flat. | 9672 // Check if resulting string will be flat. |
9652 __ cmp(ebx, String::kMinNonFlatLength); | 9673 __ cmp(ebx, String::kMinNonFlatLength); |
9653 __ j(below, &string_add_flat_result); | 9674 __ j(below, &string_add_flat_result); |
9654 // Handle exceptionally long strings in the runtime system. | 9675 // Handle exceptionally long strings in the runtime system. |
9655 ASSERT((String::kMaxLength & 0x80000000) == 0); | 9676 ASSERT((String::kMaxLength & 0x80000000) == 0); |
9656 __ cmp(ebx, String::kMaxLength); | 9677 __ cmp(ebx, String::kMaxLength); |
9657 __ j(above, &string_add_runtime); | 9678 __ j(above, &string_add_runtime); |
9658 | 9679 |
9659 // If result is not supposed to be flat allocate a cons string object. If both | 9680 // If result is not supposed to be flat allocate a cons string object. If both |
9660 // strings are ascii the result is an ascii cons string. | 9681 // strings are ascii the result is an ascii cons string. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9707 Label non_ascii_string_add_flat_result; | 9728 Label non_ascii_string_add_flat_result; |
9708 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 9729 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
9709 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 9730 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
9710 ASSERT(kStringEncodingMask == kAsciiStringTag); | 9731 ASSERT(kStringEncodingMask == kAsciiStringTag); |
9711 __ test(ecx, Immediate(kAsciiStringTag)); | 9732 __ test(ecx, Immediate(kAsciiStringTag)); |
9712 __ j(zero, &non_ascii_string_add_flat_result); | 9733 __ j(zero, &non_ascii_string_add_flat_result); |
9713 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 9734 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
9714 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 9735 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
9715 __ test(ecx, Immediate(kAsciiStringTag)); | 9736 __ test(ecx, Immediate(kAsciiStringTag)); |
9716 __ j(zero, &string_add_runtime); | 9737 __ j(zero, &string_add_runtime); |
| 9738 |
| 9739 __ bind(&make_flat_ascii_string); |
9717 // Both strings are ascii strings. As they are short they are both flat. | 9740 // Both strings are ascii strings. As they are short they are both flat. |
| 9741 // ebx: length of resulting flat string |
9718 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); | 9742 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); |
9719 // eax: result string | 9743 // eax: result string |
9720 __ mov(ecx, eax); | 9744 __ mov(ecx, eax); |
9721 // Locate first character of result. | 9745 // Locate first character of result. |
9722 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 9746 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
9723 // Load first argument and locate first character. | 9747 // Load first argument and locate first character. |
9724 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 9748 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
9725 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); | 9749 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); |
9726 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 9750 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
9727 // eax: result string | 9751 // eax: result string |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9864 __ mov_b(Operand(dest, 0), scratch); | 9888 __ mov_b(Operand(dest, 0), scratch); |
9865 __ add(Operand(src), Immediate(1)); | 9889 __ add(Operand(src), Immediate(1)); |
9866 __ add(Operand(dest), Immediate(1)); | 9890 __ add(Operand(dest), Immediate(1)); |
9867 __ sub(Operand(count), Immediate(1)); | 9891 __ sub(Operand(count), Immediate(1)); |
9868 __ j(not_zero, &loop); | 9892 __ j(not_zero, &loop); |
9869 | 9893 |
9870 __ bind(&done); | 9894 __ bind(&done); |
9871 } | 9895 } |
9872 | 9896 |
9873 | 9897 |
| 9898 void StringStubBase::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
| 9899 Register c1, |
| 9900 Register c2, |
| 9901 Register scratch1, |
| 9902 Register scratch2, |
| 9903 Register scratch3, |
| 9904 Label* not_found) { |
| 9905 // Register scratch3 is the general scratch register in this function. |
| 9906 Register scratch = scratch3; |
| 9907 |
| 9908 // Make sure that both characters are not digits as such strings has a |
| 9909 // different hash algorithm. Don't try to look for these in the symbol table. |
| 9910 Label not_array_index; |
| 9911 __ mov(scratch, c1); |
| 9912 __ sub(Operand(scratch), Immediate(static_cast<int>('0'))); |
| 9913 __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0'))); |
| 9914 __ j(above, ¬_array_index); |
| 9915 __ mov(scratch, c2); |
| 9916 __ sub(Operand(scratch), Immediate(static_cast<int>('0'))); |
| 9917 __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0'))); |
| 9918 __ j(below_equal, not_found); |
| 9919 |
| 9920 __ bind(¬_array_index); |
| 9921 // Calculate the two character string hash. |
| 9922 Register hash = scratch1; |
| 9923 GenerateHashInit(masm, hash, c1, scratch); |
| 9924 GenerateHashAddCharacter(masm, hash, c2, scratch); |
| 9925 GenerateHashGetHash(masm, hash, scratch); |
| 9926 |
| 9927 // Collect the two characters in a register. |
| 9928 Register chars = c1; |
| 9929 __ shl(c2, kBitsPerByte); |
| 9930 __ or_(chars, Operand(c2)); |
| 9931 |
| 9932 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
| 9933 // hash: hash of two character string. |
| 9934 |
| 9935 // Load the symbol table. |
| 9936 Register symbol_table = c2; |
| 9937 ExternalReference roots_address = ExternalReference::roots_address(); |
| 9938 __ mov(scratch, Immediate(Heap::kSymbolTableRootIndex)); |
| 9939 __ mov(symbol_table, |
| 9940 Operand::StaticArray(scratch, times_pointer_size, roots_address)); |
| 9941 |
| 9942 // Calculate capacity mask from the symbol table capacity. |
| 9943 Register mask = scratch2; |
| 9944 static const int kCapacityOffset = |
| 9945 FixedArray::kHeaderSize + |
| 9946 SymbolTable::kCapacityIndex * kPointerSize; |
| 9947 __ mov(mask, FieldOperand(symbol_table, kCapacityOffset)); |
| 9948 __ SmiUntag(mask); |
| 9949 __ sub(Operand(mask), Immediate(1)); |
| 9950 |
| 9951 // Registers |
| 9952 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
| 9953 // hash: hash of two character string |
| 9954 // symbol_table: symbol table |
| 9955 // mask: capacity mask |
| 9956 // scratch: - |
| 9957 |
| 9958 // Perform a number of probes in the symbol table. |
| 9959 static const int kProbes = 4; |
| 9960 Label found_in_symbol_table; |
| 9961 Label next_probe[kProbes], next_probe_pop_mask[kProbes]; |
| 9962 for (int i = 0; i < kProbes; i++) { |
| 9963 // Calculate entry in symbol table. |
| 9964 __ mov(scratch, hash); |
| 9965 if (i > 0) { |
| 9966 __ add(Operand(scratch), Immediate(SymbolTable::GetProbeOffset(i))); |
| 9967 } |
| 9968 __ and_(scratch, Operand(mask)); |
| 9969 |
| 9970 // Load the entry from the symble table. |
| 9971 Register candidate = scratch; // Scratch register contains candidate. |
| 9972 ASSERT_EQ(1, SymbolTableShape::kEntrySize); |
| 9973 static const int kFirstElementOffset = |
| 9974 FixedArray::kHeaderSize + |
| 9975 SymbolTable::kPrefixStartIndex * kPointerSize + |
| 9976 SymbolTableShape::kPrefixSize * kPointerSize; |
| 9977 __ mov(candidate, |
| 9978 FieldOperand(symbol_table, |
| 9979 scratch, |
| 9980 times_pointer_size, |
| 9981 kFirstElementOffset)); |
| 9982 |
| 9983 // If entry is undefined no string with this hash can be found. |
| 9984 __ cmp(candidate, Factory::undefined_value()); |
| 9985 __ j(equal, not_found); |
| 9986 |
| 9987 // If length is not 2 the string is not a candidate. |
| 9988 __ cmp(FieldOperand(candidate, String::kLengthOffset), Immediate(2)); |
| 9989 __ j(not_equal, &next_probe[i]); |
| 9990 |
| 9991 // As we are out of registers save the mask on the stack and use that as a |
| 9992 // temporary. |
| 9993 __ push(mask); |
| 9994 Register temp = mask; |
| 9995 |
| 9996 // Check that the candidate is a non-external ascii string. |
| 9997 __ mov(temp, FieldOperand(candidate, HeapObject::kMapOffset)); |
| 9998 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); |
| 9999 __ JumpIfInstanceTypeIsNotSequentialAscii( |
| 10000 temp, temp, &next_probe_pop_mask[i]); |
| 10001 |
| 10002 // Check if the two characters match. |
| 10003 __ mov(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); |
| 10004 __ and_(temp, 0x0000ffff); |
| 10005 __ cmp(chars, Operand(temp)); |
| 10006 __ j(equal, &found_in_symbol_table); |
| 10007 __ bind(&next_probe_pop_mask[i]); |
| 10008 __ pop(mask); |
| 10009 __ bind(&next_probe[i]); |
| 10010 } |
| 10011 |
| 10012 // No matching 2 character string found by probing. |
| 10013 __ jmp(not_found); |
| 10014 |
| 10015 // Scratch register contains result when we fall through to here. |
| 10016 Register result = scratch; |
| 10017 __ bind(&found_in_symbol_table); |
| 10018 __ pop(mask); // Pop temporally saved mask from the stack. |
| 10019 if (!result.is(eax)) { |
| 10020 __ mov(eax, result); |
| 10021 } |
| 10022 } |
| 10023 |
| 10024 |
| 10025 void StringStubBase::GenerateHashInit(MacroAssembler* masm, |
| 10026 Register hash, |
| 10027 Register character, |
| 10028 Register scratch) { |
| 10029 // hash = character + (character << 10); |
| 10030 __ mov(hash, character); |
| 10031 __ shl(hash, 10); |
| 10032 __ add(hash, Operand(character)); |
| 10033 // hash ^= hash >> 6; |
| 10034 __ mov(scratch, hash); |
| 10035 __ sar(scratch, 6); |
| 10036 __ xor_(hash, Operand(scratch)); |
| 10037 } |
| 10038 |
| 10039 |
| 10040 void StringStubBase::GenerateHashAddCharacter(MacroAssembler* masm, |
| 10041 Register hash, |
| 10042 Register character, |
| 10043 Register scratch) { |
| 10044 // hash += character; |
| 10045 __ add(hash, Operand(character)); |
| 10046 // hash += hash << 10; |
| 10047 __ mov(scratch, hash); |
| 10048 __ shl(scratch, 10); |
| 10049 __ add(hash, Operand(scratch)); |
| 10050 // hash ^= hash >> 6; |
| 10051 __ mov(scratch, hash); |
| 10052 __ sar(scratch, 6); |
| 10053 __ xor_(hash, Operand(scratch)); |
| 10054 } |
| 10055 |
| 10056 |
| 10057 void StringStubBase::GenerateHashGetHash(MacroAssembler* masm, |
| 10058 Register hash, |
| 10059 Register scratch) { |
| 10060 // hash += hash << 3; |
| 10061 __ mov(scratch, hash); |
| 10062 __ shl(scratch, 3); |
| 10063 __ add(hash, Operand(scratch)); |
| 10064 // hash ^= hash >> 11; |
| 10065 __ mov(scratch, hash); |
| 10066 __ sar(scratch, 11); |
| 10067 __ xor_(hash, Operand(scratch)); |
| 10068 // hash += hash << 15; |
| 10069 __ mov(scratch, hash); |
| 10070 __ shl(scratch, 15); |
| 10071 __ add(hash, Operand(scratch)); |
| 10072 |
| 10073 // if (hash == 0) hash = 27; |
| 10074 Label hash_not_zero; |
| 10075 __ test(hash, Operand(hash)); |
| 10076 __ j(not_zero, &hash_not_zero); |
| 10077 __ mov(hash, Immediate(27)); |
| 10078 __ bind(&hash_not_zero); |
| 10079 } |
| 10080 |
| 10081 |
9874 void SubStringStub::Generate(MacroAssembler* masm) { | 10082 void SubStringStub::Generate(MacroAssembler* masm) { |
9875 Label runtime; | 10083 Label runtime; |
9876 | 10084 |
9877 // Stack frame on entry. | 10085 // Stack frame on entry. |
9878 // esp[0]: return address | 10086 // esp[0]: return address |
9879 // esp[4]: to | 10087 // esp[4]: to |
9880 // esp[8]: from | 10088 // esp[8]: from |
9881 // esp[12]: string | 10089 // esp[12]: string |
9882 | 10090 |
9883 // Make sure first argument is a string. | 10091 // Make sure first argument is a string. |
9884 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 10092 __ mov(eax, Operand(esp, 3 * kPointerSize)); |
9885 ASSERT_EQ(0, kSmiTag); | 10093 ASSERT_EQ(0, kSmiTag); |
9886 __ test(eax, Immediate(kSmiTagMask)); | 10094 __ test(eax, Immediate(kSmiTagMask)); |
9887 __ j(zero, &runtime); | 10095 __ j(zero, &runtime); |
9888 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); | 10096 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); |
9889 __ j(NegateCondition(is_string), &runtime); | 10097 __ j(NegateCondition(is_string), &runtime); |
9890 | 10098 |
9891 // eax: string | 10099 // eax: string |
9892 // ebx: instance type | 10100 // ebx: instance type |
9893 // Calculate length of sub string using the smi values. | 10101 // Calculate length of sub string using the smi values. |
9894 __ mov(ecx, Operand(esp, 1 * kPointerSize)); // to | 10102 Label result_longer_than_two; |
| 10103 __ mov(ecx, Operand(esp, 1 * kPointerSize)); // To index. |
9895 __ test(ecx, Immediate(kSmiTagMask)); | 10104 __ test(ecx, Immediate(kSmiTagMask)); |
9896 __ j(not_zero, &runtime); | 10105 __ j(not_zero, &runtime); |
9897 __ mov(edx, Operand(esp, 2 * kPointerSize)); // from | 10106 __ mov(edx, Operand(esp, 2 * kPointerSize)); // From index. |
9898 __ test(edx, Immediate(kSmiTagMask)); | 10107 __ test(edx, Immediate(kSmiTagMask)); |
9899 __ j(not_zero, &runtime); | 10108 __ j(not_zero, &runtime); |
9900 __ sub(ecx, Operand(edx)); | 10109 __ sub(ecx, Operand(edx)); |
9901 // Handle sub-strings of length 2 and less in the runtime system. | 10110 // Special handling of sub-strings of length 1 and 2. One character strings |
| 10111 // are handled in the runtime system (looked up in the single character |
| 10112 // cache). Two character strings are looked for in the symbol cache. |
9902 __ SmiUntag(ecx); // Result length is no longer smi. | 10113 __ SmiUntag(ecx); // Result length is no longer smi. |
9903 __ cmp(ecx, 2); | 10114 __ cmp(ecx, 2); |
9904 __ j(below_equal, &runtime); | 10115 __ j(greater, &result_longer_than_two); |
| 10116 __ j(less, &runtime); |
9905 | 10117 |
| 10118 // Sub string of length 2 requested. |
| 10119 // eax: string |
| 10120 // ebx: instance type |
| 10121 // ecx: sub string length (value is 2) |
| 10122 // edx: from index (smi) |
| 10123 __ JumpIfInstanceTypeIsNotSequentialAscii(ebx, ebx, &runtime); |
| 10124 |
| 10125 // Get the two characters forming the sub string. |
| 10126 __ SmiUntag(edx); // From index is no longer smi. |
| 10127 __ movzx_b(ebx, FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize)); |
| 10128 __ movzx_b(ecx, |
| 10129 FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize + 1)); |
| 10130 |
| 10131 // Try to lookup two character string in symbol table. |
| 10132 Label make_two_character_string; |
| 10133 GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi, |
| 10134 &make_two_character_string); |
| 10135 __ ret(2 * kPointerSize); |
| 10136 |
| 10137 __ bind(&make_two_character_string); |
| 10138 // Setup registers for allocating the two character string. |
| 10139 __ mov(eax, Operand(esp, 3 * kPointerSize)); |
| 10140 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 10141 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 10142 __ Set(ecx, Immediate(2)); |
| 10143 |
| 10144 __ bind(&result_longer_than_two); |
9906 // eax: string | 10145 // eax: string |
9907 // ebx: instance type | 10146 // ebx: instance type |
9908 // ecx: result string length | 10147 // ecx: result string length |
9909 // Check for flat ascii string | 10148 // Check for flat ascii string |
9910 Label non_ascii_flat; | 10149 Label non_ascii_flat; |
9911 __ and_(ebx, kStringRepresentationMask | kStringEncodingMask); | 10150 __ JumpIfInstanceTypeIsNotSequentialAscii(ebx, ebx, &non_ascii_flat); |
9912 __ cmp(ebx, kSeqStringTag | kAsciiStringTag); | |
9913 __ j(not_equal, &non_ascii_flat); | |
9914 | 10151 |
9915 // Allocate the result. | 10152 // Allocate the result. |
9916 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime); | 10153 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime); |
9917 | 10154 |
9918 // eax: result string | 10155 // eax: result string |
9919 // ecx: result string length | 10156 // ecx: result string length |
9920 __ mov(edx, esi); // esi used by following code. | 10157 __ mov(edx, esi); // esi used by following code. |
9921 // Locate first character of result. | 10158 // Locate first character of result. |
9922 __ mov(edi, eax); | 10159 __ mov(edi, eax); |
9923 __ add(Operand(edi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 10160 __ add(Operand(edi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10094 | 10331 |
10095 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 10332 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
10096 // tagged as a small integer. | 10333 // tagged as a small integer. |
10097 __ bind(&runtime); | 10334 __ bind(&runtime); |
10098 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 10335 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
10099 } | 10336 } |
10100 | 10337 |
10101 #undef __ | 10338 #undef __ |
10102 | 10339 |
10103 } } // namespace v8::internal | 10340 } } // namespace v8::internal |
OLD | NEW |