1 /*
2  * Copyright (C) 2022 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_JNI_LOCAL_REFERENCE_TABLE_H_
18 #define ART_RUNTIME_JNI_LOCAL_REFERENCE_TABLE_H_
19 
20 #include <stdint.h>
21 
22 #include <iosfwd>
23 #include <limits>
24 #include <string>
25 
26 #include <android-base/logging.h>
27 
28 #include "base/bit_field.h"
29 #include "base/bit_utils.h"
30 #include "base/casts.h"
31 #include "base/dchecked_vector.h"
32 #include "base/locks.h"
33 #include "base/macros.h"
34 #include "base/mem_map.h"
35 #include "base/mutex.h"
36 #include "gc_root.h"
37 #include "indirect_reference_table.h"
38 #include "mirror/object_reference.h"
39 #include "obj_ptr.h"
40 #include "offsets.h"
41 
42 namespace art HIDDEN {
43 
44 class RootInfo;
45 
46 namespace mirror {
47 class Object;
48 }  // namespace mirror
49 
50 namespace jni {
51 
52 // Maintain a table of local JNI references.
53 //
54 // The table contains object references that are part of the GC root set. When an object is
55 // added we return an `IndirectRef` that is not a valid pointer but can be used to find the
56 // original value in O(1) time. Conversions to and from local JNI references are performed
57 // on upcalls and downcalls as well as in JNI functions, so they need to be very fast.
58 //
59 // To be efficient for JNI local variable storage, we need to provide operations that allow us to
60 // operate on segments of the table, where segments are pushed and popped as if on a stack. For
61 // example, deletion of an entry should only succeed if it appears in the current segment, and we
62 // want to be able to strip off the current segment quickly when a method returns. Additions to the
63 // table must be made in the current segment even if space is available in an earlier area.
64 //
65 // A new segment is created when we call into native code from managed code, or when we handle
66 // the JNI PushLocalFrame function.
67 //
68 // The GC must be able to scan the entire table quickly.
69 //
70 // In summary, these must be very fast:
71 //  - adding or removing a segment
72 //  - adding references (always adding to the current segment)
73 //  - converting a local reference back to an Object
74 // These can be a little slower, but must still be pretty quick:
75 //  - removing individual references
76 //  - scanning the entire table straight through
77 //
78 // If there's more than one segment, we don't guarantee that the table will fill completely before
79 // we fail due to lack of space. We do ensure that the current segment will pack tightly, which
80 // should satisfy JNI requirements (e.g. EnsureLocalCapacity).
81 
82 // To get the desired behavior for JNI locals, we need to know the bottom and top of the current
83 // "segment". When we call a native method or push a local frame, the current top index gets pushed
84 // on, and serves as the new bottom. When we pop a frame off, the value from the stack becomes the
85 // new top index, and the value stored in the previous frame becomes the new bottom.
86 //
87 // If we delete entries from the middle of the list, we will be left with "holes" which we track
88 // with a singly-linked list, so that they can be reused quickly. After a segment has been removed,
89 // we need to prune removed free entries from the front of this singly-linked list before we can
90 // reuse a free entry from the current segment. This is linear in the number of entries removed
91 // and may appear as a slow reference addition but this slow down is attributable to the previous
92 // removals with a constant time per removal.
93 //
94 // Without CheckJNI, we aim for the fastest possible implementation, so there is no error checking
95 // (in release build) and stale references can be erroneously used, especially after the same slot
96 // has been reused for another reference which we cannot easily detect (even in debug build).
97 //
98 // With CheckJNI, we rotate the slots that we use based on a "serial number".
99 // This increases the memory use but it allows for decent error detection.
100 //
101 // We allow switching between CheckJNI enabled and disabled but entries created with CheckJNI
102 // disabled shall have weaker checking even after enabling CheckJNI and the switch can also
103 // prevent reusing a hole that held a reference created with a different CheckJNI setting.
104 
105 // The state of the current segment contains the top index.
106 struct LRTSegmentState {
107   uint32_t top_index;
108 };
109 
110 // Use as initial value for "cookie", and when table has only one segment.
111 static constexpr LRTSegmentState kLRTFirstSegment = { 0 };
112 
113 // Each entry in the `LocalReferenceTable` can contain a null (initially or after a `Trim()`)
114 // or reference, or it can be marked as free and hold the index of the next free entry.
115 // If CheckJNI is (or was) enabled, some entries can contain serial numbers instead and
116 // only one other entry in a CheckJNI chunk starting with a serial number is active.
117 //
118 // Valid bit patterns:
119 //                   33222222222211111111110000000000
120 //                   10987654321098765432109876543210
121 //   null:           00000000000000000000000000000000  // Only above the top index.
122 //   reference:      <----- reference value ----->000  // See also `kObjectAlignment`.
123 //   free:           <-------- next free --------->01
124 //   serial number:  <------ serial number ------->10  // CheckJNI entry.
125 // Note that serial number entries can appear only as the first entry of a 16-byte aligned
126 // chunk of four entries and the serial number in the range [1, 3] specifies which of the
127 // other three entries in the chunk is currently used.
128 class LrtEntry {
129  public:
130   void SetReference(ObjPtr<mirror::Object> ref) REQUIRES_SHARED(Locks::mutator_lock_);
131 
132   ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_);
133 
IsNull()134   bool IsNull() const {
135     return root_.IsNull();
136   }
137 
138   void SetNextFree(uint32_t next_free) REQUIRES_SHARED(Locks::mutator_lock_);
139 
GetNextFree()140   uint32_t GetNextFree() {
141     DCHECK(IsFree());
142     DCHECK(!IsSerialNumber());
143     return NextFreeField::Decode(GetRawValue());
144   }
145 
IsFree()146   bool IsFree() {
147     return (GetRawValue() & (1u << kFlagFree)) != 0u;
148   }
149 
150   void SetSerialNumber(uint32_t serial_number) REQUIRES_SHARED(Locks::mutator_lock_);
151 
GetSerialNumber()152   uint32_t GetSerialNumber() {
153     DCHECK(IsSerialNumber());
154     DCHECK(!IsFree());
155     return GetSerialNumberUnchecked();
156   }
157 
GetSerialNumberUnchecked()158   uint32_t GetSerialNumberUnchecked() {
159     return SerialNumberField::Decode(GetRawValue());
160   }
161 
IsSerialNumber()162   bool IsSerialNumber() {
163     return (GetRawValue() & (1u << kFlagSerialNumber)) != 0u;
164   }
165 
GetRootAddress()166   GcRoot<mirror::Object>* GetRootAddress() {
167     return &root_;
168   }
169 
FreeListEnd()170   static constexpr uint32_t FreeListEnd() {
171     return MaxInt<uint32_t>(kFieldNextFreeBits);
172   }
173 
174  private:
175   // Definitions of bit fields and flags.
176   static constexpr size_t kFlagFree = 0u;
177   static constexpr size_t kFlagSerialNumber = kFlagFree + 1u;
178   static constexpr size_t kFieldNextFree = kFlagSerialNumber + 1u;
179   static constexpr size_t kFieldNextFreeBits = BitSizeOf<uint32_t>() - kFieldNextFree;
180 
181   using NextFreeField = BitField<uint32_t, kFieldNextFree, kFieldNextFreeBits>;
182   using SerialNumberField = NextFreeField;
183 
184   static_assert(kObjectAlignment > (1u << kFlagFree));
185   static_assert(kObjectAlignment > (1u << kFlagSerialNumber));
186 
187   void SetVRegValue(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_);
188 
GetRawValue()189   uint32_t GetRawValue() {
190     return root_.AddressWithoutBarrier()->AsVRegValue();
191   }
192 
193   // We record the contents as a `GcRoot<>` but it is an actual `GcRoot<>` only if it's below
194   // the current segment's top index, it's not a "serial number" or inactive entry in a CheckJNI
195   // chunk, and it's not marked as "free". Such entries are never null.
196   GcRoot<mirror::Object> root_;
197 };
198 static_assert(sizeof(LrtEntry) == sizeof(mirror::CompressedReference<mirror::Object>));
199 // Assert that the low bits of an `LrtEntry*` are sufficient for encoding the reference kind.
200 static_assert(enum_cast<uint32_t>(IndirectRefKind::kLastKind) < alignof(LrtEntry));
201 
202 
203 // We initially allocate local reference tables with a small number of entries, packing
204 // multiple tables into a single page. If we need to expand, we double the capacity,
205 // first allocating another chunk with the same number of entries as the first chunk
206 // and then allocating twice as big chunk on each subsequent expansion.
207 static constexpr size_t kInitialLrtBytes = 512;  // Number of bytes in an initial local table.
208 static constexpr size_t kSmallLrtEntries = kInitialLrtBytes / sizeof(LrtEntry);
209 static_assert(IsPowerOfTwo(kInitialLrtBytes));
210 
211 static_assert(kMinPageSize % kInitialLrtBytes == 0);
212 static_assert(kInitialLrtBytes % sizeof(LrtEntry) == 0);
213 
214 // A minimal stopgap allocator for initial small local LRT tables.
215 class SmallLrtAllocator {
216  public:
217   SmallLrtAllocator();
218 
219   // Allocate a small block of `LrtEntries` for the `LocalReferenceTable` table. The `size`
220   // must be a power of 2, at least `kSmallLrtEntries`, and requiring less than a page of memory.
221   LrtEntry* Allocate(size_t size, std::string* error_msg) REQUIRES(!lock_);
222 
223   void Deallocate(LrtEntry* unneeded, size_t size) REQUIRES(!lock_);
224 
225  private:
226   // Number of free lists in the allocator.
227 #ifdef ART_PAGE_SIZE_AGNOSTIC
228   const size_t num_lrt_slots_ = (WhichPowerOf2(gPageSize / kInitialLrtBytes));
229 #else
230   static constexpr size_t num_lrt_slots_ = (WhichPowerOf2(gPageSize / kInitialLrtBytes));
231 #endif
232 
233   size_t GetIndex(size_t size);
234 
235   // Free lists of small chunks linked through the first word.
236   dchecked_vector<void*> free_lists_;
237 
238   // Repository of MemMaps used for small LRT tables.
239   dchecked_vector<MemMap> shared_lrt_maps_;
240 
241   Mutex lock_;  // Level kGenericBottomLock; acquired before mem_map_lock_, which is a C++ mutex.
242 };
243 
244 class LocalReferenceTable {
245  public:
246   explicit LocalReferenceTable(bool check_jni);
247   ~LocalReferenceTable();
248 
249   // Set the CheckJNI enabled status.
250   // Called only from the Zygote post-fork callback while the process is single-threaded.
251   // Enabling CheckJNI reduces the number of entries that can be stored, thus invalidating
252   // guarantees provided by a previous call to `EnsureFreeCapacity()`.
253   void SetCheckJniEnabled(bool enabled);
254 
255   // Returns whether the CheckJNI is enabled for this `LocalReferenceTable`.
IsCheckJniEnabled()256   bool IsCheckJniEnabled() const {
257     return (free_entries_list_ & (1u << kFlagCheckJni)) != 0u;
258   }
259 
260   // Initialize the `LocalReferenceTable`.
261   //
262   // Max_count is the requested minimum initial capacity (resizable). The actual initial
263   // capacity can be higher to utilize all allocated memory.
264   //
265   // Returns true on success.
266   // On failure, returns false and reports error in `*error_msg`.
267   bool Initialize(size_t max_count, std::string* error_msg);
268 
269   // Add a new entry. The `obj` must be a valid non-null object reference. This function
270   // will return null if an error happened (with an appropriate error message set).
271   EXPORT IndirectRef Add(ObjPtr<mirror::Object> obj, std::string* error_msg)
272       REQUIRES_SHARED(Locks::mutator_lock_);
273 
274   // Given an `IndirectRef` in the table, return the `Object` it refers to.
275   //
276   // This function may abort under error conditions in debug build.
277   // In release builds, error conditions are unchecked and the function can
278   // return old or invalid references from popped segments and deleted entries.
279   ObjPtr<mirror::Object> Get(IndirectRef iref) const
280       REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE;
281 
282   // Updates an existing indirect reference to point to a new object.
283   // Used exclusively for updating `String` references after calling a `String` constructor.
284   void Update(IndirectRef iref, ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_);
285 
286   // Remove an existing entry.
287   //
288   // If the entry is not between the current top index and the bottom index
289   // specified by the cookie, we don't remove anything.  This is the behavior
290   // required by JNI's DeleteLocalRef function.
291   //
292   // Returns "false" if nothing was removed.
293   bool Remove(IndirectRef iref)
294       REQUIRES_SHARED(Locks::mutator_lock_);
295 
296   void AssertEmpty();
297 
298   void Dump(std::ostream& os) const
299       REQUIRES_SHARED(Locks::mutator_lock_)
300       REQUIRES(!Locks::alloc_tracker_lock_);
301 
GetKind()302   IndirectRefKind GetKind() const {
303     return kLocal;
304   }
305 
306   // Return the number of entries in the entire table. This includes holes,
307   // and so may be larger than the actual number of "live" entries.
308   // The value corresponds to the number of entries for the current CheckJNI setting
309   // and may be wrong if there are entries created with a different CheckJNI setting.
Capacity()310   size_t Capacity() const {
311     if (IsCheckJniEnabled()) {
312       DCHECK_ALIGNED(segment_state_.top_index, kCheckJniEntriesPerReference);
313       return segment_state_.top_index / kCheckJniEntriesPerReference;
314     } else {
315       return segment_state_.top_index;
316     }
317   }
318 
319   // Ensure that at least free_capacity elements are available, or return false.
320   // Caller ensures free_capacity > 0.
321   bool EnsureFreeCapacity(size_t free_capacity, std::string* error_msg)
322       REQUIRES_SHARED(Locks::mutator_lock_);
323   // See implementation of EnsureFreeCapacity. We'll only state here how much is trivially free,
324   // without recovering holes. Thus this is a conservative estimate.
325   size_t FreeCapacity() const;
326 
327   EXPORT void VisitRoots(RootVisitor* visitor, const RootInfo& root_info)
328       REQUIRES_SHARED(Locks::mutator_lock_);
329 
PushFrame()330   LRTSegmentState PushFrame() {
331     if (kDebugLRT) {
332       LOG(INFO) << "+++ Push frame: previous state " << previous_state_.top_index << " -> "
333                 << segment_state_.top_index;
334     }
335     LRTSegmentState result = previous_state_;
336     previous_state_ = segment_state_;
337     return result;
338   }
339 
PopFrame(LRTSegmentState previous_state)340   void PopFrame(LRTSegmentState previous_state) {
341     if (kDebugLRT) {
342       LOG(INFO) << "+++ Pop frame: current state " << segment_state_.top_index << " -> "
343                 << previous_state_.top_index << ", previous state -> " << previous_state.top_index;
344     }
345     segment_state_ = previous_state_;
346     previous_state_ = previous_state;
347   }
348 
PreviousStateOffset()349   static MemberOffset PreviousStateOffset() {
350     // Note: The `previous_state_` must be before any pointer-size-dependent members, so that
351     // `MEMBER_OFFSET()` gives the correct value even for cross-compilation.
352     return MemberOffset(OFFSETOF_MEMBER(LocalReferenceTable, previous_state_));
353   }
354 
SegmentStateOffset()355   static MemberOffset SegmentStateOffset() {
356     // Note: The `segment_state_` must be before any pointer-size-dependent members, so that
357     // `MEMBER_OFFSET()` gives the correct value even for cross-compilation.
358     return MemberOffset(OFFSETOF_MEMBER(LocalReferenceTable, segment_state_));
359   }
360 
361   // Release pages past the end of the table that may have previously held references.
362   void Trim() REQUIRES_SHARED(Locks::mutator_lock_);
363 
364   /* Reference validation for CheckJNI and debug build. */
365   bool IsValidReference(IndirectRef, /*out*/std::string* error_msg) const
366       REQUIRES_SHARED(Locks::mutator_lock_);
367 
368  private:
369   static constexpr bool kDebugLRT = false;
370 
371   // Flags and fields in the `free_entries_list_`.
372   static constexpr size_t kFlagCheckJni = 0u;
373   // Skip a bit to have the same value range for the "first free" as the "next free" in `LrtEntry`.
374   static constexpr size_t kFlagPadding = kFlagCheckJni + 1u;
375   static constexpr size_t kFieldFirstFree = kFlagPadding + 1u;
376   static constexpr size_t kFieldFirstFreeSize = BitSizeOf<uint32_t>() - kFieldFirstFree;
377 
378   using FirstFreeField = BitField<uint32_t, kFieldFirstFree, kFieldFirstFreeSize>;
379 
380   // The value of `FirstFreeField` in `free_entries_list_` indicating the end of the free list.
381   static constexpr uint32_t kFreeListEnd = LrtEntry::FreeListEnd();
382   static_assert(kFreeListEnd == MaxInt<uint32_t>(kFieldFirstFreeSize));
383 
384   // The value of `free_entries_list_` indicating empty free list and disabled CheckJNI.
385   static constexpr uint32_t kEmptyFreeListAndCheckJniDisabled =
386       FirstFreeField::Update(kFreeListEnd, 0u);  // kFlagCheckJni not set.
387 
388   // The number of entries per reference to detect obsolete reference uses with CheckJNI enabled.
389   // The first entry serves as a serial number, one of the remaining entries can hold the actual
390   // reference or the next free index.
391   static constexpr size_t kCheckJniEntriesPerReference = 4u;
392   static_assert(IsPowerOfTwo(kCheckJniEntriesPerReference));
393 
394   // The maximum total table size we allow.
395   static constexpr size_t kMaxTableSizeInBytes = 128 * MB;
396   static_assert(IsPowerOfTwo(kMaxTableSizeInBytes));
397   static_assert(IsPowerOfTwo(sizeof(LrtEntry)));
398   static constexpr size_t kMaxTableSize = kMaxTableSizeInBytes / sizeof(LrtEntry);
399 
ToIndirectRef(LrtEntry * entry)400   static IndirectRef ToIndirectRef(LrtEntry* entry) {
401     // The `IndirectRef` can be used to directly access the underlying `GcRoot<>`.
402     DCHECK_EQ(reinterpret_cast<GcRoot<mirror::Object>*>(entry), entry->GetRootAddress());
403     return reinterpret_cast<IndirectRef>(
404         reinterpret_cast<uintptr_t>(entry) | static_cast<uintptr_t>(kLocal));
405   }
406 
ToLrtEntry(IndirectRef iref)407   static LrtEntry* ToLrtEntry(IndirectRef iref) {
408     DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(iref), kLocal);
409     return IndirectReferenceTable::ClearIndirectRefKind<LrtEntry*>(iref);
410   }
411 
GetTableSize(size_t table_index)412   static constexpr size_t GetTableSize(size_t table_index) {
413     // First two tables have size `kSmallLrtEntries`, then it doubles for subsequent tables.
414     return kSmallLrtEntries << (table_index != 0u ? table_index - 1u : 0u);
415   }
416 
NumTablesForSize(size_t size)417   static constexpr size_t NumTablesForSize(size_t size) {
418     DCHECK_GE(size, kSmallLrtEntries);
419     DCHECK(IsPowerOfTwo(size));
420     return 1u + WhichPowerOf2(size / kSmallLrtEntries);
421   }
422 
MaxSmallTables()423   static size_t MaxSmallTables() {
424     return NumTablesForSize(gPageSize / sizeof(LrtEntry));
425   }
426 
GetEntry(size_t entry_index)427   LrtEntry* GetEntry(size_t entry_index) const {
428     DCHECK_LT(entry_index, max_entries_);
429     if (LIKELY(small_table_ != nullptr)) {
430       DCHECK_LT(entry_index, kSmallLrtEntries);
431       DCHECK_EQ(max_entries_, kSmallLrtEntries);
432       return &small_table_[entry_index];
433     }
434     size_t table_start_index =
435         (entry_index < kSmallLrtEntries) ? 0u : TruncToPowerOfTwo(entry_index);
436     size_t table_index =
437         (entry_index < kSmallLrtEntries) ? 0u : NumTablesForSize(table_start_index);
438     LrtEntry* table = tables_[table_index];
439     return &table[entry_index - table_start_index];
440   }
441 
442   // Get the entry index for a local reference. Note that this may be higher than
443   // the current segment state. Returns maximum uint32 value if the reference does not
444   // point to one of the internal tables.
445   uint32_t GetReferenceEntryIndex(IndirectRef iref) const;
446 
GetCheckJniSerialNumberEntry(LrtEntry * entry)447   static LrtEntry* GetCheckJniSerialNumberEntry(LrtEntry* entry) {
448     return AlignDown(entry, kCheckJniEntriesPerReference * sizeof(LrtEntry));
449   }
450 
451   static uint32_t IncrementSerialNumber(LrtEntry* serial_number_entry)
452       REQUIRES_SHARED(Locks::mutator_lock_);
453 
IsValidSerialNumber(uint32_t serial_number)454   static bool IsValidSerialNumber(uint32_t serial_number) {
455     return serial_number != 0u && serial_number < kCheckJniEntriesPerReference;
456   }
457 
458   // Debug mode check that the reference is valid.
459   void DCheckValidReference(IndirectRef iref) const REQUIRES_SHARED(Locks::mutator_lock_);
460 
461   // Resize the backing table to be at least `new_size` elements long. The `new_size`
462   // must be larger than the current size. After return max_entries_ >= new_size.
463   bool Resize(size_t new_size, std::string* error_msg);
464 
465   // Extract the first free index from `free_entries_list_`.
GetFirstFreeIndex()466   uint32_t GetFirstFreeIndex() const {
467     return FirstFreeField::Decode(free_entries_list_);
468   }
469 
470   // Remove popped free entries from the list.
471   // Called only if `free_entries_list_` points to a popped entry.
472   template <typename EntryGetter>
473   void PrunePoppedFreeEntries(EntryGetter&& get_entry);
474 
475   // Helper template function for visiting roots.
476   template <typename Visitor>
477   void VisitRootsInternal(Visitor&& visitor) const REQUIRES_SHARED(Locks::mutator_lock_);
478 
479   /// semi-public - read/write by jni down calls.
480   // These two members need to be before any pointer-size-dependent members, so that
481   // `MEMBER_OFFSET()` gives the correct value even for cross-compilation.
482   LRTSegmentState previous_state_;
483   LRTSegmentState segment_state_;
484 
485   // The maximum number of entries (modulo resizing).
486   uint32_t max_entries_;
487 
488   // The singly-linked list of free nodes.
489   // We use entry indexes instead of pointers and `kFreeListEnd` instead of null indicates
490   // the end of the list. See `LocalReferenceTable::GetEntry()` and `LrtEntry::GetNextFree().
491   //
492   // We use the lowest bit to record whether CheckJNI is enabled. This helps us
493   // check that the list is empty and CheckJNI is disabled in a single comparison.
494   uint32_t free_entries_list_;
495 
496   // Individual tables.
497   // As long as we have only one small table, we use `small_table_` to avoid an extra load
498   // from another heap allocated location, otherwise we set it to null and use `tables_`.
499   LrtEntry* small_table_;  // For optimizing the fast-path.
500   dchecked_vector<LrtEntry*> tables_;
501 
502   // Mem maps where we store tables allocated directly with `MemMap`
503   // rather than the `SmallLrtAllocator`.
504   dchecked_vector<MemMap> table_mem_maps_;
505 };
506 
507 }  // namespace jni
508 }  // namespace art
509 
510 #endif  // ART_RUNTIME_JNI_LOCAL_REFERENCE_TABLE_H_
511