Merge "Optimizing: Tag basic block allocations with their source."
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index ad2feeb..acce68b 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -333,7 +333,7 @@
     ifneq ($(NATIVE_COVERAGE),true)
       art_host_non_debug_cflags += -Wframe-larger-than=2700
       ifdef SANITIZE_TARGET
-        art_target_non_debug_cflags += -Wframe-larger-than=5450
+        art_target_non_debug_cflags += -Wframe-larger-than=6400
       else
         art_target_non_debug_cflags += -Wframe-larger-than=1728
       endif
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index bb780dc..f5c4498 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -239,7 +239,10 @@
         InitLocationsBaseline(current);
       }
       DCHECK(CheckTypeConsistency(current));
+      uintptr_t native_pc_begin = GetAssembler()->CodeSize();
       current->Accept(instruction_visitor);
+      uintptr_t native_pc_end = GetAssembler()->CodeSize();
+      RecordNativeDebugInfo(current->GetDexPc(), native_pc_begin, native_pc_end);
     }
   }
 
@@ -604,15 +607,6 @@
   }
 }
 
-void CodeGenerator::BuildSourceMap(DefaultSrcMap* src_map) const {
-  for (size_t i = 0, num = stack_map_stream_.GetNumberOfStackMaps(); i != num; ++i) {
-    const StackMapStream::StackMapEntry& stack_map_entry = stack_map_stream_.GetStackMap(i);
-    uint32_t pc2dex_offset = stack_map_entry.native_pc_offset;
-    int32_t pc2dex_dalvik_offset = stack_map_entry.dex_pc;
-    src_map->push_back(SrcMapElem({pc2dex_offset, pc2dex_dalvik_offset}));
-  }
-}
-
 void CodeGenerator::BuildMappingTable(ArenaVector<uint8_t>* data) const {
   uint32_t pc2dex_data_size = 0u;
   uint32_t pc2dex_entries = stack_map_stream_.GetNumberOfStackMaps();
@@ -728,6 +722,15 @@
   stack_map_stream_.FillIn(region);
 }
 
+void CodeGenerator::RecordNativeDebugInfo(uint32_t dex_pc,
+                                          uintptr_t native_pc_begin,
+                                          uintptr_t native_pc_end) {
+  if (src_map_ != nullptr && dex_pc != kNoDexPc && native_pc_begin != native_pc_end) {
+    src_map_->push_back(SrcMapElem({static_cast<uint32_t>(native_pc_begin),
+                                    static_cast<int32_t>(dex_pc)}));
+  }
+}
+
 void CodeGenerator::RecordPcInfo(HInstruction* instruction,
                                  uint32_t dex_pc,
                                  SlowPathCode* slow_path) {
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 754b5ec..b3c4d72 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -229,7 +229,11 @@
     return (fpu_callee_save_mask_ & (1 << reg)) != 0;
   }
 
+  // Record native to dex mapping for a suspend point.  Required by runtime.
   void RecordPcInfo(HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path = nullptr);
+  // Record additional native to dex mappings for native debugging/profiling tools.
+  void RecordNativeDebugInfo(uint32_t dex_pc, uintptr_t native_pc_begin, uintptr_t native_pc_end);
+
   bool CanMoveNullCheckToUser(HNullCheck* null_check);
   void MaybeRecordImplicitNullCheck(HInstruction* instruction);
 
@@ -237,7 +241,8 @@
     slow_paths_.Add(slow_path);
   }
 
