< prev index next >

src/hotspot/share/runtime/globals.cpp

Print this page




 444   if (is_notproduct() && is_product_build()) {
 445     jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
 446                  _name);
 447     return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
 448   }
 449   get_locked_message_ext(buf, buflen);
 450   return Flag::NONE;
 451 }
 452 
 453 bool Flag::is_writeable() const {
 454   return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
 455 }
 456 
 457 // All flags except "manageable" are assumed to be internal flags.
 458 // Long term, we need to define a mechanism to specify which flags
 459 // are external/stable and change this function accordingly.
 460 bool Flag::is_external() const {
 461   return is_manageable() || is_external_ext();
 462 }
 463 
 464 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {







 465   // Don't print notproduct and develop flags in a product build.
 466   if (is_constant_in_binary()) {
 467     return;
 468   }
 469 




 470   if (!printRanges) {
 471     // Use some named constants to make code more readable.
 472     const unsigned int nSpaces    = 10;
 473     const unsigned int maxFlagLen = 40 + nSpaces;
 474 
 475     // The print below assumes that the flag name is 40 characters or less.
 476     // This works for most flags, but there are exceptions. Our longest flag
 477     // name right now is UseAdaptiveGenerationSizePolicyAtMajorCollection and
 478     // its minor collection buddy. These are 48 characters. We use a buffer of
 479     // nSpaces spaces below to adjust the space between the flag value and the
 480     // column of flag type and origin that is printed in the end of the line.
 481     char spaces[nSpaces + 1] = "          ";
 482     st->print("%9s %-*s = ", _type, maxFlagLen-nSpaces, _name);























 483 




 484     if (is_bool()) {
 485       st->print("%-20s", get_bool() ? "true" : "false");
 486     } else if (is_int()) {
 487       st->print("%-20d", get_int());
 488     } else if (is_uint()) {
 489       st->print("%-20u", get_uint());
 490     } else if (is_intx()) {
 491       st->print(INTX_FORMAT_W(-20), get_intx());
 492     } else if (is_uintx()) {
 493       st->print(UINTX_FORMAT_W(-20), get_uintx());
 494     } else if (is_uint64_t()) {
 495       st->print(UINT64_FORMAT_W(-20), get_uint64_t());
 496     } else if (is_size_t()) {
 497       st->print(SIZE_FORMAT_W(-20), get_size_t());
 498     } else if (is_double()) {
 499       st->print("%-20f", get_double());
 500     } else if (is_ccstr()) {

 501       const char* cp = get_ccstr();
 502       if (cp != NULL) {
 503         const char* eol;
 504         while ((eol = strchr(cp, '\n')) != NULL) {
 505           size_t llen = pointer_delta(eol, cp, sizeof(char));
 506           st->print("%.*s", (int)llen, cp);
 507           st->cr();
 508           cp = eol+1;
 509           st->print("%5s %-35s += ", "", _name);
 510         }
 511         st->print("%-20s", cp);


 512       }
 513       else st->print("%-20s", "");
 514     }
 515     // Make sure we do not punch a '\0' at a negative char array index.
 516     unsigned int nameLen = (unsigned int)strlen(_name);
 517     if (nameLen <= maxFlagLen) {
 518       spaces[maxFlagLen - MAX2(maxFlagLen-nSpaces, nameLen)] = '\0';
 519       st->print("%s", spaces);
 520     }
 521     print_kind_and_origin(st);





 522 
 523 #ifndef PRODUCT
 524     if (withComments) {

 525       st->print("%s", _doc);
 526     }
 527 #endif
 528 
 529     st->cr();
 530 
 531   } else if (!is_bool() && !is_ccstr()) {
 532     st->print("%9s %-50s ", _type, _name);

































 533 
 534     RangeStrFunc func = NULL;
 535     if (is_int()) {
 536       func = Flag::get_int_default_range_str;
 537     } else if (is_uint()) {
 538       func = Flag::get_uint_default_range_str;
 539     } else if (is_intx()) {
 540       func = Flag::get_intx_default_range_str;
 541     } else if (is_uintx()) {
 542       func = Flag::get_uintx_default_range_str;
 543     } else if (is_uint64_t()) {
 544       func = Flag::get_uint64_t_default_range_str;
 545     } else if (is_size_t()) {
 546       func = Flag::get_size_t_default_range_str;
 547     } else if (is_double()) {
 548       func = Flag::get_double_default_range_str;
 549     } else {
 550       ShouldNotReachHere();
 551     }

 552     CommandLineFlagRangeList::print(st, _name, func);
 553 
 554     st->print(" %-16s", " ");
 555     print_kind_and_origin(st);



 556 
 557 #ifndef PRODUCT
 558     if (withComments) {

 559       st->print("%s", _doc);
 560     }
 561 #endif
 562 
 563     st->cr();
 564   }

 565 }
 566 
 567 void Flag::print_kind_and_origin(outputStream* st) {
 568   struct Data {
 569     int flag;
 570     const char* name;
 571   };
 572 
 573   Data data[] = {
 574       { KIND_JVMCI, "JVMCI" },
 575       { KIND_C1, "C1" },
 576       { KIND_C2, "C2" },
 577       { KIND_ARCH, "ARCH" },
 578       { KIND_PLATFORM_DEPENDENT, "pd" },
 579       { KIND_PRODUCT, "product" },
 580       { KIND_MANAGEABLE, "manageable" },
 581       { KIND_DIAGNOSTIC, "diagnostic" },
 582       { KIND_EXPERIMENTAL, "experimental" },
 583       { KIND_COMMERCIAL, "commercial" },
 584       { KIND_NOT_PRODUCT, "notproduct" },
 585       { KIND_DEVELOP, "develop" },
 586       { KIND_LP64_PRODUCT, "lp64_product" },
 587       { KIND_READ_WRITE, "rw" },


 597     jio_snprintf(kind, buffer_size, "{");
 598     buffer_used++;
 599     for (int i = 0; data[i].flag != -1; i++) {
 600       Data d = data[i];
 601       if ((_flags & d.flag) != 0) {
 602         if (is_first) {
 603           is_first = false;
 604         } else {
 605           assert(buffer_used + 1 < buffer_size, "Too small buffer");
 606           jio_snprintf(kind + buffer_used, buffer_size - buffer_used, " ");
 607           buffer_used++;
 608         }
 609         size_t length = strlen(d.name);
 610         assert(buffer_used + length < buffer_size, "Too small buffer");
 611         jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "%s", d.name);
 612         buffer_used += length;
 613       }
 614     }
 615     assert(buffer_used + 2 <= buffer_size, "Too small buffer");
 616     jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
 617     st->print("%20s", kind);
 618   }



 619 
 620   int origin = _flags & VALUE_ORIGIN_MASK;
 621   st->print(" {");
 622   switch(origin) {
 623     case DEFAULT:
 624       st->print("default"); break;
 625     case COMMAND_LINE:
 626       st->print("command line"); break;
 627     case ENVIRON_VAR:
 628       st->print("environment"); break;
 629     case CONFIG_FILE:
 630       st->print("config file"); break;
 631     case MANAGEMENT:
 632       st->print("management"); break;
 633     case ERGONOMIC:
 634       if (_flags & ORIG_COMMAND_LINE) {
 635         st->print("command line, ");
 636       }
 637       st->print("ergonomic"); break;
 638     case ATTACH_ON_DEMAND:
 639       st->print("attach"); break;
 640     case INTERNAL:
 641       st->print("internal"); break;




 444   if (is_notproduct() && is_product_build()) {
 445     jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
 446                  _name);
 447     return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
 448   }
 449   get_locked_message_ext(buf, buflen);
 450   return Flag::NONE;
 451 }
 452 
 453 bool Flag::is_writeable() const {
 454   return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
 455 }
 456 
 457 // All flags except "manageable" are assumed to be internal flags.
 458 // Long term, we need to define a mechanism to specify which flags
 459 // are external/stable and change this function accordingly.
 460 bool Flag::is_external() const {
 461   return is_manageable() || is_external_ext();
 462 }
 463 
 464 // The purpose of using stringStream:
 465 //   The Flag::print_on() method constructs the output for each existing command-line flag out of
 466 //   multiple st->print() calls, where st is an outputStream usually mapped to tty directly.
 467 //   That may cause significant overhead in elapsed time and cpu cycles.
 468 //   With a stringStream buffer, the output string for a command-line flag is constructed in a
 469 //   local stringStream object. Only after construction is complete, the stringStream object is
 470 //   written to the outputStream (usually tty), all at once.
 471 void Flag::print_on(outputStream* ost, bool withComments, bool printRanges) {
 472   // Don't print notproduct and develop flags in a product build.
 473   if (is_constant_in_binary()) {
 474     return;
 475   }
 476 
 477   ResourceMark rm;
 478   stringStream stobj = stringStream(1024);
 479   stringStream*   st = &stobj;
 480 
 481   if (!printRanges) {
 482     // The command line options -XX:+PrintFlags* cause this function to be called
 483     // for each existing flag to print information pertinent to this flag. The data
 484     // is displayed in columnar form, with the following layout:
 485     //  col1 - data type, right-justified
 486     //  col2 - name,      left-justified
 487     //  col3 - '='        single-char
 488     //  col4 - value      left-justified
 489     //  col5 - kind       right-justified
 490     //  col6 - origin     left-justified
 491     //  col7 - comments   left-justified
 492     //
 493     //  The column widths are fixed. They are defined such that, for most cases,
 494     //  an eye-pleasing tabular output is created.
 495 
 496     const unsigned int col_spacing = 1;
 497     const unsigned int col1_pos    = 0;
 498     const unsigned int col1_width  = 9;
 499     const unsigned int col2_pos    = col1_pos + col1_width + col_spacing;
 500     const unsigned int col2_width  = 39;
 501     const unsigned int col3_pos    = col2_pos + col2_width + col_spacing;
 502     const unsigned int col3_width  = 2;
 503     const unsigned int col4_pos    = col3_pos + col3_width + col_spacing;
 504     const unsigned int col4_width  = 30;
 505     const unsigned int col5_pos    = col4_pos + col4_width + col_spacing;
 506     const unsigned int col5_width  = 19;
 507     const unsigned int col6_pos    = col5_pos + col5_width + col_spacing;
 508     const unsigned int col6_width  = 15;
 509     const unsigned int col7_pos    = col6_pos + col6_width + col_spacing;
 510     const unsigned int col7_width  = 1;
 511 
 512     st->fill_to(col1_pos);
 513     st->print("%*s", col1_width, _type);  // right-justified, therefore width is required.
 514 
 515     st->fill_to(col2_pos);
 516     st->print("%s", _name);
 517 
 518     st->fill_to(col3_pos);
 519     st->print(" =");  // use " =" for proper alignment with multiline ccstr output.
 520 
 521     st->fill_to(col4_pos);
 522     if (is_bool()) {
 523       st->print("%s", get_bool() ? "true" : "false");
 524     } else if (is_int()) {
 525       st->print("%d", get_int());
 526     } else if (is_uint()) {
 527       st->print("%u", get_uint());
 528     } else if (is_intx()) {
 529       st->print(INTX_FORMAT, get_intx());
 530     } else if (is_uintx()) {
 531       st->print(UINTX_FORMAT, get_uintx());
 532     } else if (is_uint64_t()) {
 533       st->print(UINT64_FORMAT, get_uint64_t());
 534     } else if (is_size_t()) {
 535       st->print(SIZE_FORMAT, get_size_t());
 536     } else if (is_double()) {
 537       st->print("%f", get_double());
 538     } else if (is_ccstr()) {
 539       // Honor <newline> characters in ccstr: print multiple lines.
 540       const char* cp = get_ccstr();
 541       if (cp != NULL) {
 542         const char* eol;
 543         while ((eol = strchr(cp, '\n')) != NULL) {
 544           size_t llen = pointer_delta(eol, cp, sizeof(char));
 545           st->print("%.*s", (int)llen, cp);
 546           st->cr();
 547           cp = eol+1;
 548           st->fill_to(col2_pos);
 549           st->print("%s", _name);
 550           st->fill_to(col3_pos);
 551           st->print("+=");
 552           st->fill_to(col4_pos);
 553         }
 554         st->print("%s", cp);
 555       }





 556     }
 557 
 558     st->fill_to(col5_pos);
 559     print_kind(st, col5_width);
 560 
 561     st->fill_to(col6_pos);
 562     print_origin(st, col6_width);
 563 
 564 #ifndef PRODUCT
 565     if (withComments) {
 566       st->fill_to(col7_pos);
 567       st->print("%s", _doc);
 568     }
 569 #endif

 570     st->cr();

 571   } else if (!is_bool() && !is_ccstr()) {
 572     // The command line options -XX:+PrintFlags* cause this function to be called
 573     // for each existing flag to print information pertinent to this flag. The data
 574     // is displayed in columnar form, with the following layout:
 575     //  col1 - data type, right-justified
 576     //  col2 - name,      left-justified
 577     //  col4 - range      [ min ... max]
 578     //  col5 - kind       right-justified
 579     //  col6 - origin     left-justified
 580     //  col7 - comments   left-justified
 581     //
 582     //  The column widths are fixed. They are defined such that, for most cases,
 583     //  an eye-pleasing tabular output is created.
 584 
 585     const unsigned int col_spacing = 1;
 586     const unsigned int col1_pos    = 0;
 587     const unsigned int col1_width  = 9;
 588     const unsigned int col2_pos    = col1_pos + col1_width + col_spacing;
 589     const unsigned int col2_width  = 49;
 590     const unsigned int col3_pos    = col2_pos + col2_width + col_spacing;
 591     const unsigned int col3_width  = 0;
 592     const unsigned int col4_pos    = col3_pos + col3_width + col_spacing;
 593     const unsigned int col4_width  = 60;
 594     const unsigned int col5_pos    = col4_pos + col4_width + col_spacing;
 595     const unsigned int col5_width  = 35;
 596     const unsigned int col6_pos    = col5_pos + col5_width + col_spacing;
 597     const unsigned int col6_width  = 15;
 598     const unsigned int col7_pos    = col6_pos + col6_width + col_spacing;
 599     const unsigned int col7_width  = 1;
 600 
 601     st->fill_to(col1_pos);
 602     st->print("%*s", col1_width, _type);  // right-justified, therefore width is required.
 603 
 604     st->fill_to(col2_pos);
 605     st->print("%s", _name);
 606 
 607     RangeStrFunc func = NULL;
 608     if (is_int()) {
 609       func = Flag::get_int_default_range_str;
 610     } else if (is_uint()) {
 611       func = Flag::get_uint_default_range_str;
 612     } else if (is_intx()) {
 613       func = Flag::get_intx_default_range_str;
 614     } else if (is_uintx()) {
 615       func = Flag::get_uintx_default_range_str;
 616     } else if (is_uint64_t()) {
 617       func = Flag::get_uint64_t_default_range_str;
 618     } else if (is_size_t()) {
 619       func = Flag::get_size_t_default_range_str;
 620     } else if (is_double()) {
 621       func = Flag::get_double_default_range_str;
 622     } else {
 623       ShouldNotReachHere();
 624     }
 625     st->fill_to(col4_pos);
 626     CommandLineFlagRangeList::print(st, _name, func);
 627 
 628     st->fill_to(col5_pos);
 629     print_kind(st, col5_width);
 630 
 631     st->fill_to(col6_pos);
 632     print_origin(st, col6_width);
 633 
 634 #ifndef PRODUCT
 635     if (withComments) {
 636       st->fill_to(col7_pos);
 637       st->print("%s", _doc);
 638     }
 639 #endif

 640     st->cr();
 641   }
 642   ost->print("%s", st->as_string());
 643 }
 644 
 645 void Flag::print_kind(outputStream* st, unsigned int width) {
 646   struct Data {
 647     int flag;
 648     const char* name;
 649   };
 650 
 651   Data data[] = {
 652       { KIND_JVMCI, "JVMCI" },
 653       { KIND_C1, "C1" },
 654       { KIND_C2, "C2" },
 655       { KIND_ARCH, "ARCH" },
 656       { KIND_PLATFORM_DEPENDENT, "pd" },
 657       { KIND_PRODUCT, "product" },
 658       { KIND_MANAGEABLE, "manageable" },
 659       { KIND_DIAGNOSTIC, "diagnostic" },
 660       { KIND_EXPERIMENTAL, "experimental" },
 661       { KIND_COMMERCIAL, "commercial" },
 662       { KIND_NOT_PRODUCT, "notproduct" },
 663       { KIND_DEVELOP, "develop" },
 664       { KIND_LP64_PRODUCT, "lp64_product" },
 665       { KIND_READ_WRITE, "rw" },


 675     jio_snprintf(kind, buffer_size, "{");
 676     buffer_used++;
 677     for (int i = 0; data[i].flag != -1; i++) {
 678       Data d = data[i];
 679       if ((_flags & d.flag) != 0) {
 680         if (is_first) {
 681           is_first = false;
 682         } else {
 683           assert(buffer_used + 1 < buffer_size, "Too small buffer");
 684           jio_snprintf(kind + buffer_used, buffer_size - buffer_used, " ");
 685           buffer_used++;
 686         }
 687         size_t length = strlen(d.name);
 688         assert(buffer_used + length < buffer_size, "Too small buffer");
 689         jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "%s", d.name);
 690         buffer_used += length;
 691       }
 692     }
 693     assert(buffer_used + 2 <= buffer_size, "Too small buffer");
 694     jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
 695     st->print("%*s", width, kind);
 696   }
 697 }
 698 
 699 void Flag::print_origin(outputStream* st, unsigned int width) {
 700 
 701   int origin = _flags & VALUE_ORIGIN_MASK;
 702   st->print("{");
 703   switch(origin) {
 704     case DEFAULT:
 705       st->print("default"); break;
 706     case COMMAND_LINE:
 707       st->print("command line"); break;
 708     case ENVIRON_VAR:
 709       st->print("environment"); break;
 710     case CONFIG_FILE:
 711       st->print("config file"); break;
 712     case MANAGEMENT:
 713       st->print("management"); break;
 714     case ERGONOMIC:
 715       if (_flags & ORIG_COMMAND_LINE) {
 716         st->print("command line, ");
 717       }
 718       st->print("ergonomic"); break;
 719     case ATTACH_ON_DEMAND:
 720       st->print("attach"); break;
 721     case INTERNAL:
 722       st->print("internal"); break;


< prev index next >