Static and direct resolution stub.

Ensure that invoke static and direct go through a stub that causes
resolution and initialization.

Change-Id: I872900560322817d8f4378b04ac410d9ea0b3b17
diff --git a/src/runtime.cc b/src/runtime.cc
index a874464..231c010 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -42,6 +42,8 @@
       exit_(NULL),
       abort_(NULL),
       stats_enabled_(false) {
+  resolution_stub_array_[0] = NULL;
+  resolution_stub_array_[1] = NULL;
 }
 
 Runtime::~Runtime() {
@@ -550,6 +552,8 @@
   thread_list_->VisitRoots(visitor, arg);
   visitor(jni_stub_array_, arg);
   visitor(abstract_method_error_stub_array_, arg);
+  visitor(resolution_stub_array_[0], arg);
+  visitor(resolution_stub_array_[1], arg);
   visitor(callee_save_method_, arg);
 
   //(*visitor)(&gDvm.outOfMemoryObj, 0, ROOT_VM_INTERNAL, arg);
@@ -588,6 +592,22 @@
   abstract_method_error_stub_array_ = abstract_method_error_stub_array;
 }
 
+bool Runtime::HasResolutionStubArray(bool is_static) const {
+  return resolution_stub_array_[is_static ? 1 : 0] != NULL;
+}
+
+ByteArray* Runtime::GetResolutionStubArray(bool is_static) const {
+  CHECK(HasResolutionStubArray(is_static));
+  return resolution_stub_array_[is_static ? 1 : 0];
+}
+
+void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, bool is_static) {
+  CHECK(resolution_stub_array != NULL);
+  CHECK(!HasResolutionStubArray(is_static) ||
+        resolution_stub_array_[is_static ? 1 : 0] == resolution_stub_array);
+  resolution_stub_array_[is_static ? 1 : 0] = resolution_stub_array;
+}
+
 Method* Runtime::CreateCalleeSaveMethod(InstructionSet insns) {
   Class* method_class = Method::GetMethodClass();
   Method* method = down_cast<Method*>(method_class->AllocObject());