[vm, compiler] Fix annotating pool references in gen_snapshot.

This was broken by the move to the global object pool.

TEST=--disassemble
Change-Id: I2cbff1e2fa1a56d8d4d98d447a5726c0764e1a0e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244460
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/instructions.cc b/runtime/vm/instructions.cc
new file mode 100644
index 0000000..b265420
--- /dev/null
+++ b/runtime/vm/instructions.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/instructions.h"
+
+#include "vm/object.h"
+#if defined(DART_PRECOMPILER)
+#include "vm/compiler/aot/precompiler.h"
+#endif
+
+namespace dart {
+
+bool ObjectAtPoolIndex(const Code& code, intptr_t index, Object* obj) {
+#if defined(DART_PRECOMPILER)
+  if (FLAG_precompiled_mode) {
+    Precompiler* precompiler = Precompiler::Instance();
+    if (precompiler != nullptr) {
+      compiler::ObjectPoolBuilder* pool =
+          precompiler->global_object_pool_builder();
+      if (index < pool->CurrentLength()) {
+        compiler::ObjectPoolBuilderEntry& entry = pool->EntryAt(index);
+        if (entry.type() == compiler::ObjectPoolBuilderEntry::kTaggedObject) {
+          *obj = entry.obj_->ptr();
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+#endif
+  const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
+  if (!pool.IsNull() && (index < pool.Length()) &&
+      (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
+    *obj = pool.ObjectAt(index);
+    return true;
+  }
+  return false;
+}
+
+}  // namespace dart
diff --git a/runtime/vm/instructions.h b/runtime/vm/instructions.h
index 5dbe5d6..3ddb87d 100644
--- a/runtime/vm/instructions.h
+++ b/runtime/vm/instructions.h
@@ -26,6 +26,7 @@
 class Object;
 class Code;
 
+bool ObjectAtPoolIndex(const Code& code, intptr_t index, Object* obj);
 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj);
 
 #if !defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index ecacd45..9a3f92f 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -197,12 +197,7 @@
   Register dst;
   if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
     intptr_t index = ObjectPool::IndexFromOffset(offset);
-    const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
-    if (!pool.IsNull() && (index < pool.Length()) &&
-        (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
-      *obj = pool.ObjectAt(index);
-      return true;
-    }
+    return ObjectAtPoolIndex(code, index, obj);
   } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
     return Thread::ObjectAtOffset(offset, obj);
   }
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 0c64963..d78c779 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -304,17 +304,27 @@
       // PP is untagged on ARM64.
       ASSERT(Utils::IsAligned(offset, 8));
       intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
-      const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
-      if (!pool.IsNull() && (index < pool.Length()) &&
-          (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
-        *obj = pool.ObjectAt(index);
-        return true;
-      }
+      return ObjectAtPoolIndex(code, index, obj);
     } else if (instr->RnField() == THR) {
       return Thread::ObjectAtOffset(offset, obj);
     }
+    if (instr->RnField() == instr->RtField()) {
+      Instr* add = Instr::At(pc - Instr::kInstrSize);
+      if (add->IsAddSubImmOp() && add->SFField() && (instr->Bit(22) == 1) &&
+          (add->RdField() == add->RtField())) {
+        offset = (add->Imm12Field() << 12) + offset;
+        if (add->RnField() == PP) {
+          // PP is untagged on ARM64.
+          ASSERT(Utils::IsAligned(offset, 8));
+          intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
+          return ObjectAtPoolIndex(code, index, obj);
+        } else if (add->RnField() == THR) {
+          return Thread::ObjectAtOffset(offset, obj);
+        }
+      }
+    }
+    // TODO(rmacnak): Loads with offsets beyond 24 bits.
   }
-  // TODO(rmacnak): Loads with offsets beyond 12 bits.
 
   if (instr->IsAddSubImmOp() && instr->SFField() &&
       (instr->RnField() == NULL_REG)) {
diff --git a/runtime/vm/instructions_riscv.cc b/runtime/vm/instructions_riscv.cc
index cabe480..3a7d2a8 100644
--- a/runtime/vm/instructions_riscv.cc
+++ b/runtime/vm/instructions_riscv.cc
@@ -231,12 +231,7 @@
           return false;  // Being used as argument register A5.
         }
         intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
-        const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
-        if (!pool.IsNull() && (index < pool.Length()) &&
-            (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
-          *obj = pool.ObjectAt(index);
-          return true;
-        }
+        return ObjectAtPoolIndex(code, index, obj);
       } else if (instr.rs1p() == THR) {
         return Thread::ObjectAtOffset(offset, obj);
       }
@@ -255,12 +250,7 @@
           return false;  // Being used as argument register A5.
         }
         intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
-        const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
-        if (!pool.IsNull() && (index < pool.Length()) &&
-            (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
-          *obj = pool.ObjectAt(index);
-          return true;
-        }
+        return ObjectAtPoolIndex(code, index, obj);
       } else if (instr.rs1() == THR) {
         return Thread::ObjectAtOffset(offset, obj);
       }
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 30d7ed7..e2a6403 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -59,21 +59,11 @@
     if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) {  // movq, cmpq
       if ((bytes[2] & 0xc7) == (0x80 | (PP & 7))) {  // [r15+disp32]
         intptr_t index = IndexFromPPLoadDisp32(pc + 3);
-        const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
-        if (!pool.IsNull() && (index < pool.Length()) &&
-            (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
-          *obj = pool.ObjectAt(index);
-          return true;
-        }
+        return ObjectAtPoolIndex(code, index, obj);
       }
       if ((bytes[2] & 0xc7) == (0x40 | (PP & 7))) {  // [r15+disp8]
         intptr_t index = IndexFromPPLoadDisp8(pc + 3);
-        const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
-        if (!pool.IsNull() && (index < pool.Length()) &&
-            (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
-          *obj = pool.ObjectAt(index);
-          return true;
-        }
+        return ObjectAtPoolIndex(code, index, obj);
       }
     }
   }
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 0a2264a..b7a9c01 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -126,6 +126,7 @@
   "hash_table.h",
   "image_snapshot.cc",
   "image_snapshot.h",
+  "instructions.cc",
   "instructions.h",
   "instructions_arm.cc",
   "instructions_arm.h",