xref: /aosp_15_r20/art/openjdkjvm/OpenjdkJvm.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /* Copyright (C) 2014 The Android Open Source Project
2*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * This file implements interfaces from the file jvm.h. This implementation
5*795d594fSAndroid Build Coastguard Worker  * is licensed under the same terms as the file jvm.h.  The
6*795d594fSAndroid Build Coastguard Worker  * copyright and license information for the file jvm.h follows.
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
9*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10*795d594fSAndroid Build Coastguard Worker  *
11*795d594fSAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
12*795d594fSAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
13*795d594fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
14*795d594fSAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
15*795d594fSAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
16*795d594fSAndroid Build Coastguard Worker  *
17*795d594fSAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
18*795d594fSAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19*795d594fSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20*795d594fSAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
21*795d594fSAndroid Build Coastguard Worker  * accompanied this code).
22*795d594fSAndroid Build Coastguard Worker  *
23*795d594fSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
24*795d594fSAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
25*795d594fSAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26*795d594fSAndroid Build Coastguard Worker  *
27*795d594fSAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28*795d594fSAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
29*795d594fSAndroid Build Coastguard Worker  * questions.
30*795d594fSAndroid Build Coastguard Worker  */
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker /*
33*795d594fSAndroid Build Coastguard Worker  * Services that OpenJDK expects the VM to provide.
34*795d594fSAndroid Build Coastguard Worker  */
35*795d594fSAndroid Build Coastguard Worker 
36*795d594fSAndroid Build Coastguard Worker #include <assert.h>
37*795d594fSAndroid Build Coastguard Worker #include <dlfcn.h>
38*795d594fSAndroid Build Coastguard Worker #include <limits.h>
39*795d594fSAndroid Build Coastguard Worker #include <stdio.h>
40*795d594fSAndroid Build Coastguard Worker #include <sys/ioctl.h>
41*795d594fSAndroid Build Coastguard Worker #include <sys/socket.h>
42*795d594fSAndroid Build Coastguard Worker #include <sys/time.h>
43*795d594fSAndroid Build Coastguard Worker #include <unistd.h>
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker #include "../../libcore/ojluni/src/main/native/jvm.h"  // TODO(narayan): fix it
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
50*795d594fSAndroid Build Coastguard Worker #include "base/fast_exit.h"
51*795d594fSAndroid Build Coastguard Worker #include "common_throws.h"
52*795d594fSAndroid Build Coastguard Worker #include "gc/heap.h"
53*795d594fSAndroid Build Coastguard Worker #include "handle_scope-inl.h"
54*795d594fSAndroid Build Coastguard Worker #include "jni/java_vm_ext.h"
55*795d594fSAndroid Build Coastguard Worker #include "jni/jni_internal.h"
56*795d594fSAndroid Build Coastguard Worker #include "mirror/class_loader.h"
57*795d594fSAndroid Build Coastguard Worker #include "mirror/string-inl.h"
58*795d594fSAndroid Build Coastguard Worker #include "monitor.h"
59*795d594fSAndroid Build Coastguard Worker #include "native/scoped_fast_native_object_access-inl.h"
60*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_local_ref.h"
61*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_utf_chars.h"
62*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
63*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
64*795d594fSAndroid Build Coastguard Worker #include "thread.h"
65*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
66*795d594fSAndroid Build Coastguard Worker #include "verify_object.h"
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker #undef LOG_TAG
69*795d594fSAndroid Build Coastguard Worker #define LOG_TAG "artopenjdk"
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker /* posix open() with extensions; used by e.g. ZipFile */
JVM_Open(const char * fname,jint flags,jint mode)72*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Open(const char* fname, jint flags, jint mode) {
73*795d594fSAndroid Build Coastguard Worker     /*
74*795d594fSAndroid Build Coastguard Worker      * Some code seems to want the special return value JVM_EEXIST if the
75*795d594fSAndroid Build Coastguard Worker      * file open fails due to O_EXCL.
76*795d594fSAndroid Build Coastguard Worker      */
77*795d594fSAndroid Build Coastguard Worker     // Don't use JVM_O_DELETE, it's problematic with FUSE, see b/28901232.
78*795d594fSAndroid Build Coastguard Worker     if (flags & JVM_O_DELETE) {
79*795d594fSAndroid Build Coastguard Worker         LOG(FATAL) << "JVM_O_DELETE option is not supported (while opening: '"
80*795d594fSAndroid Build Coastguard Worker                    << fname << "')";
81*795d594fSAndroid Build Coastguard Worker     }
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker     flags |= O_CLOEXEC;
84*795d594fSAndroid Build Coastguard Worker     int fd = TEMP_FAILURE_RETRY(open(fname, flags & ~JVM_O_DELETE, mode));
85*795d594fSAndroid Build Coastguard Worker     if (fd < 0) {
86*795d594fSAndroid Build Coastguard Worker         int err = errno;
87*795d594fSAndroid Build Coastguard Worker         if (err == EEXIST) {
88*795d594fSAndroid Build Coastguard Worker             return JVM_EEXIST;
89*795d594fSAndroid Build Coastguard Worker         } else {
90*795d594fSAndroid Build Coastguard Worker             return -1;
91*795d594fSAndroid Build Coastguard Worker         }
92*795d594fSAndroid Build Coastguard Worker     }
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker     return fd;
95*795d594fSAndroid Build Coastguard Worker }
96*795d594fSAndroid Build Coastguard Worker 
97*795d594fSAndroid Build Coastguard Worker /* posix close() */
JVM_Close(jint fd)98*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Close(jint fd) {
99*795d594fSAndroid Build Coastguard Worker     // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR
100*795d594fSAndroid Build Coastguard Worker     return close(fd);
101*795d594fSAndroid Build Coastguard Worker }
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker /* posix read() */
JVM_Read(jint fd,char * buf,jint nbytes)104*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Read(jint fd, char* buf, jint nbytes) {
105*795d594fSAndroid Build Coastguard Worker     return TEMP_FAILURE_RETRY(read(fd, buf, nbytes));
106*795d594fSAndroid Build Coastguard Worker }
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker /* posix write(); is used to write messages to stderr */
JVM_Write(jint fd,char * buf,jint nbytes)109*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Write(jint fd, char* buf, jint nbytes) {
110*795d594fSAndroid Build Coastguard Worker     return TEMP_FAILURE_RETRY(write(fd, buf, nbytes));
111*795d594fSAndroid Build Coastguard Worker }
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker /* posix lseek() */
JVM_Lseek(jint fd,jlong offset,jint whence)114*795d594fSAndroid Build Coastguard Worker JNIEXPORT jlong JVM_Lseek(jint fd, jlong offset, jint whence) {
115*795d594fSAndroid Build Coastguard Worker #if !defined(__APPLE__)
116*795d594fSAndroid Build Coastguard Worker     // NOTE: Using TEMP_FAILURE_RETRY here is busted for LP32 on glibc - the return
117*795d594fSAndroid Build Coastguard Worker     // value will be coerced into an int32_t.
118*795d594fSAndroid Build Coastguard Worker     //
119*795d594fSAndroid Build Coastguard Worker     // lseek64 isn't specified to return EINTR so it shouldn't be necessary
120*795d594fSAndroid Build Coastguard Worker     // anyway.
121*795d594fSAndroid Build Coastguard Worker     return lseek64(fd, offset, whence);
122*795d594fSAndroid Build Coastguard Worker #else
123*795d594fSAndroid Build Coastguard Worker     // NOTE: This code is compiled for Mac OS but isn't ever run on that
124*795d594fSAndroid Build Coastguard Worker     // platform.
125*795d594fSAndroid Build Coastguard Worker     return lseek(fd, offset, whence);
126*795d594fSAndroid Build Coastguard Worker #endif
127*795d594fSAndroid Build Coastguard Worker }
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker /*
130*795d594fSAndroid Build Coastguard Worker  * "raw monitors" seem to be expected to behave like non-recursive pthread
131*795d594fSAndroid Build Coastguard Worker  * mutexes.  They're used by ZipFile.
132*795d594fSAndroid Build Coastguard Worker  */
JVM_RawMonitorCreate(void)133*795d594fSAndroid Build Coastguard Worker JNIEXPORT void* JVM_RawMonitorCreate(void) {
134*795d594fSAndroid Build Coastguard Worker     pthread_mutex_t* mutex =
135*795d594fSAndroid Build Coastguard Worker         reinterpret_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
136*795d594fSAndroid Build Coastguard Worker     CHECK(mutex != nullptr);
137*795d594fSAndroid Build Coastguard Worker     CHECK_PTHREAD_CALL(pthread_mutex_init, (mutex, nullptr), "JVM_RawMonitorCreate");
138*795d594fSAndroid Build Coastguard Worker     return mutex;
139*795d594fSAndroid Build Coastguard Worker }
140*795d594fSAndroid Build Coastguard Worker 
JVM_RawMonitorDestroy(void * mon)141*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_RawMonitorDestroy(void* mon) {
142*795d594fSAndroid Build Coastguard Worker     CHECK_PTHREAD_CALL(pthread_mutex_destroy,
143*795d594fSAndroid Build Coastguard Worker                        (reinterpret_cast<pthread_mutex_t*>(mon)),
144*795d594fSAndroid Build Coastguard Worker                        "JVM_RawMonitorDestroy");
145*795d594fSAndroid Build Coastguard Worker     free(mon);
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker 
JVM_RawMonitorEnter(void * mon)148*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_RawMonitorEnter(void* mon) {
149*795d594fSAndroid Build Coastguard Worker     return pthread_mutex_lock(reinterpret_cast<pthread_mutex_t*>(mon));
150*795d594fSAndroid Build Coastguard Worker }
151*795d594fSAndroid Build Coastguard Worker 
JVM_RawMonitorExit(void * mon)152*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_RawMonitorExit(void* mon) {
153*795d594fSAndroid Build Coastguard Worker     CHECK_PTHREAD_CALL(pthread_mutex_unlock,
154*795d594fSAndroid Build Coastguard Worker                        (reinterpret_cast<pthread_mutex_t*>(mon)),
155*795d594fSAndroid Build Coastguard Worker                        "JVM_RawMonitorExit");
156*795d594fSAndroid Build Coastguard Worker }
157*795d594fSAndroid Build Coastguard Worker 
JVM_NativePath(char * path)158*795d594fSAndroid Build Coastguard Worker JNIEXPORT char* JVM_NativePath(char* path) {
159*795d594fSAndroid Build Coastguard Worker     return path;
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker 
JVM_GetLastErrorString(char * buf,int len)162*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_GetLastErrorString(char* buf, int len) {
163*795d594fSAndroid Build Coastguard Worker #if defined(__GLIBC__) || defined(__BIONIC__)
164*795d594fSAndroid Build Coastguard Worker   if (len == 0) {
165*795d594fSAndroid Build Coastguard Worker     return 0;
166*795d594fSAndroid Build Coastguard Worker   }
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   const int err = errno;
169*795d594fSAndroid Build Coastguard Worker   char* result = strerror_r(err, buf, len);
170*795d594fSAndroid Build Coastguard Worker   if (result != buf) {
171*795d594fSAndroid Build Coastguard Worker     strncpy(buf, result, len);
172*795d594fSAndroid Build Coastguard Worker     buf[len - 1] = '\0';
173*795d594fSAndroid Build Coastguard Worker   }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker   return strlen(buf);
176*795d594fSAndroid Build Coastguard Worker #else
177*795d594fSAndroid Build Coastguard Worker   UNUSED(buf);
178*795d594fSAndroid Build Coastguard Worker   UNUSED(len);
179*795d594fSAndroid Build Coastguard Worker   return -1;
180*795d594fSAndroid Build Coastguard Worker #endif
181*795d594fSAndroid Build Coastguard Worker }
182*795d594fSAndroid Build Coastguard Worker 
jio_fprintf(FILE * fp,const char * fmt,...)183*795d594fSAndroid Build Coastguard Worker JNIEXPORT int jio_fprintf(FILE* fp, const char* fmt, ...) {
184*795d594fSAndroid Build Coastguard Worker     va_list args;
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker     va_start(args, fmt);
187*795d594fSAndroid Build Coastguard Worker     int len = jio_vfprintf(fp, fmt, args);
188*795d594fSAndroid Build Coastguard Worker     va_end(args);
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker     return len;
191*795d594fSAndroid Build Coastguard Worker }
192*795d594fSAndroid Build Coastguard Worker 
jio_vfprintf(FILE * fp,const char * fmt,va_list args)193*795d594fSAndroid Build Coastguard Worker JNIEXPORT int jio_vfprintf(FILE* fp, const char* fmt, va_list args) {
194*795d594fSAndroid Build Coastguard Worker     assert(fp != nullptr);
195*795d594fSAndroid Build Coastguard Worker     return vfprintf(fp, fmt, args);
196*795d594fSAndroid Build Coastguard Worker }
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker /* posix fsync() */
JVM_Sync(jint fd)199*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Sync(jint fd) {
200*795d594fSAndroid Build Coastguard Worker     return TEMP_FAILURE_RETRY(fsync(fd));
201*795d594fSAndroid Build Coastguard Worker }
202*795d594fSAndroid Build Coastguard Worker 
JVM_FindLibraryEntry(void * handle,const char * name)203*795d594fSAndroid Build Coastguard Worker JNIEXPORT void* JVM_FindLibraryEntry(void* handle, const char* name) {
204*795d594fSAndroid Build Coastguard Worker     return dlsym(handle, name);
205*795d594fSAndroid Build Coastguard Worker }
206*795d594fSAndroid Build Coastguard Worker 
JVM_CurrentTimeMillis(JNIEnv * env,jclass clazz)207*795d594fSAndroid Build Coastguard Worker JNIEXPORT jlong JVM_CurrentTimeMillis([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz) {
208*795d594fSAndroid Build Coastguard Worker     struct timeval tv;
209*795d594fSAndroid Build Coastguard Worker     gettimeofday(&tv, (struct timezone *) nullptr);
210*795d594fSAndroid Build Coastguard Worker     jlong when = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
211*795d594fSAndroid Build Coastguard Worker     return when;
212*795d594fSAndroid Build Coastguard Worker }
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker /**
215*795d594fSAndroid Build Coastguard Worker  * See the spec of this function in jdk.internal.misc.VM.
216*795d594fSAndroid Build Coastguard Worker  * @return -1 if the system time isn't within  +/- 2^32 seconds from offset_secs
217*795d594fSAndroid Build Coastguard Worker  */
JVM_GetNanoTimeAdjustment(JNIEnv *,jclass,jlong offset_secs)218*795d594fSAndroid Build Coastguard Worker JNIEXPORT jlong JVM_GetNanoTimeAdjustment([[maybe_unused]] JNIEnv*,
219*795d594fSAndroid Build Coastguard Worker                                           [[maybe_unused]] jclass,
220*795d594fSAndroid Build Coastguard Worker                                           jlong offset_secs) {
221*795d594fSAndroid Build Coastguard Worker     struct timeval tv;
222*795d594fSAndroid Build Coastguard Worker     // Note that we don't want the elapsed time here, but the system clock.
223*795d594fSAndroid Build Coastguard Worker     // gettimeofday() doesn't provide nanosecond-level precision.
224*795d594fSAndroid Build Coastguard Worker     // clock_gettime(CLOCK_REALTIME, tp) may provide nanosecond-level precision.
225*795d594fSAndroid Build Coastguard Worker     // If it does support higher precision, we should switch both
226*795d594fSAndroid Build Coastguard Worker     // JVM_CurrentTimeMillis and JVM_GetNanoTimeAdjustment to use clock_gettime
227*795d594fSAndroid Build Coastguard Worker     // instead of gettimeofday() because various callers assume that
228*795d594fSAndroid Build Coastguard Worker     // System.currentTimeMillis() and VM.getNanoTimeAdjustment(offset) use the
229*795d594fSAndroid Build Coastguard Worker     // same time source.
230*795d594fSAndroid Build Coastguard Worker     gettimeofday(&tv, (struct timezone *) nullptr);
231*795d594fSAndroid Build Coastguard Worker     jlong sec_diff = ((jlong) tv.tv_sec) - offset_secs;
232*795d594fSAndroid Build Coastguard Worker     const jlong max_diff = ((jlong) 1) << 32;
233*795d594fSAndroid Build Coastguard Worker     const jlong min_diff = -max_diff;
234*795d594fSAndroid Build Coastguard Worker     if (sec_diff >= max_diff || sec_diff <= min_diff) {
235*795d594fSAndroid Build Coastguard Worker         return -1;
236*795d594fSAndroid Build Coastguard Worker     }
237*795d594fSAndroid Build Coastguard Worker     jlong usec_diff = sec_diff * 1000000LL + tv.tv_usec;
238*795d594fSAndroid Build Coastguard Worker     return usec_diff * 1000;
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker 
JVM_Socket(jint domain,jint type,jint protocol)241*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Socket(jint domain, jint type, jint protocol) {
242*795d594fSAndroid Build Coastguard Worker     return TEMP_FAILURE_RETRY(socket(domain, type, protocol));
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker 
JVM_InitializeSocketLibrary()245*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_InitializeSocketLibrary() {
246*795d594fSAndroid Build Coastguard Worker   return 0;
247*795d594fSAndroid Build Coastguard Worker }
248*795d594fSAndroid Build Coastguard Worker 
jio_vsnprintf(char * str,size_t count,const char * fmt,va_list args)249*795d594fSAndroid Build Coastguard Worker int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
250*795d594fSAndroid Build Coastguard Worker   if ((intptr_t)count <= 0) return -1;
251*795d594fSAndroid Build Coastguard Worker   return vsnprintf(str, count, fmt, args);
252*795d594fSAndroid Build Coastguard Worker }
253*795d594fSAndroid Build Coastguard Worker 
jio_snprintf(char * str,size_t count,const char * fmt,...)254*795d594fSAndroid Build Coastguard Worker int jio_snprintf(char *str, size_t count, const char *fmt, ...) {
255*795d594fSAndroid Build Coastguard Worker   va_list args;
256*795d594fSAndroid Build Coastguard Worker   int len;
257*795d594fSAndroid Build Coastguard Worker   va_start(args, fmt);
258*795d594fSAndroid Build Coastguard Worker   len = jio_vsnprintf(str, count, fmt, args);
259*795d594fSAndroid Build Coastguard Worker   va_end(args);
260*795d594fSAndroid Build Coastguard Worker   return len;
261*795d594fSAndroid Build Coastguard Worker }
262*795d594fSAndroid Build Coastguard Worker 
JVM_SetSockOpt(jint fd,int level,int optname,const char * optval,int optlen)263*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_SetSockOpt(jint fd, int level, int optname,
264*795d594fSAndroid Build Coastguard Worker     const char* optval, int optlen) {
265*795d594fSAndroid Build Coastguard Worker   return TEMP_FAILURE_RETRY(setsockopt(fd, level, optname, optval, optlen));
266*795d594fSAndroid Build Coastguard Worker }
267*795d594fSAndroid Build Coastguard Worker 
JVM_SocketShutdown(jint fd,jint howto)268*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_SocketShutdown(jint fd, jint howto) {
269*795d594fSAndroid Build Coastguard Worker   return TEMP_FAILURE_RETRY(shutdown(fd, howto));
270*795d594fSAndroid Build Coastguard Worker }
271*795d594fSAndroid Build Coastguard Worker 
JVM_GetSockOpt(jint fd,int level,int optname,char * optval,int * optlen)272*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_GetSockOpt(jint fd, int level, int optname, char* optval,
273*795d594fSAndroid Build Coastguard Worker   int* optlen) {
274*795d594fSAndroid Build Coastguard Worker   socklen_t len = *optlen;
275*795d594fSAndroid Build Coastguard Worker   int cc = TEMP_FAILURE_RETRY(getsockopt(fd, level, optname, optval, &len));
276*795d594fSAndroid Build Coastguard Worker   *optlen = len;
277*795d594fSAndroid Build Coastguard Worker   return cc;
278*795d594fSAndroid Build Coastguard Worker }
279*795d594fSAndroid Build Coastguard Worker 
JVM_GetSockName(jint fd,struct sockaddr * addr,int * addrlen)280*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_GetSockName(jint fd, struct sockaddr* addr, int* addrlen) {
281*795d594fSAndroid Build Coastguard Worker   socklen_t len = *addrlen;
282*795d594fSAndroid Build Coastguard Worker   int cc = TEMP_FAILURE_RETRY(getsockname(fd, addr, &len));
283*795d594fSAndroid Build Coastguard Worker   *addrlen = len;
284*795d594fSAndroid Build Coastguard Worker   return cc;
285*795d594fSAndroid Build Coastguard Worker }
286*795d594fSAndroid Build Coastguard Worker 
JVM_SocketAvailable(jint fd,jint * result)287*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_SocketAvailable(jint fd, jint* result) {
288*795d594fSAndroid Build Coastguard Worker   if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, result)) < 0) {
289*795d594fSAndroid Build Coastguard Worker       return JNI_FALSE;
290*795d594fSAndroid Build Coastguard Worker   }
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker   return JNI_TRUE;
293*795d594fSAndroid Build Coastguard Worker }
294*795d594fSAndroid Build Coastguard Worker 
JVM_Send(jint fd,char * buf,jint nBytes,jint flags)295*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Send(jint fd, char* buf, jint nBytes, jint flags) {
296*795d594fSAndroid Build Coastguard Worker   return TEMP_FAILURE_RETRY(send(fd, buf, nBytes, flags));
297*795d594fSAndroid Build Coastguard Worker }
298*795d594fSAndroid Build Coastguard Worker 
JVM_SocketClose(jint fd)299*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_SocketClose(jint fd) {
300*795d594fSAndroid Build Coastguard Worker   // Don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR.
301*795d594fSAndroid Build Coastguard Worker   return close(fd);
302*795d594fSAndroid Build Coastguard Worker }
303*795d594fSAndroid Build Coastguard Worker 
JVM_Listen(jint fd,jint count)304*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Listen(jint fd, jint count) {
305*795d594fSAndroid Build Coastguard Worker   return TEMP_FAILURE_RETRY(listen(fd, count));
306*795d594fSAndroid Build Coastguard Worker }
307*795d594fSAndroid Build Coastguard Worker 
JVM_Connect(jint fd,struct sockaddr * addr,jint addrlen)308*795d594fSAndroid Build Coastguard Worker JNIEXPORT jint JVM_Connect(jint fd, struct sockaddr* addr, jint addrlen) {
309*795d594fSAndroid Build Coastguard Worker   return TEMP_FAILURE_RETRY(connect(fd, addr, addrlen));
310*795d594fSAndroid Build Coastguard Worker }
311*795d594fSAndroid Build Coastguard Worker 
JVM_GetHostName(char * name,int namelen)312*795d594fSAndroid Build Coastguard Worker JNIEXPORT int JVM_GetHostName(char* name, int namelen) {
313*795d594fSAndroid Build Coastguard Worker   return TEMP_FAILURE_RETRY(gethostname(name, namelen));
314*795d594fSAndroid Build Coastguard Worker }
315*795d594fSAndroid Build Coastguard Worker 
JVM_InternString(JNIEnv * env,jstring jstr)316*795d594fSAndroid Build Coastguard Worker JNIEXPORT jstring JVM_InternString(JNIEnv* env, jstring jstr) {
317*795d594fSAndroid Build Coastguard Worker   art::ScopedFastNativeObjectAccess soa(env);
318*795d594fSAndroid Build Coastguard Worker   art::ObjPtr<art::mirror::String> s = soa.Decode<art::mirror::String>(jstr);
319*795d594fSAndroid Build Coastguard Worker   return soa.AddLocalReference<jstring>(s->Intern());
320*795d594fSAndroid Build Coastguard Worker }
321*795d594fSAndroid Build Coastguard Worker 
JVM_FreeMemory(void)322*795d594fSAndroid Build Coastguard Worker JNIEXPORT jlong JVM_FreeMemory(void) {
323*795d594fSAndroid Build Coastguard Worker   return art::Runtime::Current()->GetHeap()->GetFreeMemory();
324*795d594fSAndroid Build Coastguard Worker }
325*795d594fSAndroid Build Coastguard Worker 
JVM_TotalMemory(void)326*795d594fSAndroid Build Coastguard Worker JNIEXPORT jlong JVM_TotalMemory(void) {
327*795d594fSAndroid Build Coastguard Worker   return art::Runtime::Current()->GetHeap()->GetTotalMemory();
328*795d594fSAndroid Build Coastguard Worker }
329*795d594fSAndroid Build Coastguard Worker 
JVM_MaxMemory(void)330*795d594fSAndroid Build Coastguard Worker JNIEXPORT jlong JVM_MaxMemory(void) {
331*795d594fSAndroid Build Coastguard Worker   return art::Runtime::Current()->GetHeap()->GetMaxMemory();
332*795d594fSAndroid Build Coastguard Worker }
333*795d594fSAndroid Build Coastguard Worker 
JVM_GC(void)334*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_GC(void) {
335*795d594fSAndroid Build Coastguard Worker   if (art::Runtime::Current()->IsExplicitGcDisabled()) {
336*795d594fSAndroid Build Coastguard Worker       LOG(INFO) << "Explicit GC skipped.";
337*795d594fSAndroid Build Coastguard Worker       return;
338*795d594fSAndroid Build Coastguard Worker   }
339*795d594fSAndroid Build Coastguard Worker   art::Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references */ false);
340*795d594fSAndroid Build Coastguard Worker }
341*795d594fSAndroid Build Coastguard Worker 
JVM_Exit(jint status)342*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) void JVM_Exit(jint status) {
343*795d594fSAndroid Build Coastguard Worker   LOG(INFO) << "System.exit called, status: " << status;
344*795d594fSAndroid Build Coastguard Worker   art::Runtime::Current()->CallExitHook(status);
345*795d594fSAndroid Build Coastguard Worker   // Unsafe to call exit() while threads may still be running. They would race
346*795d594fSAndroid Build Coastguard Worker   // with static destructors.
347*795d594fSAndroid Build Coastguard Worker   art::FastExit(status);
348*795d594fSAndroid Build Coastguard Worker }
349*795d594fSAndroid Build Coastguard Worker 
JVM_NativeLoad(JNIEnv * env,jstring javaFilename,jobject javaLoader,jclass caller)350*795d594fSAndroid Build Coastguard Worker JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env,
351*795d594fSAndroid Build Coastguard Worker                                  jstring javaFilename,
352*795d594fSAndroid Build Coastguard Worker                                  jobject javaLoader,
353*795d594fSAndroid Build Coastguard Worker                                  jclass caller) {
354*795d594fSAndroid Build Coastguard Worker   ScopedUtfChars filename(env, javaFilename);
355*795d594fSAndroid Build Coastguard Worker   if (filename.c_str() == nullptr) {
356*795d594fSAndroid Build Coastguard Worker     return nullptr;
357*795d594fSAndroid Build Coastguard Worker   }
358*795d594fSAndroid Build Coastguard Worker 
359*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
360*795d594fSAndroid Build Coastguard Worker   {
361*795d594fSAndroid Build Coastguard Worker     art::JavaVMExt* vm = art::Runtime::Current()->GetJavaVM();
362*795d594fSAndroid Build Coastguard Worker     bool success = vm->LoadNativeLibrary(env,
363*795d594fSAndroid Build Coastguard Worker                                          filename.c_str(),
364*795d594fSAndroid Build Coastguard Worker                                          javaLoader,
365*795d594fSAndroid Build Coastguard Worker                                          caller,
366*795d594fSAndroid Build Coastguard Worker                                          &error_msg);
367*795d594fSAndroid Build Coastguard Worker     if (success) {
368*795d594fSAndroid Build Coastguard Worker       return nullptr;
369*795d594fSAndroid Build Coastguard Worker     }
370*795d594fSAndroid Build Coastguard Worker   }
371*795d594fSAndroid Build Coastguard Worker 
372*795d594fSAndroid Build Coastguard Worker   // Don't let a pending exception from JNI_OnLoad cause a CheckJNI issue with NewStringUTF.
373*795d594fSAndroid Build Coastguard Worker   env->ExceptionClear();
374*795d594fSAndroid Build Coastguard Worker   return env->NewStringUTF(error_msg.c_str());
375*795d594fSAndroid Build Coastguard Worker }
376*795d594fSAndroid Build Coastguard Worker 
JVM_StartThread(JNIEnv * env,jobject jthread,jlong stack_size,jboolean daemon)377*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_StartThread(JNIEnv* env, jobject jthread, jlong stack_size, jboolean daemon) {
378*795d594fSAndroid Build Coastguard Worker   art::Thread::CreateNativeThread(env, jthread, stack_size, daemon == JNI_TRUE);
379*795d594fSAndroid Build Coastguard Worker }
380*795d594fSAndroid Build Coastguard Worker 
JVM_SetThreadPriority(JNIEnv * env,jobject jthread,jint prio)381*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio) {
382*795d594fSAndroid Build Coastguard Worker   art::ScopedObjectAccess soa(env);
383*795d594fSAndroid Build Coastguard Worker   art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
384*795d594fSAndroid Build Coastguard Worker   art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
385*795d594fSAndroid Build Coastguard Worker   if (thread != nullptr) {
386*795d594fSAndroid Build Coastguard Worker     thread->SetNativePriority(prio);
387*795d594fSAndroid Build Coastguard Worker   }
388*795d594fSAndroid Build Coastguard Worker }
389*795d594fSAndroid Build Coastguard Worker 
JVM_Yield(JNIEnv * env,jclass threadClass)390*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_Yield([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass threadClass) {
391*795d594fSAndroid Build Coastguard Worker   sched_yield();
392*795d594fSAndroid Build Coastguard Worker }
393*795d594fSAndroid Build Coastguard Worker 
JVM_Sleep(JNIEnv * env,jclass threadClass,jobject java_lock,jlong millis)394*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_Sleep(JNIEnv* env,
395*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] jclass threadClass,
396*795d594fSAndroid Build Coastguard Worker                          jobject java_lock,
397*795d594fSAndroid Build Coastguard Worker                          jlong millis) {
398*795d594fSAndroid Build Coastguard Worker   art::ScopedFastNativeObjectAccess soa(env);
399*795d594fSAndroid Build Coastguard Worker   art::ObjPtr<art::mirror::Object> lock = soa.Decode<art::mirror::Object>(java_lock);
400*795d594fSAndroid Build Coastguard Worker   art::Monitor::Wait(
401*795d594fSAndroid Build Coastguard Worker       art::Thread::Current(), lock.Ptr(), millis, 0, true, art::ThreadState::kSleeping);
402*795d594fSAndroid Build Coastguard Worker }
403*795d594fSAndroid Build Coastguard Worker 
JVM_CurrentThread(JNIEnv * env,jclass unused)404*795d594fSAndroid Build Coastguard Worker JNIEXPORT jobject JVM_CurrentThread(JNIEnv* env, [[maybe_unused]] jclass unused) {
405*795d594fSAndroid Build Coastguard Worker   art::ScopedFastNativeObjectAccess soa(env);
406*795d594fSAndroid Build Coastguard Worker   return soa.AddLocalReference<jobject>(soa.Self()->GetPeer());
407*795d594fSAndroid Build Coastguard Worker }
408*795d594fSAndroid Build Coastguard Worker 
JVM_Interrupt(JNIEnv * env,jobject jthread)409*795d594fSAndroid Build Coastguard Worker JNIEXPORT void JVM_Interrupt(JNIEnv* env, jobject jthread) {
410*795d594fSAndroid Build Coastguard Worker   art::ScopedFastNativeObjectAccess soa(env);
411*795d594fSAndroid Build Coastguard Worker   art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
412*795d594fSAndroid Build Coastguard Worker   art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
413*795d594fSAndroid Build Coastguard Worker   if (thread != nullptr) {
414*795d594fSAndroid Build Coastguard Worker     thread->Interrupt(soa.Self());
415*795d594fSAndroid Build Coastguard Worker   }
416*795d594fSAndroid Build Coastguard Worker }
417*795d594fSAndroid Build Coastguard Worker 
JVM_IsInterrupted(JNIEnv * env,jobject jthread,jboolean clearInterrupted)418*795d594fSAndroid Build Coastguard Worker JNIEXPORT jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clearInterrupted) {
419*795d594fSAndroid Build Coastguard Worker   if (clearInterrupted) {
420*795d594fSAndroid Build Coastguard Worker     return static_cast<art::JNIEnvExt*>(env)->GetSelf()->Interrupted() ? JNI_TRUE : JNI_FALSE;
421*795d594fSAndroid Build Coastguard Worker   } else {
422*795d594fSAndroid Build Coastguard Worker     art::ScopedFastNativeObjectAccess soa(env);
423*795d594fSAndroid Build Coastguard Worker     art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
424*795d594fSAndroid Build Coastguard Worker     art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
425*795d594fSAndroid Build Coastguard Worker     return (thread != nullptr) ? thread->IsInterrupted() : JNI_FALSE;
426*795d594fSAndroid Build Coastguard Worker   }
427*795d594fSAndroid Build Coastguard Worker }
428*795d594fSAndroid Build Coastguard Worker 
JVM_HoldsLock(JNIEnv * env,jclass unused,jobject jobj)429*795d594fSAndroid Build Coastguard Worker JNIEXPORT jboolean JVM_HoldsLock(JNIEnv* env, [[maybe_unused]] jclass unused, jobject jobj) {
430*795d594fSAndroid Build Coastguard Worker   art::ScopedObjectAccess soa(env);
431*795d594fSAndroid Build Coastguard Worker   art::ObjPtr<art::mirror::Object> object = soa.Decode<art::mirror::Object>(jobj);
432*795d594fSAndroid Build Coastguard Worker   if (object == nullptr) {
433*795d594fSAndroid Build Coastguard Worker     art::ThrowNullPointerException("object == null");
434*795d594fSAndroid Build Coastguard Worker     return JNI_FALSE;
435*795d594fSAndroid Build Coastguard Worker   }
436*795d594fSAndroid Build Coastguard Worker   return soa.Self()->HoldsLock(object);
437*795d594fSAndroid Build Coastguard Worker }
438*795d594fSAndroid Build Coastguard Worker 
JVM_SetNativeThreadName(JNIEnv * env,jobject jthread,jstring java_name)439*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) void JVM_SetNativeThreadName(
440*795d594fSAndroid Build Coastguard Worker     [[maybe_unused]] JNIEnv* env,
441*795d594fSAndroid Build Coastguard Worker     [[maybe_unused]] jobject jthread,
442*795d594fSAndroid Build Coastguard Worker     [[maybe_unused]] jstring java_name) {
443*795d594fSAndroid Build Coastguard Worker   UNIMPLEMENTED(FATAL) << "JVM_SetNativeThreadName is not implemented";
444*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
445*795d594fSAndroid Build Coastguard Worker }
446*795d594fSAndroid Build Coastguard Worker 
JVM_IHashCode(JNIEnv * env,jobject javaObject)447*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) jint JVM_IHashCode([[maybe_unused]] JNIEnv* env,
448*795d594fSAndroid Build Coastguard Worker                                                        [[maybe_unused]] jobject javaObject) {
449*795d594fSAndroid Build Coastguard Worker   UNIMPLEMENTED(FATAL) << "JVM_IHashCode is not implemented";
450*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
451*795d594fSAndroid Build Coastguard Worker }
452*795d594fSAndroid Build Coastguard Worker 
JVM_NanoTime(JNIEnv * env,jclass unused)453*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) jlong JVM_NanoTime([[maybe_unused]] JNIEnv* env,
454*795d594fSAndroid Build Coastguard Worker                                                        [[maybe_unused]] jclass unused) {
455*795d594fSAndroid Build Coastguard Worker   UNIMPLEMENTED(FATAL) << "JVM_NanoTime is not implemented";
456*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
457*795d594fSAndroid Build Coastguard Worker }
458*795d594fSAndroid Build Coastguard Worker 
JVM_ArrayCopy(JNIEnv *,jclass,jobject,jint,jobject,jint,jint)459*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) void JVM_ArrayCopy(JNIEnv* /* env */, jclass /* unused */, jobject /* javaSrc */,
460*795d594fSAndroid Build Coastguard Worker                              jint /* srcPos */, jobject /* javaDst */, jint /* dstPos */,
461*795d594fSAndroid Build Coastguard Worker                              jint /* length */) {
462*795d594fSAndroid Build Coastguard Worker   UNIMPLEMENTED(FATAL) << "JVM_ArrayCopy is not implemented";
463*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
464*795d594fSAndroid Build Coastguard Worker }
465*795d594fSAndroid Build Coastguard Worker 
JVM_FindSignal(const char * name)466*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) jint JVM_FindSignal([[maybe_unused]] const char* name) {
467*795d594fSAndroid Build Coastguard Worker   LOG(FATAL) << "JVM_FindSignal is not implemented";
468*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
469*795d594fSAndroid Build Coastguard Worker }
470*795d594fSAndroid Build Coastguard Worker 
JVM_RegisterSignal(jint signum,void * handler)471*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) void* JVM_RegisterSignal([[maybe_unused]] jint signum,
472*795d594fSAndroid Build Coastguard Worker                                                              [[maybe_unused]] void* handler) {
473*795d594fSAndroid Build Coastguard Worker   LOG(FATAL) << "JVM_RegisterSignal is not implemented";
474*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
475*795d594fSAndroid Build Coastguard Worker }
476*795d594fSAndroid Build Coastguard Worker 
JVM_RaiseSignal(jint signum)477*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn)) jboolean JVM_RaiseSignal([[maybe_unused]] jint signum) {
478*795d594fSAndroid Build Coastguard Worker   LOG(FATAL) << "JVM_RaiseSignal is not implemented";
479*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
480*795d594fSAndroid Build Coastguard Worker }
481*795d594fSAndroid Build Coastguard Worker 
JVM_Halt(jint code)482*795d594fSAndroid Build Coastguard Worker JNIEXPORT __attribute__((noreturn))  void JVM_Halt(jint code) {
483*795d594fSAndroid Build Coastguard Worker   _exit(code);
484*795d594fSAndroid Build Coastguard Worker }
485*795d594fSAndroid Build Coastguard Worker 
JVM_IsNaN(jdouble d)486*795d594fSAndroid Build Coastguard Worker JNIEXPORT jboolean JVM_IsNaN(jdouble d) {
487*795d594fSAndroid Build Coastguard Worker   return isnan(d);
488*795d594fSAndroid Build Coastguard Worker }
489