Skip to content

Commit aed5c91

Browse files
swolchokfacebook-github-bot
authored andcommitted
constexprify JMethodDescriptor
Summary: Attached task says these functions are huge. They look amenable to compile-time computation. Reviewed By: mhorowitz Differential Revision: D14015755 fbshipit-source-id: 5f131ef7c84b2b8f467f47c38512ddf39984148b
1 parent aed54f5 commit aed5c91

File tree

12 files changed

+589
-124
lines changed

12 files changed

+589
-124
lines changed

cxx/fbjni/detail/CoreClasses-inl.h

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ inline bool JClass::isAssignableFrom(alias_ref<JClass> other) const noexcept {
201201

202202
template<typename F>
203203
inline JConstructor<F> JClass::getConstructor() const {
204-
return getConstructor<F>(jmethod_traits_from_cxx<F>::constructor_descriptor().c_str());
204+
return getConstructor<F>(jmethod_traits_from_cxx<F>::kConstructorDescriptor.c_str());
205205
}
206206

207207
template<typename F>
@@ -212,7 +212,7 @@ inline JConstructor<F> JClass::getConstructor(const char* descriptor) const {
212212

213213
template<typename F>
214214
inline JMethod<F> JClass::getMethod(const char* name) const {
215-
return getMethod<F>(name, jmethod_traits_from_cxx<F>::descriptor().c_str());
215+
return getMethod<F>(name, jmethod_traits_from_cxx<F>::kDescriptor.c_str());
216216
}
217217

218218
template<typename F>
@@ -227,7 +227,7 @@ inline JMethod<F> JClass::getMethod(
227227

228228
template<typename F>
229229
inline JStaticMethod<F> JClass::getStaticMethod(const char* name) const {
230-
return getStaticMethod<F>(name, jmethod_traits_from_cxx<F>::descriptor().c_str());
230+
return getStaticMethod<F>(name, jmethod_traits_from_cxx<F>::kDescriptor.c_str());
231231
}
232232

233233
template<typename F>
@@ -242,7 +242,7 @@ inline JStaticMethod<F> JClass::getStaticMethod(
242242

243243
template<typename F>
244244
inline JNonvirtualMethod<F> JClass::getNonvirtualMethod(const char* name) const {
245-
return getNonvirtualMethod<F>(name, jmethod_traits_from_cxx<F>::descriptor().c_str());
245+
return getNonvirtualMethod<F>(name, jmethod_traits_from_cxx<F>::kDescriptor.c_str());
246246
}
247247

248248
template<typename F>
@@ -258,7 +258,7 @@ inline JNonvirtualMethod<F> JClass::getNonvirtualMethod(
258258
template<typename T>
259259
inline JField<PrimitiveOrJniType<T>>
260260
JClass::getField(const char* name) const {
261-
return getField<T>(name, jtype_traits<T>::descriptor().c_str());
261+
return getField<T>(name, jtype_traits<T>::kDescriptor.c_str());
262262
}
263263

264264
template<typename T>
@@ -274,7 +274,7 @@ inline JField<PrimitiveOrJniType<T>> JClass::getField(
274274
template<typename T>
275275
inline JStaticField<PrimitiveOrJniType<T>> JClass::getStaticField(
276276
const char* name) const {
277-
return getStaticField<T>(name, jtype_traits<T>::descriptor().c_str());
277+
return getStaticField<T>(name, jtype_traits<T>::kDescriptor.c_str());
278278
}
279279

280280
template<typename T>
@@ -416,19 +416,9 @@ inline ElementProxy<Target>::ElementProxy::operator local_ref<T> () {
416416
}
417417
}
418418

419-
template <typename T>
420-
std::string JArrayClass<T>::get_instantiated_java_descriptor() {
421-
return "[" + jtype_traits<T>::descriptor();
422-
};
423-
424-
template <typename T>
425-
std::string JArrayClass<T>::get_instantiated_base_name() {
426-
return get_instantiated_java_descriptor();
427-
};
428-
429419
template<typename T>
430420
auto JArrayClass<T>::newArray(size_t size) -> local_ref<javaobject> {
431-
static const auto elementClass = findClassStatic(jtype_traits<T>::base_name().c_str());
421+
static const auto elementClass = findClassStatic(jtype_traits<T>::kBaseName.c_str());
432422
const auto env = Environment::current();
433423
auto rawArray = env->NewObjectArray(size, elementClass.get(), nullptr);
434424
FACEBOOK_JNI_THROW_EXCEPTION_IF(!rawArray);
@@ -468,15 +458,6 @@ auto JPrimitiveArray<JArrayType>::getRegion(jsize start, jsize length)
468458
return buf;
469459
}
470460

471-
template <typename JArrayType>
472-
std::string JPrimitiveArray<JArrayType>::get_instantiated_java_descriptor() {
473-
return jtype_traits<JArrayType>::descriptor();
474-
}
475-
template <typename JArrayType>
476-
std::string JPrimitiveArray<JArrayType>::get_instantiated_base_name() {
477-
return JPrimitiveArray::get_instantiated_java_descriptor();
478-
}
479-
480461
template <typename JArrayType>
481462
auto JPrimitiveArray<JArrayType>::pin() -> PinnedPrimitiveArray<T, PinnedArrayAlloc<T>> {
482463
return PinnedPrimitiveArray<T, PinnedArrayAlloc<T>>{this->self(), 0, 0};
@@ -674,13 +655,13 @@ inline PinnedPrimitiveArray<T, Alloc>::PinnedPrimitiveArray(alias_ref<typename j
674655

675656
template<typename T, typename Base, typename JType>
676657
inline alias_ref<JClass> JavaClass<T, Base, JType>::javaClassStatic() {
677-
static auto cls = findClassStatic(jtype_traits<typename T::javaobject>::base_name().c_str());
658+
static auto cls = findClassStatic(jtype_traits<typename T::javaobject>::kBaseName.c_str());
678659
return cls;
679660
}
680661

681662
template<typename T, typename Base, typename JType>
682663
inline local_ref<JClass> JavaClass<T, Base, JType>::javaClassLocal() {
683-
std::string className(jtype_traits<typename T::javaobject>::base_name().c_str());
664+
std::string className(jtype_traits<typename T::javaobject>::kBaseName.c_str());
684665
return findClassLocal(className.c_str());
685666
}
686667

cxx/fbjni/detail/CoreClasses.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
#include <jni.h>
3232

33+
#include <fbjni/detail/SimpleFixedString.h>
34+
3335
namespace facebook {
3436
namespace jni {
3537

@@ -113,8 +115,8 @@ class JObject : detail::JObjectBase {
113115
public:
114116
static constexpr auto kJavaDescriptor = "Ljava/lang/Object;";
115117

116-
static constexpr const char* get_instantiated_java_descriptor() { return nullptr; }
117-
static constexpr const char* get_instantiated_base_name() { return nullptr; }
118+
static constexpr detail::SimpleFixedString<0> get_instantiated_java_descriptor() { return ""; }
119+
static constexpr detail::SimpleFixedString<0> get_instantiated_base_name() { return ""; }
118120

119121
/// Get a @ref local_ref of the object's class
120122
local_ref<JClass> getClass() const noexcept;
@@ -423,8 +425,13 @@ class JArrayClass : public JavaClass<JArrayClass<T>, detail::JTypeArray> {
423425
// javaobject is the jni type of the array.
424426
using javaobject = typename JavaClass<JArrayClass<T>, detail::JTypeArray>::javaobject;
425427
static constexpr const char* kJavaDescriptor = nullptr;
426-
static std::string get_instantiated_java_descriptor();
427-
static std::string get_instantiated_base_name();
428+
static constexpr auto /* detail::SimpleFixedString<_> */ get_instantiated_java_descriptor() {
429+
return "[" + jtype_traits<T>::kDescriptor;
430+
}
431+
432+
static constexpr auto /* detail::SimpleFixedString<_> */ get_instantiated_base_name() {
433+
return get_instantiated_java_descriptor();
434+
}
428435

429436
/// Allocate a new array from Java heap, for passing as a JNI parameter or return value.
430437
/// NOTE: if using as a return value, you want to call release() instead of get() on the
@@ -480,8 +487,12 @@ class JPrimitiveArray :
480487
static_assert(is_jni_primitive_array<JArrayType>(), "");
481488
public:
482489
static constexpr const char* kJavaDescriptor = nullptr;
483-
static std::string get_instantiated_java_descriptor();
484-
static std::string get_instantiated_base_name();
490+
static constexpr auto /* detail::SimpleFixedString<_> */ get_instantiated_java_descriptor() {
491+
return jtype_traits<JArrayType>::kDescriptor;
492+
}
493+
static constexpr auto /* detail::SimpleFixedString<_> */ get_instantiated_base_name() {
494+
return JPrimitiveArray::get_instantiated_java_descriptor();
495+
}
485496

486497
using T = typename jtype_traits<JArrayType>::entry_type;
487498

cxx/fbjni/detail/Hybrid.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <memory>
2020
#include <type_traits>
2121

22+
#include <fbjni/detail/SimpleFixedString.h>
23+
2224
#include "CoreClasses.h"
2325

2426
namespace facebook {
@@ -136,8 +138,8 @@ class HybridClass : public detail::HybridTraits<Base>::CxxBase {
136138
// T::kJavaDescriptor directly. jtype_traits support this escape hatch for
137139
// such a case.
138140
static constexpr const char* kJavaDescriptor = nullptr;
139-
static std::string get_instantiated_java_descriptor();
140-
static std::string get_instantiated_base_name();
141+
static constexpr auto /* detail::SimpleFixedString<_> */ get_instantiated_java_descriptor();
142+
static constexpr auto /* detail::SimpleFixedString<_> */ get_instantiated_base_name();
141143

142144
using HybridType = T;
143145

@@ -271,14 +273,15 @@ inline T* HybridClass<T, B>::JavaPart::cthis() const {
271273
};
272274

273275
template <typename T, typename B>
274-
/* static */ inline std::string HybridClass<T, B>::JavaPart::get_instantiated_java_descriptor() {
275-
return T::kJavaDescriptor;
276+
constexpr auto /* detail::SimpleFixedString<_> */ HybridClass<T, B>::JavaPart::get_instantiated_java_descriptor() {
277+
constexpr auto len = detail::constexpr_strlen(T::kJavaDescriptor);
278+
return detail::SimpleFixedString<len>(T::kJavaDescriptor, len);
276279
}
277280

278281
template <typename T, typename B>
279-
/* static */ inline std::string HybridClass<T, B>::JavaPart::get_instantiated_base_name() {
280-
auto name = get_instantiated_java_descriptor();
281-
return name.substr(1, name.size() - 2);
282+
/* static */ constexpr auto /* detail::SimpleFixedString<_> */ HybridClass<T, B>::JavaPart::get_instantiated_base_name() {
283+
constexpr auto len = detail::constexpr_strlen(T::kJavaDescriptor);
284+
return detail::SimpleFixedString<len>(T::kJavaDescriptor + 1, len - 2);
282285
}
283286

284287
// Given a *_ref object which refers to a hybrid class, this will reach inside

cxx/fbjni/detail/Meta-inl.h

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#include <jni.h>
2020

21+
#include <fbjni/detail/SimpleFixedString.h>
22+
2123
#include "Common.h"
2224
#include "Exceptions.h"
2325
#include "MetaConvert.h"
@@ -387,35 +389,24 @@ inline void JStaticField<T>::set(jclass jcls, T value) noexcept {
387389
namespace internal {
388390

389391
template<typename Head>
390-
inline std::string JavaDescriptor() {
391-
return jtype_traits<Head>::descriptor();
392+
constexpr auto /* detail::SimpleFixedString<_> */ JavaDescriptor() {
393+
return jtype_traits<Head>::kDescriptor;
392394
}
393395

394396
template<typename Head, typename Elem, typename... Tail>
395-
inline std::string JavaDescriptor() {
397+
constexpr auto /* detail::SimpleFixedString<_> */ JavaDescriptor() {
396398
return JavaDescriptor<Head>() + JavaDescriptor<Elem, Tail...>();
397399
}
398400

399401
template<typename R, typename Arg1, typename... Args>
400-
inline std::string JMethodDescriptor() {
402+
constexpr auto /* detail::SimpleFixedString<_> */ JMethodDescriptor() {
401403
return "(" + JavaDescriptor<Arg1, Args...>() + ")" + JavaDescriptor<R>();
402404
}
403405

404406
template<typename R>
405-
inline std::string JMethodDescriptor() {
407+
constexpr auto /* detail::SimpleFixedString<_> */ JMethodDescriptor() {
406408
return "()" + JavaDescriptor<R>();
407409
}
408410

409411
} // internal
410-
411-
template<typename R, typename... Args>
412-
inline std::string jmethod_traits<R(Args...)>::descriptor() {
413-
return internal::JMethodDescriptor<R, Args...>();
414-
}
415-
416-
template<typename R, typename... Args>
417-
inline std::string jmethod_traits<R(Args...)>::constructor_descriptor() {
418-
return internal::JMethodDescriptor<void, Args...>();
419-
}
420-
421412
}}

cxx/fbjni/detail/Meta.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright 2018-present, Facebook, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
// These two includes must be before Meta.h or we have circular include issues.
18+
#include "CoreClasses.h"
19+
#include "TypeTraits.h"
20+
#include "Meta.h"
21+
22+
namespace facebook {
23+
namespace jni {
24+
25+
/* static */ constexpr detail::SimpleFixedString<1> jtype_traits<void>::kDescriptor;
26+
27+
#define DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(TYPE, DSC) \
28+
/* static */ constexpr decltype(detail::makeSimpleFixedString(#DSC)) jtype_traits<TYPE>::kDescriptor; \
29+
/* static */ constexpr decltype(jtype_traits<TYPE>::kDescriptor) jtype_traits<TYPE>::kBaseName; \
30+
/* static */ constexpr decltype(detail::makeSimpleFixedString("[" #DSC)) jtype_traits<TYPE ## Array>::kDescriptor; \
31+
/* static */ constexpr decltype(jtype_traits<TYPE ## Array>::kDescriptor) jtype_traits<TYPE ## Array>::kBaseName;
32+
33+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jboolean, Z)
34+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jbyte, B)
35+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jchar, C)
36+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jshort, S)
37+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jint, I)
38+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jlong, J)
39+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jfloat, F)
40+
DEFINE_CONSTANTS_FOR_FIELD_AND_ARRAY_TRAIT(jdouble, D)
41+
42+
} // namespace jni
43+
} // namespace facebook

0 commit comments

Comments
 (0)