Re-enable OSR.

Fixes two bugs:
- Dealing with proxy methods, which the compiler and code cache
  does not handle.
- Dealing with phi types, that may have been speculatively optimized
  but do not hold once jumping to the compiled code.

Change-Id: I7dcd9976ef7b12128fff95d2b7ed3e69cc42e90a
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index d2bf6c0..3fe7861 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -203,6 +203,7 @@
 }
 
 bool JitCompiler::CompileMethod(Thread* self, ArtMethod* method, bool osr) {
+  DCHECK(!method->IsProxyMethod());
   TimingLogger logger("JIT compiler timing logger", true, VLOG_IS_ON(jit));
   const uint64_t start_time = NanoTime();
   StackHandleScope<2> hs(self);
@@ -220,20 +221,17 @@
   bool success = false;
   {
     TimingLogger::ScopedTiming t2("Compiling", &logger);
-    // If we get a request to compile a proxy method, we pass the actual Java method
-    // of that proxy method, as the compiler does not expect a proxy method.
-    ArtMethod* method_to_compile = method->GetInterfaceMethodIfProxy(sizeof(void*));
     JitCodeCache* const code_cache = runtime->GetJit()->GetCodeCache();
-    success = compiler_driver_->GetCompiler()->JitCompile(self, code_cache, method_to_compile, osr);
+    success = compiler_driver_->GetCompiler()->JitCompile(self, code_cache, method, osr);
     if (success && (perf_file_ != nullptr)) {
-      const void* ptr = method_to_compile->GetEntryPointFromQuickCompiledCode();
+      const void* ptr = method->GetEntryPointFromQuickCompiledCode();
       std::ostringstream stream;
       stream << std::hex
              << reinterpret_cast<uintptr_t>(ptr)
              << " "
              << code_cache->GetMemorySizeOfCodePointer(ptr)
              << " "
-             << PrettyMethod(method_to_compile)
+             << PrettyMethod(method)
              << std::endl;
       std::string str = stream.str();
       bool res = perf_file_->WriteFully(str.c_str(), str.size());
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index fa6aae8..3740c40 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -378,7 +378,7 @@
 
   // Run type propagation to get the guard typed, and eventually propagate the
   // type of the receiver.
-  ReferenceTypePropagation rtp_fixup(graph_, handles_);
+  ReferenceTypePropagation rtp_fixup(graph_, handles_, /* is_first_run */ false);
   rtp_fixup.Run();
 
   MaybeRecordStat(kInlinedMonomorphicCall);
@@ -420,6 +420,9 @@
       actual_method = new_method;
     } else if (actual_method != new_method) {
       // Different methods, bailout.
+      VLOG(compiler) << "Call to " << PrettyMethod(resolved_method)
+                     << " from inline cache is not inlined because it resolves"
+                     << " to different methods";
       return false;
     }
   }
@@ -474,7 +477,7 @@
   deoptimize->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
 
   // Run type propagation to get the guard typed.
-  ReferenceTypePropagation rtp_fixup(graph_, handles_);
+  ReferenceTypePropagation rtp_fixup(graph_, handles_, /* is_first_run */ false);
   rtp_fixup.Run();
 
   MaybeRecordStat(kInlinedPolymorphicCall);
@@ -727,7 +730,7 @@
       // dex pc for the associated stack map. 0 is bogus but valid. Bug: 26854537.
       /* dex_pc */ 0);
   if (iget->GetType() == Primitive::kPrimNot) {
-    ReferenceTypePropagation rtp(graph_, handles_);
+    ReferenceTypePropagation rtp(graph_, handles_, /* is_first_run */ false);
     rtp.Visit(iget);
   }
   return iget;
@@ -756,6 +759,7 @@
       /* dex_pc */ 0);
   return iput;
 }
+
 bool HInliner::TryBuildAndInline(ArtMethod* resolved_method,
                                  HInvoke* invoke_instruction,
                                  bool same_dex_file,
@@ -988,12 +992,18 @@
 
       if (current->IsNewInstance() &&
           (current->AsNewInstance()->GetEntrypoint() == kQuickAllocObjectWithAccessCheck)) {
+        VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
+                       << " could not be inlined because it is using an entrypoint"
+                       << " with access checks";
         // Allocation entrypoint does not handle inlined frames.
         return false;
       }
 
       if (current->IsNewArray() &&
           (current->AsNewArray()->GetEntrypoint() == kQuickAllocArrayWithAccessCheck)) {
+        VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
+                       << " could not be inlined because it is using an entrypoint"
+                       << " with access checks";
         // Allocation entrypoint does not handle inlined frames.
         return false;
       }
@@ -1003,6 +1013,9 @@
           current->IsUnresolvedStaticFieldSet() ||
           current->IsUnresolvedInstanceFieldSet()) {
         // Entrypoint for unresolved fields does not handle inlined frames.
+        VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
+                       << " could not be inlined because it is using an unresolved"
+                       << " entrypoint";
         return false;
       }
     }
