[runtime] Deconfuse Name::Hash() from Name::hash_field()

This CL
* renames Name::hash_field field to raw_hash_field.
* all local variables that store raw_hash_field value are also renamed
  to raw_hash_field where possible.

Bug: chromium:1133527, v8:11074
Change-Id: I17313f386110b33a64f629cc2b9d4afd1e06c6c0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2471999
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71114}
This commit is contained in:
Igor Sheludko 2020-11-11 12:35:57 +01:00 committed by Commit Bot
parent 424e7a0623
commit 47ddc5b180
31 changed files with 189 additions and 170 deletions

View File

@ -65,10 +65,10 @@ void AstRawString::Internalize(LocalIsolate* isolate) {
if (literal_bytes_.length() == 0) {
set_string(isolate->factory()->empty_string());
} else if (is_one_byte()) {
OneByteStringKey key(hash_field_, literal_bytes_);
OneByteStringKey key(raw_hash_field_, literal_bytes_);
set_string(isolate->factory()->InternalizeStringWithKey(&key));
} else {
TwoByteStringKey key(hash_field_,
TwoByteStringKey key(raw_hash_field_,
Vector<const uint16_t>::cast(literal_bytes_));
set_string(isolate->factory()->InternalizeStringWithKey(&key));
}
@ -82,9 +82,9 @@ template EXPORT_TEMPLATE_DEFINE(
bool AstRawString::AsArrayIndex(uint32_t* index) const {
// The StringHasher will set up the hash. Bail out early if we know it
// can't be convertible to an array index.
if ((hash_field_ & Name::kIsNotIntegerIndexMask) != 0) return false;
if ((raw_hash_field_ & Name::kIsNotIntegerIndexMask) != 0) return false;
if (length() <= Name::kMaxCachedArrayIndexLength) {
*index = Name::ArrayIndexValueBits::decode(hash_field_);
*index = Name::ArrayIndexValueBits::decode(raw_hash_field_);
return true;
}
// Might be an index, but too big to cache it. Do the slow conversion. This
@ -95,7 +95,7 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
}
bool AstRawString::IsIntegerIndex() const {
return (hash_field_ & Name::kIsNotIntegerIndexMask) == 0;
return (raw_hash_field_ & Name::kIsNotIntegerIndexMask) == 0;
}
bool AstRawString::IsOneByteEqualTo(const char* data) const {
@ -250,18 +250,18 @@ AstStringConstants::AstStringConstants(Isolate* isolate, uint64_t hash_seed)
string_table_(),
hash_seed_(hash_seed) {
DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
#define F(name, str) \
{ \
const char* data = str; \
Vector<const uint8_t> literal(reinterpret_cast<const uint8_t*>(data), \
static_cast<int>(strlen(data))); \
uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>( \
literal.begin(), literal.length(), hash_seed_); \
name##_string_ = zone_.New<AstRawString>(true, literal, hash_field); \
/* The Handle returned by the factory is located on the roots */ \
/* array, not on the temporary HandleScope, so this is safe. */ \
name##_string_->set_string(isolate->factory()->name##_string()); \
string_table_.InsertNew(name##_string_, name##_string_->Hash()); \
#define F(name, str) \
{ \
const char* data = str; \
Vector<const uint8_t> literal(reinterpret_cast<const uint8_t*>(data), \
static_cast<int>(strlen(data))); \
uint32_t raw_hash_field = StringHasher::HashSequentialString<uint8_t>( \
literal.begin(), literal.length(), hash_seed_); \
name##_string_ = zone_.New<AstRawString>(true, literal, raw_hash_field); \
/* The Handle returned by the factory is located on the roots */ \
/* array, not on the temporary HandleScope, so this is safe. */ \
name##_string_->set_string(isolate->factory()->name##_string()); \
string_table_.InsertNew(name##_string_, name##_string_->Hash()); \
}
AST_STRING_CONSTANTS(F)
#undef F
@ -272,22 +272,22 @@ const AstRawString* AstValueFactory::GetOneByteStringInternal(
if (literal.length() == 1 && literal[0] < kMaxOneCharStringValue) {
int key = literal[0];
if (V8_UNLIKELY(one_character_strings_[key] == nullptr)) {
uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>(
uint32_t raw_hash_field = StringHasher::HashSequentialString<uint8_t>(
literal.begin(), literal.length(), hash_seed_);
one_character_strings_[key] = GetString(hash_field, true, literal);
one_character_strings_[key] = GetString(raw_hash_field, true, literal);
}
return one_character_strings_[key];
}
uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>(
uint32_t raw_hash_field = StringHasher::HashSequentialString<uint8_t>(
literal.begin(), literal.length(), hash_seed_);
return GetString(hash_field, true, literal);
return GetString(raw_hash_field, true, literal);
}
const AstRawString* AstValueFactory::GetTwoByteStringInternal(
Vector<const uint16_t> literal) {
uint32_t hash_field = StringHasher::HashSequentialString<uint16_t>(
uint32_t raw_hash_field = StringHasher::HashSequentialString<uint16_t>(
literal.begin(), literal.length(), hash_seed_);
return GetString(hash_field, false, Vector<const byte>::cast(literal));
return GetString(raw_hash_field, false, Vector<const byte>::cast(literal));
}
const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
@ -306,7 +306,7 @@ const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
const AstRawString* AstValueFactory::CloneFromOtherFactory(
const AstRawString* raw_string) {
const AstRawString* result = GetString(
raw_string->hash_field(), raw_string->is_one_byte(),
raw_string->raw_hash_field(), raw_string->is_one_byte(),
Vector<const byte>(raw_string->raw_data(), raw_string->byte_length()));
return result;
}
@ -345,12 +345,13 @@ template EXPORT_TEMPLATE_DEFINE(
V8_EXPORT_PRIVATE) void AstValueFactory::Internalize(LocalIsolate* isolate);
const AstRawString* AstValueFactory::GetString(
uint32_t hash_field, bool is_one_byte, Vector<const byte> literal_bytes) {
uint32_t raw_hash_field, bool is_one_byte,
Vector<const byte> literal_bytes) {
// literal_bytes here points to whatever the user passed, and this is OK
// because we use vector_compare (which checks the contents) to compare
// against the AstRawStrings which are in the string_table_. We should not
// return this AstRawString.
AstRawString key(is_one_byte, literal_bytes, hash_field);
AstRawString key(is_one_byte, literal_bytes, raw_hash_field);
AstRawStringMap::Entry* entry = string_table_.LookupOrInsert(
&key, key.Hash(),
[&]() {
@ -360,7 +361,7 @@ const AstRawString* AstValueFactory::GetString(
memcpy(new_literal_bytes, literal_bytes.begin(), length);
AstRawString* new_string = zone()->New<AstRawString>(
is_one_byte, Vector<const byte>(new_literal_bytes, length),
hash_field);
raw_hash_field);
CHECK_NOT_NULL(new_string);
AddString(new_string);
return new_string;

View File

@ -71,8 +71,8 @@ class AstRawString final : public ZoneObject {
bool IsPrivateName() const { return length() > 0 && FirstCharacter() == '#'; }
// For storing AstRawStrings in a hash map.
uint32_t hash_field() const { return hash_field_; }
uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }
uint32_t raw_hash_field() const { return raw_hash_field_; }
uint32_t Hash() const { return raw_hash_field_ >> Name::kHashShift; }
// This function can be called after internalizing.
V8_INLINE Handle<String> string() const {
@ -88,10 +88,10 @@ class AstRawString final : public ZoneObject {
// Members accessed only by the AstValueFactory & related classes:
AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
uint32_t hash_field)
uint32_t raw_hash_field)
: next_(nullptr),
literal_bytes_(literal_bytes),
hash_field_(hash_field),
raw_hash_field_(raw_hash_field),
is_one_byte_(is_one_byte) {}
AstRawString* next() {
DCHECK(!has_string_);
@ -117,7 +117,7 @@ class AstRawString final : public ZoneObject {
};
Vector<const byte> literal_bytes_; // Memory owned by Zone.
uint32_t hash_field_;
uint32_t raw_hash_field_;
bool is_one_byte_;
#ifdef DEBUG
// (Debug-only:) Verify the object life-cylce: Some functions may only be
@ -369,7 +369,7 @@ class AstValueFactory {
V8_EXPORT_PRIVATE const AstRawString* GetOneByteStringInternal(
Vector<const uint8_t> literal);
const AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
const AstRawString* GetString(uint32_t hash, bool is_one_byte,
const AstRawString* GetString(uint32_t raw_hash_field, bool is_one_byte,
Vector<const byte> literal_bytes);
// All strings are copied here.

View File

@ -336,7 +336,7 @@ TNode<String> StringBuiltinsAssembler::AllocateConsString(TNode<Uint32T> length,
TNode<HeapObject> result = AllocateInNewSpace(ConsString::kSize);
StoreMapNoWriteBarrier(result, result_map);
StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
StoreObjectFieldNoWriteBarrier(result, ConsString::kRawHashFieldOffset,
Int32Constant(String::kEmptyHashField));
StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, left);
StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, right);

View File

@ -109,8 +109,8 @@ macro NumberToStringSmi(x: int32, radix: int32): String labels Slow {
// In sync with Factory::SmiToString: If radix = 10 and positive number,
// update hash for string.
if (radix == 10) {
assert(strSeq.hash_field == kNameEmptyHashField);
strSeq.hash_field = MakeArrayIndexHash(Unsigned(x), Unsigned(length));
assert(strSeq.raw_hash_field == kNameEmptyHashField);
strSeq.raw_hash_field = MakeArrayIndexHash(Unsigned(x), Unsigned(length));
}
}
return strSeq;
@ -236,7 +236,7 @@ transitioning javascript builtin NumberParseFloat(
}
} label String(s: String) {
// Check if the string is a cached array index.
const hash: NameHash = s.hash_field;
const hash: NameHash = s.raw_hash_field;
if (!hash.is_not_integer_index_mask &&
hash.array_index_length < kMaxCachedArrayIndexLength) {
const arrayIndex: uint32 = hash.array_index_value;
@ -287,7 +287,7 @@ transitioning builtin ParseInt(implicit context: Context)(
return ChangeInt32ToTagged(i);
} label String(s: String) {
// Check if the string is a cached array index.
const hash: NameHash = s.hash_field;
const hash: NameHash = s.raw_hash_field;
if (!hash.is_not_integer_index_mask &&
hash.array_index_length < kMaxCachedArrayIndexLength) {
const arrayIndex: uint32 = hash.array_index_value;

View File

@ -1816,19 +1816,19 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash(
}
TNode<Uint32T> CodeStubAssembler::LoadNameHashAssumeComputed(TNode<Name> name) {
TNode<Uint32T> hash_field = LoadNameHashField(name);
TNode<Uint32T> hash_field = LoadNameRawHashField(name);
CSA_ASSERT(this, IsClearWord32(hash_field, Name::kHashNotComputedMask));
return Unsigned(Word32Shr(hash_field, Int32Constant(Name::kHashShift)));
}
TNode<Uint32T> CodeStubAssembler::LoadNameHash(TNode<Name> name,
Label* if_hash_not_computed) {
TNode<Uint32T> hash_field = LoadNameHashField(name);
TNode<Uint32T> raw_hash_field = LoadNameRawHashField(name);
if (if_hash_not_computed != nullptr) {
GotoIf(IsSetWord32(hash_field, Name::kHashNotComputedMask),
GotoIf(IsSetWord32(raw_hash_field, Name::kHashNotComputedMask),
if_hash_not_computed);
}
return Unsigned(Word32Shr(hash_field, Int32Constant(Name::kHashShift)));
return Unsigned(Word32Shr(raw_hash_field, Int32Constant(Name::kHashShift)));
}
TNode<Smi> CodeStubAssembler::LoadStringLengthAsSmi(TNode<String> string) {
@ -3206,7 +3206,7 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString(
StoreMapNoWriteBarrier(result, RootIndex::kOneByteStringMap);
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
Uint32Constant(length));
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset,
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kRawHashFieldOffset,
Int32Constant(String::kEmptyHashField));
return CAST(result);
}
@ -3228,7 +3228,7 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString(
StoreMapNoWriteBarrier(result, RootIndex::kStringMap);
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
Uint32Constant(length));
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset,
StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kRawHashFieldOffset,
Int32Constant(String::kEmptyHashField));
return CAST(result);
}
@ -3242,7 +3242,7 @@ TNode<String> CodeStubAssembler::AllocateSlicedString(RootIndex map_root_index,
TNode<HeapObject> result = Allocate(SlicedString::kSize);
DCHECK(RootsTable::IsImmortalImmovable(map_root_index));
StoreMapNoWriteBarrier(result, map_root_index);
StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset,
StoreObjectFieldNoWriteBarrier(result, SlicedString::kRawHashFieldOffset,
Int32Constant(String::kEmptyHashField));
StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent);
@ -6173,7 +6173,7 @@ TNode<BoolT> CodeStubAssembler::IsUniqueNameNoIndex(TNode<HeapObject> object) {
return Select<BoolT>(
IsInternalizedStringInstanceType(instance_type),
[=] {
return IsSetWord32(LoadNameHashField(CAST(object)),
return IsSetWord32(LoadNameRawHashField(CAST(object)),
Name::kIsNotIntegerIndexMask);
},
[=] { return IsSymbolInstanceType(instance_type); });
@ -6191,7 +6191,7 @@ TNode<BoolT> CodeStubAssembler::IsUniqueNameNoCachedIndex(
return Select<BoolT>(
IsInternalizedStringInstanceType(instance_type),
[=] {
return IsSetWord32(LoadNameHashField(CAST(object)),
return IsSetWord32(LoadNameRawHashField(CAST(object)),
Name::kDoesNotContainCachedArrayIndexMask);
},
[=] { return IsSymbolInstanceType(instance_type); });
@ -6672,12 +6672,12 @@ TNode<Number> CodeStubAssembler::StringToNumber(TNode<String> input) {
TVARIABLE(Number, var_result);
// Check if string has a cached array index.
TNode<Uint32T> hash = LoadNameHashField(input);
GotoIf(IsSetWord32(hash, Name::kDoesNotContainCachedArrayIndexMask),
TNode<Uint32T> raw_hash_field = LoadNameRawHashField(input);
GotoIf(IsSetWord32(raw_hash_field, Name::kDoesNotContainCachedArrayIndexMask),
&runtime);
var_result =
SmiTag(Signed(DecodeWordFromWord32<String::ArrayIndexValueBits>(hash)));
var_result = SmiTag(Signed(
DecodeWordFromWord32<String::ArrayIndexValueBits>(raw_hash_field)));
Goto(&end);
BIND(&runtime);
@ -7439,12 +7439,14 @@ void CodeStubAssembler::TryToName(SloppyTNode<Object> key, Label* if_keyisindex,
{
Label if_thinstring(this), if_has_cached_index(this);
TNode<Uint32T> hash = LoadNameHashField(CAST(key));
GotoIf(IsClearWord32(hash, Name::kDoesNotContainCachedArrayIndexMask),
TNode<Uint32T> raw_hash_field = LoadNameRawHashField(CAST(key));
GotoIf(IsClearWord32(raw_hash_field,
Name::kDoesNotContainCachedArrayIndexMask),
&if_has_cached_index);
// No cached array index. If the string knows that it contains an index,
// then it must be an uncacheable index. Handle this case in the runtime.
GotoIf(IsClearWord32(hash, Name::kIsNotIntegerIndexMask), if_bailout);
GotoIf(IsClearWord32(raw_hash_field, Name::kIsNotIntegerIndexMask),
if_bailout);
GotoIf(InstanceTypeEqual(var_instance_type.value(), THIN_STRING_TYPE),
&if_thinstring);
@ -7468,8 +7470,8 @@ void CodeStubAssembler::TryToName(SloppyTNode<Object> key, Label* if_keyisindex,
BIND(&if_has_cached_index);
{
TNode<IntPtrT> index =
Signed(DecodeWordFromWord32<String::ArrayIndexValueBits>(hash));
TNode<IntPtrT> index = Signed(
DecodeWordFromWord32<String::ArrayIndexValueBits>(raw_hash_field));
CSA_ASSERT(this, IntPtrLessThan(index, IntPtrConstant(INT_MAX)));
*var_index = index;
Goto(if_keyisindex);

View File

@ -680,8 +680,8 @@ FieldAccess AccessBuilder::ForModuleRegularImports() {
}
// static
FieldAccess AccessBuilder::ForNameHashField() {
FieldAccess access = {kTaggedBase, Name::kHashFieldOffset,
FieldAccess AccessBuilder::ForNameRawHashField() {
FieldAccess access = {kTaggedBase, Name::kRawHashFieldOffset,
Handle<Name>(), MaybeHandle<Map>(),
Type::Unsigned32(), MachineType::Uint32(),
kNoWriteBarrier};

View File

@ -221,8 +221,8 @@ class V8_EXPORT_PRIVATE AccessBuilder final
// Provides access to Module::regular_imports() field.
static FieldAccess ForModuleRegularImports();
// Provides access to Name::hash_field() field.
static FieldAccess ForNameHashField();
// Provides access to Name::raw_hash_field() field.
static FieldAccess ForNameRawHashField();
// Provides access to String::length() field.
static FieldAccess ForStringLength();

View File

@ -3917,7 +3917,7 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) {
Node* result =
__ Allocate(AllocationType::kYoung, __ IntPtrConstant(ConsString::kSize));
__ StoreField(AccessBuilder::ForMap(), result, result_map);
__ StoreField(AccessBuilder::ForNameHashField(), result,
__ StoreField(AccessBuilder::ForNameRawHashField(), result,
__ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), result, length);
__ StoreField(AccessBuilder::ForConsStringFirst(), result, first);
@ -4227,7 +4227,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
__ IntPtrConstant(SeqOneByteString::SizeFor(1)));
__ StoreField(AccessBuilder::ForMap(), vtrue2,
__ HeapConstant(factory()->one_byte_string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
__ StoreField(AccessBuilder::ForNameRawHashField(), vtrue2,
__ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vtrue2,
__ Int32Constant(1));
@ -4252,7 +4252,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
__ IntPtrConstant(SeqTwoByteString::SizeFor(1)));
__ StoreField(AccessBuilder::ForMap(), vfalse1,
__ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
__ StoreField(AccessBuilder::ForNameRawHashField(), vfalse1,
__ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse1,
__ Int32Constant(1));
@ -4353,7 +4353,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ IntPtrConstant(SeqOneByteString::SizeFor(1)));
__ StoreField(AccessBuilder::ForMap(), vtrue2,
__ HeapConstant(factory()->one_byte_string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
__ StoreField(AccessBuilder::ForNameRawHashField(), vtrue2,
__ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vtrue2,
__ Int32Constant(1));
@ -4378,7 +4378,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ IntPtrConstant(SeqTwoByteString::SizeFor(1)));
__ StoreField(AccessBuilder::ForMap(), vfalse1,
__ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
__ StoreField(AccessBuilder::ForNameRawHashField(), vfalse1,
__ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse1,
__ Int32Constant(1));
@ -4418,7 +4418,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ IntPtrConstant(SeqTwoByteString::SizeFor(2)));
__ StoreField(AccessBuilder::ForMap(), vfalse0,
__ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
__ StoreField(AccessBuilder::ForNameRawHashField(), vfalse0,
__ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse0,
__ Int32Constant(2));

View File

@ -648,7 +648,7 @@ void JSRegExpStringIterator::JSRegExpStringIteratorPrint(
void Symbol::SymbolPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "Symbol");
os << "\n - hash: " << Hash();
os << "\n - hash: " << hash();
os << "\n - description: " << Brief(description());
if (description().IsUndefined()) {
os << " (" << PrivateSymbolToName() << ")";

View File

@ -504,9 +504,9 @@ Handle<String> FactoryBase<Impl>::InternalizeString(
template <typename Impl>
Handle<SeqOneByteString> FactoryBase<Impl>::NewOneByteInternalizedString(
const Vector<const uint8_t>& str, uint32_t hash_field) {
const Vector<const uint8_t>& str, uint32_t raw_hash_field) {
Handle<SeqOneByteString> result =
AllocateRawOneByteInternalizedString(str.length(), hash_field);
AllocateRawOneByteInternalizedString(str.length(), raw_hash_field);
DisallowHeapAllocation no_gc;
MemCopy(result->GetChars(no_gc), str.begin(), str.length());
return result;
@ -514,9 +514,9 @@ Handle<SeqOneByteString> FactoryBase<Impl>::NewOneByteInternalizedString(
template <typename Impl>
Handle<SeqTwoByteString> FactoryBase<Impl>::NewTwoByteInternalizedString(
const Vector<const uc16>& str, uint32_t hash_field) {
const Vector<const uc16>& str, uint32_t raw_hash_field) {
Handle<SeqTwoByteString> result =
AllocateRawTwoByteInternalizedString(str.length(), hash_field);
AllocateRawTwoByteInternalizedString(str.length(), raw_hash_field);
DisallowHeapAllocation no_gc;
MemCopy(result->GetChars(no_gc), str.begin(), str.length() * kUC16Size);
return result;
@ -537,7 +537,7 @@ MaybeHandle<SeqOneByteString> FactoryBase<Impl>::NewRawOneByteString(
Handle<SeqOneByteString> string =
handle(SeqOneByteString::cast(result), isolate());
string->set_length(length);
string->set_hash_field(String::kEmptyHashField);
string->set_raw_hash_field(String::kEmptyHashField);
DCHECK_EQ(size, string->Size());
return string;
}
@ -557,7 +557,7 @@ MaybeHandle<SeqTwoByteString> FactoryBase<Impl>::NewRawTwoByteString(
Handle<SeqTwoByteString> string =
handle(SeqTwoByteString::cast(result), isolate());
string->set_length(length);
string->set_hash_field(String::kEmptyHashField);
string->set_raw_hash_field(String::kEmptyHashField);
DCHECK_EQ(size, string->Size());
return string;
}
@ -651,7 +651,7 @@ Handle<String> FactoryBase<Impl>::NewConsString(Handle<String> left,
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
result->set_hash_field(String::kEmptyHashField);
result->set_raw_hash_field(String::kEmptyHashField);
result->set_length(length);
result->set_first(*left, mode);
result->set_second(*right, mode);
@ -734,8 +734,8 @@ Handle<ClassPositions> FactoryBase<Impl>::NewClassPositions(int start,
template <typename Impl>
Handle<SeqOneByteString>
FactoryBase<Impl>::AllocateRawOneByteInternalizedString(int length,
uint32_t hash_field) {
FactoryBase<Impl>::AllocateRawOneByteInternalizedString(
int length, uint32_t raw_hash_field) {
CHECK_GE(String::kMaxLength, length);
// The canonical empty_string is the only zero-length string we allow.
DCHECK_IMPLIES(length == 0, !impl()->EmptyStringRootIsInitialized());
@ -750,15 +750,15 @@ FactoryBase<Impl>::AllocateRawOneByteInternalizedString(int length,
Handle<SeqOneByteString> answer =
handle(SeqOneByteString::cast(result), isolate());
answer->set_length(length);
answer->set_hash_field(hash_field);
answer->set_raw_hash_field(raw_hash_field);
DCHECK_EQ(size, answer->Size());
return answer;
}
template <typename Impl>
Handle<SeqTwoByteString>
FactoryBase<Impl>::AllocateRawTwoByteInternalizedString(int length,
uint32_t hash_field) {
FactoryBase<Impl>::AllocateRawTwoByteInternalizedString(
int length, uint32_t raw_hash_field) {
CHECK_GE(String::kMaxLength, length);
DCHECK_NE(0, length); // Use Heap::empty_string() instead.
@ -769,7 +769,7 @@ FactoryBase<Impl>::AllocateRawTwoByteInternalizedString(int length,
Handle<SeqTwoByteString> answer =
handle(SeqTwoByteString::cast(result), isolate());
answer->set_length(length);
answer->set_hash_field(hash_field);
answer->set_raw_hash_field(raw_hash_field);
DCHECK_EQ(size, result.Size());
return answer;
}

View File

@ -151,14 +151,14 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase {
Handle<String> InternalizeStringWithKey(StringTableKey* key);
Handle<SeqOneByteString> NewOneByteInternalizedString(
const Vector<const uint8_t>& str, uint32_t hash_field);
const Vector<const uint8_t>& str, uint32_t raw_hash_field);
Handle<SeqTwoByteString> NewTwoByteInternalizedString(
const Vector<const uc16>& str, uint32_t hash_field);
const Vector<const uc16>& str, uint32_t raw_hash_field);
Handle<SeqOneByteString> AllocateRawOneByteInternalizedString(
int length, uint32_t hash_field);
int length, uint32_t raw_hash_field);
Handle<SeqTwoByteString> AllocateRawTwoByteInternalizedString(
int length, uint32_t hash_field);
int length, uint32_t raw_hash_field);
// Allocates and partially initializes an one-byte or two-byte String. The
// characters of the string are uninitialized. Currently used in regexp code

View File

@ -763,7 +763,7 @@ Handle<String> Factory::AllocateInternalizedStringImpl(T t, int chars,
map);
Handle<String> answer(String::cast(result), isolate());
answer->set_length(chars);
answer->set_hash_field(hash_field);
answer->set_raw_hash_field(hash_field);
DCHECK_EQ(size, answer->Size());
DisallowHeapAllocation no_gc;
@ -824,7 +824,7 @@ Handle<StringClass> Factory::InternalizeExternalString(Handle<String> string) {
StringClass::cast(New(map, AllocationType::kOld)), isolate());
external_string->AllocateExternalPointerEntries(isolate());
external_string->set_length(cast_string->length());
external_string->set_hash_field(cast_string->hash_field());
external_string->set_raw_hash_field(cast_string->raw_hash_field());
external_string->SetResource(isolate(), nullptr);
isolate()->heap()->RegisterExternalString(*external_string);
return external_string;
@ -928,7 +928,7 @@ Handle<String> Factory::NewProperSubString(Handle<String> str, int begin,
Handle<SlicedString> slice(
SlicedString::cast(New(map, AllocationType::kYoung)), isolate());
slice->set_hash_field(String::kEmptyHashField);
slice->set_raw_hash_field(String::kEmptyHashField);
slice->set_length(length);
slice->set_parent(*str);
slice->set_offset(offset);
@ -950,7 +950,7 @@ MaybeHandle<String> Factory::NewExternalStringFromOneByte(
ExternalOneByteString::cast(New(map, AllocationType::kOld)), isolate());
external_string->AllocateExternalPointerEntries(isolate());
external_string->set_length(static_cast<int>(length));
external_string->set_hash_field(String::kEmptyHashField);
external_string->set_raw_hash_field(String::kEmptyHashField);
external_string->SetResource(isolate(), resource);
isolate()->heap()->RegisterExternalString(*external_string);
@ -971,7 +971,7 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
ExternalTwoByteString::cast(New(map, AllocationType::kOld)), isolate());
external_string->AllocateExternalPointerEntries(isolate());
external_string->set_length(static_cast<int>(length));
external_string->set_hash_field(String::kEmptyHashField);
external_string->set_raw_hash_field(String::kEmptyHashField);
external_string->SetResource(isolate(), resource);
isolate()->heap()->RegisterExternalString(*external_string);
@ -1002,8 +1002,8 @@ Handle<Symbol> Factory::NewSymbol(AllocationType allocation) {
int hash = isolate()->GenerateIdentityHash(Name::kHashBitMask);
Handle<Symbol> symbol(Symbol::cast(result), isolate());
symbol->set_hash_field(Name::kIsNotIntegerIndexMask |
(hash << Name::kHashShift));
symbol->set_raw_hash_field(Name::kIsNotIntegerIndexMask |
(hash << Name::kHashShift));
symbol->set_description(*undefined_value());
symbol->set_flags(0);
DCHECK(!symbol->is_private());
@ -2832,10 +2832,11 @@ inline Handle<String> Factory::SmiToString(Smi number, NumberCacheMode mode) {
// Compute the hash here (rather than letting the caller take care of it) so
// that the "cache hit" case above doesn't have to bother with it.
STATIC_ASSERT(Smi::kMaxValue <= std::numeric_limits<uint32_t>::max());
if (result->hash_field() == String::kEmptyHashField && number.value() >= 0) {
uint32_t field = StringHasher::MakeArrayIndexHash(
if (result->raw_hash_field() == String::kEmptyHashField &&
number.value() >= 0) {
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
static_cast<uint32_t>(number.value()), result->length());
result->set_hash_field(field);
result->set_raw_hash_field(raw_hash_field);
}
return result;
}
@ -2868,10 +2869,10 @@ Handle<String> Factory::SizeToString(size_t value, bool check_cache) {
result = NewStringFromAsciiChecked(string);
}
if (value <= JSArray::kMaxArrayIndex &&
result->hash_field() == String::kEmptyHashField) {
uint32_t field = StringHasher::MakeArrayIndexHash(
result->raw_hash_field() == String::kEmptyHashField) {
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
static_cast<uint32_t>(value), result->length());
result->set_hash_field(field);
result->set_raw_hash_field(raw_hash_field);
}
return result;
}

View File

@ -2554,9 +2554,9 @@ enum AccessorAssembler::StubCacheTable : int {
TNode<IntPtrT> AccessorAssembler::StubCachePrimaryOffset(TNode<Name> name,
TNode<Map> map) {
// Compute the hash of the name (use entire hash field).
TNode<Uint32T> hash_field = LoadNameHashField(name);
TNode<Uint32T> raw_hash_field = LoadNameRawHashField(name);
CSA_ASSERT(this,
Word32Equal(Word32And(hash_field,
Word32Equal(Word32And(raw_hash_field,
Int32Constant(Name::kHashNotComputedMask)),
Int32Constant(0)));
@ -2568,7 +2568,7 @@ TNode<IntPtrT> AccessorAssembler::StubCachePrimaryOffset(TNode<Name> name,
TNode<Int32T> map32 = TruncateIntPtrToInt32(UncheckedCast<IntPtrT>(
WordXor(map_word, WordShr(map_word, StubCache::kMapKeyShift))));
// Base the offset on a simple combination of name and map.
TNode<Word32T> hash = Int32Add(hash_field, map32);
TNode<Word32T> hash = Int32Add(raw_hash_field, map32);
uint32_t mask = (StubCache::kPrimaryTableSize - 1)
<< StubCache::kCacheIndexShift;
TNode<UintPtrT> result =

View File

@ -32,7 +32,7 @@ void StubCache::Initialize() {
int StubCache::PrimaryOffset(Name name, Map map) {
// Compute the hash of the name (use entire hash field).
DCHECK(name.HasHashCode());
uint32_t field = name.hash_field();
uint32_t field = name.raw_hash_field();
// Using only the low bits in 64-bit mode is unlikely to increase the
// risk of collision even if the heap is spread over an area larger than
// 4Gb (and not at all if it isn't).

View File

@ -17,7 +17,7 @@ int DescriptorLookupCache::Hash(Map source, Name name) {
DCHECK(name.IsUniqueName());
// Uses only lower 32 bits if pointers are larger.
uint32_t source_hash = static_cast<uint32_t>(source.ptr()) >> kTaggedSizeLog2;
uint32_t name_hash = name.hash_field();
uint32_t name_hash = name.hash();
return (source_hash ^ name_hash) % kLength;
}

View File

@ -86,18 +86,18 @@ bool Name::IsHashFieldComputed(uint32_t field) {
return (field & kHashNotComputedMask) == 0;
}
bool Name::HasHashCode() { return IsHashFieldComputed(hash_field()); }
bool Name::HasHashCode() { return IsHashFieldComputed(raw_hash_field()); }
uint32_t Name::Hash() {
// Fast case: has hash code already been computed?
uint32_t field = hash_field();
uint32_t field = raw_hash_field();
if (IsHashFieldComputed(field)) return field >> kHashShift;
// Slow case: compute hash code and set it. Has to be a string.
return String::cast(*this).ComputeAndSetHash();
}
uint32_t Name::hash() const {
uint32_t field = hash_field();
uint32_t field = raw_hash_field();
DCHECK(IsHashFieldComputed(field));
return field >> kHashShift;
}
@ -133,8 +133,8 @@ bool Name::AsIntegerIndex(size_t* index) {
}
// static
bool Name::ContainsCachedArrayIndex(uint32_t hash) {
return (hash & Name::kDoesNotContainCachedArrayIndexMask) == 0;
bool Name::ContainsCachedArrayIndex(uint32_t raw_hash_field) {
return (raw_hash_field & Name::kDoesNotContainCachedArrayIndexMask) == 0;
}
} // namespace internal

View File

@ -5,7 +5,7 @@
@abstract
@generateCppClass
extern class Name extends PrimitiveHeapObject {
hash_field: NameHash;
raw_hash_field: NameHash;
}
bitfield struct NameHash extends uint32 {

View File

@ -275,9 +275,9 @@ class SequentialStringKey final : public StringTableKey {
chars.begin(), chars.length(), seed),
chars, convert) {}
SequentialStringKey(int hash, const Vector<const Char>& chars,
SequentialStringKey(int raw_hash_field, const Vector<const Char>& chars,
bool convert = false)
: StringTableKey(hash, chars.length()),
: StringTableKey(raw_hash_field, chars.length()),
chars_(chars),
convert_(convert) {}
@ -294,19 +294,19 @@ class SequentialStringKey final : public StringTableKey {
Handle<String> AsHandle(Isolate* isolate) {
if (sizeof(Char) == 1) {
return isolate->factory()->NewOneByteInternalizedString(
Vector<const uint8_t>::cast(chars_), hash_field());
Vector<const uint8_t>::cast(chars_), raw_hash_field());
}
return isolate->factory()->NewTwoByteInternalizedString(
Vector<const uint16_t>::cast(chars_), hash_field());
Vector<const uint16_t>::cast(chars_), raw_hash_field());
}
Handle<String> AsHandle(LocalIsolate* isolate) {
if (sizeof(Char) == 1) {
return isolate->factory()->NewOneByteInternalizedString(
Vector<const uint8_t>::cast(chars_), hash_field());
Vector<const uint8_t>::cast(chars_), raw_hash_field());
}
return isolate->factory()->NewTwoByteInternalizedString(
Vector<const uint16_t>::cast(chars_), hash_field());
Vector<const uint16_t>::cast(chars_), raw_hash_field());
}
private:
@ -337,9 +337,9 @@ class SeqSubStringKey final : public StringTableKey {
convert_(convert) {
// We have to set the hash later.
DisallowHeapAllocation no_gc;
uint32_t hash = StringHasher::HashSequentialString(
uint32_t raw_hash_field = StringHasher::HashSequentialString(
string->GetChars(no_gc) + from, len, HashSeed(isolate));
set_hash_field(hash);
set_raw_hash_field(raw_hash_field);
DCHECK_LE(0, length());
DCHECK_LE(from_ + length(), string_->length());
@ -366,15 +366,15 @@ class SeqSubStringKey final : public StringTableKey {
if (sizeof(Char) == 1 || (sizeof(Char) == 2 && convert_)) {
Handle<SeqOneByteString> result =
isolate->factory()->AllocateRawOneByteInternalizedString(
length(), hash_field());
length(), raw_hash_field());
DisallowHeapAllocation no_gc;
CopyChars(result->GetChars(no_gc), string_->GetChars(no_gc) + from_,
length());
return result;
}
Handle<SeqTwoByteString> result =
isolate->factory()->AllocateRawTwoByteInternalizedString(length(),
hash_field());
isolate->factory()->AllocateRawTwoByteInternalizedString(
length(), raw_hash_field());
DisallowHeapAllocation no_gc;
CopyChars(result->GetChars(no_gc), string_->GetChars(no_gc) + from_,
length());
@ -834,7 +834,7 @@ void StringCharacterStream::VisitTwoByteString(const uint16_t* chars,
bool String::AsArrayIndex(uint32_t* index) {
DisallowHeapAllocation no_gc;
uint32_t field = hash_field();
uint32_t field = raw_hash_field();
if (ContainsCachedArrayIndex(field)) {
*index = ArrayIndexValueBits::decode(field);
return true;
@ -846,7 +846,7 @@ bool String::AsArrayIndex(uint32_t* index) {
}
bool String::AsIntegerIndex(size_t* index) {
uint32_t field = hash_field();
uint32_t field = raw_hash_field();
if (ContainsCachedArrayIndex(field)) {
*index = ArrayIndexValueBits::decode(field);
return true;

View File

@ -13,15 +13,15 @@
namespace v8 {
namespace internal {
StringTableKey::StringTableKey(uint32_t hash_field, int length)
: hash_field_(hash_field), length_(length) {}
StringTableKey::StringTableKey(uint32_t raw_hash_field, int length)
: raw_hash_field_(raw_hash_field), length_(length) {}
void StringTableKey::set_hash_field(uint32_t hash_field) {
hash_field_ = hash_field;
void StringTableKey::set_raw_hash_field(uint32_t raw_hash_field) {
raw_hash_field_ = raw_hash_field;
}
uint32_t StringTableKey::hash() const {
return hash_field_ >> Name::kHashShift;
return raw_hash_field_ >> Name::kHashShift;
}
} // namespace internal

View File

@ -71,7 +71,7 @@ int ComputeStringTableCapacityWithShrink(int current_capacity,
template <typename StringTableKey>
bool KeyIsMatch(StringTableKey* key, String string) {
if (string.hash_field() != key->hash_field()) return false;
if (string.hash() != key->hash()) return false;
if (string.length() != key->length()) return false;
return key->IsMatch(string);
}
@ -355,7 +355,7 @@ class InternalizedStringKey final : public StringTableKey {
DCHECK(string->IsFlat());
// Make sure hash_field is computed.
string->Hash();
set_hash_field(string->hash_field());
set_raw_hash_field(string->raw_hash_field());
}
bool IsMatch(String string) override { return string_->SlowEquals(string); }
@ -383,7 +383,7 @@ class InternalizedStringKey final : public StringTableKey {
}
// Otherwise allocate a new internalized string.
return isolate->factory()->NewInternalizedStringImpl(
string_, string_->length(), string_->hash_field());
string_, string_->length(), string_->raw_hash_field());
}
private:
@ -610,13 +610,14 @@ Address StringTable::Data::TryStringToIndexOrLookupExisting(Isolate* isolate,
SequentialStringKey<Char> key(Vector<const Char>(chars, length), seed);
// String could be an array index.
uint32_t hash_field = key.hash_field();
uint32_t raw_hash_field = key.raw_hash_field();
if (Name::ContainsCachedArrayIndex(hash_field)) {
return Smi::FromInt(String::ArrayIndexValueBits::decode(hash_field)).ptr();
if (Name::ContainsCachedArrayIndex(raw_hash_field)) {
return Smi::FromInt(String::ArrayIndexValueBits::decode(raw_hash_field))
.ptr();
}
if ((hash_field & Name::kIsNotIntegerIndexMask) == 0) {
if ((raw_hash_field & Name::kIsNotIntegerIndexMask) == 0) {
// It is an index, but it's not cached.
return Smi::FromInt(ResultSentinel::kUnsupported).ptr();
}

View File

@ -20,15 +20,15 @@ namespace internal {
class StringTableKey {
public:
virtual ~StringTableKey() = default;
inline StringTableKey(uint32_t hash_field, int length);
inline StringTableKey(uint32_t raw_hash_field, int length);
// The individual keys will have their own AsHandle, we shouldn't call the
// base version.
Handle<String> AsHandle(Isolate* isolate) = delete;
uint32_t hash_field() const {
DCHECK_NE(0, hash_field_);
return hash_field_;
uint32_t raw_hash_field() const {
DCHECK_NE(0, raw_hash_field_);
return raw_hash_field_;
}
virtual bool IsMatch(String string) = 0;
@ -36,10 +36,10 @@ class StringTableKey {
int length() const { return length_; }
protected:
inline void set_hash_field(uint32_t hash_field);
inline void set_raw_hash_field(uint32_t raw_hash_field);
private:
uint32_t hash_field_ = 0;
uint32_t raw_hash_field_ = 0;
int length_;
};

View File

@ -512,13 +512,13 @@ Handle<Object> String::ToNumber(Isolate* isolate, Handle<String> subject) {
(len == 1 || data[0] != '0')) {
// String hash is not calculated yet but all the data are present.
// Update the hash field to speed up sequential convertions.
uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(d, len);
#ifdef DEBUG
subject->Hash(); // Force hash calculation.
DCHECK_EQ(static_cast<int>(subject->hash_field()),
static_cast<int>(hash));
DCHECK_EQ(static_cast<int>(subject->raw_hash_field()),
static_cast<int>(raw_hash_field));
#endif
subject->set_hash_field(hash);
subject->set_raw_hash_field(raw_hash_field);
}
return handle(Smi::FromInt(d), isolate);
}
@ -1392,18 +1392,19 @@ uint32_t String::ComputeAndSetHash() {
if (string.IsThinString()) {
string = ThinString::cast(string).actual();
if (length() == string.length()) {
set_hash_field(string.hash_field());
return hash_field() >> kHashShift;
set_raw_hash_field(string.raw_hash_field());
return hash();
}
}
uint32_t field = string.IsOneByteRepresentation()
? HashString<uint8_t>(string, start, length(), seed)
: HashString<uint16_t>(string, start, length(), seed);
set_hash_field(field);
uint32_t raw_hash_field =
string.IsOneByteRepresentation()
? HashString<uint8_t>(string, start, length(), seed)
: HashString<uint16_t>(string, start, length(), seed);
set_raw_hash_field(raw_hash_field);
// Check the hash code is there.
DCHECK(HasHashCode());
uint32_t result = field >> kHashShift;
uint32_t result = raw_hash_field >> kHashShift;
DCHECK_NE(result, 0); // Ensure that the hash value of 0 is never computed.
return result;
}
@ -1413,7 +1414,7 @@ bool String::SlowAsArrayIndex(uint32_t* index) {
int length = this->length();
if (length <= kMaxCachedArrayIndexLength) {
Hash(); // Force computation of hash code.
uint32_t field = hash_field();
uint32_t field = raw_hash_field();
if ((field & kIsNotIntegerIndexMask) != 0) return false;
*index = ArrayIndexValueBits::decode(field);
return true;
@ -1428,7 +1429,7 @@ bool String::SlowAsIntegerIndex(size_t* index) {
int length = this->length();
if (length <= kMaxCachedArrayIndexLength) {
Hash(); // Force computation of hash code.
uint32_t field = hash_field();
uint32_t field = raw_hash_field();
if ((field & kIsNotIntegerIndexMask) != 0) return false;
*index = ArrayIndexValueBits::decode(field);
return true;

View File

@ -86,7 +86,7 @@ macro AllocateSeqOneByteString(length: uint32): SeqOneByteString {
if (length == 0) return UnsafeCast<SeqOneByteString>(kEmptyString);
return new SeqOneByteString{
map: kOneByteStringMap,
hash_field: kNameEmptyHashField,
raw_hash_field: kNameEmptyHashField,
length: Signed(length),
chars: ...UninitializedIterator {}
};
@ -98,7 +98,7 @@ macro AllocateSeqTwoByteString(length: uint32): String {
if (length == 0) return kEmptyString;
return new SeqTwoByteString{
map: kStringMap,
hash_field: kNameEmptyHashField,
raw_hash_field: kNameEmptyHashField,
length: Signed(length),
chars: ...UninitializedIterator {}
};

View File

@ -108,9 +108,19 @@ const char* StringsStorage::GetConsName(const char* prefix, Name name) {
return "";
}
namespace {
inline uint32_t ComputeStringHash(const char* str, int len) {
uint32_t raw_hash_field =
StringHasher::HashSequentialString(str, len, kZeroHashSeed);
return raw_hash_field >> Name::kHashShift;
}
} // namespace
bool StringsStorage::Release(const char* str) {
int len = static_cast<int>(strlen(str));
uint32_t hash = StringHasher::HashSequentialString(str, len, kZeroHashSeed);
uint32_t hash = ComputeStringHash(str, len);
base::HashMap::Entry* entry = names_.Lookup(const_cast<char*>(str), hash);
DCHECK(entry);
if (!entry) {
@ -133,7 +143,7 @@ size_t StringsStorage::GetStringCountForTesting() const {
}
base::HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) {
uint32_t hash = StringHasher::HashSequentialString(str, len, kZeroHashSeed);
uint32_t hash = ComputeStringHash(str, len);
return names_.LookupOrInsert(const_cast<char*>(str), hash);
}

View File

@ -305,7 +305,7 @@ void Deserializer::LogScriptEvents(Script script) {
}
StringTableInsertionKey::StringTableInsertionKey(Handle<String> string)
: StringTableKey(ComputeHashField(*string), string->length()),
: StringTableKey(ComputeRawHashField(*string), string->length()),
string_(string) {
DCHECK(string->IsInternalizedString());
}
@ -319,10 +319,10 @@ Handle<String> StringTableInsertionKey::AsHandle(Isolate* isolate) {
return string_;
}
uint32_t StringTableInsertionKey::ComputeHashField(String string) {
// Make sure hash_field() is computed.
uint32_t StringTableInsertionKey::ComputeRawHashField(String string) {
// Make sure raw_hash_field() is computed.
string.Hash();
return string.hash_field();
return string.raw_hash_field();
}
void Deserializer::PostProcessNewObject(Handle<Map> map, Handle<HeapObject> obj,
@ -335,7 +335,7 @@ void Deserializer::PostProcessNewObject(Handle<Map> map, Handle<HeapObject> obj,
if (InstanceTypeChecker::IsString(instance_type)) {
// Uninitialize hash field as we need to recompute the hash.
Handle<String> string = Handle<String>::cast(obj);
string->set_hash_field(String::kEmptyHashField);
string->set_raw_hash_field(String::kEmptyHashField);
// Rehash strings before read-only space is sealed. Strings outside
// read-only space are rehashed lazily. (e.g. when rehashing dictionaries)
if (space == SnapshotSpace::kReadOnlyHeap) {

View File

@ -275,7 +275,7 @@ class StringTableInsertionKey final : public StringTableKey {
V8_WARN_UNUSED_RESULT Handle<String> AsHandle(LocalIsolate* isolate);
private:
uint32_t ComputeHashField(String string);
uint32_t ComputeRawHashField(String string);
Handle<String> string_;
DISALLOW_HEAP_ALLOCATION(no_gc)

View File

@ -13,6 +13,8 @@ namespace internal {
template <typename T>
class Vector;
// Helper class for incrementally calculating string hashes in a form suitable
// for storing into Name::raw_hash_field.
class V8_EXPORT_PRIVATE StringHasher final {
public:
StringHasher() = delete;

View File

@ -214,7 +214,7 @@ TEST(GetObjectProperties) {
CHECK(props->type == std::string("v8::internal::SeqOneByteString"));
CHECK_EQ(props->num_properties, 4);
CheckProp(*props->properties[0], "v8::internal::Map", "map");
CheckProp(*props->properties[1], "uint32_t", "hash_field");
CheckProp(*props->properties[1], "uint32_t", "raw_hash_field");
CheckProp(*props->properties[2], "int32_t", "length", 2);
CheckProp(*props->properties[3], "char", "chars",
d::PropertyKind::kArrayOfKnownSize, 2);
@ -261,7 +261,7 @@ TEST(GetObjectProperties) {
}
CheckProp(*props2->properties[0], "v8::internal::Map", "map",
*reinterpret_cast<i::Tagged_t*>(props->properties[0]->address));
CheckProp(*props2->properties[1], "uint32_t", "hash_field",
CheckProp(*props2->properties[1], "uint32_t", "raw_hash_field",
*reinterpret_cast<int32_t*>(props->properties[1]->address));
CheckProp(*props2->properties[2], "int32_t", "length", 2);
}
@ -276,7 +276,7 @@ TEST(GetObjectProperties) {
CHECK_EQ(props2->num_properties, 4);
CheckProp(*props2->properties[0], "v8::internal::Map", "map",
*reinterpret_cast<i::Tagged_t*>(props->properties[0]->address));
CheckProp(*props2->properties[1], "uint32_t", "hash_field",
CheckProp(*props2->properties[1], "uint32_t", "raw_hash_field",
*reinterpret_cast<i::Tagged_t*>(props->properties[1]->address));
CheckProp(*props2->properties[2], "int32_t", "length", 2);

View File

@ -36,7 +36,7 @@ Handle<Name> NewNameWithHash(Isolate* isolate, const char* str, uint32_t hash,
}
Handle<Name> name = isolate->factory()->NewOneByteInternalizedString(
OneByteVector(str), hash_field);
name->set_hash_field(hash_field);
name->set_raw_hash_field(hash_field);
CHECK(name->IsUniqueName());
return name;
}

View File

@ -1830,13 +1830,13 @@ void TestString(i::Isolate* isolate, const IndexData& data) {
CHECK(s->AsIntegerIndex(&index));
CHECK_EQ(data.integer_index, index);
s->Hash();
CHECK_EQ(0, s->hash_field() & String::kIsNotIntegerIndexMask);
CHECK_EQ(0, s->raw_hash_field() & String::kIsNotIntegerIndexMask);
CHECK(s->HasHashCode());
}
if (!s->HasHashCode()) s->Hash();
CHECK(s->HasHashCode());
if (!data.is_integer_index) {
CHECK_NE(0, s->hash_field() & String::kIsNotIntegerIndexMask);
CHECK_NE(0, s->raw_hash_field() & String::kIsNotIntegerIndexMask);
}
}

View File

@ -378,10 +378,11 @@ void CompileRunAndVerify(FuzzerArgs* args, const std::string& source) {
}
if (!ResultsAreIdentical(args)) {
uint32_t hash = StringHasher::HashSequentialString(
uint32_t raw_hash_field = StringHasher::HashSequentialString(
args->input_data, static_cast<int>(args->input_length),
kRegExpBuiltinsFuzzerHashSeed);
FATAL("!ResultAreIdentical(args); RegExpBuiltinsFuzzerHash=%x", hash);
FATAL("!ResultAreIdentical(args); RegExpBuiltinsFuzzerHash=%x",
raw_hash_field);
}
}