1 /* 2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "jni.h" 27 #include "jni_util.h" 28 #include "jvm.h" 29 #include "jlong.h" 30 #include "java_nio_MappedByteBuffer.h" 31 #include <assert.h> 32 #include <sys/mman.h> 33 #include <stddef.h> 34 #include <stdlib.h> 35 36 #ifdef _AIX 37 #include <unistd.h> 38 #endif 39 40 41 #ifdef _AIX 42 static long calculate_number_of_pages_in_range(void* address, size_t len, size_t pagesize) { 43 uintptr_t address_unaligned = (uintptr_t) address; 44 uintptr_t address_aligned = address_unaligned & (~(pagesize - 1)); 45 size_t len2 = len + (address_unaligned - address_aligned); 46 long numPages = (len2 + pagesize - 1) / pagesize; 47 return len2 + pagesize - 1 / pagesize; 48 } 49 #endif 50 51 /* Output type for mincore(2) */ 52 #ifdef __linux__ 53 typedef unsigned char mincore_vec_t; 54 #else 55 typedef char mincore_vec_t; 56 #endif 57 58 JNIEXPORT jboolean JNICALL 59 Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address, 60 jlong len, jint numPages) 61 { 62 jboolean loaded = JNI_TRUE; 63 int result = 0; 64 int i = 0; 65 void *a = (void *) jlong_to_ptr(address); 66 mincore_vec_t* vec = NULL; 67 68 #ifdef _AIX 69 /* See JDK-8186665 */ 70 size_t pagesize = (size_t)sysconf(_SC_PAGESIZE); 71 if ((long)pagesize == -1) { 72 return JNI_FALSE; 73 } 74 numPages = (jint) calculate_number_of_pages_in_range(a, len, pagesize); 75 #endif 76 77 vec = (mincore_vec_t*) malloc(numPages + 1); 78 79 if (vec == NULL) { 80 JNU_ThrowOutOfMemoryError(env, NULL); 81 return JNI_FALSE; 82 } 83 84 vec[numPages] = '\x7f'; /* Sentinel */ 85 result = mincore(a, (size_t)len, vec); 86 assert(vec[numPages] == '\x7f'); 87 88 if (result == -1) { 89 JNU_ThrowIOExceptionWithLastError(env, "mincore failed"); 90 free(vec); 91 return JNI_FALSE; 92 } 93 94 for (i=0; i<numPages; i++) { 95 if (vec[i] == 0) { 96 loaded = JNI_FALSE; 97 break; 98 } 99 } 100 free(vec); 101 return loaded; 102 } 103 104 105 JNIEXPORT void JNICALL 106 Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address, 107 jlong len) 108 { 109 char *a = (char *)jlong_to_ptr(address); 110 int result = madvise((caddr_t)a, (size_t)len, MADV_WILLNEED); 111 if (result == -1) { 112 JNU_ThrowIOExceptionWithLastError(env, "madvise failed"); 113 } 114 } 115 116 117 JNIEXPORT void JNICALL 118 Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo, 119 jlong address, jlong len) 120 { 121 void* a = (void *)jlong_to_ptr(address); 122 int result = msync(a, (size_t)len, MS_SYNC); 123 if (result == -1) { 124 JNU_ThrowIOExceptionWithLastError(env, "msync failed"); 125 } 126 }