1 /* 2 * Copyright (C) 2018 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 #include "intrinsic_objects.h" 18 19 #include "art_field-inl.h" 20 #include "base/logging.h" 21 #include "class_root.h" 22 #include "handle.h" 23 #include "obj_ptr-inl.h" 24 #include "mirror/object_array-alloc-inl.h" 25 #include "mirror/object_array-inl.h" 26 27 namespace art { 28 29 static ObjPtr<mirror::ObjectArray<mirror::Object>> LookupIntegerCache(Thread* self, 30 ClassLinker* class_linker) 31 REQUIRES_SHARED(Locks::mutator_lock_) { 32 ObjPtr<mirror::Class> integer_cache_class = class_linker->LookupClass( 33 self, "Ljava/lang/Integer$IntegerCache;", /* class_loader= */ nullptr); 34 if (integer_cache_class == nullptr || !integer_cache_class->IsInitialized()) { 35 return nullptr; 36 } 37 ArtField* cache_field = 38 integer_cache_class->FindDeclaredStaticField("cache", "[Ljava/lang/Integer;"); 39 CHECK(cache_field != nullptr); 40 ObjPtr<mirror::ObjectArray<mirror::Object>> integer_cache = 41 ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast( 42 cache_field->GetObject(integer_cache_class)); 43 CHECK(integer_cache != nullptr); 44 return integer_cache; 45 } 46 47 ObjPtr<mirror::ObjectArray<mirror::Object>> IntrinsicObjects::AllocateBootImageLiveObjects( 48 Thread* self, 49 ClassLinker* class_linker) REQUIRES_SHARED(Locks::mutator_lock_) { 50 // The objects used for the Integer.valueOf() intrinsic must remain live even if references 51 // to them are removed using reflection. Image roots are not accessible through reflection, 52 // so the array we construct here shall keep them alive. 53 StackHandleScope<1> hs(self); 54 Handle<mirror::ObjectArray<mirror::Object>> integer_cache = 55 hs.NewHandle(LookupIntegerCache(self, class_linker)); 56 size_t live_objects_size = 57 (integer_cache != nullptr) ? (/* cache */ 1u + integer_cache->GetLength()) : 0u; 58 ObjPtr<mirror::ObjectArray<mirror::Object>> live_objects = 59 mirror::ObjectArray<mirror::Object>::Alloc( 60 self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker), live_objects_size); 61 int32_t index = 0; 62 if (integer_cache != nullptr) { 63 live_objects->Set(index++, integer_cache.Get()); 64 for (int32_t i = 0, length = integer_cache->GetLength(); i != length; ++i) { 65 live_objects->Set(index++, integer_cache->Get(i)); 66 } 67 } 68 CHECK_EQ(index, live_objects->GetLength()); 69 70 if (kIsDebugBuild && integer_cache != nullptr) { 71 CHECK_EQ(integer_cache.Get(), GetIntegerValueOfCache(live_objects)); 72 for (int32_t i = 0, len = integer_cache->GetLength(); i != len; ++i) { 73 CHECK_EQ(integer_cache->GetWithoutChecks(i), GetIntegerValueOfObject(live_objects, i)); 74 } 75 } 76 return live_objects; 77 } 78 79 ObjPtr<mirror::ObjectArray<mirror::Object>> IntrinsicObjects::GetIntegerValueOfCache( 80 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects) { 81 DCHECK(boot_image_live_objects != nullptr); 82 if (boot_image_live_objects->GetLength() == 0u) { 83 return nullptr; // No intrinsic objects. 84 } 85 // No need for read barrier for boot image object or for verifying the value that was just stored. 86 ObjPtr<mirror::Object> result = 87 boot_image_live_objects->GetWithoutChecks<kVerifyNone, kWithoutReadBarrier>(0); 88 DCHECK(result != nullptr); 89 DCHECK(result->IsObjectArray()); 90 DCHECK(result->GetClass()->DescriptorEquals("[Ljava/lang/Integer;")); 91 return ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(result); 92 } 93 94 ObjPtr<mirror::Object> IntrinsicObjects::GetIntegerValueOfObject( 95 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, 96 uint32_t index) { 97 DCHECK(boot_image_live_objects != nullptr); 98 DCHECK_NE(boot_image_live_objects->GetLength(), 0); 99 DCHECK_LT(index, 100 static_cast<uint32_t>(GetIntegerValueOfCache(boot_image_live_objects)->GetLength())); 101 102 // No need for read barrier for boot image object or for verifying the value that was just stored. 103 ObjPtr<mirror::Object> result = 104 boot_image_live_objects->GetWithoutChecks<kVerifyNone, kWithoutReadBarrier>( 105 /* skip the IntegerCache.cache */ 1u + index); 106 DCHECK(result != nullptr); 107 DCHECK(result->GetClass()->DescriptorEquals("Ljava/lang/Integer;")); 108 return result; 109 } 110 111 MemberOffset IntrinsicObjects::GetIntegerValueOfArrayDataOffset( 112 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects) { 113 DCHECK_NE(boot_image_live_objects->GetLength(), 0); 114 MemberOffset result = mirror::ObjectArray<mirror::Object>::OffsetOfElement(1u); 115 DCHECK_EQ(GetIntegerValueOfObject(boot_image_live_objects, 0u), 116 (boot_image_live_objects 117 ->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(result))); 118 return result; 119 } 120 121 } // namespace art 122