indirect_reference_table-inl.h revision 94f7b49578b6aaa80de8ffed230648d601393905
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 "verify_object-inl.h" 23 24namespace art { 25namespace mirror { 26class Object; 27} // namespace mirror 28 29// Verifies that the indirect table lookup is valid. 30// Returns "false" if something looks bad. 31inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const { 32 if (UNLIKELY(iref == nullptr)) { 33 LOG(WARNING) << "Attempt to look up NULL " << kind_; 34 return false; 35 } 36 if (UNLIKELY(GetIndirectRefKind(iref) == kHandleScopeOrInvalid)) { 37 LOG(ERROR) << "JNI ERROR (app bug): invalid " << kind_ << " " << iref; 38 AbortIfNoCheckJNI(); 39 return false; 40 } 41 const int topIndex = segment_state_.parts.topIndex; 42 int idx = ExtractIndex(iref); 43 if (UNLIKELY(idx >= topIndex)) { 44 LOG(ERROR) << "JNI ERROR (app bug): accessed stale " << kind_ << " " 45 << iref << " (index " << idx << " in a table of size " << topIndex << ")"; 46 AbortIfNoCheckJNI(); 47 return false; 48 } 49 if (UNLIKELY(table_[idx].IsNull())) { 50 LOG(ERROR) << "JNI ERROR (app bug): accessed deleted " << kind_ << " " << iref; 51 AbortIfNoCheckJNI(); 52 return false; 53 } 54 if (UNLIKELY(!CheckEntry("use", iref, idx))) { 55 return false; 56 } 57 return true; 58} 59 60// Make sure that the entry at "idx" is correctly paired with "iref". 61inline bool IndirectReferenceTable::CheckEntry(const char* what, IndirectRef iref, int idx) const { 62 IndirectRef checkRef = ToIndirectRef(idx); 63 if (UNLIKELY(checkRef != iref)) { 64 LOG(ERROR) << "JNI ERROR (app bug): attempt to " << what 65 << " stale " << kind_ << " " << iref 66 << " (should be " << checkRef << ")"; 67 AbortIfNoCheckJNI(); 68 return false; 69 } 70 return true; 71} 72 73template<ReadBarrierOption kReadBarrierOption> 74inline mirror::Object* IndirectReferenceTable::Get(IndirectRef iref) const { 75 if (!GetChecked(iref)) { 76 return kInvalidIndirectRefObject; 77 } 78 uint32_t idx = ExtractIndex(iref); 79 mirror::Object* obj = table_[idx].Read<kWithoutReadBarrier>(); 80 if (LIKELY(obj != kClearedJniWeakGlobal)) { 81 // The read barrier or VerifyObject won't handle kClearedJniWeakGlobal. 82 obj = table_[idx].Read(); 83 VerifyObject(obj); 84 } 85 return obj; 86} 87 88} // namespace art 89 90#endif // ART_RUNTIME_INDIRECT_REFERENCE_TABLE_INL_H_ 91