diff options
author | 2021-01-07 10:59:54 +0000 | |
---|---|---|
committer | 2021-01-11 13:53:33 +0000 | |
commit | 83881483515aec1dfaa0c848f1ce876c3f966b43 (patch) | |
tree | 01bfa31dbdef146ec88505378e4829f133a5ab91 | |
parent | 7d4a71ee0ecab7bf65086c786fb5358444dd2a8f (diff) |
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
-rw-r--r-- | runtime/common_runtime_test.cc | 2 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 109 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime.h | 37 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime_list.h | 165 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime_test.cc | 33 |
5 files changed, 195 insertions, 151 deletions
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index 16f0d5868b..45095732be 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -142,6 +142,8 @@ void CommonRuntimeTestImpl::FinalizeSetup() { 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 229142ec4c..c61447f6a2 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 @@ void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace( 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 @@ using JNIHandler = void(*)(Thread* self, 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" +// 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; +} + +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_RUNTIME_DIRECT_LIST -#undef UNSTARTED_RUNTIME_JNI_LIST #undef UNSTARTED_DIRECT + DCHECK_EQ(invoke_handlers_.NumBuckets(), kInvokeHandlersBufferSize); } -void UnstartedRuntime::InitializeJNIHandlers() { -#define UNSTARTED_JNI(ShortName, Sig) \ - jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName)); -#include "unstarted_runtime_list.h" +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 @@ void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor // 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 b38c685d9b..4a716455ac 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 @@ class UnstartedRuntime { 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 @@ class UnstartedRuntime { 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 @@ class UnstartedRuntime { 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 3cc598aed7..4130654dd2 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 792444a956..77075a6c54 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 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { // 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, |