Home | History | Annotate | Download | only in mirror
      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.
     41   static constexpr uint32_t InstanceSize() {
     42     return sizeof(String);
     43   }
     44 
     45   static MemberOffset CountOffset() {
     46     return OFFSET_OF_OBJECT_MEMBER(String, count_);
     47   }
     48 
     49   static MemberOffset ValueOffset() {
     50     return OFFSET_OF_OBJECT_MEMBER(String, array_);
     51   }
     52 
     53   static MemberOffset OffsetOffset() {
     54     return OFFSET_OF_OBJECT_MEMBER(String, offset_);
     55   }
     56 
     57   CharArray* GetCharArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     58 
     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 
    114   static Class* GetJavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    115     DCHECK(!java_lang_String_.IsNull());
    116     return java_lang_String_.Read();
    117   }
    118 
    119   static void SetClass(Class* java_lang_String);
    120   static void ResetClass();
    121   static void VisitRoots(RootCallback* callback, void* arg)
    122       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    123 
    124  private:
    125   void SetHashCode(int32_t new_hash_code) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    126     // Hash code is invariant so use non-transactional mode. Also disable check as we may run inside
    127     // a transaction.
    128     DCHECK_EQ(0, GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_)));
    129     SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), new_hash_code);
    130   }
    131 
    132   void SetCount(int32_t new_count) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    133     // Count is invariant so use non-transactional mode. Also disable check as we may run inside
    134     // a transaction.
    135     DCHECK_LE(0, new_count);
    136     SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count);
    137   }
    138 
    139   void SetOffset(int32_t new_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    140     // Offset is only used during testing so use non-transactional mode.
    141     DCHECK_LE(0, new_offset);
    142     DCHECK_GE(GetLength(), new_offset);
    143     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(String, offset_), new_offset);
    144   }
    145 
    146   static String* Alloc(Thread* self, int32_t utf16_length)
    147       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    148 
    149   static String* Alloc(Thread* self, Handle<CharArray> array)
    150       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    151 
    152   void SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    153 
    154   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
    155   HeapReference<CharArray> array_;
    156 
    157   int32_t count_;
    158 
    159   uint32_t hash_code_;
    160 
    161   int32_t offset_;
    162 
    163   static GcRoot<Class> java_lang_String_;
    164 
    165   friend struct art::StringOffsets;  // for verifying offset information
    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