JIT mini-debug-info: Insert application entries at the head.
Simpleperf expects that new entries will be added at the head.
It is easier to maintain that property than adjust simpleperf.
Bug: 143375574
Test: test.py --host -b -r --jit --64
Change-Id: Ib7aaa10d79791464b8233cacffd7c40070565f34
diff --git a/runtime/jit/debugger_interface.cc b/runtime/jit/debugger_interface.cc
index 1ca4165..cecf533 100644
--- a/runtime/jit/debugger_interface.cc
+++ b/runtime/jit/debugger_interface.cc
@@ -69,9 +69,6 @@
// 2) Read the symfile and re-read the next pointer.
// 3) Re-read both the current and next seqlock.
// 4) Go to step 1 with using new entry and seqlock.
-// * New entries are appended at the end which makes it
-// possible to repack entries even when the reader
-// is concurrently iterating over the linked list.
//
// 3) Asynchronously, using the global seqlock.
// * The seqlock is a monotonically increasing counter which is incremented
@@ -314,9 +311,9 @@
uint64_t timestamp = GetNextTimestamp(descriptor);
// We must insert entries at specific place. See NativeDebugInfoPreFork().
- const JITCodeEntry* next = nullptr; // Append at the end of linked list.
- if (!Runtime::Current()->IsZygote() && descriptor.zygote_head_entry_ != nullptr) {
- next = &descriptor.application_tail_entry_;
+ const JITCodeEntry* next = descriptor.head_.load(kNonRacingRelaxed); // Insert at the head.
+ if (descriptor.zygote_head_entry_ != nullptr && Runtime::Current()->IsZygote()) {
+ next = nullptr; // Insert zygote entries at the tail.
}
// Pop entry from the free list.
@@ -423,9 +420,16 @@
// <------- owned by the application memory --------> <--- owned by zygote memory --->
// |----------------------|------------------|-------------|-----------------|
// head -> | application_entries* | application_tail | zygote_head | zygote_entries* |
-// |---------------------+|------------------|-------------|----------------+|
-// | |
-// (new application entries)-/ (new zygote entries)-/
+// |+---------------------|------------------|-------------|----------------+|
+// | |
+// \-(new application entries) (new zygote entries)-/
+//
+// Zygote entries are inserted at the end, which means that repacked zygote entries
+// will still be seen by single forward iteration of the linked list (avoiding race).
+//
+// Application entries are inserted at the start which introduces repacking race,
+// but that is ok, since it is easy to read new entries from head in further pass.
+// The benefit is that this makes it fast to read only the new entries.
//
void NativeDebugInfoPreFork() {
CHECK(Runtime::Current()->IsZygote());