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