Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 17 | #ifndef ART_RUNTIME_MIRROR_STRING_H_ |
| 18 | #define ART_RUNTIME_MIRROR_STRING_H_ |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 19 | |
Hiroshi Yamauchi | 94f7b49 | 2014-07-22 18:08:23 -0700 | [diff] [blame] | 20 | #include "gc_root.h" |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 21 | #include "gc/allocator_type.h" |
Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 22 | #include "object.h" |
Mathieu Chartier | 83c8ee0 | 2014-01-28 14:50:23 -0800 | [diff] [blame] | 23 | #include "object_callbacks.h" |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 24 | |
| 25 | namespace art { |
| 26 | |
Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 27 | template<class T> class Handle; |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 28 | struct StringOffsets; |
| 29 | class StringPiece; |
Roland Levillain | 0d5a281 | 2015-11-13 10:07:31 +0000 | [diff] [blame] | 30 | class StubTest_ReadBarrierForRoot_Test; |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 31 | |
| 32 | namespace mirror { |
| 33 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 34 | // String Compression |
| 35 | static constexpr bool kUseStringCompression = false; |
| 36 | |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 37 | // C++ mirror of java.lang.String |
Mingyao Yang | 98d1cc8 | 2014-05-15 17:02:16 -0700 | [diff] [blame] | 38 | class MANAGED String FINAL : public Object { |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 39 | public: |
Mingyao Yang | 98d1cc8 | 2014-05-15 17:02:16 -0700 | [diff] [blame] | 40 | // Size of java.lang.String.class. |
Andreas Gampe | 542451c | 2016-07-26 09:02:02 -0700 | [diff] [blame] | 41 | static uint32_t ClassSize(PointerSize pointer_size); |
Mingyao Yang | 98d1cc8 | 2014-05-15 17:02:16 -0700 | [diff] [blame] | 42 | |
| 43 | // Size of an instance of java.lang.String not including its value array. |
| 44 | static constexpr uint32_t InstanceSize() { |
| 45 | return sizeof(String); |
| 46 | } |
| 47 | |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 48 | static MemberOffset CountOffset() { |
| 49 | return OFFSET_OF_OBJECT_MEMBER(String, count_); |
| 50 | } |
| 51 | |
| 52 | static MemberOffset ValueOffset() { |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 53 | return OFFSET_OF_OBJECT_MEMBER(String, value_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 54 | } |
| 55 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 56 | uint16_t* GetValue() REQUIRES_SHARED(Locks::mutator_lock_) { |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 57 | return &value_[0]; |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 58 | } |
| 59 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 60 | uint8_t* GetValueCompressed() REQUIRES_SHARED(Locks::mutator_lock_) { |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 61 | return &value_compressed_[0]; |
| 62 | } |
| 63 | |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 64 | template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 65 | size_t SizeOf() REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 66 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 67 | // Taking out the first/uppermost bit because it is not part of actual length value |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 68 | template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 69 | int32_t GetLength() REQUIRES_SHARED(Locks::mutator_lock_) { |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 70 | return GetLengthFromCount(GetCount<kVerifyFlags>()); |
| 71 | } |
| 72 | |
| 73 | template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 74 | int32_t GetCount() REQUIRES_SHARED(Locks::mutator_lock_) { |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 75 | return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(String, count_)); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 76 | } |
| 77 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 78 | void SetCount(int32_t new_count) REQUIRES_SHARED(Locks::mutator_lock_) { |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 79 | // Count is invariant so use non-transactional mode. Also disable check as we may run inside |
| 80 | // a transaction. |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 81 | DCHECK_LE(0, (new_count & INT32_MAX)); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 82 | SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count); |
| 83 | } |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 84 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 85 | int32_t GetHashCode() REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 86 | |
Mathieu Chartier | cdfd39f | 2014-08-29 18:16:58 -0700 | [diff] [blame] | 87 | // Computes, stores, and returns the hash code. |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 88 | int32_t ComputeHashCode() REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 89 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 90 | int32_t GetUtfLength() REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 91 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 92 | uint16_t CharAt(int32_t index) REQUIRES_SHARED(Locks::mutator_lock_); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 93 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 94 | void SetCharAt(int32_t index, uint16_t c) REQUIRES_SHARED(Locks::mutator_lock_); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 95 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 96 | String* Intern() REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 97 | |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 98 | template <bool kIsInstrumented> |
| 99 | ALWAYS_INLINE static String* AllocFromByteArray(Thread* self, int32_t byte_length, |
| 100 | Handle<ByteArray> array, int32_t offset, |
| 101 | int32_t high_byte, |
| 102 | gc::AllocatorType allocator_type) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 103 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 104 | |
| 105 | template <bool kIsInstrumented> |
Igor Murashkin | c449e8b | 2015-06-10 15:56:42 -0700 | [diff] [blame] | 106 | ALWAYS_INLINE static String* AllocFromCharArray(Thread* self, int32_t count, |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 107 | Handle<CharArray> array, int32_t offset, |
| 108 | gc::AllocatorType allocator_type) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 109 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 110 | |
| 111 | template <bool kIsInstrumented> |
| 112 | ALWAYS_INLINE static String* AllocFromString(Thread* self, int32_t string_length, |
| 113 | Handle<String> string, int32_t offset, |
| 114 | gc::AllocatorType allocator_type) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 115 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 116 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 117 | template <bool kIsInstrumented> |
| 118 | ALWAYS_INLINE static String* AllocEmptyString(Thread* self, |
| 119 | gc::AllocatorType allocator_type) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 120 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 121 | |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 122 | static String* AllocFromStrings(Thread* self, Handle<String> string, Handle<String> string2) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 123 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 124 | |
| 125 | static String* AllocFromUtf16(Thread* self, int32_t utf16_length, const uint16_t* utf16_data_in) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 126 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 127 | |
| 128 | static String* AllocFromModifiedUtf8(Thread* self, const char* utf) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 129 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 130 | |
Bruce Hoult | 1646d7a | 2015-10-28 15:06:12 +0300 | [diff] [blame] | 131 | static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, |
| 132 | const char* utf8_data_in, int32_t utf8_length) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 133 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Bruce Hoult | 1646d7a | 2015-10-28 15:06:12 +0300 | [diff] [blame] | 134 | |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 135 | static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, const char* utf8_data_in) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 136 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 137 | |
Narayan Kamath | a5afcfc | 2015-01-29 20:06:46 +0000 | [diff] [blame] | 138 | // TODO: This is only used in the interpreter to compare against |
| 139 | // entries from a dex files constant pool (ArtField names). Should |
| 140 | // we unify this with Equals(const StringPiece&); ? |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 141 | bool Equals(const char* modified_utf8) REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 142 | |
Narayan Kamath | a5afcfc | 2015-01-29 20:06:46 +0000 | [diff] [blame] | 143 | // TODO: This is only used to compare DexCache.location with |
| 144 | // a dex_file's location (which is an std::string). Do we really |
| 145 | // need this in mirror::String just for that one usage ? |
Ian Rogers | ef7d42f | 2014-01-06 12:55:46 -0800 | [diff] [blame] | 146 | bool Equals(const StringPiece& modified_utf8) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 147 | REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 148 | |
Mathieu Chartier | 31e8822 | 2016-10-14 18:43:19 -0700 | [diff] [blame^] | 149 | bool Equals(ObjPtr<String> that) REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 150 | |
| 151 | // Compare UTF-16 code point values not in a locale-sensitive manner |
| 152 | int Compare(int32_t utf16_length, const char* utf8_data_in); |
| 153 | |
| 154 | // TODO: do we need this overload? give it a more intention-revealing name. |
| 155 | bool Equals(const uint16_t* that_chars, int32_t that_offset, |
Ian Rogers | ef7d42f | 2014-01-06 12:55:46 -0800 | [diff] [blame] | 156 | int32_t that_length) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 157 | REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 158 | |
| 159 | // Create a modified UTF-8 encoded std::string from a java/lang/String object. |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 160 | std::string ToModifiedUtf8() REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 161 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 162 | int32_t FastIndexOf(int32_t ch, int32_t start) REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 163 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 164 | template <typename MemoryType> |
| 165 | int32_t FastIndexOf(MemoryType* chars, int32_t ch, int32_t start) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 166 | REQUIRES_SHARED(Locks::mutator_lock_); |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 167 | |
Mathieu Chartier | 31e8822 | 2016-10-14 18:43:19 -0700 | [diff] [blame^] | 168 | int32_t CompareTo(ObjPtr<String> other) REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 169 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 170 | CharArray* ToCharArray(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) |
Mathieu Chartier | ed8990a | 2015-07-23 14:11:16 -0700 | [diff] [blame] | 171 | REQUIRES(!Roles::uninterruptible_); |
Mathieu Chartier | fd04b6f | 2014-11-14 19:34:18 -0800 | [diff] [blame] | 172 | |
Jeff Hao | 848f70a | 2014-01-15 13:49:50 -0800 | [diff] [blame] | 173 | void GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 174 | REQUIRES_SHARED(Locks::mutator_lock_); |
Mathieu Chartier | fd04b6f | 2014-11-14 19:34:18 -0800 | [diff] [blame] | 175 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 176 | template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 177 | bool IsCompressed() REQUIRES_SHARED(Locks::mutator_lock_) { |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 178 | return kUseStringCompression && GetCompressionFlagFromCount(GetCount()); |
| 179 | } |
| 180 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 181 | bool IsValueNull() REQUIRES_SHARED(Locks::mutator_lock_); |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 182 | |
| 183 | template<typename MemoryType> |
| 184 | static bool AllASCII(const MemoryType* const chars, const int length); |
| 185 | |
| 186 | ALWAYS_INLINE static bool GetCompressionFlagFromCount(const int32_t count) { |
| 187 | return kUseStringCompression && ((count & (1u << 31)) != 0); |
| 188 | } |
| 189 | |
| 190 | ALWAYS_INLINE static int32_t GetLengthFromCount(const int32_t count) { |
| 191 | return kUseStringCompression ? (count & INT32_MAX) : count; |
| 192 | } |
| 193 | |
| 194 | ALWAYS_INLINE static int32_t GetFlaggedCount(const int32_t count) { |
| 195 | return kUseStringCompression ? (count | (1u << 31)) : count; |
| 196 | } |
| 197 | |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 198 | static Class* GetJavaLangString() REQUIRES_SHARED(Locks::mutator_lock_) { |
Hiroshi Yamauchi | 94f7b49 | 2014-07-22 18:08:23 -0700 | [diff] [blame] | 199 | DCHECK(!java_lang_String_.IsNull()); |
| 200 | return java_lang_String_.Read(); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 201 | } |
| 202 | |
Mathieu Chartier | 31e8822 | 2016-10-14 18:43:19 -0700 | [diff] [blame^] | 203 | static void SetClass(ObjPtr<Class> java_lang_String) REQUIRES_SHARED(Locks::mutator_lock_); |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 204 | static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_); |
| 205 | static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 206 | |
| 207 | private: |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 208 | void SetHashCode(int32_t new_hash_code) REQUIRES_SHARED(Locks::mutator_lock_) { |
Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 209 | // Hash code is invariant so use non-transactional mode. Also disable check as we may run inside |
| 210 | // a transaction. |
Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 211 | DCHECK_EQ(0, GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_))); |
| 212 | SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), new_hash_code); |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 213 | } |
| 214 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 215 | template <bool kIsInstrumented, typename PreFenceVisitor> |
| 216 | ALWAYS_INLINE static String* Alloc(Thread* self, int32_t utf16_length_with_flag, |
| 217 | gc::AllocatorType allocator_type, |
| 218 | const PreFenceVisitor& pre_fence_visitor) |
Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 219 | REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 220 | |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 221 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 222 | // First bit (uppermost/leftmost) is taken out for Compressed/Uncompressed flag |
| 223 | // [0] Uncompressed: string uses 16-bit memory | [1] Compressed: 8-bit memory |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 224 | int32_t count_; |
| 225 | |
| 226 | uint32_t hash_code_; |
| 227 | |
jessicahandojo | 3aaa37b | 2016-07-29 14:46:37 -0700 | [diff] [blame] | 228 | // Compression of all-ASCII into 8-bit memory leads to usage one of these fields |
| 229 | union { |
| 230 | uint16_t value_[0]; |
| 231 | uint8_t value_compressed_[0]; |
| 232 | }; |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 233 | |
Hiroshi Yamauchi | 94f7b49 | 2014-07-22 18:08:23 -0700 | [diff] [blame] | 234 | static GcRoot<Class> java_lang_String_; |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 235 | |
| 236 | friend struct art::StringOffsets; // for verifying offset information |
Roland Levillain | 0d5a281 | 2015-11-13 10:07:31 +0000 | [diff] [blame] | 237 | ART_FRIEND_TEST(art::StubTest, ReadBarrierForRoot); // For java_lang_String_. |
Ian Rogers | 6f3dbba | 2014-10-14 17:41:57 -0700 | [diff] [blame] | 238 | |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 239 | DISALLOW_IMPLICIT_CONSTRUCTORS(String); |
| 240 | }; |
| 241 | |
Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 242 | } // namespace mirror |
| 243 | } // namespace art |
| 244 | |
Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 245 | #endif // ART_RUNTIME_MIRROR_STRING_H_ |