Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef RUNTIME_VM_OBJECT_H_ | 5 #ifndef RUNTIME_VM_OBJECT_H_ |
| 6 #define RUNTIME_VM_OBJECT_H_ | 6 #define RUNTIME_VM_OBJECT_H_ |
| 7 | 7 |
| 8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
| (...skipping 6734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6745 // 64-bit architecture stay in Smi range when loaded on a 32-bit | 6745 // 64-bit architecture stay in Smi range when loaded on a 32-bit |
| 6746 // architecture. | 6746 // architecture. |
| 6747 static const intptr_t kHashBits = 30; | 6747 static const intptr_t kHashBits = 30; |
| 6748 | 6748 |
| 6749 static const intptr_t kOneByteChar = 1; | 6749 static const intptr_t kOneByteChar = 1; |
| 6750 static const intptr_t kTwoByteChar = 2; | 6750 static const intptr_t kTwoByteChar = 2; |
| 6751 | 6751 |
| 6752 // All strings share the same maximum element count to keep things | 6752 // All strings share the same maximum element count to keep things |
| 6753 // simple. We choose a value that will prevent integer overflow for | 6753 // simple. We choose a value that will prevent integer overflow for |
| 6754 // 2 byte strings, since it is the worst case. | 6754 // 2 byte strings, since it is the worst case. |
| 6755 static const intptr_t kSizeofRawString = | 6755 #if defined(HASH_IN_OBJECT_HEADER) |
| 6756 sizeof(RawInstance) + (2 * kWordSize); | 6756 static const intptr_t kSizeofRawString = sizeof(RawInstance) + kWordSize; |
| 6757 #else | |
| 6758 static const intptr_t kSizeofRawString = sizeof(RawInstance) + 2 * kWordSize; | |
| 6759 #endif | |
| 6757 static const intptr_t kMaxElements = kSmiMax / kTwoByteChar; | 6760 static const intptr_t kMaxElements = kSmiMax / kTwoByteChar; |
| 6758 | 6761 |
| 6759 class CodePointIterator : public ValueObject { | 6762 class CodePointIterator : public ValueObject { |
| 6760 public: | 6763 public: |
| 6761 explicit CodePointIterator(const String& str) | 6764 explicit CodePointIterator(const String& str) |
| 6762 : str_(str), ch_(0), index_(-1), end_(str.Length()) { | 6765 : str_(str), ch_(0), index_(-1), end_(str.Length()) { |
| 6763 ASSERT(!str_.IsNull()); | 6766 ASSERT(!str_.IsNull()); |
| 6764 } | 6767 } |
| 6765 | 6768 |
| 6766 CodePointIterator(const String& str, intptr_t start, intptr_t length) | 6769 CodePointIterator(const String& str, intptr_t start, intptr_t length) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 6782 int32_t ch_; | 6785 int32_t ch_; |
| 6783 intptr_t index_; | 6786 intptr_t index_; |
| 6784 intptr_t end_; | 6787 intptr_t end_; |
| 6785 DISALLOW_IMPLICIT_CONSTRUCTORS(CodePointIterator); | 6788 DISALLOW_IMPLICIT_CONSTRUCTORS(CodePointIterator); |
| 6786 }; | 6789 }; |
| 6787 | 6790 |
| 6788 intptr_t Length() const { return Smi::Value(raw_ptr()->length_); } | 6791 intptr_t Length() const { return Smi::Value(raw_ptr()->length_); } |
| 6789 static intptr_t length_offset() { return OFFSET_OF(RawString, length_); } | 6792 static intptr_t length_offset() { return OFFSET_OF(RawString, length_); } |
| 6790 | 6793 |
| 6791 intptr_t Hash() const { | 6794 intptr_t Hash() const { |
| 6792 intptr_t result = Smi::Value(raw_ptr()->hash_); | 6795 intptr_t result = GetRawHash(); |
|
Vyacheslav Egorov (Google)
2017/05/18 06:14:42
Maybe call it GetCachedHash(...)?
erikcorry
2017/05/18 14:28:38
Done.
| |
| 6793 if (result != 0) { | 6796 if (result != 0) { |
| 6794 return result; | 6797 return result; |
| 6795 } | 6798 } |
| 6796 result = String::Hash(*this, 0, this->Length()); | 6799 result = String::Hash(*this, 0, this->Length()); |
| 6797 this->SetHash(result); | 6800 this->SetHash(result); |
| 6798 return result; | 6801 return result; |
| 6799 } | 6802 } |
| 6800 | 6803 |
| 6801 bool HasHash() const { | 6804 bool HasHash() const { |
| 6802 ASSERT(Smi::New(0) == NULL); | 6805 ASSERT(Smi::New(0) == NULL); |
| 6803 return (raw_ptr()->hash_ != NULL); | 6806 return GetRawHash() != 0; |
| 6804 } | 6807 } |
| 6805 | 6808 |
| 6809 #if defined(HASH_IN_OBJECT_HEADER) | |
| 6810 static intptr_t hash_offset() { return kInt32Size; } // Wrong for big-endian? | |
|
Vyacheslav Egorov (Google)
2017/05/18 06:14:42
we don't support big-endian afaik
erikcorry
2017/05/18 14:28:38
No, but if we ever do, it's nice to leave hints th
| |
| 6811 #else | |
| 6806 static intptr_t hash_offset() { return OFFSET_OF(RawString, hash_); } | 6812 static intptr_t hash_offset() { return OFFSET_OF(RawString, hash_); } |
| 6813 #endif | |
| 6814 uint32_t GetRawHash() const { return raw()->GetRawHash(); } | |
| 6815 void SetRawHash(uint32_t hash) { raw()->SetRawHash(hash); } | |
| 6807 static intptr_t Hash(const String& str, intptr_t begin_index, intptr_t len); | 6816 static intptr_t Hash(const String& str, intptr_t begin_index, intptr_t len); |
| 6808 static intptr_t Hash(const char* characters, intptr_t len); | 6817 static intptr_t Hash(const char* characters, intptr_t len); |
| 6809 static intptr_t Hash(const uint16_t* characters, intptr_t len); | 6818 static intptr_t Hash(const uint16_t* characters, intptr_t len); |
| 6810 static intptr_t Hash(const int32_t* characters, intptr_t len); | 6819 static intptr_t Hash(const int32_t* characters, intptr_t len); |
| 6811 static intptr_t HashRawSymbol(const RawString* symbol) { | 6820 static intptr_t HashRawSymbol(const RawString* symbol) { |
| 6812 ASSERT(symbol->IsCanonical()); | 6821 ASSERT(symbol->IsCanonical()); |
| 6813 intptr_t result = Smi::Value(symbol->ptr()->hash_); | 6822 intptr_t result = symbol->GetRawHash(); |
| 6814 ASSERT(result != 0); | 6823 ASSERT(result != 0); |
| 6815 return result; | 6824 return result; |
| 6816 } | 6825 } |
| 6817 | 6826 |
| 6818 // Returns the hash of str1 + str2. | 6827 // Returns the hash of str1 + str2. |
| 6819 static intptr_t HashConcat(const String& str1, const String& str2); | 6828 static intptr_t HashConcat(const String& str1, const String& str2); |
| 6820 | 6829 |
| 6821 virtual RawObject* HashCode() const { return Integer::New(Hash()); } | 6830 virtual RawObject* HashCode() const { return Integer::New(Hash()); } |
| 6822 | 6831 |
| 6823 uint16_t CharAt(intptr_t index) const; | 6832 uint16_t CharAt(intptr_t index) const; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7035 // by friendly templated code (e.g., Symbols). | 7044 // by friendly templated code (e.g., Symbols). |
| 7036 bool Equals(const uint8_t* characters, intptr_t len) const; | 7045 bool Equals(const uint8_t* characters, intptr_t len) const; |
| 7037 static intptr_t Hash(const uint8_t* characters, intptr_t len); | 7046 static intptr_t Hash(const uint8_t* characters, intptr_t len); |
| 7038 | 7047 |
| 7039 void SetLength(intptr_t value) const { | 7048 void SetLength(intptr_t value) const { |
| 7040 // This is only safe because we create a new Smi, which does not cause | 7049 // This is only safe because we create a new Smi, which does not cause |
| 7041 // heap allocation. | 7050 // heap allocation. |
| 7042 StoreSmi(&raw_ptr()->length_, Smi::New(value)); | 7051 StoreSmi(&raw_ptr()->length_, Smi::New(value)); |
| 7043 } | 7052 } |
| 7044 | 7053 |
| 7045 void SetHash(intptr_t value) const { | 7054 void SetHash(intptr_t value) const { raw()->SetRawHash(value); } |
| 7046 // This is only safe because we create a new Smi, which does not cause | |
| 7047 // heap allocation. | |
| 7048 StoreSmi(&raw_ptr()->hash_, Smi::New(value)); | |
| 7049 } | |
| 7050 | 7055 |
| 7051 template <typename HandleType, typename ElementType, typename CallbackType> | 7056 template <typename HandleType, typename ElementType, typename CallbackType> |
| 7052 static void ReadFromImpl(SnapshotReader* reader, | 7057 static void ReadFromImpl(SnapshotReader* reader, |
| 7053 String* str_obj, | 7058 String* str_obj, |
| 7054 intptr_t len, | 7059 intptr_t len, |
| 7055 intptr_t tags, | 7060 intptr_t tags, |
| 7056 CallbackType new_symbol, | 7061 CallbackType new_symbol, |
| 7057 Snapshot::Kind kind); | 7062 Snapshot::Kind kind); |
| 7058 | 7063 |
| 7059 FINAL_HEAP_OBJECT_IMPLEMENTATION(String, Instance); | 7064 FINAL_HEAP_OBJECT_IMPLEMENTATION(String, Instance); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7098 | 7103 |
| 7099 static intptr_t InstanceSize() { | 7104 static intptr_t InstanceSize() { |
| 7100 ASSERT(sizeof(RawOneByteString) == | 7105 ASSERT(sizeof(RawOneByteString) == |
| 7101 OFFSET_OF_RETURNED_VALUE(RawOneByteString, data)); | 7106 OFFSET_OF_RETURNED_VALUE(RawOneByteString, data)); |
| 7102 return 0; | 7107 return 0; |
| 7103 } | 7108 } |
| 7104 | 7109 |
| 7105 static intptr_t InstanceSize(intptr_t len) { | 7110 static intptr_t InstanceSize(intptr_t len) { |
| 7106 ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString); | 7111 ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString); |
| 7107 ASSERT(0 <= len && len <= kMaxElements); | 7112 ASSERT(0 <= len && len <= kMaxElements); |
| 7113 #if defined(HASH_IN_OBJECT_HEADER) | |
| 7114 // We have to pad zero-length raw strings so that they can be externalized. | |
| 7115 // If we don't pad, then the external string object does not fit in the | |
| 7116 // memory allocated for the raw string. | |
| 7117 if (len == 0) return InstanceSize(1); | |
| 7118 #endif | |
| 7108 return String::RoundedAllocationSize(sizeof(RawOneByteString) + | 7119 return String::RoundedAllocationSize(sizeof(RawOneByteString) + |
| 7109 (len * kBytesPerElement)); | 7120 (len * kBytesPerElement)); |
| 7110 } | 7121 } |
| 7111 | 7122 |
| 7112 static RawOneByteString* New(intptr_t len, Heap::Space space); | 7123 static RawOneByteString* New(intptr_t len, Heap::Space space); |
| 7113 static RawOneByteString* New(const char* c_string, | 7124 static RawOneByteString* New(const char* c_string, |
| 7114 Heap::Space space = Heap::kNew) { | 7125 Heap::Space space = Heap::kNew) { |
| 7115 return New(reinterpret_cast<const uint8_t*>(c_string), strlen(c_string), | 7126 return New(reinterpret_cast<const uint8_t*>(c_string), strlen(c_string), |
| 7116 space); | 7127 space); |
| 7117 } | 7128 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7231 | 7242 |
| 7232 static intptr_t InstanceSize() { | 7243 static intptr_t InstanceSize() { |
| 7233 ASSERT(sizeof(RawTwoByteString) == | 7244 ASSERT(sizeof(RawTwoByteString) == |
| 7234 OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data)); | 7245 OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data)); |
| 7235 return 0; | 7246 return 0; |
| 7236 } | 7247 } |
| 7237 | 7248 |
| 7238 static intptr_t InstanceSize(intptr_t len) { | 7249 static intptr_t InstanceSize(intptr_t len) { |
| 7239 ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString); | 7250 ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString); |
| 7240 ASSERT(0 <= len && len <= kMaxElements); | 7251 ASSERT(0 <= len && len <= kMaxElements); |
| 7252 // We have to pad zero-length raw strings so that they can be externalized. | |
| 7253 // If we don't pad, then the external string object does not fit in the | |
| 7254 // memory allocated for the raw string. | |
| 7255 if (len == 0) return InstanceSize(1); | |
| 7241 return String::RoundedAllocationSize(sizeof(RawTwoByteString) + | 7256 return String::RoundedAllocationSize(sizeof(RawTwoByteString) + |
| 7242 (len * kBytesPerElement)); | 7257 (len * kBytesPerElement)); |
| 7243 } | 7258 } |
| 7244 | 7259 |
| 7245 static RawTwoByteString* New(intptr_t len, Heap::Space space); | 7260 static RawTwoByteString* New(intptr_t len, Heap::Space space); |
| 7246 static RawTwoByteString* New(const uint16_t* characters, | 7261 static RawTwoByteString* New(const uint16_t* characters, |
| 7247 intptr_t len, | 7262 intptr_t len, |
| 7248 Heap::Space space); | 7263 Heap::Space space); |
| 7249 static RawTwoByteString* New(intptr_t utf16_len, | 7264 static RawTwoByteString* New(intptr_t utf16_len, |
| 7250 const int32_t* characters, | 7265 const int32_t* characters, |
| (...skipping 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8924 return false; // Two symbols that aren't identical aren't equal. | 8939 return false; // Two symbols that aren't identical aren't equal. |
| 8925 } | 8940 } |
| 8926 if (HasHash() && str.HasHash() && (Hash() != str.Hash())) { | 8941 if (HasHash() && str.HasHash() && (Hash() != str.Hash())) { |
| 8927 return false; // Both sides have hash codes and they do not match. | 8942 return false; // Both sides have hash codes and they do not match. |
| 8928 } | 8943 } |
| 8929 return Equals(str, 0, str.Length()); | 8944 return Equals(str, 0, str.Length()); |
| 8930 } | 8945 } |
| 8931 | 8946 |
| 8932 | 8947 |
| 8933 intptr_t Library::UrlHash() const { | 8948 intptr_t Library::UrlHash() const { |
| 8934 intptr_t result = Smi::Value(url()->ptr()->hash_); | 8949 intptr_t result = url()->GetRawHash(); |
| 8935 ASSERT(result != 0); | 8950 ASSERT(result != 0); |
| 8936 return result; | 8951 return result; |
| 8937 } | 8952 } |
| 8938 | 8953 |
| 8939 | 8954 |
| 8940 void MegamorphicCache::SetEntry(const Array& array, | 8955 void MegamorphicCache::SetEntry(const Array& array, |
| 8941 intptr_t index, | 8956 intptr_t index, |
| 8942 const Smi& class_id, | 8957 const Smi& class_id, |
| 8943 const Function& target) { | 8958 const Function& target) { |
| 8944 array.SetAt((index * kEntryLength) + kClassIdIndex, class_id); | 8959 array.SetAt((index * kEntryLength) + kClassIdIndex, class_id); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9018 | 9033 |
| 9019 inline void TypeArguments::SetHash(intptr_t value) const { | 9034 inline void TypeArguments::SetHash(intptr_t value) const { |
| 9020 // This is only safe because we create a new Smi, which does not cause | 9035 // This is only safe because we create a new Smi, which does not cause |
| 9021 // heap allocation. | 9036 // heap allocation. |
| 9022 StoreSmi(&raw_ptr()->hash_, Smi::New(value)); | 9037 StoreSmi(&raw_ptr()->hash_, Smi::New(value)); |
| 9023 } | 9038 } |
| 9024 | 9039 |
| 9025 } // namespace dart | 9040 } // namespace dart |
| 9026 | 9041 |
| 9027 #endif // RUNTIME_VM_OBJECT_H_ | 9042 #endif // RUNTIME_VM_OBJECT_H_ |
| OLD | NEW |