OpenjdkJvm.cc revision 67d39adad3261f3932defef6b2d1d30b470d1be0
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) {
621df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  static const char* names[] = {
622df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        "", "HUP", "INT", "QUIT",
623df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        "ILL", "TRAP", "ABRT", "BUS",
624df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        "FPE", "KILL", "USR1", "SEGV",
625df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        "USR2", "PIPE", "ALRM", "TERM",
626df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        NULL
627df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    };
628df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
629df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    int i = 0;
630df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    while (names[++i] != NULL) {
631df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        if (strcmp(name, names[i]) == 0) {
632df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski            return i;
633df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        }
634df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
635df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(WARNING) << "Signal '" << name << "' not found";
636df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    assert(false);
637df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return 0;
638df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
639df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
640df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski/* signal handler */
641df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebskistatic void internalSignalHandler(int sig)
642df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{
643df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    /*
644df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * This is expected to invoke sun.misc.Signal.dispatch().  We really
645df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * don't want to do that directly from a signal handler, so if we
646df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     * decide we need this we should hook it into the safe-point mechanism.
647df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski     */
648df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
649df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
650df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void* JVM_RegisterSignal(jint signum, void* handler)
651df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{
652df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    LOG(INFO) << "SIGNAL: signum=" << signum << ", handler=" << handler;
653df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
654df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    struct sigaction act, oldact;
655df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
656df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    /* OpenJDK code makes these assumptions */
657df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    assert(SIG_DFL == (void*)0);
658df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    assert(SIG_IGN == (void*)1);
659df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
660df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (handler == (void*) 2) {
661df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        /* magic value indicating we should use our internal handler */
662df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        handler = (void*) internalSignalHandler;
663df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
664df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
665df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    act.sa_handler = (void (*)(int))handler;
666df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    sigemptyset(&act.sa_mask);
667df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    act.sa_flags = SA_RESTART;
668df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    sigaction(signum, &act, &oldact);
669df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
670df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    if (oldact.sa_handler == internalSignalHandler) {
671df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        return (void*) 2;
672df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    } else {
673df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski        return (void*) oldact.sa_handler;
674df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    }
675df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
676df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
677df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT jboolean JVM_RaiseSignal(jint signum)
678df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski{
679df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    raise(signum);
680df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski    return JNI_TRUE;
681df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
682df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski
683df0b17a474306198b7b0320311496e42d707a00ePiotr JastrzebskiJNIEXPORT void JVM_Halt(jint code) {
684df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski  exit(code);
685df0b17a474306198b7b0320311496e42d707a00ePiotr Jastrzebski}
686