Revert "Revert "Add intrinsic for Reference.get()""

This reverts commit a9b870b73a155ce70c867d5b3f9758fab0b45f07.

Change-Id: Ic2a9b47f2b911bef4b764d10bc33cf000e4b4211
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5180e34..a957eb6 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -254,6 +254,13 @@
   java_lang_String->SetObjectSize(sizeof(mirror::String));
   java_lang_String->SetStatus(mirror::Class::kStatusResolved, self);
 
+  // Setup Reference.
+  Handle<mirror::Class> java_lang_ref_Reference(
+      hs.NewHandle(AllocClass(self, java_lang_Class.Get(), sizeof(mirror::ReferenceClass))));
+  mirror::Reference::SetClass(down_cast<mirror::ReferenceClass*>(java_lang_ref_Reference.Get()));
+  java_lang_ref_Reference->SetObjectSize(sizeof(mirror::Reference));
+  java_lang_ref_Reference->SetStatus(mirror::Class::kStatusResolved, self);
+
   // Create storage for root classes, save away our work so far (requires descriptors).
   class_roots_ = mirror::ObjectArray<mirror::Class>::Alloc(self, object_array_class.Get(),
                                                            kClassRootsMax);
@@ -264,6 +271,7 @@
   SetClassRoot(kObjectArrayClass, object_array_class.Get());
   SetClassRoot(kCharArrayClass, char_array_class.Get());
   SetClassRoot(kJavaLangString, java_lang_String.Get());
+  SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference.Get());
 
   // Setup the primitive type classes.
   SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
@@ -452,8 +460,12 @@
   SetClassRoot(kJavaLangReflectProxy, java_lang_reflect_Proxy);
 
   // java.lang.ref classes need to be specially flagged, but otherwise are normal classes
-  mirror::Class* java_lang_ref_Reference = FindSystemClass(self, "Ljava/lang/ref/Reference;");
-  SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference);
+  // finish initializing Reference class
+  java_lang_ref_Reference->SetStatus(mirror::Class::kStatusNotReady, self);
+  mirror::Class* Reference_class = FindSystemClass(self, "Ljava/lang/ref/Reference;");
+  CHECK_EQ(java_lang_ref_Reference.Get(), Reference_class);
+  CHECK_EQ(java_lang_ref_Reference->GetObjectSize(), sizeof(mirror::Reference));
+  CHECK_EQ(java_lang_ref_Reference->GetClassSize(), sizeof(mirror::ReferenceClass));
   mirror::Class* java_lang_ref_FinalizerReference =
       FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;");
   java_lang_ref_FinalizerReference->SetAccessFlags(
@@ -538,6 +550,9 @@
 
   CHECK(array_iftable_ != NULL);
 
+  // disable slow path for reference gets
+  mirror::Reference::GetJavaLangRefReference()->Init();
+
   // disable the slow paths in FindClass and CreatePrimitiveClass now
   // that Object, Class, and Object[] are setup
   init_done_ = true;
@@ -1220,6 +1235,8 @@
   array_iftable_ = GetClassRoot(kObjectArrayClass)->GetIfTable();
   DCHECK(array_iftable_ == GetClassRoot(kBooleanArrayClass)->GetIfTable());
   // String class root was set above
+  mirror::Reference::SetClass(down_cast<mirror::ReferenceClass*>(GetClassRoot(
+      kJavaLangRefReference)));
   mirror::ArtField::SetClass(GetClassRoot(kJavaLangReflectArtField));
   mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
   mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
@@ -1343,6 +1360,7 @@
 ClassLinker::~ClassLinker() {
   mirror::Class::ResetClass();
   mirror::String::ResetClass();
+  mirror::Reference::ResetClass();
   mirror::ArtField::ResetClass();
   mirror::ArtMethod::ResetClass();
   mirror::BooleanArray::ResetArrayClass();
@@ -1587,6 +1605,8 @@
       klass.Assign(GetClassRoot(kJavaLangClass));
     } else if (strcmp(descriptor, "Ljava/lang/String;") == 0) {
       klass.Assign(GetClassRoot(kJavaLangString));
+    } else if (strcmp(descriptor, "Ljava/lang/ref/Reference;") == 0) {
+      klass.Assign(GetClassRoot(kJavaLangRefReference));
     } else if (strcmp(descriptor, "Ljava/lang/DexCache;") == 0) {
       klass.Assign(GetClassRoot(kJavaLangDexCache));
     } else if (strcmp(descriptor, "Ljava/lang/reflect/ArtField;") == 0) {