ART: Refactor unstarted runtime
Refactor and clean up unstarted runtime.
Bug: 19542228
Change-Id: Ib3e4b3517e06e8242d4fed32ca59419fef553a47
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 9d988e9..686b518 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -19,116 +19,13 @@
#include <limits>
#include "mirror/string-inl.h"
+#include "scoped_thread_state_change.h"
+#include "ScopedLocalRef.h"
+#include "unstarted_runtime.h"
namespace art {
namespace interpreter {
-// Hand select a number of methods to be run in a not yet started runtime without using JNI.
-static void UnstartedRuntimeJni(Thread* self, ArtMethod* method,
- Object* receiver, uint32_t* args, JValue* result)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string name(PrettyMethod(method));
- if (name == "java.lang.Object dalvik.system.VMRuntime.newUnpaddedArray(java.lang.Class, int)") {
- int32_t length = args[1];
- DCHECK_GE(length, 0);
- mirror::Class* element_class = reinterpret_cast<Object*>(args[0])->AsClass();
- Runtime* runtime = Runtime::Current();
- mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class);
- DCHECK(array_class != nullptr);
- gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
- result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length,
- array_class->GetComponentSizeShift(), allocator));
- } else if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") {
- result->SetL(NULL);
- } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") {
- NthCallerVisitor visitor(self, 3);
- visitor.WalkStack();
- result->SetL(visitor.caller->GetDeclaringClass());
- } else if (name == "double java.lang.Math.log(double)") {
- JValue value;
- value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
- result->SetD(log(value.GetD()));
- } else if (name == "java.lang.String java.lang.Class.getNameNative()") {
- StackHandleScope<1> hs(self);
- result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
- } else if (name == "int java.lang.Float.floatToRawIntBits(float)") {
- result->SetI(args[0]);
- } else if (name == "float java.lang.Float.intBitsToFloat(int)") {
- result->SetI(args[0]);
- } else if (name == "double java.lang.Math.exp(double)") {
- JValue value;
- value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
- result->SetD(exp(value.GetD()));
- } else if (name == "java.lang.Object java.lang.Object.internalClone()") {
- result->SetL(receiver->Clone(self));
- } else if (name == "void java.lang.Object.notifyAll()") {
- receiver->NotifyAll(self);
- } else if (name == "int java.lang.String.compareTo(java.lang.String)") {
- String* rhs = reinterpret_cast<Object*>(args[0])->AsString();
- CHECK(rhs != NULL);
- result->SetI(receiver->AsString()->CompareTo(rhs));
- } else if (name == "java.lang.String java.lang.String.intern()") {
- result->SetL(receiver->AsString()->Intern());
- } else if (name == "int java.lang.String.fastIndexOf(int, int)") {
- result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
- } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") {
- StackHandleScope<2> hs(self);
- auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
- auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
- result->SetL(Array::CreateMultiArray(self, h_class, h_dimensions));
- } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") {
- ScopedObjectAccessUnchecked soa(self);
- if (Runtime::Current()->IsActiveTransaction()) {
- result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<true>(soa)));
- } else {
- result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<false>(soa)));
- }
- } else if (name == "int java.lang.System.identityHashCode(java.lang.Object)") {
- mirror::Object* obj = reinterpret_cast<Object*>(args[0]);
- result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
- } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") {
- result->SetZ(JNI_TRUE);
- } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
- Object* obj = reinterpret_cast<Object*>(args[0]);
- jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
- jint expectedValue = args[3];
- jint newValue = args[4];
- bool success;
- if (Runtime::Current()->IsActiveTransaction()) {
- success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
- expectedValue, newValue);
- } else {
- success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
- expectedValue, newValue);
- }
- result->SetZ(success ? JNI_TRUE : JNI_FALSE);
- } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") {
- Object* obj = reinterpret_cast<Object*>(args[0]);
- jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
- Object* newValue = reinterpret_cast<Object*>(args[3]);
- if (Runtime::Current()->IsActiveTransaction()) {
- obj->SetFieldObject<true>(MemberOffset(offset), newValue);
- } else {
- obj->SetFieldObject<false>(MemberOffset(offset), newValue);
- }
- } else if (name == "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)") {
- mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass();
- Primitive::Type primitive_type = component->GetPrimitiveType();
- result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
- } else if (name == "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)") {
- mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass();
- Primitive::Type primitive_type = component->GetPrimitiveType();
- result->SetI(Primitive::ComponentSize(primitive_type));
- } else if (Runtime::Current()->IsActiveTransaction()) {
- AbortTransaction(self, "Attempt to invoke native method in non-started runtime: %s",
- name.c_str());
-
- } else {
- LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
- "non-transactional runtime";
- }
-}
-
static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty,
Object* receiver, uint32_t* args, JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {