Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(575)

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 8512004: Fixing generated hash function on all platforms. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5228 matching lines...) Expand 10 before | Expand all | Expand 10 after
5239 5239
5240 5240
5241 void StringCharAtGenerator::GenerateSlow( 5241 void StringCharAtGenerator::GenerateSlow(
5242 MacroAssembler* masm, 5242 MacroAssembler* masm,
5243 const RuntimeCallHelper& call_helper) { 5243 const RuntimeCallHelper& call_helper) {
5244 char_code_at_generator_.GenerateSlow(masm, call_helper); 5244 char_code_at_generator_.GenerateSlow(masm, call_helper);
5245 char_from_code_generator_.GenerateSlow(masm, call_helper); 5245 char_from_code_generator_.GenerateSlow(masm, call_helper);
5246 } 5246 }
5247 5247
5248 5248
5249 class StringHelper : public AllStatic {
5250 public:
5251 // Generate code for copying characters using a simple loop. This should only
5252 // be used in places where the number of characters is small and the
5253 // additional setup and checking in GenerateCopyCharactersLong adds too much
5254 // overhead. Copying of overlapping regions is not supported.
5255 // Dest register ends at the position after the last character written.
5256 static void GenerateCopyCharacters(MacroAssembler* masm,
5257 Register dest,
5258 Register src,
5259 Register count,
5260 Register scratch,
5261 bool ascii);
5262
5263 // Generate code for copying a large number of characters. This function
5264 // is allowed to spend extra time setting up conditions to make copying
5265 // faster. Copying of overlapping regions is not supported.
5266 // Dest register ends at the position after the last character written.
5267 static void GenerateCopyCharactersLong(MacroAssembler* masm,
5268 Register dest,
5269 Register src,
5270 Register count,
5271 Register scratch1,
5272 Register scratch2,
5273 Register scratch3,
5274 Register scratch4,
5275 Register scratch5,
5276 int flags);
5277
5278
5279 // Probe the symbol table for a two character string. If the string is
5280 // not found by probing a jump to the label not_found is performed. This jump
5281 // does not guarantee that the string is not in the symbol table. If the
5282 // string is found the code falls through with the string in register r0.
5283 // Contents of both c1 and c2 registers are modified. At the exit c1 is
5284 // guaranteed to contain halfword with low and high bytes equal to
5285 // initial contents of c1 and c2 respectively.
5286 static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
5287 Register c1,
5288 Register c2,
5289 Register scratch1,
5290 Register scratch2,
5291 Register scratch3,
5292 Register scratch4,
5293 Register scratch5,
5294 Label* not_found);
5295
5296 // Generate string hash.
5297 static void GenerateHashInit(MacroAssembler* masm,
5298 Register hash,
5299 Register character);
5300
5301 static void GenerateHashAddCharacter(MacroAssembler* masm,
5302 Register hash,
5303 Register character);
5304
5305 static void GenerateHashGetHash(MacroAssembler* masm,
5306 Register hash);
5307
5308 private:
5309 DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
5310 };
5311
5312
5313 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, 5249 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
5314 Register dest, 5250 Register dest,
5315 Register src, 5251 Register src,
5316 Register count, 5252 Register count,
5317 Register scratch, 5253 Register scratch,
5318 bool ascii) { 5254 bool ascii) {
5319 Label loop; 5255 Label loop;
5320 Label done; 5256 Label done;
5321 // This loop just copies one character at a time, as it is only used for very 5257 // This loop just copies one character at a time, as it is only used for very
5322 // short strings. 5258 // short strings.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5555 // mask: capacity mask 5491 // mask: capacity mask
5556 // first_symbol_table_element: address of the first element of 5492 // first_symbol_table_element: address of the first element of
5557 // the symbol table 5493 // the symbol table
5558 // undefined: the undefined object 5494 // undefined: the undefined object
5559 // scratch: - 5495 // scratch: -
5560 5496
5561 // Perform a number of probes in the symbol table. 5497 // Perform a number of probes in the symbol table.
5562 static const int kProbes = 4; 5498 static const int kProbes = 4;
5563 Label found_in_symbol_table; 5499 Label found_in_symbol_table;
5564 Label next_probe[kProbes]; 5500 Label next_probe[kProbes];
5501 Register candidate = scratch5; // Scratch register contains candidate.
5565 for (int i = 0; i < kProbes; i++) { 5502 for (int i = 0; i < kProbes; i++) {
5566 Register candidate = scratch5; // Scratch register contains candidate.
5567
5568 // Calculate entry in symbol table. 5503 // Calculate entry in symbol table.
5569 if (i > 0) { 5504 if (i > 0) {
5570 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); 5505 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i)));
5571 } else { 5506 } else {
5572 __ mov(candidate, hash); 5507 __ mov(candidate, hash);
5573 } 5508 }
5574 5509
5575 __ and_(candidate, candidate, Operand(mask)); 5510 __ and_(candidate, candidate, Operand(mask));
5576 5511
5577 // Load the entry from the symble table. 5512 // Load the entry from the symble table.
5578 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 5513 STATIC_ASSERT(SymbolTable::kEntrySize == 1);
5579 __ ldr(candidate, 5514 __ ldr(candidate,
5580 MemOperand(first_symbol_table_element, 5515 MemOperand(first_symbol_table_element,
5581 candidate, 5516 candidate,
5582 LSL, 5517 LSL,
5583 kPointerSizeLog2)); 5518 kPointerSizeLog2));
5584 5519
5585 // If entry is undefined no string with this hash can be found. 5520 // If entry is undefined no string with this hash can be found.
5586 Label is_string; 5521 Label is_string;
5587 __ CompareObjectType(candidate, scratch, scratch, ODDBALL_TYPE); 5522 __ CompareObjectType(candidate, scratch, scratch, ODDBALL_TYPE);
5588 __ b(ne, &is_string); 5523 __ b(ne, &is_string);
5589 5524
5590 __ cmp(undefined, candidate); 5525 __ cmp(undefined, candidate);
5591 __ b(eq, not_found); 5526 __ b(eq, not_found);
5592 // Must be null (deleted entry). 5527 // Must be the hole (deleted entry).
5593 if (FLAG_debug_code) { 5528 if (FLAG_debug_code) {
5594 __ LoadRoot(ip, Heap::kNullValueRootIndex); 5529 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
5595 __ cmp(ip, candidate); 5530 __ cmp(ip, candidate);
5596 __ Assert(eq, "oddball in symbol table is not undefined or null"); 5531 __ Assert(eq, "oddball in symbol table is not undefined or the hole");
5597 } 5532 }
5598 __ jmp(&next_probe[i]); 5533 __ jmp(&next_probe[i]);
5599 5534
5600 __ bind(&is_string); 5535 __ bind(&is_string);
5601 5536
5602 // Check that the candidate is a non-external ASCII string. The instance 5537 // Check that the candidate is a non-external ASCII string. The instance
5603 // type is still in the scratch register from the CompareObjectType 5538 // type is still in the scratch register from the CompareObjectType
5604 // operation. 5539 // operation.
5605 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]); 5540 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]);
5606 5541
5607 // If length is not 2 the string is not a candidate. 5542 // If length is not 2 the string is not a candidate.
5608 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset)); 5543 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset));
5609 __ cmp(scratch, Operand(Smi::FromInt(2))); 5544 __ cmp(scratch, Operand(Smi::FromInt(2)));
5610 __ b(ne, &next_probe[i]); 5545 __ b(ne, &next_probe[i]);
5611 5546
5612 // Check if the two characters match. 5547 // Check if the two characters match.
5613 // Assumes that word load is little endian. 5548 // Assumes that word load is little endian.
5614 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize)); 5549 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize));
5615 __ cmp(chars, scratch); 5550 __ cmp(chars, scratch);
5616 __ b(eq, &found_in_symbol_table); 5551 __ b(eq, &found_in_symbol_table);
5617 __ bind(&next_probe[i]); 5552 __ bind(&next_probe[i]);
5618 } 5553 }
5619 5554
5620 // No matching 2 character string found by probing. 5555 // No matching 2 character string found by probing.
5621 __ jmp(not_found); 5556 __ jmp(not_found);
5622 5557
5623 // Scratch register contains result when we fall through to here. 5558 // Scratch register contains result when we fall through to here.
5624 Register result = scratch; 5559 Register result = candidate;
5625 __ bind(&found_in_symbol_table); 5560 __ bind(&found_in_symbol_table);
5626 __ Move(r0, result); 5561 __ Move(r0, result);
5627 } 5562 }
5628 5563
5629 5564
5630 void StringHelper::GenerateHashInit(MacroAssembler* masm, 5565 void StringHelper::GenerateHashInit(MacroAssembler* masm,
5631 Register hash, 5566 Register hash,
5632 Register character) { 5567 Register character) {
5633 // hash = character + (character << 10); 5568 // hash = character + (character << 10);
5634 __ add(hash, character, Operand(character, LSL, 10)); 5569 __ add(hash, character, Operand(character, LSL, 10));
5635 // hash ^= hash >> 6; 5570 // hash ^= hash >> 6;
5636 __ eor(hash, hash, Operand(hash, ASR, 6)); 5571 __ eor(hash, hash, Operand(hash, LSR, 6));
5637 } 5572 }
5638 5573
5639 5574
5640 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm, 5575 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
5641 Register hash, 5576 Register hash,
5642 Register character) { 5577 Register character) {
5643 // hash += character; 5578 // hash += character;
5644 __ add(hash, hash, Operand(character)); 5579 __ add(hash, hash, Operand(character));
5645 // hash += hash << 10; 5580 // hash += hash << 10;
5646 __ add(hash, hash, Operand(hash, LSL, 10)); 5581 __ add(hash, hash, Operand(hash, LSL, 10));
5647 // hash ^= hash >> 6; 5582 // hash ^= hash >> 6;
5648 __ eor(hash, hash, Operand(hash, ASR, 6)); 5583 __ eor(hash, hash, Operand(hash, LSR, 6));
5649 } 5584 }
5650 5585
5651 5586
5652 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, 5587 void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
5653 Register hash) { 5588 Register hash) {
5654 // hash += hash << 3; 5589 // hash += hash << 3;
5655 __ add(hash, hash, Operand(hash, LSL, 3)); 5590 __ add(hash, hash, Operand(hash, LSL, 3));
5656 // hash ^= hash >> 11; 5591 // hash ^= hash >> 11;
5657 __ eor(hash, hash, Operand(hash, ASR, 11)); 5592 __ eor(hash, hash, Operand(hash, LSR, 11));
5658 // hash += hash << 15; 5593 // hash += hash << 15;
5659 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); 5594 __ add(hash, hash, Operand(hash, LSL, 15), SetCC);
5660 5595
5596 uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1;
5597 __ and_(hash, hash, Operand(kHashShiftCutOffMask));
5598
5661 // if (hash == 0) hash = 27; 5599 // if (hash == 0) hash = 27;
5662 __ mov(hash, Operand(27), LeaveCC, ne); 5600 __ mov(hash, Operand(27), LeaveCC, eq);
5663 } 5601 }
5664 5602
5665 5603
5666 void SubStringStub::Generate(MacroAssembler* masm) { 5604 void SubStringStub::Generate(MacroAssembler* masm) {
5667 Label runtime; 5605 Label runtime;
5668 5606
5669 // Stack frame on entry. 5607 // Stack frame on entry.
5670 // lr: return address 5608 // lr: return address
5671 // sp[0]: to 5609 // sp[0]: to
5672 // sp[4]: from 5610 // sp[4]: from
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after
7181 __ bind(&need_incremental); 7119 __ bind(&need_incremental);
7182 7120
7183 // Fall through when we need to inform the incremental marker. 7121 // Fall through when we need to inform the incremental marker.
7184 } 7122 }
7185 7123
7186 #undef __ 7124 #undef __
7187 7125
7188 } } // namespace v8::internal 7126 } } // namespace v8::internal
7189 7127
7190 #endif // V8_TARGET_ARCH_ARM 7128 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698