comparison src/share/vm/runtime/arguments.cpp @ 6197:d2a62e0f25eb

6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents cdeda3fd141e
children 24b9c7f4cae6
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
33 #include "prims/jvmtiExport.hpp" 33 #include "prims/jvmtiExport.hpp"
34 #include "runtime/arguments.hpp" 34 #include "runtime/arguments.hpp"
35 #include "runtime/globals_extension.hpp" 35 #include "runtime/globals_extension.hpp"
36 #include "runtime/java.hpp" 36 #include "runtime/java.hpp"
37 #include "services/management.hpp" 37 #include "services/management.hpp"
38 #include "services/memTracker.hpp"
38 #include "utilities/defaultStream.hpp" 39 #include "utilities/defaultStream.hpp"
39 #include "utilities/taskqueue.hpp" 40 #include "utilities/taskqueue.hpp"
40 #ifdef TARGET_OS_FAMILY_linux 41 #ifdef TARGET_OS_FAMILY_linux
41 # include "os_linux.inline.hpp" 42 # include "os_linux.inline.hpp"
42 #endif 43 #endif
366 } 367 }
367 368
368 inline void SysClassPath::reset_item_at(int index) { 369 inline void SysClassPath::reset_item_at(int index) {
369 assert(index < _scp_nitems && index != _scp_base, "just checking"); 370 assert(index < _scp_nitems && index != _scp_base, "just checking");
370 if (_items[index] != NULL) { 371 if (_items[index] != NULL) {
371 FREE_C_HEAP_ARRAY(char, _items[index]); 372 FREE_C_HEAP_ARRAY(char, _items[index], mtInternal);
372 _items[index] = NULL; 373 _items[index] = NULL;
373 } 374 }
374 } 375 }
375 376
376 inline void SysClassPath::reset_path(const char* base) { 377 inline void SysClassPath::reset_path(const char* base) {
398 const char* tmp_end = strchr(path, separator); 399 const char* tmp_end = strchr(path, separator);
399 if (tmp_end == NULL) { 400 if (tmp_end == NULL) {
400 expanded_path = add_jars_to_path(expanded_path, path); 401 expanded_path = add_jars_to_path(expanded_path, path);
401 path = end; 402 path = end;
402 } else { 403 } else {
403 char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1); 404 char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
404 memcpy(dirpath, path, tmp_end - path); 405 memcpy(dirpath, path, tmp_end - path);
405 dirpath[tmp_end - path] = '\0'; 406 dirpath[tmp_end - path] = '\0';
406 expanded_path = add_jars_to_path(expanded_path, dirpath); 407 expanded_path = add_jars_to_path(expanded_path, dirpath);
407 FREE_C_HEAP_ARRAY(char, dirpath); 408 FREE_C_HEAP_ARRAY(char, dirpath, mtInternal);
408 path = tmp_end + 1; 409 path = tmp_end + 1;
409 } 410 }
410 } 411 }
411 _items[_scp_endorsed] = expanded_path; 412 _items[_scp_endorsed] = expanded_path;
412 DEBUG_ONLY(_expansion_done = true;) 413 DEBUG_ONLY(_expansion_done = true;)
433 } 434 }
434 } 435 }
435 assert(total_len > 0, "empty sysclasspath not allowed"); 436 assert(total_len > 0, "empty sysclasspath not allowed");
436 437
437 // Copy the _items to a single string. 438 // Copy the _items to a single string.
438 char* cp = NEW_C_HEAP_ARRAY(char, total_len); 439 char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtInternal);
439 char* cp_tmp = cp; 440 char* cp_tmp = cp;
440 for (i = 0; i < _scp_nitems; ++i) { 441 for (i = 0; i < _scp_nitems; ++i) {
441 if (_items[i] != NULL) { 442 if (_items[i] != NULL) {
442 memcpy(cp_tmp, _items[i], lengths[i]); 443 memcpy(cp_tmp, _items[i], lengths[i]);
443 cp_tmp += lengths[i]; 444 cp_tmp += lengths[i];
454 char *cp; 455 char *cp;
455 456
456 assert(str != NULL, "just checking"); 457 assert(str != NULL, "just checking");
457 if (path == NULL) { 458 if (path == NULL) {
458 size_t len = strlen(str) + 1; 459 size_t len = strlen(str) + 1;
459 cp = NEW_C_HEAP_ARRAY(char, len); 460 cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
460 memcpy(cp, str, len); // copy the trailing null 461 memcpy(cp, str, len); // copy the trailing null
461 } else { 462 } else {
462 const char separator = *os::path_separator(); 463 const char separator = *os::path_separator();
463 size_t old_len = strlen(path); 464 size_t old_len = strlen(path);
464 size_t str_len = strlen(str); 465 size_t str_len = strlen(str);
465 size_t len = old_len + str_len + 2; 466 size_t len = old_len + str_len + 2;
466 467
467 if (prepend) { 468 if (prepend) {
468 cp = NEW_C_HEAP_ARRAY(char, len); 469 cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
469 char* cp_tmp = cp; 470 char* cp_tmp = cp;
470 memcpy(cp_tmp, str, str_len); 471 memcpy(cp_tmp, str, str_len);
471 cp_tmp += str_len; 472 cp_tmp += str_len;
472 *cp_tmp = separator; 473 *cp_tmp = separator;
473 memcpy(++cp_tmp, path, old_len + 1); // copy the trailing null 474 memcpy(++cp_tmp, path, old_len + 1); // copy the trailing null
474 FREE_C_HEAP_ARRAY(char, path); 475 FREE_C_HEAP_ARRAY(char, path, mtInternal);
475 } else { 476 } else {
476 cp = REALLOC_C_HEAP_ARRAY(char, path, len); 477 cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtInternal);
477 char* cp_tmp = cp + old_len; 478 char* cp_tmp = cp + old_len;
478 *cp_tmp = separator; 479 *cp_tmp = separator;
479 memcpy(++cp_tmp, str, str_len + 1); // copy the trailing null 480 memcpy(++cp_tmp, str, str_len + 1); // copy the trailing null
480 } 481 }
481 } 482 }
493 const char fileSep = *os::file_separator(); 494 const char fileSep = *os::file_separator();
494 if (directory[directory_len - 1] != fileSep) dir_sep[0] = fileSep; 495 if (directory[directory_len - 1] != fileSep) dir_sep[0] = fileSep;
495 496
496 /* Scan the directory for jars/zips, appending them to path. */ 497 /* Scan the directory for jars/zips, appending them to path. */
497 struct dirent *entry; 498 struct dirent *entry;
498 char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory)); 499 char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
499 while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) { 500 while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
500 const char* name = entry->d_name; 501 const char* name = entry->d_name;
501 const char* ext = name + strlen(name) - 4; 502 const char* ext = name + strlen(name) - 4;
502 bool isJarOrZip = ext > name && 503 bool isJarOrZip = ext > name &&
503 (os::file_name_strcmp(ext, ".jar") == 0 || 504 (os::file_name_strcmp(ext, ".jar") == 0 ||
504 os::file_name_strcmp(ext, ".zip") == 0); 505 os::file_name_strcmp(ext, ".zip") == 0);
505 if (isJarOrZip) { 506 if (isJarOrZip) {
506 char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name)); 507 char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtInternal);
507 sprintf(jarpath, "%s%s%s", directory, dir_sep, name); 508 sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
508 path = add_to_path(path, jarpath, false); 509 path = add_to_path(path, jarpath, false);
509 FREE_C_HEAP_ARRAY(char, jarpath); 510 FREE_C_HEAP_ARRAY(char, jarpath, mtInternal);
510 } 511 }
511 } 512 }
512 FREE_C_HEAP_ARRAY(char, dbuf); 513 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
513 os::closedir(dir); 514 os::closedir(dir);
514 return path; 515 return path;
515 } 516 }
516 517
517 // Parses a memory size specification string. 518 // Parses a memory size specification string.
629 } 630 }
630 631
631 static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) { 632 static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) {
632 if (!CommandLineFlags::ccstrAtPut(name, &value, origin)) return false; 633 if (!CommandLineFlags::ccstrAtPut(name, &value, origin)) return false;
633 // Contract: CommandLineFlags always returns a pointer that needs freeing. 634 // Contract: CommandLineFlags always returns a pointer that needs freeing.
634 FREE_C_HEAP_ARRAY(char, value); 635 FREE_C_HEAP_ARRAY(char, value, mtInternal);
635 return true; 636 return true;
636 } 637 }
637 638
638 static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) { 639 static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) {
639 const char* old_value = ""; 640 const char* old_value = "";
645 if (old_len == 0) { 646 if (old_len == 0) {
646 value = new_value; 647 value = new_value;
647 } else if (new_len == 0) { 648 } else if (new_len == 0) {
648 value = old_value; 649 value = old_value;
649 } else { 650 } else {
650 char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1); 651 char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtInternal);
651 // each new setting adds another LINE to the switch: 652 // each new setting adds another LINE to the switch:
652 sprintf(buf, "%s\n%s", old_value, new_value); 653 sprintf(buf, "%s\n%s", old_value, new_value);
653 value = buf; 654 value = buf;
654 free_this_too = buf; 655 free_this_too = buf;
655 } 656 }
656 (void) CommandLineFlags::ccstrAtPut(name, &value, origin); 657 (void) CommandLineFlags::ccstrAtPut(name, &value, origin);
657 // CommandLineFlags always returns a pointer that needs freeing. 658 // CommandLineFlags always returns a pointer that needs freeing.
658 FREE_C_HEAP_ARRAY(char, value); 659 FREE_C_HEAP_ARRAY(char, value, mtInternal);
659 if (free_this_too != NULL) { 660 if (free_this_too != NULL) {
660 // CommandLineFlags made its own copy, so I must delete my own temp. buffer. 661 // CommandLineFlags made its own copy, so I must delete my own temp. buffer.
661 FREE_C_HEAP_ARRAY(char, free_this_too); 662 FREE_C_HEAP_ARRAY(char, free_this_too, mtInternal);
662 } 663 }
663 return true; 664 return true;
664 } 665 }
665 666
666 bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) { 667 bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) {
733 int index = *count; 734 int index = *count;
734 735
735 // expand the array and add arg to the last element 736 // expand the array and add arg to the last element
736 (*count)++; 737 (*count)++;
737 if (*bldarray == NULL) { 738 if (*bldarray == NULL) {
738 *bldarray = NEW_C_HEAP_ARRAY(char*, *count); 739 *bldarray = NEW_C_HEAP_ARRAY(char*, *count, mtInternal);
739 } else { 740 } else {
740 *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, *count); 741 *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, *count, mtInternal);
741 } 742 }
742 (*bldarray)[index] = strdup(arg); 743 (*bldarray)[index] = strdup(arg);
743 } 744 }
744 745
745 void Arguments::build_jvm_args(const char* arg) { 746 void Arguments::build_jvm_args(const char* arg) {
915 // ns must be static--its address may be stored in a SystemProperty object. 916 // ns must be static--its address may be stored in a SystemProperty object.
916 const static char ns[1] = {0}; 917 const static char ns[1] = {0};
917 char* value = (char *)ns; 918 char* value = (char *)ns;
918 919
919 size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop); 920 size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop);
920 key = AllocateHeap(key_len + 1, "add_property"); 921 key = AllocateHeap(key_len + 1, mtInternal);
921 strncpy(key, prop, key_len); 922 strncpy(key, prop, key_len);
922 key[key_len] = '\0'; 923 key[key_len] = '\0';
923 924
924 if (eq != NULL) { 925 if (eq != NULL) {
925 size_t value_len = strlen(prop) - key_len - 1; 926 size_t value_len = strlen(prop) - key_len - 1;
926 value = AllocateHeap(value_len + 1, "add_property"); 927 value = AllocateHeap(value_len + 1, mtInternal);
927 strncpy(value, &prop[key_len + 1], value_len + 1); 928 strncpy(value, &prop[key_len + 1], value_len + 1);
928 } 929 }
929 930
930 if (strcmp(key, "java.compiler") == 0) { 931 if (strcmp(key, "java.compiler") == 0) {
931 process_java_compiler_argument(value); 932 process_java_compiler_argument(value);
2056 // prefix and the default bootclasspath. os::set_boot_path() 2057 // prefix and the default bootclasspath. os::set_boot_path()
2057 // uses meta_index_dir as the default bootclasspath directory. 2058 // uses meta_index_dir as the default bootclasspath directory.
2058 const char* altclasses_jar = "alt-rt.jar"; 2059 const char* altclasses_jar = "alt-rt.jar";
2059 size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 + 2060 size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 +
2060 strlen(altclasses_jar); 2061 strlen(altclasses_jar);
2061 char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len); 2062 char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len, mtInternal);
2062 strcpy(altclasses_path, get_meta_index_dir()); 2063 strcpy(altclasses_path, get_meta_index_dir());
2063 strcat(altclasses_path, altclasses_jar); 2064 strcat(altclasses_path, altclasses_jar);
2064 scp.add_suffix_to_prefix(altclasses_path); 2065 scp.add_suffix_to_prefix(altclasses_path);
2065 scp_assembly_required = true; 2066 scp_assembly_required = true;
2066 FREE_C_HEAP_ARRAY(char, altclasses_path); 2067 FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal);
2067 } 2068 }
2068 2069
2069 if (WhiteBoxAPI) { 2070 if (WhiteBoxAPI) {
2070 // Append wb.jar to bootclasspath if enabled 2071 // Append wb.jar to bootclasspath if enabled
2071 const char* wb_jar = "wb.jar"; 2072 const char* wb_jar = "wb.jar";
2072 size_t wb_path_len = strlen(get_meta_index_dir()) + 1 + 2073 size_t wb_path_len = strlen(get_meta_index_dir()) + 1 +
2073 strlen(wb_jar); 2074 strlen(wb_jar);
2074 char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len); 2075 char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len, mtInternal);
2075 strcpy(wb_path, get_meta_index_dir()); 2076 strcpy(wb_path, get_meta_index_dir());
2076 strcat(wb_path, wb_jar); 2077 strcat(wb_path, wb_jar);
2077 scp.add_suffix(wb_path); 2078 scp.add_suffix(wb_path);
2078 scp_assembly_required = true; 2079 scp_assembly_required = true;
2079 FREE_C_HEAP_ARRAY(char, wb_path); 2080 FREE_C_HEAP_ARRAY(char, wb_path, mtInternal);
2080 } 2081 }
2081 2082
2082 // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) 2083 // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
2083 result = parse_java_options_environment_variable(&scp, &scp_assembly_required); 2084 result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
2084 if (result != JNI_OK) { 2085 if (result != JNI_OK) {
2159 // -Xrun 2160 // -Xrun
2160 } else if (match_option(option, "-Xrun", &tail)) { 2161 } else if (match_option(option, "-Xrun", &tail)) {
2161 if (tail != NULL) { 2162 if (tail != NULL) {
2162 const char* pos = strchr(tail, ':'); 2163 const char* pos = strchr(tail, ':');
2163 size_t len = (pos == NULL) ? strlen(tail) : pos - tail; 2164 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2164 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len); 2165 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
2165 name[len] = '\0'; 2166 name[len] = '\0';
2166 2167
2167 char *options = NULL; 2168 char *options = NULL;
2168 if(pos != NULL) { 2169 if(pos != NULL) {
2169 size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied. 2170 size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied.
2170 options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2), pos+1, len2); 2171 options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtInternal), pos+1, len2);
2171 } 2172 }
2172 #ifdef JVMTI_KERNEL 2173 #ifdef JVMTI_KERNEL
2173 if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { 2174 if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
2174 warning("profiling and debugging agents are not supported with Kernel VM"); 2175 warning("profiling and debugging agents are not supported with Kernel VM");
2175 } else 2176 } else
2180 } else if (match_option(option, "-agentlib:", &tail) || 2181 } else if (match_option(option, "-agentlib:", &tail) ||
2181 (is_absolute_path = match_option(option, "-agentpath:", &tail))) { 2182 (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2182 if(tail != NULL) { 2183 if(tail != NULL) {
2183 const char* pos = strchr(tail, '='); 2184 const char* pos = strchr(tail, '=');
2184 size_t len = (pos == NULL) ? strlen(tail) : pos - tail; 2185 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2185 char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len); 2186 char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
2186 name[len] = '\0'; 2187 name[len] = '\0';
2187 2188
2188 char *options = NULL; 2189 char *options = NULL;
2189 if(pos != NULL) { 2190 if(pos != NULL) {
2190 options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1), pos + 1); 2191 options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1, mtInternal), pos + 1);
2191 } 2192 }
2192 #ifdef JVMTI_KERNEL 2193 #ifdef JVMTI_KERNEL
2193 if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { 2194 if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
2194 warning("profiling and debugging agents are not supported with Kernel VM"); 2195 warning("profiling and debugging agents are not supported with Kernel VM");
2195 } else 2196 } else
2198 2199
2199 } 2200 }
2200 // -javaagent 2201 // -javaagent
2201 } else if (match_option(option, "-javaagent:", &tail)) { 2202 } else if (match_option(option, "-javaagent:", &tail)) {
2202 if(tail != NULL) { 2203 if(tail != NULL) {
2203 char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1), tail); 2204 char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
2204 add_init_agent("instrument", options, false); 2205 add_init_agent("instrument", options, false);
2205 } 2206 }
2206 // -Xnoclassgc 2207 // -Xnoclassgc
2207 } else if (match_option(option, "-Xnoclassgc", &tail)) { 2208 } else if (match_option(option, "-Xnoclassgc", &tail)) {
2208 FLAG_SET_CMDLINE(bool, ClassUnloading, false); 2209 FLAG_SET_CMDLINE(bool, ClassUnloading, false);
2956 char jvm_path[JVM_MAXPATHLEN]; 2957 char jvm_path[JVM_MAXPATHLEN];
2957 os::jvm_path(jvm_path, sizeof(jvm_path)); 2958 os::jvm_path(jvm_path, sizeof(jvm_path));
2958 char *end = strrchr(jvm_path, *os::file_separator()); 2959 char *end = strrchr(jvm_path, *os::file_separator());
2959 if (end != NULL) *end = '\0'; 2960 if (end != NULL) *end = '\0';
2960 char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) + 2961 char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) +
2961 strlen(os::file_separator()) + 20); 2962 strlen(os::file_separator()) + 20, mtInternal);
2962 if (shared_archive_path == NULL) return JNI_ENOMEM; 2963 if (shared_archive_path == NULL) return JNI_ENOMEM;
2963 strcpy(shared_archive_path, jvm_path); 2964 strcpy(shared_archive_path, jvm_path);
2964 strcat(shared_archive_path, os::file_separator()); 2965 strcat(shared_archive_path, os::file_separator());
2965 strcat(shared_archive_path, "classes"); 2966 strcat(shared_archive_path, "classes");
2966 DEBUG_ONLY(strcat(shared_archive_path, "_g");) 2967 DEBUG_ONLY(strcat(shared_archive_path, "_g");)
2994 } 2995 }
2995 if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) { 2996 if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) {
2996 CommandLineFlags::printFlags(tty, false); 2997 CommandLineFlags::printFlags(tty, false);
2997 vm_exit(0); 2998 vm_exit(0);
2998 } 2999 }
3000 if (match_option(option, "-XX:NativeMemoryTracking", &tail)) {
3001 MemTracker::init_tracking_options(tail);
3002 }
3003
2999 3004
3000 #ifndef PRODUCT 3005 #ifndef PRODUCT
3001 if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) { 3006 if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
3002 CommandLineFlags::printFlags(tty, true); 3007 CommandLineFlags::printFlags(tty, true);
3003 vm_exit(0); 3008 vm_exit(0);
3329 if (strncmp(prop->key(), "kernel.", 7 ) == 0) { 3334 if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
3330 length += (strlen(prop->key()) + strlen(prop->value()) + 5); // "-D =" 3335 length += (strlen(prop->key()) + strlen(prop->value()) + 5); // "-D ="
3331 } 3336 }
3332 } 3337 }
3333 // Add one for null terminator. 3338 // Add one for null terminator.
3334 char *props = AllocateHeap(length + 1, "get_kernel_properties"); 3339 char *props = AllocateHeap(length + 1, mtInternal);
3335 if (length != 0) { 3340 if (length != 0) {
3336 int pos = 0; 3341 int pos = 0;
3337 for (prop = _system_properties; prop != NULL; prop = prop->next()) { 3342 for (prop = _system_properties; prop != NULL; prop = prop->next()) {
3338 if (strncmp(prop->key(), "kernel.", 7 ) == 0) { 3343 if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
3339 jio_snprintf(&props[pos], length-pos, 3344 jio_snprintf(&props[pos], length-pos,