| Index: test/cctest/test-hashing.cc
 | 
| ===================================================================
 | 
| --- test/cctest/test-hashing.cc	(revision 10404)
 | 
| +++ test/cctest/test-hashing.cc	(working copy)
 | 
| @@ -46,80 +46,121 @@
 | 
|  
 | 
|  static v8::Persistent<v8::Context> env;
 | 
|  
 | 
| -#define __ assm->
 | 
| +#define __ masm->
 | 
|  
 | 
|  
 | 
| -void generate(MacroAssembler* assm, i::Vector<const char> string) {
 | 
| +void generate(MacroAssembler* masm, i::Vector<const char> string) {
 | 
| +  // GenerateHashInit takes the first character as an argument so it can't
 | 
| +  // handle the zero length string.
 | 
| +  ASSERT(string.length() > 0);
 | 
|  #ifdef V8_TARGET_ARCH_IA32
 | 
|    __ push(ebx);
 | 
|    __ push(ecx);
 | 
|    __ mov(eax, Immediate(0));
 | 
| -  if (string.length() > 0) {
 | 
| -    __ mov(ebx, Immediate(string.at(0)));
 | 
| -    StringHelper::GenerateHashInit(assm, eax, ebx, ecx);
 | 
| -  }
 | 
| +  __ mov(ebx, Immediate(string.at(0)));
 | 
| +  StringHelper::GenerateHashInit(masm, eax, ebx, ecx);
 | 
|    for (int i = 1; i < string.length(); i++) {
 | 
|      __ mov(ebx, Immediate(string.at(i)));
 | 
| -    StringHelper::GenerateHashAddCharacter(assm, eax, ebx, ecx);
 | 
| +    StringHelper::GenerateHashAddCharacter(masm, eax, ebx, ecx);
 | 
|    }
 | 
| -  StringHelper::GenerateHashGetHash(assm, eax, ecx);
 | 
| +  StringHelper::GenerateHashGetHash(masm, eax, ecx);
 | 
|    __ pop(ecx);
 | 
|    __ pop(ebx);
 | 
|    __ Ret();
 | 
|  #elif V8_TARGET_ARCH_X64
 | 
| +  __ push(kRootRegister);
 | 
| +  __ InitializeRootRegister();
 | 
|    __ push(rbx);
 | 
|    __ push(rcx);
 | 
|    __ movq(rax, Immediate(0));
 | 
| -  if (string.length() > 0) {
 | 
| -    __ movq(rbx, Immediate(string.at(0)));
 | 
| -    StringHelper::GenerateHashInit(assm, rax, rbx, rcx);
 | 
| -  }
 | 
| +  __ movq(rbx, Immediate(string.at(0)));
 | 
| +  StringHelper::GenerateHashInit(masm, rax, rbx, rcx);
 | 
|    for (int i = 1; i < string.length(); i++) {
 | 
|      __ movq(rbx, Immediate(string.at(i)));
 | 
| -    StringHelper::GenerateHashAddCharacter(assm, rax, rbx, rcx);
 | 
| +    StringHelper::GenerateHashAddCharacter(masm, rax, rbx, rcx);
 | 
|    }
 | 
| -  StringHelper::GenerateHashGetHash(assm, rax, rcx);
 | 
| +  StringHelper::GenerateHashGetHash(masm, rax, rcx);
 | 
|    __ pop(rcx);
 | 
|    __ pop(rbx);
 | 
| +  __ pop(kRootRegister);
 | 
|    __ Ret();
 | 
|  #elif V8_TARGET_ARCH_ARM
 | 
| +  __ push(kRootRegister);
 | 
| +  __ InitializeRootRegister();
 | 
| +
 | 
|    __ mov(r0, Operand(0));
 | 
| -  if (string.length() > 0) {
 | 
| -    __ mov(ip, Operand(string.at(0)));
 | 
| -    StringHelper::GenerateHashInit(assm, r0, ip);
 | 
| -  }
 | 
| +  __ mov(ip, Operand(string.at(0)));
 | 
| +  StringHelper::GenerateHashInit(masm, r0, ip);
 | 
|    for (int i = 1; i < string.length(); i++) {
 | 
|      __ mov(ip, Operand(string.at(i)));
 | 
| -    StringHelper::GenerateHashAddCharacter(assm, r0, ip);
 | 
| +    StringHelper::GenerateHashAddCharacter(masm, r0, ip);
 | 
|    }
 | 
| -  StringHelper::GenerateHashGetHash(assm, r0);
 | 
| +  StringHelper::GenerateHashGetHash(masm, r0);
 | 
| +  __ pop(kRootRegister);
 | 
|    __ mov(pc, Operand(lr));
 | 
|  #elif V8_TARGET_ARCH_MIPS
 | 
| +  __ push(kRootRegister);
 | 
| +  __ InitializeRootRegister();
 | 
| +
 | 
|    __ li(v0, Operand(0));
 | 
| -  if (string.length() > 0) {
 | 
| -    __ li(t1, Operand(string.at(0)));
 | 
| -    StringHelper::GenerateHashInit(assm, v0, t1);
 | 
| -  }
 | 
| +  __ li(t1, Operand(string.at(0)));
 | 
| +  StringHelper::GenerateHashInit(masm, v0, t1);
 | 
|    for (int i = 1; i < string.length(); i++) {
 | 
|      __ li(t1, Operand(string.at(i)));
 | 
| -    StringHelper::GenerateHashAddCharacter(assm, v0, t1);
 | 
| +    StringHelper::GenerateHashAddCharacter(masm, v0, t1);
 | 
|    }
 | 
| -  StringHelper::GenerateHashGetHash(assm, v0);
 | 
| +  StringHelper::GenerateHashGetHash(masm, v0);
 | 
| +  __ pop(kRootRegister);
 | 
|    __ jr(ra);
 | 
|    __ nop();
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void generate(MacroAssembler* masm, uint32_t key) {
 | 
| +#ifdef V8_TARGET_ARCH_IA32
 | 
| +  __ push(ebx);
 | 
| +  __ mov(eax, Immediate(key));
 | 
| +  __ GetNumberHash(eax, ebx);
 | 
| +  __ pop(ebx);
 | 
| +  __ Ret();
 | 
| +#elif V8_TARGET_ARCH_X64
 | 
| +  __ push(kRootRegister);
 | 
| +  __ InitializeRootRegister();
 | 
| +  __ push(rbx);
 | 
| +  __ movq(rax, Immediate(key));
 | 
| +  __ GetNumberHash(rax, rbx);
 | 
| +  __ pop(rbx);
 | 
| +  __ pop(kRootRegister);
 | 
| +  __ Ret();
 | 
| +#elif V8_TARGET_ARCH_ARM
 | 
| +  __ push(kRootRegister);
 | 
| +  __ InitializeRootRegister();
 | 
| +  __ mov(r0, Operand(key));
 | 
| +  __ GetNumberHash(r0, ip);
 | 
| +  __ pop(kRootRegister);
 | 
| +  __ mov(pc, Operand(lr));
 | 
| +#elif V8_TARGET_ARCH_MIPS
 | 
| +  __ push(kRootRegister);
 | 
| +  __ InitializeRootRegister();
 | 
| +  __ li(v0, Operand(key));
 | 
| +  __ GetNumberHash(v0, t1);
 | 
| +  __ pop(kRootRegister);
 | 
| +  __ jr(ra);
 | 
| +  __ nop();
 | 
| +#endif
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void check(i::Vector<const char> string) {
 | 
|    v8::HandleScope scope;
 | 
|    v8::internal::byte buffer[2048];
 | 
| -  MacroAssembler assm(Isolate::Current(), buffer, sizeof buffer);
 | 
| +  MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer);
 | 
|  
 | 
| -  generate(&assm, string);
 | 
| +  generate(&masm, string);
 | 
|  
 | 
|    CodeDesc desc;
 | 
| -  assm.GetCode(&desc);
 | 
| +  masm.GetCode(&desc);
 | 
|    Code* code = Code::cast(HEAP->CreateCode(
 | 
|        desc,
 | 
|        Code::ComputeFlags(Code::STUB),
 | 
| @@ -140,12 +181,47 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void check(uint32_t key) {
 | 
| +  v8::HandleScope scope;
 | 
| +  v8::internal::byte buffer[2048];
 | 
| +  MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer);
 | 
| +
 | 
| +  generate(&masm, key);
 | 
| +
 | 
| +  CodeDesc desc;
 | 
| +  masm.GetCode(&desc);
 | 
| +  Code* code = Code::cast(HEAP->CreateCode(
 | 
| +      desc,
 | 
| +      Code::ComputeFlags(Code::STUB),
 | 
| +      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
 | 
| +  CHECK(code->IsCode());
 | 
| +
 | 
| +  HASH_FUNCTION hash = FUNCTION_CAST<HASH_FUNCTION>(code->entry());
 | 
| +#ifdef USE_SIMULATOR
 | 
| +  uint32_t codegen_hash =
 | 
| +      reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0));
 | 
| +#else
 | 
| +  uint32_t codegen_hash = hash();
 | 
| +#endif
 | 
| +
 | 
| +  uint32_t runtime_hash = ComputeIntegerHash(
 | 
| +      key,
 | 
| +      Isolate::Current()->heap()->HashSeed());
 | 
| +  CHECK(runtime_hash == codegen_hash);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void check_twochars(char a, char b) {
 | 
|    char ab[2] = {a, b};
 | 
|    check(i::Vector<const char>(ab, 2));
 | 
|  }
 | 
|  
 | 
|  
 | 
| +static uint32_t PseudoRandom(uint32_t i, uint32_t j) {
 | 
| +  return ~(~((i * 781) ^ (j * 329)));
 | 
| +}
 | 
| +
 | 
| +
 | 
|  TEST(StringHash) {
 | 
|    if (env.IsEmpty()) env = v8::Context::New();
 | 
|    for (int a = 0; a < String::kMaxAsciiCharCode; a++) {
 | 
| @@ -156,7 +232,6 @@
 | 
|        check_twochars(static_cast<char>(a), static_cast<char>(b));
 | 
|      }
 | 
|    }
 | 
| -  check(i::Vector<const char>("",        0));
 | 
|    check(i::Vector<const char>("*",       1));
 | 
|    check(i::Vector<const char>(".zZ",     3));
 | 
|    check(i::Vector<const char>("muc",     3));
 | 
| @@ -164,4 +239,22 @@
 | 
|    check(i::Vector<const char>("-=[ vee eight ftw ]=-", 21));
 | 
|  }
 | 
|  
 | 
| +
 | 
| +TEST(NumberHash) {
 | 
| +  if (env.IsEmpty()) env = v8::Context::New();
 | 
| +
 | 
| +  // Some specific numbers
 | 
| +  for (uint32_t key = 0; key < 42; key += 7) {
 | 
| +    check(key);
 | 
| +  }
 | 
| +
 | 
| +  // Some pseudo-random numbers
 | 
| +  static const uint32_t kLimit = 1000;
 | 
| +  for (uint32_t i = 0; i < 5; i++) {
 | 
| +    for (uint32_t j = 0; j < 5; j++) {
 | 
| +      check(PseudoRandom(i, j) % kLimit);
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  #undef __
 | 
| 
 |