@@ -1044,13 +1057,13 @@
         if (invoke_rti.IsStrictSupertypeOf(return_rti)
             || (return_rti.IsExact() && !invoke_rti.IsExact())
             || !return_replacement->CanBeNull()) {
-          ReferenceTypePropagation(graph_, handles_).Run();
+          ReferenceTypePropagation(graph_, handles_, /* is_first_run */ false).Run();
         }
       }
     } else if (return_replacement->IsInstanceOf()) {
       if (do_rtp) {
         // Inlining InstanceOf into an If may put a tighter bound on reference types.
-        ReferenceTypePropagation(graph_, handles_).Run();
+        ReferenceTypePropagation(graph_, handles_, /* is_first_run */ false).Run();
       }
     }
   }
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 1224a48..deaa415 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -55,10 +55,12 @@
  public:
   RTPVisitor(HGraph* graph,
              HandleCache* handle_cache,
-             ArenaVector<HInstruction*>* worklist)
+             ArenaVector<HInstruction*>* worklist,
+             bool is_first_run)
     : HGraphDelegateVisitor(graph),
       handle_cache_(handle_cache),
-      worklist_(worklist) {}
+      worklist_(worklist),
+      is_first_run_(is_first_run) {}
 
   void VisitNewInstance(HNewInstance* new_instance) OVERRIDE;
   void VisitLoadClass(HLoadClass* load_class) OVERRIDE;
@@ -86,14 +88,17 @@
  private:
   HandleCache* handle_cache_;
   ArenaVector<HInstruction*>* worklist_;
+  const bool is_first_run_;
 };
 
 ReferenceTypePropagation::ReferenceTypePropagation(HGraph* graph,
                                                    StackHandleScopeCollection* handles,
+                                                   bool is_first_run,
                                                    const char* name)
     : HOptimization(graph, name),
       handle_cache_(handles),
-      worklist_(graph->GetArena()->Adapter(kArenaAllocReferenceTypePropagation)) {
+      worklist_(graph->GetArena()->Adapter(kArenaAllocReferenceTypePropagation)),
+      is_first_run_(is_first_run) {
 }
 
 void ReferenceTypePropagation::ValidateTypes() {
@@ -125,7 +130,7 @@
 }
 
 void ReferenceTypePropagation::Visit(HInstruction* instruction) {
-  RTPVisitor visitor(graph_, &handle_cache_, &worklist_);
+  RTPVisitor visitor(graph_, &handle_cache_, &worklist_, is_first_run_);
   instruction->Accept(&visitor);
 }
 
@@ -144,7 +149,7 @@
 }
 
 void ReferenceTypePropagation::VisitBasicBlock(HBasicBlock* block) {
-  RTPVisitor visitor(graph_, &handle_cache_, &worklist_);
+  RTPVisitor visitor(graph_, &handle_cache_, &worklist_, is_first_run_);
   // Handle Phis first as there might be instructions in the same block who depend on them.
   for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
     VisitPhi(it.Current()->AsPhi());
@@ -620,6 +625,7 @@
   DCHECK_EQ(bound_type->InputAt(0), check_cast->InputAt(0));
 
   if (class_rti.IsValid()) {
+    DCHECK(is_first_run_);
     // This is the first run of RTP and class is resolved.
     bound_type->SetUpperBound(class_rti, /* CheckCast succeeds for nulls. */ true);
   } else {
@@ -636,6 +642,12 @@
   }
 
   if (phi->GetBlock()->IsLoopHeader()) {
+    if (!is_first_run_ && graph_->IsCompilingOsr()) {
+      // Don't update the type of a loop phi when compiling OSR: we may have done
+      // speculative optimizations dominating that phi, that do not hold at the
+      // point the interpreter jumps to that loop header.
+      return;
+    }
     ScopedObjectAccess soa(Thread::Current());
     // Set the initial type for the phi. Use the non back edge input for reaching
     // a fixed point faster.
diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h
index a7f10a6..028a6fc 100644
--- a/compiler/optimizing/reference_type_propagation.h
+++ b/compiler/optimizing/reference_type_propagation.h
@@ -33,6 +33,7 @@
  public:
   ReferenceTypePropagation(HGraph* graph,
                            StackHandleScopeCollection* handles,
+                           bool is_first_run,
                            const char* name = kReferenceTypePropagationPassName);
 
   // Visit a single instruction.
@@ -93,6 +94,8 @@
 
   ArenaVector<HInstruction*> worklist_;
 
+  // Whether this reference type propagation is the first run we are doing.
+  const bool is_first_run_;
 
   static constexpr size_t kDefaultWorklistSize = 8;
 
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index 165d09d..c08e5dd 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -483,7 +483,7 @@
 
   // 6) Compute type of reference type instructions. The pass assumes that
   // NullConstant has been fixed up.
-  ReferenceTypePropagation(GetGraph(), handles_).Run();
+  ReferenceTypePropagation(GetGraph(), handles_, /* is_first_run */ true).Run();
 
   // 7) Step 1) duplicated ArrayGet instructions with ambiguous type (int/float
   // or long/double) and marked ArraySets with ambiguous input type. Now that RTP