OpenjdkJvm.cc revision 18d209582e0bb1caed97102a86b416173f5aad42
128ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath/* Copyright (C) 2014 The Android Open Source Project
228ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
328ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath *
428ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * This file implements interfaces from the file jvm.h. This implementation
528ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * is licensed under the same terms as the file jvm.h.  The
628ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * copyright and license information for the file jvm.h follows.
728ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath *
828ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
928ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1028ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath *
1128ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * This code is free software; you can redistribute it and/or modify it
1228ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * under the terms of the GNU General Public License version 2 only, as
1328ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * published by the Free Software Foundation.  Oracle designates this
1428ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * particular file as subject to the "Classpath" exception as provided
1528ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * by Oracle in the LICENSE file that accompanied this code.
16df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *
1728ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * This code is distributed in the hope that it will be useful, but WITHOUT
1828ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1928ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2028ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * version 2 for more details (a copy is included in the LICENSE file that
2128ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * accompanied this code).
22df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *
2328ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * You should have received a copy of the GNU General Public License version
2428ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * 2 along with this work; if not, write to the Free Software Foundation,
2528ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *
2728ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2828ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * or visit www.oracle.com if you need additional information or have any
2928ee8dbece62bf1ed9a7dfd3c581fd5860ed8867Narayan Kamath * questions.
30df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */
31df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
32df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/*
33df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * Services that OpenJDK expects the VM to provide.
34df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */
35df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include<stdio.h>
36df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <dlfcn.h>
37df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <limits.h>
38df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <unistd.h>
39df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
40df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "common_throws.h"
41df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "gc/heap.h"
42df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "thread.h"
43df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "thread_list.h"
44df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "runtime.h"
45df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "handle_scope-inl.h"
46df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "scoped_thread_state_change.h"
47df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "ScopedUtfChars.h"
48df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "mirror/class_loader.h"
49df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "verify_object-inl.h"
50df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "base/logging.h"
51df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "base/macros.h"
52a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath#include "../../libcore/ojluni/src/main/native/jvm.h"  // TODO(narayan): fix it
53df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "jni_internal.h"
54df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "mirror/string-inl.h"
5518d209582e0bb1caed97102a86b416173f5aad42Narayan Kamath#include "native/scoped_fast_native_object_access.h"
56df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "ScopedLocalRef.h"
57df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <sys/time.h>
58df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <sys/socket.h>
59df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <sys/ioctl.h>
60df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
613e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#ifdef __ANDROID__
623e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov// This function is provided by android linker.
633e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanovextern "C" void android_update_LD_LIBRARY_PATH(const char* ld_library_path);
643e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#endif  // __ANDROID__
653e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
66df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#undef LOG_TAG
676280ef88a9231d2a14f2b0bbe6d39770c994787dNarayan Kamath#define LOG_TAG "artopenjdk"
68df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
69d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::DEBUG;
70d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::WARNING;
71d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::VERBOSE;
72d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::INFO;
73d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::ERROR;
74d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::FATAL;
75d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath
76df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix open() with extensions; used by e.g. ZipFile */
77a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Open(const char* fname, jint flags, jint mode) {
78df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Open fname='" << fname << "', flags=" << flags << ", mode=" << mode;
79df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
80df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    /*
81df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * The call is expected to handle JVM_O_DELETE, which causes the file
82df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * to be removed after it is opened.  Also, some code seems to
83df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * want the special return value JVM_EEXIST if the file open fails
84df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * due to O_EXCL.
85df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     */
86df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    int fd = TEMP_FAILURE_RETRY(open(fname, flags & ~JVM_O_DELETE, mode));
87df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (fd < 0) {
88df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        int err = errno;
89df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        LOG(DEBUG) << "open(" << fname << ") failed: " << strerror(errno);
90df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        if (err == EEXIST) {
91df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            return JVM_EEXIST;
92df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        } else {
93df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            return -1;
94df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        }
95df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
96df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
97df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (flags & JVM_O_DELETE) {
98df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        LOG(DEBUG) << "Deleting '" << fname << "' after open\n";
99df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        if (unlink(fname) != 0) {
100df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            LOG(WARNING) << "Post-open deletion of '" << fname << "' failed: " << strerror(errno);
101df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        }
102df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        /* ignore */
103df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
104df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
105df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(VERBOSE) << "open(" << fname << ") --> " << fd;
106df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return fd;
107df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
108df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
109df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix close() */
110a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Close(jint fd) {
111df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Close fd=" << fd;
112df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR
113df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return close(fd);
114df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
115df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
116df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix read() */
117a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Read(jint fd, char* buf, jint nbytes) {
118df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Read fd=" << fd << ", buf='" << buf << "', nbytes=" << nbytes;
119df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(read(fd, buf, nbytes));
120df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
121df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
122df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix write(); is used to write messages to stderr */
123a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Write(jint fd, char* buf, jint nbytes) {
124df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Write fd=" << fd << ", buf='" << buf << "', nbytes=" << nbytes;
125df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(write(fd, buf, nbytes));
126df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
127df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
128df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix lseek() */
129a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jlong JVM_Lseek(jint fd, jlong offset, jint whence) {
130df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Lseek fd=" << fd << ", offset=" << offset << ", whence=" << whence;
131df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(lseek(fd, offset, whence));
132df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
133a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath
134df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/*
135df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * "raw monitors" seem to be expected to behave like non-recursive pthread
136df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * mutexes.  They're used by ZipFile.
137df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */
138a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void* JVM_RawMonitorCreate(void) {
139df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorCreate";
140df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    pthread_mutex_t* newMutex =
141a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath        reinterpret_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
142df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    pthread_mutex_init(newMutex, NULL);
143df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return newMutex;
144df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
145df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
146a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void JVM_RawMonitorDestroy(void* mon) {
147df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorDestroy mon=" << mon;
148a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    pthread_mutex_destroy(reinterpret_cast<pthread_mutex_t*>(mon));
149df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
150df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
151a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_RawMonitorEnter(void* mon) {
152df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorEnter mon=" << mon;
153a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    return pthread_mutex_lock(reinterpret_cast<pthread_mutex_t*>(mon));
154df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
155df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
156a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void JVM_RawMonitorExit(void* mon) {
157df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorExit mon=" << mon;
158a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    pthread_mutex_unlock(reinterpret_cast<pthread_mutex_t*>(mon));
159df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
160df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
161a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT char* JVM_NativePath(char* path) {
162df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_NativePath path='" << path << "'";
163df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return path;
164df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
165df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
166a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_GetLastErrorString(char* buf, int len) {
167d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath#if defined(__GLIBC__) || defined(__BIONIC__)
168d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  int err = errno;    // grab before JVM_TRACE can trash it
169d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  LOG(DEBUG) << "JVM_GetLastErrorString buf=" << buf << ", len=" << len;
170d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath
171d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  if (len == 0) {
172d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    return 0;
173d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  }
174df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
175d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  char* result = strerror_r(err, buf, len);
176d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  if (result != buf) {
177d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    strncpy(buf, result, len);
178d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    buf[len - 1] = '\0';
179d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  }
180df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
181d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  return strlen(buf);
182df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#else
183d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  UNUSED(buf);
184d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  UNUSED(len);
185d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  return -1;
186df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#endif
187df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
188df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
189a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT int jio_fprintf(FILE* fp, const char* fmt, ...) {
190df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    va_list args;
191df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
192df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    va_start(args, fmt);
193df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    int len = jio_vfprintf(fp, fmt, args);
194df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    va_end(args);
195df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
196df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return len;
197df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
198df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
199a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT int jio_vfprintf(FILE* fp, const char* fmt, va_list args) {
200df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    assert(fp != NULL);
201df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return vfprintf(fp, fmt, args);
202df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
203df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
204df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix fsync() */
205a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Sync(jint fd) {
206df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Sync fd=" << fd;
207df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(fsync(fd));
208df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
209df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
210a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void* JVM_FindLibraryEntry(void* handle, const char* name) {
211df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_FindLibraryEntry handle=" << handle << " name=" << name;
21267d39adad3261f3932defef6b2d1d30b470d1be0Przemyslaw Szczepaniak    return dlsym(handle, name);
213df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
214df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
2156c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jlong JVM_CurrentTimeMillis(JNIEnv* env, jclass clazz ATTRIBUTE_UNUSED) {
216df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_CurrentTimeMillis env=" << env;
217df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    struct timeval tv;
218df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
219df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    gettimeofday(&tv, (struct timezone *) NULL);
220df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    jlong when = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
221df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return when;
222df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
223df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
224a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Socket(jint domain, jint type, jint protocol) {
225df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Socket domain=" << domain << ", type=" << type << ", protocol=" << protocol;
226df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
227df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(socket(domain, type, protocol));
228df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
229df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
230df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_InitializeSocketLibrary() {
231df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  return 0;
232df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
233df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
234df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskiint jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
235a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  if ((intptr_t)count <= 0) return -1;
236a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return vsnprintf(str, count, fmt, args);
237df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
238df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
239df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskiint jio_snprintf(char *str, size_t count, const char *fmt, ...) {
240a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  va_list args;
241a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int len;
242a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  va_start(args, fmt);
243a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  len = jio_vsnprintf(str, count, fmt, args);
244a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  va_end(args);
245a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return len;
246df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
247df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
248df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_SetSockOpt(jint fd, int level, int optname,
249a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    const char* optval, int optlen) {
250a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SetSockOpt fd=" << fd << ", level=" << level << ", optname=" << optname
251a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath             << ", optval=" << optval << ", optlen=" << optlen;
252a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(setsockopt(fd, level, optname, optval, optlen));
253df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
254df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
255a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_SocketShutdown(jint fd, jint howto) {
256a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SocketShutdown fd=" << fd << ", howto=" << howto;
257a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(shutdown(fd, howto));
258df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
259df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
260df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_GetSockOpt(jint fd, int level, int optname, char* optval,
261a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int* optlen) {
262a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_GetSockOpt fd=" << fd << ", level=" << level << ", optname=" << optname
263a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath             << ", optval=" << optval << ", optlen=" << optlen;
264df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
265a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  socklen_t len = *optlen;
266a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int cc = TEMP_FAILURE_RETRY(getsockopt(fd, level, optname, optval, &len));
267a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  *optlen = len;
268a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return cc;
269df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
270df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
271a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_GetSockName(jint fd, struct sockaddr* addr, int* addrlen) {
272a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_GetSockName fd=" << fd << ", addr=" << addr << ", addrlen=" << addrlen;
273df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
274a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  socklen_t len = *addrlen;
275a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int cc = TEMP_FAILURE_RETRY(getsockname(fd, addr, &len));
276a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  *addrlen = len;
277a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return cc;
278df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
279df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
280a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_SocketAvailable(jint fd, jint* result) {
281a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SocketAvailable fd=" << fd << ", result=" << result;
282df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
283a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, result)) < 0) {
284a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      LOG(DEBUG) << "ioctl(" << fd << ", FIONREAD) failed: " << strerror(errno);
285a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      return JNI_FALSE;
286a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  }
287df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
288a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return JNI_TRUE;
289df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
290df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
291a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Send(jint fd, char* buf, jint nBytes, jint flags) {
292a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_Send fd=" << fd << ", buf=" << buf << ", nBytes="
293a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath             << nBytes << ", flags=" << flags;
294df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
295a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(send(fd, buf, nBytes, flags));
296df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
297df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
298a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_SocketClose(jint fd) {
299a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SocketClose fd=" << fd;
300df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
301df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR
302a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return close(fd);
303df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
304df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
305a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Listen(jint fd, jint count) {
306a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_Listen fd=" << fd << ", count=" << count;
307df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
308a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(listen(fd, count));
309df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
310df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
311a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Connect(jint fd, struct sockaddr* addr, jint addrlen) {
312a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_Connect fd=" << fd << ", addr=" << addr << ", addrlen=" << addrlen;
313df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
314a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(connect(fd, addr, addrlen));
315df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
316df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
317a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT int JVM_GetHostName(char* name, int namelen) {
318a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_GetHostName name=" << name << ", namelen=" << namelen;
319df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
320a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(gethostname(name, namelen));
321df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
322df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
323a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jstring JVM_InternString(JNIEnv* env, jstring jstr) {
324a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_InternString env=" << env << ", jstr=" << jstr;
325a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::ScopedFastNativeObjectAccess soa(env);
326a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::mirror::String* s = soa.Decode<art::mirror::String*>(jstr);
327a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::mirror::String* result = s->Intern();
328a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return soa.AddLocalReference<jstring>(result);
329df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
330df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
331df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_FreeMemory(void) {
332a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return art::Runtime::Current()->GetHeap()->GetFreeMemory();
333df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
334df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
335df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_TotalMemory(void) {
336a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return art::Runtime::Current()->GetHeap()->GetTotalMemory();
337df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
338df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
339df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_MaxMemory(void) {
340a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return art::Runtime::Current()->GetHeap()->GetMaxMemory();
341df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
342df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
343df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_GC(void) {
344a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  if (art::Runtime::Current()->IsExplicitGcDisabled()) {
345a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      LOG(INFO) << "Explicit GC skipped.";
346a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      return;
347a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  }
348a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::Runtime::Current()->GetHeap()->CollectGarbage(false);
349df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
350df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3516c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT __attribute__((noreturn)) void JVM_Exit(jint status) {
352df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  LOG(INFO) << "System.exit called, status: " << status;
353df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Runtime::Current()->CallExitHook(status);
354df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  exit(status);
355df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
356df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3573e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanovstatic void SetLdLibraryPath(JNIEnv* env, jstring javaLdLibraryPath) {
3583e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#ifdef __ANDROID__
3593e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  if (javaLdLibraryPath != nullptr) {
3603e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    ScopedUtfChars ldLibraryPath(env, javaLdLibraryPath);
3613e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    if (ldLibraryPath.c_str() != nullptr) {
3623e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov      android_update_LD_LIBRARY_PATH(ldLibraryPath.c_str());
3633e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    }
3643e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  }
3653e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
3663e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#else
3673e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  LOG(WARNING) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!";
3683e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  UNUSED(javaLdLibraryPath, env);
3693e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#endif
3703e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov}
3713e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
3723e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
373df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename, jobject javaLoader,
374986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                 jboolean isSharedNamespace, jstring javaLibrarySearchPath,
375986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                 jstring javaLibraryPermittedPath) {
376df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  ScopedUtfChars filename(env, javaFilename);
377df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (filename.c_str() == NULL) {
378df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return NULL;
379df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
380df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3813e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  int32_t target_sdk_version = art::Runtime::Current()->GetTargetSdkVersion();
3823e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
3833e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  // Starting with N nativeLoad uses classloader local
3843e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  // linker namespace instead of global LD_LIBRARY_PATH
3853e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  // (23 is Marshmallow)
3863e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  if (target_sdk_version <= 23) {
387986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov    SetLdLibraryPath(env, javaLibrarySearchPath);
388df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
389df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3903e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  std::string error_msg;
391df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  {
392df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::ScopedObjectAccess soa(env);
393df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::StackHandleScope<1> hs(soa.Self());
394df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::JavaVMExt* vm = art::Runtime::Current()->GetJavaVM();
395986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov    bool success = vm->LoadNativeLibrary(env,
396986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                         filename.c_str(),
397986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                         javaLoader,
398986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                         isSharedNamespace == JNI_TRUE,
399986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                         javaLibrarySearchPath,
400986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                         javaLibraryPermittedPath,
401986f650d8b552e8b7dbebef1f50f015e7850edfcDimitry Ivanov                                         &error_msg);
402df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (success) {
403df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      return nullptr;
404df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
405df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
406df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
407df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // Don't let a pending exception from JNI_OnLoad cause a CheckJNI issue with NewStringUTF.
408df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  env->ExceptionClear();
4093e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  return env->NewStringUTF(error_msg.c_str());
410df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
411df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
412df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_StartThread(JNIEnv* env, jobject jthread, jlong stack_size, jboolean daemon) {
413df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread::CreateNativeThread(env, jthread, stack_size, daemon == JNI_TRUE);
414df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
415df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
416df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio) {
417df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedObjectAccess soa(env);
418df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
419df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
420df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (thread != NULL) {
421df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread->SetNativePriority(prio);
422df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
423df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
424df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4256c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT void JVM_Yield(JNIEnv* env ATTRIBUTE_UNUSED, jclass threadClass ATTRIBUTE_UNUSED) {
426df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  sched_yield();
427df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
428df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4296c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT void JVM_Sleep(JNIEnv* env, jclass threadClass ATTRIBUTE_UNUSED,
4306c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw Szczepaniak                         jobject java_lock, jlong millis) {
431df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedFastNativeObjectAccess soa(env);
432df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::mirror::Object* lock = soa.Decode<art::mirror::Object*>(java_lock);
433df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Monitor::Wait(art::Thread::Current(), lock, millis, 0, true, art::kSleeping);
434df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
435df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4366c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jobject JVM_CurrentThread(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED) {
437df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedFastNativeObjectAccess soa(env);
438df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  return soa.AddLocalReference<jobject>(soa.Self()->GetPeer());
439df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
440df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
441df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Interrupt(JNIEnv* env, jobject jthread) {
442df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedFastNativeObjectAccess soa(env);
443df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
444df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
445df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (thread != nullptr) {
446df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread->Interrupt(soa.Self());
447df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
448df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
449df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
450df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clearInterrupted) {
451df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (clearInterrupted) {
452df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return static_cast<art::JNIEnvExt*>(env)->self->Interrupted() ? JNI_TRUE : JNI_FALSE;
453df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  } else {
454df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::ScopedFastNativeObjectAccess soa(env);
455df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
456df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
457df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return (thread != nullptr) ? thread->IsInterrupted() : JNI_FALSE;
458df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
459df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
460df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4616c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jboolean JVM_HoldsLock(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED, jobject jobj) {
462df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedObjectAccess soa(env);
463df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::mirror::Object* object = soa.Decode<art::mirror::Object*>(jobj);
464df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (object == NULL) {
465d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    art::ThrowNullPointerException("object == null");
466df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return JNI_FALSE;
467df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
468df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  return soa.Self()->HoldsLock(object);
469df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
470df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
471df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring java_name) {
472df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  ScopedUtfChars name(env, java_name);
473df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  {
474df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::ScopedObjectAccess soa(env);
475df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (soa.Decode<art::mirror::Object*>(jthread) == soa.Self()->GetPeer()) {
476df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      soa.Self()->SetThreadName(name.c_str());
477df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      return;
478df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
479df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
480df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // Suspend thread to avoid it from killing itself while we set its name. We don't just hold the
481df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // thread list lock to avoid this, as setting the thread name causes mutator to lock/unlock
482df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // in the DDMS send code.
483df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ThreadList* thread_list = art::Runtime::Current()->GetThreadList();
484df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  bool timed_out;
485df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // Take suspend thread lock to avoid races with threads trying to suspend this one.
486df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread* thread;
487df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  {
488df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread = thread_list->SuspendThreadByPeer(jthread, true, false, &timed_out);
489df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
490df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (thread != NULL) {
491df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    {
492df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      art::ScopedObjectAccess soa(env);
493df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      thread->SetThreadName(name.c_str());
494df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
495df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread_list->Resume(thread, false);
496df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  } else if (timed_out) {
497df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread "
498df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        "failed to suspend within a generous timeout.";
499df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
500df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
501df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
50268d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan KamathJNIEXPORT jint JVM_IHashCode(JNIEnv* env ATTRIBUTE_UNUSED,
50368d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath                             jobject javaObject ATTRIBUTE_UNUSED) {
50468d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  UNIMPLEMENTED(FATAL) << "JVM_IHashCode is not implemented";
50568d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  return 0;
506df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
507df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5086c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jlong JVM_NanoTime(JNIEnv* env ATTRIBUTE_UNUSED, jclass unused ATTRIBUTE_UNUSED) {
50968d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  UNIMPLEMENTED(FATAL) << "JVM_NanoTime is not implemented";
51068d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  return 0L;
511df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
512df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
51368d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan KamathJNIEXPORT void JVM_ArrayCopy(JNIEnv* /* env */, jclass /* unused */, jobject /* javaSrc */,
51468d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath                             jint /* srcPos */, jobject /* javaDst */, jint /* dstPos */,
51568d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath                             jint /* length */) {
51668d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  UNIMPLEMENTED(FATAL) << "JVM_ArrayCopy is not implemented";
517df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
518df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5196c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jint JVM_FindSignal(const char* name ATTRIBUTE_UNUSED) {
52036379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  LOG(FATAL) << "JVM_FindSignal is not implemented";
52136379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  return 0;
522df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
523df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5246c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT void* JVM_RegisterSignal(jint signum ATTRIBUTE_UNUSED, void* handler ATTRIBUTE_UNUSED) {
52536379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  LOG(FATAL) << "JVM_RegisterSignal is not implemented";
52636379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  return nullptr;
527df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
528df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5296c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jboolean JVM_RaiseSignal(jint signum ATTRIBUTE_UNUSED) {
53036379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  LOG(FATAL) << "JVM_RaiseSignal is not implemented";
53136379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  return JNI_FALSE;
532df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
533df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5346c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT __attribute__((noreturn))  void JVM_Halt(jint code) {
535df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  exit(code);
536df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
537b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak
538b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw SzczepaniakJNIEXPORT jboolean JVM_IsNaN(jdouble d) {
539b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak  return isnan(d);
540b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak}
541