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

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

Issue 9124004: Backport hash collision workaround to 3.6. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.6/
Patch Set: Created 8 years, 11 months 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
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 5521 matching lines...) Expand 10 before | Expand all | Expand 10 after
5532 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5532 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5533 // hash: hash of two character string 5533 // hash: hash of two character string
5534 // symbol_table: symbol table 5534 // symbol_table: symbol table
5535 // mask: capacity mask 5535 // mask: capacity mask
5536 // scratch: - 5536 // scratch: -
5537 5537
5538 // Perform a number of probes in the symbol table. 5538 // Perform a number of probes in the symbol table.
5539 static const int kProbes = 4; 5539 static const int kProbes = 4;
5540 Label found_in_symbol_table; 5540 Label found_in_symbol_table;
5541 Label next_probe[kProbes], next_probe_pop_mask[kProbes]; 5541 Label next_probe[kProbes], next_probe_pop_mask[kProbes];
5542 Register candidate = scratch; // Scratch register contains candidate.
5542 for (int i = 0; i < kProbes; i++) { 5543 for (int i = 0; i < kProbes; i++) {
5543 // Calculate entry in symbol table. 5544 // Calculate entry in symbol table.
5544 __ mov(scratch, hash); 5545 __ mov(scratch, hash);
5545 if (i > 0) { 5546 if (i > 0) {
5546 __ add(Operand(scratch), Immediate(SymbolTable::GetProbeOffset(i))); 5547 __ add(Operand(scratch), Immediate(SymbolTable::GetProbeOffset(i)));
5547 } 5548 }
5548 __ and_(scratch, Operand(mask)); 5549 __ and_(scratch, Operand(mask));
5549 5550
5550 // Load the entry from the symbol table. 5551 // Load the entry from the symbol table.
5551 Register candidate = scratch; // Scratch register contains candidate.
5552 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 5552 STATIC_ASSERT(SymbolTable::kEntrySize == 1);
5553 __ mov(candidate, 5553 __ mov(candidate,
5554 FieldOperand(symbol_table, 5554 FieldOperand(symbol_table,
5555 scratch, 5555 scratch,
5556 times_pointer_size, 5556 times_pointer_size,
5557 SymbolTable::kElementsStartOffset)); 5557 SymbolTable::kElementsStartOffset));
5558 5558
5559 // If entry is undefined no string with this hash can be found. 5559 // If entry is undefined no string with this hash can be found.
5560 Factory* factory = masm->isolate()->factory(); 5560 Factory* factory = masm->isolate()->factory();
5561 __ cmp(candidate, factory->undefined_value()); 5561 __ cmp(candidate, factory->undefined_value());
(...skipping 24 matching lines...) Expand all
5586 __ j(equal, &found_in_symbol_table); 5586 __ j(equal, &found_in_symbol_table);
5587 __ bind(&next_probe_pop_mask[i]); 5587 __ bind(&next_probe_pop_mask[i]);
5588 __ pop(mask); 5588 __ pop(mask);
5589 __ bind(&next_probe[i]); 5589 __ bind(&next_probe[i]);
5590 } 5590 }
5591 5591
5592 // No matching 2 character string found by probing. 5592 // No matching 2 character string found by probing.
5593 __ jmp(not_found); 5593 __ jmp(not_found);
5594 5594
5595 // Scratch register contains result when we fall through to here. 5595 // Scratch register contains result when we fall through to here.
5596 Register result = scratch; 5596 Register result = candidate;
5597 __ bind(&found_in_symbol_table); 5597 __ bind(&found_in_symbol_table);
5598 __ pop(mask); // Pop saved mask from the stack. 5598 __ pop(mask); // Pop saved mask from the stack.
5599 if (!result.is(eax)) { 5599 if (!result.is(eax)) {
5600 __ mov(eax, result); 5600 __ mov(eax, result);
5601 } 5601 }
5602 } 5602 }
5603 5603
5604 5604
5605 void StringHelper::GenerateHashInit(MacroAssembler* masm, 5605 void StringHelper::GenerateHashInit(MacroAssembler* masm,
5606 Register hash, 5606 Register hash,
5607 Register character, 5607 Register character,
5608 Register scratch) { 5608 Register scratch) {
5609 // hash = character + (character << 10); 5609 // hash = (seed + character) + ((seed + character) << 10);
5610 __ mov(hash, character); 5610 if (Serializer::enabled()) {
5611 __ shl(hash, 10); 5611 ExternalReference roots_address =
5612 __ add(hash, Operand(character)); 5612 ExternalReference::roots_address(masm->isolate());
5613 __ mov(scratch, Immediate(Heap::kStringHashSeedRootIndex));
5614 __ mov(scratch, Operand::StaticArray(scratch,
5615 times_pointer_size,
5616 roots_address));
5617 __ add(scratch, Operand(character));
5618 __ mov(hash, scratch);
5619 __ shl(scratch, 10);
5620 __ add(hash, Operand(scratch));
5621 } else {
5622 int32_t seed = masm->isolate()->heap()->StringHashSeed();
5623 __ lea(scratch, Operand(character, seed));
5624 __ shl(scratch, 10);
5625 __ lea(hash, Operand(scratch, character, times_1, seed));
5626 }
5613 // hash ^= hash >> 6; 5627 // hash ^= hash >> 6;
5614 __ mov(scratch, hash); 5628 __ mov(scratch, hash);
5615 __ sar(scratch, 6); 5629 __ shr(scratch, 6);
5616 __ xor_(hash, Operand(scratch)); 5630 __ xor_(hash, Operand(scratch));
5617 } 5631 }
5618 5632
5619 5633
5620 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm, 5634 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
5621 Register hash, 5635 Register hash,
5622 Register character, 5636 Register character,
5623 Register scratch) { 5637 Register scratch) {
5624 // hash += character; 5638 // hash += character;
5625 __ add(hash, Operand(character)); 5639 __ add(hash, Operand(character));
5626 // hash += hash << 10; 5640 // hash += hash << 10;
5627 __ mov(scratch, hash); 5641 __ mov(scratch, hash);
5628 __ shl(scratch, 10); 5642 __ shl(scratch, 10);
5629 __ add(hash, Operand(scratch)); 5643 __ add(hash, Operand(scratch));
5630 // hash ^= hash >> 6; 5644 // hash ^= hash >> 6;
5631 __ mov(scratch, hash); 5645 __ mov(scratch, hash);
5632 __ sar(scratch, 6); 5646 __ shr(scratch, 6);
5633 __ xor_(hash, Operand(scratch)); 5647 __ xor_(hash, Operand(scratch));
5634 } 5648 }
5635 5649
5636 5650
5637 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, 5651 void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
5638 Register hash, 5652 Register hash,
5639 Register scratch) { 5653 Register scratch) {
5640 // hash += hash << 3; 5654 // hash += hash << 3;
5641 __ mov(scratch, hash); 5655 __ mov(scratch, hash);
5642 __ shl(scratch, 3); 5656 __ shl(scratch, 3);
5643 __ add(hash, Operand(scratch)); 5657 __ add(hash, Operand(scratch));
5644 // hash ^= hash >> 11; 5658 // hash ^= hash >> 11;
5645 __ mov(scratch, hash); 5659 __ mov(scratch, hash);
5646 __ sar(scratch, 11); 5660 __ shr(scratch, 11);
5647 __ xor_(hash, Operand(scratch)); 5661 __ xor_(hash, Operand(scratch));
5648 // hash += hash << 15; 5662 // hash += hash << 15;
5649 __ mov(scratch, hash); 5663 __ mov(scratch, hash);
5650 __ shl(scratch, 15); 5664 __ shl(scratch, 15);
5651 __ add(hash, Operand(scratch)); 5665 __ add(hash, Operand(scratch));
5652 5666
5667 uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1;
5668 __ and_(hash, kHashShiftCutOffMask);
5669
5653 // if (hash == 0) hash = 27; 5670 // if (hash == 0) hash = 27;
5654 Label hash_not_zero; 5671 Label hash_not_zero;
5655 __ test(hash, Operand(hash)); 5672 __ test(hash, Operand(hash));
5656 __ j(not_zero, &hash_not_zero, Label::kNear); 5673 __ j(not_zero, &hash_not_zero, Label::kNear);
5657 __ mov(hash, Immediate(27)); 5674 __ mov(hash, Immediate(27));
5658 __ bind(&hash_not_zero); 5675 __ bind(&hash_not_zero);
5659 } 5676 }
5660 5677
5661 5678
5662 void SubStringStub::Generate(MacroAssembler* masm) { 5679 void SubStringStub::Generate(MacroAssembler* masm) {
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
6508 __ Drop(1); 6525 __ Drop(1);
6509 __ ret(2 * kPointerSize); 6526 __ ret(2 * kPointerSize);
6510 } 6527 }
6511 6528
6512 6529
6513 #undef __ 6530 #undef __
6514 6531
6515 } } // namespace v8::internal 6532 } } // namespace v8::internal
6516 6533
6517 #endif // V8_TARGET_ARCH_IA32 6534 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698