diff --git a/runtime/ecma_string-inl.h b/runtime/ecma_string-inl.h index d0b2d766a185ae19658410a32b190382597b7086..70690920fb6b9e2596213c0a3516ed54c29ec5c3 100644 --- a/runtime/ecma_string-inl.h +++ b/runtime/ecma_string-inl.h @@ -43,6 +43,7 @@ inline EcmaString *EcmaString::CreateEmptyString(const EcmaVM *vm) auto string = vm->GetFactory()->AllocNonMovableStringObject(EcmaString::SIZE); string->SetLength(0, GetCompressedStringsEnabled()); string->SetRawHashcode(0); + ASSERT(string->GetStringHashCode() == 0U); return string; } @@ -124,6 +125,7 @@ inline EcmaString *EcmaString::AllocStringObject(size_t length, bool compressed, : reinterpret_cast(vm->GetFactory()->AllocStringObject(size)); string->SetLength(length, compressed); string->SetRawHashcode(0); + ASSERT(string->GetStringHashCode() == 0U); return reinterpret_cast(string); } diff --git a/runtime/ecma_string.cpp b/runtime/ecma_string.cpp index 5d39282763a8d5f43420837dee511e886a8fb34d..3156d4e306737ae28cddd6b3ab1732184cb535ee 100644 --- a/runtime/ecma_string.cpp +++ b/runtime/ecma_string.cpp @@ -375,6 +375,23 @@ bool EcmaString::StringCopy(Span &dst, size_t dst_max, Span &src, si return true; } +template +static int32_t ComputeHashForData(const T *data, size_t size) +{ + uint32_t hash = 0; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wignored-attributes" + Span sp(data, size); +#pragma GCC diagnostic pop +#endif + for (auto c : sp) { + constexpr size_t SHIFT = 5; + hash = (hash << SHIFT) - hash + c; + } + return static_cast(hash) & MarkWord::HASH_MASK; +} + static int32_t ComputeHashForUtf8(const uint8_t *utf8_data, size_t utf8_len) { if (utf8_data == nullptr) { @@ -385,7 +402,7 @@ static int32_t ComputeHashForUtf8(const uint8_t *utf8_data, size_t utf8_len) constexpr size_t SHIFT = 5; hash = (hash << SHIFT) - hash + *utf8_data++; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) } - return static_cast(hash); + return static_cast(hash) & MarkWord::HASH_MASK; } uint32_t EcmaString::ComputeHashcode() const diff --git a/runtime/ecma_string.h b/runtime/ecma_string.h index bdd17113cbbb7507f19ce7fd134556189702391f..4293332d65d1e54d7298be00308d082345238d82 100644 --- a/runtime/ecma_string.h +++ b/runtime/ecma_string.h @@ -30,23 +30,6 @@ template class JSHandle; class EcmaVM; -template -static int32_t ComputeHashForData(const T *data, size_t size) -{ - uint32_t hash = 0; -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wignored-attributes" - Span sp(data, size); -#pragma GCC diagnostic pop -#endif - for (auto c : sp) { - constexpr size_t SHIFT = 5; - hash = (hash << SHIFT) - hash + c; - } - return static_cast(hash); -} - class EcmaString : public TaggedObject { public: static EcmaString *Cast(ObjectHeader *object); @@ -233,11 +216,15 @@ public: uint32_t GetHashcode() { - uint32_t hashcode = GetRawHashcode(); + uint32_t hashcode = this->GetStringHashCode(); if (hashcode == 0) { hashcode = ComputeHashcode(); SetRawHashcode(hashcode); + this->SaveStringHashCode(hashcode); + } else { + ASSERT(hashcode == ComputeHashcode()); } + ASSERT((hashcode & (~MarkWord::HASH_MASK)) == 0U); return hashcode; } @@ -309,6 +296,7 @@ private: return reinterpret_cast(GetData()); } + static uint32_t ConvertHashCode(uint32_t hashcode); uint32_t ComputeHashcode() const; static void CopyUtf16AsUtf8(const uint16_t *utf16_from, uint8_t *utf8_to, uint32_t utf16_len);