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

Unified Diff: runtime/vm/object.h

Issue 2895183002: More compact string representation on 64 bit. (Closed)
Patch Set: Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/intrinsifier_x64.cc ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.h
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3bb0676ad323a7c8eb9e4e5d12b43c3ea91f0d19..d43fbaaed9fa17c68c2444756a4262322f83ad24 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -432,6 +432,18 @@ class Object {
return *transition_sentinel_;
}
+#if defined(HASH_IN_OBJECT_HEADER)
+ static uint32_t GetCachedHash(const RawObject* obj) {
+ uword tags = obj->ptr()->tags_;
+ return tags >> 32;
+ }
+
+ static void SetCachedHash(RawObject* obj, uintptr_t hash) {
+ ASSERT(hash >> 32 == 0);
+ obj->ptr()->tags_ |= hash << 32;
+ }
+#endif
+
// Compiler's constant propagation constants.
static const Instance& unknown_constant() {
ASSERT(unknown_constant_ != NULL);
@@ -6754,8 +6766,11 @@ class String : public Instance {
// All strings share the same maximum element count to keep things
// simple. We choose a value that will prevent integer overflow for
// 2 byte strings, since it is the worst case.
- static const intptr_t kSizeofRawString =
- sizeof(RawInstance) + (2 * kWordSize);
+#if defined(HASH_IN_OBJECT_HEADER)
+ static const intptr_t kSizeofRawString = sizeof(RawInstance) + kWordSize;
+#else
+ static const intptr_t kSizeofRawString = sizeof(RawInstance) + 2 * kWordSize;
+#endif
static const intptr_t kMaxElements = kSmiMax / kTwoByteChar;
class CodePointIterator : public ValueObject {
@@ -6791,28 +6806,32 @@ class String : public Instance {
static intptr_t length_offset() { return OFFSET_OF(RawString, length_); }
intptr_t Hash() const {
- intptr_t result = Smi::Value(raw_ptr()->hash_);
+ intptr_t result = GetCachedHash(raw());
if (result != 0) {
return result;
}
result = String::Hash(*this, 0, this->Length());
- this->SetHash(result);
+ SetCachedHash(raw(), result);
return result;
}
bool HasHash() const {
ASSERT(Smi::New(0) == NULL);
- return (raw_ptr()->hash_ != NULL);
+ return GetCachedHash(raw()) != 0;
}
+#if defined(HASH_IN_OBJECT_HEADER)
+ static intptr_t hash_offset() { return kInt32Size; } // Wrong for big-endian?
+#else
static intptr_t hash_offset() { return OFFSET_OF(RawString, hash_); }
+#endif
static intptr_t Hash(const String& str, intptr_t begin_index, intptr_t len);
static intptr_t Hash(const char* characters, intptr_t len);
static intptr_t Hash(const uint16_t* characters, intptr_t len);
static intptr_t Hash(const int32_t* characters, intptr_t len);
static intptr_t HashRawSymbol(const RawString* symbol) {
ASSERT(symbol->IsCanonical());
- intptr_t result = Smi::Value(symbol->ptr()->hash_);
+ intptr_t result = GetCachedHash(symbol);
ASSERT(result != 0);
return result;
}
@@ -7031,6 +7050,16 @@ class String : public Instance {
intptr_t end,
double* result);
+#if !defined(HASH_IN_OBJECT_HEADER)
+ static uint32_t GetCachedHash(const RawString* obj) {
+ return Smi::Value(obj->ptr()->hash_);
+ }
+
+ static void SetCachedHash(RawString* obj, uintptr_t hash) {
+ obj->ptr()->hash_ = Smi::New(hash);
+ }
+#endif
+
protected:
// These two operate on an array of Latin-1 encoded characters.
// They are protected to avoid mistaking Latin-1 for UTF-8, but used
@@ -7044,11 +7073,7 @@ class String : public Instance {
StoreSmi(&raw_ptr()->length_, Smi::New(value));
}
- void SetHash(intptr_t value) const {
- // This is only safe because we create a new Smi, which does not cause
- // heap allocation.
- StoreSmi(&raw_ptr()->hash_, Smi::New(value));
- }
+ void SetHash(intptr_t value) const { SetCachedHash(raw(), value); }
template <typename HandleType, typename ElementType, typename CallbackType>
static void ReadFromImpl(SnapshotReader* reader,
@@ -7107,6 +7132,12 @@ class OneByteString : public AllStatic {
static intptr_t InstanceSize(intptr_t len) {
ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString);
ASSERT(0 <= len && len <= kMaxElements);
+#if defined(HASH_IN_OBJECT_HEADER)
+ // We have to pad zero-length raw strings so that they can be externalized.
+ // If we don't pad, then the external string object does not fit in the
+ // memory allocated for the raw string.
+ if (len == 0) return InstanceSize(1);
+#endif
return String::RoundedAllocationSize(sizeof(RawOneByteString) +
(len * kBytesPerElement));
}
@@ -7240,6 +7271,10 @@ class TwoByteString : public AllStatic {
static intptr_t InstanceSize(intptr_t len) {
ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString);
ASSERT(0 <= len && len <= kMaxElements);
+ // We have to pad zero-length raw strings so that they can be externalized.
+ // If we don't pad, then the external string object does not fit in the
+ // memory allocated for the raw string.
+ if (len == 0) return InstanceSize(1);
return String::RoundedAllocationSize(sizeof(RawTwoByteString) +
(len * kBytesPerElement));
}
@@ -8933,7 +8968,7 @@ bool String::Equals(const String& str) const {
intptr_t Library::UrlHash() const {
- intptr_t result = Smi::Value(url()->ptr()->hash_);
+ intptr_t result = String::GetCachedHash(url());
ASSERT(result != 0);
return result;
}
« no previous file with comments | « runtime/vm/intrinsifier_x64.cc ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698