445 if (is_notproduct() && is_product_build()) {
446 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
447 _name);
448 return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
449 }
450 get_locked_message_ext(buf, buflen);
451 return Flag::NONE;
452 }
453
454 bool Flag::is_writeable() const {
455 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
456 }
457
458 // All flags except "manageable" are assumed to be internal flags.
459 // Long term, we need to define a mechanism to specify which flags
460 // are external/stable and change this function accordingly.
461 bool Flag::is_external() const {
462 return is_manageable() || is_external_ext();
463 }
464
465 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
466 // Don't print notproduct and develop flags in a product build.
467 if (is_constant_in_binary()) {
468 return;
469 }
470
471 if (!printRanges) {
472 // Use some named constants to make code more readable.
473 const unsigned int nSpaces = 10;
474 const unsigned int maxFlagLen = 40 + nSpaces;
475
476 // The print below assumes that the flag name is 40 characters or less.
477 // This works for most flags, but there are exceptions. Our longest flag
478 // name right now is UseAdaptiveGenerationSizePolicyAtMajorCollection and
479 // its minor collection buddy. These are 48 characters. We use a buffer of
480 // nSpaces spaces below to adjust the space between the flag value and the
481 // column of flag type and origin that is printed in the end of the line.
482 char spaces[nSpaces + 1] = " ";
483 st->print("%9s %-*s = ", _type, maxFlagLen-nSpaces, _name);
484
485 if (is_bool()) {
486 st->print("%-20s", get_bool() ? "true" : "false");
487 } else if (is_int()) {
488 st->print("%-20d", get_int());
489 } else if (is_uint()) {
490 st->print("%-20u", get_uint());
491 } else if (is_intx()) {
492 st->print(INTX_FORMAT_W(-20), get_intx());
493 } else if (is_uintx()) {
494 st->print(UINTX_FORMAT_W(-20), get_uintx());
495 } else if (is_uint64_t()) {
496 st->print(UINT64_FORMAT_W(-20), get_uint64_t());
497 } else if (is_size_t()) {
498 st->print(SIZE_FORMAT_W(-20), get_size_t());
499 } else if (is_double()) {
500 st->print("%-20f", get_double());
501 } else if (is_ccstr()) {
502 const char* cp = get_ccstr();
503 if (cp != NULL) {
504 const char* eol;
505 while ((eol = strchr(cp, '\n')) != NULL) {
506 size_t llen = pointer_delta(eol, cp, sizeof(char));
507 st->print("%.*s", (int)llen, cp);
508 st->cr();
509 cp = eol+1;
510 st->print("%5s %-35s += ", "", _name);
511 }
512 st->print("%-20s", cp);
513 }
514 else st->print("%-20s", "");
515 }
516 // Make sure we do not punch a '\0' at a negative char array index.
517 unsigned int nameLen = (unsigned int)strlen(_name);
518 if (nameLen <= maxFlagLen) {
519 spaces[maxFlagLen - MAX2(maxFlagLen-nSpaces, nameLen)] = '\0';
520 st->print("%s", spaces);
521 }
522 print_kind_and_origin(st);
523
524 #ifndef PRODUCT
525 if (withComments) {
526 st->print("%s", _doc);
527 }
528 #endif
529
530 st->cr();
531
532 } else if (!is_bool() && !is_ccstr()) {
533 st->print("%9s %-50s ", _type, _name);
534
535 RangeStrFunc func = NULL;
536 if (is_int()) {
537 func = Flag::get_int_default_range_str;
538 } else if (is_uint()) {
539 func = Flag::get_uint_default_range_str;
540 } else if (is_intx()) {
541 func = Flag::get_intx_default_range_str;
542 } else if (is_uintx()) {
543 func = Flag::get_uintx_default_range_str;
544 } else if (is_uint64_t()) {
545 func = Flag::get_uint64_t_default_range_str;
546 } else if (is_size_t()) {
547 func = Flag::get_size_t_default_range_str;
548 } else if (is_double()) {
549 func = Flag::get_double_default_range_str;
550 } else {
551 ShouldNotReachHere();
552 }
553 CommandLineFlagRangeList::print(st, _name, func);
554
555 st->print(" %-16s", " ");
556 print_kind_and_origin(st);
557
558 #ifndef PRODUCT
559 if (withComments) {
560 st->print("%s", _doc);
561 }
562 #endif
563
564 st->cr();
565 }
566 }
567
568 void Flag::print_kind_and_origin(outputStream* st) {
569 struct Data {
570 int flag;
571 const char* name;
572 };
573
574 Data data[] = {
575 { KIND_JVMCI, "JVMCI" },
576 { KIND_C1, "C1" },
577 { KIND_C2, "C2" },
578 { KIND_ARCH, "ARCH" },
579 { KIND_PLATFORM_DEPENDENT, "pd" },
580 { KIND_PRODUCT, "product" },
581 { KIND_MANAGEABLE, "manageable" },
582 { KIND_DIAGNOSTIC, "diagnostic" },
583 { KIND_EXPERIMENTAL, "experimental" },
584 { KIND_COMMERCIAL, "commercial" },
585 { KIND_NOT_PRODUCT, "notproduct" },
586 { KIND_DEVELOP, "develop" },
587 { KIND_LP64_PRODUCT, "lp64_product" },
588 { KIND_READ_WRITE, "rw" },
598 jio_snprintf(kind, buffer_size, "{");
599 buffer_used++;
600 for (int i = 0; data[i].flag != -1; i++) {
601 Data d = data[i];
602 if ((_flags & d.flag) != 0) {
603 if (is_first) {
604 is_first = false;
605 } else {
606 assert(buffer_used + 1 < buffer_size, "Too small buffer");
607 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, " ");
608 buffer_used++;
609 }
610 size_t length = strlen(d.name);
611 assert(buffer_used + length < buffer_size, "Too small buffer");
612 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "%s", d.name);
613 buffer_used += length;
614 }
615 }
616 assert(buffer_used + 2 <= buffer_size, "Too small buffer");
617 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
618 st->print("%20s", kind);
619 }
620
621 int origin = _flags & VALUE_ORIGIN_MASK;
622 st->print(" {");
623 switch(origin) {
624 case DEFAULT:
625 st->print("default"); break;
626 case COMMAND_LINE:
627 st->print("command line"); break;
628 case ENVIRON_VAR:
629 st->print("environment"); break;
630 case CONFIG_FILE:
631 st->print("config file"); break;
632 case MANAGEMENT:
633 st->print("management"); break;
634 case ERGONOMIC:
635 if (_flags & ORIG_COMMAND_LINE) {
636 st->print("command line, ");
637 }
638 st->print("ergonomic"); break;
639 case ATTACH_ON_DEMAND:
640 st->print("attach"); break;
641 case INTERNAL:
642 st->print("internal"); break;
|
445 if (is_notproduct() && is_product_build()) {
446 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
447 _name);
448 return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
449 }
450 get_locked_message_ext(buf, buflen);
451 return Flag::NONE;
452 }
453
454 bool Flag::is_writeable() const {
455 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
456 }
457
458 // All flags except "manageable" are assumed to be internal flags.
459 // Long term, we need to define a mechanism to specify which flags
460 // are external/stable and change this function accordingly.
461 bool Flag::is_external() const {
462 return is_manageable() || is_external_ext();
463 }
464
465 // Helper function for Flag::print_on().
466 // Fills current line up to requested position.
467 // Should the current position already be past the requested position,
468 // one separator blank is enforced.
469 void fill_to_pos(outputStream* st, unsigned int req_pos) {
470 if ((unsigned int)st->position() < req_pos) {
471 st->fill_to(req_pos); // need to fill with blanks to reach req_pos
472 } else {
473 st->print(" "); // enforce blank separation. Previous field too long.
474 }
475 }
476
477 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
478 // Don't print notproduct and develop flags in a product build.
479 if (is_constant_in_binary()) {
480 return;
481 }
482
483 if (!printRanges) {
484 // The command line options -XX:+PrintFlags* cause this function to be called
485 // for each existing flag to print information pertinent to this flag. The data
486 // is displayed in columnar form, with the following layout:
487 // col1 - data type, right-justified
488 // col2 - name, left-justified
489 // col3 - ' =' double-char, leading space to align with possible '+='
490 // col4 - value left-justified
491 // col5 - kind right-justified
492 // col6 - origin left-justified
493 // col7 - comments left-justified
494 //
495 // The column widths are fixed. They are defined such that, for most cases,
496 // an eye-pleasing tabular output is created.
497 //
498 // Sample output:
499 // bool CMSScavengeBeforeRemark = false {product} {default}
500 // uintx CMSScheduleRemarkEdenPenetration = 50 {product} {default}
501 // size_t CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} {default}
502 // uintx CMSScheduleRemarkSamplingRatio = 5 {product} {default}
503 // double CMSSmallCoalSurplusPercent = 1.050000 {product} {default}
504 // ccstr CompileCommandFile = MyFile.cmd {product} {command line}
505 // ccstrlist CompileOnly = Method1
506 // CompileOnly += Method2 {product} {command line}
507 // | | | | | | |
508 // | | | | | | +-- col7
509 // | | | | | +-- col6
510 // | | | | +-- col5
511 // | | | +-- col4
512 // | | +-- col3
513 // | +-- col2
514 // +-- col1
515
516 const unsigned int col_spacing = 1;
517 const unsigned int col1_pos = 0;
518 const unsigned int col1_width = 9;
519 const unsigned int col2_pos = col1_pos + col1_width + col_spacing;
520 const unsigned int col2_width = 39;
521 const unsigned int col3_pos = col2_pos + col2_width + col_spacing;
522 const unsigned int col3_width = 2;
523 const unsigned int col4_pos = col3_pos + col3_width + col_spacing;
524 const unsigned int col4_width = 30;
525 const unsigned int col5_pos = col4_pos + col4_width + col_spacing;
526 const unsigned int col5_width = 20;
527 const unsigned int col6_pos = col5_pos + col5_width + col_spacing;
528 const unsigned int col6_width = 15;
529 const unsigned int col7_pos = col6_pos + col6_width + col_spacing;
530 const unsigned int col7_width = 1;
531
532 st->fill_to(col1_pos);
533 st->print("%*s", col1_width, _type); // right-justified, therefore width is required.
534
535 fill_to_pos(st, col2_pos);
536 st->print("%s", _name);
537
538 fill_to_pos(st, col3_pos);
539 st->print(" ="); // use " =" for proper alignment with multiline ccstr output.
540
541 fill_to_pos(st, col4_pos);
542 if (is_bool()) {
543 st->print("%s", get_bool() ? "true" : "false");
544 } else if (is_int()) {
545 st->print("%d", get_int());
546 } else if (is_uint()) {
547 st->print("%u", get_uint());
548 } else if (is_intx()) {
549 st->print(INTX_FORMAT, get_intx());
550 } else if (is_uintx()) {
551 st->print(UINTX_FORMAT, get_uintx());
552 } else if (is_uint64_t()) {
553 st->print(UINT64_FORMAT, get_uint64_t());
554 } else if (is_size_t()) {
555 st->print(SIZE_FORMAT, get_size_t());
556 } else if (is_double()) {
557 st->print("%f", get_double());
558 } else if (is_ccstr()) {
559 // Honor <newline> characters in ccstr: print multiple lines.
560 const char* cp = get_ccstr();
561 if (cp != NULL) {
562 const char* eol;
563 while ((eol = strchr(cp, '\n')) != NULL) {
564 size_t llen = pointer_delta(eol, cp, sizeof(char));
565 st->print("%.*s", (int)llen, cp);
566 st->cr();
567 cp = eol+1;
568 fill_to_pos(st, col2_pos);
569 st->print("%s", _name);
570 fill_to_pos(st, col3_pos);
571 st->print("+=");
572 fill_to_pos(st, col4_pos);
573 }
574 st->print("%s", cp);
575 }
576 } else {
577 st->print("unhandled type %s", _type);
578 st->cr();
579 return;
580 }
581
582 fill_to_pos(st, col5_pos);
583 print_kind(st, col5_width);
584
585 fill_to_pos(st, col6_pos);
586 print_origin(st, col6_width);
587
588 #ifndef PRODUCT
589 if (withComments) {
590 fill_to_pos(st, col7_pos);
591 st->print("%s", _doc);
592 }
593 #endif
594 st->cr();
595 } else if (!is_bool() && !is_ccstr()) {
596 // The command line options -XX:+PrintFlags* cause this function to be called
597 // for each existing flag to print information pertinent to this flag. The data
598 // is displayed in columnar form, with the following layout:
599 // col1 - data type, right-justified
600 // col2 - name, left-justified
601 // col4 - range [ min ... max]
602 // col5 - kind right-justified
603 // col6 - origin left-justified
604 // col7 - comments left-justified
605 //
606 // The column widths are fixed. They are defined such that, for most cases,
607 // an eye-pleasing tabular output is created.
608 //
609 // Sample output:
610 // intx MinPassesBeforeFlush [ 0 ... 9223372036854775807 ] {diagnostic} {default}
611 // uintx MinRAMFraction [ 1 ... 18446744073709551615 ] {product} {default}
612 // double MinRAMPercentage [ 0.000 ... 100.000 ] {product} {default}
613 // uintx MinSurvivorRatio [ 3 ... 18446744073709551615 ] {product} {default}
614 // size_t MinTLABSize [ 1 ... 9223372036854775807 ] {product} {default}
615 // intx MonitorBound [ 0 ... 2147483647 ] {product} {default}
616 // | | | | | |
617 // | | | | | +-- col7
618 // | | | | +-- col6
619 // | | | +-- col5
620 // | | +-- col4
621 // | +-- col2
622 // +-- col1
623
624 const unsigned int col_spacing = 1;
625 const unsigned int col1_pos = 0;
626 const unsigned int col1_width = 9;
627 const unsigned int col2_pos = col1_pos + col1_width + col_spacing;
628 const unsigned int col2_width = 49;
629 const unsigned int col3_pos = col2_pos + col2_width + col_spacing;
630 const unsigned int col3_width = 0;
631 const unsigned int col4_pos = col3_pos + col3_width + col_spacing;
632 const unsigned int col4_width = 60;
633 const unsigned int col5_pos = col4_pos + col4_width + col_spacing;
634 const unsigned int col5_width = 35;
635 const unsigned int col6_pos = col5_pos + col5_width + col_spacing;
636 const unsigned int col6_width = 15;
637 const unsigned int col7_pos = col6_pos + col6_width + col_spacing;
638 const unsigned int col7_width = 1;
639
640 st->fill_to(col1_pos);
641 st->print("%*s", col1_width, _type); // right-justified, therefore width is required.
642
643 fill_to_pos(st, col2_pos);
644 st->print("%s", _name);
645
646 fill_to_pos(st, col4_pos);
647 RangeStrFunc func = NULL;
648 if (is_int()) {
649 func = Flag::get_int_default_range_str;
650 } else if (is_uint()) {
651 func = Flag::get_uint_default_range_str;
652 } else if (is_intx()) {
653 func = Flag::get_intx_default_range_str;
654 } else if (is_uintx()) {
655 func = Flag::get_uintx_default_range_str;
656 } else if (is_uint64_t()) {
657 func = Flag::get_uint64_t_default_range_str;
658 } else if (is_size_t()) {
659 func = Flag::get_size_t_default_range_str;
660 } else if (is_double()) {
661 func = Flag::get_double_default_range_str;
662 } else {
663 st->print("unhandled type %s", _type);
664 st->cr();
665 return;
666 }
667 CommandLineFlagRangeList::print(st, _name, func);
668
669 fill_to_pos(st, col5_pos);
670 print_kind(st, col5_width);
671
672 fill_to_pos(st, col6_pos);
673 print_origin(st, col6_width);
674
675 #ifndef PRODUCT
676 if (withComments) {
677 fill_to_pos(st, col7_pos);
678 st->print("%s", _doc);
679 }
680 #endif
681 st->cr();
682 }
683 }
684
685 void Flag::print_kind(outputStream* st, unsigned int width) {
686 struct Data {
687 int flag;
688 const char* name;
689 };
690
691 Data data[] = {
692 { KIND_JVMCI, "JVMCI" },
693 { KIND_C1, "C1" },
694 { KIND_C2, "C2" },
695 { KIND_ARCH, "ARCH" },
696 { KIND_PLATFORM_DEPENDENT, "pd" },
697 { KIND_PRODUCT, "product" },
698 { KIND_MANAGEABLE, "manageable" },
699 { KIND_DIAGNOSTIC, "diagnostic" },
700 { KIND_EXPERIMENTAL, "experimental" },
701 { KIND_COMMERCIAL, "commercial" },
702 { KIND_NOT_PRODUCT, "notproduct" },
703 { KIND_DEVELOP, "develop" },
704 { KIND_LP64_PRODUCT, "lp64_product" },
705 { KIND_READ_WRITE, "rw" },
715 jio_snprintf(kind, buffer_size, "{");
716 buffer_used++;
717 for (int i = 0; data[i].flag != -1; i++) {
718 Data d = data[i];
719 if ((_flags & d.flag) != 0) {
720 if (is_first) {
721 is_first = false;
722 } else {
723 assert(buffer_used + 1 < buffer_size, "Too small buffer");
724 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, " ");
725 buffer_used++;
726 }
727 size_t length = strlen(d.name);
728 assert(buffer_used + length < buffer_size, "Too small buffer");
729 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "%s", d.name);
730 buffer_used += length;
731 }
732 }
733 assert(buffer_used + 2 <= buffer_size, "Too small buffer");
734 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
735 st->print("%*s", width, kind);
736 }
737 }
738
739 void Flag::print_origin(outputStream* st, unsigned int width) {
740 int origin = _flags & VALUE_ORIGIN_MASK;
741 st->print("{");
742 switch(origin) {
743 case DEFAULT:
744 st->print("default"); break;
745 case COMMAND_LINE:
746 st->print("command line"); break;
747 case ENVIRON_VAR:
748 st->print("environment"); break;
749 case CONFIG_FILE:
750 st->print("config file"); break;
751 case MANAGEMENT:
752 st->print("management"); break;
753 case ERGONOMIC:
754 if (_flags & ORIG_COMMAND_LINE) {
755 st->print("command line, ");
756 }
757 st->print("ergonomic"); break;
758 case ATTACH_ON_DEMAND:
759 st->print("attach"); break;
760 case INTERNAL:
761 st->print("internal"); break;
|