OpenjdkJvm.cc revision b02d9b7329909cbf741b16faf81616a992a1bd2b
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" 37df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#include "../../libcore/ojluni/src/main/native/jvm.h" // TODO(haaawk): 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 46df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#undef LOG_TAG 47df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#define LOG_TAG "artopenjdx" 48df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 49df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix open() with extensions; used by e.g. ZipFile */ 50df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Open(const char* fname, jint flags, jint mode) 51df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 52df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Open fname='" << fname << "', flags=" << flags << ", mode=" << mode; 53df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 54df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski /* 55df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * The call is expected to handle JVM_O_DELETE, which causes the file 56df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * to be removed after it is opened. Also, some code seems to 57df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * want the special return value JVM_EEXIST if the file open fails 58df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * due to O_EXCL. 59df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */ 60df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int fd = TEMP_FAILURE_RETRY(open(fname, flags & ~JVM_O_DELETE, mode)); 61df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (fd < 0) { 62df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int err = errno; 63df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "open(" << fname << ") failed: " << strerror(errno); 64df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (err == EEXIST) { 65df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return JVM_EEXIST; 66df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } else { 67df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return -1; 68df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 69df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 70df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 71df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (flags & JVM_O_DELETE) { 72df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "Deleting '" << fname << "' after open\n"; 73df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (unlink(fname) != 0) { 74df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(WARNING) << "Post-open deletion of '" << fname << "' failed: " << strerror(errno); 75df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 76df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski /* ignore */ 77df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 78df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 79df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(VERBOSE) << "open(" << fname << ") --> " << fd; 80df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return fd; 81df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 82df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 83df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix close() */ 84df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Close(jint fd) 85df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 86df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Close fd=" << fd; 87df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR 88df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return close(fd); 89df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 90df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 91df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix read() */ 92df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Read(jint fd, char* buf, jint nbytes) 93df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 94df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Read fd=" << fd << ", buf='" << buf << "', nbytes=" << nbytes; 95df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(read(fd, buf, nbytes)); 96df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 97df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 98df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix write(); is used to write messages to stderr */ 99df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Write(jint fd, char* buf, jint nbytes) 100df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 101df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Write fd=" << fd << ", buf='" << buf << "', nbytes=" << nbytes; 102df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(write(fd, buf, nbytes)); 103df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 104df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 105df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix lseek() */ 106df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_Lseek(jint fd, jlong offset, jint whence) 107df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 108df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Lseek fd=" << fd << ", offset=" << offset << ", whence=" << whence; 109df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(lseek(fd, offset, whence)); 110df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 111df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* 112df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * "raw monitors" seem to be expected to behave like non-recursive pthread 113df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski * mutexes. They're used by ZipFile. 114df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski */ 115df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 116df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void* JVM_RawMonitorCreate(void) 117df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 118df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_RawMonitorCreate"; 119df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski pthread_mutex_t* newMutex = 120df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); 121df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski pthread_mutex_init(newMutex, NULL); 122df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return newMutex; 123df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 124df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 125df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_RawMonitorDestroy(void* mon) 126df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 127df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_RawMonitorDestroy mon=" << mon; 128df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski pthread_mutex_destroy((pthread_mutex_t*) mon); 129df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 130df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 131df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_RawMonitorEnter(void* mon) 132df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 133df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_RawMonitorEnter mon=" << mon; 134df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return pthread_mutex_lock((pthread_mutex_t*) mon); 135df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 136df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 137df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_RawMonitorExit(void* mon) 138df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 139df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_RawMonitorExit mon=" << mon; 140df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski pthread_mutex_unlock((pthread_mutex_t*) mon); 141df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 142df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 143df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT char* JVM_NativePath(char* path) 144df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 145df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_NativePath path='" << path << "'"; 146df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return path; 147df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 148df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 149df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_GetLastErrorString(char* buf, int len) 150df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 151df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int err = errno; // grab before JVM_TRACE can trash it 152df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_GetLastErrorString buf=" << buf << ", len=" << len; 153df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 154df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#ifdef __GLIBC__ 155df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (len == 0) 156df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return 0; 157df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 158df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski char* result = strerror_r(err, buf, len); 159df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (result != buf) { 160df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski strncpy(buf, result, len); 161df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski buf[len-1] = '\0'; 162df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 163df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return strlen(buf); 164df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#else 165df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return strerror_r(err, buf, len); 166df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#endif 167df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 168df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 169df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT int jio_fprintf(FILE* fp, const char* fmt, ...) 170df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 171df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski va_list args; 172df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 173df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski va_start(args, fmt); 174df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int len = jio_vfprintf(fp, fmt, args); 175df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski va_end(args); 176df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 177df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return len; 178df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 179df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 180df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT int jio_vfprintf(FILE* fp, const char* fmt, va_list args) 181df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 182df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski assert(fp != NULL); 183df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return vfprintf(fp, fmt, args); 184df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 185df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 186df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* posix fsync() */ 187df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Sync(jint fd) 188df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 189df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Sync fd=" << fd; 190df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(fsync(fd)); 191df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 192df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 193df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void* JVM_FindLibraryEntry(void* handle, const char* name) 194df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 195df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_FindLibraryEntry handle=" << handle << " name=" << name; 19667d39adad3261f3932defef6b2d1d30b470d1be0Przemyslaw Szczepaniak return dlsym(handle, name); 197df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 198df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 199df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_CurrentTimeMillis(JNIEnv* env, jclass unused) 200df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 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 209df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Socket(jint domain, jint type, jint protocol) 210df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 211df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Socket domain=" << domain << ", type=" << type << ", protocol=" << protocol; 212df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 213df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(socket(domain, type, protocol)); 214df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 215df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 216df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_InitializeSocketLibrary() { 217df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return 0; 218df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 219df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 220df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskiint jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { 221df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if ((intptr_t)count <= 0) return -1; 222df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return vsnprintf(str, count, fmt, args); 223df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 224df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 225df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskiint jio_snprintf(char *str, size_t count, const char *fmt, ...) { 226df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski va_list args; 227df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int len; 228df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski va_start(args, fmt); 229df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski len = jio_vsnprintf(str, count, fmt, args); 230df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski va_end(args); 231df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return len; 232df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 233df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 234df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_SetSockOpt(jint fd, int level, int optname, 235df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski const char* optval, int optlen) 236df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 237df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_SetSockOpt fd=" << fd << ", level=" << level << ", optname=" << optname 238df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski << ", optval=" << optval << ", optlen=" << optlen; 239df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(setsockopt(fd, level, optname, optval, optlen)); 240df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 241df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 242df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_SocketShutdown(jint fd, jint howto) 243df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 244df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_SocketShutdown fd=" << fd << ", howto=" << howto; 245df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(shutdown(fd, howto)); 246df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 247df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 248df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_GetSockOpt(jint fd, int level, int optname, char* optval, 249df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int* optlen) 250df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 251df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_GetSockOpt fd=" << fd << ", level=" << level << ", optname=" << optname 252df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski << ", optval=" << optval << ", optlen=" << optlen; 253df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 254df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski socklen_t len = *optlen; 255df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int cc = TEMP_FAILURE_RETRY(getsockopt(fd, level, optname, optval, &len)); 256df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *optlen = len; 257df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return cc; 258df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 259df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 260df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_GetSockName(jint fd, struct sockaddr* addr, int* addrlen) 261df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 262df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_GetSockName fd=" << fd << ", addr=" << addr << ", addrlen=" << addrlen; 263df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 264df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski socklen_t len = *addrlen; 265df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski int cc = TEMP_FAILURE_RETRY(getsockname(fd, addr, &len)); 266df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski *addrlen = len; 267df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return cc; 268df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 269df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 270df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_SocketAvailable(jint fd, jint* result) 271df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 272df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_SocketAvailable fd=" << fd << ", result=" << result; 273df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 274df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, result)) < 0) { 275df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "ioctl(" << fd << ", FIONREAD) failed: " << strerror(errno); 276df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return JNI_FALSE; 277df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 278df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 279df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return JNI_TRUE; 280df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 281df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 282df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Send(jint fd, char* buf, jint nBytes, jint flags) 283df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 284df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Send fd=" << fd << ", buf=" << buf << ", nBytes=" << nBytes << ", flags=" 285df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski << flags; 286df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 287df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(send(fd, buf, nBytes, flags)); 288df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 289df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 290df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_SocketClose(jint fd) 291df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 292df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_SocketClose fd=" << fd; 293df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 294df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR 295df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return close(fd); 296df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 297df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 298df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Listen(jint fd, jint count) 299df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 300df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Listen fd=" << fd << ", count=" << count; 301df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 302df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(listen(fd, count)); 303df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 304df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 305df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_Connect(jint fd, struct sockaddr* addr, jint addrlen) 306df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 307df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_Connect fd=" << fd << ", addr=" << addr << ", addrlen=" << addrlen; 308df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 309df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(connect(fd, addr, addrlen)); 310df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 311df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 312df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT int JVM_GetHostName(char* name, int namelen) 313df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 314df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_GetHostName name=" << name << ", namelen=" << namelen; 315df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 316df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return TEMP_FAILURE_RETRY(gethostname(name, namelen)); 317df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 318df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 319df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jstring JVM_InternString(JNIEnv* env, jstring jstr) 320df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{ 321df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(DEBUG) << "JVM_InternString env=" << env << ", jstr=" << jstr; 322df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 323df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::String* s = soa.Decode<art::mirror::String*>(jstr); 324df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::String* result = s->Intern(); 325df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return soa.AddLocalReference<jstring>(result); 326df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 327df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 328df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_FreeMemory(void) { 329df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return art::Runtime::Current()->GetHeap()->GetFreeMemory(); 330df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 331df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 332df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_TotalMemory(void) { 333df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return art::Runtime::Current()->GetHeap()->GetTotalMemory(); 334df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 335df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 336df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_MaxMemory(void) { 337df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return art::Runtime::Current()->GetHeap()->GetMaxMemory(); 338df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 339df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 340df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_GC(void) { 341df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (art::Runtime::Current()->IsExplicitGcDisabled()) { 342df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(INFO) << "Explicit GC skipped."; 343df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 344df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 345df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Runtime::Current()->GetHeap()->CollectGarbage(false); 346df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 347df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 348df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Exit(jint status) { 349df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(INFO) << "System.exit called, status: " << status; 350df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Runtime::Current()->CallExitHook(status); 351df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski exit(status); 352df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 353df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 354df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename, jobject javaLoader, 355df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski jstring javaLdLibraryPath) { 356df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski ScopedUtfChars filename(env, javaFilename); 357df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (filename.c_str() == NULL) { 358df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return NULL; 359df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 360df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 361df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (javaLdLibraryPath != NULL) { 362df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski ScopedUtfChars ldLibraryPath(env, javaLdLibraryPath); 363df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (ldLibraryPath.c_str() == NULL) { 364df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return NULL; 365df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 366df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski void* sym = dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH"); 367df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (sym != NULL) { 368df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski typedef void (*Fn)(const char*); 369df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski Fn android_update_LD_LIBRARY_PATH = reinterpret_cast<Fn>(sym); 370df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski (*android_update_LD_LIBRARY_PATH)(ldLibraryPath.c_str()); 371df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } else { 372df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(ERROR) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!"; 373df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 374df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 375df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 376df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski std::string detail; 377df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski { 378df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedObjectAccess soa(env); 379df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::StackHandleScope<1> hs(soa.Self()); 380df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Handle<art::mirror::ClassLoader> classLoader( 381df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski hs.NewHandle(soa.Decode<art::mirror::ClassLoader*>(javaLoader))); 382df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::JavaVMExt* vm = art::Runtime::Current()->GetJavaVM(); 383df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski bool success = vm->LoadNativeLibrary(filename.c_str(), classLoader, &detail); 384df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (success) { 385df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return nullptr; 386df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 387df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 388df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 389df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Don't let a pending exception from JNI_OnLoad cause a CheckJNI issue with NewStringUTF. 390df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski env->ExceptionClear(); 391df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return env->NewStringUTF(detail.c_str()); 392df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 393df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 394df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_StartThread(JNIEnv* env, jobject jthread, jlong stack_size, jboolean daemon) { 395df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread::CreateNativeThread(env, jthread, stack_size, daemon == JNI_TRUE); 396df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 397df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 398df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio) { 399df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedObjectAccess soa(env); 400df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_); 401df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread* thread = art::Thread::FromManagedThread(soa, jthread); 402df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (thread != NULL) { 403df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski thread->SetNativePriority(prio); 404df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 405df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 406df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 407df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Yield(JNIEnv* env, jclass threadClass) { 408df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski sched_yield(); 409df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 410df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 411df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Sleep(JNIEnv* env, jclass threadClass, jobject java_lock, jlong millis) { 412df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 413df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Object* lock = soa.Decode<art::mirror::Object*>(java_lock); 414df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Monitor::Wait(art::Thread::Current(), lock, millis, 0, true, art::kSleeping); 415df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 416df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 417df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jobject JVM_CurrentThread(JNIEnv* env, jclass unused) { 418df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 419df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return soa.AddLocalReference<jobject>(soa.Self()->GetPeer()); 420df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 421df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 422df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Interrupt(JNIEnv* env, jobject jthread) { 423df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 424df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_); 425df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread* thread = art::Thread::FromManagedThread(soa, jthread); 426df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (thread != nullptr) { 427df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski thread->Interrupt(soa.Self()); 428df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 429df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 430df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 431df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clearInterrupted) { 432df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (clearInterrupted) { 433df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return static_cast<art::JNIEnvExt*>(env)->self->Interrupted() ? JNI_TRUE : JNI_FALSE; 434df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } else { 435df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 436df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_); 437df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread* thread = art::Thread::FromManagedThread(soa, jthread); 438df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return (thread != nullptr) ? thread->IsInterrupted() : JNI_FALSE; 439df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 440df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 441df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 442df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jboolean JVM_HoldsLock(JNIEnv* env, jclass unused, jobject jobj) { 443df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedObjectAccess soa(env); 444df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Object* object = soa.Decode<art::mirror::Object*>(jobj); 445df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (object == NULL) { 446df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThrowNullPointerException(NULL, "object == null"); 447df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return JNI_FALSE; 448df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 449df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return soa.Self()->HoldsLock(object); 450df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 451df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 452df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring java_name) { 453df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski ScopedUtfChars name(env, java_name); 454df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread* self; 455df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski { 456df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedObjectAccess soa(env); 457df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (soa.Decode<art::mirror::Object*>(jthread) == soa.Self()->GetPeer()) { 458df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski soa.Self()->SetThreadName(name.c_str()); 459df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 460df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 461df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski self = soa.Self(); 462df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 463df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Suspend thread to avoid it from killing itself while we set its name. We don't just hold the 464df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // thread list lock to avoid this, as setting the thread name causes mutator to lock/unlock 465df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // in the DDMS send code. 466df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThreadList* thread_list = art::Runtime::Current()->GetThreadList(); 467df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski bool timed_out; 468df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Take suspend thread lock to avoid races with threads trying to suspend this one. 469df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread* thread; 470df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski { 471df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::MutexLock mu(self, *art::Locks::thread_list_suspend_thread_lock_); 472df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski thread = thread_list->SuspendThreadByPeer(jthread, true, false, &timed_out); 473df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 474df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (thread != NULL) { 475df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski { 476df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedObjectAccess soa(env); 477df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski thread->SetThreadName(name.c_str()); 478df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 479df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski thread_list->Resume(thread, false); 480df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } else if (timed_out) { 481df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread " 482df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski "failed to suspend within a generous timeout."; 483df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 484df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 485df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 486df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_IHashCode(JNIEnv* env, jobject javaObject) { 487df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY(javaObject == nullptr)) { 488df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return 0; 489df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 490df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 491df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Object* o = soa.Decode<art::mirror::Object*>(javaObject); 492df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return static_cast<jint>(o->IdentityHashCode()); 493df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 494df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 495df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jlong JVM_NanoTime(JNIEnv* env, jclass unused) { 496df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#if defined(HAVE_POSIX_CLOCKS) 497df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski timespec now; 498df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski clock_gettime(CLOCK_MONOTONIC, &now); 499df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return now.tv_sec * 1000000000LL + now.tv_nsec; 500df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#else 501df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski timeval now; 502df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski gettimeofday(&now, NULL); 503df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return static_cast<jlong>(now.tv_sec) * 1000000000LL + now.tv_usec * 1000LL; 504df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski#endif 505df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 506df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskistatic void ThrowArrayStoreException_NotAnArray(const char* identifier, art::mirror::Object* array) 507df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski SHARED_LOCKS_REQUIRED(art::Locks::mutator_lock_) { 508df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski std::string actualType(art::PrettyTypeOf(array)); 509df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Thread* self = art::Thread::Current(); 510df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 511df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski self->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayStoreException;", 512df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski "%s of type %s is not an array", identifier, actualType.c_str()); 513df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 514df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 515df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_ArrayCopy(JNIEnv* env, jclass unused, jobject javaSrc, 516df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski jint srcPos, jobject javaDst, jint dstPos, jint length) { 517df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // The API is defined in terms of length, but length is somewhat overloaded so we use count. 518df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski const jint count = length; 519df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ScopedFastNativeObjectAccess soa(env); 520df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 521df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Null pointer checks. 522df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY(javaSrc == nullptr)) { 523df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThrowNullPointerException(nullptr, "src == null"); 524df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 525df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 526df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY(javaDst == nullptr)) { 527df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThrowNullPointerException(nullptr, "dst == null"); 528df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 529df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 530df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 531df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Make sure source and destination are both arrays. 532df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Object* srcObject = soa.Decode<art::mirror::Object*>(javaSrc); 533df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY(!srcObject->IsArrayInstance())) { 534df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski ThrowArrayStoreException_NotAnArray("source", srcObject); 535df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 536df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 537df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Object* dstObject = soa.Decode<art::mirror::Object*>(javaDst); 538df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY(!dstObject->IsArrayInstance())) { 539df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski ThrowArrayStoreException_NotAnArray("destination", dstObject); 540df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 541df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 542df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Array* srcArray = srcObject->AsArray(); 543df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Array* dstArray = dstObject->AsArray(); 544df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 545df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Bounds checking. 546df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY(srcPos < 0) || UNLIKELY(dstPos < 0) || UNLIKELY(count < 0) || 547df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski UNLIKELY(srcPos > srcArray->GetLength() - count) || 548df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski UNLIKELY(dstPos > dstArray->GetLength() - count)) { 549df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 550df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;", 551df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d", 552df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski srcArray->GetLength(), srcPos, dstArray->GetLength(), dstPos, 553df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski count); 554df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 555df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 556df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 557df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Class* dstComponentType = dstArray->GetClass()->GetComponentType(); 558df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::Class* srcComponentType = srcArray->GetClass()->GetComponentType(); 559df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::Primitive::Type dstComponentPrimitiveType = dstComponentType->GetPrimitiveType(); 560df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 561df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (LIKELY(srcComponentType == dstComponentType)) { 562df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Trivial assignability. 563df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski switch (dstComponentPrimitiveType) { 564df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimVoid: 565df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(FATAL) << "Unreachable, cannot have arrays of type void"; 566df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 567df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimBoolean: 568df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimByte: 569df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 1U); 570df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstArray->AsByteSizedArray()->Memmove(dstPos, srcArray->AsByteSizedArray(), srcPos, count); 571df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 572df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimChar: 573df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimShort: 574df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 2U); 575df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstArray->AsShortSizedArray()->Memmove(dstPos, srcArray->AsShortSizedArray(), srcPos, count); 576df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 577df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimInt: 578df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimFloat: 579df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 4U); 580df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstArray->AsIntArray()->Memmove(dstPos, srcArray->AsIntArray(), srcPos, count); 581df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 582df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimLong: 583df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimDouble: 584df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski DCHECK_EQ(art::Primitive::ComponentSize(dstComponentPrimitiveType), 8U); 585df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstArray->AsLongArray()->Memmove(dstPos, srcArray->AsLongArray(), srcPos, count); 586df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 587df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski case art::Primitive::kPrimNot: { 588df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::ObjectArray<art::mirror::Object>* dstObjArray = dstArray->AsObjectArray<art::mirror::Object>(); 589df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::ObjectArray<art::mirror::Object>* srcObjArray = srcArray->AsObjectArray<art::mirror::Object>(); 590df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstObjArray->AssignableMemmove(dstPos, srcObjArray, srcPos, count); 591df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 592df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 593df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski default: 594df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski LOG(FATAL) << "Unknown array type: " << art::PrettyTypeOf(srcArray); 595df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 596df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 597df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 598df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // If one of the arrays holds a primitive type the other array must hold the exact same type. 599df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (UNLIKELY((dstComponentPrimitiveType != art::Primitive::kPrimNot) || 600df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski srcComponentType->IsPrimitive())) { 601df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski std::string srcType(art::PrettyTypeOf(srcArray)); 602df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski std::string dstType(art::PrettyTypeOf(dstArray)); 603df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 604df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayStoreException;", 605df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski "Incompatible types: src=%s, dst=%s", 606df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski srcType.c_str(), dstType.c_str()); 607df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 608df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 609df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // Arrays hold distinct types and so therefore can't alias - use memcpy instead of memmove. 610df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::ObjectArray<art::mirror::Object>* dstObjArray = dstArray->AsObjectArray<art::mirror::Object>(); 611df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski art::mirror::ObjectArray<art::mirror::Object>* srcObjArray = srcArray->AsObjectArray<art::mirror::Object>(); 612df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski // If we're assigning into say Object[] then we don't need per element checks. 613df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski if (dstComponentType->IsAssignableFrom(srcComponentType)) { 614df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstObjArray->AssignableMemcpy(dstPos, srcObjArray, srcPos, count); 615df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski return; 616df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski } 617df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski dstObjArray->AssignableCheckingMemcpy(dstPos, srcObjArray, srcPos, count, true); 618df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 619df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 620df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jint JVM_FindSignal(const char* name) { 62136379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath LOG(FATAL) << "JVM_FindSignal is not implemented"; 62236379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath return 0; 623df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 624df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 62536379fdf339a85cd89d12506d97ecdf582041b16Narayan KamathJNIEXPORT void* JVM_RegisterSignal(jint signum, void* handler) { 62636379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath LOG(FATAL) << "JVM_RegisterSignal is not implemented"; 62736379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath return nullptr; 628df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 629df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 63036379fdf339a85cd89d12506d97ecdf582041b16Narayan KamathJNIEXPORT jboolean JVM_RaiseSignal(jint signum) { 63136379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath LOG(FATAL) << "JVM_RaiseSignal is not implemented"; 63236379fdf339a85cd89d12506d97ecdf582041b16Narayan Kamath return JNI_FALSE; 633df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 634df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski 635df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Halt(jint code) { 636df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski exit(code); 637df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski} 638b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak 639b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw SzczepaniakJNIEXPORT jboolean JVM_IsNaN(jdouble d) { 640b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak return isnan(d); 641b02d9b7329909cbf741b16faf81616a992a1bd2bPrzemyslaw Szczepaniak} 642