blob: 47c6b514d5915dfb553c02760bbe3eca5e4f5be4 [file] [log] [blame]
Ian Rogers57b86d42012-03-27 16:05:41 -07001/*
2 * Copyright (C) 2012 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
Mathieu Chartiere401d142015-04-22 13:56:20 -070017#include "art_method-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070018#include "callee_save_frame.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070019#include "entrypoints/entrypoint_utils-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080020#include "class_linker-inl.h"
Vladimir Markoaad75c62016-10-03 08:46:48 +000021#include "class_table-inl.h"
Ian Rogersfa46d3e2013-05-15 00:16:04 -070022#include "dex_file-inl.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080023#include "dex_file_types.h"
Vladimir Markoaad75c62016-10-03 08:46:48 +000024#include "gc/heap.h"
25#include "mirror/class-inl.h"
26#include "mirror/class_loader.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027#include "mirror/object_array-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070028#include "mirror/object-inl.h"
Vladimir Markoaad75c62016-10-03 08:46:48 +000029#include "oat_file.h"
30#include "runtime.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070031
32namespace art {
33
Vladimir Marko6bec91c2017-01-09 15:03:12 +000034static inline void BssWriteBarrier(ArtMethod* outer_method) REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko9b03cb42017-02-16 16:37:03 +000035 // For non-CC AOT code, we need a write barrier for the class loader that holds the
36 // GC roots in the .bss. For CC, we do not need to do anything because the roots
37 // we're storing are all referencing to-space and do not need to be re-visited.
38 // However, we do the DCHECK() for the registration of oat files with .bss sections.
39 const DexFile* dex_file =
40 (kUseReadBarrier && !kIsDebugBuild) ? nullptr : outer_method->GetDexFile();
Vladimir Marko6bec91c2017-01-09 15:03:12 +000041 if (dex_file != nullptr &&
42 dex_file->GetOatDexFile() != nullptr &&
43 !dex_file->GetOatDexFile()->GetOatFile()->GetBssGcRoots().empty()) {
Vladimir Marko9b03cb42017-02-16 16:37:03 +000044 ObjPtr<mirror::ClassLoader> class_loader = outer_method->GetClassLoader();
45 if (kIsDebugBuild) {
46 ClassTable* class_table =
47 Runtime::Current()->GetClassLinker()->ClassTableForClassLoader(class_loader);
48 CHECK(class_table != nullptr &&
49 !class_table->InsertOatFile(dex_file->GetOatDexFile()->GetOatFile()))
Vladimir Marko1998cd02017-01-13 13:02:58 +000050 << "Oat file with .bss GC roots was not registered in class table: "
51 << dex_file->GetOatDexFile()->GetOatFile()->GetLocation();
Vladimir Marko9b03cb42017-02-16 16:37:03 +000052 }
53 if (!kUseReadBarrier) {
54 if (class_loader != nullptr) {
55 // Note that we emit the barrier before the compiled code stores the String or Class
56 // as a GC root. This is OK as there is no suspend point point in between.
57 Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader);
58 } else {
59 Runtime::Current()->GetClassLinker()->WriteBarrierForBootOatFileBssRoots(
60 dex_file->GetOatDexFile()->GetOatFile());
61 }
Vladimir Marko1998cd02017-01-13 13:02:58 +000062 }
Vladimir Marko6bec91c2017-01-09 15:03:12 +000063 }
64}
65
Vladimir Markoea4c1262017-02-06 19:59:33 +000066constexpr Runtime::CalleeSaveType kInitEntrypointSaveType =
67 // TODO: Change allocation entrypoints on MIPS and MIPS64 to kSaveEverything.
68 (kRuntimeISA == kMips || kRuntimeISA == kMips64) ? Runtime::kSaveRefsOnly
69 : Runtime::kSaveEverything;
70
Nicolas Geoffray7ea6a172015-05-19 18:58:54 +010071extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070072 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogerse2645d32012-04-11 14:42:42 -070073 // Called to ensure static storage base is initialized for direct static field reads and writes.
74 // A class may be accessing another class' fields when it doesn't have access, as access has been
75 // given by inheritance.
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070076 ScopedQuickEntrypointChecks sqec(self);
Vladimir Markoea4c1262017-02-06 19:59:33 +000077 auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, kInitEntrypointSaveType);
Vladimir Marko6bec91c2017-01-09 15:03:12 +000078 ArtMethod* caller = caller_and_outer.caller;
79 mirror::Class* result =
80 ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, true, false);
81 if (LIKELY(result != nullptr)) {
82 BssWriteBarrier(caller_and_outer.outer_method);
83 }
84 return result;
Ian Rogers57b86d42012-03-27 16:05:41 -070085}
86
Nicolas Geoffray7ea6a172015-05-19 18:58:54 +010087extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070088 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogerse2645d32012-04-11 14:42:42 -070089 // Called when method->dex_cache_resolved_types_[] misses.
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070090 ScopedQuickEntrypointChecks sqec(self);
Vladimir Markoea4c1262017-02-06 19:59:33 +000091 auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, kInitEntrypointSaveType);
Vladimir Marko6bec91c2017-01-09 15:03:12 +000092 ArtMethod* caller = caller_and_outer.caller;
93 mirror::Class* result =
94 ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, false);
95 if (LIKELY(result != nullptr)) {
96 BssWriteBarrier(caller_and_outer.outer_method);
97 }
98 return result;
Ian Rogers57b86d42012-03-27 16:05:41 -070099}
100
Nicolas Geoffray7ea6a172015-05-19 18:58:54 +0100101extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700102 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700103 // Called when caller isn't guaranteed to have access to a type and the dex cache may be
Ian Rogerse2645d32012-04-11 14:42:42 -0700104 // unpopulated.
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700105 ScopedQuickEntrypointChecks sqec(self);
Vladimir Markoea4c1262017-02-06 19:59:33 +0000106 auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, kInitEntrypointSaveType);
Vladimir Marko6bec91c2017-01-09 15:03:12 +0000107 ArtMethod* caller = caller_and_outer.caller;
108 mirror::Class* result =
109 ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, true);
110 if (LIKELY(result != nullptr)) {
111 BssWriteBarrier(caller_and_outer.outer_method);
112 }
113 return result;
Ian Rogers57b86d42012-03-27 16:05:41 -0700114}
115
Nicolas Geoffray7ea6a172015-05-19 18:58:54 +0100116extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700117 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700118 ScopedQuickEntrypointChecks sqec(self);
Vladimir Markoea4c1262017-02-06 19:59:33 +0000119 auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, kInitEntrypointSaveType);
Vladimir Marko6bec91c2017-01-09 15:03:12 +0000120 ArtMethod* caller = caller_and_outer.caller;
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800121 mirror::String* result = ResolveStringFromCode(caller, dex::StringIndex(string_idx));
Vladimir Markoaad75c62016-10-03 08:46:48 +0000122 if (LIKELY(result != nullptr)) {
Vladimir Marko6bec91c2017-01-09 15:03:12 +0000123 BssWriteBarrier(caller_and_outer.outer_method);
Vladimir Markoaad75c62016-10-03 08:46:48 +0000124 }
125 return result;
Ian Rogers57b86d42012-03-27 16:05:41 -0700126}
127
128} // namespace art