Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2014 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 #ifndef ART_RUNTIME_INDIRECT_REFERENCE_TABLE_INL_H_
     18 #define ART_RUNTIME_INDIRECT_REFERENCE_TABLE_INL_H_
     19 
     20 #include "indirect_reference_table.h"
     21 
     22 #include "gc_root-inl.h"
     23 #include "runtime-inl.h"
     24 #include "verify_object-inl.h"
     25 
     26 namespace art {
     27 namespace mirror {
     28 class Object;
     29 }  // namespace mirror
     30 
     31 // Verifies that the indirect table lookup is valid.
     32 // Returns "false" if something looks bad.
     33 inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
     34   if (UNLIKELY(iref == nullptr)) {
     35     LOG(WARNING) << "Attempt to look up nullptr " << kind_;
     36     return false;
     37   }
     38   if (UNLIKELY(GetIndirectRefKind(iref) == kHandleScopeOrInvalid)) {
     39     AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): invalid %s %p",
     40                                    GetIndirectRefKindString(kind_),
     41                                    iref));
     42     return false;
     43   }
     44   const int topIndex = segment_state_.parts.topIndex;
     45   int idx = ExtractIndex(iref);
     46   if (UNLIKELY(idx >= topIndex)) {
     47     std::string msg = StringPrintf(
     48         "JNI ERROR (app bug): accessed stale %s %p  (index %d in a table of size %d)",
     49         GetIndirectRefKindString(kind_),
     50         iref,
     51         idx,
     52         topIndex);
     53     AbortIfNoCheckJNI(msg);
     54     return false;
     55   }
     56   if (UNLIKELY(table_[idx].GetReference()->IsNull())) {
     57     AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): accessed deleted %s %p",
     58                                    GetIndirectRefKindString(kind_),
     59                                    iref));
     60     return false;
     61   }
     62   if (UNLIKELY(!CheckEntry("use", iref, idx))) {
     63     return false;
     64   }
     65   return true;
     66 }
     67 
     68 // Make sure that the entry at "idx" is correctly paired with "iref".
     69 inline bool IndirectReferenceTable::CheckEntry(const char* what, IndirectRef iref, int idx) const {
     70   IndirectRef checkRef = ToIndirectRef(idx);
     71   if (UNLIKELY(checkRef != iref)) {
     72     std::string msg = StringPrintf(
     73         "JNI ERROR (app bug): attempt to %s stale %s %p (should be %p)",
     74         what,
     75         GetIndirectRefKindString(kind_),
     76         iref,
     77         checkRef);
     78     AbortIfNoCheckJNI(msg);
     79     return false;
     80   }
     81   return true;
     82 }
     83 
     84 template<ReadBarrierOption kReadBarrierOption>
     85 inline mirror::Object* IndirectReferenceTable::Get(IndirectRef iref) const {
     86   if (!GetChecked(iref)) {
     87     return nullptr;
     88   }
     89   uint32_t idx = ExtractIndex(iref);
     90   mirror::Object* obj = table_[idx].GetReference()->Read<kReadBarrierOption>();
     91   VerifyObject(obj);
     92   return obj;
     93 }
     94 
     95 inline void IndirectReferenceTable::Update(IndirectRef iref, mirror::Object* obj) {
     96   if (!GetChecked(iref)) {
     97     LOG(WARNING) << "IndirectReferenceTable Update failed to find reference " << iref;
     98     return;
     99   }
    100   uint32_t idx = ExtractIndex(iref);
    101   table_[idx].SetReference(obj);
    102 }
    103 
    104 }  // namespace art
    105 
    106 #endif  // ART_RUNTIME_INDIRECT_REFERENCE_TABLE_INL_H_
    107