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