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_INL_H_ 18 #define ART_RUNTIME_MIRROR_STRING_INL_H_ 19 20 #include "array.h" 21 #include "class.h" 22 #include "intern_table.h" 23 #include "runtime.h" 24 #include "string.h" 25 #include "thread.h" 26 #include "utf.h" 27 28 namespace art { 29 namespace mirror { 30 31 inline uint32_t String::ClassSize() { 32 uint32_t vtable_entries = Object::kVTableLength + 51; 33 return Class::ComputeClassSize(true, vtable_entries, 1, 1, 2); 34 } 35 36 inline CharArray* String::GetCharArray() { 37 return GetFieldObject<CharArray>(ValueOffset()); 38 } 39 40 inline int32_t String::GetLength() { 41 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_)); 42 DCHECK(result >= 0 && result <= GetCharArray()->GetLength()); 43 return result; 44 } 45 46 inline void String::SetArray(CharArray* new_array) { 47 // Array is invariant so use non-transactional mode. Also disable check as we may run inside 48 // a transaction. 49 DCHECK(new_array != NULL); 50 SetFieldObject<false, false>(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array); 51 } 52 53 inline String* String::Intern() { 54 return Runtime::Current()->GetInternTable()->InternWeak(this); 55 } 56 57 inline uint16_t String::CharAt(int32_t index) { 58 // TODO: do we need this? Equals is the only caller, and could 59 // bounds check itself. 60 DCHECK_GE(count_, 0); // ensures the unsigned comparison is safe. 61 if (UNLIKELY(static_cast<uint32_t>(index) >= static_cast<uint32_t>(count_))) { 62 Thread* self = Thread::Current(); 63 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 64 self->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;", 65 "length=%i; index=%i", count_, index); 66 return 0; 67 } 68 return GetCharArray()->Get(index + GetOffset()); 69 } 70 71 inline int32_t String::GetHashCode() { 72 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_)); 73 if (UNLIKELY(result == 0)) { 74 result = ComputeHashCode(); 75 } 76 DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0) 77 << ToModifiedUtf8() << " " << result; 78 return result; 79 } 80 81 } // namespace mirror 82 } // namespace art 83 84 #endif // ART_RUNTIME_MIRROR_STRING_INL_H_ 85