Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/os.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 | 94ec88ca68e2 |
children | 1d7922586cf6 |
comparison
equal
deleted
inserted
replaced
6174:74533f63b116 | 6197:d2a62e0f25eb |
---|---|
43 #include "runtime/javaCalls.hpp" | 43 #include "runtime/javaCalls.hpp" |
44 #include "runtime/mutexLocker.hpp" | 44 #include "runtime/mutexLocker.hpp" |
45 #include "runtime/os.hpp" | 45 #include "runtime/os.hpp" |
46 #include "runtime/stubRoutines.hpp" | 46 #include "runtime/stubRoutines.hpp" |
47 #include "services/attachListener.hpp" | 47 #include "services/attachListener.hpp" |
48 #include "services/memTracker.hpp" | |
48 #include "services/threadService.hpp" | 49 #include "services/threadService.hpp" |
49 #include "utilities/defaultStream.hpp" | 50 #include "utilities/defaultStream.hpp" |
50 #include "utilities/events.hpp" | 51 #include "utilities/events.hpp" |
51 #ifdef TARGET_OS_FAMILY_linux | 52 #ifdef TARGET_OS_FAMILY_linux |
52 # include "os_linux.inline.hpp" | 53 # include "os_linux.inline.hpp" |
431 return _native_java_library; | 432 return _native_java_library; |
432 } | 433 } |
433 | 434 |
434 // --------------------- heap allocation utilities --------------------- | 435 // --------------------- heap allocation utilities --------------------- |
435 | 436 |
436 char *os::strdup(const char *str) { | 437 char *os::strdup(const char *str, MEMFLAGS flags) { |
437 size_t size = strlen(str); | 438 size_t size = strlen(str); |
438 char *dup_str = (char *)malloc(size + 1); | 439 char *dup_str = (char *)malloc(size + 1, flags); |
439 if (dup_str == NULL) return NULL; | 440 if (dup_str == NULL) return NULL; |
440 strcpy(dup_str, str); | 441 strcpy(dup_str, str); |
441 return dup_str; | 442 return dup_str; |
442 } | 443 } |
443 | 444 |
557 } | 558 } |
558 } | 559 } |
559 } | 560 } |
560 #endif | 561 #endif |
561 | 562 |
562 void* os::malloc(size_t size) { | 563 void* os::malloc(size_t size, MEMFLAGS memflags, address caller) { |
563 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); | 564 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); |
564 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); | 565 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); |
565 | 566 |
566 if (size == 0) { | 567 if (size == 0) { |
567 // return a valid pointer if size is zero | 568 // return a valid pointer if size is zero |
569 size = 1; | 570 size = 1; |
570 } | 571 } |
571 | 572 |
572 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | 573 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); |
573 u_char* ptr = (u_char*)::malloc(size + space_before + space_after); | 574 u_char* ptr = (u_char*)::malloc(size + space_before + space_after); |
575 | |
574 #ifdef ASSERT | 576 #ifdef ASSERT |
575 if (ptr == NULL) return NULL; | 577 if (ptr == NULL) return NULL; |
576 if (MallocCushion) { | 578 if (MallocCushion) { |
577 for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue; | 579 for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue; |
578 u_char* end = ptr + space_before + size; | 580 u_char* end = ptr + space_before + size; |
587 tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); | 589 tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); |
588 breakpoint(); | 590 breakpoint(); |
589 } | 591 } |
590 debug_only(if (paranoid) verify_block(memblock)); | 592 debug_only(if (paranoid) verify_block(memblock)); |
591 if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); | 593 if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); |
594 | |
595 // we do not track MallocCushion memory | |
596 if (MemTracker::is_on()) { | |
597 MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller); | |
598 } | |
599 | |
592 return memblock; | 600 return memblock; |
593 } | 601 } |
594 | 602 |
595 | 603 |
596 void* os::realloc(void *memblock, size_t size) { | 604 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) { |
597 #ifndef ASSERT | 605 #ifndef ASSERT |
598 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); | 606 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); |
599 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); | 607 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); |
600 return ::realloc(memblock, size); | 608 void* ptr = ::realloc(memblock, size); |
609 if (ptr != NULL && MemTracker::is_on()) { | |
610 MemTracker::record_realloc((address)memblock, (address)ptr, size, memflags, | |
611 caller == 0 ? CALLER_PC : caller); | |
612 } | |
613 return ptr; | |
601 #else | 614 #else |
602 if (memblock == NULL) { | 615 if (memblock == NULL) { |
603 return malloc(size); | 616 return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller)); |
604 } | 617 } |
605 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | 618 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { |
606 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock); | 619 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock); |
607 breakpoint(); | 620 breakpoint(); |
608 } | 621 } |
609 verify_block(memblock); | 622 verify_block(memblock); |
610 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | 623 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); |
611 if (size == 0) return NULL; | 624 if (size == 0) return NULL; |
612 // always move the block | 625 // always move the block |
613 void* ptr = malloc(size); | 626 void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller); |
614 if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); | 627 if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); |
615 // Copy to new memory if malloc didn't fail | 628 // Copy to new memory if malloc didn't fail |
616 if ( ptr != NULL ) { | 629 if ( ptr != NULL ) { |
617 memcpy(ptr, memblock, MIN2(size, get_size(memblock))); | 630 memcpy(ptr, memblock, MIN2(size, get_size(memblock))); |
618 if (paranoid) verify_block(ptr); | 631 if (paranoid) verify_block(ptr); |
625 return ptr; | 638 return ptr; |
626 #endif | 639 #endif |
627 } | 640 } |
628 | 641 |
629 | 642 |
630 void os::free(void *memblock) { | 643 void os::free(void *memblock, MEMFLAGS memflags) { |
631 NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); | 644 NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); |
632 #ifdef ASSERT | 645 #ifdef ASSERT |
633 if (memblock == NULL) return; | 646 if (memblock == NULL) return; |
634 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | 647 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { |
635 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock); | 648 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock); |
658 } else if (PrintMalloc && tty != NULL) { | 671 } else if (PrintMalloc && tty != NULL) { |
659 // tty->print_cr("os::free %p", memblock); | 672 // tty->print_cr("os::free %p", memblock); |
660 fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock); | 673 fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock); |
661 } | 674 } |
662 #endif | 675 #endif |
676 MemTracker::record_free((address)memblock, memflags); | |
677 | |
663 ::free((char*)memblock - space_before); | 678 ::free((char*)memblock - space_before); |
664 } | 679 } |
665 | 680 |
666 void os::init_random(long initval) { | 681 void os::init_random(long initval) { |
667 _rand_seed = initval; | 682 _rand_seed = initval; |
1046 for (p = format_string; *p != 0; ++p) { | 1061 for (p = format_string; *p != 0; ++p) { |
1047 if (*p == '%') formatted_path_len += home_len - 1; | 1062 if (*p == '%') formatted_path_len += home_len - 1; |
1048 ++formatted_path_len; | 1063 ++formatted_path_len; |
1049 } | 1064 } |
1050 | 1065 |
1051 char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1); | 1066 char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1, mtInternal); |
1052 if (formatted_path == NULL) { | 1067 if (formatted_path == NULL) { |
1053 return NULL; | 1068 return NULL; |
1054 } | 1069 } |
1055 | 1070 |
1056 // Create boot classpath from format, substituting separator chars and | 1071 // Create boot classpath from format, substituting separator chars and |
1125 *n = 0; | 1140 *n = 0; |
1126 if (path == NULL || strlen(path) == 0) { | 1141 if (path == NULL || strlen(path) == 0) { |
1127 return NULL; | 1142 return NULL; |
1128 } | 1143 } |
1129 const char psepchar = *os::path_separator(); | 1144 const char psepchar = *os::path_separator(); |
1130 char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1); | 1145 char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal); |
1131 if (inpath == NULL) { | 1146 if (inpath == NULL) { |
1132 return NULL; | 1147 return NULL; |
1133 } | 1148 } |
1134 strncpy(inpath, path, strlen(path)); | 1149 strncpy(inpath, path, strlen(path)); |
1135 int count = 1; | 1150 int count = 1; |
1138 while (p != NULL) { | 1153 while (p != NULL) { |
1139 count++; | 1154 count++; |
1140 p++; | 1155 p++; |
1141 p = strchr(p, psepchar); | 1156 p = strchr(p, psepchar); |
1142 } | 1157 } |
1143 char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count); | 1158 char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal); |
1144 if (opath == NULL) { | 1159 if (opath == NULL) { |
1145 return NULL; | 1160 return NULL; |
1146 } | 1161 } |
1147 | 1162 |
1148 // do the actual splitting | 1163 // do the actual splitting |
1151 size_t len = strcspn(p, os::path_separator()); | 1166 size_t len = strcspn(p, os::path_separator()); |
1152 if (len > JVM_MAXPATHLEN) { | 1167 if (len > JVM_MAXPATHLEN) { |
1153 return NULL; | 1168 return NULL; |
1154 } | 1169 } |
1155 // allocate the string and add terminator storage | 1170 // allocate the string and add terminator storage |
1156 char* s = (char*)NEW_C_HEAP_ARRAY(char, len + 1); | 1171 char* s = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); |
1157 if (s == NULL) { | 1172 if (s == NULL) { |
1158 return NULL; | 1173 return NULL; |
1159 } | 1174 } |
1160 strncpy(s, p, len); | 1175 strncpy(s, p, len); |
1161 s[len] = '\0'; | 1176 s[len] = '\0'; |
1162 opath[i] = s; | 1177 opath[i] = s; |
1163 p += len + 1; | 1178 p += len + 1; |
1164 } | 1179 } |
1165 FREE_C_HEAP_ARRAY(char, inpath); | 1180 FREE_C_HEAP_ARRAY(char, inpath, mtInternal); |
1166 *n = count; | 1181 *n = count; |
1167 return opath; | 1182 return opath; |
1168 } | 1183 } |
1169 | 1184 |
1170 void os::set_memory_serialize_page(address page) { | 1185 void os::set_memory_serialize_page(address page) { |
1364 // return initial part of line that fits in buf. | 1379 // return initial part of line that fits in buf. |
1365 // If we reached EOF, it will be returned on next call. | 1380 // If we reached EOF, it will be returned on next call. |
1366 | 1381 |
1367 return (int) i; | 1382 return (int) i; |
1368 } | 1383 } |
1384 | |
1385 bool os::create_stack_guard_pages(char* addr, size_t bytes) { | |
1386 return os::pd_create_stack_guard_pages(addr, bytes); | |
1387 } | |
1388 | |
1389 | |
1390 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { | |
1391 char* result = pd_reserve_memory(bytes, addr, alignment_hint); | |
1392 if (result != NULL && MemTracker::is_on()) { | |
1393 MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); | |
1394 } | |
1395 | |
1396 return result; | |
1397 } | |
1398 char* os::attempt_reserve_memory_at(size_t bytes, char* addr) { | |
1399 char* result = pd_attempt_reserve_memory_at(bytes, addr); | |
1400 if (result != NULL && MemTracker::is_on()) { | |
1401 MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); | |
1402 } | |
1403 return result; | |
1404 } | |
1405 | |
1406 void os::split_reserved_memory(char *base, size_t size, | |
1407 size_t split, bool realloc) { | |
1408 pd_split_reserved_memory(base, size, split, realloc); | |
1409 } | |
1410 | |
1411 bool os::commit_memory(char* addr, size_t bytes, bool executable) { | |
1412 bool res = pd_commit_memory(addr, bytes, executable); | |
1413 if (res && MemTracker::is_on()) { | |
1414 MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC); | |
1415 } | |
1416 return res; | |
1417 } | |
1418 | |
1419 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, | |
1420 bool executable) { | |
1421 bool res = os::pd_commit_memory(addr, size, alignment_hint, executable); | |
1422 if (res && MemTracker::is_on()) { | |
1423 MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC); | |
1424 } | |
1425 return res; | |
1426 } | |
1427 | |
1428 bool os::uncommit_memory(char* addr, size_t bytes) { | |
1429 bool res = pd_uncommit_memory(addr, bytes); | |
1430 if (res) { | |
1431 MemTracker::record_virtual_memory_uncommit((address)addr, bytes); | |
1432 } | |
1433 return res; | |
1434 } | |
1435 | |
1436 bool os::release_memory(char* addr, size_t bytes) { | |
1437 bool res = pd_release_memory(addr, bytes); | |
1438 if (res) { | |
1439 MemTracker::record_virtual_memory_release((address)addr, bytes); | |
1440 } | |
1441 return res; | |
1442 } | |
1443 | |
1444 | |
1445 char* os::map_memory(int fd, const char* file_name, size_t file_offset, | |
1446 char *addr, size_t bytes, bool read_only, | |
1447 bool allow_exec) { | |
1448 char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec); | |
1449 if (result != NULL && MemTracker::is_on()) { | |
1450 MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); | |
1451 } | |
1452 return result; | |
1453 } | |
1454 | |
1455 char* os::remap_memory(int fd, const char* file_name, size_t file_offset, | |
1456 char *addr, size_t bytes, bool read_only, | |
1457 bool allow_exec) { | |
1458 return pd_remap_memory(fd, file_name, file_offset, addr, bytes, | |
1459 read_only, allow_exec); | |
1460 } | |
1461 | |
1462 bool os::unmap_memory(char *addr, size_t bytes) { | |
1463 bool result = pd_unmap_memory(addr, bytes); | |
1464 if (result) { | |
1465 MemTracker::record_virtual_memory_release((address)addr, bytes); | |
1466 } | |
1467 return result; | |
1468 } | |
1469 | |
1470 void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) { | |
1471 pd_free_memory(addr, bytes, alignment_hint); | |
1472 } | |
1473 | |
1474 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { | |
1475 pd_realign_memory(addr, bytes, alignment_hint); | |
1476 } | |
1477 |