You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2006/12/15 09:33:23 UTC
svn commit: r487483 [2/4] - in /harmony/enhanced/drlvm/trunk:
build/make/targets/ vm/interpreter/src/ vm/jitrino/src/jet/
vm/port/src/lil/em64t/pim/ vm/port/src/lil/ia32/pim/
vm/port/src/lil/ipf/pim/ vm/tests/smoke/shutdown/ vm/vmcore/include/
vm/vmcor...
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_properties.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_properties.cpp?view=diff&rev=487483&r1=487482&r2=487483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_properties.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_properties.cpp Fri Dec 15 00:33:21 2006
@@ -1,395 +1,394 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <apr_file_io.h>
-#include <apr_file_info.h>
-#include <apr_env.h>
-#include <apr_strings.h>
-#include "port_dso.h"
-#include "port_filepath.h"
-#include "port_sysinfo.h"
-
-#define LOG_DOMAIN "init.properties"
-#include "cxxlog.h"
-#include "properties.h"
-#include "vm_properties.h"
-#include "init.h"
-
-inline char* unquote(char *str)
-{
- const char *tokens = " \t\n\r\'\"";
- size_t i = strspn(str, tokens);
- str += i;
- char *p = str + strlen(str) - 1;
- while(strchr(tokens, *p) && p >= str)
- *(p--) = '\0';
- return str;
-}
-
-#define PROP_ENV_NAME "VM_PROPERTIES"
-#define PROP_FILE_NAME "vm.properties"
-
-#define MAX_PROP_LINE 5120
-
-// local memory pool for temporary allocation
-static apr_pool_t *prop_pool;
-
-static void
-read_properties(char *fname, Properties & prop)
-{
- apr_file_t *f;
- char *src, *tok;
- if (APR_SUCCESS != apr_file_open(&f, fname, APR_FOPEN_READ, 0, prop_pool))
- return;
- WARN("USAGE OF vm.properties FILE IS DEPRECATED. THIS FUNCTIONALITY WILL BE REMOVED SOON. ALL PROPERTIES SHOULD BE SET ON COMMAND LINE");
- char buf[MAX_PROP_LINE];
- while (!apr_file_eof(f) && !apr_file_gets(buf, MAX_PROP_LINE, f))
- {
- if (buf[0] != '#') {
- src = strdup(buf);
- tok = strchr(src, '=');
- if(tok)
- {
- *tok = '\0';
- prop.set(unquote(src), unquote(tok + 1));
- }
- STD_FREE(src);
- }
- }
- apr_file_close(f);
-}
-
-#define API_DLL1 "harmonyvm"
-#define API_DLL2 "hythr"
-#define API_DLL3 "hysig"
-#define API_DLL4 "hyprt"
-#define API_DLL5 "hyzlib"
-#define API_DLL6 "hytext"
-#define API_DLL7 "hynio"
-#define API_DLL8 "vmi"
-#define API_DLLA "hyluni"
-#define API_DLLB "hyarchive"
-
-#define GC_DLL "gc_cc"
-
-/**
- * Compose a string of file names each of them beginning with path,
- * names separated by PORT_PATH_SEPARATOR. If patch is NULL, no path
- * or separator will be prefixed
- */
-static char *compose_full_files_path_names_list(const char *path,
- const char **dll_names,
- const int names_number,
- bool is_dll)
-{
- char* full_name = "";
- for (int iii = 0; iii < names_number; iii++)
- {
- const char *tmp = dll_names[iii];
- if (is_dll) {
- tmp = port_dso_name_decorate(tmp, prop_pool);
- }
-
- /*
- * if the path is non-null, prefix, otherwise do nothing
- * to avoid the problem of "/libfoo.so" when we don't want
- * a path attached
- */
-
- if (path != NULL) {
- tmp = port_filepath_merge(path, tmp, prop_pool);
- }
-
- full_name = apr_pstrcat(prop_pool, full_name, tmp,
- (iii + 1 < names_number) ? PORT_PATH_SEPARATOR_STR : "", NULL);
- }
-
- return full_name;
-}
-
-static void init_java_properties(Properties & properties)
-{
- //java part
- //!!! java.compiler property must be defined by EM
-
- char *os_name, *os_version, *path;
- const char *tmp;
- char *path_buf = NULL;
-
- port_OS_name_version(&os_name, &os_version, prop_pool);
- apr_filepath_get(&path, APR_FILEPATH_NATIVE, prop_pool);
- if (APR_SUCCESS != apr_temp_dir_get(&tmp, prop_pool)) {
- tmp = ".";
- }
- properties.set("java.version", "1.5.0");
- properties.set("java.vendor", "Apache Software Foundation");
- properties.set("java.vendor.url", "http://harmony.apache.org");
- // java.home initialization, try to find absolute location of the executable and set
- // java.home to the parent directory.
- char *base_path_buf;
- if (port_executable_name(&base_path_buf, prop_pool) != APR_SUCCESS) {
- DIE("Failed to find executable location");
- }
- // directory for the executable
- char *p = strrchr(base_path_buf, PORT_FILE_SEPARATOR);
- if (NULL == p)
- DIE("Failed to determine executable parent directory");
- *p = '\0';
- // home directory
- char* home_path = apr_pstrdup(prop_pool, base_path_buf);
- p = strrchr(home_path, PORT_FILE_SEPARATOR);
- if (NULL == p)
- DIE("Failed to determine java home directory");
- *p = '\0';
-
- properties.set("java.home", home_path);
- properties.set("java.vm.specification.version", "1.0");
- properties.set("java.vm.specification.vendor", "Sun Microsystems Inc.");
- properties.set("java.vm.specification.name", "Java Virtual Machine Specification");
- properties.set("java.vm.version", "11.2.0");
- properties.set("java.vm.vendor", "Apache Software Foundation");
- properties.set("java.vm.name", "DRLVM");
- properties.set("java.specification.version", "1.5");
- properties.set("java.specification.vendor", "Sun Microsystems Inc.");
- properties.set("java.specification.name", "Java Platform API Specification");
- properties.set("java.class.version", "49.0");
- properties.set("java.class.path", ".");
-
- // java.library.path initialization, the value is the location of VM executable,
- // prepended to OS library search path
- char *env;
- char *lib_path = base_path_buf;
- if (APR_SUCCESS == port_dso_search_path(&env, prop_pool))
- {
- lib_path = apr_pstrcat(prop_pool, base_path_buf, PORT_PATH_SEPARATOR_STR,
- base_path_buf, PORT_FILE_SEPARATOR_STR, "default",
- PORT_PATH_SEPARATOR_STR, env, NULL);
- }
- properties.set("java.library.path", lib_path);
- //java.ext.dirs initialization.
- char *ext_path = port_filepath_merge(home_path, "lib" PORT_FILE_SEPARATOR_STR "ext", prop_pool);
- properties.set("java.ext.dirs", ext_path);
- properties.set("os.name", os_name);
- properties.set("os.arch", port_CPU_architecture());
- properties.set("os.version", os_version);
- properties.set("file.separator", PORT_FILE_SEPARATOR_STR);
- properties.set("path.separator", PORT_PATH_SEPARATOR_STR);
- properties.set("line.separator", APR_EOL_STR);
- // user.name initialization, try to get the name from the system
- char *user_buf;
- apr_status_t status = port_user_name(&user_buf, prop_pool);
- if (APR_SUCCESS != status) {
- DIE("Failed to get user name from the system. Error code " << status);
- }
- properties.set("user.name", user_buf);
- // user.home initialization, try to get home from the system.
- char *user_home;
- status = port_user_home(&user_home, prop_pool);
- if (APR_SUCCESS != status) {
- DIE("Failed to get user home from the system. Error code " << status);
- }
- properties.set("user.home", user_home);
- // java.io.tmpdir initialization.
- const char *tmpdir;
- status = apr_temp_dir_get(&tmpdir, prop_pool);
- if (APR_SUCCESS != status) {
- tmpdir = user_home;
- }
- properties.set("java.io.tmpdir", tmpdir);
- properties.set("user.dir", path);
-
- // FIXME??? other (not required by api specification) properties
-
- properties.set("java.vm.info", "no info");
- properties.set("java.tmpdir", tmp);
- properties.set("user.language", "en");
- properties.set("user.region", "US");
- properties.set("file.encoding", "8859_1");
-
- // FIXME user.timezone initialization, required by java.util.TimeZone implementation
- char *user_tz;
- status = port_user_timezone(&user_tz, prop_pool);
- if (APR_SUCCESS != status) {
- INFO("Failed to get user timezone from the system. Error code " << status);
- user_tz = "GMT";
- }
-
- properties.set("user.timezone", user_tz);
-
- // FIXME: This is a workaround code for third party APIs which depend on this property.
- properties.set("java.util.prefs.PreferencesFactory",
-#ifdef PLATFORM_NT
- "java.util.prefs.RegistryPreferencesFactoryImpl");
-#else
- "java.util.prefs.FilePreferencesFactoryImpl");
-#endif
-
- // Added for compatibility with the external java JDWP agent
- properties.set("sun.boot.library.path", base_path_buf);
-
- /*
- * it's possible someone forgot to set this property - set to default of .
- */
- if (!properties.is_set(O_A_H_VM_VMDIR)) {
- TRACE2("init", "o.a.h.vm.vmdir not set - setting predefined value of as '.'");
- properties.set(O_A_H_VM_VMDIR, ".");
- }
-
- /*
- * also, do the same for java.class.path
- */
- if (!properties.is_set("java.class.path")) {
- TRACE2("init", "java.class.path not set - setting predefined value of as '.'");
- properties.set("java.class.path", ".");
- }
-}
-
-//vm part
-static void init_vm_properties(Properties & properties)
-{
- properties.set("vm.assert_dialog", "true");
- properties.set("vm.crash_handler", "false");
- properties.set("vm.finalize", "true");
- properties.set("vm.jit_may_inline_sync", "true");
- properties.set("vm.use_verifier", "true");
- properties.set("vm.jvmti.enabled", "false");
- properties.set("vm.cleanupOnExit", "false");
- properties.set("vm.bootclasspath.appendclasspath", "false");
-
- /*
- * vm.boot.library.path initialization, the value is the location of VM executable
- *
- * 2006-09-06 gmj : there's no reason to ever believe this is true given how the VM can be
- * launched in a mariad of ways, so just set to empty string.
- */
- properties.set("vm.boot.library.path", "");
-
- properties.set("vm.dlls", PORT_DSO_NAME(GC_DLL));
-
- // vm.other_natives_dlls initialization, the value is location of VM executable.
- const char *api_dll_files[] =
- {
- API_DLL1,
- API_DLL2,
- API_DLL3,
- API_DLL4,
- API_DLL5,
- API_DLL6,
- API_DLL7,
- API_DLL8,
- API_DLLA,
- API_DLLB
- };
- int n_api_dll_files = sizeof(api_dll_files) / sizeof(char *);
- /*
- * pass NULL for the pathname as we don't want
- * any path pre-pended
- */
- char* path_buf = compose_full_files_path_names_list(NULL, api_dll_files, n_api_dll_files, true);
- properties.set("vm.other_natives_dlls", path_buf);
-}
-
-void
-initialize_properties(Global_Env * p_env)
-{
- if (!prop_pool) {
- apr_pool_create(&prop_pool, 0);
- }
-/*
- * 0. Add predefined properties from property table
- */
-
- init_java_properties(*p_env->JavaProperties());
- init_vm_properties(*p_env->VmProperties());
-
-/*
- * 1. VM looks for an environment variable, say,
- * VM_PROPERTIES=d:\xyz\eee\vm.Properties, read the Properties;
- */
- char *pf;
- if (apr_env_get(&pf, PROP_ENV_NAME, prop_pool) == APR_SUCCESS){
- read_properties(pf, *p_env->JavaProperties());
- }
-/*
- * 2. Looks for vm.Properties in the directory where vm executable resides
- * (it's also a global file), read the Properties, if key is duplicated,
- * override the value;
- */
- char *buf;
- if (port_executable_name(&buf, prop_pool) == APR_SUCCESS)
- {
- char *p = strrchr(buf, PORT_FILE_SEPARATOR);
- if (p)
- {
- *(p + 1) = '\0';
- buf = apr_pstrcat(prop_pool, buf, PROP_FILE_NAME, NULL);
- read_properties(buf, *p_env->JavaProperties());
- }
- }
-
-/*
- * 3. Looks for it in current directory(it's an app-specific file), read the
- * Properties, if key is duplicated, override the value;
- */
- apr_filepath_get(&buf, 0, prop_pool);
- buf = port_filepath_merge(buf, PROP_FILE_NAME, prop_pool);
- read_properties(buf, *p_env->JavaProperties());
-/*
- * 4. Check whether there is a command line option, say,
- * -Properties-file "d:\xyz\eee\vm.Properties" or -Droperties key=value,
- * read the Properties, if key is duplicated, override the value.
- */
- char *src, *tok;
- for (int arg_num = 0; arg_num < p_env->vm_arguments.nOptions; arg_num++)
- {
- char *option = p_env->vm_arguments.options[arg_num].optionString;
- if (strncmp(option, "-D", 2) == 0)
- {
- TRACE("setting property " << option + 2);
- src = strdup(option + 2);
- tok = strchr(src, '=');
- if(tok)
- {
- *tok = '\0';
- p_env->JavaProperties()->set(unquote(src), unquote(tok + 1));
- }
- else
- {
- p_env->JavaProperties()->set(unquote(src), "");
- }
- STD_FREE(src);
- }
- else if (strncmp(option, "-XD", 3) == 0)
- {
- TRACE("setting internal property " << option + 3);
- src = strdup(option + 3);
- tok = strchr(src, '=');
- if(tok)
- {
- *tok = '\0';
- p_env->VmProperties()->set(unquote(src), unquote(tok + 1));
- }
- else
- {
- p_env->VmProperties()->set(unquote(src), "");
- }
-
- STD_FREE(src);
- }
- }
- apr_pool_clear(prop_pool);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr_file_io.h>
+#include <apr_file_info.h>
+#include <apr_env.h>
+#include <apr_strings.h>
+#include "port_dso.h"
+#include "port_filepath.h"
+#include "port_sysinfo.h"
+
+#define LOG_DOMAIN "init.properties"
+#include "cxxlog.h"
+#include "properties.h"
+#include "vm_properties.h"
+#include "init.h"
+
+inline char* unquote(char *str)
+{
+ const char *tokens = " \t\n\r\'\"";
+ size_t i = strspn(str, tokens);
+ str += i;
+ char *p = str + strlen(str) - 1;
+ while(strchr(tokens, *p) && p >= str)
+ *(p--) = '\0';
+ return str;
+}
+
+#define PROP_ENV_NAME "VM_PROPERTIES"
+#define PROP_FILE_NAME "vm.properties"
+
+#define MAX_PROP_LINE 5120
+
+// local memory pool for temporary allocation
+static apr_pool_t *prop_pool;
+
+static void
+read_properties(char *fname, Properties & prop)
+{
+ apr_file_t *f;
+ char *src, *tok;
+ if (APR_SUCCESS != apr_file_open(&f, fname, APR_FOPEN_READ, 0, prop_pool))
+ return;
+ WARN("USAGE OF vm.properties FILE IS DEPRECATED. THIS FUNCTIONALITY WILL BE REMOVED SOON. ALL PROPERTIES SHOULD BE SET ON COMMAND LINE");
+ char buf[MAX_PROP_LINE];
+ while (!apr_file_eof(f) && !apr_file_gets(buf, MAX_PROP_LINE, f))
+ {
+ if (buf[0] != '#') {
+ src = strdup(buf);
+ tok = strchr(src, '=');
+ if(tok)
+ {
+ *tok = '\0';
+ prop.set(unquote(src), unquote(tok + 1));
+ }
+ STD_FREE(src);
+ }
+ }
+ apr_file_close(f);
+}
+
+#define API_DLL1 "harmonyvm"
+#define API_DLL2 "hythr"
+#define API_DLL3 "hysig"
+#define API_DLL4 "hyprt"
+#define API_DLL5 "hyzlib"
+#define API_DLL6 "hytext"
+#define API_DLL7 "hynio"
+#define API_DLL8 "vmi"
+#define API_DLLA "hyluni"
+#define API_DLLB "hyarchive"
+
+#define GC_DLL "gc_cc"
+
+/**
+ * Compose a string of file names each of them beginning with path,
+ * names separated by PORT_PATH_SEPARATOR. If patch is NULL, no path
+ * or separator will be prefixed
+ */
+static char *compose_full_files_path_names_list(const char *path,
+ const char **dll_names,
+ const int names_number,
+ bool is_dll)
+{
+ char* full_name = "";
+ for (int iii = 0; iii < names_number; iii++)
+ {
+ const char *tmp = dll_names[iii];
+ if (is_dll) {
+ tmp = port_dso_name_decorate(tmp, prop_pool);
+ }
+
+ /*
+ * if the path is non-null, prefix, otherwise do nothing
+ * to avoid the problem of "/libfoo.so" when we don't want
+ * a path attached
+ */
+
+ if (path != NULL) {
+ tmp = port_filepath_merge(path, tmp, prop_pool);
+ }
+
+ full_name = apr_pstrcat(prop_pool, full_name, tmp,
+ (iii + 1 < names_number) ? PORT_PATH_SEPARATOR_STR : "", NULL);
+ }
+
+ return full_name;
+}
+
+static void init_java_properties(Properties & properties)
+{
+ //java part
+ //!!! java.compiler property must be defined by EM
+
+ char *os_name, *os_version, *path;
+ const char *tmp;
+ char *path_buf = NULL;
+
+ port_OS_name_version(&os_name, &os_version, prop_pool);
+ apr_filepath_get(&path, APR_FILEPATH_NATIVE, prop_pool);
+ if (APR_SUCCESS != apr_temp_dir_get(&tmp, prop_pool)) {
+ tmp = ".";
+ }
+ properties.set("java.version", "1.5.0");
+ properties.set("java.vendor", "Apache Software Foundation");
+ properties.set("java.vendor.url", "http://harmony.apache.org");
+ // java.home initialization, try to find absolute location of the executable and set
+ // java.home to the parent directory.
+ char *base_path_buf;
+ if (port_executable_name(&base_path_buf, prop_pool) != APR_SUCCESS) {
+ DIE("Failed to find executable location");
+ }
+ // directory for the executable
+ char *p = strrchr(base_path_buf, PORT_FILE_SEPARATOR);
+ if (NULL == p)
+ DIE("Failed to determine executable parent directory");
+ *p = '\0';
+ // home directory
+ char* home_path = apr_pstrdup(prop_pool, base_path_buf);
+ p = strrchr(home_path, PORT_FILE_SEPARATOR);
+ if (NULL == p)
+ DIE("Failed to determine java home directory");
+ *p = '\0';
+
+ properties.set("java.home", home_path);
+ properties.set("java.vm.specification.version", "1.0");
+ properties.set("java.vm.specification.vendor", "Sun Microsystems Inc.");
+ properties.set("java.vm.specification.name", "Java Virtual Machine Specification");
+ properties.set("java.vm.version", "11.2.0");
+ properties.set("java.vm.vendor", "Apache Software Foundation");
+ properties.set("java.vm.name", "DRLVM");
+ properties.set("java.specification.version", "1.5");
+ properties.set("java.specification.vendor", "Sun Microsystems Inc.");
+ properties.set("java.specification.name", "Java Platform API Specification");
+ properties.set("java.class.version", "49.0");
+ properties.set("java.class.path", ".");
+
+ // java.library.path initialization, the value is the location of VM executable,
+ // prepended to OS library search path
+ char *env;
+ char *lib_path = base_path_buf;
+ if (APR_SUCCESS == port_dso_search_path(&env, prop_pool))
+ {
+ lib_path = apr_pstrcat(prop_pool, base_path_buf, PORT_PATH_SEPARATOR_STR,
+ base_path_buf, PORT_FILE_SEPARATOR_STR, "default",
+ PORT_PATH_SEPARATOR_STR, env, NULL);
+ }
+ properties.set("java.library.path", lib_path);
+ //java.ext.dirs initialization.
+ char *ext_path = port_filepath_merge(home_path, "lib" PORT_FILE_SEPARATOR_STR "ext", prop_pool);
+ properties.set("java.ext.dirs", ext_path);
+ properties.set("os.name", os_name);
+ properties.set("os.arch", port_CPU_architecture());
+ properties.set("os.version", os_version);
+ properties.set("file.separator", PORT_FILE_SEPARATOR_STR);
+ properties.set("path.separator", PORT_PATH_SEPARATOR_STR);
+ properties.set("line.separator", APR_EOL_STR);
+ // user.name initialization, try to get the name from the system
+ char *user_buf;
+ apr_status_t status = port_user_name(&user_buf, prop_pool);
+ if (APR_SUCCESS != status) {
+ DIE("Failed to get user name from the system. Error code " << status);
+ }
+ properties.set("user.name", user_buf);
+ // user.home initialization, try to get home from the system.
+ char *user_home;
+ status = port_user_home(&user_home, prop_pool);
+ if (APR_SUCCESS != status) {
+ DIE("Failed to get user home from the system. Error code " << status);
+ }
+ properties.set("user.home", user_home);
+ // java.io.tmpdir initialization.
+ const char *tmpdir;
+ status = apr_temp_dir_get(&tmpdir, prop_pool);
+ if (APR_SUCCESS != status) {
+ tmpdir = user_home;
+ }
+ properties.set("java.io.tmpdir", tmpdir);
+ properties.set("user.dir", path);
+
+ // FIXME??? other (not required by api specification) properties
+
+ properties.set("java.vm.info", "no info");
+ properties.set("java.tmpdir", tmp);
+ properties.set("user.language", "en");
+ properties.set("user.region", "US");
+ properties.set("file.encoding", "8859_1");
+
+ // FIXME user.timezone initialization, required by java.util.TimeZone implementation
+ char *user_tz;
+ status = port_user_timezone(&user_tz, prop_pool);
+ if (APR_SUCCESS != status) {
+ INFO("Failed to get user timezone from the system. Error code " << status);
+ user_tz = "GMT";
+ }
+
+ properties.set("user.timezone", user_tz);
+
+ // FIXME: This is a workaround code for third party APIs which depend on this property.
+ properties.set("java.util.prefs.PreferencesFactory",
+#ifdef PLATFORM_NT
+ "java.util.prefs.RegistryPreferencesFactoryImpl");
+#else
+ "java.util.prefs.FilePreferencesFactoryImpl");
+#endif
+
+ // Added for compatibility with the external java JDWP agent
+ properties.set("sun.boot.library.path", base_path_buf);
+
+ /*
+ * it's possible someone forgot to set this property - set to default of .
+ */
+ if (!properties.is_set(O_A_H_VM_VMDIR)) {
+ TRACE2("init", "o.a.h.vm.vmdir not set - setting predefined value of as '.'");
+ properties.set(O_A_H_VM_VMDIR, ".");
+ }
+
+ /*
+ * also, do the same for java.class.path
+ */
+ if (!properties.is_set("java.class.path")) {
+ TRACE2("init", "java.class.path not set - setting predefined value of as '.'");
+ properties.set("java.class.path", ".");
+ }
+}
+
+//vm part
+static void init_vm_properties(Properties & properties)
+{
+ properties.set("vm.assert_dialog", "true");
+ properties.set("vm.crash_handler", "false");
+ properties.set("vm.finalize", "true");
+ properties.set("vm.jit_may_inline_sync", "true");
+ properties.set("vm.use_verifier", "true");
+ properties.set("vm.jvmti.enabled", "false");
+ properties.set("vm.bootclasspath.appendclasspath", "false");
+
+ /*
+ * vm.boot.library.path initialization, the value is the location of VM executable
+ *
+ * 2006-09-06 gmj : there's no reason to ever believe this is true given how the VM can be
+ * launched in a mariad of ways, so just set to empty string.
+ */
+ properties.set("vm.boot.library.path", "");
+
+ properties.set("vm.dlls", PORT_DSO_NAME(GC_DLL));
+
+ // vm.other_natives_dlls initialization, the value is location of VM executable.
+ const char *api_dll_files[] =
+ {
+ API_DLL1,
+ API_DLL2,
+ API_DLL3,
+ API_DLL4,
+ API_DLL5,
+ API_DLL6,
+ API_DLL7,
+ API_DLL8,
+ API_DLLA,
+ API_DLLB
+ };
+ int n_api_dll_files = sizeof(api_dll_files) / sizeof(char *);
+ /*
+ * pass NULL for the pathname as we don't want
+ * any path pre-pended
+ */
+ char* path_buf = compose_full_files_path_names_list(NULL, api_dll_files, n_api_dll_files, true);
+ properties.set("vm.other_natives_dlls", path_buf);
+}
+
+void
+initialize_properties(Global_Env * p_env)
+{
+ if (!prop_pool) {
+ apr_pool_create(&prop_pool, 0);
+ }
+/*
+ * 0. Add predefined properties from property table
+ */
+
+ init_java_properties(*p_env->JavaProperties());
+ init_vm_properties(*p_env->VmProperties());
+
+/*
+ * 1. VM looks for an environment variable, say,
+ * VM_PROPERTIES=d:\xyz\eee\vm.Properties, read the Properties;
+ */
+ char *pf;
+ if (apr_env_get(&pf, PROP_ENV_NAME, prop_pool) == APR_SUCCESS){
+ read_properties(pf, *p_env->JavaProperties());
+ }
+/*
+ * 2. Looks for vm.Properties in the directory where vm executable resides
+ * (it's also a global file), read the Properties, if key is duplicated,
+ * override the value;
+ */
+ char *buf;
+ if (port_executable_name(&buf, prop_pool) == APR_SUCCESS)
+ {
+ char *p = strrchr(buf, PORT_FILE_SEPARATOR);
+ if (p)
+ {
+ *(p + 1) = '\0';
+ buf = apr_pstrcat(prop_pool, buf, PROP_FILE_NAME, NULL);
+ read_properties(buf, *p_env->JavaProperties());
+ }
+ }
+
+/*
+ * 3. Looks for it in current directory(it's an app-specific file), read the
+ * Properties, if key is duplicated, override the value;
+ */
+ apr_filepath_get(&buf, 0, prop_pool);
+ buf = port_filepath_merge(buf, PROP_FILE_NAME, prop_pool);
+ read_properties(buf, *p_env->JavaProperties());
+/*
+ * 4. Check whether there is a command line option, say,
+ * -Properties-file "d:\xyz\eee\vm.Properties" or -Droperties key=value,
+ * read the Properties, if key is duplicated, override the value.
+ */
+ char *src, *tok;
+ for (int arg_num = 0; arg_num < p_env->vm_arguments.nOptions; arg_num++)
+ {
+ char *option = p_env->vm_arguments.options[arg_num].optionString;
+ if (strncmp(option, "-D", 2) == 0)
+ {
+ TRACE("setting property " << option + 2);
+ src = strdup(option + 2);
+ tok = strchr(src, '=');
+ if(tok)
+ {
+ *tok = '\0';
+ p_env->JavaProperties()->set(unquote(src), unquote(tok + 1));
+ }
+ else
+ {
+ p_env->JavaProperties()->set(unquote(src), "");
+ }
+ STD_FREE(src);
+ }
+ else if (strncmp(option, "-XD", 3) == 0)
+ {
+ TRACE("setting internal property " << option + 3);
+ src = strdup(option + 3);
+ tok = strchr(src, '=');
+ if(tok)
+ {
+ *tok = '\0';
+ p_env->VmProperties()->set(unquote(src), unquote(tok + 1));
+ }
+ else
+ {
+ p_env->VmProperties()->set(unquote(src), "");
+ }
+
+ STD_FREE(src);
+ }
+ }
+ apr_pool_clear(prop_pool);
+}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp?view=diff&rev=487483&r1=487482&r2=487483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp Fri Dec 15 00:33:21 2006
@@ -24,6 +24,7 @@
#include "open/hythread.h"
#include "open/jthread.h"
#include "open/gc.h"
+#include "open/thread_externals.h"
#include "jni.h"
#include "jni_direct.h"
@@ -82,6 +83,85 @@
return JNI_OK;
}
+static void vm_shutdown_callback() {
+ hythread_t self_native;
+ jthread self_java;
+ VM_thread * self_vm;
+ JNIEnv * jni_env;
+ Global_Env * vm_env;
+
+ self_native = hythread_self();
+ self_java = jthread_get_java_thread(self_native);
+ self_vm = get_vm_thread(self_native);
+
+ // Make sure the thread is still attached to the VM.
+ if (self_java == NULL || self_vm == NULL) {
+ return;
+ }
+
+ jni_env = jthread_get_JNI_env(self_java);
+ vm_env = jni_get_vm_env(jni_env);
+
+ // We need to be in suspend disabled state to be able to throw an exception.
+ assert(!hythread_is_suspend_enabled());
+
+ //hythread_suspend_disable();
+
+ // Raise an exception. In shutdown stage it should cause entire stack unwinding.
+ jthread_throw_exception_object(vm_env->java_lang_ThreadDeath);
+
+ //hythread_suspend_enable();
+}
+
+/*
+void vm_shutdown_stop_java_threads(int exit_code)
+{
+ jthread current_java_thread;
+ JNIEnv_Internal * jni_env;
+ Global_Env * vm_env;
+
+ // Current thread should be in suspend enabled state to prevent
+ // possible dead-locks.
+ assert(hythread_is_suspend_enabled());
+
+ current_java_thread = jthread_self();
+ // Current thread should be attached to ThreadManager.
+ assert(current_java_thread);
+ jni_env = (JNIEnv_Internal *) jthread_get_JNI_env(current_java_thread);
+ vm_env = jni_env->vm->vm_env;
+
+ // 2) Acquire VM state lock.
+ apr_thread_mutex_lock(vm_env->vm_state_mutex);
+ assert(vm_env->vm_state != Global_Env::VM_INITIALIZING);
+
+ // 3) Check VM state.
+ if (vm_env->vm_state == Global_Env::VM_SHUTDOWNING) {
+ apr_thread_mutex_unlock(vm_env->vm_state_mutex);
+ return;
+ }
+
+ assert(vm_env->vm_state == Global_Env::VM_RUNNING);
+
+ // 4) Change VM state. Exception propagation mechanism should be changed
+ // upon setting up this flag.
+ vm_env->vm_state = Global_Env::VM_SHUTDOWNING;
+
+ // 5) Block thread creation.
+ // TODO: investigate how to achive that with ThreadManager
+
+ // 6) Execute shutdown callback for the current thread.
+ vm_shutdown_callback(NULL);
+
+ // 7) Setup shutdown callback to all java threads but current.
+ // It causes an exception to be raised and all java monitors to
+ // be released upon reaching a safepoint.
+ hythread_group_set_suspend_disabled_callback(hythread_group_get_java(), vm_shutdown_callback, NULL);
+
+ // 8) Unlock VM state mutex.
+ apr_thread_mutex_unlock(vm_env->vm_state_mutex);
+}
+*/
+
/**
* TODO:
*/
@@ -92,13 +172,15 @@
jobject uncaught_exception;
VM_thread * vm_thread;
hythread_t native_thread;
- hythread_t current_native_thread;
+ hythread_t self;
hythread_iterator_t it;
+ hythread_t * running_threads;
+ int size;
assert(hythread_is_suspend_enabled());
jni_env = jthread_get_JNI_env(java_thread);
- current_native_thread = hythread_self();
+ self = hythread_self();
status = jthread_wait_for_all_nondaemon_threads();
if (status != TM_ERROR_NONE) {
@@ -138,65 +220,177 @@
// Call Agent_OnUnload() for agents and unload agents.
java_vm->vm_env->TI->Shutdown(java_vm);
+ // Block thread creation.
+ // TODO: investigate how to achive that with ThreadManager
+
+ // Starting this moment any exception occured in java thread will cause
+ // entire java stack unwinding to the most recent native frame.
+ // JNI is not available as well.
+ assert(java_vm->vm_env->vm_state == Global_Env::VM_RUNNING);
+ java_vm->vm_env->vm_state = Global_Env::VM_SHUTDOWNING;
+
// Stop all (except current) java and native threads
// before destroying VM-wide data.
- // TODO: current implementation doesn't stop java threads :-(
- // So, don't perform cleanup if there are running java threads.
+ // Stop java threads
+ size = 0;
it = hythread_iterator_create(NULL);
- while (native_thread = hythread_iterator_next(&it)) {
+ running_threads = (hythread_t *)apr_palloc(
+ java_vm->vm_env->mem_pool, hythread_iterator_size(it) * sizeof(hythread_t));
+ while(native_thread = hythread_iterator_next(&it)) {
vm_thread = get_vm_thread(native_thread);
- if (vm_thread != NULL && native_thread != current_native_thread) {
- java_vm->vm_env->VmProperties()->set("vm.noCleanupOnExit", "true");
- hythread_iterator_release(&it);
- return JNI_ERR;
+ if (vm_thread != NULL && native_thread != self) {
+ running_threads[size] = native_thread;
+ ++size;
+ hythread_set_safepoint_callback(native_thread, vm_shutdown_callback);
}
}
hythread_iterator_release(&it);
+ // Interrupt running threads.
+ for (int i = 0; i < size; i++) {
+ hythread_interrupt(running_threads[i]);
+ }
+
+ // Wait for threads completion.
+ for (int i = 0; i < size; i++) {
+ hythread_join(running_threads[i]);
+ }
+
// TODO: ups we don't stop native threads as well :-((
// We are lucky! Currently, there are no such threads.
return JNI_OK;
}
-static inline void dump_all_java_stacks()
-{
- hythread_t native_thread;
- hythread_iterator_t iterator;
- VM_thread * vm_thread;
+static int vm_interrupt_process(void * data) {
+ hythread_t * threadBuf;
+ int i;
+
+ threadBuf = (hythread_t *)data;
+ i = 0;
+ // Join all threads.
+ while (threadBuf[i] != NULL) {
+ hythread_join(threadBuf[i]);
+ i++;
+ }
- INFO("****** BEGIN OF JAVA STACKS *****\n");
+ // Return 130 to be compatible with RI.
+ exit(130);
+}
- hythread_suspend_all(&iterator, NULL);
- native_thread ;
- while(native_thread = hythread_iterator_next(&iterator)) {
- vm_thread = get_vm_thread(native_thread);
- if (!vm_thread) continue;
- interpreter.stack_dump(vm_thread);
+/**
+ * Initiates VM shutdown sequence.
+ */
+static int vm_interrupt_entry_point(void * data) {
+ JNIEnv * jni_env;
+ JavaVMAttachArgs args;
+ JavaVM * java_vm;
+ jint status;
+
+ java_vm = (JavaVM *)data;
+ args.version = JNI_VERSION_1_2;
+ args.group = NULL;
+ args.name = "InterruptionHandler";
+
+ status = AttachCurrentThread(java_vm, (void **)&jni_env, &args);
+ if (status == JNI_OK) {
+ exec_shutdown_sequence(jni_env);
+ DetachCurrentThread(java_vm);
}
- hythread_resume_all(NULL);
-
- INFO("****** END OF JAVA STACKS *****\n");
+ return status;
+}
+
+/**
+ * Dumps all java stacks.
+ */
+static int vm_dump_entry_point(void * data) {
+ JNIEnv * jni_env;
+ JavaVMAttachArgs args;
+ JavaVM * java_vm;
+ jint status;
+
+ java_vm = (JavaVM *)data;
+ args.version = JNI_VERSION_1_2;
+ args.group = NULL;
+ args.name = "DumpHandler";
+
+ status = AttachCurrentThread(java_vm, (void **)&jni_env, &args);
+ if (status == JNI_OK) {
+ // TODO: specify particular VM to notify.
+ jvmti_notify_data_dump_request();
+ st_print_all(stdout);
+ DetachCurrentThread(java_vm);
+ }
+ return status;
}
-void quit_handler(int UNREF x) {
- jvmti_notify_data_dump_request();
- if (interpreter_enabled()) {
- dump_all_java_stacks();
- } else {
- td_dump_all_threads(stderr);
+/**
+ * Current process recieved an interruption signal (Ctrl+C pressed).
+ * Shutdown all running VMs and terminate the process.
+ */
+void vm_interrupt_handler(int UNREF x) {
+ JavaVM ** vmBuf;
+ hythread_t * threadBuf;
+ int nVMs;
+ jint status;
+
+ status = JNI_GetCreatedJavaVMs(NULL, 0, &nVMs);
+ assert(nVMs <= 1);
+ if (status != JNI_OK) return;
+
+ vmBuf = (JavaVM **) STD_MALLOC(nVMs * sizeof(JavaVM *));
+ status = JNI_GetCreatedJavaVMs(vmBuf, nVMs, &nVMs);
+ assert(nVMs <= 1);
+ if (status != JNI_OK) goto cleanup;
+
+ status = hythread_attach(NULL);
+ if (status != TM_ERROR_NONE) goto cleanup;
+
+
+ threadBuf = (hythread_t *) STD_MALLOC((nVMs + 1) * sizeof(hythread_t));
+ threadBuf[nVMs] = NULL;
+
+ // Create a new thread for each VM to avoid scalability and deadlock problems.
+ for (int i = 0; i < nVMs; i++) {
+ threadBuf[i] = NULL;
+ hythread_create((threadBuf + i), 0, HYTHREAD_PRIORITY_NORMAL, 0, vm_interrupt_entry_point, (void *)vmBuf[i]);
}
+
+ // spawn a new thread which will terminate the proccess.
+ hythread_create(NULL, 0, HYTHREAD_PRIORITY_NORMAL, 0, vm_interrupt_process, (void *)threadBuf);
+
+cleanup:
+ STD_FREE(vmBuf);
}
-void interrupt_handler(int UNREF x)
-{
- static bool begin_shutdown_hooks = false;
+/**
+ * Current process recieved an ??? signal (Ctrl+Break pressed).
+ * Prints java stack traces for each VM running in the current procces.
+ */
+void vm_dump_handler(int UNREF x) {
+ JavaVM ** vmBuf;
+ int nVMs;
+ jint status;
+
+ status = JNI_GetCreatedJavaVMs(NULL, 0, &nVMs);
+ assert(nVMs <= 1);
+ if (status != JNI_OK) return;
+
+ vmBuf = (JavaVM **) STD_MALLOC(nVMs * sizeof(JavaVM *));
+ status = JNI_GetCreatedJavaVMs(vmBuf, nVMs, &nVMs);
+ assert(nVMs <= 1);
+
+ if (status != JNI_OK) goto cleanup;
+
+ status = hythread_attach(NULL);
+ if (status != TM_ERROR_NONE) goto cleanup;
+
+ // Create a new thread for each VM to avoid scalability and deadlock problems.
+ for (int i = 0; i < nVMs; i++) {
+ hythread_create(NULL, 0, HYTHREAD_PRIORITY_NORMAL, 0, vm_dump_entry_point, (void *)vmBuf[i]);
+ }
- if(!begin_shutdown_hooks){
- begin_shutdown_hooks = true;
- //FIXME: integration should do int another way.
- //vm_set_event(non_daemon_threads_dead_handle);
- }else
- exit(1);
+cleanup:
+ STD_FREE(vmBuf);
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp?view=diff&rev=487483&r1=487482&r2=487483
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp Fri Dec 15 00:33:21 2006
@@ -50,6 +50,7 @@
#include "jni_utils.h"
#include "jit_runtime_support.h"
#include "jvmti_direct.h"
+#include "stack_trace.h"
#ifdef _IPF_
#include "stub_code_utils.h"
@@ -418,16 +419,13 @@
apr_thread_mutex_lock(GLOBAL_LOCK);
*nVMs = 0;
- if (!APR_RING_EMPTY(&GLOBAL_VMS, JavaVM_Internal, link)) {
- JavaVM_Internal * current_vm = APR_RING_FIRST(&GLOBAL_VMS);
- while (current_vm) {
- if (*nVMs < bufLen) {
- vmBuf[*nVMs] = (JavaVM *)current_vm;
- }
- ++(*nVMs);
- current_vm = APR_RING_NEXT(current_vm, link);
- }
-
+ JavaVM_Internal * current_vm = APR_RING_FIRST(&GLOBAL_VMS);
+ while (current_vm != APR_RING_SENTINEL(&GLOBAL_VMS, JavaVM_Internal, link)) {
+ if (*nVMs < bufLen) {
+ vmBuf[*nVMs] = (JavaVM *)current_vm;
+ }
+ ++(*nVMs);
+ current_vm = APR_RING_NEXT(current_vm, link);
}
apr_thread_mutex_unlock(GLOBAL_LOCK);
return JNI_OK;
@@ -522,6 +520,9 @@
goto done;
}
+ // The VM is fully initialized now.
+ vm_env->vm_state = Global_Env::VM_RUNNING;
+
// Send VM init event.
jvmti_send_vm_init_event(vm_env);
@@ -644,56 +645,58 @@
assert(hythread_is_suspend_enabled());
return struct_Class_to_jclass(clss);
}
- else
- {
- assert(exn_raised());
- return NULL;
- }
+
+ assert(exn_raised());
+ return NULL;
} //DefineClass
-jclass JNICALL FindClass(JNIEnv* env_ext,
- const char* name)
+ jclass JNICALL FindClass(JNIEnv * jni_env,
+ const char * name)
{
- if (exn_raised()) return NULL;
TRACE2("jni", "FindClass called, name = " << name);
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (exn_raised() || vm_env->IsVmShutdowning()) return NULL;
char *ch = strchr(name, '.');
if (NULL != ch)
{
- ThrowNew_Quick(env_ext,
+ ThrowNew_Quick(jni_env,
VM_Global_State::loader_env->JavaLangNoClassDefFoundError_String->bytes,
name);
return NULL;
}
- String* cls_name = VM_Global_State::loader_env->string_pool.lookup(name);
- return FindClass(env_ext, cls_name);
+ String* cls_name = vm_env->string_pool.lookup(name);
+ return FindClass(jni_env, cls_name);
} //FindClass
-jclass JNICALL GetSuperclass(JNIEnv * UNREF env, jclass clazz)
+jclass JNICALL GetSuperclass(JNIEnv * jni_env, jclass clazz)
{
TRACE2("jni", "GetSuperclass called");
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return NULL;
Class* clss = jclass_to_struct_Class(clazz);
if(clss) {
if(clss->is_interface()) {
- return 0;
+ return NULL;
} else {
Class* super_class = clss->get_super_class();
if(super_class) {
assert(hythread_is_suspend_enabled());
return struct_Class_to_jclass(super_class);
} else {
- return 0;
+ return NULL;
}
}
} else {
- return 0;
+ return NULL;
}
} //GetSuperclass
-jboolean JNICALL IsAssignableFrom(JNIEnv * UNREF env,
+jboolean JNICALL IsAssignableFrom(JNIEnv * UNREF jni_env,
jclass clazz1,
jclass clazz2)
{
@@ -710,10 +713,11 @@
}
} //IsAssignableFrom
-jint JNICALL Throw(JNIEnv * UNREF env, jthrowable obj)
+jint JNICALL Throw(JNIEnv * UNREF jni_env, jthrowable obj)
{
TRACE2("jni", "Throw called");
assert(hythread_is_suspend_enabled());
+
if(obj) {
exn_raise_object(obj);
return 0;
@@ -722,7 +726,7 @@
}
} // Throw
-jint JNICALL ThrowNew(JNIEnv *env, jclass clazz, const char *message)
+jint JNICALL ThrowNew(JNIEnv * jni_env, jclass clazz, const char *message)
{
TRACE2("jni", "ThrowNew called, message = " << (message ? message : "<no message>"));
assert(hythread_is_suspend_enabled());
@@ -730,18 +734,23 @@
jstring str = (jstring)0;
if(message) {
- str = NewStringUTF(env, message);
+ str = NewStringUTF(jni_env, message);
if(!str) {
return -1;
}
}
- jmethodID init_id = GetMethodID(env, clazz, "<init>", "(Ljava/lang/String;)V");
+ jmethodID init_id = GetMethodID(jni_env, clazz, "<init>", "(Ljava/lang/String;)V");
+ if (!init_id) {
+ jni_env->DeleteLocalRef(str);
+ return -1;
+ }
+
jvalue args[1];
args[0].l = str;
- jobject obj = NewObjectA(env, clazz, init_id, args);
- env->DeleteLocalRef(str);
- if(obj && !ExceptionOccurred(env)) {
+ jobject obj = NewObjectA(jni_env, clazz, init_id, args);
+ jni_env->DeleteLocalRef(str);
+ if(obj && !ExceptionOccurred(jni_env)) {
exn_raise_object(obj);
return 0;
} else {
@@ -749,58 +758,79 @@
}
} //ThrowNew
-jint JNICALL ThrowNew_Quick(JNIEnv *env, const char *classname, const char *message)
+jint JNICALL ThrowNew_Quick(JNIEnv * jni_env, const char *classname, const char *message)
{
- jclass exclazz = FindClass(env, classname);
+ jclass exclazz = FindClass(jni_env, classname);
if(!exclazz) {
return -1;
}
- jint result = ThrowNew(env, exclazz, message);
- env->DeleteLocalRef(exclazz);
+ jint result = ThrowNew(jni_env, exclazz, message);
+ jni_env->DeleteLocalRef(exclazz);
return result;
} // ThrowNew_Quick
//FIXME LAZY EXCEPTION (2006.05.15)
// chacks usage of this function and replace by lazy
-jthrowable JNICALL ExceptionOccurred(JNIEnv * UNREF env)
+jthrowable JNICALL ExceptionOccurred(JNIEnv * jni_env)
{
TRACE2("jni", "ExceptionOccurred called");
assert(hythread_is_suspend_enabled());
-#ifdef _DEBUG
- tmn_suspend_disable();
- if (!exn_raised())
- {
- TRACE2("jni", "Exception occured, no exception");
- }
- else
- {
- TRACE2("jni", "Exception occured, class = " << exn_get_name());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) {
+ // Wait until shutdown exception is raised by callback.
+ while (!exn_raised()) {
+ // Switch enable/disable status to give a chance for
+ // callback execution.
+ hythread_suspend_disable();
+ hythread_suspend_enable();
+ hythread_yield();
+ }
}
- tmn_suspend_enable();
-#endif
+ jthrowable result = exn_get();
- if(exn_raised()) {
- return exn_get();
+#ifdef _DEBUG
+ hythread_suspend_disable();
+ if (result) {
+ TRACE2("jni", "Exception occured, class = " << exn_get_name());
} else {
- return 0;
+ TRACE2("jni", "Exception occured, no exception");
+ }
+ if (vm_env->IsVmShutdowning() && !result) {
+ TRACE2("vm.core.shutdown", "ExceptionOccured: shutdown exception hasn't been raised");
}
+ hythread_suspend_enable();
+#endif
+
+ return result;
} //ExceptionOccurred
-void JNICALL ExceptionDescribe(JNIEnv * UNREF env)
+void JNICALL ExceptionDescribe(JNIEnv * jni_env)
{
TRACE2("jni", "ExceptionDescribe called");
assert(hythread_is_suspend_enabled());
+ // we should not report vm shutdown exception to the user
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return;
if (exn_raised()) {
exn_print_stack_trace(stderr, exn_get());
}
} //ExceptionDescribe
-void JNICALL ExceptionClear(JNIEnv * UNREF env)
+void JNICALL ExceptionClear(JNIEnv * jni_env)
{
TRACE2("jni", "ExceptionClear called");
assert(hythread_is_suspend_enabled());
+
tmn_suspend_disable();
+ // It is important to check the VM shutdown state in suspend disabled mode
+ // to garantee that we will not clear raised shutdown exception
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) {
+ tmn_suspend_enable();
+ return;
+ }
#ifdef _DEBUG
if (!exn_raised())
{
@@ -815,17 +845,25 @@
tmn_suspend_enable();
} //ExceptionClear
-void JNICALL FatalError(JNIEnv * UNREF env, const char *msg)
+void JNICALL FatalError(JNIEnv * UNREF jni_env, const char *msg)
{
TRACE2("jni", "FatalError called");
assert(hythread_is_suspend_enabled());
- DIE("\nFATAL error occurred in a JNI native method:\n\t" << msg);
+
+ fprintf(stdout, "\nFATAL ERROR occurred in native method: %s\n", msg);
+ st_print(stdout, hythread_self());
+
+ // Return 1 to be compatible with RI.
+ exit(1);
} //FatalError
-jobject JNICALL NewGlobalRef(JNIEnv * UNREF env, jobject obj)
+jobject JNICALL NewGlobalRef(JNIEnv * jni_env, jobject obj)
{
TRACE2("jni", "NewGlobalRef called");
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning() || !obj) return NULL;
if(!obj) {
return 0;
}
@@ -844,33 +882,35 @@
return (jobject)new_handle;
} //NewGlobalRef
-void JNICALL DeleteGlobalRef(JNIEnv * UNREF env, jobject globalRef)
+void JNICALL DeleteGlobalRef(JNIEnv * UNREF jni_env, jobject globalRef)
{
TRACE2("jni", "DeleteGlobalRef called");
assert(hythread_is_suspend_enabled());
+
+ if (globalRef == NULL) return;
+
#ifdef _DEBUG
tmn_suspend_disable();
ObjectHandle h = (ObjectHandle)globalRef;
TRACE2("jni", "DeleteGlobalRef class = " << h->object->vt()->clss);
tmn_suspend_enable();
#endif
- if (globalRef != NULL) {
- oh_deallocate_global_handle((ObjectHandle)globalRef);
- }
+
+ oh_deallocate_global_handle((ObjectHandle)globalRef);
} //DeleteGlobalRef
-jobject JNICALL NewLocalRef(JNIEnv *env, jobject ref)
+jobject JNICALL NewLocalRef(JNIEnv * jni_env, jobject ref)
{
TRACE2("jni", "NewLocalRef called");
assert(hythread_is_suspend_enabled());
- if (NULL == ref)
- return NULL;
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning() || ref == NULL) return NULL;
jobject new_ref = oh_copy_to_local_handle(ref);
if (NULL == new_ref) {
- exn_raise_object(
- (jthrowable)(((JNIEnv_Internal*)env)->vm->vm_env->java_lang_OutOfMemoryError));
+ exn_raise_object(vm_env->java_lang_OutOfMemoryError);
return NULL;
}
@@ -879,22 +919,24 @@
return new_ref;
} //NewLocalRef
-void JNICALL DeleteLocalRef(JNIEnv * UNREF env, jobject localRef)
+void JNICALL DeleteLocalRef(JNIEnv * UNREF jni_env, jobject localRef)
{
TRACE2("jni", "DeleteLocalRef called");
assert(hythread_is_suspend_enabled());
+
+ if (localRef == NULL) return;
+
#ifdef _DEBUG
tmn_suspend_disable();
ObjectHandle h = (ObjectHandle)localRef;
TRACE2("jni", "DeleteLocalRef class = " << h->object->vt()->clss);
tmn_suspend_enable();
#endif
- if (localRef != NULL) {
- oh_discard_local_handle((ObjectHandle)localRef);
- }
+
+ oh_discard_local_handle((ObjectHandle)localRef);
} //DeleteLocalRef
-jboolean JNICALL IsSameObject(JNIEnv * UNREF env,
+jboolean JNICALL IsSameObject(JNIEnv * UNREF jni_env,
jobject ref1,
jobject ref2)
{
@@ -926,7 +968,7 @@
return result;
} //IsSameObject
-VMEXPORT jint JNICALL PushLocalFrame(JNIEnv * UNREF env, jint UNREF cap)
+VMEXPORT jint JNICALL PushLocalFrame(JNIEnv * UNREF jni_env, jint UNREF cap)
{
TRACE2("jni", "PushLocalFrame called");
assert(hythread_is_suspend_enabled());
@@ -934,7 +976,7 @@
return 0;
}
-VMEXPORT jobject JNICALL PopLocalFrame(JNIEnv * UNREF env, jobject res)
+VMEXPORT jobject JNICALL PopLocalFrame(JNIEnv * UNREF jni_env, jobject res)
{
TRACE2("jni", "PopLocalFrame called");
assert(hythread_is_suspend_enabled());
@@ -943,7 +985,7 @@
}
-jint JNICALL EnsureLocalCapacity(JNIEnv* UNREF env, jint UNREF cap)
+jint JNICALL EnsureLocalCapacity(JNIEnv * UNREF jni_env, jint UNREF cap)
{
TRACE2("jni", "EnsureLocalCapacity called");
assert(hythread_is_suspend_enabled());
@@ -951,18 +993,21 @@
}
-jobject JNICALL AllocObject(JNIEnv *env,
+jobject JNICALL AllocObject(JNIEnv * jni_env,
jclass clazz)
{
TRACE2("jni", "AllocObject called");
assert(hythread_is_suspend_enabled());
- assert(clazz);
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning() || clazz == NULL) return NULL;
+
Class* clss = jclass_to_struct_Class(clazz);
if(clss->is_interface() || clss->is_abstract()) {
// Can't instantiate interfaces and abtract classes.
- ThrowNew_Quick(env, "java/lang/InstantiationException", clss->get_name()->bytes);
- return 0;
+ ThrowNew_Quick(jni_env, "java/lang/InstantiationException", clss->get_name()->bytes);
+ return NULL;
}
tmn_suspend_disable(); //---------------------------------v
@@ -970,8 +1015,7 @@
ManagedObject *new_obj = (ManagedObject *)class_alloc_new_object(clss);
if (new_obj == NULL) {
tmn_suspend_enable();
- return 0;
-
+ return NULL;
}
new_handle->object = (ManagedObject *)new_obj;
tmn_suspend_enable(); //---------------------------------^
@@ -981,7 +1025,7 @@
-jobject JNICALL NewObject(JNIEnv *env,
+jobject JNICALL NewObject(JNIEnv * jni_env,
jclass clazz,
jmethodID methodID,
...)
@@ -990,10 +1034,10 @@
assert(hythread_is_suspend_enabled());
va_list args;
va_start(args, methodID);
- return NewObjectV(env, clazz, methodID, args);
+ return NewObjectV(jni_env, clazz, methodID, args);
} //NewObject
-jobject JNICALL NewObjectV(JNIEnv *env,
+jobject JNICALL NewObjectV(JNIEnv * jni_env,
jclass clazz,
jmethodID methodID,
va_list args)
@@ -1001,12 +1045,12 @@
TRACE2("jni", "NewObjectV called");
assert(hythread_is_suspend_enabled());
jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args);
- jobject result = NewObjectA(env, clazz, methodID, jvalue_args);
+ jobject result = NewObjectA(jni_env, clazz, methodID, jvalue_args);
STD_FREE(jvalue_args);
return result;
} //NewObjectV
-jobject JNICALL NewObjectA(JNIEnv *env,
+jobject JNICALL NewObjectA(JNIEnv * jni_env,
jclass clazz,
jmethodID methodID,
jvalue *args)
@@ -1014,27 +1058,25 @@
TRACE2("jni", "NewObjectA called");
assert(hythread_is_suspend_enabled());
// Allocate the object.
- jobject new_handle = AllocObject(env, clazz);
+ jobject new_handle = AllocObject(jni_env, clazz);
if(!new_handle) {
// Couldn't allocate the object.
- return 0;
+ return NULL;
}
- CallNonvirtualVoidMethodA(env, new_handle, clazz, methodID, args);
- if (ExceptionCheck(env))
- return NULL;
- else
- return new_handle;
+ CallNonvirtualVoidMethodA(jni_env, new_handle, clazz, methodID, args);
+ return ExceptionCheck(jni_env) ? NULL : new_handle;
} //NewObjectA
-jclass JNICALL GetObjectClass(JNIEnv * UNREF env,
+jclass JNICALL GetObjectClass(JNIEnv * jni_env,
jobject obj)
{
TRACE2("jni", "GetObjectClass called");
assert(hythread_is_suspend_enabled());
// The spec guarantees that the reference is not null.
assert(obj);
+
ObjectHandle h = (ObjectHandle)obj;
tmn_suspend_disable(); //---------------------------------v
@@ -1051,7 +1093,7 @@
return (jobject)new_handle;
} //GetObjectClass
-jboolean JNICALL IsInstanceOf(JNIEnv *env,
+jboolean JNICALL IsInstanceOf(JNIEnv * jni_env,
jobject obj,
jclass clazz)
{
@@ -1061,18 +1103,14 @@
return JNI_TRUE;
}
- jclass obj_class = GetObjectClass(env, obj);
+ jclass obj_class = GetObjectClass(jni_env, obj);
Class* clss = jclass_to_struct_Class(clazz);
Class* obj_clss = jclass_to_struct_Class(obj_class);
Boolean isInstance = obj_clss->is_instanceof(clss);
- if(isInstance) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
+ return isInstance ? JNI_TRUE : JNI_FALSE;
} //IsInstanceOf
static bool
@@ -1095,16 +1133,20 @@
#endif // !NDEBUG
}
-jstring JNICALL NewString(JNIEnv * UNREF env,
+jstring JNICALL NewString(JNIEnv * jni_env,
const jchar *unicodeChars,
jsize length)
{
TRACE2("jni", "NewString called, length = " << length);
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return NULL;
+
return (jstring)string_create_from_unicode_h(unicodeChars, length);
} //NewString
-jsize JNICALL GetStringLength(JNIEnv * UNREF env,
+jsize JNICALL GetStringLength(JNIEnv * UNREF jni_env,
jstring string)
{
TRACE2("jni", "GetStringLength called");
@@ -1115,14 +1157,16 @@
return string_get_length_h((ObjectHandle)string);
} //GetStringLength
-const jchar *JNICALL GetStringChars(JNIEnv * UNREF env,
+const jchar *JNICALL GetStringChars(JNIEnv * jni_env,
jstring string,
jboolean *isCopy)
{
TRACE2("jni", "GetStringChars called");
assert(hythread_is_suspend_enabled());
- if(!string)
- return 0;
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (!string || vm_env->IsVmShutdowning()) return NULL;
+
assert(check_is_jstring_class(string));
tmn_suspend_disable();
@@ -1133,7 +1177,7 @@
return chars;
} //GetStringChars
-void JNICALL ReleaseStringChars(JNIEnv * UNREF env,
+void JNICALL ReleaseStringChars(JNIEnv * UNREF jni_env,
jstring string,
const jchar *chars)
{
@@ -1145,15 +1189,19 @@
STD_FREE((void*)chars);
} //ReleaseStringChars
-jstring JNICALL NewStringUTF(JNIEnv * UNREF env,
+jstring JNICALL NewStringUTF(JNIEnv * jni_env,
const char *bytes)
{
TRACE2("jni", "NewStringUTF called, bytes = " << bytes);
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return NULL;
+
return (jstring)string_create_from_utf8_h(bytes, (unsigned)strlen(bytes));
} //NewStringUTF
-jsize JNICALL GetStringUTFLength(JNIEnv * UNREF env,
+jsize JNICALL GetStringUTFLength(JNIEnv * UNREF jni_env,
jstring string)
{
TRACE2("jni", "GetStringUTFLength called");
@@ -1164,21 +1212,22 @@
return string_get_utf8_length_h((ObjectHandle)string);
} //GetStringUTFLength
-const char *JNICALL GetStringUTFChars(JNIEnv * UNREF env,
+const char *JNICALL GetStringUTFChars(JNIEnv * jni_env,
jstring string,
jboolean *isCopy)
{
TRACE2("jni", "GetStringUTFChars called");
- if(!string)
- return 0;
- assert(check_is_jstring_class(string));
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning() || !string) return NULL;
+ assert(check_is_jstring_class(string));
const char* res = string_get_utf8_chars_h((ObjectHandle)string);
if (isCopy) *isCopy = JNI_TRUE;
return res;
} //GetStringUTFChars
-void JNICALL ReleaseStringUTFChars(JNIEnv * UNREF env,
+void JNICALL ReleaseStringUTFChars(JNIEnv * UNREF jni_env,
jstring string,
const char *utf)
{
@@ -1190,18 +1239,22 @@
STD_FREE((void*)utf);
} //ReleaseStringUTFChars
-jint JNICALL RegisterNatives(JNIEnv * UNREF env,
+jint JNICALL RegisterNatives(JNIEnv * jni_env,
jclass clazz,
const JNINativeMethod *methods,
jint nMethods)
{
TRACE2("jni", "RegisterNatives called");
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return -1;
+
Class_Handle clss = jclass_to_struct_Class(clazz);
return class_register_methods(clss, methods, nMethods) ? -1 : 0;
} //RegisterNatives
-jint JNICALL UnregisterNatives(JNIEnv * UNREF env, jclass clazz)
+jint JNICALL UnregisterNatives(JNIEnv * jni_env, jclass clazz)
{
TRACE2("jni", "UnregisterNatives called");
assert(hythread_is_suspend_enabled());
@@ -1209,17 +1262,21 @@
return class_unregister_methods(clss) ? -1 : 0;
} //UnregisterNatives
-jint JNICALL MonitorEnter(JNIEnv * UNREF env, jobject obj)
+jint JNICALL MonitorEnter(JNIEnv * jni_env, jobject obj)
{
TRACE2("jni", "MonitorEnter called");
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return -1;
+
jthread_monitor_enter(obj);
return exn_raised() ? -1 : 0;
} //MonitorEnter
-jint JNICALL MonitorExit(JNIEnv * UNREF env, jobject obj)
+jint JNICALL MonitorExit(JNIEnv * UNREF jni_env, jobject obj)
{
ASSERT_RAISE_AREA;
@@ -1231,20 +1288,23 @@
-jint JNICALL GetJavaVM(JNIEnv *env_ext, JavaVM **vm)
+jint JNICALL GetJavaVM(JNIEnv * jni_env, JavaVM **vm)
{
TRACE2("jni", "GetJavaVM called");
assert(hythread_is_suspend_enabled());
- JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext;
- *vm = env->vm;
+ *vm = ((JNIEnv_Internal *) jni_env)->vm;
return JNI_OK;
} //GetJavaVM
-void JNICALL GetStringRegion(JNIEnv * UNREF env, jstring s, jsize off, jsize len, jchar *b)
+void JNICALL GetStringRegion(JNIEnv * jni_env, jstring s, jsize off, jsize len, jchar *b)
{
TRACE2("jni", "GetStringRegion called");
assert(hythread_is_suspend_enabled());
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+ if (vm_env->IsVmShutdowning()) return;
+
assert(s);
string_get_unicode_region_h((ObjectHandle)s, off, len, b);
@@ -1257,7 +1317,7 @@
string_get_utf8_region_h((ObjectHandle)s, off, len, b);
}
-VMEXPORT void* JNICALL GetPrimitiveArrayCritical(JNIEnv* jenv, jarray array, jboolean* isCopy)
+VMEXPORT void* JNICALL GetPrimitiveArrayCritical(JNIEnv * jni_env, jarray array, jboolean* isCopy)
{
TRACE2("jni", "GetPrimitiveArrayCritical called");
assert(hythread_is_suspend_enabled());
@@ -1269,35 +1329,36 @@
TRACE2("jni.pin", "pinning array " << array->object);
gc_pin_object((Managed_Object_Handle*)array);
switch (array_clss->get_name()->bytes[1]) {
- case 'B': return GetByteArrayElements(jenv, array, isCopy);
- case 'C': return GetCharArrayElements(jenv, array, isCopy);
- case 'D': return GetDoubleArrayElements(jenv, array, isCopy);
- case 'F': return GetFloatArrayElements(jenv, array, isCopy);
- case 'I': return GetIntArrayElements(jenv, array, isCopy);
- case 'J': return GetLongArrayElements(jenv, array, isCopy);
- case 'S': return GetShortArrayElements(jenv, array, isCopy);
- case 'Z': return GetBooleanArrayElements(jenv, array, isCopy);
+ case 'B': return GetByteArrayElements(jni_env, array, isCopy);
+ case 'C': return GetCharArrayElements(jni_env, array, isCopy);
+ case 'D': return GetDoubleArrayElements(jni_env, array, isCopy);
+ case 'F': return GetFloatArrayElements(jni_env, array, isCopy);
+ case 'I': return GetIntArrayElements(jni_env, array, isCopy);
+ case 'J': return GetLongArrayElements(jni_env, array, isCopy);
+ case 'S': return GetShortArrayElements(jni_env, array, isCopy);
+ case 'Z': return GetBooleanArrayElements(jni_env, array, isCopy);
default: ABORT("Wrong array type descriptor"); return NULL;
}
}
-VMEXPORT void JNICALL ReleasePrimitiveArrayCritical(JNIEnv* jenv, jarray array, void* carray, jint mode)
+VMEXPORT void JNICALL ReleasePrimitiveArrayCritical(JNIEnv * jni_env, jarray array, void* carray, jint mode)
{
TRACE2("jni", "ReleasePrimitiveArrayCritical called");
assert(hythread_is_suspend_enabled());
+
tmn_suspend_disable();
Class* array_clss = ((ObjectHandle)array)->object->vt()->clss;
tmn_suspend_enable();
assert(array_clss->get_name()->bytes[0]=='[');
switch (array_clss->get_name()->bytes[1]) {
- case 'B': ReleaseByteArrayElements(jenv, array, (jbyte*)carray, mode); break;
- case 'C': ReleaseCharArrayElements(jenv, array, (jchar*)carray, mode); break;
- case 'D': ReleaseDoubleArrayElements(jenv, array, (jdouble*)carray, mode); break;
- case 'F': ReleaseFloatArrayElements(jenv, array, (jfloat*)carray, mode); break;
- case 'I': ReleaseIntArrayElements(jenv, array, (jint*)carray, mode); break;
- case 'J': ReleaseLongArrayElements(jenv, array, (jlong*)carray, mode); break;
- case 'S': ReleaseShortArrayElements(jenv, array, (jshort*)carray, mode); break;
- case 'Z': ReleaseBooleanArrayElements(jenv, array, (jboolean*)carray, mode); break;
+ case 'B': ReleaseByteArrayElements(jni_env, array, (jbyte*)carray, mode); break;
+ case 'C': ReleaseCharArrayElements(jni_env, array, (jchar*)carray, mode); break;
+ case 'D': ReleaseDoubleArrayElements(jni_env, array, (jdouble*)carray, mode); break;
+ case 'F': ReleaseFloatArrayElements(jni_env, array, (jfloat*)carray, mode); break;
+ case 'I': ReleaseIntArrayElements(jni_env, array, (jint*)carray, mode); break;
+ case 'J': ReleaseLongArrayElements(jni_env, array, (jlong*)carray, mode); break;
+ case 'S': ReleaseShortArrayElements(jni_env, array, (jshort*)carray, mode); break;
+ case 'Z': ReleaseBooleanArrayElements(jni_env, array, (jboolean*)carray, mode); break;
default: ABORT("Wrong array type descriptor"); break;
}
if (mode != JNI_COMMIT) {
@@ -1306,100 +1367,109 @@
}
}
-const jchar* JNICALL GetStringCritical(JNIEnv *env, jstring s, jboolean* isCopy)
+const jchar* JNICALL GetStringCritical(JNIEnv *jni_env, jstring s, jboolean* isCopy)
{
TRACE2("jni", "GetStringCritical called");
assert(hythread_is_suspend_enabled());
- return GetStringChars(env, s, isCopy);
+ return GetStringChars(jni_env, s, isCopy);
}
-void JNICALL ReleaseStringCritical(JNIEnv *env, jstring s, const jchar* cstr)
+void JNICALL ReleaseStringCritical(JNIEnv * jni_env, jstring s, const jchar* cstr)
{
TRACE2("jni", "ReleaseStringCritical called");
assert(hythread_is_suspend_enabled());
- ReleaseStringChars(env, s, cstr);
+ ReleaseStringChars(jni_env, s, cstr);
}
-VMEXPORT jweak JNICALL NewWeakGlobalRef(JNIEnv *env, jobject obj)
+VMEXPORT jweak JNICALL NewWeakGlobalRef(JNIEnv * jni_env, jobject obj)
{
TRACE2("jni", "NewWeakGlobalRef called");
assert(hythread_is_suspend_enabled());
- return NewGlobalRef(env, obj);
+ return NewGlobalRef(jni_env, obj);
}
-VMEXPORT void JNICALL DeleteWeakGlobalRef(JNIEnv *env, jweak obj)
+VMEXPORT void JNICALL DeleteWeakGlobalRef(JNIEnv * jni_env, jweak obj)
{
TRACE2("jni", "DeleteWeakGlobalRef called");
assert(hythread_is_suspend_enabled());
- DeleteGlobalRef(env, obj);
+ DeleteGlobalRef(jni_env, obj);
}
-jboolean JNICALL ExceptionCheck(JNIEnv * UNREF env)
+jboolean JNICALL ExceptionCheck(JNIEnv * jni_env)
{
TRACE2("jni", "ExceptionCheck called, exception status = " << exn_raised());
assert(hythread_is_suspend_enabled());
- if (exn_raised())
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+
+ if (exn_raised() || vm_env->IsVmShutdowning())
return JNI_TRUE;
else
return JNI_FALSE;
}
-VMEXPORT jmethodID JNICALL FromReflectedMethod(JNIEnv *env, jobject method)
+VMEXPORT jmethodID JNICALL FromReflectedMethod(JNIEnv * jni_env, jobject method)
{
TRACE2("jni", "FromReflectedMethod called");
Class* clss = jobject_to_struct_Class(method);
- if (clss == VM_Global_State::loader_env->java_lang_reflect_Constructor_Class)
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
+
+ if (clss == vm_env->java_lang_reflect_Constructor_Class)
{
static jmethodID m = (jmethodID)class_lookup_method(clss, "getId", "()J");
- return (jmethodID) ((POINTER_SIZE_INT) CallLongMethodA(env, method, m, 0));
+ return (jmethodID) ((POINTER_SIZE_INT) CallLongMethodA(jni_env, method, m, 0));
}
- else if (clss == VM_Global_State::loader_env->java_lang_reflect_Method_Class)
+ else if (clss == vm_env->java_lang_reflect_Method_Class)
{
static jmethodID m = (jmethodID)class_lookup_method(clss, "getId", "()J");
- return (jmethodID) ((POINTER_SIZE_INT) CallLongMethodA(env, method, m, 0));
+ return (jmethodID) ((POINTER_SIZE_INT) CallLongMethodA(jni_env, method, m, 0));
}
- else
- return NULL;
+ return NULL;
}
-VMEXPORT jfieldID JNICALL FromReflectedField(JNIEnv *env, jobject field)
+VMEXPORT jfieldID JNICALL FromReflectedField(JNIEnv * jni_env, jobject field)
{
TRACE2("jni", "FromReflectedField called");
Class* clss = jobject_to_struct_Class(field);
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
- if (clss == VM_Global_State::loader_env->java_lang_reflect_Field_Class)
+ if (clss == vm_env->java_lang_reflect_Field_Class)
{
static jmethodID m = (jmethodID)class_lookup_method(clss, "getId", "()J");
- return (jfieldID) ((POINTER_SIZE_INT) CallLongMethodA(env, field, m, 0));
+ return (jfieldID) ((POINTER_SIZE_INT) CallLongMethodA(jni_env, field, m, 0));
}
- else
- return NULL;
+ return NULL;
}
-VMEXPORT jobject JNICALL ToReflectedMethod(JNIEnv *env, jclass UNREF cls, jmethodID methodID,
+VMEXPORT jobject JNICALL ToReflectedMethod(JNIEnv * jni_env, jclass UNREF cls, jmethodID methodID,
jboolean isStatic)
{
TRACE2("jni", "ToReflectedMethod called");
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
Method *m = (Method*)methodID;
- if ((bool)m->is_static() != (bool)isStatic) // True if flags are different
+ // True if flags are different
+ if ((bool)m->is_static() != (bool)isStatic || vm_env->IsVmShutdowning())
return NULL;
if (m->is_init())
- return reflection_reflect_constructor(env, m);
+ return reflection_reflect_constructor(jni_env, m);
else
- return reflection_reflect_method(env, m);
+ return reflection_reflect_method(jni_env, m);
}
-VMEXPORT jobject JNICALL ToReflectedField(JNIEnv *env, jclass UNREF cls, jfieldID fieldID,
+VMEXPORT jobject JNICALL ToReflectedField(JNIEnv * jni_env, jclass UNREF cls, jfieldID fieldID,
jboolean isStatic)
{
TRACE2("jni", "ToReflectedField called");
+
+ Global_Env * vm_env = jni_get_vm_env(jni_env);
Field *f = (Field*)fieldID;
- if ((bool)f->is_static() != (bool)isStatic) // True if flags are different
+ if ((bool)f->is_static() != (bool)isStatic || vm_env->IsVmShutdowning()) // True if flags are different
return NULL;
- return reflection_reflect_field(env, fieldID);
+ return reflection_reflect_field(jni_env, fieldID);
}
jobject JNICALL NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity)
@@ -1727,7 +1797,6 @@
assert(hythread_is_suspend_enabled());
}
-
void unsafe_global_object_handles_init(JNIEnv * jni_env) {
assert(!hythread_is_suspend_enabled());
tmn_suspend_enable();
@@ -1740,7 +1809,7 @@
jfieldID NEGATIVE_INFINITY_id = jni_env->GetStaticFieldID((jclass)gh_jldouble, "NEGATIVE_INFINITY", "D");
gc_double_NEGATIVE_INFINITY = jni_env->GetStaticDoubleField((jclass)gh_jldouble, NEGATIVE_INFINITY_id);
assert(hythread_is_suspend_enabled());
- check_for_unexpected_exception();
- assert(hythread_is_suspend_enabled());
+ check_for_unexpected_exception();
+ assert(hythread_is_suspend_enabled());
tmn_suspend_disable();
}