238c17bdb5
Adjust thread stack size for static TLS on Linux when AdjustStackSizeForTLS is enabled. Co-authored-by: Florian Weimer <fweimer@redhat.com> Co-authored-by: Jiangli Zhou <jianglizhou@google.com> Reviewed-by: dholmes, fweimer, stuefe, rriggs, martin
106 lines
3.4 KiB
C
106 lines
3.4 KiB
C
/*
|
|
* Copyright (c) 2019, Google Inc. All rights reserved.
|
|
* Copyright (c) 2019, 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 <jni.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// Declare the thread local variable(s) in the main executable. This can be
|
|
// used to demonstrate the issues associated with the on-stack static TLS blocks
|
|
// that may cause insufficient stack space. The dynamic TLS blocks for shared
|
|
// objects (such as a JNI library) loaded via dlopen are not allocated on stack.
|
|
__thread int tls[128 * 1024];
|
|
|
|
JNIEnv* create_vm(JavaVM **jvm, char* argTLS) {
|
|
JNIEnv* env;
|
|
JavaVMInitArgs args;
|
|
JavaVMOption options[3];
|
|
args.version = JNI_VERSION_1_8;
|
|
args.nOptions = 3;
|
|
char classpath[4096];
|
|
snprintf(classpath, sizeof classpath,
|
|
"-Djava.class.path=%s", getenv("CLASSPATH"));
|
|
options[0].optionString = classpath;
|
|
options[1].optionString = "-Xlog:os+thread=info";
|
|
options[2].optionString = argTLS;
|
|
args.options = &options[0];
|
|
args.ignoreUnrecognized = 0;
|
|
int rv;
|
|
rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
|
|
if (rv < 0) return NULL;
|
|
return env;
|
|
}
|
|
|
|
int run(jboolean addTLS) {
|
|
JavaVM *jvm;
|
|
jclass testClass;
|
|
jmethodID runMethod;
|
|
char* argTLS;
|
|
int res = -1;
|
|
|
|
if (addTLS) {
|
|
argTLS = "-XX:+AdjustStackSizeForTLS";
|
|
} else {
|
|
argTLS = "-XX:-AdjustStackSizeForTLS"; // default
|
|
}
|
|
printf("Running test with %s ...\n", argTLS);
|
|
JNIEnv *env = create_vm(&jvm, argTLS);
|
|
|
|
// Run T.run() and check result:
|
|
// - Expect T.run() to return 'true' when stack size is adjusted for TLS,
|
|
// return 0 if so
|
|
// - Expect T.run() to return 'false' if stack size is not adjusted for
|
|
// TLS, return 0 if so
|
|
// Return -1 (fail) for other cases
|
|
testClass = (*env)->FindClass(env, "T");
|
|
runMethod = (*env)->GetStaticMethodID(env, testClass, "run", "()Z");
|
|
if ((*env)->CallStaticBooleanMethod(env, testClass, runMethod, NULL)) {
|
|
if (addTLS) {
|
|
// expect T.run() to return 'true'
|
|
res = 0;
|
|
}
|
|
} else {
|
|
if (!addTLS) {
|
|
// expect T.run() to return 'false'
|
|
res = 0;
|
|
}
|
|
}
|
|
|
|
if (res == 0) {
|
|
printf("Test passed with %s\n", argTLS);
|
|
} else {
|
|
printf("Test failed with %s\n", argTLS);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc == 2 && strcmp(argv[1], "-add_tls") == 0) {
|
|
return run(JNI_TRUE);
|
|
} else {
|
|
return run(JNI_FALSE);
|
|
}
|
|
}
|