Coverage Report

Created: 2026-09-09 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/util/jni-util.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <butil/macros.h>
21
#include <jni.h>
22
#include <limits.h>
23
#include <stddef.h>
24
#include <stdint.h>
25
26
#include <string>
27
28
#include "common/status.h"
29
#include "jni_md.h"
30
#include "util/defer_op.h"
31
#include "util/thrift_util.h"
32
33
#ifdef USE_HADOOP_HDFS
34
// defined in hadoop/hadoop-hdfs-project/hadoop-hdfs/src/main/native/libhdfs/jni_helper.c
35
extern "C" JNIEnv* getJNIEnv(void);
36
#endif
37
38
namespace doris {
39
40
#define RETURN_ERROR_IF_EXC(env)                      \
41
298k
    do {                                              \
42
298k
        if (env->ExceptionCheck()) [[unlikely]]       \
43
4
            return Jni::Env::GetJniExceptionMsg(env); \
44
298k
    } while (false)
45
46
//In order to reduce the potential risks caused by not handling exceptions,
47
// you need to refer to  https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html
48
// to confirm whether the jni method will throw an exception.
49
50
namespace Jni {
51
class Env {
52
public:
53
240k
    static Status Get(JNIEnv** env) {
54
240k
        if (tls_env_) {
55
240k
            *env = tls_env_;
56
240k
        } else {
57
220
            Status status = GetJNIEnvSlowPath(env);
58
220
            if (!status.ok()) {
59
0
                return status;
60
0
            }
61
220
        }
62
240k
        if (*env == nullptr) [[unlikely]] {
63
0
            return Status::JniError("Failed to get JNIEnv: it is nullptr.");
64
0
        }
65
240k
        return Status::OK();
66
240k
    }
67
68
7
    static Status Init() { return init_throw_exception(); }
69
70
    static Status GetJniExceptionMsg(JNIEnv* env, bool log_stack = true,
71
                                     const std::string& prefix = "") WARN_UNUSED_RESULT;
72
73
private:
74
    static Status GetJNIEnvSlowPath(JNIEnv** env);
75
7
    static Status init_throw_exception() {
76
7
        JNIEnv* env = nullptr;
77
7
        RETURN_IF_ERROR(Jni::Env::Get(&env));
78
79
        // Find JniUtil class and create a global ref.
80
7
        jclass local_jni_util_cl = env->FindClass("org/apache/doris/common/jni/utils/JniUtil");
81
7
        if (local_jni_util_cl == nullptr) {
82
0
            if (env->ExceptionOccurred()) {
83
0
                env->ExceptionDescribe();
84
0
            }
85
0
            return Status::JniError("Failed to find JniUtil class.");
86
0
        }
87
7
        jni_util_cl_ = reinterpret_cast<jclass>(env->NewGlobalRef(local_jni_util_cl));
88
7
        env->DeleteLocalRef(local_jni_util_cl);
89
7
        if (jni_util_cl_ == nullptr) {
90
0
            if (env->ExceptionOccurred()) {
91
0
                env->ExceptionDescribe();
92
0
            }
93
0
            return Status::JniError("Failed to create global reference to JniUtil class.");
94
0
        }
95
7
        if (env->ExceptionOccurred()) {
96
0
            return Status::JniError("Failed to delete local reference to JniUtil class.");
97
0
        }
98
99
        // Throwable toString()
100
7
        throwable_to_string_id_ = env->GetStaticMethodID(
101
7
                jni_util_cl_, "throwableToString", "(Ljava/lang/Throwable;)Ljava/lang/String;");
102
7
        if (throwable_to_string_id_ == nullptr) {
103
0
            if (env->ExceptionOccurred()) {
104
0
                env->ExceptionDescribe();
105
0
            }
106
0
            return Status::JniError("Failed to find JniUtil.throwableToString method.");
107
0
        }
108
109
        // throwableToStackTrace()
110
7
        throwable_to_stack_trace_id_ = env->GetStaticMethodID(
111
7
                jni_util_cl_, "throwableToStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
112
7
        if (throwable_to_stack_trace_id_ == nullptr) {
113
0
            if (env->ExceptionOccurred()) {
114
0
                env->ExceptionDescribe();
115
0
            }
116
0
            return Status::JniError("Failed to find JniUtil.throwableToFullStackTrace method.");
117
0
        }
118
7
        return Status::OK();
119
7
    }
120
121
private:
122
    // Thread-local cache of the JNIEnv for this thread.
123
    static __thread JNIEnv* tls_env_;
124
125
    //for exception
126
    static jclass jni_util_cl_;
127
    static jmethodID throwable_to_string_id_;
128
    static jmethodID throwable_to_stack_trace_id_;
129
};
130
131
enum RefType { Local, Global };
132
133
enum BufferType { Chars, ByteArray };
134
135
template <RefType Ref>
136
struct RefHelper {};
137
138
template <>
139
struct RefHelper<Local> {
140
6.60k
    static jobject create(JNIEnv* env, jobject obj) { return env->NewLocalRef(obj); }
141
142
206k
    static void destroy(JNIEnv* env, jobject obj) { env->DeleteLocalRef(obj); }
143
144
213k
    static Status get_env(JNIEnv** env) {
145
        // Get the JNIEnv* corresponding to current thread.
146
213k
        return Jni::Env::Get(env);
147
213k
    }
148
};
149
150
template <>
151
struct RefHelper<Global> {
152
10.7k
    static jobject create(JNIEnv* env, jobject obj) { return env->NewGlobalRef(obj); }
153
154
10.6k
    static void destroy(JNIEnv* env, jobject obj) { env->DeleteGlobalRef(obj); }
155
156
10.6k
    static Status get_env(JNIEnv** env) { return Jni::Env::Get(env); }
157
};
158
159
template <RefType Ref>
160
class Object;
161
162
template <RefType Ref>
163
class Class;
164
165
class MethodId {
166
public:
167
19.3k
    MethodId() = default;
168
165k
    bool uninitialized() const { return _id == nullptr; }
169
170
    template <RefType U>
171
    friend class Object;
172
173
    template <RefType U>
174
    friend class Class;
175
176
private:
177
    jmethodID _id = nullptr;
178
};
179
180
class FieldId {
181
public:
182
42
    FieldId() = default;
183
84
    bool uninitialized() const { return _id == nullptr; }
184
185
    template <RefType U>
186
    friend class Object;
187
188
    template <RefType U>
189
    friend class Class;
190
191
private:
192
    jfieldID _id = nullptr;
193
};
194
195
enum CallTag {
196
    ObjectMethod,
197
    IntMethod,
198
    LongMethod,
199
    VoidMethod,
200
    BooleanMethod,
201
202
    StaticObjectMethod,
203
    StaticIntMethod,
204
    StaticLongMethod,
205
    StaticVoidMethod,
206
207
    NewObject,
208
209
    NonvirtualVoidMethod,
210
    NonvirtualObjectMethod,
211
    NonvirtualIntMethod,
212
    NonvirtualBooleanMethod,
213
};
214
215
template <CallTag Tag>
216
struct CallHelper {};
217
218
template <>
219
struct CallHelper<ObjectMethod> {
220
100k
    static jobject call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
221
100k
        return env->CallObjectMethodA(obj, methodID, args);
222
100k
    }
223
    using BASE_TYPE = jobject;
224
    using RETURN_TYPE = jobject;
225
};
226
227
template <>
228
struct CallHelper<IntMethod> {
229
1.98k
    static jint call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
230
1.98k
        return env->CallIntMethodA(obj, methodID, args);
231
1.98k
    }
232
    using BASE_TYPE = jobject;
233
    using RETURN_TYPE = jint;
234
};
235
236
template <>
237
struct CallHelper<LongMethod> {
238
24.5k
    static jlong call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
239
24.5k
        return env->CallLongMethodA(obj, methodID, args);
240
24.5k
    }
241
    using BASE_TYPE = jobject;
242
    using RETURN_TYPE = jlong;
243
};
244
245
template <>
246
struct CallHelper<VoidMethod> {
247
1.17k
    static void call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
248
1.17k
        env->CallVoidMethodA(obj, methodID, args);
249
1.17k
    }
250
    using BASE_TYPE = jobject;
251
    using RETURN_TYPE = void;
252
};
253
254
template <>
255
struct CallHelper<BooleanMethod> {
256
6
    static jboolean call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
257
6
        return env->CallBooleanMethodA(obj, methodID, args);
258
6
    }
259
    using BASE_TYPE = jobject;
260
    using RETURN_TYPE = jboolean;
261
};
262
263
template <>
264
struct CallHelper<StaticObjectMethod> {
265
2.64k
    static jobject call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
266
2.64k
        return env->CallStaticObjectMethodA(cls, methodID, args);
267
2.64k
    }
268
    using BASE_TYPE = jclass;
269
    using RETURN_TYPE = jobject;
270
};
271
272
template <>
273
struct CallHelper<StaticIntMethod> {
274
0
    static jint call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
275
0
        return env->CallStaticIntMethodA(cls, methodID, args);
276
0
    }
277
    using BASE_TYPE = jclass;
278
    using RETURN_TYPE = jint;
279
};
280
281
template <>
282
struct CallHelper<StaticLongMethod> {
283
0
    static jlong call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
284
0
        return env->CallStaticLongMethodA(cls, methodID, args);
285
0
    }
286
    using BASE_TYPE = jclass;
287
    using RETURN_TYPE = jlong;
