Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 5025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5036 } | 5036 } |
| 5037 | 5037 |
| 5038 | 5038 |
| 5039 void StringCharAtGenerator::GenerateSlow( | 5039 void StringCharAtGenerator::GenerateSlow( |
| 5040 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 5040 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { |
| 5041 char_code_at_generator_.GenerateSlow(masm, call_helper); | 5041 char_code_at_generator_.GenerateSlow(masm, call_helper); |
| 5042 char_from_code_generator_.GenerateSlow(masm, call_helper); | 5042 char_from_code_generator_.GenerateSlow(masm, call_helper); |
| 5043 } | 5043 } |
| 5044 | 5044 |
| 5045 | 5045 |
| 5046 class StringHelper : public AllStatic { | |
| 5047 public: | |
| 5048 // Generate code for copying characters using a simple loop. This should only | |
| 5049 // be used in places where the number of characters is small and the | |
| 5050 // additional setup and checking in GenerateCopyCharactersLong adds too much | |
| 5051 // overhead. Copying of overlapping regions is not supported. | |
| 5052 // Dest register ends at the position after the last character written. | |
| 5053 static void GenerateCopyCharacters(MacroAssembler* masm, | |
| 5054 Register dest, | |
| 5055 Register src, | |
| 5056 Register count, | |
| 5057 Register scratch, | |
| 5058 bool ascii); | |
| 5059 | |
| 5060 // Generate code for copying a large number of characters. This function | |
| 5061 // is allowed to spend extra time setting up conditions to make copying | |
| 5062 // faster. Copying of overlapping regions is not supported. | |
| 5063 // Dest register ends at the position after the last character written. | |
| 5064 static void GenerateCopyCharactersLong(MacroAssembler* masm, | |
| 5065 Register dest, | |
| 5066 Register src, | |
| 5067 Register count, | |
| 5068 Register scratch1, | |
| 5069 Register scratch2, | |
| 5070 Register scratch3, | |
| 5071 Register scratch4, | |
| 5072 Register scratch5, | |
| 5073 int flags); | |
| 5074 | |
| 5075 | |
| 5076 // Probe the symbol table for a two character string. If the string is | |
| 5077 // not found by probing a jump to the label not_found is performed. This jump | |
| 5078 // does not guarantee that the string is not in the symbol table. If the | |
| 5079 // string is found the code falls through with the string in register r0. | |
| 5080 // Contents of both c1 and c2 registers are modified. At the exit c1 is | |
| 5081 // guaranteed to contain halfword with low and high bytes equal to | |
| 5082 // initial contents of c1 and c2 respectively. | |
| 5083 static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, | |
| 5084 Register c1, | |
| 5085 Register c2, | |
| 5086 Register scratch1, | |
| 5087 Register scratch2, | |
| 5088 Register scratch3, | |
| 5089 Register scratch4, | |
| 5090 Register scratch5, | |
| 5091 Label* not_found); | |
| 5092 | |
| 5093 // Generate string hash. | |
| 5094 static void GenerateHashInit(MacroAssembler* masm, | |
| 5095 Register hash, | |
| 5096 Register character); | |
| 5097 | |
| 5098 static void GenerateHashAddCharacter(MacroAssembler* masm, | |
| 5099 Register hash, | |
| 5100 Register character); | |
| 5101 | |
| 5102 static void GenerateHashGetHash(MacroAssembler* masm, | |
| 5103 Register hash); | |
| 5104 | |
| 5105 private: | |
| 5106 DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); | |
| 5107 }; | |
| 5108 | |
| 5109 | |
| 5110 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, | 5046 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, |
| 5111 Register dest, | 5047 Register dest, |
| 5112 Register src, | 5048 Register src, |
| 5113 Register count, | 5049 Register count, |
| 5114 Register scratch, | 5050 Register scratch, |
| 5115 bool ascii) { | 5051 bool ascii) { |
| 5116 Label loop; | 5052 Label loop; |
| 5117 Label done; | 5053 Label done; |
| 5118 // This loop just copies one character at a time, as it is only used for very | 5054 // This loop just copies one character at a time, as it is only used for very |
| 5119 // short strings. | 5055 // short strings. |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5352 // mask: capacity mask | 5288 // mask: capacity mask |
| 5353 // first_symbol_table_element: address of the first element of | 5289 // first_symbol_table_element: address of the first element of |
| 5354 // the symbol table | 5290 // the symbol table |
| 5355 // undefined: the undefined object | 5291 // undefined: the undefined object |
| 5356 // scratch: - | 5292 // scratch: - |
| 5357 | 5293 |
| 5358 // Perform a number of probes in the symbol table. | 5294 // Perform a number of probes in the symbol table. |
| 5359 static const int kProbes = 4; | 5295 static const int kProbes = 4; |
| 5360 Label found_in_symbol_table; | 5296 Label found_in_symbol_table; |
| 5361 Label next_probe[kProbes]; | 5297 Label next_probe[kProbes]; |
| 5298 Register candidate = scratch5; // Scratch register contains candidate. | |
| 5362 for (int i = 0; i < kProbes; i++) { | 5299 for (int i = 0; i < kProbes; i++) { |
| 5363 Register candidate = scratch5; // Scratch register contains candidate. | |
| 5364 | |
| 5365 // Calculate entry in symbol table. | 5300 // Calculate entry in symbol table. |
| 5366 if (i > 0) { | 5301 if (i > 0) { |
| 5367 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); | 5302 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); |
| 5368 } else { | 5303 } else { |
| 5369 __ mov(candidate, hash); | 5304 __ mov(candidate, hash); |
| 5370 } | 5305 } |
| 5371 | 5306 |
| 5372 __ and_(candidate, candidate, Operand(mask)); | 5307 __ and_(candidate, candidate, Operand(mask)); |
| 5373 | 5308 |
| 5374 // Load the entry from the symble table. | 5309 // Load the entry from the symble table. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5411 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize)); | 5346 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize)); |
| 5412 __ cmp(chars, scratch); | 5347 __ cmp(chars, scratch); |
| 5413 __ b(eq, &found_in_symbol_table); | 5348 __ b(eq, &found_in_symbol_table); |
| 5414 __ bind(&next_probe[i]); | 5349 __ bind(&next_probe[i]); |
| 5415 } | 5350 } |
| 5416 | 5351 |
| 5417 // No matching 2 character string found by probing. | 5352 // No matching 2 character string found by probing. |
| 5418 __ jmp(not_found); | 5353 __ jmp(not_found); |
| 5419 | 5354 |
| 5420 // Scratch register contains result when we fall through to here. | 5355 // Scratch register contains result when we fall through to here. |
| 5421 Register result = scratch; | 5356 Register result = candidate; |
| 5422 __ bind(&found_in_symbol_table); | 5357 __ bind(&found_in_symbol_table); |
| 5423 __ Move(r0, result); | 5358 __ Move(r0, result); |
| 5424 } | 5359 } |
| 5425 | 5360 |
| 5426 | 5361 |
| 5427 void StringHelper::GenerateHashInit(MacroAssembler* masm, | 5362 void StringHelper::GenerateHashInit(MacroAssembler* masm, |
| 5428 Register hash, | 5363 Register hash, |
| 5429 Register character) { | 5364 Register character) { |
| 5430 // hash = character + (character << 10); | 5365 // hash = character + (character << 10); |
| 5431 __ add(hash, character, Operand(character, LSL, 10)); | 5366 __ LoadRoot(hash, Heap::kStringHashSeedRootIndex); |
| 5367 // Untag smi seed and add the character. | |
| 5368 __ add(hash, character, Operand(hash, LSR, kSmiTagSize)); | |
| 5369 // hash += hash << 10; | |
| 5370 __ add(hash, hash, Operand(hash, LSL, 10)); | |
| 5432 // hash ^= hash >> 6; | 5371 // hash ^= hash >> 6; |
| 5433 __ eor(hash, hash, Operand(hash, ASR, 6)); | 5372 __ eor(hash, hash, Operand(hash, LSR, 6)); |
| 5434 } | 5373 } |
| 5435 | 5374 |
| 5436 | 5375 |
| 5437 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm, | 5376 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm, |
| 5438 Register hash, | 5377 Register hash, |
| 5439 Register character) { | 5378 Register character) { |
| 5440 // hash += character; | 5379 // hash += character; |
| 5441 __ add(hash, hash, Operand(character)); | 5380 __ add(hash, hash, Operand(character)); |
| 5442 // hash += hash << 10; | 5381 // hash += hash << 10; |
| 5443 __ add(hash, hash, Operand(hash, LSL, 10)); | 5382 __ add(hash, hash, Operand(hash, LSL, 10)); |
| 5444 // hash ^= hash >> 6; | 5383 // hash ^= hash >> 6; |
| 5445 __ eor(hash, hash, Operand(hash, ASR, 6)); | 5384 __ eor(hash, hash, Operand(hash, LSR, 6)); |
| 5446 } | 5385 } |
| 5447 | 5386 |
| 5448 | 5387 |
| 5449 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, | 5388 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, |
| 5450 Register hash) { | 5389 Register hash) { |
| 5451 // hash += hash << 3; | 5390 // hash += hash << 3; |
| 5452 __ add(hash, hash, Operand(hash, LSL, 3)); | 5391 __ add(hash, hash, Operand(hash, LSL, 3)); |
| 5453 // hash ^= hash >> 11; | 5392 // hash ^= hash >> 11; |
| 5454 __ eor(hash, hash, Operand(hash, ASR, 11)); | 5393 __ eor(hash, hash, Operand(hash, LSR, 11)); |
| 5455 // hash += hash << 15; | 5394 // hash += hash << 15; |
| 5456 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); | 5395 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); |
| 5457 | 5396 |
| 5397 uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1; | |
| 5398 __ and_(hash, hash, Operand(kHashShiftCutOffMask)); | |
|
Vyacheslav Egorov (Chromium)
2012/01/09 19:09:33
Shouldn't it be SetCC? (instead of SetCC on the on
Erik Corry
2012/01/10 00:18:44
Good catch, this needs fixing in bleeding edge too
| |
| 5399 | |
| 5458 // if (hash == 0) hash = 27; | 5400 // if (hash == 0) hash = 27; |
| 5459 __ mov(hash, Operand(27), LeaveCC, ne); | 5401 __ mov(hash, Operand(27), LeaveCC, eq); |
| 5460 } | 5402 } |
| 5461 | 5403 |
| 5462 | 5404 |
| 5463 void SubStringStub::Generate(MacroAssembler* masm) { | 5405 void SubStringStub::Generate(MacroAssembler* masm) { |
| 5464 Label runtime; | 5406 Label runtime; |
| 5465 | 5407 |
| 5466 // Stack frame on entry. | 5408 // Stack frame on entry. |
| 5467 // lr: return address | 5409 // lr: return address |
| 5468 // sp[0]: to | 5410 // sp[0]: to |
| 5469 // sp[4]: from | 5411 // sp[4]: from |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6700 __ mov(result, Operand::Zero()); | 6642 __ mov(result, Operand::Zero()); |
| 6701 __ Ret(); | 6643 __ Ret(); |
| 6702 } | 6644 } |
| 6703 | 6645 |
| 6704 | 6646 |
| 6705 #undef __ | 6647 #undef __ |
| 6706 | 6648 |
| 6707 } } // namespace v8::internal | 6649 } } // namespace v8::internal |
| 6708 | 6650 |
| 6709 #endif // V8_TARGET_ARCH_ARM | 6651 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |