Change well-known `DdmServer` methods to `ArtMethod*`.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --interpreter
Test: run-libjdwp-tests.sh --mode=device --variant=X32 --debug
Change-Id: I31c61424a81037a20d4a6bceb081915da067d87f
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 6499bac..0057bf9 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -48,6 +48,158 @@
namespace art {
+namespace detail {
+
+template <> struct ShortyTraits<'V'> {
+ using Type = void;
+ static Type Get(const JValue& value ATTRIBUTE_UNUSED) {}
+ // `kVRegCount` and `Set()` are not defined.
+};
+
+template <> struct ShortyTraits<'Z'> {
+ // We're using `uint8_t` for `boolean`, see `JValue`.
+ using Type = uint8_t;
+ static Type Get(const JValue& value) { return value.GetZ(); }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'B'> {
+ using Type = int8_t;
+ static Type Get(const JValue& value) { return value.GetB(); }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'C'> {
+ using Type = uint16_t;
+ static Type Get(const JValue& value) { return value.GetC(); }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'S'> {
+ using Type = int16_t;
+ static Type Get(const JValue& value) { return value.GetS(); }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'I'> {
+ using Type = int32_t;
+ static Type Get(const JValue& value) { return value.GetI(); }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) { args[0] = static_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'J'> {
+ using Type = int64_t;
+ static Type Get(const JValue& value) { return value.GetJ(); }
+ static constexpr size_t kVRegCount = 2u;
+ static void Set(uint32_t* args, Type value) {
+ // Little-endian representation.
+ args[0] = static_cast<uint32_t>(value);
+ args[1] = static_cast<uint32_t>(static_cast<uint64_t>(value) >> 32);
+ }
+};
+
+template <> struct ShortyTraits<'F'> {
+ using Type = float;
+ static Type Get(const JValue& value) { return value.GetF(); }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) { args[0] = bit_cast<uint32_t>(value); }
+};
+
+template <> struct ShortyTraits<'D'> {
+ using Type = double;
+ static Type Get(const JValue& value) { return value.GetD(); }
+ static constexpr size_t kVRegCount = 2u;
+ static void Set(uint32_t* args, Type value) {
+ // Little-endian representation.
+ uint64_t v = bit_cast<uint64_t>(value);
+ args[0] = static_cast<uint32_t>(v);
+ args[1] = static_cast<uint32_t>(v >> 32);
+ }
+};
+
+template <> struct ShortyTraits<'L'> {
+ using Type = ObjPtr<mirror::Object>;
+ static Type Get(const JValue& value) REQUIRES_SHARED(Locks::mutator_lock_) {
+ return value.GetL();
+ }
+ static constexpr size_t kVRegCount = 1u;
+ static void Set(uint32_t* args, Type value) REQUIRES_SHARED(Locks::mutator_lock_) {
+ args[0] = StackReference<mirror::Object>::FromMirrorPtr(value.Ptr()).AsVRegValue();
+ }
+};
+
+template <char... Shorty>
+constexpr auto MaterializeShorty() {
+ constexpr size_t kSize = std::size({Shorty...}) + 1u;
+ return std::array<char, kSize>{Shorty..., '\0'};
+}
+
+template <char... ArgType>
+constexpr size_t NumberOfVRegs() {
+ constexpr size_t kArgVRegCount[] = {
+ ShortyTraits<ArgType>::kVRegCount...
+ };
+ size_t sum = 0u;
+ for (size_t count : kArgVRegCount) {
+ sum += count;
+ }
+ return sum;
+}
+
+template <char... ArgType>
+inline ALWAYS_INLINE void FillVRegs(uint32_t* vregs ATTRIBUTE_UNUSED,
+ typename ShortyTraits<ArgType>::Type... args ATTRIBUTE_UNUSED)
+ REQUIRES_SHARED(Locks::mutator_lock_) {}
+
+template <char FirstArgType, char... ArgType>
+inline ALWAYS_INLINE void FillVRegs(uint32_t* vregs,
+ typename ShortyTraits<FirstArgType>::Type first_arg,
+ typename ShortyTraits<ArgType>::Type... args)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ ShortyTraits<FirstArgType>::Set(vregs, first_arg);
+ FillVRegs<ArgType...>(vregs + ShortyTraits<FirstArgType>::kVRegCount, args...);
+}
+
+template <char... ArgType>
+inline ALWAYS_INLINE auto MaterializeVRegs(typename ShortyTraits<ArgType>::Type... args)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ constexpr size_t kNumVRegs = NumberOfVRegs<ArgType...>();
+ std::array<uint32_t, kNumVRegs> vregs;
+ FillVRegs<ArgType...>(vregs.data(), args...);
+ return vregs;
+}
+
+} // namespace detail
+
+template <char ReturnType, char... ArgType>
+inline typename detail::ShortyTraits<ReturnType>::Type
+ArtMethod::InvokeStatic(Thread* self, typename detail::ShortyTraits<ArgType>::Type... args) {
+ DCHECK(IsStatic());
+ JValue result;
+ constexpr auto shorty = detail::MaterializeShorty<ReturnType, ArgType...>();
+ auto vregs = detail::MaterializeVRegs<ArgType...>(args...);
+ Invoke(self, vregs.data(), sizeof(vregs), &result, shorty.data());
+ return detail::ShortyTraits<ReturnType>::Get(result);
+}
+
+template <char ReturnType, char... ArgType>
+typename detail::ShortyTraits<ReturnType>::Type
+ArtMethod::InvokeInstance(Thread* self,
+ ObjPtr<mirror::Object> receiver,
+ typename detail::ShortyTraits<ArgType>::Type... args) {
+ DCHECK(!IsStatic());
+ JValue result;
+ constexpr auto shorty = detail::MaterializeShorty<ReturnType, ArgType...>();
+ auto vregs = detail::MaterializeVRegs<'L', ArgType...>(receiver, args...);
+ Invoke(self, vregs.data(), sizeof(vregs), &result, shorty.data());
+ return detail::ShortyTraits<ReturnType>::Get(result);
+}
+
template <ReadBarrierOption kReadBarrierOption>
inline ObjPtr<mirror::Class> ArtMethod::GetDeclaringClassUnchecked() {
GcRootSource gc_root_source(this);