ART: Refactor UnstartedRuntime for testing
Expose the UnstartedRuntime implementation functions as private static
methods of a class. Add a gtest that can invoke these functions. Add
sample tests for String and Memory.
Bug: 21173514
(cherry picked from commit 799681b176ad25437ce2849639f54f610dcbf684)
Change-Id: Ib5bde6347fafaf7607c642542ea7d5938ff4b1df
diff --git a/runtime/interpreter/unstarted_runtime.h b/runtime/interpreter/unstarted_runtime.h
index 2d7d380..a361af0 100644
--- a/runtime/interpreter/unstarted_runtime.h
+++ b/runtime/interpreter/unstarted_runtime.h
@@ -36,16 +36,69 @@
namespace interpreter {
-void UnstartedRuntimeInitialize();
+// Support for an unstarted runtime. These are special handwritten implementations for select
+// libcore native and non-native methods so we can compile-time initialize classes in the boot
+// image.
+//
+// While it would technically be OK to only expose the public functions, a class was chosen to
+// wrap this so the actual implementations are exposed for testing. This is also why the private
+// methods are not documented here - they are not intended to be used directly except in
+// testing.
-void UnstartedRuntimeInvoke(Thread* self, const DexFile::CodeItem* code_item,
- ShadowFrame* shadow_frame,
- JValue* result, size_t arg_offset)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+class UnstartedRuntime {
+ public:
+ static void Initialize();
-void UnstartedRuntimeJni(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
- uint32_t* args, JValue* result)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ static void Invoke(Thread* self,
+ const DexFile::CodeItem* code_item,
+ ShadowFrame* shadow_frame,
+ JValue* result,
+ size_t arg_offset)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static void Jni(Thread* self,
+ mirror::ArtMethod* method,
+ mirror::Object* receiver,
+ uint32_t* args,
+ JValue* result)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+ // Methods that intercept available libcore implementations.
+#define UNSTARTED_DIRECT(ShortName, SigIgnored) \
+ static void Unstarted ## ShortName(Thread* self, \
+ ShadowFrame* shadow_frame, \
+ JValue* result, \
+ size_t arg_offset) \
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#include "unstarted_runtime_list.h"
+ UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
+#undef UNSTARTED_RUNTIME_DIRECT_LIST
+#undef UNSTARTED_RUNTIME_JNI_LIST
+#undef UNSTARTED_DIRECT
+
+ // Methods that are native.
+#define UNSTARTED_JNI(ShortName, SigIgnored) \
+ static void UnstartedJNI ## ShortName(Thread* self, \
+ mirror::ArtMethod* method, \
+ mirror::Object* receiver, \
+ uint32_t* args, \
+ JValue* result) \
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#include "unstarted_runtime_list.h"
+ UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
+#undef UNSTARTED_RUNTIME_DIRECT_LIST
+#undef UNSTARTED_RUNTIME_JNI_LIST
+#undef UNSTARTED_JNI
+
+ static void InitializeInvokeHandlers();
+ static void InitializeJNIHandlers();
+
+ friend class UnstartedRuntimeTest;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_COPY_AND_ASSIGN(UnstartedRuntime);
+};
} // namespace interpreter
} // namespace art