12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/* 22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project 32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License. 62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at 72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software 112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and 142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License. 152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */ 162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_STRING_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_STRING_H_ 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h" 21848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "gc/allocator_type.h" 22e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "object.h" 2383c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier#include "object_callbacks.h" 242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 27eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiertemplate<class T> class Handle; 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstruct StringOffsets; 292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass StringPiece; 300d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillainclass StubTest_ReadBarrierForRoot_Test; 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// C++ mirror of java.lang.String 3598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yangclass MANAGED String FINAL : public Object { 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public: 3798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Size of java.lang.String.class. 38e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static uint32_t ClassSize(size_t pointer_size); 3998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 4098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Size of an instance of java.lang.String not including its value array. 4198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang static constexpr uint32_t InstanceSize() { 4298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang return sizeof(String); 4398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang } 4498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static MemberOffset CountOffset() { 462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return OFFSET_OF_OBJECT_MEMBER(String, count_); 472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static MemberOffset ValueOffset() { 50848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return OFFSET_OF_OBJECT_MEMBER(String, value_); 512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 5390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint16_t* GetValue() SHARED_REQUIRES(Locks::mutator_lock_) { 54848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return &value_[0]; 552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 57848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 5890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t SizeOf() SHARED_REQUIRES(Locks::mutator_lock_); 592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 60848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 6190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier int32_t GetLength() SHARED_REQUIRES(Locks::mutator_lock_) { 62848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(String, count_)); 632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 6590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void SetCount(int32_t new_count) SHARED_REQUIRES(Locks::mutator_lock_) { 66848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Count is invariant so use non-transactional mode. Also disable check as we may run inside 67848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // a transaction. 68848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao DCHECK_LE(0, new_count); 69848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count); 70848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier int32_t GetHashCode() SHARED_REQUIRES(Locks::mutator_lock_); 732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 74cdfd39f579574a75b98e7ad48c69826b00361b27Mathieu Chartier // Computes, stores, and returns the hash code. 7590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier int32_t ComputeHashCode() SHARED_REQUIRES(Locks::mutator_lock_); 762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier int32_t GetUtfLength() SHARED_REQUIRES(Locks::mutator_lock_); 782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint16_t CharAt(int32_t index) SHARED_REQUIRES(Locks::mutator_lock_); 80848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 8190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void SetCharAt(int32_t index, uint16_t c) SHARED_REQUIRES(Locks::mutator_lock_); 82848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 8390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier String* Intern() SHARED_REQUIRES(Locks::mutator_lock_); 842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 85848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template <bool kIsInstrumented, typename PreFenceVisitor> 86848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ALWAYS_INLINE static String* Alloc(Thread* self, int32_t utf16_length, 87848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao gc::AllocatorType allocator_type, 88848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao const PreFenceVisitor& pre_fence_visitor) 89ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 90848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 91848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template <bool kIsInstrumented> 92848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ALWAYS_INLINE static String* AllocFromByteArray(Thread* self, int32_t byte_length, 93848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Handle<ByteArray> array, int32_t offset, 94848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao int32_t high_byte, 95848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao gc::AllocatorType allocator_type) 96ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 97848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 98848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template <bool kIsInstrumented> 99c449e8b79aaaf156ce055524c41474cc1200ed5aIgor Murashkin ALWAYS_INLINE static String* AllocFromCharArray(Thread* self, int32_t count, 100848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Handle<CharArray> array, int32_t offset, 101848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao gc::AllocatorType allocator_type) 102ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 103848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 104848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template <bool kIsInstrumented> 105848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ALWAYS_INLINE static String* AllocFromString(Thread* self, int32_t string_length, 106848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Handle<String> string, int32_t offset, 107848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao gc::AllocatorType allocator_type) 108ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 109848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 110848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao static String* AllocFromStrings(Thread* self, Handle<String> string, Handle<String> string2) 111ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 112848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 113848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao static String* AllocFromUtf16(Thread* self, int32_t utf16_length, const uint16_t* utf16_data_in) 114ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 1152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static String* AllocFromModifiedUtf8(Thread* self, const char* utf) 117ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 1182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1191646d7a22e43a1fb25452ead47a4073e63d7f391Bruce Hoult static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, 1201646d7a22e43a1fb25452ead47a4073e63d7f391Bruce Hoult const char* utf8_data_in, int32_t utf8_length) 1211646d7a22e43a1fb25452ead47a4073e63d7f391Bruce Hoult SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 1221646d7a22e43a1fb25452ead47a4073e63d7f391Bruce Hoult 123848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, const char* utf8_data_in) 124ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 1252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 126a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath // TODO: This is only used in the interpreter to compare against 127a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath // entries from a dex files constant pool (ArtField names). Should 128a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath // we unify this with Equals(const StringPiece&); ? 12990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier bool Equals(const char* modified_utf8) SHARED_REQUIRES(Locks::mutator_lock_); 1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 131a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath // TODO: This is only used to compare DexCache.location with 132a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath // a dex_file's location (which is an std::string). Do we really 133a5afcfc73141e5e378d79a326d02c5c2039fb025Narayan Kamath // need this in mirror::String just for that one usage ? 134ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers bool Equals(const StringPiece& modified_utf8) 13590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 1362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 13790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier bool Equals(String* that) SHARED_REQUIRES(Locks::mutator_lock_); 1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Compare UTF-16 code point values not in a locale-sensitive manner 1402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int Compare(int32_t utf16_length, const char* utf8_data_in); 1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // TODO: do we need this overload? give it a more intention-revealing name. 1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool Equals(const uint16_t* that_chars, int32_t that_offset, 144ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers int32_t that_length) 14590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 1462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Create a modified UTF-8 encoded std::string from a java/lang/String object. 14890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier std::string ToModifiedUtf8() SHARED_REQUIRES(Locks::mutator_lock_); 1492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 15090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier int32_t FastIndexOf(int32_t ch, int32_t start) SHARED_REQUIRES(Locks::mutator_lock_); 1512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 15290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier int32_t CompareTo(String* other) SHARED_REQUIRES(Locks::mutator_lock_); 1532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 154ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier CharArray* ToCharArray(Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) 155ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier REQUIRES(!Roles::uninterruptible_); 156fd04b6f89238af5da682805aa11899639fb4ee07Mathieu Chartier 157848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao void GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index) 15890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 159fd04b6f89238af5da682805aa11899639fb4ee07Mathieu Chartier 16090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static Class* GetJavaLangString() SHARED_REQUIRES(Locks::mutator_lock_) { 16194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi DCHECK(!java_lang_String_.IsNull()); 16294f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi return java_lang_String_.Read(); 1632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 16552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier static void SetClass(Class* java_lang_String) SHARED_REQUIRES(Locks::mutator_lock_); 16652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier static void ResetClass() SHARED_REQUIRES(Locks::mutator_lock_); 16752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier static void VisitRoots(RootVisitor* visitor) SHARED_REQUIRES(Locks::mutator_lock_); 1682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private: 17090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void SetHashCode(int32_t new_hash_code) SHARED_REQUIRES(Locks::mutator_lock_) { 171d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Hash code is invariant so use non-transactional mode. Also disable check as we may run inside 172d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // a transaction. 173b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers DCHECK_EQ(0, GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_))); 174b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), new_hash_code); 1752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int32_t count_; 1792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t hash_code_; 1812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 182848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao uint16_t value_[0]; 1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 18494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi static GcRoot<Class> java_lang_String_; 1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers friend struct art::StringOffsets; // for verifying offset information 1870d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain ART_FRIEND_TEST(art::StubTest, ReadBarrierForRoot); // For java_lang_String_. 1886f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers 1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DISALLOW_IMPLICIT_CONSTRUCTORS(String); 1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}; 1912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 1932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 1942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 195fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_STRING_H_ 196