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 <gtest/gtest.h>
21 
22 #include "gc_root.h"
23 #include "object.h"
24 #include "object_callbacks.h"
25 
26 namespace art {
27 
28 template<class T> class Handle;
29 struct StringOffsets;
30 class StringPiece;
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();
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, array_);
51   }
52 
OffsetOffset()53   static MemberOffset OffsetOffset() {
54     return OFFSET_OF_OBJECT_MEMBER(String, offset_);
55   }
56 
57   CharArray* GetCharArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
58 
GetOffset()59   int32_t GetOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
60     int32_t result = GetField32(OffsetOffset());
61     DCHECK_LE(0, result);
62     return result;
63   }
64 
65   int32_t GetLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
66 
67   int32_t GetHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
68 
69   // Computes, stores, and returns the hash code.
70   int32_t ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
71 
72   int32_t GetUtfLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
73 
74   uint16_t CharAt(int32_t index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
75 
76   String* Intern() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
77 
78   static String* AllocFromUtf16(Thread* self,
79                                 int32_t utf16_length,
80                                 const uint16_t* utf16_data_in,
81                                 int32_t hash_code = 0)
82       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
83 
84   static String* AllocFromModifiedUtf8(Thread* self, const char* utf)
85       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
86 
87   static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
88                                        const char* utf8_data_in)
89       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
90 
91   bool Equals(const char* modified_utf8) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
92 
93   // TODO: do we need this overload? give it a more intention-revealing name.
94   bool Equals(const StringPiece& modified_utf8)
95       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
96 
97   bool Equals(String* that) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
98 
99   // Compare UTF-16 code point values not in a locale-sensitive manner
100   int Compare(int32_t utf16_length, const char* utf8_data_in);
101 
102   // TODO: do we need this overload? give it a more intention-revealing name.
103   bool Equals(const uint16_t* that_chars, int32_t that_offset,
104               int32_t that_length)
105       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
106 
107   // Create a modified UTF-8 encoded std::string from a java/lang/String object.
108   std::string ToModifiedUtf8() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
109 
110   int32_t FastIndexOf(int32_t ch, int32_t start) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
111 
112   int32_t CompareTo(String* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
113 
SetOffset(int32_t new_offset)114   void SetOffset(int32_t new_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
115     // Offset is only used during testing so use non-transactional mode.
116     DCHECK_LE(0, new_offset);
117     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(String, offset_), new_offset);
118   }
119 
120   void SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
121 
GetJavaLangString()122   static Class* GetJavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
123     DCHECK(!java_lang_String_.IsNull());
124     return java_lang_String_.Read();
125   }
126 
127   static void SetClass(Class* java_lang_String);
128   static void ResetClass();
129   static void VisitRoots(RootCallback* callback, void* arg)
130       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
131 
132  private:
SetHashCode(int32_t new_hash_code)133   void SetHashCode(int32_t new_hash_code) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
134     // Hash code is invariant so use non-transactional mode. Also disable check as we may run inside
135     // a transaction.
136     DCHECK_EQ(0, GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_)));
137     SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), new_hash_code);
138   }
139 
SetCount(int32_t new_count)140   void SetCount(int32_t new_count) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
141     // Count is invariant so use non-transactional mode. Also disable check as we may run inside
142     // a transaction.
143     DCHECK_LE(0, new_count);
144     SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count);
145   }
146 
147   static String* Alloc(Thread* self, int32_t utf16_length)
148       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
149 
150   static String* Alloc(Thread* self, Handle<CharArray> array)
151       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
152 
153   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
154   HeapReference<CharArray> array_;
155 
156   int32_t count_;
157 
158   uint32_t hash_code_;
159 
160   int32_t offset_;
161 
162   static GcRoot<Class> java_lang_String_;
163 
164   friend struct art::StringOffsets;  // for verifying offset information
165 
166   FRIEND_TEST(ObjectTest, StringLength);  // for SetOffset and SetCount
167   DISALLOW_IMPLICIT_CONSTRUCTORS(String);
168 };
169 
170 }  // namespace mirror
171 }  // namespace art
172 
173 #endif  // ART_RUNTIME_MIRROR_STRING_H_
174