Mercurial > hg > truffle
comparison src/os/bsd/vm/perfMemory_bsd.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 | f08d439fab8c |
children | b9a9ed0f8eeb |
comparison
equal
deleted
inserted
replaced
6174:74533f63b116 | 6197:d2a62e0f25eb |
---|---|
124 if (result == OS_ERR) { | 124 if (result == OS_ERR) { |
125 warning("Could not close %s: %s\n", destfile, strerror(errno)); | 125 warning("Could not close %s: %s\n", destfile, strerror(errno)); |
126 } | 126 } |
127 } | 127 } |
128 } | 128 } |
129 FREE_C_HEAP_ARRAY(char, destfile); | 129 FREE_C_HEAP_ARRAY(char, destfile, mtInternal); |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 // Shared Memory Implementation Details | 133 // Shared Memory Implementation Details |
134 | 134 |
151 static char* get_user_tmp_dir(const char* user) { | 151 static char* get_user_tmp_dir(const char* user) { |
152 | 152 |
153 const char* tmpdir = os::get_temp_directory(); | 153 const char* tmpdir = os::get_temp_directory(); |
154 const char* perfdir = PERFDATA_NAME; | 154 const char* perfdir = PERFDATA_NAME; |
155 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; | 155 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; |
156 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes); | 156 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
157 | 157 |
158 // construct the path name to user specific tmp directory | 158 // construct the path name to user specific tmp directory |
159 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); | 159 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); |
160 | 160 |
161 return dirname; | 161 return dirname; |
244 // | 244 // |
245 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); | 245 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); |
246 if (bufsize == -1) | 246 if (bufsize == -1) |
247 bufsize = 1024; | 247 bufsize = 1024; |
248 | 248 |
249 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize); | 249 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); |
250 | 250 |
251 // POSIX interface to getpwuid_r is used on LINUX | 251 // POSIX interface to getpwuid_r is used on LINUX |
252 struct passwd* p; | 252 struct passwd* p; |
253 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); | 253 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); |
254 | 254 |
276 warning("Could not determine user name: %s\n", | 276 warning("Could not determine user name: %s\n", |
277 p->pw_name == NULL ? "pw_name = NULL" : | 277 p->pw_name == NULL ? "pw_name = NULL" : |
278 "pw_name zero length"); | 278 "pw_name zero length"); |
279 } | 279 } |
280 } | 280 } |
281 FREE_C_HEAP_ARRAY(char, pwbuf); | 281 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); |
282 return NULL; | 282 return NULL; |
283 } | 283 } |
284 | 284 |
285 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1); | 285 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal); |
286 strcpy(user_name, p->pw_name); | 286 strcpy(user_name, p->pw_name); |
287 | 287 |
288 FREE_C_HEAP_ARRAY(char, pwbuf); | 288 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); |
289 return user_name; | 289 return user_name; |
290 } | 290 } |
291 | 291 |
292 // return the name of the user that owns the process identified by vmid. | 292 // return the name of the user that owns the process identified by vmid. |
293 // | 293 // |
326 // open the directory and check if the file for the given vmid exists. | 326 // open the directory and check if the file for the given vmid exists. |
327 // The file with the expected name and the latest creation date is used | 327 // The file with the expected name and the latest creation date is used |
328 // to determine the user name for the process id. | 328 // to determine the user name for the process id. |
329 // | 329 // |
330 struct dirent* dentry; | 330 struct dirent* dentry; |
331 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname)); | 331 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); |
332 errno = 0; | 332 errno = 0; |
333 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { | 333 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { |
334 | 334 |
335 // check if the directory entry is a hsperfdata file | 335 // check if the directory entry is a hsperfdata file |
336 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { | 336 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { |
337 continue; | 337 continue; |
338 } | 338 } |
339 | 339 |
340 char* usrdir_name = NEW_C_HEAP_ARRAY(char, | 340 char* usrdir_name = NEW_C_HEAP_ARRAY(char, |
341 strlen(tmpdirname) + strlen(dentry->d_name) + 2); | 341 strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal); |
342 strcpy(usrdir_name, tmpdirname); | 342 strcpy(usrdir_name, tmpdirname); |
343 strcat(usrdir_name, "/"); | 343 strcat(usrdir_name, "/"); |
344 strcat(usrdir_name, dentry->d_name); | 344 strcat(usrdir_name, dentry->d_name); |
345 | 345 |
346 DIR* subdirp = os::opendir(usrdir_name); | 346 DIR* subdirp = os::opendir(usrdir_name); |
347 | 347 |
348 if (subdirp == NULL) { | 348 if (subdirp == NULL) { |
349 FREE_C_HEAP_ARRAY(char, usrdir_name); | 349 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); |
350 continue; | 350 continue; |
351 } | 351 } |
352 | 352 |
353 // Since we don't create the backing store files in directories | 353 // Since we don't create the backing store files in directories |
354 // pointed to by symbolic links, we also don't follow them when | 354 // pointed to by symbolic links, we also don't follow them when |
355 // looking for the files. We check for a symbolic link after the | 355 // looking for the files. We check for a symbolic link after the |
356 // call to opendir in order to eliminate a small window where the | 356 // call to opendir in order to eliminate a small window where the |
357 // symlink can be exploited. | 357 // symlink can be exploited. |
358 // | 358 // |
359 if (!is_directory_secure(usrdir_name)) { | 359 if (!is_directory_secure(usrdir_name)) { |
360 FREE_C_HEAP_ARRAY(char, usrdir_name); | 360 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); |
361 os::closedir(subdirp); | 361 os::closedir(subdirp); |
362 continue; | 362 continue; |
363 } | 363 } |
364 | 364 |
365 struct dirent* udentry; | 365 struct dirent* udentry; |
366 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name)); | 366 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); |
367 errno = 0; | 367 errno = 0; |
368 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { | 368 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { |
369 | 369 |
370 if (filename_to_pid(udentry->d_name) == vmid) { | 370 if (filename_to_pid(udentry->d_name) == vmid) { |
371 struct stat statbuf; | 371 struct stat statbuf; |
372 int result; | 372 int result; |
373 | 373 |
374 char* filename = NEW_C_HEAP_ARRAY(char, | 374 char* filename = NEW_C_HEAP_ARRAY(char, |
375 strlen(usrdir_name) + strlen(udentry->d_name) + 2); | 375 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal); |
376 | 376 |
377 strcpy(filename, usrdir_name); | 377 strcpy(filename, usrdir_name); |
378 strcat(filename, "/"); | 378 strcat(filename, "/"); |
379 strcat(filename, udentry->d_name); | 379 strcat(filename, udentry->d_name); |
380 | 380 |
381 // don't follow symbolic links for the file | 381 // don't follow symbolic links for the file |
382 RESTARTABLE(::lstat(filename, &statbuf), result); | 382 RESTARTABLE(::lstat(filename, &statbuf), result); |
383 if (result == OS_ERR) { | 383 if (result == OS_ERR) { |
384 FREE_C_HEAP_ARRAY(char, filename); | 384 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
385 continue; | 385 continue; |
386 } | 386 } |
387 | 387 |
388 // skip over files that are not regular files. | 388 // skip over files that are not regular files. |
389 if (!S_ISREG(statbuf.st_mode)) { | 389 if (!S_ISREG(statbuf.st_mode)) { |
390 FREE_C_HEAP_ARRAY(char, filename); | 390 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
391 continue; | 391 continue; |
392 } | 392 } |
393 | 393 |
394 // compare and save filename with latest creation time | 394 // compare and save filename with latest creation time |
395 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { | 395 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { |
396 | 396 |
397 if (statbuf.st_ctime > oldest_ctime) { | 397 if (statbuf.st_ctime > oldest_ctime) { |
398 char* user = strchr(dentry->d_name, '_') + 1; | 398 char* user = strchr(dentry->d_name, '_') + 1; |
399 | 399 |
400 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user); | 400 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal); |
401 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1); | 401 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal); |
402 | 402 |
403 strcpy(oldest_user, user); | 403 strcpy(oldest_user, user); |
404 oldest_ctime = statbuf.st_ctime; | 404 oldest_ctime = statbuf.st_ctime; |
405 } | 405 } |
406 } | 406 } |
407 | 407 |
408 FREE_C_HEAP_ARRAY(char, filename); | 408 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
409 } | 409 } |
410 } | 410 } |
411 os::closedir(subdirp); | 411 os::closedir(subdirp); |
412 FREE_C_HEAP_ARRAY(char, udbuf); | 412 FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); |
413 FREE_C_HEAP_ARRAY(char, usrdir_name); | 413 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); |
414 } | 414 } |
415 os::closedir(tmpdirp); | 415 os::closedir(tmpdirp); |
416 FREE_C_HEAP_ARRAY(char, tdbuf); | 416 FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); |
417 | 417 |
418 return(oldest_user); | 418 return(oldest_user); |
419 } | 419 } |
420 | 420 |
421 // return the name of the user that owns the JVM indicated by the given vmid. | 421 // return the name of the user that owns the JVM indicated by the given vmid. |
432 static char* get_sharedmem_filename(const char* dirname, int vmid) { | 432 static char* get_sharedmem_filename(const char* dirname, int vmid) { |
433 | 433 |
434 // add 2 for the file separator and a null terminator. | 434 // add 2 for the file separator and a null terminator. |
435 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; | 435 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; |
436 | 436 |
437 char* name = NEW_C_HEAP_ARRAY(char, nbytes); | 437 char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
438 snprintf(name, nbytes, "%s/%d", dirname, vmid); | 438 snprintf(name, nbytes, "%s/%d", dirname, vmid); |
439 | 439 |
440 return name; | 440 return name; |
441 } | 441 } |
442 | 442 |
470 // named directory. | 470 // named directory. |
471 // | 471 // |
472 static void remove_file(const char* dirname, const char* filename) { | 472 static void remove_file(const char* dirname, const char* filename) { |
473 | 473 |
474 size_t nbytes = strlen(dirname) + strlen(filename) + 2; | 474 size_t nbytes = strlen(dirname) + strlen(filename) + 2; |
475 char* path = NEW_C_HEAP_ARRAY(char, nbytes); | 475 char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
476 | 476 |
477 strcpy(path, dirname); | 477 strcpy(path, dirname); |
478 strcat(path, "/"); | 478 strcat(path, "/"); |
479 strcat(path, filename); | 479 strcat(path, filename); |
480 | 480 |
481 remove_file(path); | 481 remove_file(path); |
482 | 482 |
483 FREE_C_HEAP_ARRAY(char, path); | 483 FREE_C_HEAP_ARRAY(char, path, mtInternal); |
484 } | 484 } |
485 | 485 |
486 | 486 |
487 // cleanup stale shared memory resources | 487 // cleanup stale shared memory resources |
488 // | 488 // |
515 // remove or create new files in this directory. The behavior of this | 515 // remove or create new files in this directory. The behavior of this |
516 // loop under these conditions is dependent upon the implementation of | 516 // loop under these conditions is dependent upon the implementation of |
517 // opendir/readdir. | 517 // opendir/readdir. |
518 // | 518 // |
519 struct dirent* entry; | 519 struct dirent* entry; |
520 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname)); | 520 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); |
521 errno = 0; | 521 errno = 0; |
522 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { | 522 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { |
523 | 523 |
524 pid_t pid = filename_to_pid(entry->d_name); | 524 pid_t pid = filename_to_pid(entry->d_name); |
525 | 525 |
554 remove_file(dirname, entry->d_name); | 554 remove_file(dirname, entry->d_name); |
555 } | 555 } |
556 errno = 0; | 556 errno = 0; |
557 } | 557 } |
558 os::closedir(dirp); | 558 os::closedir(dirp); |
559 FREE_C_HEAP_ARRAY(char, dbuf); | 559 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); |
560 } | 560 } |
561 | 561 |
562 // make the user specific temporary directory. Returns true if | 562 // make the user specific temporary directory. Returns true if |
563 // the directory exists and is secure upon return. Returns false | 563 // the directory exists and is secure upon return. Returns false |
564 // if the directory exists but is either a symlink, is otherwise | 564 // if the directory exists but is either a symlink, is otherwise |
721 assert(((size > 0) && (size % os::vm_page_size() == 0)), | 721 assert(((size > 0) && (size % os::vm_page_size() == 0)), |
722 "unexpected PerfMemory region size"); | 722 "unexpected PerfMemory region size"); |
723 | 723 |
724 fd = create_sharedmem_resources(dirname, filename, size); | 724 fd = create_sharedmem_resources(dirname, filename, size); |
725 | 725 |
726 FREE_C_HEAP_ARRAY(char, user_name); | 726 FREE_C_HEAP_ARRAY(char, user_name, mtInternal); |
727 FREE_C_HEAP_ARRAY(char, dirname); | 727 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); |
728 | 728 |
729 if (fd == -1) { | 729 if (fd == -1) { |
730 FREE_C_HEAP_ARRAY(char, filename); | 730 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
731 return NULL; | 731 return NULL; |
732 } | 732 } |
733 | 733 |
734 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | 734 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); |
735 | 735 |
741 if (mapAddress == MAP_FAILED) { | 741 if (mapAddress == MAP_FAILED) { |
742 if (PrintMiscellaneous && Verbose) { | 742 if (PrintMiscellaneous && Verbose) { |
743 warning("mmap failed - %s\n", strerror(errno)); | 743 warning("mmap failed - %s\n", strerror(errno)); |
744 } | 744 } |
745 remove_file(filename); | 745 remove_file(filename); |
746 FREE_C_HEAP_ARRAY(char, filename); | 746 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
747 return NULL; | 747 return NULL; |
748 } | 748 } |
749 | 749 |
750 // save the file name for use in delete_shared_memory() | 750 // save the file name for use in delete_shared_memory() |
751 backing_store_file_name = filename; | 751 backing_store_file_name = filename; |
867 | 867 |
868 // since we don't follow symbolic links when creating the backing | 868 // since we don't follow symbolic links when creating the backing |
869 // store file, we don't follow them when attaching either. | 869 // store file, we don't follow them when attaching either. |
870 // | 870 // |
871 if (!is_directory_secure(dirname)) { | 871 if (!is_directory_secure(dirname)) { |
872 FREE_C_HEAP_ARRAY(char, dirname); | 872 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); |
873 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | 873 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
874 "Process not found"); | 874 "Process not found"); |
875 } | 875 } |
876 | 876 |
877 char* filename = get_sharedmem_filename(dirname, vmid); | 877 char* filename = get_sharedmem_filename(dirname, vmid); |
882 // would otherwise occur. | 882 // would otherwise occur. |
883 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); | 883 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); |
884 strcpy(rfilename, filename); | 884 strcpy(rfilename, filename); |
885 | 885 |
886 // free the c heap resources that are no longer needed | 886 // free the c heap resources that are no longer needed |
887 if (luser != user) FREE_C_HEAP_ARRAY(char, luser); | 887 if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal); |
888 FREE_C_HEAP_ARRAY(char, dirname); | 888 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); |
889 FREE_C_HEAP_ARRAY(char, filename); | 889 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
890 | 890 |
891 // open the shared memory file for the give vmid | 891 // open the shared memory file for the give vmid |
892 fd = open_sharedmem_file(rfilename, file_flags, CHECK); | 892 fd = open_sharedmem_file(rfilename, file_flags, CHECK); |
893 assert(fd != OS_ERR, "unexpected value"); | 893 assert(fd != OS_ERR, "unexpected value"); |
894 | 894 |