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