-  void BuildSourceMap(DefaultSrcMap* src_map) const;
+  void SetSrcMap(DefaultSrcMap* src_map) { src_map_ = src_map; }
+
   void BuildMappingTable(ArenaVector<uint8_t>* vector) const;
   void BuildVMapTable(ArenaVector<uint8_t>* vector) const;
   void BuildNativeGCMap(
@@ -395,6 +400,7 @@
         disasm_info_(nullptr),
         graph_(graph),
         compiler_options_(compiler_options),
+        src_map_(nullptr),
         slow_paths_(graph->GetArena(), 8),
         current_block_index_(0),
         is_leaf_(true),
@@ -489,6 +495,8 @@
   HGraph* const graph_;
   const CompilerOptions& compiler_options_;
 
+  // Native to dex_pc map used for native debugging/profiling tools.
+  DefaultSrcMap* src_map_;
   GrowableArray<SlowPathCode*> slow_paths_;
 
   // The current block index in `block_order_` of the block
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 768658e..3e603fd 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1740,9 +1740,7 @@
 
   virtual bool NeedsEnvironment() const { return false; }
   virtual uint32_t GetDexPc() const {
-    LOG(FATAL) << "GetDexPc() cannot be called on an instruction that"
-                  " does not need an environment";
-    UNREACHABLE();
+    return kNoDexPc;
   }
   virtual bool IsControlFlow() const { return false; }
 
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 898b656..8e48f6d 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -558,15 +558,14 @@
 
   ArenaAllocator* arena = graph->GetArena();
   CodeVectorAllocator allocator(arena);
+  DefaultSrcMap src_mapping_table;
+  codegen->SetSrcMap(compiler_driver->GetCompilerOptions().GetGenerateDebugInfo()
+                         ? &src_mapping_table
+                         : nullptr);
   codegen->CompileOptimized(&allocator);
 
   ArenaVector<LinkerPatch> linker_patches = EmitAndSortLinkerPatches(codegen);
 
-  DefaultSrcMap src_mapping_table;
-  if (compiler_driver->GetCompilerOptions().GetGenerateDebugInfo()) {
-    codegen->BuildSourceMap(&src_mapping_table);
-  }
-
   ArenaVector<uint8_t> stack_map(arena->Adapter(kArenaAllocStackMaps));
   codegen->BuildStackMaps(&stack_map);
 
@@ -601,16 +600,16 @@
     PassObserver* pass_observer) const {
   ArenaAllocator* arena = codegen->GetGraph()->GetArena();
   CodeVectorAllocator allocator(arena);
+  DefaultSrcMap src_mapping_table;
+  codegen->SetSrcMap(compiler_driver->GetCompilerOptions().GetGenerateDebugInfo()
+                         ? &src_mapping_table
+                         : nullptr);
   codegen->CompileBaseline(&allocator);
 
   ArenaVector<LinkerPatch> linker_patches = EmitAndSortLinkerPatches(codegen);
 
   ArenaVector<uint8_t> mapping_table(arena->Adapter(kArenaAllocBaselineMaps));
   codegen->BuildMappingTable(&mapping_table);
-  DefaultSrcMap src_mapping_table;
-  if (compiler_driver->GetCompilerOptions().GetGenerateDebugInfo()) {
-    codegen->BuildSourceMap(&src_mapping_table);
-  }
   ArenaVector<uint8_t> vmap_table(arena->Adapter(kArenaAllocBaselineMaps));
   codegen->BuildVMapTable(&vmap_table);
   ArenaVector<uint8_t> gc_map(arena->Adapter(kArenaAllocBaselineMaps));
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 29413bf..5526883 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -1787,8 +1787,15 @@
             klass->GetDexFile(), index, klass.Get());
         set_object = true;
         if (element_object == nullptr) {
-          // TODO: Put a TypeNotFoundExceptionProxy instead of throwing here.
-          return false;
+          CHECK(self->IsExceptionPending());
+          if (result_style == kAllObjects) {
+            const char* msg = StringByTypeIdx(index);
+            self->ThrowNewWrappedException("Ljava/lang/TypeNotPresentException;", msg);
+            element_object = self->GetException();
+            self->ClearException();
+          } else {
+            return false;
+          }
         }
       }
       break;
diff --git a/runtime/length_prefixed_array.h b/runtime/length_prefixed_array.h
index d9bc656..0ff6d7a 100644
--- a/runtime/length_prefixed_array.h
+++ b/runtime/length_prefixed_array.h
@@ -19,7 +19,6 @@
 
 #include <stddef.h>  // for offsetof()
 
