OpenjdkJvm.cc revision 6280ef88a9231d2a14f2b0bbe6d39770c994787d
1df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/*
2df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * Copyright (C) 2014 The Android Open Source Project
3df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *
4df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * Licensed under the Apache License, Version 2.0 (the "License");
5df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * you may not use this file except in compliance with the License.
6df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * You may obtain a copy of the License at
7df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *
8df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *      http://www.apache.org/licenses/LICENSE-2.0
9df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *
10df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * Unless required by applicable law or agreed to in writing, software
11df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * distributed under the License is distributed on an "AS IS" BASIS,
12df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * See the License for the specific language governing permissions and
14df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * limitations under the License.
15df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */
16df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
17df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/*
18df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * Services that OpenJDK expects the VM to provide.
19df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */
20df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include<stdio.h>
21df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <dlfcn.h>
22df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <limits.h>
23df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <unistd.h>
24df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
25df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "common_throws.h"
26df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "gc/heap.h"
27df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "thread.h"
28df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "thread_list.h"
29df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "runtime.h"
30df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "handle_scope-inl.h"
31df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "scoped_thread_state_change.h"
32df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "ScopedUtfChars.h"
33df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "mirror/class_loader.h"
34df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "verify_object-inl.h"
35df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "base/logging.h"
36df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "base/macros.h"
37a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath#include "../../libcore/ojluni/src/main/native/jvm.h"  // TODO(narayan): fix it
38df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "jni_internal.h"
39df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "mirror/string-inl.h"
40df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "scoped_fast_native_object_access.h"
41df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "ScopedLocalRef.h"
42df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <sys/time.h>
43df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <sys/socket.h>
44df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include <sys/ioctl.h>
45df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
463e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#ifdef __ANDROID__
473e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov// This function is provided by android linker.
483e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanovextern "C" void android_update_LD_LIBRARY_PATH(const char* ld_library_path);
493e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#endif  // __ANDROID__
503e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
51df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#undef LOG_TAG
526280ef88a9231d2a14f2b0bbe6d39770c994787dNarayan Kamath#define LOG_TAG "artopenjdk"
53df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
54d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::DEBUG;
55d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::WARNING;
56d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::VERBOSE;
57d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::INFO;
58d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::ERROR;
59d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamathusing art::FATAL;
60d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath
61df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix open() with extensions; used by e.g. ZipFile */
62a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Open(const char* fname, jint flags, jint mode) {
63df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Open fname='" << fname << "', flags=" << flags << ", mode=" << mode;
64df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
65df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    /*
66df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * The call is expected to handle JVM_O_DELETE, which causes the file
67df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * to be removed after it is opened.  Also, some code seems to
68df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * want the special return value JVM_EEXIST if the file open fails
69df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * due to O_EXCL.
70df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     */
71df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    int fd = TEMP_FAILURE_RETRY(open(fname, flags & ~JVM_O_DELETE, mode));
72df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (fd < 0) {
73df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        int err = errno;
74df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        LOG(DEBUG) << "open(" << fname << ") failed: " << strerror(errno);
75df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        if (err == EEXIST) {
76df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            return JVM_EEXIST;
77df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        } else {
78df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            return -1;
79df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        }
80df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
81df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
82df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (flags & JVM_O_DELETE) {
83df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        LOG(DEBUG) << "Deleting '" << fname << "' after open\n";
84df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        if (unlink(fname) != 0) {
85df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            LOG(WARNING) << "Post-open deletion of '" << fname << "' failed: " << strerror(errno);
86df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        }
87df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        /* ignore */
88df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
89df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
90df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(VERBOSE) << "open(" << fname << ") --> " << fd;
91df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return fd;
92df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
93df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
94df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix close() */
95a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Close(jint fd) {
96df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Close fd=" << fd;
97df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR
98df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return close(fd);
99df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
100df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
101df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix read() */
102a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Read(jint fd, char* buf, jint nbytes) {
103df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Read fd=" << fd << ", buf='" << buf << "', nbytes=" << nbytes;
104df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(read(fd, buf, nbytes));
105df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
106df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
107df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix write(); is used to write messages to stderr */
108a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Write(jint fd, char* buf, jint nbytes) {
109df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Write fd=" << fd << ", buf='" << buf << "', nbytes=" << nbytes;
110df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(write(fd, buf, nbytes));
111df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
112df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
113df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix lseek() */
114a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jlong JVM_Lseek(jint fd, jlong offset, jint whence) {
115df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Lseek fd=" << fd << ", offset=" << offset << ", whence=" << whence;
116df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(lseek(fd, offset, whence));
117df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
118a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath
119df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/*
120df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * "raw monitors" seem to be expected to behave like non-recursive pthread
121df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * mutexes.  They're used by ZipFile.
122df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */
123a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void* JVM_RawMonitorCreate(void) {
124df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorCreate";
125df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    pthread_mutex_t* newMutex =
126a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath        reinterpret_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
127df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    pthread_mutex_init(newMutex, NULL);
128df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return newMutex;
129df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
130df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
131a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void JVM_RawMonitorDestroy(void* mon) {
132df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorDestroy mon=" << mon;
133a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    pthread_mutex_destroy(reinterpret_cast<pthread_mutex_t*>(mon));
134df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
135df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
136a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_RawMonitorEnter(void* mon) {
137df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorEnter mon=" << mon;
138a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    return pthread_mutex_lock(reinterpret_cast<pthread_mutex_t*>(mon));
139df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
140df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
141a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void JVM_RawMonitorExit(void* mon) {
142df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_RawMonitorExit mon=" << mon;
143a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    pthread_mutex_unlock(reinterpret_cast<pthread_mutex_t*>(mon));
144df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
145df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
146a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT char* JVM_NativePath(char* path) {
147df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_NativePath path='" << path << "'";
148df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return path;
149df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
150df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
151a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_GetLastErrorString(char* buf, int len) {
152d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath#if defined(__GLIBC__) || defined(__BIONIC__)
153d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  int err = errno;    // grab before JVM_TRACE can trash it
154d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  LOG(DEBUG) << "JVM_GetLastErrorString buf=" << buf << ", len=" << len;
155d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath
156d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  if (len == 0) {
157d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    return 0;
158d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  }
159df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
160d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  char* result = strerror_r(err, buf, len);
161d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  if (result != buf) {
162d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    strncpy(buf, result, len);
163d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    buf[len - 1] = '\0';
164d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  }
165df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
166d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  return strlen(buf);
167df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#else
168d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  UNUSED(buf);
169d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  UNUSED(len);
170d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  return -1;
171df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#endif
172df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
173df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
174a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT int jio_fprintf(FILE* fp, const char* fmt, ...) {
175df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    va_list args;
176df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
177df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    va_start(args, fmt);
178df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    int len = jio_vfprintf(fp, fmt, args);
179df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    va_end(args);
180df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
181df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return len;
182df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
183df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
184a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT int jio_vfprintf(FILE* fp, const char* fmt, va_list args) {
185df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    assert(fp != NULL);
186df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return vfprintf(fp, fmt, args);
187df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
188df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
189df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix fsync() */
190a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Sync(jint fd) {
191df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Sync fd=" << fd;
192df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(fsync(fd));
193df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
194df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
195a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT void* JVM_FindLibraryEntry(void* handle, const char* name) {
196df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_FindLibraryEntry handle=" << handle << " name=" << name;
19767d39adad3261f3932defef6b2d1d30b470d1be0Przemyslaw Szczepaniak    return dlsym(handle, name);
198df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
199df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
2006c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jlong JVM_CurrentTimeMillis(JNIEnv* env, jclass clazz ATTRIBUTE_UNUSED) {
201df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_CurrentTimeMillis env=" << env;
202df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    struct timeval tv;
203df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
204df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    gettimeofday(&tv, (struct timezone *) NULL);
205df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    jlong when = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
206df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return when;
207df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
208df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
209a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Socket(jint domain, jint type, jint protocol) {
210df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(DEBUG) << "JVM_Socket domain=" << domain << ", type=" << type << ", protocol=" << protocol;
211df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
212df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return TEMP_FAILURE_RETRY(socket(domain, type, protocol));
213df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
214df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
215df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_InitializeSocketLibrary() {
216df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  return 0;
217df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
218df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
219df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskiint jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
220a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  if ((intptr_t)count <= 0) return -1;
221a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return vsnprintf(str, count, fmt, args);
222df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
223df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
224df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskiint jio_snprintf(char *str, size_t count, const char *fmt, ...) {
225a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  va_list args;
226a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int len;
227a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  va_start(args, fmt);
228a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  len = jio_vsnprintf(str, count, fmt, args);
229a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  va_end(args);
230a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return len;
231df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
232df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
233df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_SetSockOpt(jint fd, int level, int optname,
234a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath    const char* optval, int optlen) {
235a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SetSockOpt fd=" << fd << ", level=" << level << ", optname=" << optname
236a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath             << ", optval=" << optval << ", optlen=" << optlen;
237a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(setsockopt(fd, level, optname, optval, optlen));
238df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
239df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
240a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_SocketShutdown(jint fd, jint howto) {
241a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SocketShutdown fd=" << fd << ", howto=" << howto;
242a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(shutdown(fd, howto));
243df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
244df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
245df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_GetSockOpt(jint fd, int level, int optname, char* optval,
246a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int* optlen) {
247a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_GetSockOpt fd=" << fd << ", level=" << level << ", optname=" << optname
248a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath             << ", optval=" << optval << ", optlen=" << optlen;
249df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
250a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  socklen_t len = *optlen;
251a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int cc = TEMP_FAILURE_RETRY(getsockopt(fd, level, optname, optval, &len));
252a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  *optlen = len;
253a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return cc;
254df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
255df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
256a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_GetSockName(jint fd, struct sockaddr* addr, int* addrlen) {
257a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_GetSockName fd=" << fd << ", addr=" << addr << ", addrlen=" << addrlen;
258df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
259a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  socklen_t len = *addrlen;
260a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  int cc = TEMP_FAILURE_RETRY(getsockname(fd, addr, &len));
261a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  *addrlen = len;
262a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return cc;
263df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
264df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
265a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_SocketAvailable(jint fd, jint* result) {
266a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SocketAvailable fd=" << fd << ", result=" << result;
267df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
268a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, result)) < 0) {
269a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      LOG(DEBUG) << "ioctl(" << fd << ", FIONREAD) failed: " << strerror(errno);
270a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      return JNI_FALSE;
271a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  }
272df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
273a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return JNI_TRUE;
274df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
275df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
276a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Send(jint fd, char* buf, jint nBytes, jint flags) {
277a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_Send fd=" << fd << ", buf=" << buf << ", nBytes="
278a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath             << nBytes << ", flags=" << flags;
279df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
280a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(send(fd, buf, nBytes, flags));
281df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
282df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
283a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_SocketClose(jint fd) {
284a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_SocketClose fd=" << fd;
285df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
286df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR
287a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return close(fd);
288df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
289df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
290a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Listen(jint fd, jint count) {
291a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_Listen fd=" << fd << ", count=" << count;
292df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
293a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(listen(fd, count));
294df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
295df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
296a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jint JVM_Connect(jint fd, struct sockaddr* addr, jint addrlen) {
297a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_Connect fd=" << fd << ", addr=" << addr << ", addrlen=" << addrlen;
298df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
299a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(connect(fd, addr, addrlen));
300df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
301df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
302a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT int JVM_GetHostName(char* name, int namelen) {
303a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_GetHostName name=" << name << ", namelen=" << namelen;
304df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
305a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return TEMP_FAILURE_RETRY(gethostname(name, namelen));
306df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
307df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
308a0cf5a663f19f0392187d349f1832d85f90ab805Narayan KamathJNIEXPORT jstring JVM_InternString(JNIEnv* env, jstring jstr) {
309a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  LOG(DEBUG) << "JVM_InternString env=" << env << ", jstr=" << jstr;
310a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::ScopedFastNativeObjectAccess soa(env);
311a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::mirror::String* s = soa.Decode<art::mirror::String*>(jstr);
312a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::mirror::String* result = s->Intern();
313a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return soa.AddLocalReference<jstring>(result);
314df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
315df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
316df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_FreeMemory(void) {
317a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return art::Runtime::Current()->GetHeap()->GetFreeMemory();
318df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
319df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
320df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_TotalMemory(void) {
321a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return art::Runtime::Current()->GetHeap()->GetTotalMemory();
322df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
323df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
324df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_MaxMemory(void) {
325a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  return art::Runtime::Current()->GetHeap()->GetMaxMemory();
326df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
327df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
328df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_GC(void) {
329a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  if (art::Runtime::Current()->IsExplicitGcDisabled()) {
330a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      LOG(INFO) << "Explicit GC skipped.";
331a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath      return;
332a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  }
333a0cf5a663f19f0392187d349f1832d85f90ab805Narayan Kamath  art::Runtime::Current()->GetHeap()->CollectGarbage(false);
334df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
335df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3366c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT __attribute__((noreturn)) void JVM_Exit(jint status) {
337df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  LOG(INFO) << "System.exit called, status: " << status;
338df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Runtime::Current()->CallExitHook(status);
339df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  exit(status);
340df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
341df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3423e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanovstatic void SetLdLibraryPath(JNIEnv* env, jstring javaLdLibraryPath) {
3433e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#ifdef __ANDROID__
3443e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  if (javaLdLibraryPath != nullptr) {
3453e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    ScopedUtfChars ldLibraryPath(env, javaLdLibraryPath);
3463e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    if (ldLibraryPath.c_str() != nullptr) {
3473e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov      android_update_LD_LIBRARY_PATH(ldLibraryPath.c_str());
3483e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    }
3493e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  }
3503e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
3513e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#else
3523e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  LOG(WARNING) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!";
3533e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  UNUSED(javaLdLibraryPath, env);
3543e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov#endif
3553e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov}
3563e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
3573e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
358df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename, jobject javaLoader,
3593e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov                                 jstring javaLdLibraryPath, jstring javaLibraryPermittedPath) {
360df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  ScopedUtfChars filename(env, javaFilename);
361df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (filename.c_str() == NULL) {
362df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return NULL;
363df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
364df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3653e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  int32_t target_sdk_version = art::Runtime::Current()->GetTargetSdkVersion();
3663e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov
3673e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  // Starting with N nativeLoad uses classloader local
3683e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  // linker namespace instead of global LD_LIBRARY_PATH
3693e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  // (23 is Marshmallow)
3703e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  if (target_sdk_version <= 23) {
3713e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    SetLdLibraryPath(env, javaLdLibraryPath);
372df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
373df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
3743e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  std::string error_msg;
375df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  {
376df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::ScopedObjectAccess soa(env);
377df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::StackHandleScope<1> hs(soa.Self());
378df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::JavaVMExt* vm = art::Runtime::Current()->GetJavaVM();
3793e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov    bool success = vm->LoadNativeLibrary(env, filename.c_str(), javaLoader,
3803e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov                                         javaLdLibraryPath, javaLibraryPermittedPath, &error_msg);
381df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (success) {
382df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      return nullptr;
383df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
384df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
385df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
386df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // Don't let a pending exception from JNI_OnLoad cause a CheckJNI issue with NewStringUTF.
387df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  env->ExceptionClear();
3883e381723658e8a0bce24071b53f57bf22af76a1eDmitriy Ivanov  return env->NewStringUTF(error_msg.c_str());
389df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
390df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
391df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_StartThread(JNIEnv* env, jobject jthread, jlong stack_size, jboolean daemon) {
392df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread::CreateNativeThread(env, jthread, stack_size, daemon == JNI_TRUE);
393df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
394df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
395df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio) {
396df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedObjectAccess soa(env);
397df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
398df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
399df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (thread != NULL) {
400df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread->SetNativePriority(prio);
401df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
402df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
403df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4046c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT void JVM_Yield(JNIEnv* env ATTRIBUTE_UNUSED, jclass threadClass ATTRIBUTE_UNUSED) {
405df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  sched_yield();
406df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
407df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4086c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT void JVM_Sleep(JNIEnv* env, jclass threadClass ATTRIBUTE_UNUSED,
4096c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw Szczepaniak                         jobject java_lock, jlong millis) {
410df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedFastNativeObjectAccess soa(env);
411df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::mirror::Object* lock = soa.Decode<art::mirror::Object*>(java_lock);
412df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Monitor::Wait(art::Thread::Current(), lock, millis, 0, true, art::kSleeping);
413df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
414df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4156c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jobject JVM_CurrentThread(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED) {
416df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedFastNativeObjectAccess soa(env);
417df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  return soa.AddLocalReference<jobject>(soa.Self()->GetPeer());
418df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
419df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
420df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Interrupt(JNIEnv* env, jobject jthread) {
421df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedFastNativeObjectAccess soa(env);
422df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
423df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
424df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (thread != nullptr) {
425df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread->Interrupt(soa.Self());
426df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
427df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
428df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
429df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clearInterrupted) {
430df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (clearInterrupted) {
431df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return static_cast<art::JNIEnvExt*>(env)->self->Interrupted() ? JNI_TRUE : JNI_FALSE;
432df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  } else {
433df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::ScopedFastNativeObjectAccess soa(env);
434df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
435df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
436df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return (thread != nullptr) ? thread->IsInterrupted() : JNI_FALSE;
437df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
438df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
439df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4406c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jboolean JVM_HoldsLock(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED, jobject jobj) {
441df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ScopedObjectAccess soa(env);
442df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::mirror::Object* object = soa.Decode<art::mirror::Object*>(jobj);
443df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (object == NULL) {
444d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath    art::ThrowNullPointerException("object == null");
445df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return JNI_FALSE;
446df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
447df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  return soa.Self()->HoldsLock(object);
448df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
449df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
450df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring java_name) {
451df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  ScopedUtfChars name(env, java_name);
452df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  {
453df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    art::ScopedObjectAccess soa(env);
454df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (soa.Decode<art::mirror::Object*>(jthread) == soa.Self()->GetPeer()) {
455df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      soa.Self()->SetThreadName(name.c_str());
456df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      return;
457df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
458df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
459df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // Suspend thread to avoid it from killing itself while we set its name. We don't just hold the
460df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // thread list lock to avoid this, as setting the thread name causes mutator to lock/unlock
461df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // in the DDMS send code.
462df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::ThreadList* thread_list = art::Runtime::Current()->GetThreadList();
463df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  bool timed_out;
464df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  // Take suspend thread lock to avoid races with threads trying to suspend this one.
465df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  art::Thread* thread;
466df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  {
467df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread = thread_list->SuspendThreadByPeer(jthread, true, false, &timed_out);
468df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
469df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  if (thread != NULL) {
470df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    {
471df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      art::ScopedObjectAccess soa(env);
472df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski      thread->SetThreadName(name.c_str());
473df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
474df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    thread_list->Resume(thread, false);
475df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  } else if (timed_out) {
476df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread "
477df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        "failed to suspend within a generous timeout.";
478df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  }
479df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
480df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
48168d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan KamathJNIEXPORT jint JVM_IHashCode(JNIEnv* env ATTRIBUTE_UNUSED,
48268d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath                             jobject javaObject ATTRIBUTE_UNUSED) {
48368d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  UNIMPLEMENTED(FATAL) << "JVM_IHashCode is not implemented";
48468d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  return 0;
485df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
486df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4876c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jlong JVM_NanoTime(JNIEnv* env ATTRIBUTE_UNUSED, jclass unused ATTRIBUTE_UNUSED) {
48868d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  UNIMPLEMENTED(FATAL) << "JVM_NanoTime is not implemented";
48968d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  return 0L;
490df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
491df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
49268d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan KamathJNIEXPORT void JVM_ArrayCopy(JNIEnv* /* env */, jclass /* unused */, jobject /* javaSrc */,
49368d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath                             jint /* srcPos */, jobject /* javaDst */, jint /* dstPos */,
49468d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath                             jint /* length */) {
49568d8ff4bc1b83c87e9dac0ac0394d1381369e223Narayan Kamath  UNIMPLEMENTED(FATAL) << "JVM_ArrayCopy is not implemented";
496df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
497df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
4986c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jint JVM_FindSignal(const char* name ATTRIBUTE_UNUSED) {
49936379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  LOG(FATAL) << "JVM_FindSignal is not implemented";
50036379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  return 0;
501df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
502df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5036c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT void* JVM_RegisterSignal(jint signum ATTRIBUTE_UNUSED, void* handler ATTRIBUTE_UNUSED) {
50436379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  LOG(FATAL) << "JVM_RegisterSignal is not implemented";
50536379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  return nullptr;
506df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
507df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5086c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT jboolean JVM_RaiseSignal(jint signum ATTRIBUTE_UNUSED) {
50936379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  LOG(FATAL) << "JVM_RaiseSignal is not implemented";
51036379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath  return JNI_FALSE;
511df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
512df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
5136c0ea2799f7dc8b8763c07a6e94c23590f6b54b5Przemyslaw SzczepaniakJNIEXPORT __attribute__((noreturn))  void JVM_Halt(jint code) {
514df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  exit(code);
515df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
516b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak
517b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw SzczepaniakJNIEXPORT jboolean JVM_IsNaN(jdouble d) {
518b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak  return isnan(d);
519b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak}
520