jdk-24/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress001.cpp

254 lines
8.1 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2007, 2024, 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>
/* Changed from strings.h to string.h for Windows. */
#include <string.h>
#include <stdlib.h>
#include "jnihelper.hpp"
extern "C" {
#define DIGESTLENGTH 16
typedef struct {
const char **str;
char **checkstr;
} CHAR_ARRAY;
typedef struct {
const jchar **str;
char **checkstr;
int *size;
} JCHAR_ARRAY;
JNIEXPORT jstring JNICALL
Java_nsk_stress_jni_JNIter001_jnistress (JNIEnv *env, jobject jobj, jstring jstr,
jint nstr, jint printperiod) {
int i, j;
size_t k;
static CHAR_ARRAY *element;
unsigned char digest[DIGESTLENGTH];
static int allocs = 0;
static size_t strsize = 0;
static unsigned int compared = 1;
const char *clsName = "nsk/stress/jni/JNIter001";
const char *name = "setpass";
const char *sig = "(Z)V";
const char *halt = "halt";
const char *haltSig = "()V";
jstring tmpstr;
jclass clazz;
jmethodID methodID;
CHECK(env->MonitorEnter(jobj));
if (!allocs) {
element = (CHAR_ARRAY *)c_malloc(env, sizeof(CHAR_ARRAY));
element->str = (const char **)c_malloc(env, nstr * sizeof(const char*));
element->checkstr = (char **)c_malloc(env, nstr * sizeof(char*));
for (j = 0; j < nstr; j++) {
element->checkstr[j] = (char *)c_malloc(env, DIGESTLENGTH * sizeof(char));
}
}
for (j = 0; j < DIGESTLENGTH; j++) {
digest[j] = 0;
}
element->str[allocs] = env->GetStringUTFChars(jstr, 0); CE
if (strlen(element->str[allocs]) != (size_t) env->GetStringUTFLength(jstr)) {
printf("Length is wrong in string No. %d\n", allocs);
} else {
strsize += strlen(element->str[allocs]) + 1;
}
for (k = 0; k < strlen(element->str[allocs]); k++) {
digest[k % DIGESTLENGTH] += element->str[allocs][k];
}
memcpy(element->checkstr[allocs], digest, DIGESTLENGTH);
allocs++;
if (allocs % printperiod == 0) {
printf("Check string for thread %s is ", element->str[allocs - 1]);
for (j = 0; j < DIGESTLENGTH; j++) {
printf("%02x", digest[j]);
}
printf("\n");
}
if (allocs == nstr) {
printf("JNI UTF8 strings memory = %zd\n", strsize);
tmpstr = env->NewStringUTF(element->str[allocs - 1]); CE
for (j = 0; j < nstr; j++) {
for (i = 0; i < DIGESTLENGTH; i++) {
digest[i] = 0;
}
for (k = 0; k < strlen(element->str[j]); k++) {
digest[k % DIGESTLENGTH] += element->str[j][k];
}
if (memcmp(digest, element->checkstr[j], DIGESTLENGTH) == 0) {
env->ReleaseStringUTFChars(jstr, element->str[j]); CE
element->str[j] = nullptr;
element->checkstr[j] = nullptr;
} else {
compared = 0;
printf("The element No. %d has been corrupted %s vs %s\n", j,
element->str[j], element->checkstr[j]);
printf("Digest string is %s [", element->str[j]);
for (i = 0; i < DIGESTLENGTH; i++) {
printf("ch[%d] = %02x", i, digest[i]);
}
printf("Digest end\n");
}
}
allocs = 0;
strsize = 0;
for (j = 0; j < nstr; j++) {
free(element->checkstr[j]);
}
free(element->checkstr);
free((void *)(element->str));
free(element);
clazz = env->FindClass(clsName); CE
if (!compared) {
methodID = env->GetStaticMethodID(clazz, name, sig); CE
env->CallStaticVoidMethod(clazz, methodID, JNI_FALSE); CE
}
//methodID = env->GetStaticMethodID(clazz, halt, haltSig); CE
//env->CallStaticVoidMethod(clazz, methodID); CE
return tmpstr;
}
CHECK(env->MonitorExit(jobj));
return (env->NewStringUTF(element->str[allocs - 1]));
}
JNIEXPORT jstring JNICALL
Java_nsk_stress_jni_JNIter001_jnistress1(JNIEnv *env, jobject jobj, jstring jstr,
jint nstr, jint printperiod) {
int i, j;
static JCHAR_ARRAY *javachars;
unsigned char digest[DIGESTLENGTH];
static int index = 0;
static long len = 0;
static unsigned int equal = 1;
char *elem;
int elem_len = -1;
const char *clsName = "nsk/stress/jni/JNIter001";
const char *name = "setpass";
const char *sig = "(Z)V";
const char *halt = "halt";
const char *haltSig = "()V";
jstring tmpstr;
jclass clazz;
jmethodID methodID;
CHECK(env->MonitorEnter(jobj));
if (!index) {
javachars = (JCHAR_ARRAY *)c_malloc(env, sizeof(JCHAR_ARRAY));
javachars->str = (const jchar **)c_malloc(env, nstr * sizeof(const jchar*));
javachars->checkstr = (char **)c_malloc(env, nstr * sizeof(char*));
javachars->size = (int *)c_malloc(env, nstr * sizeof(int));
for (j = 0; j < nstr; j++) {
javachars->checkstr[j] = (char *)c_malloc(env, DIGESTLENGTH * sizeof(char));
}
}
for (j = 0; j < DIGESTLENGTH; j++) {
digest[j] = 0;
}
javachars->str[index] = env->GetStringChars(jstr, 0); CE
javachars->size[index] = env->GetStringUTFLength(jstr); CE
elem_len = javachars->size[index];
len += elem_len;
elem = (char*) c_malloc(env, elem_len * sizeof(char));
for (j = 0; j < elem_len; j++) {
elem[j] = (char) javachars->str[index][j];
}
//memcpy(digest, elem, javachars->size[index]);
for (j = 0; j < elem_len; j++) {
digest[j % DIGESTLENGTH] += elem[j];
}
memcpy(javachars->checkstr[index++], digest, DIGESTLENGTH);
if (index % printperiod == 0) {
printf("Check string sum for thread %.*s is ", elem_len, elem);
for (j = 0; j < DIGESTLENGTH; j++) {
printf("%02x", digest[j]);
}
printf("\n");
}
free(elem);
if (index == nstr) {
printf("JNI Unicode strings memory = %ld\n", len);
tmpstr = env->NewString(javachars->str[index - 1], elem_len); CE
for (j = 0; j < nstr; j++) {
elem = (char*) c_malloc(env, javachars->size[j] * sizeof(char));
for (i = 0; i < javachars->size[j]; i++) {
elem[i] = (char) javachars->str[j][i];
}
//memcpy(digest, elem, javachars->size[j]);
for (i = 0; i < DIGESTLENGTH; i++) {
digest[i] = 0;
}
for (i = 0; i < javachars->size[j]; i++) {
digest[i % DIGESTLENGTH] += elem[i];
}
free(elem);
if (memcmp(digest, javachars->checkstr[j], javachars->size[j]) == 0) {
env->ReleaseStringChars(jstr, javachars->str[j]); CE
javachars->str[j] = nullptr;
javachars->checkstr[j] = nullptr;
javachars->size[j] = 0;
} else {
equal = 0;
printf("The Unicode element No. %d has been corrupted\n", j);
for (i = 0; i < DIGESTLENGTH; i++) {
printf("digest[%d] = %02x checkstr[%d] = %02x\n", i, digest[i], i, javachars->checkstr[j][i]);
}
}
}
index = 0;
len = 0;
for (j = 0; j < nstr; j++) {
free(javachars->checkstr[j]);
}
free(javachars->checkstr);
free((void *)(javachars->str));
free(javachars->size);
free(javachars);
clazz = env->FindClass(clsName); CE
if (!equal) {
methodID = env->GetStaticMethodID(clazz, name, sig); CE
env->CallStaticVoidMethod(clazz, methodID, JNI_FALSE); CE
}
//methodID = env->GetStaticMethodID(clazz, halt, haltSig); CE
//env->CallStaticVoidMethod(clazz, methodID); CE
return tmpstr;
}
CHECK(env->MonitorExit(jobj));
return env->NewString(javachars->str[index - 1], elem_len);
}
}