OSDN Git Service

Merge "MIPS32: Assign missing entrypoints in InitEntryPoints"
[android-x86/art.git] / runtime / indirect_reference_table-inl.h
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 "base/dumpable.h"
23 #include "gc_root-inl.h"
24 #include "obj_ptr-inl.h"
25 #include "runtime-inl.h"
26 #include "verify_object-inl.h"
27
28 namespace art {
29 namespace mirror {
30 class Object;
31 }  // namespace mirror
32
33 // Verifies that the indirect table lookup is valid.
34 // Returns "false" if something looks bad.
35 inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
36   if (UNLIKELY(iref == nullptr)) {
37     LOG(WARNING) << "Attempt to look up nullptr " << kind_;
38     return false;
39   }
40   if (UNLIKELY(GetIndirectRefKind(iref) == kHandleScopeOrInvalid)) {
41     AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): invalid %s %p",
42                                    GetIndirectRefKindString(kind_),
43                                    iref));
44     return false;
45   }
46   const uint32_t top_index = segment_state_.top_index;
47   uint32_t idx = ExtractIndex(iref);
48   if (UNLIKELY(idx >= top_index)) {
49     std::string msg = StringPrintf(
50         "JNI ERROR (app bug): accessed stale %s %p  (index %d in a table of size %d)",
51         GetIndirectRefKindString(kind_),
52         iref,
53         idx,
54         top_index);
55     AbortIfNoCheckJNI(msg);
56     return false;
57   }
58   if (UNLIKELY(table_[idx].GetReference()->IsNull())) {
59     AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): accessed deleted %s %p",
60                                    GetIndirectRefKindString(kind_),
61                                    iref));
62     return false;
63   }
64   if (UNLIKELY(!CheckEntry("use", iref, idx))) {
65     return false;
66   }
67   return true;
68 }
69
70 // Make sure that the entry at "idx" is correctly paired with "iref".
71 inline bool IndirectReferenceTable::CheckEntry(const char* what,
72                                                IndirectRef iref,
73                                                uint32_t idx) const {
74   IndirectRef checkRef = ToIndirectRef(idx);
75   if (UNLIKELY(checkRef != iref)) {
76     std::string msg = StringPrintf(
77         "JNI ERROR (app bug): attempt to %s stale %s %p (should be %p)",
78         what,
79         GetIndirectRefKindString(kind_),
80         iref,
81         checkRef);
82     AbortIfNoCheckJNI(msg);
83     return false;
84   }
85   return true;
86 }
87
88 template<ReadBarrierOption kReadBarrierOption>
89 inline ObjPtr<mirror::Object> IndirectReferenceTable::Get(IndirectRef iref) const {
90   if (!GetChecked(iref)) {
91     return nullptr;
92   }
93   uint32_t idx = ExtractIndex(iref);
94   ObjPtr<mirror::Object> obj = table_[idx].GetReference()->Read<kReadBarrierOption>();
95   VerifyObject(obj);
96   return obj;
97 }
98
99 inline void IndirectReferenceTable::Update(IndirectRef iref, ObjPtr<mirror::Object> obj) {
100   if (!GetChecked(iref)) {
101     LOG(WARNING) << "IndirectReferenceTable Update failed to find reference " << iref;
102     return;
103   }
104   uint32_t idx = ExtractIndex(iref);
105   table_[idx].SetReference(obj);
106 }
107
108 inline void IrtEntry::Add(ObjPtr<mirror::Object> obj) {
109   ++serial_;
110   if (serial_ == kIRTPrevCount) {
111     serial_ = 0;
112   }
113   references_[serial_] = GcRoot<mirror::Object>(obj);
114 }
115
116 inline void IrtEntry::SetReference(ObjPtr<mirror::Object> obj) {
117   DCHECK_LT(serial_, kIRTPrevCount);
118   references_[serial_] = GcRoot<mirror::Object>(obj);
119 }
120
121 }  // namespace art
122
123 #endif  // ART_RUNTIME_INDIRECT_REFERENCE_TABLE_INL_H_