288
};
289
290
template <>
291
struct CallHelper<StaticVoidMethod> {
292
0
    static void call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
293
0
        return env->CallStaticVoidMethodA(cls, methodID, args);
294
0
    }
295
296
    using BASE_TYPE = jclass;
297
    using RETURN_TYPE = void;
298
};
299
300
template <>
301
struct CallHelper<NewObject> {
302
10.7k
    static jobject call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
303
10.7k
        return env->NewObjectA(cls, methodID, args);
304
10.7k
    }
305
306
    using BASE_TYPE = jclass;
307
    using RETURN_TYPE = jobject;
308
};
309
310
template <>
311
struct CallHelper<NonvirtualVoidMethod> {
312
    static void call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
313
6.32k
                          const jvalue* args) {
314
6.32k
        return env->CallNonvirtualVoidMethodA(obj, clazz, methodID, args);
315
6.32k
    }
316
317
    using BASE_TYPE = jobject;
318
    using RETURN_TYPE = void;
319
};
320
321
template <>
322
struct CallHelper<NonvirtualObjectMethod> {
323
    static jobject call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
324
77
                             const jvalue* args) {
325
77
        return env->CallNonvirtualObjectMethodA(obj, clazz, methodID, args);
326
77
    }
327
328
    using BASE_TYPE = jobject;
329
    using RETURN_TYPE = jobject;
330
};
331
332
template <>
333
struct CallHelper<NonvirtualIntMethod> {
334
    static jint call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
335
0
                          const jvalue* args) {
336
0
        return env->CallNonvirtualIntMethodA(obj, clazz, methodID, args);
337
0
    }
338
339
    using BASE_TYPE = jobject;
340
    using RETURN_TYPE = jint;
341
};
342
343
template <>
344
struct CallHelper<NonvirtualBooleanMethod> {
345
    static jboolean call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
346
0
                              const jvalue* args) {
347
0
        return env->CallNonvirtualBooleanMethodA(obj, clazz, methodID, args);
348
0
    }
349
350
    using BASE_TYPE = jobject;
351
    using RETURN_TYPE = jboolean;
