Home | History | Annotate | Download | only in mirror
      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 
     30 void Field::SetClass(ObjPtr<Class> klass) {
     31   CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
     32   CHECK(klass != nullptr);
     33   static_class_ = GcRoot<Class>(klass);
     34 }
     35 
     36 void Field::ResetClass() {
     37   CHECK(!static_class_.IsNull());
     38   static_class_ = GcRoot<Class>(nullptr);
     39 }
     40 
     41 void Field::SetArrayClass(ObjPtr<Class> klass) {
     42   CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
     43   CHECK(klass != nullptr);
     44   array_class_ = GcRoot<Class>(klass);
     45 }
     46 
     47 void Field::ResetArrayClass() {
     48   CHECK(!array_class_.IsNull());
     49   array_class_ = GcRoot<Class>(nullptr);
     50 }
     51 
     52 void Field::VisitRoots(RootVisitor* visitor) {
     53   static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
     54   array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
     55 }
     56 
     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->GetSFieldsPtr()->At(0);
     65     } else {
     66       DCHECK_EQ(GetDexFieldIndex(), 1U);
     67       return &declaring_class->GetSFieldsPtr()->At(1);
     68     }
     69   }
     70   mirror::DexCache* const dex_cache = declaring_class->GetDexCache();
     71   ArtField* art_field = dex_cache->GetResolvedField(GetDexFieldIndex(), kRuntimePointerSize);
     72   if (UNLIKELY(art_field == nullptr)) {
     73     if (IsStatic()) {
     74       art_field = declaring_class->FindDeclaredStaticField(dex_cache, GetDexFieldIndex());
     75     } else {
     76       art_field = declaring_class->FindInstanceField(dex_cache, GetDexFieldIndex());
     77     }
     78     CHECK(art_field != nullptr);
     79     dex_cache->SetResolvedField(GetDexFieldIndex(), art_field, kRuntimePointerSize);
     80   }
     81   CHECK_EQ(declaring_class, art_field->GetDeclaringClass());
     82   return art_field;
     83 }
     84 
     85 }  // namespace mirror
     86 }  // namespace art
     87