-#include "linear_alloc.h"
 #include "stride_iterator.h"
 #include "base/bit_utils.h"
 #include "base/casts.h"
diff --git a/test/005-annotations/expected.txt b/test/005-annotations/expected.txt
index 36b3868..e1c3dad 100644
--- a/test/005-annotations/expected.txt
+++ b/test/005-annotations/expected.txt
@@ -101,3 +101,10 @@
 Package declared annotations:
       @android.test.anno.AnnoSimplePackage()
         interface android.test.anno.AnnoSimplePackage
+
+Inner Classes:
+Canonical:android.test.anno.ClassWithInnerClasses.InnerClass Simple:InnerClass
+Canonical:null Simple:
+
+Get annotation with missing class should not throw
+Got expected TypeNotPresentException
diff --git a/test/005-annotations/src/android/test/anno/AnnoMissingClass.java b/test/005-annotations/src/android/test/anno/AnnoMissingClass.java
new file mode 100644
index 0000000..c32e9a2
--- /dev/null
+++ b/test/005-annotations/src/android/test/anno/AnnoMissingClass.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.test.anno;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AnnoMissingClass {
+    Class value();
+}
diff --git a/test/005-annotations/src/android/test/anno/ClassWithInnerClasses.java b/test/005-annotations/src/android/test/anno/ClassWithInnerClasses.java
new file mode 100644
index 0000000..e151f1a
--- /dev/null
+++ b/test/005-annotations/src/android/test/anno/ClassWithInnerClasses.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.test.anno;
+
+public class ClassWithInnerClasses {
+  public class InnerClass {
+    public String toString() {
+      return "Canonical:" + getClass().getCanonicalName() + " Simple:" + getClass().getSimpleName();
+    }
+  }
+  Object anonymousClass = new Object() {
+    public String toString() {
+      return "Canonical:" + getClass().getCanonicalName() + " Simple:" + getClass().getSimpleName();
+    }
+  };
+
+  public void print() {
+    System.out.println(new InnerClass());
+    System.out.println(anonymousClass);
+  }
+}
diff --git a/test/005-annotations/src/android/test/anno/ClassWithMissingAnnotation.java b/test/005-annotations/src/android/test/anno/ClassWithMissingAnnotation.java
new file mode 100644
index 0000000..8cfdd8c
--- /dev/null
+++ b/test/005-annotations/src/android/test/anno/ClassWithMissingAnnotation.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.test.anno;
+
+// Add annotation for missing type to cause TypeNotPresentException.
+@AnnoMissingClass(MissingAnnotation.class)
+public class ClassWithMissingAnnotation {
+}
diff --git a/test/005-annotations/src/android/test/anno/TestAnnotations.java b/test/005-annotations/src/android/test/anno/TestAnnotations.java
index 1deff33..7b74a73 100644
--- a/test/005-annotations/src/android/test/anno/TestAnnotations.java
+++ b/test/005-annotations/src/android/test/anno/TestAnnotations.java
@@ -180,5 +180,24 @@
         printAnnotationArray("    ", TestAnnotations.class.getPackage().getAnnotations());
         System.out.println("Package declared annotations:");
         printAnnotationArray("    ", TestAnnotations.class.getPackage().getDeclaredAnnotations());
+
+        System.out.println();
+
+        // Test inner classes.
+        System.out.println("Inner Classes:");
+        new ClassWithInnerClasses().print();
+
+        System.out.println();
+
+        // Test TypeNotPresentException.
+        try {
+            AnnoMissingClass missingAnno =
+                ClassWithMissingAnnotation.class.getAnnotation(AnnoMissingClass.class);
+            System.out.println("Get annotation with missing class should not throw");
+            System.out.println(missingAnno.value());
+            System.out.println("Getting value of missing annotaton should have thrown");
+        } catch (TypeNotPresentException expected) {
+            System.out.println("Got expected TypeNotPresentException");
+        }
     }
 }