Rewrite method matching in UnstartedRuntime.
Use the `ArtMethod*` as the key in the maps to avoid
the `PrettyMethod()` overhead.
Remove ByteOrder.isLittleEndian() implementation from
UnstartedRuntime. The Java method has been removed by
https://android-review.googlesource.com/151062 .
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: boots.
Bug: 175869411
Change-Id: I97cf91a0abf2b28f83562d8764d28edafa1a09e2
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 16f0d58..4509573 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -142,6 +142,8 @@
if (!unstarted_initialized_) {
interpreter::UnstartedRuntime::Initialize();
unstarted_initialized_ = true;
+ } else {
+ interpreter::UnstartedRuntime::Reinitialize();
}
{
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 229142e..c61447f 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -24,7 +24,6 @@
#include <initializer_list>
#include <limits>
#include <locale>
-#include <unordered_map>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
@@ -32,6 +31,7 @@
#include "art_method-inl.h"
#include "base/casts.h"
#include "base/enums.h"
+#include "base/hash_map.h"
#include "base/macros.h"
#include "base/quasi_atomic.h"
#include "base/zip_archive.h"
@@ -60,6 +60,7 @@
#include "reflection.h"
#include "thread-inl.h"
#include "transaction.h"
+#include "unstarted_runtime_list.h"
#include "well_known_classes.h"
namespace art {
@@ -1851,12 +1852,6 @@
result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace(soa)));
}
-void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
- Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
- mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
- result->SetZ(JNI_TRUE);
-}
-
void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
Thread* self,
ArtMethod* method ATTRIBUTE_UNUSED,
@@ -1971,47 +1966,104 @@
uint32_t* args,
JValue* result);
-static bool tables_initialized_ = false;
-static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
-static std::unordered_map<std::string, JNIHandler> jni_handlers_;
+#define ONE_PLUS(ShortNameIgnored, DescriptorIgnored, NameIgnored, SignatureIgnored) 1 +
+static constexpr size_t kInvokeHandlersSize = UNSTARTED_RUNTIME_DIRECT_LIST(ONE_PLUS) 0;
+static constexpr size_t kJniHandlersSize = UNSTARTED_RUNTIME_JNI_LIST(ONE_PLUS) 0;
+#undef ONE_PLUS
-void UnstartedRuntime::InitializeInvokeHandlers() {
-#define UNSTARTED_DIRECT(ShortName, Sig) \
- invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
-#include "unstarted_runtime_list.h"
- UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
-#undef UNSTARTED_RUNTIME_DIRECT_LIST
-#undef UNSTARTED_RUNTIME_JNI_LIST
-#undef UNSTARTED_DIRECT
+// The actual value of `kMinLoadFactor` is irrelevant because the HashMap<>s below
+// are never resized, but we still need to pass a reasonable value to the constructor.
+static constexpr double kMinLoadFactor = 0.5;
+static constexpr double kMaxLoadFactor = 0.7;
+
+constexpr size_t BufferSize(size_t size) {
+ // Note: ceil() is not suitable for constexpr, so cast to size_t and adjust by 1 if needed.
+ const size_t estimate = static_cast<size_t>(size / kMaxLoadFactor);
+ return static_cast<size_t>(estimate * kMaxLoadFactor) == size ? estimate : estimate + 1u;
}
-void UnstartedRuntime::InitializeJNIHandlers() {
-#define UNSTARTED_JNI(ShortName, Sig) \
- jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
-#include "unstarted_runtime_list.h"
+static constexpr size_t kInvokeHandlersBufferSize = BufferSize(kInvokeHandlersSize);
+static_assert(
+ static_cast<size_t>(kInvokeHandlersBufferSize * kMaxLoadFactor) == kInvokeHandlersSize);
+static constexpr size_t kJniHandlersBufferSize = BufferSize(kJniHandlersSize);
+static_assert(static_cast<size_t>(kJniHandlersBufferSize * kMaxLoadFactor) == kJniHandlersSize);
+
+static bool tables_initialized_ = false;
+static std::pair<ArtMethod*, InvokeHandler> kInvokeHandlersBuffer[kInvokeHandlersBufferSize];
+static HashMap<ArtMethod*, InvokeHandler> invoke_handlers_(
+ kMinLoadFactor, kMaxLoadFactor, kInvokeHandlersBuffer, kInvokeHandlersBufferSize);
+static std::pair<ArtMethod*, JNIHandler> kJniHandlersBuffer[kJniHandlersBufferSize];
+static HashMap<ArtMethod*, JNIHandler> jni_handlers_(
+ kMinLoadFactor, kMaxLoadFactor, kJniHandlersBuffer, kJniHandlersBufferSize);
+
+static ArtMethod* FindMethod(Thread* self,
+ ClassLinker* class_linker,
+ const char* descriptor,
+ std::string_view name,
+ std::string_view signature) REQUIRES_SHARED(Locks::mutator_lock_) {
+ ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, descriptor);
+ DCHECK(klass != nullptr) << descriptor;
+ ArtMethod* method = klass->FindClassMethod(name, signature, class_linker->GetImagePointerSize());
+ DCHECK(method != nullptr) << descriptor << "." << name << signature;
+ return method;
+}
+
+void UnstartedRuntime::InitializeInvokeHandlers(Thread* self) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+#define UNSTARTED_DIRECT(ShortName, Descriptor, Name, Signature) \
+ { \
+ ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
+ invoke_handlers_.insert(std::make_pair(method, & UnstartedRuntime::Unstarted ## ShortName)); \
+ }
+ UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
+#undef UNSTARTED_DIRECT
+ DCHECK_EQ(invoke_handlers_.NumBuckets(), kInvokeHandlersBufferSize);
+}
+
+void UnstartedRuntime::InitializeJNIHandlers(Thread* self) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+#define UNSTARTED_JNI(ShortName, Descriptor, Name, Signature) \
+ { \
+ ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
+ jni_handlers_.insert(std::make_pair(method, & UnstartedRuntime::UnstartedJNI ## ShortName)); \
+ }
UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
-#undef UNSTARTED_RUNTIME_DIRECT_LIST
-#undef UNSTARTED_RUNTIME_JNI_LIST
#undef UNSTARTED_JNI
+ DCHECK_EQ(jni_handlers_.NumBuckets(), kJniHandlersBufferSize);
}
void UnstartedRuntime::Initialize() {
CHECK(!tables_initialized_);
- InitializeInvokeHandlers();
- InitializeJNIHandlers();
+ ScopedObjectAccess soa(Thread::Current());
+ InitializeInvokeHandlers(soa.Self());
+ InitializeJNIHandlers(soa.Self());
tables_initialized_ = true;
}
+void UnstartedRuntime::Reinitialize() {
+ CHECK(tables_initialized_);
+
+ // Note: HashSet::clear() abandons the pre-allocated storage which we need to keep.
+ while (!invoke_handlers_.empty()) {
+ invoke_handlers_.erase(invoke_handlers_.begin());
+ }
+ while (!jni_handlers_.empty()) {
+ jni_handlers_.erase(jni_handlers_.begin());
+ }
+
+ tables_initialized_ = false;
+ Initialize();
+}
+
void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
// In a runtime that's not started we intercept certain methods to avoid complicated dependency
// problems in core libraries.
CHECK(tables_initialized_);
- std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
- const auto& iter = invoke_handlers_.find(name);
+ const auto& iter = invoke_handlers_.find(shadow_frame->GetMethod());
if (iter != invoke_handlers_.end()) {
// Clear out the result in case it's not zeroed out.
result->SetL(nullptr);
@@ -2031,15 +2083,14 @@
// Hand select a number of methods to be run in a not yet started runtime without using JNI.
void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
uint32_t* args, JValue* result) {
- std::string name(ArtMethod::PrettyMethod(method));
- const auto& iter = jni_handlers_.find(name);
+ const auto& iter = jni_handlers_.find(method);
if (iter != jni_handlers_.end()) {
// Clear out the result in case it's not zeroed out.
result->SetL(nullptr);
(*iter->second)(self, method, receiver, args, result);
} else if (Runtime::Current()->IsActiveTransaction()) {
AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
- name.c_str());
+ ArtMethod::PrettyMethod(method).c_str());
} else {
LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
"non-transactional runtime";
diff --git a/runtime/interpreter/unstarted_runtime.h b/runtime/interpreter/unstarted_runtime.h
index b38c685..4a71645 100644
--- a/runtime/interpreter/unstarted_runtime.h
+++ b/runtime/interpreter/unstarted_runtime.h
@@ -21,6 +21,7 @@
#include "dex/dex_file.h"
#include "jvalue.h"
+#include "unstarted_runtime_list.h"
namespace art {
@@ -48,6 +49,10 @@
public:
static void Initialize();
+ // For testing. When we destroy the Runtime and create a new one,
+ // we need to reinitialize maps with new `ArtMethod*` keys.
+ static void Reinitialize();
+
static void Invoke(Thread* self,
const CodeItemDataAccessor& accessor,
ShadowFrame* shadow_frame,
@@ -64,30 +69,24 @@
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) \
+#define UNSTARTED_DIRECT(ShortName, DescriptorIgnored, NameIgnored, SignatureIgnored) \
+ static void Unstarted ## ShortName(Thread* self, \
+ ShadowFrame* shadow_frame, \
+ JValue* result, \
+ size_t arg_offset) \
REQUIRES_SHARED(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, \
- ArtMethod* method, \
- mirror::Object* receiver, \
- uint32_t* args, \
- JValue* result) \
+#define UNSTARTED_JNI(ShortName, DescriptorIgnored, NameIgnored, SignatureIgnored) \
+ static void UnstartedJNI ## ShortName(Thread* self, \
+ ArtMethod* method, \
+ mirror::Object* receiver, \
+ uint32_t* args, \
+ JValue* result) \
REQUIRES_SHARED(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 UnstartedClassForNameCommon(Thread* self,
@@ -97,8 +96,8 @@
bool long_form,
const char* caller) REQUIRES_SHARED(Locks::mutator_lock_);
- static void InitializeInvokeHandlers();
- static void InitializeJNIHandlers();
+ static void InitializeInvokeHandlers(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
+ static void InitializeJNIHandlers(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
friend class UnstartedRuntimeTest;
diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h
index 3cc598a..4130654 100644
--- a/runtime/interpreter/unstarted_runtime_list.h
+++ b/runtime/interpreter/unstarted_runtime_list.h
@@ -19,92 +19,89 @@
// Methods that intercept available libcore implementations.
#define UNSTARTED_RUNTIME_DIRECT_LIST(V) \
- V(CharacterToLowerCase, "int java.lang.Character.toLowerCase(int)") \
- V(CharacterToUpperCase, "int java.lang.Character.toUpperCase(int)") \
- V(ClassForName, "java.lang.Class java.lang.Class.forName(java.lang.String)") \
- V(ClassForNameLong, "java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader)") \
- V(ClassGetPrimitiveClass, "java.lang.Class java.lang.Class.getPrimitiveClass(java.lang.String)") \
- V(ClassClassForName, "java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader)") \
- V(ClassNewInstance, "java.lang.Object java.lang.Class.newInstance()") \
- V(ClassGetDeclaredField, "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") \
- V(ClassGetDeclaredMethod, "java.lang.reflect.Method java.lang.Class.getDeclaredMethodInternal(java.lang.String, java.lang.Class[])") \
- V(ClassGetDeclaredConstructor, "java.lang.reflect.Constructor java.lang.Class.getDeclaredConstructorInternal(java.lang.Class[])") \
- V(ClassGetDeclaringClass, "java.lang.Class java.lang.Class.getDeclaringClass()") \
- V(ClassGetEnclosingClass, "java.lang.Class java.lang.Class.getEnclosingClass()") \
- V(ClassGetInnerClassFlags, "int java.lang.Class.getInnerClassFlags(int)") \
- V(ClassGetSignatureAnnotation, "java.lang.String[] java.lang.Class.getSignatureAnnotation()") \
- V(ClassIsAnonymousClass, "boolean java.lang.Class.isAnonymousClass()") \
- V(ClassLoaderGetResourceAsStream, "java.io.InputStream java.lang.ClassLoader.getResourceAsStream(java.lang.String)") \
- V(ConstructorNewInstance0, "java.lang.Object java.lang.reflect.Constructor.newInstance0(java.lang.Object[])") \
- V(VmClassLoaderFindLoadedClass, "java.lang.Class java.lang.VMClassLoader.findLoadedClass(java.lang.ClassLoader, java.lang.String)") \
- V(SystemArraycopy, "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)") \
- V(SystemArraycopyByte, "void java.lang.System.arraycopy(byte[], int, byte[], int, int)") \
- V(SystemArraycopyChar, "void java.lang.System.arraycopy(char[], int, char[], int, int)") \
- V(SystemArraycopyInt, "void java.lang.System.arraycopy(int[], int, int[], int, int)") \
- V(SystemGetSecurityManager, "java.lang.SecurityManager java.lang.System.getSecurityManager()") \
- V(SystemGetProperty, "java.lang.String java.lang.System.getProperty(java.lang.String)") \
- V(SystemGetPropertyWithDefault, "java.lang.String java.lang.System.getProperty(java.lang.String, java.lang.String)") \
- V(ThreadLocalGet, "java.lang.Object java.lang.ThreadLocal.get()") \
- V(MathCeil, "double java.lang.Math.ceil(double)") \
- V(MathFloor, "double java.lang.Math.floor(double)") \
- V(MathSin, "double java.lang.Math.sin(double)") \
- V(MathCos, "double java.lang.Math.cos(double)") \
- V(MathPow, "double java.lang.Math.pow(double, double)") \
- V(ObjectHashCode, "int java.lang.Object.hashCode()") \
- V(DoubleDoubleToRawLongBits, "long java.lang.Double.doubleToRawLongBits(double)") \
- V(MemoryPeekByte, "byte libcore.io.Memory.peekByte(long)") \
- V(MemoryPeekShort, "short libcore.io.Memory.peekShortNative(long)") \
- V(MemoryPeekInt, "int libcore.io.Memory.peekIntNative(long)") \
- V(MemoryPeekLong, "long libcore.io.Memory.peekLongNative(long)") \
- V(MemoryPeekByteArray, "void libcore.io.Memory.peekByteArray(long, byte[], int, int)") \
- V(MethodInvoke, "java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])") \
- V(ReferenceGetReferent, "java.lang.Object java.lang.ref.Reference.getReferent()") \
- V(RuntimeAvailableProcessors, "int java.lang.Runtime.availableProcessors()") \
- V(StringGetCharsNoCheck, "void java.lang.String.getCharsNoCheck(int, int, char[], int)") \
- V(StringCharAt, "char java.lang.String.charAt(int)") \
- V(StringDoReplace, "java.lang.String java.lang.String.doReplace(char, char)") \
- V(StringFactoryNewStringFromChars, "java.lang.String java.lang.StringFactory.newStringFromChars(int, int, char[])") \
- V(StringFactoryNewStringFromString, "java.lang.String java.lang.StringFactory.newStringFromString(java.lang.String)") \
- V(StringFastSubstring, "java.lang.String java.lang.String.fastSubstring(int, int)") \
- V(StringToCharArray, "char[] java.lang.String.toCharArray()") \
- V(ThreadCurrentThread, "java.lang.Thread java.lang.Thread.currentThread()") \
- V(ThreadGetNativeState, "int java.lang.Thread.nativeGetStatus(boolean)") \
- V(UnsafeCompareAndSwapLong, "boolean sun.misc.Unsafe.compareAndSwapLong(java.lang.Object, long, long, long)") \
- V(UnsafeCompareAndSwapObject, "boolean sun.misc.Unsafe.compareAndSwapObject(java.lang.Object, long, java.lang.Object, java.lang.Object)") \
- V(UnsafeGetObjectVolatile, "java.lang.Object sun.misc.Unsafe.getObjectVolatile(java.lang.Object, long)") \
- V(UnsafePutObjectVolatile, "void sun.misc.Unsafe.putObjectVolatile(java.lang.Object, long, java.lang.Object)") \
- V(UnsafePutOrderedObject, "void sun.misc.Unsafe.putOrderedObject(java.lang.Object, long, java.lang.Object)") \
- V(IntegerParseInt, "int java.lang.Integer.parseInt(java.lang.String)") \
- V(LongParseLong, "long java.lang.Long.parseLong(java.lang.String)") \
- V(SystemIdentityHashCode, "int java.lang.System.identityHashCode(java.lang.Object)")
+ V(CharacterToLowerCase, "Ljava/lang/Character;", "toLowerCase", "(I)I") \
+ V(CharacterToUpperCase, "Ljava/lang/Character;", "toUpperCase", "(I)I") \
+ V(ClassForName, "Ljava/lang/Class;", "forName", "(Ljava/lang/String;)Ljava/lang/Class;") \
+ V(ClassForNameLong, "Ljava/lang/Class;", "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;") \
+ V(ClassGetPrimitiveClass, "Ljava/lang/Class;", "getPrimitiveClass", "(Ljava/lang/String;)Ljava/lang/Class;") \
+ V(ClassClassForName, "Ljava/lang/Class;", "classForName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;") \
+ V(ClassNewInstance, "Ljava/lang/Class;", "newInstance", "()Ljava/lang/Object;") \
+ V(ClassGetDeclaredField, "Ljava/lang/Class;", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;") \
+ V(ClassGetDeclaredMethod, "Ljava/lang/Class;", "getDeclaredMethodInternal", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;") \
+ V(ClassGetDeclaredConstructor, "Ljava/lang/Class;", "getDeclaredConstructorInternal", "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;") \
+ V(ClassGetDeclaringClass, "Ljava/lang/Class;", "getDeclaringClass", "()Ljava/lang/Class;") \
+ V(ClassGetEnclosingClass, "Ljava/lang/Class;", "getEnclosingClass", "()Ljava/lang/Class;") \
+ V(ClassGetInnerClassFlags, "Ljava/lang/Class;", "getInnerClassFlags", "(I)I") \
+ V(ClassGetSignatureAnnotation, "Ljava/lang/Class;", "getSignatureAnnotation", "()[Ljava/lang/String;") \
+ V(ClassIsAnonymousClass, "Ljava/lang/Class;", "isAnonymousClass", "()Z") \
+ V(ClassLoaderGetResourceAsStream, "Ljava/lang/ClassLoader;", "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;") \
+ V(ConstructorNewInstance0, "Ljava/lang/reflect/Constructor;", "newInstance0", "([Ljava/lang/Object;)Ljava/lang/Object;") \
+ V(VmClassLoaderFindLoadedClass, "Ljava/lang/VMClassLoader;", "findLoadedClass", "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;") \
+ V(SystemArraycopy, "Ljava/lang/System;", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V") \
+ V(SystemArraycopyByte, "Ljava/lang/System;", "arraycopy", "([BI[BII)V") \
+ V(SystemArraycopyChar, "Ljava/lang/System;", "arraycopy", "([CI[CII)V") \
+ V(SystemArraycopyInt, "Ljava/lang/System;", "arraycopy", "([II[III)V") \
+ V(SystemGetSecurityManager, "Ljava/lang/System;", "getSecurityManager", "()Ljava/lang/SecurityManager;") \
+ V(SystemGetProperty, "Ljava/lang/System;", "getProperty", "(Ljava/lang/String;)Ljava/lang/String;") \
+ V(SystemGetPropertyWithDefault, "Ljava/lang/System;", "getProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;") \
+ V(ThreadLocalGet, "Ljava/lang/ThreadLocal;", "get", "()Ljava/lang/Object;") \
+ V(MathCeil, "Ljava/lang/Math;", "ceil", "(D)D") \
+ V(MathFloor, "Ljava/lang/Math;", "floor", "(D)D") \
+ V(MathSin, "Ljava/lang/Math;", "sin", "(D)D") \
+ V(MathCos, "Ljava/lang/Math;", "cos", "(D)D") \
+ V(MathPow, "Ljava/lang/Math;", "pow", "(DD)D") \
+ V(ObjectHashCode, "Ljava/lang/Object;", "hashCode", "()I") \
+ V(DoubleDoubleToRawLongBits, "Ljava/lang/Double;", "doubleToRawLongBits", "(D)J") \
+ V(MemoryPeekByte, "Llibcore/io/Memory;", "peekByte", "(J)B") \
+ V(MemoryPeekShort, "Llibcore/io/Memory;", "peekShortNative", "(J)S") \
+ V(MemoryPeekInt, "Llibcore/io/Memory;", "peekIntNative", "(J)I") \
+ V(MemoryPeekLong, "Llibcore/io/Memory;", "peekLongNative", "(J)J") \
+ V(MemoryPeekByteArray, "Llibcore/io/Memory;", "peekByteArray", "(J[BII)V") \
+ V(MethodInvoke, "Ljava/lang/reflect/Method;", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;") \
+ V(ReferenceGetReferent, "Ljava/lang/ref/Reference;", "getReferent", "()Ljava/lang/Object;") \
+ V(RuntimeAvailableProcessors, "Ljava/lang/Runtime;", "availableProcessors", "()I") \
+ V(StringGetCharsNoCheck, "Ljava/lang/String;", "getCharsNoCheck", "(II[CI)V") \
+ V(StringCharAt, "Ljava/lang/String;", "charAt", "(I)C") \
+ V(StringDoReplace, "Ljava/lang/String;", "doReplace", "(CC)Ljava/lang/String;") \
+ V(StringFactoryNewStringFromChars, "Ljava/lang/StringFactory;", "newStringFromChars", "(II[C)Ljava/lang/String;") \
+ V(StringFactoryNewStringFromString, "Ljava/lang/StringFactory;", "newStringFromString", "(Ljava/lang/String;)Ljava/lang/String;") \
+ V(StringFastSubstring, "Ljava/lang/String;", "fastSubstring", "(II)Ljava/lang/String;") \
+ V(StringToCharArray, "Ljava/lang/String;", "toCharArray", "()[C") \
+ V(ThreadCurrentThread, "Ljava/lang/Thread;", "currentThread", "()Ljava/lang/Thread;") \
+ V(ThreadGetNativeState, "Ljava/lang/Thread;", "nativeGetStatus", "(Z)I") \
+ V(UnsafeCompareAndSwapLong, "Lsun/misc/Unsafe;", "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z") \
+ V(UnsafeCompareAndSwapObject, "Lsun/misc/Unsafe;", "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
+ V(UnsafeGetObjectVolatile, "Lsun/misc/Unsafe;", "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;") \
+ V(UnsafePutObjectVolatile, "Lsun/misc/Unsafe;", "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V") \
+ V(UnsafePutOrderedObject, "Lsun/misc/Unsafe;", "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V") \
+ V(IntegerParseInt, "Ljava/lang/Integer;", "parseInt", "(Ljava/lang/String;)I") \
+ V(LongParseLong, "Ljava/lang/Long;", "parseLong", "(Ljava/lang/String;)J") \
+ V(SystemIdentityHashCode, "Ljava/lang/System;", "identityHashCode", "(Ljava/lang/Object;)I")
// Methods that are native.
#define UNSTARTED_RUNTIME_JNI_LIST(V) \
- V(VMRuntimeIs64Bit, "boolean dalvik.system.VMRuntime.is64Bit()") \
- V(VMRuntimeNewUnpaddedArray, "java.lang.Object dalvik.system.VMRuntime.newUnpaddedArray(java.lang.Class, int)") \
- V(VMStackGetCallingClassLoader, "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") \
- V(VMStackGetStackClass2, "java.lang.Class dalvik.system.VMStack.getStackClass2()") \
- V(MathLog, "double java.lang.Math.log(double)") \
- V(MathExp, "double java.lang.Math.exp(double)") \
- V(AtomicLongVMSupportsCS8, "boolean java.util.concurrent.atomic.AtomicLong.VMSupportsCS8()") \
- V(ClassGetNameNative, "java.lang.String java.lang.Class.getNameNative()") \
- V(DoubleLongBitsToDouble, "double java.lang.Double.longBitsToDouble(long)") \
- V(FloatFloatToRawIntBits, "int java.lang.Float.floatToRawIntBits(float)") \
- V(FloatIntBitsToFloat, "float java.lang.Float.intBitsToFloat(int)") \
- V(ObjectInternalClone, "java.lang.Object java.lang.Object.internalClone()") \
- V(ObjectNotifyAll, "void java.lang.Object.notifyAll()") \
- V(StringCompareTo, "int java.lang.String.compareTo(java.lang.String)") \
- V(StringIntern, "java.lang.String java.lang.String.intern()") \
- V(ArrayCreateMultiArray, "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") \
- V(ArrayCreateObjectArray, "java.lang.Object java.lang.reflect.Array.createObjectArray(java.lang.Class, int)") \
- V(ThrowableNativeFillInStackTrace, "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") \
- V(ByteOrderIsLittleEndian, "boolean java.nio.ByteOrder.isLittleEndian()") \
- V(UnsafeCompareAndSwapInt, "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") \
- V(UnsafeGetIntVolatile, "int sun.misc.Unsafe.getIntVolatile(java.lang.Object, long)") \
- V(UnsafePutObject, "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") \
- V(UnsafeGetArrayBaseOffsetForComponentType, "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)") \
- V(UnsafeGetArrayIndexScaleForComponentType, "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)")
+ V(VMRuntimeIs64Bit, "Ldalvik/system/VMRuntime;", "is64Bit", "()Z") \
+ V(VMRuntimeNewUnpaddedArray, "Ldalvik/system/VMRuntime;", "newUnpaddedArray", "(Ljava/lang/Class;I)Ljava/lang/Object;") \
+ V(VMStackGetCallingClassLoader, "Ldalvik/system/VMStack;", "getCallingClassLoader", "()Ljava/lang/ClassLoader;") \
+ V(VMStackGetStackClass2, "Ldalvik/system/VMStack;", "getStackClass2", "()Ljava/lang/Class;") \
+ V(MathLog, "Ljava/lang/Math;", "log", "(D)D") \
+ V(MathExp, "Ljava/lang/Math;", "exp", "(D)D") \
+ V(AtomicLongVMSupportsCS8, "Ljava/util/concurrent/atomic/AtomicLong;", "VMSupportsCS8", "()Z") \
+ V(ClassGetNameNative, "Ljava/lang/Class;", "getNameNative", "()Ljava/lang/String;") \
+ V(DoubleLongBitsToDouble, "Ljava/lang/Double;", "longBitsToDouble", "(J)D") \
+ V(FloatFloatToRawIntBits, "Ljava/lang/Float;", "floatToRawIntBits", "(F)I") \
+ V(FloatIntBitsToFloat, "Ljava/lang/Float;", "intBitsToFloat", "(I)F") \
+ V(ObjectInternalClone, "Ljava/lang/Object;", "internalClone", "()Ljava/lang/Object;") \
+ V(ObjectNotifyAll, "Ljava/lang/Object;", "notifyAll", "()V") \
+ V(StringCompareTo, "Ljava/lang/String;", "compareTo", "(Ljava/lang/String;)I") \
+ V(StringIntern, "Ljava/lang/String;", "intern", "()Ljava/lang/String;") \
+ V(ArrayCreateMultiArray, "Ljava/lang/reflect/Array;", "createMultiArray", "(Ljava/lang/Class;[I)Ljava/lang/Object;") \
+ V(ArrayCreateObjectArray, "Ljava/lang/reflect/Array;", "createObjectArray", "(Ljava/lang/Class;I)Ljava/lang/Object;") \
+ V(ThrowableNativeFillInStackTrace, "Ljava/lang/Throwable;", "nativeFillInStackTrace", "()Ljava/lang/Object;") \
+ V(UnsafeCompareAndSwapInt, "Lsun/misc/Unsafe;", "compareAndSwapInt", "(Ljava/lang/Object;JII)Z") \
+ V(UnsafeGetIntVolatile, "Lsun/misc/Unsafe;", "getIntVolatile", "(Ljava/lang/Object;J)I") \
+ V(UnsafePutObject, "Lsun/misc/Unsafe;", "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V") \
+ V(UnsafeGetArrayBaseOffsetForComponentType, "Lsun/misc/Unsafe;", "getArrayBaseOffsetForComponentType", "(Ljava/lang/Class;)I") \
+ V(UnsafeGetArrayIndexScaleForComponentType, "Lsun/misc/Unsafe;", "getArrayIndexScaleForComponentType", "(Ljava/lang/Class;)I")
#endif // ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_LIST_H_
-// the guard in this file is just for cpplint
-#undef ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_LIST_H_
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 792444a..77075a6 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -42,6 +42,7 @@
#include "shadow_frame-inl.h"
#include "thread.h"
#include "transaction.h"
+#include "unstarted_runtime_list.h"
namespace art {
namespace interpreter {
@@ -64,34 +65,28 @@
// test friends.
// Methods that intercept available libcore implementations.
-#define UNSTARTED_DIRECT(Name, SigIgnored) \
- static void Unstarted ## Name(Thread* self, \
- ShadowFrame* shadow_frame, \
- JValue* result, \
- size_t arg_offset) \
- REQUIRES_SHARED(Locks::mutator_lock_) { \
+#define UNSTARTED_DIRECT(Name, DescriptorIgnored, NameIgnored, SignatureIgnored) \
+ static void Unstarted ## Name(Thread* self, \
+ ShadowFrame* shadow_frame, \
+ JValue* result, \
+ size_t arg_offset) \
+ REQUIRES_SHARED(Locks::mutator_lock_) { \
interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
}
-#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(Name, SigIgnored) \
- static void UnstartedJNI ## Name(Thread* self, \
- ArtMethod* method, \
- mirror::Object* receiver, \
- uint32_t* args, \
- JValue* result) \
- REQUIRES_SHARED(Locks::mutator_lock_) { \
+#define UNSTARTED_JNI(Name, DescriptorIgnored, NameIgnored, SignatureIgnored) \
+ static void UnstartedJNI ## Name(Thread* self, \
+ ArtMethod* method, \
+ mirror::Object* receiver, \
+ uint32_t* args, \
+ JValue* result) \
+ REQUIRES_SHARED(Locks::mutator_lock_) { \
interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
}
-#include "unstarted_runtime_list.h"
UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
-#undef UNSTARTED_RUNTIME_DIRECT_LIST
-#undef UNSTARTED_RUNTIME_JNI_LIST
#undef UNSTARTED_JNI
UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs,