blob: 25cbdc131b3215a55f5e8cddf96184e9df7467ff [file] [log] [blame]
Mathieu Chartierfc58af42015-04-16 18:00:39 -07001/*
2 * Copyright (C) 2015 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 "method.h"
18
Mathieu Chartiere401d142015-04-22 13:56:20 -070019#include "art_method.h"
20#include "gc_root-inl.h"
21#include "mirror/class-inl.h"
Mathieu Chartierfc58af42015-04-16 18:00:39 -070022#include "mirror/object-inl.h"
23
24namespace art {
25namespace mirror {
26
27GcRoot<Class> Method::static_class_;
28GcRoot<Class> Method::array_class_;
29GcRoot<Class> Constructor::static_class_;
30GcRoot<Class> Constructor::array_class_;
31
32void Method::SetClass(Class* klass) {
33 CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
34 CHECK(klass != nullptr);
35 static_class_ = GcRoot<Class>(klass);
36}
37
38void Method::ResetClass() {
39 CHECK(!static_class_.IsNull());
40 static_class_ = GcRoot<Class>(nullptr);
41}
42
43void Method::SetArrayClass(Class* klass) {
44 CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
45 CHECK(klass != nullptr);
46 array_class_ = GcRoot<Class>(klass);
47}
48
49void Method::ResetArrayClass() {
50 CHECK(!array_class_.IsNull());
51 array_class_ = GcRoot<Class>(nullptr);
52}
53
Andreas Gampe542451c2016-07-26 09:02:02 -070054template <PointerSize kPointerSize, bool kTransactionActive>
Mathieu Chartiere401d142015-04-22 13:56:20 -070055Method* Method::CreateFromArtMethod(Thread* self, ArtMethod* method) {
David Sehr709b0702016-10-13 09:12:37 -070056 DCHECK(!method->IsConstructor()) << method->PrettyMethod();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070057 ObjPtr<Method> ret = ObjPtr<Method>::DownCast(StaticClass()->AllocObject(self));
Mathieu Chartierfc58af42015-04-16 18:00:39 -070058 if (LIKELY(ret != nullptr)) {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070059 ObjPtr<Executable>(ret)->
Andreas Gampee01e3642016-07-25 13:06:04 -070060 CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
Mathieu Chartierfc58af42015-04-16 18:00:39 -070061 }
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070062 return ret.Ptr();
Mathieu Chartierfc58af42015-04-16 18:00:39 -070063}
64
Andreas Gampe542451c2016-07-26 09:02:02 -070065template Method* Method::CreateFromArtMethod<PointerSize::k32, false>(Thread* self,
66 ArtMethod* method);
67template Method* Method::CreateFromArtMethod<PointerSize::k32, true>(Thread* self,
68 ArtMethod* method);
69template Method* Method::CreateFromArtMethod<PointerSize::k64, false>(Thread* self,
70 ArtMethod* method);
71template Method* Method::CreateFromArtMethod<PointerSize::k64, true>(Thread* self,
72 ArtMethod* method);
Andreas Gampebc4d2182016-02-22 10:03:12 -080073
Mathieu Chartierfc58af42015-04-16 18:00:39 -070074void Method::VisitRoots(RootVisitor* visitor) {
75 static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
76 array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
77}
78
79void Constructor::SetClass(Class* klass) {
80 CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
81 CHECK(klass != nullptr);
82 static_class_ = GcRoot<Class>(klass);
83}
84
85void Constructor::ResetClass() {
86 CHECK(!static_class_.IsNull());
87 static_class_ = GcRoot<Class>(nullptr);
88}
89
90void Constructor::SetArrayClass(Class* klass) {
91 CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
92 CHECK(klass != nullptr);
93 array_class_ = GcRoot<Class>(klass);
94}
95
96void Constructor::ResetArrayClass() {
97 CHECK(!array_class_.IsNull());
98 array_class_ = GcRoot<Class>(nullptr);
99}
100
101void Constructor::VisitRoots(RootVisitor* visitor) {
102 static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
103 array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
104}
105
Andreas Gampe542451c2016-07-26 09:02:02 -0700106template <PointerSize kPointerSize, bool kTransactionActive>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700107Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method) {
David Sehr709b0702016-10-13 09:12:37 -0700108 DCHECK(method->IsConstructor()) << method->PrettyMethod();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700109 ObjPtr<Constructor> ret = ObjPtr<Constructor>::DownCast(StaticClass()->AllocObject(self));
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700110 if (LIKELY(ret != nullptr)) {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700111 ObjPtr<Executable>(ret)->
Andreas Gampee01e3642016-07-25 13:06:04 -0700112 CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700113 }
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700114 return ret.Ptr();
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700115}
116
Andreas Gampe542451c2016-07-26 09:02:02 -0700117template Constructor* Constructor::CreateFromArtMethod<PointerSize::k32, false>(
118 Thread* self, ArtMethod* method);
119template Constructor* Constructor::CreateFromArtMethod<PointerSize::k32, true>(
120 Thread* self, ArtMethod* method);
121template Constructor* Constructor::CreateFromArtMethod<PointerSize::k64, false>(
122 Thread* self, ArtMethod* method);
123template Constructor* Constructor::CreateFromArtMethod<PointerSize::k64, true>(
124 Thread* self, ArtMethod* method);
Andreas Gampe6039e562016-04-05 18:18:43 -0700125
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700126} // namespace mirror
127} // namespace art