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 |