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 |