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 17 #ifndef ART_RUNTIME_MIRROR_STRING_H_ 18 #define ART_RUNTIME_MIRROR_STRING_H_ 19 20 #include "gc_root.h" 21 #include "gc/allocator_type.h" 22 #include "object.h" 23 #include "object_callbacks.h" 24 25 namespace art { 26 27 template<class T> class Handle; 28 struct StringOffsets; 29 class StringPiece; 30 class StubTest_ReadBarrierForRoot_Test; 31 32 namespace mirror { 33 34 // C++ mirror of java.lang.String 35 class MANAGED String FINAL : public Object { 36 public: 37 // Size of java.lang.String.class. 38 static uint32_t ClassSize(size_t pointer_size); 39 40 // Size of an instance of java.lang.String not including its value array. InstanceSize()41 static constexpr uint32_t InstanceSize() { 42 return sizeof(String); 43 } 44 CountOffset()45 static MemberOffset CountOffset() { 46 return OFFSET_OF_OBJECT_MEMBER(String, count_); 47 } 48 ValueOffset()49 static MemberOffset ValueOffset() { 50 return OFFSET_OF_OBJECT_MEMBER(String, value_); 51 } 52 GetValue()53 uint16_t* GetValue() SHARED_REQUIRES(Locks::mutator_lock_) { 54 return &value_[0]; 55 } 56 57 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 58 size_t SizeOf() SHARED_REQUIRES(Locks::mutator_lock_); 59 60 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> GetLength()61 int32_t GetLength() SHARED_REQUIRES(Locks::mutator_lock_) { 62 return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(String, count_)); 63 } 64 SetCount(int32_t new_count)65 void SetCount(int32_t new_count) SHARED_REQUIRES(Locks::mutator_lock_) { 66 // Count is invariant so use non-transactional mode. Also disable check as we may run inside 67 // a transaction. 68 DCHECK_LE(0, new_count); 69 SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count); 70 } 71 72 int32_t GetHashCode() SHARED_REQUIRES(Locks::mutator_lock_); 73 74 // Computes, stores, and returns the hash code. 75 int32_t ComputeHashCode() SHARED_REQUIRES(Locks::mutator_lock_); 76 77 int32_t GetUtfLength() SHARED_REQUIRES(Locks::mutator_lock_); 78 79 uint16_t CharAt(int32_t index) SHARED_REQUIRES(Locks::mutator_lock_); 80 81 void SetCharAt(int32_t index, uint16_t c) SHARED_REQUIRES(Locks::mutator_lock_); 82 83 String* Intern() SHARED_REQUIRES(Locks::mutator_lock_); 84 85 template <bool kIsInstrumented, typename PreFenceVisitor> 86 ALWAYS_INLINE static String* Alloc(Thread* self, int32_t utf16_length, 87 gc::AllocatorType allocator_type, 88 const PreFenceVisitor& pre_fence_visitor) 89 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 90 91 template <bool kIsInstrumented> 92 ALWAYS_INLINE static String* AllocFromByteArray(Thread* self, int32_t byte_length, 93 Handle<ByteArray> array, int32_t offset, 94 int32_t high_byte, 95 gc::AllocatorType allocator_type) 96 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 97 98 template <bool kIsInstrumented> 99 ALWAYS_INLINE static String* AllocFromCharArray(Thread* self, int32_t count, 100 Handle<CharArray> array, int32_t offset, 101 gc::AllocatorType allocator_type) 102 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 103 104 template <bool kIsInstrumented> 105 ALWAYS_INLINE static String* AllocFromString(Thread* self, int32_t string_length, 106 Handle<String> string, int32_t offset, 107 gc::AllocatorType allocator_type) 108 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 109 110 static String* AllocFromStrings(Thread* self, Handle<String> string, Handle<String> string2) 111 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 112 113 static String* AllocFromUtf16(Thread* self, int32_t utf16_length, const uint16_t* utf16_data_in) 114 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 115 116 static String* AllocFromModifiedUtf8(Thread* self, const char* utf) 117 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 118 119 static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, 120 const char* utf8_data_in, int32_t utf8_length) 121 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 122 123 static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, const char* utf8_data_in) 124 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 125 126 // TODO: This is only used in the interpreter to compare against 127 // entries from a dex files constant pool (ArtField names). Should 128 // we unify this with Equals(const StringPiece&); ? 129 bool Equals(const char* modified_utf8) SHARED_REQUIRES(Locks::mutator_lock_); 130 131 // TODO: This is only used to compare DexCache.location with 132 // a dex_file's location (which is an std::string). Do we really 133 // need this in mirror::String just for that one usage ? 134 bool Equals(const StringPiece& modified_utf8) 135 SHARED_REQUIRES(Locks::mutator_lock_); 136 137 bool Equals(String* that) SHARED_REQUIRES(Locks::mutator_lock_); 138 139 // Compare UTF-16 code point values not in a locale-sensitive manner 140 int Compare(int32_t utf16_length, const char* utf8_data_in); 141 142 // TODO: do we need this overload? give it a more intention-revealing name. 143 bool Equals(const uint16_t* that_chars, int32_t that_offset, 144 int32_t that_length) 145 SHARED_REQUIRES(Locks::mutator_lock_); 146 147 // Create a modified UTF-8 encoded std::string from a java/lang/String object. 148 std::string ToModifiedUtf8() SHARED_REQUIRES(Locks::mutator_lock_); 149 150 int32_t FastIndexOf(int32_t ch, int32_t start) SHARED_REQUIRES(Locks::mutator_lock_); 151 152 int32_t CompareTo(String* other) SHARED_REQUIRES(Locks::mutator_lock_); 153 154 CharArray* ToCharArray(Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) 155 REQUIRES(!Roles::uninterruptible_); 156 157 void GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index) 158 SHARED_REQUIRES(Locks::mutator_lock_); 159 GetJavaLangString()160 static Class* GetJavaLangString() SHARED_REQUIRES(Locks::mutator_lock_) { 161 DCHECK(!java_lang_String_.IsNull()); 162 return java_lang_String_.Read(); 163 } 164 165 static void SetClass(Class* java_lang_String) SHARED_REQUIRES(Locks::mutator_lock_); 166 static void ResetClass() SHARED_REQUIRES(Locks::mutator_lock_); 167 static void VisitRoots(RootVisitor* visitor) SHARED_REQUIRES(Locks::mutator_lock_); 168 169 private: SetHashCode(int32_t new_hash_code)170 void SetHashCode(int32_t new_hash_code) SHARED_REQUIRES(Locks::mutator_lock_) { 171 // Hash code is invariant so use non-transactional mode. Also disable check as we may run inside 172 // a transaction. 173 DCHECK_EQ(0, GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_))); 174 SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), new_hash_code); 175 } 176 177 // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 178 int32_t count_; 179 180 uint32_t hash_code_; 181 182 uint16_t value_[0]; 183 184 static GcRoot<Class> java_lang_String_; 185 186 friend struct art::StringOffsets; // for verifying offset information 187 ART_FRIEND_TEST(art::StubTest, ReadBarrierForRoot); // For java_lang_String_. 188 189 DISALLOW_IMPLICIT_CONSTRUCTORS(String); 190 }; 191 192 } // namespace mirror 193 } // namespace art 194 195 #endif // ART_RUNTIME_MIRROR_STRING_H_ 196