diff -r c069e5e285cb -r d6c3ecec1d34 hotspot/test/runtime/jni/CalleeSavedRegisters/exeFPRegs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/jni/CalleeSavedRegisters/exeFPRegs.c Fri Oct 28 12:28:46 2016 -0700 @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include +#include + +#ifdef WINDOWS +#include +#else +#include +#endif // WINDOWS + +#ifdef WINDOWS + HMODULE handle; +#else + void* handle; +#endif // WINDOWS + +jint(JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL; + +// method to perform dlclose on an open dynamic library handle +void closeHandle() { +#ifdef WINDOWS + if (!FreeLibrary(handle)) { + fprintf(stderr, "Error occurred while closing handle: 0x%02X\n", GetLastError()); + } +#else + if (dlclose(handle) != 0) { + fprintf(stderr, "Error occurred while closing handle: %s\n", dlerror()); + } +#endif // WINDOWS +} + +void fail(int code) { + if (handle) { + closeHandle(); + } + exit(code); +} + + +// method to load the dynamic library libjvm +int loadJVM(const char* path) { +#ifdef WINDOWS + UINT errorMode = GetErrorMode(); + SetErrorMode(errorMode | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + handle = LoadLibraryA(path); +#else + handle = dlopen(path, RTLD_LAZY); +#endif // WINDOWS + + if (handle) { + // find the address of function +#ifdef WINDOWS + *(void **) (&jni_create_java_vm) = GetProcAddress(handle, "JNI_CreateJavaVM"); +#else + *(void **) (&jni_create_java_vm) = dlsym(handle, "JNI_CreateJavaVM"); +#endif // WINDOWS + + if (jni_create_java_vm == NULL) { + fprintf(stderr, "ERROR: No JNI_CreateJavaVM found: '%s'\n", path); + return -1; + } + } else { +#ifdef WINDOWS + fprintf(stderr, "ERROR: Can't load JVM library: 0x%02X\n", GetLastError()); +#else + fprintf(stderr, "ERROR: Can't load JVM library: %s\n", dlerror()); +#endif // WINDOWS + return -1; + } + return 0; +} + +long long unsigned int d2l(double d) { + union { + double d; + long long unsigned int llu; + } dl; + + dl.d = d; + return dl.llu; +} + +#define print_reg(r) printf("%s = %f (0x%llX)\n", #r, r, d2l(r)); + +int main(int argc, const char** argv) { + JavaVM* jvm; + JNIEnv* env; + JavaVMInitArgs vm_args; + + // values to trick constant folding + long long unsigned int vd[32]; + int i; + int bad_cnt = 0; + + // values occupy fp registers + // note: suitable code shape is produced only on Windows, + // and even then registers are corrupted not on every machine + register double d00; + register double d01; + register double d02; + register double d03; + register double d04; + register double d05; + register double d06; + register double d07; + register double d08; + register double d09; + register double d10; + register double d11; + register double d12; + register double d13; + register double d14; + register double d15; + + if (argc != 2) { + printf("Usage: FPRegs "); + fail(2); + } + printf("jvm_path = %s\n", argv[1]); + + if (loadJVM(argv[1]) < 0) { + fail(3); + } + + vm_args.version = JNI_VERSION_1_8; + vm_args.ignoreUnrecognized = JNI_FALSE; + vm_args.options = NULL; + vm_args.nOptions = 0; + + for(i = 0; i < 16; i++) { + vd[i] = d2l(100 + i); + } + + d00 = 100.0; + d01 = 101.0; + d02 = 102.0; + d03 = 103.0; + d04 = 104.0; + d05 = 105.0; + d06 = 106.0; + d07 = 107.0; + d08 = 108.0; + d09 = 109.0; + d10 = 110.0; + d11 = 111.0; + d12 = 112.0; + d13 = 113.0; + d14 = 114.0; + d15 = 115.0; + + printf("BEFORE:\n"); + print_reg(d00); + print_reg(d01); + print_reg(d02); + print_reg(d03); + print_reg(d04); + print_reg(d05); + print_reg(d06); + print_reg(d07); + print_reg(d08); + print_reg(d09); + print_reg(d10); + print_reg(d11); + print_reg(d12); + print_reg(d13); + print_reg(d14); + print_reg(d15); + + if (jni_create_java_vm(&jvm, &env, &vm_args) < 0 ) { + fprintf(stderr, "ERROR: Can't create JavaVM\n"); + fail(4); + } + + if (d2l(d00) != vd[0]) bad_cnt++; + if (d2l(d01) != vd[1]) bad_cnt++; + if (d2l(d02) != vd[2]) bad_cnt++; + if (d2l(d03) != vd[3]) bad_cnt++; + if (d2l(d04) != vd[4]) bad_cnt++; + if (d2l(d05) != vd[5]) bad_cnt++; + if (d2l(d06) != vd[6]) bad_cnt++; + if (d2l(d07) != vd[7]) bad_cnt++; + if (d2l(d08) != vd[8]) bad_cnt++; + if (d2l(d09) != vd[9]) bad_cnt++; + if (d2l(d10) != vd[10]) bad_cnt++; + if (d2l(d11) != vd[11]) bad_cnt++; + if (d2l(d12) != vd[12]) bad_cnt++; + if (d2l(d13) != vd[13]) bad_cnt++; + if (d2l(d14) != vd[14]) bad_cnt++; + if (d2l(d15) != vd[15]) bad_cnt++; + + printf("AFTER:\n"); + print_reg(d00); + print_reg(d01); + print_reg(d02); + print_reg(d03); + print_reg(d04); + print_reg(d05); + print_reg(d06); + print_reg(d07); + print_reg(d08); + print_reg(d09); + print_reg(d10); + print_reg(d11); + print_reg(d12); + print_reg(d13); + print_reg(d14); + print_reg(d15); + + printf("%d registers corrupted\n", bad_cnt); + if (bad_cnt > 0) { + printf("TEST FAILED"); + fail(1); + } + + printf("TEST PASSED"); + closeHandle(); + return 0; +} +