352
};
353
354
template <CallTag tag>
355
class FunctionCall {
356
public:
357
    FunctionCall(FunctionCall&& other) noexcept = default;
358
359
    static FunctionCall instance(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
360
141k
                                 jmethodID method_id) {
361
141k
        return FunctionCall(env, base, method_id);
362
141k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EE8instanceEP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
360
2.64k
                                 jmethodID method_id) {
361
2.64k
        return FunctionCall(env, base, method_id);
362
2.64k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
360
100k
                                 jmethodID method_id) {
361
100k
        return FunctionCall(env, base, method_id);
362
100k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
360
24.5k
                                 jmethodID method_id) {
361
24.5k
        return FunctionCall(env, base, method_id);
362
24.5k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE1EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
360
1.98k
                                 jmethodID method_id) {
361
1.98k
        return FunctionCall(env, base, method_id);
362
1.98k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE8instanceEP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
360
10.7k
                                 jmethodID method_id) {
361
10.7k
        return FunctionCall(env, base, method_id);
362
10.7k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
360
1.17k
                                 jmethodID method_id) {
361
1.17k
        return FunctionCall(env, base, method_id);
362
1.17k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE4EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
360
6
                                 jmethodID method_id) {
361
6
        return FunctionCall(env, base, method_id);
362
6
    }
Unexecuted instantiation: _ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE8instanceEP7JNIEnv_P7_jclassP10_jmethodID
363
364
    /// Pass a primitive arg (eg an integer).
365
    /// Multiple arguments may be passed by repeated calls.
366
    template <class T>
367
        requires std::disjunction_v<std::is_same<T, jboolean>, std::is_same<T, jbyte>,
368
                                    std::is_same<T, jchar>, std::is_same<T, jshort>,
369
                                    std::is_same<T, jint>, std::is_same<T, jlong>,
370
                                    std::is_same<T, jfloat>, std::is_same<T, jdouble>>
371
14.9k
    FunctionCall& with_arg(T arg) {
372
14.9k
        jvalue v;
373
14.9k
        std::memset(&v, 0, sizeof(v));
374
14.9k
        if constexpr (std::is_same_v<T, jboolean>) {
375
219
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
13.4k
        } else if constexpr (std::is_same_v<T, jint>) {
383
13.4k
            v.i = arg;
384
13.4k
        } else if constexpr (std::is_same_v<T, jlong>) {
385
1.33k
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
14.9k
        _args.push_back(v);
394
14.9k
        return *this;
395
14.9k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
371
7.26k
    FunctionCall& with_arg(T arg) {
372
7.26k
        jvalue v;
373
7.26k
        std::memset(&v, 0, sizeof(v));
374
        if constexpr (std::is_same_v<T, jboolean>) {
375
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
7.26k
        } else if constexpr (std::is_same_v<T, jint>) {
383
7.26k
            v.i = arg;
384
        } else if constexpr (std::is_same_v<T, jlong>) {
385
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
7.26k
        _args.push_back(v);
394
7.26k
        return *this;
395
7.26k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
371
5.52k
    FunctionCall& with_arg(T arg) {
372
5.52k
        jvalue v;
373
5.52k
        std::memset(&v, 0, sizeof(v));
374
        if constexpr (std::is_same_v<T, jboolean>) {
375
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
5.52k
        } else if constexpr (std::is_same_v<T, jint>) {
383
5.52k
            v.i = arg;
384
        } else if constexpr (std::is_same_v<T, jlong>) {
385
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
5.52k
        _args.push_back(v);
394
5.52k
        return *this;
395
5.52k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argIhQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
371
219
    FunctionCall& with_arg(T arg) {
372
219
        jvalue v;
373
219
        std::memset(&v, 0, sizeof(v));
374
219
        if constexpr (std::is_same_v<T, jboolean>) {
375
219
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
        } else if constexpr (std::is_same_v<T, jint>) {
383
            v.i = arg;
384
        } else if constexpr (std::is_same_v<T, jlong>) {
385
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
219
        _args.push_back(v);
394
219
        return *this;
395
219
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
371
661
    FunctionCall& with_arg(T arg) {
372
661
        jvalue v;
373
661
        std::memset(&v, 0, sizeof(v));
374
        if constexpr (std::is_same_v<T, jboolean>) {
375
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
661
        } else if constexpr (std::is_same_v<T, jint>) {
383
661
            v.i = arg;
384
        } else if constexpr (std::is_same_v<T, jlong>) {
385
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
661
        _args.push_back(v);
394
661
        return *this;
395
661
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
371
1.14k
    FunctionCall& with_arg(T arg) {
372
1.14k
        jvalue v;
373
1.14k
        std::memset(&v, 0, sizeof(v));
374
        if constexpr (std::is_same_v<T, jboolean>) {
375
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
        } else if constexpr (std::is_same_v<T, jint>) {
383
            v.i = arg;
384
1.14k
        } else if constexpr (std::is_same_v<T, jlong>) {
385
1.14k
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
1.14k
        _args.push_back(v);
394
1.14k
        return *this;
395
1.14k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
371
192
    FunctionCall& with_arg(T arg) {
372
192
        jvalue v;
373
192
        std::memset(&v, 0, sizeof(v));
374
        if constexpr (std::is_same_v<T, jboolean>) {
375
            v.z = arg;
376
        } else if constexpr (std::is_same_v<T, jbyte>) {
377
            v.b = arg;
378
        } else if constexpr (std::is_same_v<T, jchar>) {
379
            v.c = arg;
380
        } else if constexpr (std::is_same_v<T, jshort>) {
381
            v.s = arg;
382
        } else if constexpr (std::is_same_v<T, jint>) {
383
            v.i = arg;
384
192
        } else if constexpr (std::is_same_v<T, jlong>) {
385
192
            v.j = arg;
386
        } else if constexpr (std::is_same_v<T, jfloat>) {
387
            v.f = arg;
388
        } else if constexpr (std::is_same_v<T, jdouble>) {
389
            v.d = arg;
390
        } else {
391
            static_assert(false);
392
        }
393
192
        _args.push_back(v);
394
192
        return *this;
395
192
    }
396
397
    template <RefType Ref>
398
    FunctionCall& with_arg(const Object<Ref>& obj) WARN_UNUSED_RESULT;
399
400
    template <typename ReturnType>
401
        requires(std::is_same_v<typename CallHelper<tag>::RETURN_TYPE, ReturnType>)
402
26.5k
    Status call(ReturnType* result) {
403
26.5k
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
404
26.5k
        RETURN_ERROR_IF_EXC(_env);
405
26.5k
        return Status::OK();
406
26.5k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE4callIlQsr3stdE9is_same_vINS0_10CallHelperIXT_EE11RETURN_TYPEETL0__EEENS_6StatusEPT_
Line
Count
Source
402
24.5k
    Status call(ReturnType* result) {
403
24.5k
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
404
24.5k
        RETURN_ERROR_IF_EXC(_env);
405
24.5k
        return Status::OK();
406
24.5k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE1EE4callIiQsr3stdE9is_same_vINS0_10CallHelperIXT_EE11RETURN_TYPEETL0__EEENS_6StatusEPT_
Line
Count
Source
402
1.98k
    Status call(ReturnType* result) {
403
1.98k
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
404
1.98k
        RETURN_ERROR_IF_EXC(_env);
405
1.98k
        return Status::OK();
406
1.98k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE4EE4callIhQsr3stdE9is_same_vINS0_10CallHelperIXT_EE11RETURN_TYPEETL0__EEENS_6StatusEPT_
Line
Count
Source
402
6
    Status call(ReturnType* result) {
403
6
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
404
6
        RETURN_ERROR_IF_EXC(_env);
405
6
        return Status::OK();
406
6
    }
407
408
    Status call(Object<Local>* result);
409
410
    Status call(Object<Global>* result);
411
412
17.7k
    Status call() {
413
17.7k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
414
        if constexpr (std::disjunction_v<
415
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
416
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
417
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
418
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
419
1.17k
                              std::is_same<return_type, void>>) {
420
1.17k
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
421
1.17k
            RETURN_ERROR_IF_EXC(_env);
422
16.6k
        } else if constexpr (std::is_same_v<return_type, jobject>) {
423
16.6k
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
424
16.6k
            _env->DeleteLocalRef(tmp);
425
16.6k
            RETURN_ERROR_IF_EXC(_env);
426
        } else {
427
            static_assert(false);
428
        }
429
17.7k
        return Status::OK();
430
17.7k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE4callEv
Line
Count
Source
412
16.6k
    Status call() {
413
16.6k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
414
        if constexpr (std::disjunction_v<
415
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
416
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
417
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
418
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
419
                              std::is_same<return_type, void>>) {
420
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
421
            RETURN_ERROR_IF_EXC(_env);
422
16.6k
        } else if constexpr (std::is_same_v<return_type, jobject>) {
423
16.6k
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
424
16.6k
            _env->DeleteLocalRef(tmp);
425
16.6k
            RETURN_ERROR_IF_EXC(_env);
426
        } else {
427
            static_assert(false);
428
        }
429
16.6k
        return Status::OK();
430
16.6k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE4callEv
Line
Count
Source
412
1.17k
    Status call() {
413
1.17k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
414
        if constexpr (std::disjunction_v<
415
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
416
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
417
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
418
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
419
1.17k
                              std::is_same<return_type, void>>) {
420
1.17k
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
421
1.17k
            RETURN_ERROR_IF_EXC(_env);
422
        } else if constexpr (std::is_same_v<return_type, jobject>) {
423
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
424
            _env->DeleteLocalRef(tmp);
425
            RETURN_ERROR_IF_EXC(_env);
426
        } else {
427
            static_assert(false);
428
        }
429
1.17k
        return Status::OK();
430
1.17k
    }
Unexecuted instantiation: _ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE4callEv
431
432
protected:
433
    explicit FunctionCall(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
434
                          jmethodID method_id)
435
147k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EEC2EP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
435
2.64k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
100k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
24.5k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE1EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
1.98k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EEC2EP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
435
10.7k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE10EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
6.32k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
1.17k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE11EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
77
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE4EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
435
6
            : _env(env), _base(base), _method(method_id) {}
Unexecuted instantiation: _ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EEC2EP7JNIEnv_P7_jclassP10_jmethodID
436
437
    JNIEnv* _env = nullptr;
438
    CallHelper<tag>::BASE_TYPE _base; // is jobject/jclass  not need new/delete local/global ref.
439
    const jmethodID _method = nullptr;
440
    std::vector<jvalue> _args;
441
    Status _st = Status::OK();
442
    DISALLOW_COPY_AND_ASSIGN(FunctionCall);
443
};
444
445
template <CallTag tag>
446
class NonvirtualFunctionCall : public FunctionCall<tag> {
447
public:
448
    NonvirtualFunctionCall(NonvirtualFunctionCall&& other) noexcept = default;
449
450
    static NonvirtualFunctionCall instance(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
451
6.39k
                                           jclass cls, jmethodID method_id) {
452
6.39k
        return NonvirtualFunctionCall(env, base, cls, method_id);
453
6.39k
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE10EE8instanceEP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
451
6.32k
                                           jclass cls, jmethodID method_id) {
452
6.32k
        return NonvirtualFunctionCall(env, base, cls, method_id);
453
6.32k
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE11EE8instanceEP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
451
77
                                           jclass cls, jmethodID method_id) {
452
77
        return NonvirtualFunctionCall(env, base, cls, method_id);
453
77
    }
454
455
    // no override
456
    template <class T>
457
        requires std::disjunction_v<std::is_same<T, jboolean>, std::is_same<T, jbyte>,
458
                                    std::is_same<T, jchar>, std::is_same<T, jshort>,
459
                                    std::is_same<T, jint>, std::is_same<T, jlong>,
460
                                    std::is_same<T, jfloat>, std::is_same<T, jdouble>>
461
189
    NonvirtualFunctionCall& with_arg(T arg) {
462
189
        jvalue v;
463
189
        std::memset(&v, 0, sizeof(v));
464
        if constexpr (std::is_same_v<T, jboolean>) {
465
            v.z = arg;
466
        } else if constexpr (std::is_same_v<T, jbyte>) {
467
            v.b = arg;
468
        } else if constexpr (std::is_same_v<T, jchar>) {
469
            v.c = arg;
470
        } else if constexpr (std::is_same_v<T, jshort>) {
471
            v.s = arg;
472
        } else if constexpr (std::is_same_v<T, jint>) {
473
            v.i = arg;
474
189
        } else if constexpr (std::is_same_v<T, jlong>) {
475
189
            v.j = arg;
476
        } else if constexpr (std::is_same_v<T, jfloat>) {
477
            v.f = arg;
478
        } else if constexpr (std::is_same_v<T, jdouble>) {
479
            v.d = arg;
480
        } else {
481
            static_assert(false);
482
        }
483
189
        this->_args.push_back(v);
484
189
        return *this;
485
189
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE10EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
461
113
    NonvirtualFunctionCall& with_arg(T arg) {
462
113
        jvalue v;
463
113
        std::memset(&v, 0, sizeof(v));
464
        if constexpr (std::is_same_v<T, jboolean>) {
465
            v.z = arg;
466
        } else if constexpr (std::is_same_v<T, jbyte>) {
467
            v.b = arg;
468
        } else if constexpr (std::is_same_v<T, jchar>) {
469
            v.c = arg;
470
        } else if constexpr (std::is_same_v<T, jshort>) {
471
            v.s = arg;
472
        } else if constexpr (std::is_same_v<T, jint>) {
473
            v.i = arg;
474
113
        } else if constexpr (std::is_same_v<T, jlong>) {
475
113
            v.j = arg;
476
        } else if constexpr (std::is_same_v<T, jfloat>) {
477
            v.f = arg;
478
        } else if constexpr (std::is_same_v<T, jdouble>) {
479
            v.d = arg;
480
        } else {
481
            static_assert(false);
482
        }
483
113
        this->_args.push_back(v);
484
113
        return *this;
485
113
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE11EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
461
76
    NonvirtualFunctionCall& with_arg(T arg) {
462
76
        jvalue v;
463
76
        std::memset(&v, 0, sizeof(v));
464
        if constexpr (std::is_same_v<T, jboolean>) {
465
            v.z = arg;
466
        } else if constexpr (std::is_same_v<T, jbyte>) {
467
            v.b = arg;
468
        } else if constexpr (std::is_same_v<T, jchar>) {
469
            v.c = arg;
470
        } else if constexpr (std::is_same_v<T, jshort>) {
471
            v.s = arg;
472
        } else if constexpr (std::is_same_v<T, jint>) {
473
            v.i = arg;
474
76
        } else if constexpr (std::is_same_v<T, jlong>) {
475
76
            v.j = arg;
476
        } else if constexpr (std::is_same_v<T, jfloat>) {
477
            v.f = arg;
478
        } else if constexpr (std::is_same_v<T, jdouble>) {
479
            v.d = arg;
480
        } else {
481
            static_assert(false);
482
        }
483
76
        this->_args.push_back(v);
484
76
        return *this;
485
76
    }
486
487
    template <RefType Ref>
488
    NonvirtualFunctionCall& with_arg(const Object<Ref>& obj) WARN_UNUSED_RESULT;
489
490
    // no override
491
6.31k
    Status call() {
492
6.31k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
493
        if constexpr (std::disjunction_v<
494
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
495
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
496
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
497
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
498
6.31k
                              std::is_same<return_type, void>>) {
499
6.31k
            CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
500
6.31k
                                       this->_args.data());
501
6.31k
            RETURN_ERROR_IF_EXC(this->_env);
502
        } else if constexpr (std::is_same_v<return_type, jobject>) {
503
            jobject tmp = CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
504
                                                     this->_args.data());
505
            RETURN_ERROR_IF_EXC(this->_env);
506
            this->_env->DeleteLocalRef(tmp);
507
        } else {
508
            static_assert(false);
509
        }
510
6.31k
        return Status::OK();
511
6.31k
    }
512
513
    Status call(Object<Local>* result);
514
515
    template <typename ReturnType>
516
        requires(std::is_same_v<typename CallHelper<tag>::RETURN_TYPE, ReturnType>)
517
    Status call(ReturnType* result) {
518
        *result = CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
519
                                             this->_args.data());
520
        RETURN_ERROR_IF_EXC(this->_env);
521
        return Status::OK();
522
    }
523
524
private:
525
    explicit NonvirtualFunctionCall(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
526
                                    jclass cls, jmethodID method_id)
527
6.39k
            : FunctionCall<tag>(env, base, method_id), _cls(cls) {}
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE10EEC2EP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
527
6.32k
            : FunctionCall<tag>(env, base, method_id), _cls(cls) {}
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE11EEC2EP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
527
77
            : FunctionCall<tag>(env, base, method_id), _cls(cls) {}
528
    jclass _cls;
529
    DISALLOW_COPY_AND_ASSIGN(NonvirtualFunctionCall);
530
};
531
532
/**
533
 * When writing JNI code, developers usually need to pay extra attention to several error-prone aspects, including:
534
 * 1. The reference type of jobject (local vs. global)
535
 * 2. The lifetime and scope of JNI references
536
 * 3. Proper release of references after use
537
 * 4. Explicit exception checking after JNI calls
538
 * Because these concerns are verbose and easy to overlook, they often lead to bugs or inconsistent code. To simplify this, 
539
 * we provide a wrapper framework around raw JNI APIs. The following describes how to use it (assuming the user already 
540
 * understands the basic JNI programming model).
541
 *
542
 * 0. Get JNIEnv* env: `Status st = Jni::Env::Get(&env)`
543
 * 1. Choose the reference type
544
 *   First, determine whether the JNI object should be a local or global reference. Based on this, create the corresponding C++ wrapper object:
545
 *   LocalObject / GlobalObject. If the exact JNI type is known, use specialized wrappers such as <Local/Global><Array/String/Class>. 
546
 * 2. Initialize the object
547
 *   For `jclass`, typically use: `Status st = Jni::Util::find_class(xxx);`
548
 *   For other object types, they are usually initialized via: `Status st = clazz.new_object(xxx).with_arg(xxx).call(&object) or by calling methods on existing objects.
549
 * 3. Call methods and retrieve results
550
 *   To invoke a method and obtain a return value, use: `Status st = object.call_<return_type>_method(xxx).call(&result);` 
551
 * 
552
 * Notes
553
 * 1. All JNI references are automatically released in the wrapper’s destructor, ensuring safe and deterministic cleanup.
554
 * 2. All framework method invocations return a Status.
555
 * The actual JNI return value is written to the address passed to call().
556
 * 
557
 * Example: be/test/util/jni_util_test.cpp
558
*/
559
template <RefType Ref>
560
class Object {
561
    // env->GetObjectRefType
562
public:
563
234k
    Object() = default;
_ZN5doris3Jni6ObjectILNS0_7RefTypeE1EEC2Ev
Line
Count
Source
563
10.9k
    Object() = default;
_ZN5doris3Jni6ObjectILNS0_7RefTypeE0EEC2Ev
Line
Count
Source
563
223k
    Object() = default;
564
565
    template <RefType U>
566
    friend class Object;
567
568
    template <RefType U>
569
    friend class Class;
570
571
    template <RefType U>
572
    friend class String;
573
574
    template <RefType U>
575
    friend class Array;
576
577
    template <BufferType bufferfType, RefType U>
578
    friend class BufferGuard;
579
580
    template <CallTag tag>
581
    friend class FunctionCall;
582
583
    template <CallTag tag>
584
    friend class NonvirtualFunctionCall;
585
586
233k
    virtual ~Object() {
587
233k
        if (_obj != nullptr) [[likely]] {
588
217k
            JNIEnv* env = nullptr;
589
217k
            if (Status st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
590
0
                LOG(WARNING) << "Can't destroy Jni Ref : " << st.msg();
591
0
                return;
592
0
            }
593
217k
            RefHelper<Ref>::destroy(env, _obj);
594
217k
        }
595
233k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE0EED2Ev
Line
Count
Source
586
222k
    virtual ~Object() {
587
222k
        if (_obj != nullptr) [[likely]] {
588
206k
            JNIEnv* env = nullptr;
589
206k
            if (Status st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
590
0
                LOG(WARNING) << "Can't destroy Jni Ref : " << st.msg();
591
0
                return;
592
0
            }
593
206k
            RefHelper<Ref>::destroy(env, _obj);
594
206k
        }
595
222k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE1EED2Ev
Line
Count
Source
586
10.9k
    virtual ~Object() {
587
10.9k
        if (_obj != nullptr) [[likely]] {
588
10.6k
            JNIEnv* env = nullptr;
589
10.6k
            if (Status st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
590
0
                LOG(WARNING) << "Can't destroy Jni Ref : " << st.msg();
591
0
                return;
592
0
            }
593
10.6k
            RefHelper<Ref>::destroy(env, _obj);
594
10.6k
        }
595
10.9k
    }
596
597
    template <RefType R>
598
17.2k
    static Status create(JNIEnv* env, const Object<R>& other, Object<Ref>* result) {
599
17.2k
        DCHECK(!other.uninitialized());
600
17.2k
        DCHECK(result->uninitialized());
601
602
17.2k
        result->_obj = RefHelper<Ref>::create(env, other._obj);
603
17.2k
        RETURN_ERROR_IF_EXC(env);
604
17.2k
        return Status::OK();
605
17.2k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE1EE6createILS2_0EEENS_6StatusEP7JNIEnv_RKNS1_IXT_EEEPS3_
Line
Count
Source
598
10.6k
    static Status create(JNIEnv* env, const Object<R>& other, Object<Ref>* result) {
599
10.6k
        DCHECK(!other.uninitialized());
600
10.6k
        DCHECK(result->uninitialized());
601
602
10.6k
        result->_obj = RefHelper<Ref>::create(env, other._obj);
603
10.6k
        RETURN_ERROR_IF_EXC(env);
604
10.6k
        return Status::OK();
605
10.6k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE0EE6createILS2_0EEENS_6StatusEP7JNIEnv_RKNS1_IXT_EEEPS3_
Line
Count
Source
598
6.60k
    static Status create(JNIEnv* env, const Object<R>& other, Object<Ref>* result) {
599
6.60k
        DCHECK(!other.uninitialized());
600
6.60k
        DCHECK(result->uninitialized());
601
602
6.60k
        result->_obj = RefHelper<Ref>::create(env, other._obj);
603
6.60k
        RETURN_ERROR_IF_EXC(env);
604
6.60k
        return Status::OK();
605
6.60k
    }
606
607
770k
    bool uninitialized() const { return _obj == nullptr; }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE13uninitializedEv
Line
Count
Source
607
586k
    bool uninitialized() const { return _obj == nullptr; }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE13uninitializedEv
Line
Count
Source
607
183k
    bool uninitialized() const { return _obj == nullptr; }
608
609
2
    void reset(JNIEnv* env) {
610
2
        if (_obj == nullptr) {
611
0
            return;
612
0
        }
613
2
        RefHelper<Ref>::destroy(env, _obj);
614
2
        _obj = nullptr;
615
2
    }
616
617
    template <RefType T>
618
120k
    bool equal(JNIEnv* env, const Object<T>& other) {
619
120k
        DCHECK(!uninitialized());
620
120k
        DCHECK(!other.uninitialized());
621
120k
        return env->IsSameObject(this->_obj, other._obj); //assume not throw exception.
622
120k
    }
623
624
100k
    FunctionCall<ObjectMethod> call_object_method(JNIEnv* env, MethodId method_id) const {
625
100k
        DCHECK(!this->uninitialized());
626
100k
        DCHECK(!method_id.uninitialized());
627
100k
        return FunctionCall<ObjectMethod>::instance(env, _obj, method_id._id);
628
100k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE18call_object_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
624
100k
    FunctionCall<ObjectMethod> call_object_method(JNIEnv* env, MethodId method_id) const {
625
100k
        DCHECK(!this->uninitialized());
626
        DCHECK(!method_id.uninitialized());
627
100k
        return FunctionCall<ObjectMethod>::instance(env, _obj, method_id._id);
628
100k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE18call_object_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
624
7
    FunctionCall<ObjectMethod> call_object_method(JNIEnv* env, MethodId method_id) const {
625
7
        DCHECK(!this->uninitialized());
626
        DCHECK(!method_id.uninitialized());
627
7
        return FunctionCall<ObjectMethod>::instance(env, _obj, method_id._id);
628
7
    }
629
630
1.98k
    FunctionCall<IntMethod> call_int_method(JNIEnv* env, MethodId method_id) const {
631
1.98k
        DCHECK(!this->uninitialized());
632
1.98k
        DCHECK(!method_id.uninitialized());
633
1.98k
        return FunctionCall<IntMethod>::instance(env, _obj, method_id._id);
634
1.98k
    }
635
636
24.5k
    FunctionCall<LongMethod> call_long_method(JNIEnv* env, MethodId method_id) const {
637
24.5k
        DCHECK(!this->uninitialized());
638
24.5k
        DCHECK(!method_id.uninitialized());
639
24.5k
        return FunctionCall<LongMethod>::instance(env, _obj, method_id._id);
640
24.5k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE16call_long_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
636
21.7k
    FunctionCall<LongMethod> call_long_method(JNIEnv* env, MethodId method_id) const {
637
21.7k
        DCHECK(!this->uninitialized());
638
        DCHECK(!method_id.uninitialized());
639
21.7k
        return FunctionCall<LongMethod>::instance(env, _obj, method_id._id);
640
21.7k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE16call_long_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
636
2.75k
    FunctionCall<LongMethod> call_long_method(JNIEnv* env, MethodId method_id) const {
637
2.75k
        DCHECK(!this->uninitialized());
638
        DCHECK(!method_id.uninitialized());
639
2.75k
        return FunctionCall<LongMethod>::instance(env, _obj, method_id._id);
640
2.75k
    }
641
642
1.17k
    FunctionCall<VoidMethod> call_void_method(JNIEnv* env, MethodId method_id) const {
643
1.17k
        DCHECK(!this->uninitialized());
644
1.17k
        DCHECK(!method_id.uninitialized());
645
1.17k
        return FunctionCall<VoidMethod>::instance(env, _obj, method_id._id);
646
1.17k
    }
647
648
6
    FunctionCall<BooleanMethod> call_boolean_method(JNIEnv* env, MethodId method_id) const {
649
6
        DCHECK(!this->uninitialized());
650
6
        DCHECK(!method_id.uninitialized());
651
6
        return FunctionCall<BooleanMethod>::instance(env, _obj, method_id._id);
652
6
    }
653
654
    template <RefType R>
655
    NonvirtualFunctionCall<NonvirtualVoidMethod> call_nonvirtual_void_method(
656
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
657
658
    template <RefType R>
659
    NonvirtualFunctionCall<NonvirtualObjectMethod> call_nonvirtual_object_method(
660
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
661
662
    template <RefType R>
663
    NonvirtualFunctionCall<NonvirtualIntMethod> call_nonvirtual_int_method(
664
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
665
666
    template <RefType R>
667
    NonvirtualFunctionCall<NonvirtualBooleanMethod> call_nonvirtual_boolean_method(
668
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
669
670
protected:
671
    jobject _obj = nullptr;
672
    DISALLOW_COPY_AND_ASSIGN(Object);
673
};
674
675
using LocalObject = Object<Local>;
676
using GlobalObject = Object<Global>;
677
678
static inline Status local_to_global_ref(JNIEnv* env, const LocalObject& local_ref,
679
10.7k
                                         GlobalObject* global_ref) {
680
10.7k
    return Object<Global>::create(env, local_ref, global_ref);
681
10.7k
}
Unexecuted instantiation: doris_main.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_0_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: config.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: doris_metrics.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
jvm_metrics.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Line
Count
Source
679
5.43k
                                         GlobalObject* global_ref) {
680
5.43k
    return Object<Global>::create(env, local_ref, global_ref);
681
5.43k
}
Unexecuted instantiation: unity_2_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_3_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_5_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_4_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_13_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
unity_1_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Line
Count
Source
679
5
                                         GlobalObject* global_ref) {
680
5
    return Object<Global>::create(env, local_ref, global_ref);
681
5
}
Unexecuted instantiation: unity_7_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_6_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_12_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_11_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_10_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_9_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_8_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hashjoin_build_sink.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: join_build_sink_operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: partitioned_aggregation_sink_operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: scan_operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vfile_result_writer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_31_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_30_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
unity_29_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Line
Count
Source
679
5.31k
                                         GlobalObject* global_ref) {
680
5.31k
    return Object<Global>::create(env, local_ref, global_ref);
681
5.31k
}
Unexecuted instantiation: unity_28_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_27_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_26_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_25_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_24_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_22_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_21_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_20_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_19_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_18_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_17_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_16_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_15_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_14_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: ai_functions.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: function_array_aggregation.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: function_date_or_datetime_computation.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: function_datetime_floor_ceil.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: in.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: uuid.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: arrow_row_batch.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: arrow_stream_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: csv_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: new_json_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: native_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vorc_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: column_type_convert.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: schema_desc.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_group_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_column_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_column_chunk_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_page_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_column_convert.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_page_index.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_block_split_bloom_filter.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: deletion_vector_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: es_http_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hive_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hive_orc_nested_column_utils.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hudi_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hudi_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_delete_file_reader_helper.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_position_delete_sys_table_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_orc_nested_column_utils.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: equality_delete.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_sys_table_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: jdbc_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: max_compute_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: paimon_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: paimon_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_metadata_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_utils.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: remote_doris_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: table_format_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: table_schema_change_helper.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: transactional_hive_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: trino_connector_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: text_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: merge_partitioner.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_partition_function.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vcsv_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vfile_format_transformer_factory.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vjni_format_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vnative_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vorc_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: adbc_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hdfs_file_system.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_23_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: inverted_index_compound_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: inverted_index_fs_directory.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: zone_map_index.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vcollect_iterator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: predicate_creator_comparison.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: predicate_creator_in_list_in.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: predicate_creator_in_list_not_in.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: tablet.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: engine_clone_task.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: descriptors.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: backend_service.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: point_query_executor.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: be_server_starter_factory.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: http_service.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: internal_service.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: arrow_flight_batch_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: thrift_util.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: load_stream.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: routine_load_task_executor.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: cloud_compaction_action.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
682
683
// auto ReleaseStringUTFChars ReleaseByteArrayElements ...
684
template <BufferType bufferfType, RefType Ref>
685
class BufferGuard {
686
public:
687
6.60k
    BufferGuard() = default;
688
689
    template <RefType R>
690
    static Status create(JNIEnv* env, const Object<R>& object,
691
6.60k
                         BufferGuard<bufferfType, Ref>* result, jboolean* isCopy) {
692
6.60k
        DCHECK(result->_buffer == nullptr && result->_object.uninitialized());
693
694
6.60k
        RETURN_IF_ERROR(Object<Ref>::create(env, object, &result->_object));
695
696
6.60k
        if constexpr (bufferfType == BufferType::Chars) {
697
6.60k
            result->_buffer = env->GetStringUTFChars((jstring)result->_object._obj, isCopy);
698
        } else if constexpr (bufferfType == BufferType::ByteArray) {
699
            result->_buffer =
700
                    (char*)env->GetByteArrayElements((jbyteArray)result->_object._obj, isCopy);
701
        } else {
702
            static_assert(false);
703
        }
704
705
6.60k
        RETURN_ERROR_IF_EXC(env);
706
6.60k
        if (result->_buffer == nullptr) [[unlikely]] {
707
0
            return Status::JniError("GetStringUTFChars/GetByteArrayElements fail.");
708
0
        }
709
710
6.60k
        return Status::OK();
711
6.60k
    }
712
713
6.60k
    ~BufferGuard() {
714
6.60k
        if (_object.uninitialized() || _buffer == nullptr) [[unlikely]] {
715
0
            return;
716
0
        }
717
6.60k
        JNIEnv* env = nullptr;
718
719
6.60k
        if (auto st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
720
0
            LOG(WARNING) << "BufferGuard release fail: " << st;
721
0
            return;
722
0
        }
723
724
6.60k
        if constexpr (bufferfType == BufferType::Chars) {
725
6.60k
            env->ReleaseStringUTFChars((jstring)_object._obj, _buffer);
726
        } else if constexpr (bufferfType == BufferType::ByteArray) {
727
            env->ReleaseByteArrayElements((jbyteArray)_object._obj, (jbyte*)_buffer, JNI_ABORT);
728
        }
729
6.60k
    }
730
731
13.2k
    const char* get() const { return _buffer; }
732
733
private:
734
    Object<Ref> _object;
735
    const char* _buffer = nullptr;
736
737
    DISALLOW_COPY_AND_ASSIGN(BufferGuard);
738
};
739
740
template <RefType Ref>
741
using StringBufferGuard = BufferGuard<Chars, Ref>;
742
using LocalStringBufferGuard = BufferGuard<Chars, Local>;
743
using GlobalStringBufferGuard = BufferGuard<Chars, Global>;
744
745
template <RefType Ref>
746
using ByteArrayBufferGuard = BufferGuard<ByteArray, Ref>;
747
using LocalByteArrayBufferGuard = BufferGuard<ByteArray, Local>;
748
using GlobalByteArrayBufferGuard = BufferGuard<ByteArray, Global>;
749
750
template <RefType Ref>
751
class String : public Object<Ref> {
752
public:
753
40.8k
    String() = default;
754
755
34.0k
    static Status new_string(JNIEnv* env, const char* utf_chars, String<Ref>* result) {
756
34.0k
        DCHECK(result->uninitialized());
757
758
34.0k
        if constexpr (Ref == Local) {
759
34.0k
            result->_obj = env->NewStringUTF(utf_chars);
760
34.0k
            RETURN_ERROR_IF_EXC(env);
761
        } else if constexpr (Ref == Global) {
762
            String local_result;
763
            local_result->_obj = env->NewStringUTF(utf_chars);
764
            RETURN_ERROR_IF_EXC(env);
765
            RETURN_IF_ERROR(local_to_global_ref(env, local_result, result));
766
        } else {
767
            static_assert(false);
768
        }
769
34.0k
        return Status::OK();
770
34.0k
    }
771
772
6.60k
    Status get_string_chars(JNIEnv* env, StringBufferGuard<Ref>* jni_chars) const {
773
6.60k
        return StringBufferGuard<Ref>::create(env, *this, jni_chars, nullptr);
774
6.60k
    }
775
776
private:
777
    DISALLOW_COPY_AND_ASSIGN(String);
778
};
779
780
template <RefType Ref>
781
class Array : public Object<Ref> {
782
public:
783
6.74k
    Array() = default;
784
785
736
    Status get_length(JNIEnv* env, jsize* result) const {
786
736
        DCHECK(!this->uninitialized());
787
788
736
        *result = env->GetArrayLength((jarray)this->_obj);
789
736
        RETURN_ERROR_IF_EXC(env);
790
736
        return Status::OK();
791
736
    }
792
793
57.4k
    Status get_object_array_element(JNIEnv* env, jsize index, Jni::LocalObject* result) {
794
57.4k
        DCHECK(!this->uninitialized());
795
57.4k
        DCHECK(result->uninitialized());
796
57.4k
        result->_obj = env->GetObjectArrayElement((jobjectArray)this->_obj, index);
797
57.4k
        RETURN_ERROR_IF_EXC(env);
798
57.4k
        return Status::OK();
799
57.4k
    }
800
801
    Status get_byte_elements(JNIEnv* env, ByteArrayBufferGuard<Ref>* jni_bytes) const {
802
        DCHECK(!this->uninitialized());
803
        return ByteArrayBufferGuard<Ref>::create(env, *this, jni_bytes, nullptr);
804
    }
805
806
75
    Status get_byte_elements(JNIEnv* env, jsize start, jsize len, jbyte* buffer) {
807
75
        DCHECK(!this->uninitialized());
808
75
        env->GetByteArrayRegion((jbyteArray)this->_obj, start, len, buffer);
809
75
        RETURN_ERROR_IF_EXC(env);
810
75
        return Status::OK();
811
75
    }
812
813
    static Status WriteBufferToByteArray(JNIEnv* env, const jbyte* buffer, jint size,
814
5.31k
                                         Array<Local>* serialized_msg) {
815
5.31k
        DCHECK(serialized_msg->uninitialized());
816
        /// create jbyteArray given buffer
817
5.31k
        serialized_msg->_obj = env->NewByteArray(size);
818
5.31k
        RETURN_ERROR_IF_EXC(env);
819
5.31k
        if (serialized_msg->_obj == nullptr) [[unlikely]] {
820
0
            return Status::JniError("couldn't construct jbyteArray");
821
0
        }
822
5.31k
        env->SetByteArrayRegion((jbyteArray)serialized_msg->_obj, 0, size, buffer);
823
5.31k
        RETURN_ERROR_IF_EXC(env);
824
5.31k
        return Status::OK();
825
5.31k
    }
826
827
    template <class T>
828
5.21k
    static Status SerializeThriftMsg(JNIEnv* env, T* msg, Array<Local>* serialized_msg) {
829
5.21k
        int buffer_size = 100 * 1024; // start out with 100KB
830
5.21k
        ThriftSerializer serializer(false, buffer_size);
831
832
5.21k
        uint8_t* buffer = nullptr;
833
5.21k
        uint32_t size = 0;
834
5.21k
        RETURN_IF_ERROR(serializer.serialize(msg, &size, &buffer));
835
836
        // Make sure that 'size' is within the limit of INT_MAX as the use of
837
        // 'size' below takes int.
838
5.21k
        if (size > INT_MAX) [[unlikely]] {
839
0
            return Status::JniError(
840
0
                    "The length of the serialization buffer ({} bytes) exceeds the limit of {} "
841
0
                    "bytes",
842
0
                    size, INT_MAX);
843
0
        }
844
5.21k
        RETURN_IF_ERROR(WriteBufferToByteArray(env, (jbyte*)buffer, size, serialized_msg));
845
5.21k
        return Status::OK();
846
5.21k
    }
847
848
private:
849
    DISALLOW_COPY_AND_ASSIGN(Array);
850
};
851
852
template <RefType Ref>
853
class Class : public Object<Ref> {
854
public:
855
10.9k
    Class() = default;
_ZN5doris3Jni5ClassILNS0_7RefTypeE1EEC2Ev
Line
Count
Source
855
5.50k
    Class() = default;
_ZN5doris3Jni5ClassILNS0_7RefTypeE0EEC2Ev
Line
Count
Source
855
5.42k
    Class() = default;
856
857
5.41k
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
858
5.41k
        DCHECK(result->uninitialized());
859
5.41k
        if constexpr (Ref == Local) {
860
7
            result->_obj = env->FindClass(class_str);
861
7
            RETURN_ERROR_IF_EXC(env);
862
7
            return Status::OK();
863
5.40k
        } else if constexpr (Ref == Global) {
864
5.40k
            Class<Local> local_class;
865
5.40k
            local_class._obj = env->FindClass(class_str);
866
5.40k
            RETURN_ERROR_IF_EXC(env);
867
5.40k
            return local_to_global_ref(env, local_class, result);
868
        } else {
869
            static_assert(false);
870
        }
871
5.41k
    }
_ZN5doris3Jni5ClassILNS0_7RefTypeE1EE10find_classEP7JNIEnv_PKcPS3_
Line
Count
Source
857
5.40k
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
858
5.40k
        DCHECK(result->uninitialized());
859
        if constexpr (Ref == Local) {
860
            result->_obj = env->FindClass(class_str);
861
            RETURN_ERROR_IF_EXC(env);
862
            return Status::OK();
863
5.40k
        } else if constexpr (Ref == Global) {
864
5.40k
            Class<Local> local_class;
865
5.40k
            local_class._obj = env->FindClass(class_str);
866
5.40k
            RETURN_ERROR_IF_EXC(env);
867
5.40k
            return local_to_global_ref(env, local_class, result);
868
        } else {
869
            static_assert(false);
870
        }
871
5.40k
    }
_ZN5doris3Jni5ClassILNS0_7RefTypeE0EE10find_classEP7JNIEnv_PKcPS3_
Line
Count
Source
857
7
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
858
7
        DCHECK(result->uninitialized());
859
7
        if constexpr (Ref == Local) {
860
7
            result->_obj = env->FindClass(class_str);
861
7
            RETURN_ERROR_IF_EXC(env);
862
7
            return Status::OK();
863
        } else if constexpr (Ref == Global) {
864
            Class<Local> local_class;
865
            local_class._obj = env->FindClass(class_str);
866
            RETURN_ERROR_IF_EXC(env);
867
            return local_to_global_ref(env, local_class, result);
868
        } else {
869
            static_assert(false);
870
        }
871
7
    }
872
873
    Status get_static_method(JNIEnv* env, const char* method_str, const char* method_signature,
874
28
                             MethodId* method_id) const {
875
28
        DCHECK(!this->uninitialized());
876
28
        DCHECK(method_id->uninitialized());
877
28
        method_id->_id = env->GetStaticMethodID((jclass)this->_obj, method_str, method_signature);
878
28
        RETURN_ERROR_IF_EXC(env);
879
28
        return Status::OK();
880
28
    }
_ZNK5doris3Jni5ClassILNS0_7RefTypeE1EE17get_static_methodEP7JNIEnv_PKcS7_PNS0_8MethodIdE
Line
Count
Source
874
28
                             MethodId* method_id) const {
875
28
        DCHECK(!this->uninitialized());
876
28
        DCHECK(method_id->uninitialized());
877
28
        method_id->_id = env->GetStaticMethodID((jclass)this->_obj, method_str, method_signature);
878
28
        RETURN_ERROR_IF_EXC(env);
879
28
        return Status::OK();
880
28
    }
Unexecuted instantiation: _ZNK5doris3Jni5ClassILNS0_7RefTypeE0EE17get_static_methodEP7JNIEnv_PKcS7_PNS0_8MethodIdE
881
882
    Status get_method(JNIEnv* env, const char* method_str, const char* method_signature,
883
17.9k
                      MethodId* method_id) const {
884
17.9k
        DCHECK(!this->uninitialized());
885
17.9k
        DCHECK(method_id->uninitialized());
886
17.9k
        method_id->_id = env->GetMethodID((jclass)this->_obj, method_str, method_signature);
887
17.9k
        RETURN_ERROR_IF_EXC(env);
888
17.9k
        return Status::OK();
889
17.9k
    }
_ZNK5doris3Jni5ClassILNS0_7RefTypeE1EE10get_methodEP7JNIEnv_PKcS7_PNS0_8MethodIdE
Line
Count
Source
883
17.9k
                      MethodId* method_id) const {
884
17.9k
        DCHECK(!this->uninitialized());
885
17.9k
        DCHECK(method_id->uninitialized());
886
17.9k
        method_id->_id = env->GetMethodID((jclass)this->_obj, method_str, method_signature);
887
17.9k
        RETURN_ERROR_IF_EXC(env);
888
17.9k
        return Status::OK();
889
17.9k
    }
_ZNK5doris3Jni5ClassILNS0_7RefTypeE0EE10get_methodEP7JNIEnv_PKcS7_PNS0_8MethodIdE
Line
Count
Source
883
28
                      MethodId* method_id) const {
884
28
        DCHECK(!this->uninitialized());
885
28
        DCHECK(method_id->uninitialized());
886
28
        method_id->_id = env->GetMethodID((jclass)this->_obj, method_str, method_signature);
887
28
        RETURN_ERROR_IF_EXC(env);
888
28
        return Status::OK();
889
28
    }
890
891
    Status get_static_fieldId(JNIEnv* env, const char* name, const char* signature,
892
42
                              FieldId* field_id) const {
893
42
        DCHECK(!this->uninitialized());
894
42
        DCHECK(field_id->uninitialized());
895
42
        field_id->_id = env->GetStaticFieldID((jclass)this->_obj, name, signature);
896
42
        RETURN_ERROR_IF_EXC(env);
897
42
        return Status::OK();
898
42
    }
899
900
    Status get_static_object_field(JNIEnv* env, const FieldId& field_id,
901
                                   Object<Local>* result) const {
902
        DCHECK(!this->uninitialized());
903
        DCHECK(!field_id.uninitialized());
904
        result->_obj = env->GetStaticObjectField((jclass)this->_obj, field_id._id);
905
        RETURN_ERROR_IF_EXC(env);
906
        return Status::OK();
907
    }
908
909
    Status get_static_object_field(JNIEnv* env, const FieldId& field_id,
910
42
                                   Object<Global>* global_result) const {
911
42
        DCHECK(!this->uninitialized());
912
42
        DCHECK(!field_id.uninitialized());
913
42
        Object<Local> local_result;
914
42
        local_result._obj = env->GetStaticObjectField((jclass)this->_obj, field_id._id);
915
42
        RETURN_ERROR_IF_EXC(env);
916
42
        return local_to_global_ref(env, local_result, global_result);
917
42
    }
918
919
    Status get_static_object_field(JNIEnv* env, const char* name, const char* signature,
920
42
                                   Object<Global>* global_result) const {
921
42
        Jni::FieldId tmpFieldID;
922
42
        RETURN_IF_ERROR(get_static_fieldId(env, name, signature, &tmpFieldID));
923
42
        RETURN_IF_ERROR(get_static_object_field(env, tmpFieldID, global_result));
924
42
        return Status::OK();
925
42
    }
926
927
10.7k
    FunctionCall<NewObject> new_object(JNIEnv* env, MethodId method_id) const {
928
10.7k
        DCHECK(!this->uninitialized());
929
10.7k
        DCHECK(!method_id.uninitialized());
930
10.7k
        return FunctionCall<NewObject>::instance(env, (jclass)this->_obj, method_id._id);
931
10.7k
    }
_ZNK5doris3Jni5ClassILNS0_7RefTypeE1EE10new_objectEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
927
10.7k
    FunctionCall<NewObject> new_object(JNIEnv* env, MethodId method_id) const {
928
10.7k
        DCHECK(!this->uninitialized());
929
        DCHECK(!method_id.uninitialized());
930
10.7k
        return FunctionCall<NewObject>::instance(env, (jclass)this->_obj, method_id._id);
931
10.7k
    }
_ZNK5doris3Jni5ClassILNS0_7RefTypeE0EE10new_objectEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
927
7
    FunctionCall<NewObject> new_object(JNIEnv* env, MethodId method_id) const {
928
7
        DCHECK(!this->uninitialized());
929
        DCHECK(!method_id.uninitialized());
930
7
        return FunctionCall<NewObject>::instance(env, (jclass)this->_obj, method_id._id);
931
7
    }
932
933
    FunctionCall<StaticObjectMethod> call_static_object_method(JNIEnv* env,
934
2.64k
                                                               MethodId method_id) const {
935
2.64k
        DCHECK(!this->uninitialized());
936
2.64k
        DCHECK(!method_id.uninitialized());
937
2.64k
        return FunctionCall<StaticObjectMethod>::instance(env, (jclass)this->_obj, method_id._id);
938
2.64k
    }
939
940
0
    FunctionCall<StaticVoidMethod> call_static_void_method(JNIEnv* env, MethodId method_id) const {
941
0
        DCHECK(!this->uninitialized());
942
0
        DCHECK(!method_id.uninitialized());
943
0
        return FunctionCall<StaticVoidMethod>::instance(env, (jclass)this->_obj, method_id._id);
944
0
    }
945
946
private:
947
    DISALLOW_COPY_AND_ASSIGN(Class);
948
};
949
950
using LocalClass = Class<Local>;
951
using GlobalClass = Class<Global>;
952
953
using LocalArray = Array<Local>;
954
using GlobalArray = Array<Global>;
955
956
using LocalString = String<Local>;
957
using GlobalString = String<Global>;
958
959
template <CallTag tag>
960
template <RefType Ref>
961
45.6k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
962
45.6k
    jvalue v;
963
45.6k
    std::memset(&v, 0, sizeof(v));
964
45.6k
    v.l = obj._obj;
965
45.6k
    _args.push_back(v);
966
45.6k
    return *this;
967
45.6k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
961
33.9k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
962
33.9k
    jvalue v;
963
33.9k
    std::memset(&v, 0, sizeof(v));
964
33.9k
    v.l = obj._obj;
965
33.9k
    _args.push_back(v);
966
33.9k
    return *this;
967
33.9k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
961
5.24k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
962
5.24k
    jvalue v;
963
5.24k
    std::memset(&v, 0, sizeof(v));
964
5.24k
    v.l = obj._obj;
965
5.24k
    _args.push_back(v);
966
5.24k
    return *this;
967
5.24k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
961
1.14k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
962
1.14k
    jvalue v;
963
1.14k
    std::memset(&v, 0, sizeof(v));
964
1.14k
    v.l = obj._obj;
965
1.14k
    _args.push_back(v);
966
1.14k
    return *this;
967
1.14k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
961
5.30k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
962
5.30k
    jvalue v;
963
5.30k
    std::memset(&v, 0, sizeof(v));
964
5.30k
    v.l = obj._obj;
965
5.30k
    _args.push_back(v);
966
5.30k
    return *this;
967
5.30k
}
Unexecuted instantiation: _ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
968
969
template <CallTag tag>
970
template <RefType Ref>
971
77
NonvirtualFunctionCall<tag>& NonvirtualFunctionCall<tag>::with_arg(const Object<Ref>& obj) {
972
77
    jvalue v;
973
77
    std::memset(&v, 0, sizeof(v));
974
77
    v.l = obj._obj;
975
77
    this->_args.push_back(v);
976
77
    return *this;
977
77
}
978
979
template <CallTag tag>
980
92.0k
Status FunctionCall<tag>::call(Object<Local>* result) {
981
92.0k
    DCHECK(result->uninitialized());
982
92.0k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
983
92.0k
    RETURN_ERROR_IF_EXC(this->_env);
984
92.0k
    return Status::OK();
985
92.0k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EE4callEPNS0_6ObjectILNS0_7RefTypeE0EEE
Line
Count
Source
980
2.64k
Status FunctionCall<tag>::call(Object<Local>* result) {
981
2.64k
    DCHECK(result->uninitialized());
982
2.64k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
983
2.64k
    RETURN_ERROR_IF_EXC(this->_env);
984
2.64k
    return Status::OK();
985
2.64k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE4callEPNS0_6ObjectILNS0_7RefTypeE0EEE
Line
Count
Source
980
83.8k
Status FunctionCall<tag>::call(Object<Local>* result) {
981
83.8k
    DCHECK(result->uninitialized());
982
83.8k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
983
83.8k
    RETURN_ERROR_IF_EXC(this->_env);
984
83.8k
    return Status::OK();
985
83.8k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE4callEPNS0_6ObjectILNS0_7RefTypeE0EEE
Line
Count
Source
980
5.51k
Status FunctionCall<tag>::call(Object<Local>* result) {
981
5.51k
    DCHECK(result->uninitialized());
982
5.51k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
983
5.51k
    RETURN_ERROR_IF_EXC(this->_env);
984
5.51k
    return Status::OK();
985
5.51k
}
986
987
template <CallTag tag>
988
5.25k
Status FunctionCall<tag>::call(Object<Global>* result) {
989
5.25k
    DCHECK(result->uninitialized());
990
5.25k
    Object<Local> local_result;
991
5.25k
    local_result._obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
992
5.25k
    RETURN_ERROR_IF_EXC(this->_env);
993
5.25k
    return local_to_global_ref(_env, local_result, result);
994
5.25k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE4callEPNS0_6ObjectILNS0_7RefTypeE1EEE
Line
Count
Source
988
5.24k
Status FunctionCall<tag>::call(Object<Global>* result) {
989
5.24k
    DCHECK(result->uninitialized());
990
5.24k
    Object<Local> local_result;
991
5.24k
    local_result._obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
992
5.24k
    RETURN_ERROR_IF_EXC(this->_env);
993
5.24k
    return local_to_global_ref(_env, local_result, result);
994
5.24k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE4callEPNS0_6ObjectILNS0_7RefTypeE1EEE
Line
Count
Source
988
5
Status FunctionCall<tag>::call(Object<Global>* result) {
989
5
    DCHECK(result->uninitialized());
990
5
    Object<Local> local_result;
991
5
    local_result._obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
992
5
    RETURN_ERROR_IF_EXC(this->_env);
993
5
    return local_to_global_ref(_env, local_result, result);
994
5
}
995
996
template <CallTag tag>
997
77
Status NonvirtualFunctionCall<tag>::call(Object<Local>* result) {
998
77
    DCHECK(result->uninitialized());
999
77
    result->_obj = CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
1000
77
                                              this->_args.data());
1001
77
    RETURN_ERROR_IF_EXC(this->_env);
1002
77
    return Status::OK();
1003
77
}
1004
1005
template <RefType Ref>
1006
template <RefType R>
1007
NonvirtualFunctionCall<NonvirtualObjectMethod> Object<Ref>::call_nonvirtual_object_method(
1008
75
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1009
75
    DCHECK(!this->uninitialized());
1010
75
    DCHECK(!method_id.uninitialized());
1011
1012
75
    return NonvirtualFunctionCall<NonvirtualObjectMethod>::instance(env, _obj, (jclass)clazz._obj,
1013
75
                                                                    method_id._id);
1014
75
}
1015
1016
template <RefType Ref>
1017
template <RefType R>
1018
NonvirtualFunctionCall<NonvirtualVoidMethod> Object<Ref>::call_nonvirtual_void_method(
1019
6.31k
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1020
6.31k
    DCHECK(!this->uninitialized());
1021
6.31k
    DCHECK(!method_id.uninitialized());
1022
6.31k
    return NonvirtualFunctionCall<NonvirtualVoidMethod>::instance(env, _obj, (jclass)clazz._obj,
1023
6.31k
                                                                  method_id._id);
1024
6.31k
}
1025
1026
template <RefType Ref>
1027
template <RefType R>
1028
NonvirtualFunctionCall<NonvirtualIntMethod> Object<Ref>::call_nonvirtual_int_method(
1029
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1030
    DCHECK(!this->uninitialized());
1031
    DCHECK(!method_id.uninitialized());
1032
    return NonvirtualFunctionCall<NonvirtualIntMethod>::instance(env, _obj, (jclass)clazz._obj,
1033
                                                                 method_id._id);
1034
}
1035
1036
template <RefType Ref>
1037
template <RefType R>
1038
NonvirtualFunctionCall<NonvirtualBooleanMethod> Object<Ref>::call_nonvirtual_boolean_method(
1039
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1040
    DCHECK(!this->uninitialized());
1041
    DCHECK(!method_id.uninitialized());
1042
    return NonvirtualFunctionCall<NonvirtualBooleanMethod>::instance(env, _obj, (jclass)clazz._obj,
1043
                                                                     method_id._id);
1044
}
1045
1046
class Util {
1047
public:
1048
    static size_t get_max_jni_heap_memory_size();
1049
1050
    template <RefType Ref>
1051
5.42k
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
1052
5.42k
        return Class<Ref>::find_class(env, class_str, result);
1053
5.42k
    }
_ZN5doris3Jni4Util10find_classILNS0_7RefTypeE1EEENS_6StatusEP7JNIEnv_PKcPNS0_5ClassIXT_EEE
Line
Count
Source
1051
5.41k
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
1052
5.41k
        return Class<Ref>::find_class(env, class_str, result);
1053
5.41k
    }
_ZN5doris3Jni4Util10find_classILNS0_7RefTypeE0EEENS_6StatusEP7JNIEnv_PKcPNS0_5ClassIXT_EEE
Line
Count
Source
1051
7
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
1052
7
        return Class<Ref>::find_class(env, class_str, result);
1053
7
    }
1054
1055
    template <RefType Ref>
1056
    static Status WriteBufferToByteArray(JNIEnv* env, const jbyte* buffer, jint size,
1057
77
                                         Array<Ref>* serialized_msg) {
1058
77
        if constexpr (Ref == Local) {
1059
77
            return Array<Local>::WriteBufferToByteArray(env, buffer, size, serialized_msg);
1060
        } else if constexpr (Ref == Global) {
1061
            Array<Local> local_obj;
1062
            RETURN_IF_ERROR(Array<Local>::WriteBufferToByteArray(env, buffer, size, &local_obj));
1063
            return local_to_global_ref(env, local_obj, serialized_msg);
1064
        } else {
1065
            static_assert(false);
1066
        }
1067
77
    }
1068
1069
    template <class T, RefType Ref>
1070
5.25k
    static Status SerializeThriftMsg(JNIEnv* env, T* msg, Array<Ref>* serialized_msg) {
1071
5.25k
        if constexpr (Ref == Local) {
1072
5.25k
            return Array<Local>::SerializeThriftMsg(env, msg, serialized_msg);
1073
        } else if (Ref == Global) {
1074
            Array<Local> local_obj;
1075
            RETURN_IF_ERROR(Array<Local>::SerializeThriftMsg(env, msg, local_obj));
1076
            return local_to_global_ref(env, local_obj, serialized_msg);
1077
        } else {
1078
            static_assert(false);
1079
        }
1080
5.25k
    }
1081
1082
    template <RefType Ref>
1083
    static Status get_jni_scanner_class(JNIEnv* env, const char* classname,
1084
5
                                        Object<Ref>* jni_scanner_class) {
1085
        // Get JNI scanner class by class name;
1086
5
        LocalString class_name_str;
1087
5
        RETURN_IF_ERROR(LocalString::new_string(env, classname, &class_name_str));
1088
5
        return jni_scanner_loader_obj_.call_object_method(env, jni_scanner_loader_method_)
1089
5
                .with_arg(class_name_str)
1090
5
                .call(jni_scanner_class);
1091
5
    }
_ZN5doris3Jni4Util21get_jni_scanner_classILNS0_7RefTypeE1EEENS_6StatusEP7JNIEnv_PKcPNS0_6ObjectIXT_EEE
Line
Count
Source
1084
5
                                        Object<Ref>* jni_scanner_class) {
1085
        // Get JNI scanner class by class name;
1086
5
        LocalString class_name_str;
1087
5
        RETURN_IF_ERROR(LocalString::new_string(env, classname, &class_name_str));
1088
5
        return jni_scanner_loader_obj_.call_object_method(env, jni_scanner_loader_method_)
1089
5
                .with_arg(class_name_str)
1090
5
                .call(jni_scanner_class);
1091
5
    }
Unexecuted instantiation: _ZN5doris3Jni4Util21get_jni_scanner_classILNS0_7RefTypeE0EEENS_6StatusEP7JNIEnv_PKcPNS0_6ObjectIXT_EEE
1092
1093
    template <RefType Ref>
1094
    static Status convert_to_java_map(JNIEnv* env, const std::map<std::string, std::string>& map,
1095
5.51k
                                      Object<Ref>* hashmap_object) {
1096
5.51k
        RETURN_IF_ERROR(hashmap_class.new_object(env, hashmap_constructor)
1097
5.51k
                                .with_arg((jint)map.size())
1098
5.51k
                                .call(hashmap_object));
1099
1100
16.6k
        for (const auto& it : map) {
1101
16.6k
            LocalString key;
1102
16.6k
            RETURN_IF_ERROR(String<Local>::new_string(env, it.first.c_str(), &key));
1103
1104
16.6k
            LocalString value;
1105
16.6k
            RETURN_IF_ERROR(String<Local>::new_string(env, it.second.c_str(), &value));
1106
1107
16.6k
            LocalObject result;
1108
16.6k
            RETURN_IF_ERROR(hashmap_object->call_object_method(env, hashmap_put)
1109
16.6k
                                    .with_arg(key)
1110
16.6k
                                    .with_arg(value)
1111
16.6k
                                    .call());
1112
16.6k
        }
1113
5.51k
        return Status::OK();
1114
5.51k
    }
1115
1116
    template <RefType Ref>
1117
    static Status convert_to_cpp_map(JNIEnv* env, const Object<Ref>& map,
1118
2
                                     std::map<std::string, std::string>* resultMap) {
1119
2
        LocalObject entrySet;
1120
2
        RETURN_IF_ERROR(map.call_object_method(env, mapEntrySetMethod).call(&entrySet));
1121
1122
        // Call the iterator method on the set to iterate over the key-value pairs
1123
2
        LocalObject iteratorSet;
1124
2
        RETURN_IF_ERROR(entrySet.call_object_method(env, iteratorSetMethod).call(&iteratorSet));
1125
1126
6
        while (true) {
1127
6
            jboolean hasNext = false;
1128
6
            RETURN_IF_ERROR(
1129
6
                    iteratorSet.call_boolean_method(env, iteratorHasNextMethod).call(&hasNext));
1130
6
            if (!hasNext) {
1131
2
                break;
1132
2
            }
1133
1134
4
            LocalObject entry;
1135
4
            RETURN_IF_ERROR(iteratorSet.call_object_method(env, iteratorNextMethod).call(&entry));
1136
1137
4
            LocalString javaKey;
1138
4
            RETURN_IF_ERROR(entry.call_object_method(env, getEntryKeyMethod).call(&javaKey));
1139
1140
4
            LocalString javaValue;
1141
4
            RETURN_IF_ERROR(entry.call_object_method(env, getEntryValueMethod).call(&javaValue));
1142
1143
4
            LocalStringBufferGuard key;
1144
4
            RETURN_IF_ERROR(javaKey.get_string_chars(env, &key));
1145
1146
4
            LocalStringBufferGuard value;
1147
4
            RETURN_IF_ERROR(javaValue.get_string_chars(env, &value));
1148
1149
            // Store the key-value pair in the map
1150
4
            (*resultMap)[key.get()] = value.get();
1151
4
        }
1152
2
        return Status::OK();
1153
2
    }
1154
1155
    static Status clean_udf_class_load_cache(const std::string& function_signature,
1156
                                             int64_t function_id);
1157
1158
    static Status Init();
1159
1160
private:
1161
    static void _parse_max_heap_memory_size_from_jvm();
1162
1163
    static Status _init_collect_class() WARN_UNUSED_RESULT;
1164
    static Status _init_register_natives() WARN_UNUSED_RESULT;
1165
    static Status _init_jni_scanner_loader() WARN_UNUSED_RESULT;
1166
1167
    static bool jvm_inited_;
1168
1169
    // for jvm heap
1170
    static jlong max_jvm_heap_memory_size_;
1171
1172
    // for JNI scanner loader
1173
    static GlobalObject jni_scanner_loader_obj_;
1174
    static MethodId jni_scanner_loader_method_;
1175
1176
    // for clean udf cache
1177
    static MethodId _clean_udf_cache_method_id;
1178
1179
    //for hashmap
1180
    static GlobalClass hashmap_class;
1181
    static MethodId hashmap_constructor;
1182
    static MethodId hashmap_put;
1183
1184
    //for map
1185
    static GlobalClass mapClass;
1186
    static MethodId mapEntrySetMethod;
1187
1188
    // for map entry
1189
    static GlobalClass mapEntryClass;
1190
    static MethodId getEntryKeyMethod;
1191
    static MethodId getEntryValueMethod;
1192
1193
    //for set
1194
    static GlobalClass setClass;
1195
    static MethodId iteratorSetMethod;
1196
1197
    // for iterator
1198
    static GlobalClass iteratorClass;
1199
    static MethodId iteratorHasNextMethod;
1200
    static MethodId iteratorNextMethod;
1201
};
1202
}; // namespace Jni
1203
1204
} // namespace doris