1 /*
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 "field-inl.h"
18 
19 #include "class-inl.h"
20 #include "dex_cache-inl.h"
21 #include "object_array-inl.h"
22 #include "object-inl.h"
23 
24 namespace art {
25 namespace mirror {
26 
27 GcRoot<Class> Field::static_class_;
28 GcRoot<Class> Field::array_class_;
29 
SetClass(Class * klass)30 void Field::SetClass(Class* klass) {
31   CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
32   CHECK(klass != nullptr);
33   static_class_ = GcRoot<Class>(klass);
34 }
35 
ResetClass()36 void Field::ResetClass() {
37   CHECK(!static_class_.IsNull());
38   static_class_ = GcRoot<Class>(nullptr);
39 }
40 
SetArrayClass(Class * klass)41 void Field::SetArrayClass(Class* klass) {
42   CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
43   CHECK(klass != nullptr);
44   array_class_ = GcRoot<Class>(klass);
45 }
46 
ResetArrayClass()47 void Field::ResetArrayClass() {
48   CHECK(!array_class_.IsNull());
49   array_class_ = GcRoot<Class>(nullptr);
50 }
51 
VisitRoots(RootVisitor * visitor)52 void Field::VisitRoots(RootVisitor* visitor) {
53   static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
54   array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
55 }
56 
GetArtField()57 ArtField* Field::GetArtField() {
58   mirror::Class* declaring_class = GetDeclaringClass();
59   if (UNLIKELY(declaring_class->IsProxyClass())) {
60     DCHECK(IsStatic());
61     DCHECK_EQ(declaring_class->NumStaticFields(), 2U);
62     // 0 == Class[] interfaces; 1 == Class[][] throws;
63     if (GetDexFieldIndex() == 0) {
64       return &declaring_class->GetSFields()[0];
65     } else {
66       DCHECK_EQ(GetDexFieldIndex(), 1U);
67       return &declaring_class->GetSFields()[1];
68     }
69   }
70   mirror::DexCache* const dex_cache = declaring_class->GetDexCache();
71   ArtField* const art_field = dex_cache->GetResolvedField(GetDexFieldIndex(), sizeof(void*));
72   CHECK(art_field != nullptr);
73   CHECK_EQ(declaring_class, art_field->GetDeclaringClass());
74   return art_field;
75 }
76 
77 }  // namespace mirror
78 }  // namespace art
79