[vm,dyn_modules] Handle bytecode in LookupHeapObjectCode.
TEST=pkg/vm_service/test/code
pkg/vm_service/test/fetch_all_types
Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try,vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-mac-debug-arm64-try
Change-Id: I4e630911ec836ddcad2cadd338bc59be50827316
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449801
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 9be7318..9d9f4b7 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -19529,6 +19529,39 @@
return zone->PrintToString("[Bytecode] %s", function_name);
}
+BytecodePtr Bytecode::FindBytecode(uword pc) {
+#if defined(DART_DYNAMIC_MODULES)
+ class SlowFindBytecodeVisitor : public ObjectVisitor {
+ public:
+ explicit SlowFindBytecodeVisitor(uword pc)
+ : pc_(pc), result_(Bytecode::null()) {}
+
+ void VisitObject(ObjectPtr obj) {
+ if (!obj->IsBytecode()) return;
+ BytecodePtr bytecode = static_cast<BytecodePtr>(obj);
+ if (PayloadStartOf(bytecode) != pc_) return;
+ ASSERT(result_ == Bytecode::null());
+ result_ = bytecode;
+ }
+
+ BytecodePtr result() const { return result_; }
+
+ private:
+ uword pc_;
+ BytecodePtr result_;
+ };
+
+ HeapIterationScope iteration(Thread::Current());
+ SlowFindBytecodeVisitor visitor(pc);
+ iteration.IterateVMIsolateObjects(&visitor);
+ iteration.IterateOldObjectsNoImagePages(&visitor);
+ return visitor.result();
+#else
+ UNREACHABLE();
+ return Bytecode::null();
+#endif
+}
+
void Bytecode::set_binary(const TypedDataBase& binary) const {
ASSERT(binary.IsNull() || binary.IsExternalOrExternalView());
untag()->set_binary(binary.ptr());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 35a80a1..f0b221e 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -7522,7 +7522,10 @@
public:
uword instructions() const { return untag()->instructions_; }
- uword PayloadStart() const { return instructions(); }
+ static uword PayloadStartOf(BytecodePtr ptr) {
+ return ptr->untag()->instructions_;
+ }
+ uword PayloadStart() const { return PayloadStartOf(ptr()); }
intptr_t Size() const { return untag()->instructions_size_; }
ObjectPoolPtr object_pool() const { return untag()->object_pool(); }
@@ -7628,6 +7631,8 @@
const char* QualifiedName() const;
const char* FullyQualifiedName() const;
+ static BytecodePtr FindBytecode(uword pc);
+
private:
void set_instructions(uword instructions) const {
StoreNonPointer(&untag()->instructions_, instructions);
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 8a819d6..f7c9ff4 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2194,6 +2194,12 @@
if (!code.IsNull()) {
return code.ptr();
}
+#if defined(DART_DYNAMIC_MODULES)
+ const auto& bytecode = Bytecode::Handle(Bytecode::FindBytecode(pc));
+ if (!bytecode.IsNull()) {
+ return bytecode.ptr();
+ }
+#endif
// Not found.
return Object::sentinel().ptr();