test-hashing.cc revision 592a9fc1d8ea420377a2e7efd0600e20b058be2b
1// Copyright 2011 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#include <stdlib.h> 29 30#include "v8.h" 31 32#include "factory.h" 33#include "macro-assembler.h" 34#include "cctest.h" 35#include "code-stubs.h" 36#include "objects.h" 37 38#ifdef USE_SIMULATOR 39#include "simulator.h" 40#endif 41 42using namespace v8::internal; 43 44 45typedef uint32_t (*HASH_FUNCTION)(); 46 47static v8::Persistent<v8::Context> env; 48 49#define __ assm-> 50 51 52void generate(MacroAssembler* assm, i::Vector<const char> string) { 53#ifdef V8_TARGET_ARCH_IA32 54 __ push(ebx); 55 __ push(ecx); 56 __ mov(eax, Immediate(0)); 57 if (string.length() > 0) { 58 __ mov(ebx, Immediate(string.at(0))); 59 StringHelper::GenerateHashInit(assm, eax, ebx, ecx); 60 } 61 for (int i = 1; i < string.length(); i++) { 62 __ mov(ebx, Immediate(string.at(i))); 63 StringHelper::GenerateHashAddCharacter(assm, eax, ebx, ecx); 64 } 65 StringHelper::GenerateHashGetHash(assm, eax, ecx); 66 __ pop(ecx); 67 __ pop(ebx); 68 __ Ret(); 69#elif V8_TARGET_ARCH_X64 70 __ push(rbx); 71 __ push(rcx); 72 __ movq(rax, Immediate(0)); 73 if (string.length() > 0) { 74 __ movq(rbx, Immediate(string.at(0))); 75 StringHelper::GenerateHashInit(assm, rax, rbx, rcx); 76 } 77 for (int i = 1; i < string.length(); i++) { 78 __ movq(rbx, Immediate(string.at(i))); 79 StringHelper::GenerateHashAddCharacter(assm, rax, rbx, rcx); 80 } 81 StringHelper::GenerateHashGetHash(assm, rax, rcx); 82 __ pop(rcx); 83 __ pop(rbx); 84 __ Ret(); 85#elif V8_TARGET_ARCH_ARM 86 __ mov(r0, Operand(0)); 87 if (string.length() > 0) { 88 __ mov(ip, Operand(string.at(0))); 89 StringHelper::GenerateHashInit(assm, r0, ip); 90 } 91 for (int i = 1; i < string.length(); i++) { 92 __ mov(ip, Operand(string.at(i))); 93 StringHelper::GenerateHashAddCharacter(assm, r0, ip); 94 } 95 StringHelper::GenerateHashGetHash(assm, r0); 96 __ mov(pc, Operand(lr)); 97#elif V8_TARGET_ARCH_MIPS 98 __ li(v0, Operand(0)); 99 if (string.length() > 0) { 100 __ li(t1, Operand(string.at(0))); 101 StringHelper::GenerateHashInit(assm, v0, t1); 102 } 103 for (int i = 1; i < string.length(); i++) { 104 __ li(t1, Operand(string.at(i))); 105 StringHelper::GenerateHashAddCharacter(assm, v0, t1); 106 } 107 StringHelper::GenerateHashGetHash(assm, v0); 108 __ jr(ra); 109#endif 110} 111 112 113void check(i::Vector<const char> string) { 114 v8::HandleScope scope; 115 v8::internal::byte buffer[2048]; 116 MacroAssembler assm(Isolate::Current(), buffer, sizeof buffer); 117 118 generate(&assm, string); 119 120 CodeDesc desc; 121 assm.GetCode(&desc); 122 Code* code = Code::cast(HEAP->CreateCode( 123 desc, 124 Code::ComputeFlags(Code::STUB), 125 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked()); 126 CHECK(code->IsCode()); 127 128 HASH_FUNCTION hash = FUNCTION_CAST<HASH_FUNCTION>(Code::cast(code)->entry()); 129 Handle<String> v8_string = FACTORY->NewStringFromAscii(string); 130 v8_string->set_hash_field(String::kEmptyHashField); 131#ifdef USE_SIMULATOR 132 uint32_t codegen_hash = 133 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0)); 134#else 135 uint32_t codegen_hash = hash(); 136#endif 137 uint32_t runtime_hash = v8_string->Hash(); 138 CHECK(runtime_hash == codegen_hash); 139} 140 141 142void check_twochars(char a, char b) { 143 char ab[2] = {a, b}; 144 check(i::Vector<const char>(ab, 2)); 145} 146 147 148TEST(StringHash) { 149 if (env.IsEmpty()) env = v8::Context::New(); 150 for (int a = 0; a < String::kMaxAsciiCharCode; a++) { 151 // Numbers are hashed differently. 152 if (a >= '0' && a <= '9') continue; 153 for (int b = 0; b < String::kMaxAsciiCharCode; b++) { 154 if (b >= '0' && b <= '9') continue; 155 check_twochars(static_cast<char>(a), static_cast<char>(b)); 156 } 157 } 158 check(i::Vector<const char>("", 0)); 159 check(i::Vector<const char>("*", 1)); 160 check(i::Vector<const char>(".zZ", 3)); 161 check(i::Vector<const char>("muc", 3)); 162 check(i::Vector<const char>("(>'_')>", 7)); 163 check(i::Vector<const char>("-=[ vee eight ftw ]=-", 21)); 164} 165 166#undef __ 167