Mercurial > hg > graal-compiler
comparison src/os/solaris/vm/perfMemory_solaris.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 | f95d63e2154a |
children | b9a9ed0f8eeb |
comparison
equal
deleted
inserted
replaced
6174:74533f63b116 | 6197:d2a62e0f25eb |
---|---|
126 if (result == OS_ERR) { | 126 if (result == OS_ERR) { |
127 warning("Could not close %s: %s\n", destfile, strerror(errno)); | 127 warning("Could not close %s: %s\n", destfile, strerror(errno)); |
128 } | 128 } |
129 } | 129 } |
130 } | 130 } |
131 FREE_C_HEAP_ARRAY(char, destfile); | 131 FREE_C_HEAP_ARRAY(char, destfile, mtInternal); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 // Shared Memory Implementation Details | 135 // Shared Memory Implementation Details |
136 | 136 |
153 static char* get_user_tmp_dir(const char* user) { | 153 static char* get_user_tmp_dir(const char* user) { |
154 | 154 |
155 const char* tmpdir = os::get_temp_directory(); | 155 const char* tmpdir = os::get_temp_directory(); |
156 const char* perfdir = PERFDATA_NAME; | 156 const char* perfdir = PERFDATA_NAME; |
157 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; | 157 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; |
158 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes); | 158 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
159 | 159 |
160 // construct the path name to user specific tmp directory | 160 // construct the path name to user specific tmp directory |
161 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); | 161 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); |
162 | 162 |
163 return dirname; | 163 return dirname; |
246 // | 246 // |
247 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); | 247 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); |
248 if (bufsize == -1) | 248 if (bufsize == -1) |
249 bufsize = 1024; | 249 bufsize = 1024; |
250 | 250 |
251 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize); | 251 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); |
252 | 252 |
253 #ifdef _GNU_SOURCE | 253 #ifdef _GNU_SOURCE |
254 struct passwd* p = NULL; | 254 struct passwd* p = NULL; |
255 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); | 255 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); |
256 #else // _GNU_SOURCE | 256 #else // _GNU_SOURCE |
267 warning("Could not determine user name: %s\n", | 267 warning("Could not determine user name: %s\n", |
268 p->pw_name == NULL ? "pw_name = NULL" : | 268 p->pw_name == NULL ? "pw_name = NULL" : |
269 "pw_name zero length"); | 269 "pw_name zero length"); |
270 } | 270 } |
271 } | 271 } |
272 FREE_C_HEAP_ARRAY(char, pwbuf); | 272 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); |
273 return NULL; | 273 return NULL; |
274 } | 274 } |
275 | 275 |
276 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1); | 276 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal); |
277 strcpy(user_name, p->pw_name); | 277 strcpy(user_name, p->pw_name); |
278 | 278 |
279 FREE_C_HEAP_ARRAY(char, pwbuf); | 279 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); |
280 return user_name; | 280 return user_name; |
281 } | 281 } |
282 | 282 |
283 // return the name of the user that owns the process identified by vmid. | 283 // return the name of the user that owns the process identified by vmid. |
284 // | 284 // |
317 // open the directory and check if the file for the given vmid exists. | 317 // open the directory and check if the file for the given vmid exists. |
318 // The file with the expected name and the latest creation date is used | 318 // The file with the expected name and the latest creation date is used |
319 // to determine the user name for the process id. | 319 // to determine the user name for the process id. |
320 // | 320 // |
321 struct dirent* dentry; | 321 struct dirent* dentry; |
322 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname)); | 322 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); |
323 errno = 0; | 323 errno = 0; |
324 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { | 324 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { |
325 | 325 |
326 // check if the directory entry is a hsperfdata file | 326 // check if the directory entry is a hsperfdata file |
327 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { | 327 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { |
328 continue; | 328 continue; |
329 } | 329 } |
330 | 330 |
331 char* usrdir_name = NEW_C_HEAP_ARRAY(char, | 331 char* usrdir_name = NEW_C_HEAP_ARRAY(char, |
332 strlen(tmpdirname) + strlen(dentry->d_name) + 2); | 332 strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal); |
333 strcpy(usrdir_name, tmpdirname); | 333 strcpy(usrdir_name, tmpdirname); |
334 strcat(usrdir_name, "/"); | 334 strcat(usrdir_name, "/"); |
335 strcat(usrdir_name, dentry->d_name); | 335 strcat(usrdir_name, dentry->d_name); |
336 | 336 |
337 DIR* subdirp = os::opendir(usrdir_name); | 337 DIR* subdirp = os::opendir(usrdir_name); |
338 | 338 |
339 if (subdirp == NULL) { | 339 if (subdirp == NULL) { |
340 FREE_C_HEAP_ARRAY(char, usrdir_name); | 340 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); |
341 continue; | 341 continue; |
342 } | 342 } |
343 | 343 |
344 // Since we don't create the backing store files in directories | 344 // Since we don't create the backing store files in directories |
345 // pointed to by symbolic links, we also don't follow them when | 345 // pointed to by symbolic links, we also don't follow them when |
346 // looking for the files. We check for a symbolic link after the | 346 // looking for the files. We check for a symbolic link after the |
347 // call to opendir in order to eliminate a small window where the | 347 // call to opendir in order to eliminate a small window where the |
348 // symlink can be exploited. | 348 // symlink can be exploited. |
349 // | 349 // |
350 if (!is_directory_secure(usrdir_name)) { | 350 if (!is_directory_secure(usrdir_name)) { |
351 FREE_C_HEAP_ARRAY(char, usrdir_name); | 351 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); |
352 os::closedir(subdirp); | 352 os::closedir(subdirp); |
353 continue; | 353 continue; |
354 } | 354 } |
355 | 355 |
356 struct dirent* udentry; | 356 struct dirent* udentry; |
357 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name)); | 357 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); |
358 errno = 0; | 358 errno = 0; |
359 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { | 359 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { |
360 | 360 |
361 if (filename_to_pid(udentry->d_name) == vmid) { | 361 if (filename_to_pid(udentry->d_name) == vmid) { |
362 struct stat statbuf; | 362 struct stat statbuf; |
363 int result; | 363 int result; |
364 | 364 |
365 char* filename = NEW_C_HEAP_ARRAY(char, | 365 char* filename = NEW_C_HEAP_ARRAY(char, |
366 strlen(usrdir_name) + strlen(udentry->d_name) + 2); | 366 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal); |
367 | 367 |
368 strcpy(filename, usrdir_name); | 368 strcpy(filename, usrdir_name); |
369 strcat(filename, "/"); | 369 strcat(filename, "/"); |
370 strcat(filename, udentry->d_name); | 370 strcat(filename, udentry->d_name); |
371 | 371 |
372 // don't follow symbolic links for the file | 372 // don't follow symbolic links for the file |
373 RESTARTABLE(::lstat(filename, &statbuf), result); | 373 RESTARTABLE(::lstat(filename, &statbuf), result); |
374 if (result == OS_ERR) { | 374 if (result == OS_ERR) { |
375 FREE_C_HEAP_ARRAY(char, filename); | 375 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
376 continue; | 376 continue; |
377 } | 377 } |
378 | 378 |
379 // skip over files that are not regular files. | 379 // skip over files that are not regular files. |
380 if (!S_ISREG(statbuf.st_mode)) { | 380 if (!S_ISREG(statbuf.st_mode)) { |
381 FREE_C_HEAP_ARRAY(char, filename); | 381 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
382 continue; | 382 continue; |
383 } | 383 } |
384 | 384 |
385 // compare and save filename with latest creation time | 385 // compare and save filename with latest creation time |
386 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { | 386 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { |
387 | 387 |
388 if (statbuf.st_ctime > oldest_ctime) { | 388 if (statbuf.st_ctime > oldest_ctime) { |
389 char* user = strchr(dentry->d_name, '_') + 1; | 389 char* user = strchr(dentry->d_name, '_') + 1; |
390 | 390 |
391 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user); | 391 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal); |
392 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1); | 392 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal); |
393 | 393 |
394 strcpy(oldest_user, user); | 394 strcpy(oldest_user, user); |
395 oldest_ctime = statbuf.st_ctime; | 395 oldest_ctime = statbuf.st_ctime; |
396 } | 396 } |
397 } | 397 } |
398 | 398 |
399 FREE_C_HEAP_ARRAY(char, filename); | 399 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
400 } | 400 } |
401 } | 401 } |
402 os::closedir(subdirp); | 402 os::closedir(subdirp); |
403 FREE_C_HEAP_ARRAY(char, udbuf); | 403 FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); |
404 FREE_C_HEAP_ARRAY(char, usrdir_name); | 404 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); |
405 } | 405 } |
406 os::closedir(tmpdirp); | 406 os::closedir(tmpdirp); |
407 FREE_C_HEAP_ARRAY(char, tdbuf); | 407 FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); |
408 | 408 |
409 return(oldest_user); | 409 return(oldest_user); |
410 } | 410 } |
411 | 411 |
412 // return the name of the user that owns the JVM indicated by the given vmid. | 412 // return the name of the user that owns the JVM indicated by the given vmid. |
469 static char* get_sharedmem_filename(const char* dirname, int vmid) { | 469 static char* get_sharedmem_filename(const char* dirname, int vmid) { |
470 | 470 |
471 // add 2 for the file separator and a NULL terminator. | 471 // add 2 for the file separator and a NULL terminator. |
472 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; | 472 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; |
473 | 473 |
474 char* name = NEW_C_HEAP_ARRAY(char, nbytes); | 474 char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
475 snprintf(name, nbytes, "%s/%d", dirname, vmid); | 475 snprintf(name, nbytes, "%s/%d", dirname, vmid); |
476 | 476 |
477 return name; | 477 return name; |
478 } | 478 } |
479 | 479 |
507 // named directory. | 507 // named directory. |
508 // | 508 // |
509 static void remove_file(const char* dirname, const char* filename) { | 509 static void remove_file(const char* dirname, const char* filename) { |
510 | 510 |
511 size_t nbytes = strlen(dirname) + strlen(filename) + 2; | 511 size_t nbytes = strlen(dirname) + strlen(filename) + 2; |
512 char* path = NEW_C_HEAP_ARRAY(char, nbytes); | 512 char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); |
513 | 513 |
514 strcpy(path, dirname); | 514 strcpy(path, dirname); |
515 strcat(path, "/"); | 515 strcat(path, "/"); |
516 strcat(path, filename); | 516 strcat(path, filename); |
517 | 517 |
518 remove_file(path); | 518 remove_file(path); |
519 | 519 |
520 FREE_C_HEAP_ARRAY(char, path); | 520 FREE_C_HEAP_ARRAY(char, path, mtInternal); |
521 } | 521 } |
522 | 522 |
523 | 523 |
524 // cleanup stale shared memory resources | 524 // cleanup stale shared memory resources |
525 // | 525 // |
552 // remove or create new files in this directory. The behavior of this | 552 // remove or create new files in this directory. The behavior of this |
553 // loop under these conditions is dependent upon the implementation of | 553 // loop under these conditions is dependent upon the implementation of |
554 // opendir/readdir. | 554 // opendir/readdir. |
555 // | 555 // |
556 struct dirent* entry; | 556 struct dirent* entry; |
557 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname)); | 557 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); |
558 errno = 0; | 558 errno = 0; |
559 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { | 559 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { |
560 | 560 |
561 pid_t pid = filename_to_pid(entry->d_name); | 561 pid_t pid = filename_to_pid(entry->d_name); |
562 | 562 |
591 remove_file(dirname, entry->d_name); | 591 remove_file(dirname, entry->d_name); |
592 } | 592 } |
593 errno = 0; | 593 errno = 0; |
594 } | 594 } |
595 os::closedir(dirp); | 595 os::closedir(dirp); |
596 FREE_C_HEAP_ARRAY(char, dbuf); | 596 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); |
597 } | 597 } |
598 | 598 |
599 // make the user specific temporary directory. Returns true if | 599 // make the user specific temporary directory. Returns true if |
600 // the directory exists and is secure upon return. Returns false | 600 // the directory exists and is secure upon return. Returns false |
601 // if the directory exists but is either a symlink, is otherwise | 601 // if the directory exists but is either a symlink, is otherwise |
736 assert(((size > 0) && (size % os::vm_page_size() == 0)), | 736 assert(((size > 0) && (size % os::vm_page_size() == 0)), |
737 "unexpected PerfMemory region size"); | 737 "unexpected PerfMemory region size"); |
738 | 738 |
739 fd = create_sharedmem_resources(dirname, filename, size); | 739 fd = create_sharedmem_resources(dirname, filename, size); |
740 | 740 |
741 FREE_C_HEAP_ARRAY(char, user_name); | 741 FREE_C_HEAP_ARRAY(char, user_name, mtInternal); |
742 FREE_C_HEAP_ARRAY(char, dirname); | 742 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); |
743 | 743 |
744 if (fd == -1) { | 744 if (fd == -1) { |
745 FREE_C_HEAP_ARRAY(char, filename); | 745 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
746 return NULL; | 746 return NULL; |
747 } | 747 } |
748 | 748 |
749 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | 749 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); |
750 | 750 |
756 if (mapAddress == MAP_FAILED) { | 756 if (mapAddress == MAP_FAILED) { |
757 if (PrintMiscellaneous && Verbose) { | 757 if (PrintMiscellaneous && Verbose) { |
758 warning("mmap failed - %s\n", strerror(errno)); | 758 warning("mmap failed - %s\n", strerror(errno)); |
759 } | 759 } |
760 remove_file(filename); | 760 remove_file(filename); |
761 FREE_C_HEAP_ARRAY(char, filename); | 761 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
762 return NULL; | 762 return NULL; |
763 } | 763 } |
764 | 764 |
765 // save the file name for use in delete_shared_memory() | 765 // save the file name for use in delete_shared_memory() |
766 backing_store_file_name = filename; | 766 backing_store_file_name = filename; |
882 | 882 |
883 // since we don't follow symbolic links when creating the backing | 883 // since we don't follow symbolic links when creating the backing |
884 // store file, we don't follow them when attaching either. | 884 // store file, we don't follow them when attaching either. |
885 // | 885 // |
886 if (!is_directory_secure(dirname)) { | 886 if (!is_directory_secure(dirname)) { |
887 FREE_C_HEAP_ARRAY(char, dirname); | 887 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); |
888 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | 888 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
889 "Process not found"); | 889 "Process not found"); |
890 } | 890 } |
891 | 891 |
892 char* filename = get_sharedmem_filename(dirname, vmid); | 892 char* filename = get_sharedmem_filename(dirname, vmid); |
897 // would otherwise occur. | 897 // would otherwise occur. |
898 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); | 898 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); |
899 strcpy(rfilename, filename); | 899 strcpy(rfilename, filename); |
900 | 900 |
901 // free the c heap resources that are no longer needed | 901 // free the c heap resources that are no longer needed |
902 if (luser != user) FREE_C_HEAP_ARRAY(char, luser); | 902 if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal); |
903 FREE_C_HEAP_ARRAY(char, dirname); | 903 FREE_C_HEAP_ARRAY(char, dirname, mtInternal); |
904 FREE_C_HEAP_ARRAY(char, filename); | 904 FREE_C_HEAP_ARRAY(char, filename, mtInternal); |
905 | 905 |
906 // open the shared memory file for the give vmid | 906 // open the shared memory file for the give vmid |
907 fd = open_sharedmem_file(rfilename, file_flags, CHECK); | 907 fd = open_sharedmem_file(rfilename, file_flags, CHECK); |
908 assert(fd != OS_ERR, "unexpected value"); | 908 assert(fd != OS_ERR, "unexpected value"); |
909 | 909 |