Restore back pointer from Instructions to Code

Fixes #24449

R=rmacnak@google.com

Review URL: https://codereview.chromium.org//1377583005 .
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 9311f72..11cd82b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -13029,6 +13029,7 @@
   INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize());
   INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize());
 
+  instrs.set_code(code.raw());
   // Copy the instructions into the instruction area and apply all fixups.
   // Embedded pointers are still in handles at this point.
   MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()),
@@ -13110,8 +13111,13 @@
 
 
 // Check if object matches find condition.
-bool Code::FindRawCodeVisitor::FindObject(RawObject* obj) const {
-  return RawCode::ContainsPC(obj, pc_);
+bool Code::FindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
+  uword tags = raw_obj->ptr()->tags_;
+  if (RawObject::ClassIdTag::decode(tags) == kInstructionsCid) {
+    RawInstructions* raw_insts = reinterpret_cast<RawInstructions*>(raw_obj);
+    return RawInstructions::ContainsPC(raw_insts, pc_);
+  }
+  return false;
 }
 
 
@@ -13119,13 +13125,18 @@
   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
   NoSafepointScope no_safepoint;
   FindRawCodeVisitor visitor(pc);
-  RawObject* instr;
+  RawInstructions* instr;
+  if (Dart::IsRunningPrecompiledCode()) {
+    // TODO(johnmccutchan): Make code lookup work when running precompiled.
+    UNIMPLEMENTED();
+    return Code::null();
+  }
   if (isolate->heap() == NULL) {
     return Code::null();
   }
-  instr = isolate->heap()->FindOldObject(&visitor);
-  if (instr != Code::null()) {
-    return static_cast<RawCode*>(instr);
+  instr = isolate->heap()->FindObjectInCodeSpace(&visitor);
+  if (instr != Instructions::null()) {
+    return Instructions::Handle(instr).code();
   }
   return Code::null();
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 8e4b24e..934697e 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3714,6 +3714,13 @@
  public:
   intptr_t size() const { return raw_ptr()->size_; }  // Excludes HeaderSize().
 
+  RawCode* code() const {
+    // This should only be accessed when jitting.
+    // TODO(johnmccutchan): Remove code back pointer.
+    ASSERT(!Dart::IsRunningPrecompiledCode());
+    return raw_ptr()->code_;
+  }
+
   uword EntryPoint() const {
     return reinterpret_cast<uword>(raw_ptr()) + HeaderSize();
   }
@@ -3752,6 +3759,10 @@
     StoreNonPointer(&raw_ptr()->size_, size);
   }
 
+  void set_code(RawCode* code) const {
+    StorePointer(&raw_ptr()->code_, code);
+  }
+
   // New is a private method as RawInstruction and RawCode objects should
   // only be created using the Code::FinalizeCode method. This method creates
   // the RawInstruction and RawCode objects, sets up the pointer offsets
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 74013a6..47fa009 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -556,6 +556,9 @@
 intptr_t RawInstructions::VisitInstructionsPointers(
     RawInstructions* raw_obj, ObjectPointerVisitor* visitor) {
   RawInstructions* obj = raw_obj->ptr();
+  if (!Dart::IsRunningPrecompiledCode()) {
+    visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  }
   return Instructions::InstanceSize(obj->size_);
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 925f56d..b6f14f0 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1084,6 +1084,14 @@
 class RawInstructions : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Instructions);
 
+  RawObject** from() {
+    return reinterpret_cast<RawObject**>(&ptr()->code_);
+  }
+  RawCode* code_;
+  RawObject** to() {
+    return reinterpret_cast<RawObject**>(&ptr()->code_);
+  }
+
   int32_t size_;
 
   // Variable length data follows here.