blob: 5f6f562161c8b132e72452aaa06a2e089b4f1c05 [file] [log] [blame]
Vladimir Markoeebb8212018-06-05 14:57:24 +01001/*
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"
Vladimir Marko024d69f2019-06-13 10:52:32 +010020#include "base/casts.h"
Vladimir Markoeebb8212018-06-05 14:57:24 +010021#include "base/logging.h"
Vladimir Marko024d69f2019-06-13 10:52:32 +010022#include "image.h"
Vladimir Markoeebb8212018-06-05 14:57:24 +010023#include "obj_ptr-inl.h"
Vladimir Markoeebb8212018-06-05 14:57:24 +010024
25namespace art {
26
Vladimir Marko024d69f2019-06-13 10:52:32 +010027static constexpr size_t kIntrinsicObjectsOffset =
28 enum_cast<size_t>(ImageHeader::kIntrinsicObjectsStart);
29
30ObjPtr<mirror::ObjectArray<mirror::Object>> IntrinsicObjects::LookupIntegerCache(
31 Thread* self, ClassLinker* class_linker) {
Vladimir Markoeebb8212018-06-05 14:57:24 +010032 ObjPtr<mirror::Class> integer_cache_class = class_linker->LookupClass(
Andreas Gampe3db70682018-12-26 15:12:03 -080033 self, "Ljava/lang/Integer$IntegerCache;", /* class_loader= */ nullptr);
Vladimir Markoeebb8212018-06-05 14:57:24 +010034 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
Vladimir Marko024d69f2019-06-13 10:52:32 +010047static bool HasIntrinsicObjects(
48 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects)
49 REQUIRES_SHARED(Locks::mutator_lock_) {
50 DCHECK(boot_image_live_objects != nullptr);
51 uint32_t length = static_cast<uint32_t>(boot_image_live_objects->GetLength());
52 DCHECK_GE(length, kIntrinsicObjectsOffset);
53 return length != kIntrinsicObjectsOffset;
Vladimir Markoeebb8212018-06-05 14:57:24 +010054}
55
56ObjPtr<mirror::ObjectArray<mirror::Object>> IntrinsicObjects::GetIntegerValueOfCache(
57 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects) {
Vladimir Marko024d69f2019-06-13 10:52:32 +010058 if (!HasIntrinsicObjects(boot_image_live_objects)) {
Vladimir Markoeebb8212018-06-05 14:57:24 +010059 return nullptr; // No intrinsic objects.
60 }
61 // No need for read barrier for boot image object or for verifying the value that was just stored.
62 ObjPtr<mirror::Object> result =
Vladimir Marko024d69f2019-06-13 10:52:32 +010063 boot_image_live_objects->GetWithoutChecks<kVerifyNone, kWithoutReadBarrier>(
64 kIntrinsicObjectsOffset);
Vladimir Markoeebb8212018-06-05 14:57:24 +010065 DCHECK(result != nullptr);
66 DCHECK(result->IsObjectArray());
67 DCHECK(result->GetClass()->DescriptorEquals("[Ljava/lang/Integer;"));
68 return ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(result);
69}
70
71ObjPtr<mirror::Object> IntrinsicObjects::GetIntegerValueOfObject(
72 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects,
73 uint32_t index) {
Vladimir Marko024d69f2019-06-13 10:52:32 +010074 DCHECK(HasIntrinsicObjects(boot_image_live_objects));
Vladimir Markoeebb8212018-06-05 14:57:24 +010075 DCHECK_LT(index,
76 static_cast<uint32_t>(GetIntegerValueOfCache(boot_image_live_objects)->GetLength()));
77
78 // No need for read barrier for boot image object or for verifying the value that was just stored.
79 ObjPtr<mirror::Object> result =
80 boot_image_live_objects->GetWithoutChecks<kVerifyNone, kWithoutReadBarrier>(
Vladimir Marko024d69f2019-06-13 10:52:32 +010081 kIntrinsicObjectsOffset + /* skip the IntegerCache.cache */ 1u + index);
Vladimir Markoeebb8212018-06-05 14:57:24 +010082 DCHECK(result != nullptr);
83 DCHECK(result->GetClass()->DescriptorEquals("Ljava/lang/Integer;"));
84 return result;
85}
86
87MemberOffset IntrinsicObjects::GetIntegerValueOfArrayDataOffset(
88 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects) {
Vladimir Marko024d69f2019-06-13 10:52:32 +010089 DCHECK(HasIntrinsicObjects(boot_image_live_objects));
90 MemberOffset result =
91 mirror::ObjectArray<mirror::Object>::OffsetOfElement(kIntrinsicObjectsOffset + 1u);
Vladimir Markoeebb8212018-06-05 14:57:24 +010092 DCHECK_EQ(GetIntegerValueOfObject(boot_image_live_objects, 0u),
93 (boot_image_live_objects
94 ->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(result)));
95 return result;
96}
97
98} // namespace art