| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 6111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6122 __ lbu(scratch1, MemOperand(src)); | 6122 __ lbu(scratch1, MemOperand(src)); |
| 6123 __ addiu(src, src, 1); | 6123 __ addiu(src, src, 1); |
| 6124 __ sb(scratch1, MemOperand(dest)); | 6124 __ sb(scratch1, MemOperand(dest)); |
| 6125 __ addiu(dest, dest, 1); | 6125 __ addiu(dest, dest, 1); |
| 6126 __ Branch(&byte_loop); | 6126 __ Branch(&byte_loop); |
| 6127 | 6127 |
| 6128 __ bind(&done); | 6128 __ bind(&done); |
| 6129 } | 6129 } |
| 6130 | 6130 |
| 6131 | 6131 |
| 6132 void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, | 6132 void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm, |
| 6133 Register c1, | 6133 Register c1, |
| 6134 Register c2, | 6134 Register c2, |
| 6135 Register scratch1, | 6135 Register scratch1, |
| 6136 Register scratch2, | 6136 Register scratch2, |
| 6137 Register scratch3, | 6137 Register scratch3, |
| 6138 Register scratch4, | 6138 Register scratch4, |
| 6139 Register scratch5, | 6139 Register scratch5, |
| 6140 Label* not_found) { | 6140 Label* not_found) { |
| 6141 // Register scratch3 is the general scratch register in this function. | 6141 // Register scratch3 is the general scratch register in this function. |
| 6142 Register scratch = scratch3; | 6142 Register scratch = scratch3; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 6172 // Collect the two characters in a register. | 6172 // Collect the two characters in a register. |
| 6173 Register chars = c1; | 6173 Register chars = c1; |
| 6174 __ sll(scratch, c2, kBitsPerByte); | 6174 __ sll(scratch, c2, kBitsPerByte); |
| 6175 __ Or(chars, chars, scratch); | 6175 __ Or(chars, chars, scratch); |
| 6176 | 6176 |
| 6177 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. | 6177 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
| 6178 // hash: hash of two character string. | 6178 // hash: hash of two character string. |
| 6179 | 6179 |
| 6180 // Load symbol table. | 6180 // Load symbol table. |
| 6181 // Load address of first element of the symbol table. | 6181 // Load address of first element of the symbol table. |
| 6182 Register symbol_table = c2; | 6182 Register string_table = c2; |
| 6183 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); | 6183 __ LoadRoot(string_table, Heap::kStringTableRootIndex); |
| 6184 | 6184 |
| 6185 Register undefined = scratch4; | 6185 Register undefined = scratch4; |
| 6186 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); | 6186 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); |
| 6187 | 6187 |
| 6188 // Calculate capacity mask from the symbol table capacity. | 6188 // Calculate capacity mask from the symbol table capacity. |
| 6189 Register mask = scratch2; | 6189 Register mask = scratch2; |
| 6190 __ lw(mask, FieldMemOperand(symbol_table, SymbolTable::kCapacityOffset)); | 6190 __ lw(mask, FieldMemOperand(string_table, StringTable::kCapacityOffset)); |
| 6191 __ sra(mask, mask, 1); | 6191 __ sra(mask, mask, 1); |
| 6192 __ Addu(mask, mask, -1); | 6192 __ Addu(mask, mask, -1); |
| 6193 | 6193 |
| 6194 // Calculate untagged address of the first element of the symbol table. | 6194 // Calculate untagged address of the first element of the symbol table. |
| 6195 Register first_symbol_table_element = symbol_table; | 6195 Register first_string_table_element = string_table; |
| 6196 __ Addu(first_symbol_table_element, symbol_table, | 6196 __ Addu(first_string_table_element, string_table, |
| 6197 Operand(SymbolTable::kElementsStartOffset - kHeapObjectTag)); | 6197 Operand(StringTable::kElementsStartOffset - kHeapObjectTag)); |
| 6198 | 6198 |
| 6199 // Registers. | 6199 // Registers. |
| 6200 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. | 6200 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
| 6201 // hash: hash of two character string | 6201 // hash: hash of two character string |
| 6202 // mask: capacity mask | 6202 // mask: capacity mask |
| 6203 // first_symbol_table_element: address of the first element of | 6203 // first_string_table_element: address of the first element of |
| 6204 // the symbol table | 6204 // the symbol table |
| 6205 // undefined: the undefined object | 6205 // undefined: the undefined object |
| 6206 // scratch: - | 6206 // scratch: - |
| 6207 | 6207 |
| 6208 // Perform a number of probes in the symbol table. | 6208 // Perform a number of probes in the symbol table. |
| 6209 const int kProbes = 4; | 6209 const int kProbes = 4; |
| 6210 Label found_in_symbol_table; | 6210 Label found_in_string_table; |
| 6211 Label next_probe[kProbes]; | 6211 Label next_probe[kProbes]; |
| 6212 Register candidate = scratch5; // Scratch register contains candidate. | 6212 Register candidate = scratch5; // Scratch register contains candidate. |
| 6213 for (int i = 0; i < kProbes; i++) { | 6213 for (int i = 0; i < kProbes; i++) { |
| 6214 // Calculate entry in symbol table. | 6214 // Calculate entry in symbol table. |
| 6215 if (i > 0) { | 6215 if (i > 0) { |
| 6216 __ Addu(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); | 6216 __ Addu(candidate, hash, Operand(StringTable::GetProbeOffset(i))); |
| 6217 } else { | 6217 } else { |
| 6218 __ mov(candidate, hash); | 6218 __ mov(candidate, hash); |
| 6219 } | 6219 } |
| 6220 | 6220 |
| 6221 __ And(candidate, candidate, Operand(mask)); | 6221 __ And(candidate, candidate, Operand(mask)); |
| 6222 | 6222 |
| 6223 // Load the entry from the symble table. | 6223 // Load the entry from the symble table. |
| 6224 STATIC_ASSERT(SymbolTable::kEntrySize == 1); | 6224 STATIC_ASSERT(StringTable::kEntrySize == 1); |
| 6225 __ sll(scratch, candidate, kPointerSizeLog2); | 6225 __ sll(scratch, candidate, kPointerSizeLog2); |
| 6226 __ Addu(scratch, scratch, first_symbol_table_element); | 6226 __ Addu(scratch, scratch, first_string_table_element); |
| 6227 __ lw(candidate, MemOperand(scratch)); | 6227 __ lw(candidate, MemOperand(scratch)); |
| 6228 | 6228 |
| 6229 // If entry is undefined no string with this hash can be found. | 6229 // If entry is undefined no string with this hash can be found. |
| 6230 Label is_string; | 6230 Label is_string; |
| 6231 __ GetObjectType(candidate, scratch, scratch); | 6231 __ GetObjectType(candidate, scratch, scratch); |
| 6232 __ Branch(&is_string, ne, scratch, Operand(ODDBALL_TYPE)); | 6232 __ Branch(&is_string, ne, scratch, Operand(ODDBALL_TYPE)); |
| 6233 | 6233 |
| 6234 __ Branch(not_found, eq, undefined, Operand(candidate)); | 6234 __ Branch(not_found, eq, undefined, Operand(candidate)); |
| 6235 // Must be the hole (deleted entry). | 6235 // Must be the hole (deleted entry). |
| 6236 if (FLAG_debug_code) { | 6236 if (FLAG_debug_code) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6247 // operation. | 6247 // operation. |
| 6248 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]); | 6248 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]); |
| 6249 | 6249 |
| 6250 // If length is not 2 the string is not a candidate. | 6250 // If length is not 2 the string is not a candidate. |
| 6251 __ lw(scratch, FieldMemOperand(candidate, String::kLengthOffset)); | 6251 __ lw(scratch, FieldMemOperand(candidate, String::kLengthOffset)); |
| 6252 __ Branch(&next_probe[i], ne, scratch, Operand(Smi::FromInt(2))); | 6252 __ Branch(&next_probe[i], ne, scratch, Operand(Smi::FromInt(2))); |
| 6253 | 6253 |
| 6254 // Check if the two characters match. | 6254 // Check if the two characters match. |
| 6255 // Assumes that word load is little endian. | 6255 // Assumes that word load is little endian. |
| 6256 __ lhu(scratch, FieldMemOperand(candidate, SeqOneByteString::kHeaderSize)); | 6256 __ lhu(scratch, FieldMemOperand(candidate, SeqOneByteString::kHeaderSize)); |
| 6257 __ Branch(&found_in_symbol_table, eq, chars, Operand(scratch)); | 6257 __ Branch(&found_in_string_table, eq, chars, Operand(scratch)); |
| 6258 __ bind(&next_probe[i]); | 6258 __ bind(&next_probe[i]); |
| 6259 } | 6259 } |
| 6260 | 6260 |
| 6261 // No matching 2 character string found by probing. | 6261 // No matching 2 character string found by probing. |
| 6262 __ jmp(not_found); | 6262 __ jmp(not_found); |
| 6263 | 6263 |
| 6264 // Scratch register contains result when we fall through to here. | 6264 // Scratch register contains result when we fall through to here. |
| 6265 Register result = candidate; | 6265 Register result = candidate; |
| 6266 __ bind(&found_in_symbol_table); | 6266 __ bind(&found_in_string_table); |
| 6267 __ mov(v0, result); | 6267 __ mov(v0, result); |
| 6268 } | 6268 } |
| 6269 | 6269 |
| 6270 | 6270 |
| 6271 void StringHelper::GenerateHashInit(MacroAssembler* masm, | 6271 void StringHelper::GenerateHashInit(MacroAssembler* masm, |
| 6272 Register hash, | 6272 Register hash, |
| 6273 Register character) { | 6273 Register character) { |
| 6274 // hash = seed + character + ((seed + character) << 10); | 6274 // hash = seed + character + ((seed + character) << 10); |
| 6275 __ LoadRoot(hash, Heap::kHashSeedRootIndex); | 6275 __ LoadRoot(hash, Heap::kHashSeedRootIndex); |
| 6276 // Untag smi seed and add the character. | 6276 // Untag smi seed and add the character. |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6778 __ JumpIfBothInstanceTypesAreNotSequentialAscii(t0, t1, t2, t3, | 6778 __ JumpIfBothInstanceTypesAreNotSequentialAscii(t0, t1, t2, t3, |
| 6779 &call_runtime); | 6779 &call_runtime); |
| 6780 | 6780 |
| 6781 // Get the two characters forming the sub string. | 6781 // Get the two characters forming the sub string. |
| 6782 __ lbu(a2, FieldMemOperand(a0, SeqOneByteString::kHeaderSize)); | 6782 __ lbu(a2, FieldMemOperand(a0, SeqOneByteString::kHeaderSize)); |
| 6783 __ lbu(a3, FieldMemOperand(a1, SeqOneByteString::kHeaderSize)); | 6783 __ lbu(a3, FieldMemOperand(a1, SeqOneByteString::kHeaderSize)); |
| 6784 | 6784 |
| 6785 // Try to lookup two character string in symbol table. If it is not found | 6785 // Try to lookup two character string in symbol table. If it is not found |
| 6786 // just allocate a new one. | 6786 // just allocate a new one. |
| 6787 Label make_two_character_string; | 6787 Label make_two_character_string; |
| 6788 StringHelper::GenerateTwoCharacterSymbolTableProbe( | 6788 StringHelper::GenerateTwoCharacterStringTableProbe( |
| 6789 masm, a2, a3, t2, t3, t0, t1, t5, &make_two_character_string); | 6789 masm, a2, a3, t2, t3, t0, t1, t5, &make_two_character_string); |
| 6790 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); | 6790 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); |
| 6791 __ DropAndRet(2); | 6791 __ DropAndRet(2); |
| 6792 | 6792 |
| 6793 __ bind(&make_two_character_string); | 6793 __ bind(&make_two_character_string); |
| 6794 // Resulting string has length 2 and first chars of two strings | 6794 // Resulting string has length 2 and first chars of two strings |
| 6795 // are combined into single halfword in a2 register. | 6795 // are combined into single halfword in a2 register. |
| 6796 // So we can fill resulting string without two loops by a single | 6796 // So we can fill resulting string without two loops by a single |
| 6797 // halfword store instruction (which assumes that processor is | 6797 // halfword store instruction (which assumes that processor is |
| 6798 // in a little endian mode). | 6798 // in a little endian mode). |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8045 __ Pop(ra, t1, a1); | 8045 __ Pop(ra, t1, a1); |
| 8046 __ Ret(); | 8046 __ Ret(); |
| 8047 } | 8047 } |
| 8048 | 8048 |
| 8049 | 8049 |
| 8050 #undef __ | 8050 #undef __ |
| 8051 | 8051 |
| 8052 } } // namespace v8::internal | 8052 } } // namespace v8::internal |
| 8053 | 8053 |
| 8054 #endif // V8_TARGET_ARCH_MIPS | 8054 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |