ssssssss70


bool Arguments::parse_argument(const char* arg, Flag::Flags origin) {
#define NAME_RANGE  "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]"
#define BUFLEN 255
  char name[BUFLEN+1];
  char dummy;
  if (sscanf(arg, "-%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) {
    return set_bool_flag(name, false, origin);
  }
  if (sscanf(arg, "+%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) {
    return set_bool_flag(name, true, origin);
  }
  char punct;
  if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "%c", name, &punct) == 2 && punct == '=') {
    const char* value = strchr(arg, '=') + 1;
    Flag* flag = Flag::find_flag(name, strlen(name));
    if (flag != NULL && flag->is_ccstr()) {
      if (flag->ccstr_accumulates()) {
        return append_to_string_flag(name, value, origin);
      } else {
        if (value[0] == '\0') {
          value = NULL;
        }
        return set_string_flag(name, value, origin);
      }
    }
  }
  if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE ":%c", name, &punct) == 2 && punct == '=') {
    const char* value = strchr(arg, '=') + 1;
    if (value[0] == '\0') {
      value = NULL;
    }
    return set_string_flag(name, value, origin);
  }
#define SIGNED_FP_NUMBER_RANGE "[-0123456789.]"
#define SIGNED_NUMBER_RANGE    "[-0123456789]"
#define        NUMBER_RANGE    "[0123456789]"
  char value[BUFLEN + 1];
  char value2[BUFLEN + 1];
  if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) SIGNED_NUMBER_RANGE "." "%" XSTR(BUFLEN) NUMBER_RANGE "%c", name, value, value2, &dummy) == 3) {
    if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) SIGNED_FP_NUMBER_RANGE "%c", name, value, &dummy) == 2) {
      return set_fp_numeric_flag(name, value, origin);
    }
  }
#define VALUE_RANGE "[-kmgtKMGT0123456789]"
  if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) VALUE_RANGE "%c", name, value, &dummy) == 2) {
    return set_numeric_flag(name, value, origin);
  }
  return false;
}
void Arguments::add_string(char*** bldarray, int* count, const char* arg) {
  assert(bldarray != NULL, "illegal argument");
  if (arg == NULL) {
    return;
  }
  int new_count = *count + 1;
  if (*bldarray == NULL) {
  } else {
  }
  (*bldarray)[*count] = strdup(arg);
}
void Arguments::build_jvm_args(const char* arg) {
  add_string(&_jvm_args_array, &_num_jvm_args, arg);
}
void Arguments::build_jvm_flags(const char* arg) {
  add_string(&_jvm_flags_array, &_num_jvm_flags, arg);
}
const char* Arguments::build_resource_string(char** args, int count) {
  if (args == NULL || count == 0) {
    return NULL;
  }
  size_t length = 0;
  for (int i = 0; i < count; i++) {
    length += strlen(args[i]) + 1; // add 1 for a space or NULL terminating character
  }
  char* s = NEW_RESOURCE_ARRAY(char, length);
  char* dst = s;
  for (int j = 0; j < count; j++) {
    size_t offset = strlen(args[j]) + 1; // add 1 for a space or NULL terminating character
    jio_snprintf(dst, length, "%s ", args[j]); // jio_snprintf will replace the last space character with NULL character
    dst += offset;
    length -= offset;
  }
  return (const char*) s;
}
void Arguments::print_on(outputStream* st) {
  st->print_cr("VM Arguments:");
  if (num_jvm_flags() > 0) {
    st->print("jvm_flags: "); print_jvm_flags_on(st);
  }
  if (num_jvm_args() > 0) {
    st->print("jvm_args: "); print_jvm_args_on(st);
  }
  st->print_cr("java_command: %s", java_command() ? java_command() : "<unknown>");
  if (_java_class_path != NULL) {
    char* path = _java_class_path->value();
    st->print_cr("java_class_path (initial): %s", strlen(path) == 0 ? "<not set>" : path );
  }
  st->print_cr("Launcher Type: %s", _sun_java_launcher);
}
void Arguments::print_jvm_flags_on(outputStream* st) {
  if (_num_jvm_flags > 0) {
    for (int i=0; i < _num_jvm_flags; i++) {
      st->print("%s ", _jvm_flags_array[i]);
    }
    st->cr();
  }
}
void Arguments::print_jvm_args_on(outputStream* st) {
  if (_num_jvm_args > 0) {
    for (int i=0; i < _num_jvm_args; i++) {
      st->print("%s ", _jvm_args_array[i]);
    }
    st->cr();
  }
}
bool Arguments::process_argument(const char* arg,
    jboolean ignore_unrecognized, Flag::Flags origin) {
  JDK_Version since = JDK_Version();
  if (parse_argument(arg, origin) || ignore_unrecognized) {
    return true;
  }
  bool has_plus_minus = (*arg == '+' || *arg == '-');
  const char* const argname = has_plus_minus ? arg + 1 : arg;
  if (is_newly_obsolete(arg, &since)) {
    char version[256];
    since.to_string(version, sizeof(version));
    warning("ignoring option %s; support was removed in %s", argname, version);
    return true;
  }
  size_t arg_len;
  const char* equal_sign = strchr(argname, '=');
  if (equal_sign == NULL) {
    arg_len = strlen(argname);
  } else {
    arg_len = equal_sign - argname;
  }
  Flag* found_flag = Flag::find_flag((const char*)argname, arg_len, true, true);
  if (found_flag != NULL) {
    char locked_message_buf[BUFLEN];
    found_flag->get_locked_message(locked_message_buf, BUFLEN);
    if (strlen(locked_message_buf) == 0) {
      if (found_flag->is_bool() && !has_plus_minus) {
        jio_fprintf(defaultStream::error_stream(),
          "Missing +/- setting for VM option '%s'\n", argname);
      } else if (!found_flag->is_bool() && has_plus_minus) {
        jio_fprintf(defaultStream::error_stream(),
          "Unexpected +/- setting in VM option '%s'\n", argname);
      } else {
        jio_fprintf(defaultStream::error_stream(),
          "Improperly specified VM option '%s'\n", argname);
      }
    } else {
      jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
    }
  } else {
    jio_fprintf(defaultStream::error_stream(),
                "Unrecognized VM option '%s'\n", argname);
    Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true);
    if (fuzzy_matched != NULL) {
      jio_fprintf(defaultStream::error_stream(),
                  "Did you mean '%s%s%s'?\n",
                  (fuzzy_matched->is_bool()) ? "(+/-)" : "",
                  fuzzy_matched->_name,
                  (fuzzy_matched->is_bool()) ? "" : "=<value>");
    }
  }
  return arg[0] == '#';
}
bool Arguments::process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized) {
  FILE* stream = fopen(file_name, "rb");
  if (stream == NULL) {
    if (should_exist) {
      jio_fprintf(defaultStream::error_stream(),
                  "Could not open settings file %s\n", file_name);
      return false;
    } else {
      return true;
    }
  }
  char token[1024];
  int  pos = 0;
  bool in_white_space = true;
  bool in_comment     = false;
  bool in_quote       = false;
  char quote_c        = 0;
  bool result         = true;
  int c = getc(stream);
  while(c != EOF && pos < (int)(sizeof(token)-1)) {
    if (in_white_space) {
      if (in_comment) {
        if (c == '\n') in_comment = false;
      } else {
        if (c == '#') in_comment = true;
        else if (!isspace(c)) {
          in_white_space = false;
          token[pos++] = c;
        }
      }
    } else {
      if (c == '\n' || (!in_quote && isspace(c))) {
        token[pos] = '\0';
        logOption(token);
        result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
        build_jvm_flags(token);
        pos = 0;
        in_white_space = true;
        in_quote = false;
      } else if (!in_quote && (c == '\'' || c == '"')) {
        in_quote = true;
        quote_c = c;
      } else if (in_quote && (c == quote_c)) {
        in_quote = false;
      } else {
        token[pos++] = c;
      }
    }
    c = getc(stream);
  }
  if (pos > 0) {
    token[pos] = '\0';
    result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
    build_jvm_flags(token);
  }
  fclose(stream);
  return result;
}
const char* Arguments::get_property(const char* key) {
  return PropertyList_get_value(system_properties(), key);
}
bool Arguments::add_property(const char* prop) {
  const char* eq = strchr(prop, '=');
  char* key;
  const static char ns[1] = {0};
  char* value = (char *)ns;
  size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop);
  key = AllocateHeap(key_len + 1, mtInternal);
  strncpy(key, prop, key_len);
  key[key_len] = '\0';
  if (eq != NULL) {
    size_t value_len = strlen(prop) - key_len - 1;
    value = AllocateHeap(value_len + 1, mtInternal);
    strncpy(value, &prop[key_len + 1], value_len + 1);
  }
  if (strcmp(key, "java.compiler") == 0) {
    process_java_compiler_argument(value);
    FreeHeap(key);
    if (eq != NULL) {
      FreeHeap(value);
    }
    return true;
  } else if (strcmp(key, "sun.java.command") == 0) {
    _java_command = value;
  } else if (strcmp(key, "sun.java.launcher.pid") == 0) {
    FreeHeap(key);
    if (eq != NULL) {
      FreeHeap(value);
    }
    return true;
  } else if (strcmp(key, "java.vendor.url.bug") == 0) {
    _java_vendor_url_bug = value;
  } else if (strcmp(key, "sun.boot.library.path") == 0) {
    PropertyList_unique_add(&_system_properties, key, value, true);
    return true;
  }
  PropertyList_unique_add(&_system_properties, key, value);
  return true;
}
void Arguments::set_mode_flags(Mode mode) {
  set_java_compiler(false);
  _mode                      = mode;
  PropertyList_unique_add(&_system_properties, "java.vm.info",
                          (char*)VM_Version::vm_info_string(), false);
  UseInterpreter             = true;
  UseCompiler                = true;
  UseLoopCounter             = true;
#ifndef ZERO
  if (FLAG_IS_DEFAULT(UseFastAccessorMethods)) {
    UseFastAccessorMethods = (mode == _int);
  }
  if (FLAG_IS_DEFAULT(UseFastEmptyMethods)) {
    UseFastEmptyMethods = (mode == _int);
  }
#endif
  ClipInlining               = Arguments::_ClipInlining;
  AlwaysCompileLoopMethods   = Arguments::_AlwaysCompileLoopMethods;
  UseOnStackReplacement      = Arguments::_UseOnStackReplacement;
  BackgroundCompilation      = Arguments::_BackgroundCompilation;
  switch (mode) {
  default:
    ShouldNotReachHere();
    break;
  case _int:
    UseCompiler              = false;
    UseLoopCounter           = false;
    AlwaysCompileLoopMethods = false;
    UseOnStackReplacement    = false;
    break;
  case _mixed:
    break;
  case _comp:
    UseInterpreter           = false;
    BackgroundCompilation    = false;
    ClipInlining             = false;
    if (TieredCompilation) {
      Tier3InvokeNotifyFreqLog = 0;
      Tier4InvocationThreshold = 0;
    }
    break;
  }
}
#if defined(COMPILER2) || defined(_LP64) || !INCLUDE_CDS
static void no_shared_spaces(const char* message) {
  if (RequireSharedSpaces) {
    jio_fprintf(defaultStream::error_stream(),
      "Class data sharing is inconsistent with other specified options.\n");
    vm_exit_during_initialization("Unable to use shared archive.", message);
  } else {
    FLAG_SET_DEFAULT(UseSharedSpaces, false);
  }
}
#endif
void Arguments::set_tiered_flags() {
  if (FLAG_IS_DEFAULT(CompilationPolicyChoice)) {
    FLAG_SET_DEFAULT(CompilationPolicyChoice, 3);
  }
  if (CompilationPolicyChoice < 2) {
    vm_exit_during_initialization(
      "Incompatible compilation policy selected", NULL);
  }
  if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
#ifndef AARCH64
    FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 5);
#else
    FLAG_SET_DEFAULT(ReservedCodeCacheSize,
                     MIN2(CODE_CACHE_DEFAULT_LIMIT, ReservedCodeCacheSize * 5));
#endif
  }
  if (!UseInterpreter) { // -Xcomp
    Tier3InvokeNotifyFreqLog = 0;
    Tier4InvocationThreshold = 0;
  }
}
int Arguments::get_min_number_of_compiler_threads() {
#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
  return 0;   // case 1
#else
  if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
    return 1; // case 2 or case 3
  }
  return 2;   // case 4 (tiered)
#endif
}
#if INCLUDE_ALL_GCS
static void disable_adaptive_size_policy(const char* collector_name) {
  if (UseAdaptiveSizePolicy) {
    if (FLAG_IS_CMDLINE(UseAdaptiveSizePolicy)) {
      warning("disabling UseAdaptiveSizePolicy; it is incompatible with %s.",
              collector_name);
    }
    FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
  }
}
void Arguments::set_parnew_gc_flags() {
  assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC && !UseG1GC,
         "control point invariant");
  assert(UseParNewGC, "Error");
  disable_adaptive_size_policy("UseParNewGC");
  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
    FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads());
    assert(ParallelGCThreads > 0, "We should always have at least one thread by default");
  } else if (ParallelGCThreads == 0) {
    jio_fprintf(defaultStream::error_stream(),
        "The ParNew GC can not be combined with -XX:ParallelGCThreads=0\n");
    vm_exit(1);
  }
  if (FLAG_IS_DEFAULT(YoungPLABSize)) {
    FLAG_SET_DEFAULT(YoungPLABSize, (intx)1024);
  }
  if (FLAG_IS_DEFAULT(OldPLABSize)) {
    FLAG_SET_DEFAULT(OldPLABSize, (intx)1024);
  }
  if (AlwaysTenure) {
    FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0);
  }
  if (UseCompressedOops && !ParGCUseLocalOverflow) {
    if (!FLAG_IS_DEFAULT(ParGCUseLocalOverflow)) {
      warning("Forcing +ParGCUseLocalOverflow: needed if using compressed references");
    }
    FLAG_SET_DEFAULT(ParGCUseLocalOverflow, true);
  }
  assert(ParGCUseLocalOverflow || !UseCompressedOops, "Error");
}
void Arguments::set_cms_and_parnew_gc_flags() {
  assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC, "Error");
  assert(UseConcMarkSweepGC, "CMS is expected to be on here");
  if (FLAG_IS_DEFAULT(UseParNewGC)) {
    FLAG_SET_ERGO(bool, UseParNewGC, true);
  }
  disable_adaptive_size_policy("UseConcMarkSweepGC");
  if (UseParNewGC) {
    set_parnew_gc_flags();
  }
  size_t max_heap = align_size_down(MaxHeapSize,
                                    CardTableRS::ct_max_alignment_constraint());
  intx   tenuring_default = (intx)6;
  size_t young_gen_per_worker = CMSYoungGenPerWorker;
  const uintx parallel_gc_threads =
    (ParallelGCThreads == 0 ? 1 : ParallelGCThreads);
  const size_t preferred_max_new_size_unaligned =
    MIN2(max_heap/(NewRatio+1), ScaleForWordSize(young_gen_per_worker * parallel_gc_threads));
  size_t preferred_max_new_size =
    align_size_up(preferred_max_new_size_unaligned, os::vm_page_size());
  if (FLAG_IS_DEFAULT(MaxNewSize) && FLAG_IS_DEFAULT(NewRatio)) {
    if (!FLAG_IS_DEFAULT(NewSize)) {   // NewSize explicitly set at command-line
      FLAG_SET_ERGO(uintx, MaxNewSize, MAX2(NewSize, preferred_max_new_size));
    } else {
      FLAG_SET_ERGO(uintx, MaxNewSize, preferred_max_new_size);
    }
    if (PrintGCDetails && Verbose) {
      tty->print_cr("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
    }
    if (PrintGCDetails && Verbose) {
      tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT
           " initial_heap_size:  " SIZE_FORMAT
           " max_heap: " SIZE_FORMAT,
           min_heap_size(), InitialHeapSize, max_heap);
    }
    size_t min_new = preferred_max_new_size;
    if (FLAG_IS_CMDLINE(NewSize)) {
      min_new = NewSize;
    }
    if (max_heap > min_new && min_heap_size() > min_new) {
      if (FLAG_IS_DEFAULT(NewSize)) {
        FLAG_SET_ERGO(uintx, NewSize, MAX2(NewSize, min_new));
        FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize));
        if (PrintGCDetails && Verbose) {
          tty->print_cr("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
        }
      }
      if (FLAG_IS_DEFAULT(OldSize)) {
        if (max_heap > NewSize) {
          FLAG_SET_ERGO(uintx, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
          if (PrintGCDetails && Verbose) {
            tty->print_cr("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
          }
        }
      }
    }
  }
  if (FLAG_IS_DEFAULT(MaxTenuringThreshold) &&
      FLAG_IS_DEFAULT(SurvivorRatio)) {
    FLAG_SET_ERGO(uintx, MaxTenuringThreshold, tenuring_default);
  }
  if (FLAG_IS_DEFAULT(SurvivorRatio) && MaxTenuringThreshold == 0) {
    FLAG_SET_ERGO(uintx, SurvivorRatio, MAX2((uintx)1024, SurvivorRatio));
  }
  if (!FLAG_IS_DEFAULT(OldPLABSize)) {
    if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) {
      FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, OldPLABSize);
    } else {
      jio_fprintf(defaultStream::error_stream(),
                  "Both OldPLABSize and CMSParPromoteBlocksToClaim"
                  " options are specified for the CMS collector."
                  " CMSParPromoteBlocksToClaim will take precedence.\n");
    }
  }
  if (!FLAG_IS_DEFAULT(ResizeOldPLAB) && !ResizeOldPLAB) {
    if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) {
      FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, 50); // default value before 6631166
    }
  }
  FLAG_SET_ERGO(uintx, OldPLABSize, CMSParPromoteBlocksToClaim);
  if (!FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim) || !FLAG_IS_DEFAULT(OldPLABWeight)) {
    CFLS_LAB::modify_initialization(OldPLABSize, OldPLABWeight);
  }
  if (PrintGCDetails && Verbose) {
    tty->print_cr("MarkStackSize: %uk  MarkStackSizeMax: %uk",
      (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
    tty->print_cr("ConcGCThreads: %u", (uint) ConcGCThreads);
  }
}
#endif // INCLUDE_ALL_GCS
void set_object_alignment() {
  assert(is_power_of_2(ObjectAlignmentInBytes), "ObjectAlignmentInBytes must be power of 2");
  MinObjAlignmentInBytes     = ObjectAlignmentInBytes;
  assert(MinObjAlignmentInBytes >= HeapWordsPerLong * HeapWordSize, "ObjectAlignmentInBytes value is too small");
  MinObjAlignment            = MinObjAlignmentInBytes / HeapWordSize;
  assert(MinObjAlignmentInBytes == MinObjAlignment * HeapWordSize, "ObjectAlignmentInBytes value is incorrect");
  MinObjAlignmentInBytesMask = MinObjAlignmentInBytes - 1;
  LogMinObjAlignmentInBytes  = exact_log2(ObjectAlignmentInBytes);
  LogMinObjAlignment         = LogMinObjAlignmentInBytes - LogHeapWordSize;
  OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;
#if INCLUDE_ALL_GCS
  CompactibleFreeListSpace::set_cms_values();
#endif // INCLUDE_ALL_GCS
}
bool verify_object_alignment() {
  if (!is_power_of_2(ObjectAlignmentInBytes)) {
    jio_fprintf(defaultStream::error_stream(),
                "error: ObjectAlignmentInBytes=%d must be power of 2\n",
                (int)ObjectAlignmentInBytes);
    return false;
  }
  if ((int)ObjectAlignmentInBytes < BytesPerLong) {
    jio_fprintf(defaultStream::error_stream(),
                "error: ObjectAlignmentInBytes=%d must be greater or equal %d\n",
                (int)ObjectAlignmentInBytes, BytesPerLong);
    return false;
  }
  if ((int)ObjectAlignmentInBytes > 256) {
    jio_fprintf(defaultStream::error_stream(),
                "error: ObjectAlignmentInBytes=%d must not be greater than 256\n",
                (int)ObjectAlignmentInBytes);
    return false;
  }
  if ((int)ObjectAlignmentInBytes >= os::vm_page_size()) {
    jio_fprintf(defaultStream::error_stream(),
                "error: ObjectAlignmentInBytes=%d must be less than page size %d\n",
                (int)ObjectAlignmentInBytes, os::vm_page_size());
    return false;
  }
  if(SurvivorAlignmentInBytes == 0) {
    SurvivorAlignmentInBytes = ObjectAlignmentInBytes;
  } else {
    if (!is_power_of_2(SurvivorAlignmentInBytes)) {
      jio_fprintf(defaultStream::error_stream(),
            "error: SurvivorAlignmentInBytes=%d must be power of 2\n",
            (int)SurvivorAlignmentInBytes);
      return false;
    }
    if (SurvivorAlignmentInBytes < ObjectAlignmentInBytes) {
      jio_fprintf(defaultStream::error_stream(),
          "error: SurvivorAlignmentInBytes=%d must be greater than ObjectAlignmentInBytes=%d \n",
          (int)SurvivorAlignmentInBytes, (int)ObjectAlignmentInBytes);
      return false;
    }
  }
  return true;
}
size_t Arguments::max_heap_for_compressed_oops() {
  assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size");
  size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(),
                                                        _conservative_max_heap_alignment);
  LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page);
  NOT_LP64(ShouldNotReachHere(); return 0);
}
bool Arguments::should_auto_select_low_pause_collector() {
  if (UseAutoGCSelectPolicy &&
      !FLAG_IS_DEFAULT(MaxGCPauseMillis) &&
      (MaxGCPauseMillis <= AutoGCSelectPauseMillis)) {
    if (PrintGCDetails) {
      tty->print_cr("Automatic selection of the low pause collector"
       " based on pause goal of %d (ms)", (int) MaxGCPauseMillis);
    }
    return true;
  }
  return false;
}
void Arguments::set_use_compressed_oops() {
#ifndef ZERO
#ifdef _LP64
  size_t max_heap_size = MAX2(MaxHeapSize, InitialHeapSize);
  if (max_heap_size <= max_heap_for_compressed_oops()) {
#if !defined(COMPILER1) || defined(TIERED)
    if (FLAG_IS_DEFAULT(UseCompressedOops)) {
      FLAG_SET_ERGO(bool, UseCompressedOops, true);
    }
#endif
#ifdef _WIN64
    if (UseLargePages && UseCompressedOops) {
      Universe::set_narrow_oop_use_implicit_null_checks(false);
    }
#endif //  _WIN64
  } else {
    if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
      warning("Max heap size too large for Compressed Oops");
      FLAG_SET_DEFAULT(UseCompressedOops, false);
      FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
    }
  }
#endif // _LP64
#endif // ZERO
}
void Arguments::set_use_compressed_klass_ptrs() {
#ifndef ZERO
#ifdef _LP64
  if (!UseCompressedOops) {
    if (UseCompressedClassPointers) {
      warning("UseCompressedClassPointers requires UseCompressedOops");
    }
    FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
  } else {
    if (FLAG_IS_DEFAULT(UseCompressedClassPointers)) {
      FLAG_SET_ERGO(bool, UseCompressedClassPointers, true);
    }
    if (UseCompressedClassPointers) {
      if (CompressedClassSpaceSize > KlassEncodingMetaspaceMax) {
        warning("CompressedClassSpaceSize is too large for UseCompressedClassPointers");
        FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
      }
    }
  }
#endif // _LP64
#endif // !ZERO
}
void Arguments::set_conservative_max_heap_alignment() {
  size_t heap_alignment = GenCollectedHeap::conservative_max_heap_alignment();
#if INCLUDE_ALL_GCS
  if (UseParallelGC) {
    heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment();
  } else if (UseG1GC) {
    heap_alignment = G1CollectedHeap::conservative_max_heap_alignment();
  }
#endif // INCLUDE_ALL_GCS
  _conservative_max_heap_alignment = MAX4(heap_alignment,
                                          (size_t)os::vm_allocation_granularity(),
                                          os::max_page_size(),
                                          CollectorPolicy::compute_heap_alignment());
}
void Arguments::select_gc_ergonomically() {
  if (os::is_server_class_machine()) {
    if (should_auto_select_low_pause_collector()) {
      FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
    } else {
      FLAG_SET_ERGO(bool, UseParallelGC, true);
    }
  }
}
void Arguments::select_gc() {
  if (!gc_selected()) {
    select_gc_ergonomically();
  }
}
void Arguments::set_ergonomics_flags() {
  select_gc();
#ifdef COMPILER2
  if (!DumpSharedSpaces && !RequireSharedSpaces &&
      (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
    no_shared_spaces("COMPILER2 default: -Xshare:auto | off, have to manually setup to on.");
  }
#endif
  set_conservative_max_heap_alignment();
#ifndef ZERO
#ifdef _LP64
  set_use_compressed_oops();
  set_use_compressed_klass_ptrs();
#endif // _LP64
#endif // !ZERO
}
void Arguments::set_parallel_gc_flags() {
  assert(UseParallelGC || UseParallelOldGC, "Error");
  if (FLAG_IS_DEFAULT(UseParallelOldGC)) {
    FLAG_SET_DEFAULT(UseParallelOldGC, true);
  }
  FLAG_SET_DEFAULT(UseParallelGC, true);
  FLAG_SET_DEFAULT(ParallelGCThreads,
                   Abstract_VM_Version::parallel_worker_threads());
  if (ParallelGCThreads == 0) {
    jio_fprintf(defaultStream::error_stream(),
        "The Parallel GC can not be combined with -XX:ParallelGCThreads=0\n");
    vm_exit(1);
  }
  if (UseAdaptiveSizePolicy) {
    if (FLAG_IS_DEFAULT(MinHeapFreeRatio)) {
      FLAG_SET_DEFAULT(MinHeapFreeRatio, 0);
      _min_heap_free_ratio = MinHeapFreeRatio;
    }
    if (FLAG_IS_DEFAULT(MaxHeapFreeRatio)) {
      FLAG_SET_DEFAULT(MaxHeapFreeRatio, 100);
      _max_heap_free_ratio = MaxHeapFreeRatio;
    }
  }
  if (!FLAG_IS_DEFAULT(SurvivorRatio)) {
    if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) {
       FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2);
    }
    if (FLAG_IS_DEFAULT(MinSurvivorRatio)) {
      FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2);
    }
  }
  if (UseParallelOldGC) {
    if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) {
      FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1);
    }
  }
}
void Arguments::set_g1_gc_flags() {
  assert(UseG1GC, "Error");
#ifdef COMPILER1
  FastTLABRefill = false;
#endif
  FLAG_SET_DEFAULT(ParallelGCThreads,
                     Abstract_VM_Version::parallel_worker_threads());
  if (ParallelGCThreads == 0) {
    vm_exit_during_initialization("The flag -XX:+UseG1GC can not be combined with -XX:ParallelGCThreads=0", NULL);
    }
#if INCLUDE_ALL_GCS
  if (G1ConcRefinementThreads == 0) {
    FLAG_SET_DEFAULT(G1ConcRefinementThreads, ParallelGCThreads);
  }
#endif
  if (FLAG_IS_DEFAULT(MarkStackSizeMax)) {
    FLAG_SET_DEFAULT(MarkStackSizeMax, 128 * TASKQUEUE_SIZE);
  }
  if (FLAG_IS_DEFAULT(GCTimeRatio) || GCTimeRatio == 0) {
    FLAG_SET_DEFAULT(GCTimeRatio, 9);
  }
  if (PrintGCDetails && Verbose) {
    tty->print_cr("MarkStackSize: %uk  MarkStackSizeMax: %uk",
      (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
    tty->print_cr("ConcGCThreads: %u", (uint) ConcGCThreads);
  }
}
#if !INCLUDE_ALL_GCS
#ifdef ASSERT
static bool verify_serial_gc_flags() {
  return (UseSerialGC &&
        !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||
          UseParallelGC || UseParallelOldGC));
}
#endif // ASSERT
#endif // INCLUDE_ALL_GCS
void Arguments::set_gc_specific_flags() {
#if INCLUDE_ALL_GCS
  if (UseParallelGC || UseParallelOldGC) {
    set_parallel_gc_flags();
  } else if (UseConcMarkSweepGC) { // Should be done before ParNew check below
    set_cms_and_parnew_gc_flags();
  } else if (UseParNewGC) {  // Skipped if CMS is set above
    set_parnew_gc_flags();
  } else if (UseG1GC) {
    set_g1_gc_flags();
  }
  check_deprecated_gcs();
  check_deprecated_gc_flags();
  if (AssumeMP && !UseSerialGC) {
    if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
      warning("If the number of processors is expected to increase from one, then"
              " you should configure the number of parallel GC threads appropriately"
              " using -XX:ParallelGCThreads=N");
    }
  }
  if (MinHeapFreeRatio == 100) {
    FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
  }
  if (!ClassUnloading) {
    FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false);
    FLAG_SET_CMDLINE(bool, ClassUnloadingWithConcurrentMark, false);
    FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false);
  }
#else // INCLUDE_ALL_GCS
  assert(verify_serial_gc_flags(), "SerialGC unset");
#endif // INCLUDE_ALL_GCS
}
julong Arguments::limit_by_allocatable_memory(julong limit) {
  julong max_allocatable;
  julong result = limit;
  if (os::has_allocatable_memory_limit(&max_allocatable)) {
    result = MIN2(result, max_allocatable / MaxVirtMemFraction);
  }
  return result;
}
void Arguments::set_heap_size() {
  if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
    FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction);
  }
  julong phys_mem =
    FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
                            : (julong)MaxRAM;
  if (UseCGroupMemoryLimitForHeap) {
    const char* lim_file = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
    FILE *fp = fopen(lim_file, "r");
    if (fp != NULL) {
      julong cgroup_max = 0;
      int ret = fscanf(fp, JULONG_FORMAT, &cgroup_max);
      if (ret == 1 && cgroup_max > 0) {
        if (PrintGCDetails && Verbose) {
          tty->print_cr("Setting phys_mem to the min of cgroup limit ("
                        JULONG_FORMAT "MB) and initial phys_mem ("
                        JULONG_FORMAT "MB)", cgroup_max/M, phys_mem/M);
        }
        phys_mem = MIN2(cgroup_max, phys_mem);
      } else {
        warning("Unable to read/parse cgroup memory limit from %s: %s",
                lim_file, errno != 0 ? strerror(errno) : "unknown error");
      }
      fclose(fp);
    } else {
      warning("Unable to open cgroup memory limit file %s (%s)", lim_file, strerror(errno));
    }
  }
  if (FLAG_IS_DEFAULT(MaxRAMPercentage) &&
      !FLAG_IS_DEFAULT(MaxRAMFraction))
    MaxRAMPercentage = 100.0 / MaxRAMFraction;
   if (FLAG_IS_DEFAULT(MinRAMPercentage) &&
       !FLAG_IS_DEFAULT(MinRAMFraction))
     MinRAMPercentage = 100.0 / MinRAMFraction;
   if (FLAG_IS_DEFAULT(InitialRAMPercentage) &&
       !FLAG_IS_DEFAULT(InitialRAMFraction))
     InitialRAMPercentage = 100.0 / InitialRAMFraction;
  if (FLAG_IS_DEFAULT(MaxHeapSize)) {
    julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
    const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);
    if (reasonable_min < MaxHeapSize) {
      reasonable_max = reasonable_min;
    } else {
      reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize);
    }
    if (!FLAG_IS_DEFAULT(ErgoHeapSizeLimit) && ErgoHeapSizeLimit != 0) {
      reasonable_max = MIN2(reasonable_max, (julong)ErgoHeapSizeLimit);
    }
    if (UseCompressedOops) {
      julong max_coop_heap = (julong)max_heap_for_compressed_oops();
      if (HeapBaseMinAddress + MaxHeapSize < max_coop_heap) {
        max_coop_heap -= HeapBaseMinAddress;
      }
      reasonable_max = MIN2(reasonable_max, max_coop_heap);
    }
    reasonable_max = limit_by_allocatable_memory(reasonable_max);
    if (!FLAG_IS_DEFAULT(InitialHeapSize)) {
      reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize);
    }
    if (PrintGCDetails && Verbose) {
      tty->print_cr("  Maximum heap size " SIZE_FORMAT, (size_t) reasonable_max);
    }
    FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max);
  }
  if (InitialHeapSize == 0 || min_heap_size() == 0) {
    julong reasonable_minimum = (julong)(OldSize + NewSize);
    reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);
    reasonable_minimum = limit_by_allocatable_memory(reasonable_minimum);
    if (InitialHeapSize == 0) {
      julong reasonable_initial = (julong)((phys_mem * InitialRAMPercentage) / 100);
      reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, (julong)min_heap_size());
      reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
      reasonable_initial = limit_by_allocatable_memory(reasonable_initial);
      if (PrintGCDetails && Verbose) {
        tty->print_cr("  Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial);
      }
      FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial);
    }
    if (min_heap_size() == 0) {
      set_min_heap_size(MIN2((uintx)reasonable_minimum, InitialHeapSize));
      if (PrintGCDetails && Verbose) {
        tty->print_cr("  Minimum heap size " SIZE_FORMAT, min_heap_size());
      }
    }
  }
}
jint Arguments::set_aggressive_heap_flags() {
  julong initHeapSize;
  julong total_memory = os::physical_memory();
  if (total_memory < (julong) 256 * M) {
    jio_fprintf(defaultStream::error_stream(),
            "You need at least 256mb of memory to use -XX:+AggressiveHeap\n");
    vm_exit(1);
  }
  initHeapSize = MIN2(total_memory / (julong) 2,
                      total_memory - (julong) 160 * M);
  initHeapSize = limit_by_allocatable_memory(initHeapSize);
  if (FLAG_IS_DEFAULT(MaxHeapSize)) {
    FLAG_SET_CMDLINE(uintx, MaxHeapSize, initHeapSize);
    FLAG_SET_CMDLINE(uintx, InitialHeapSize, initHeapSize);
    set_min_heap_size(initHeapSize);
  }
  if (FLAG_IS_DEFAULT(NewSize)) {
    FLAG_SET_CMDLINE(uintx, NewSize,
            ((julong) MaxHeapSize / (julong) 8) * (julong) 3);
    FLAG_SET_CMDLINE(uintx, MaxNewSize, NewSize);
  }
#ifndef _ALLBSD_SOURCE  // UseLargePages is not yet supported on BSD.
  FLAG_SET_DEFAULT(UseLargePages, true);
#endif
  FLAG_SET_CMDLINE(uintx, BaseFootPrintEstimate, MaxHeapSize);
  FLAG_SET_CMDLINE(bool, ResizeTLAB, false);
  FLAG_SET_CMDLINE(uintx, TLABSize, 256 * K);
  FLAG_SET_CMDLINE(uintx, YoungPLABSize, 256 * K);     // Note: this is in words
  FLAG_SET_CMDLINE(uintx, OldPLABSize, 8 * K);      // Note: this is in words
  FLAG_SET_CMDLINE(bool, UseParallelGC, true);
  FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
  FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
  FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true);
  return JNI_OK;
}
void Arguments::set_bytecode_flags() {
  if (UseSharedSpaces) {
    FLAG_SET_DEFAULT(RewriteBytecodes, false);
    FLAG_SET_DEFAULT(RewriteFrequentPairs, false);
  }
  if (!RewriteBytecodes) {
    FLAG_SET_DEFAULT(RewriteFrequentPairs, false);
  }
}
void Arguments::set_aggressive_opts_flags() {
#ifdef COMPILER2
  if (AggressiveUnboxing) {
    if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
      FLAG_SET_DEFAULT(EliminateAutoBox, true);
    } else if (!EliminateAutoBox) {
      AggressiveUnboxing = false;
    }
    if (FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
      FLAG_SET_DEFAULT(DoEscapeAnalysis, true);
    } else if (!DoEscapeAnalysis) {
      AggressiveUnboxing = false;
    }
  }
  if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
    if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
      FLAG_SET_DEFAULT(EliminateAutoBox, true);
    }
    if (FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
      FLAG_SET_DEFAULT(AutoBoxCacheMax, 20000);
    }
    char buffer[1024];
    jio_snprintf(buffer, 1024, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
    add_property(buffer);
  }
  if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
    FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
  }
#endif
  if (AggressiveOpts) {
  }
}
void Arguments::process_java_compiler_argument(char* arg) {
  if (strlen(arg) == 0 || strcasecmp(arg, "NONE") == 0) {
    set_java_compiler(true);    // "-Djava.compiler[=...]" most recently seen.
  }
}
void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) {
  _sun_java_launcher = strdup(launcher);
  if (strcmp("gamma", _sun_java_launcher) == 0) {
    _created_by_gamma_launcher = true;
  }
}
bool Arguments::created_by_java_launcher() {
  assert(_sun_java_launcher != NULL, "property must have value");
  return strcmp(DEFAULT_JAVA_LAUNCHER, _sun_java_launcher) != 0;
}
bool Arguments::created_by_gamma_launcher() {
  return _created_by_gamma_launcher;
}
bool Arguments::verify_interval(uintx val, uintx min,
                                uintx max, const char* name) {
  if (val >= min && val <= max) {
    return true;
  }
  jio_fprintf(defaultStream::error_stream(),
              "%s of " UINTX_FORMAT " is invalid; must be between " UINTX_FORMAT
              " and " UINTX_FORMAT "\n",
              name, val, min, max);
  return false;
}
bool Arguments::verify_min_value(intx val, intx min, const char* name) {
  if (val >= min ) {
      return true;
  }
  jio_fprintf(defaultStream::error_stream(),
              "%s of " INTX_FORMAT " is invalid; must be at least " INTX_FORMAT "\n",
              name, val, min);
  return false;
}
bool Arguments::verify_percentage(uintx value, const char* name) {
  if (is_percentage(value)) {
    return true;
  }
  jio_fprintf(defaultStream::error_stream(),
              "%s of " UINTX_FORMAT " is invalid; must be between 0 and 100\n",
              name, value);
  return false;
}
void check_gclog_consistency() {
  if (UseGCLogFileRotation) {
    if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) {
      jio_fprintf(defaultStream::output_stream(),
                  "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files>\n"
                  "where num_of_file > 0\n"
                  "GC log rotation is turned off\n");
      UseGCLogFileRotation = false;
    }
  }
  if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) {
    FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
    jio_fprintf(defaultStream::output_stream(),
                "GCLogFileSize changed to minimum 8K\n");
  }
}
bool is_filename_valid(const char *file_name) {
  const char* p = file_name;
  char file_sep = os::file_separator()[0];
  const char* cp;
  for (cp = file_name; *cp != '\0'; cp++) {
    if (*cp == '/' || *cp == file_sep) {
      p = cp + 1;
    }
  }
  int count_p = 0;
  int count_t = 0;
  while (*p != '\0') {
    if ((*p >= '0' && *p <= '9') ||
        (*p >= 'A' && *p <= 'Z') ||
        (*p >= 'a' && *p <= 'z') ||
       p++;
       continue;
    }
    if (*p == '%') {
      if(*(p + 1) == 'p') {
        p += 2;
        count_p ++;
        continue;
      }
      if (*(p + 1) == 't') {
        p += 2;
        count_t ++;
        continue;
      }
    }
    return false;
  }
  return count_p < 2 && count_t < 2;
}
bool Arguments::verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio) {
  if (!is_percentage(min_heap_free_ratio)) {
    err_msg.print("MinHeapFreeRatio must have a value between 0 and 100");
    return false;
  }
  if (min_heap_free_ratio > MaxHeapFreeRatio) {
    err_msg.print("MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
                  "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")", min_heap_free_ratio,
                  MaxHeapFreeRatio);
    return false;
  }
  _min_heap_free_ratio = min_heap_free_ratio;
  return true;
}
bool Arguments::verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio) {
  if (!is_percentage(max_heap_free_ratio)) {
    err_msg.print("MaxHeapFreeRatio must have a value between 0 and 100");
    return false;
  }
  if (max_heap_free_ratio < MinHeapFreeRatio) {
    err_msg.print("MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or "
                  "equal to MinHeapFreeRatio (" UINTX_FORMAT ")", max_heap_free_ratio,
                  MinHeapFreeRatio);
    return false;
  }
  _max_heap_free_ratio = max_heap_free_ratio;
  return true;
}
bool Arguments::check_gc_consistency() {
  check_gclog_consistency();
  bool status = true;
  uint i = 0;
  if (UseSerialGC)                       i++;
  if (UseConcMarkSweepGC || UseParNewGC) i++;
  if (UseParallelGC || UseParallelOldGC) i++;
  if (UseG1GC)                           i++;
  if (i > 1) {
    jio_fprintf(defaultStream::error_stream(),
                "Conflicting collector combinations in option list; "
                "please refer to the release notes for the combinations "
                "allowed\n");
    status = false;
  }
  return status;
}
void Arguments::check_deprecated_gcs() {
  if (UseConcMarkSweepGC && !UseParNewGC) {
    warning("Using the DefNew young collector with the CMS collector is deprecated "
        "and will likely be removed in a future release");
  }
  if (UseParNewGC && !UseConcMarkSweepGC) {
    warning("Using the ParNew young collector with the Serial old collector is deprecated "
        "and will likely be removed in a future release");
  }
  if (CMSIncrementalMode) {
    warning("Using incremental CMS is deprecated and will likely be removed in a future release");
  }
}
void Arguments::check_deprecated_gc_flags() {
  if (FLAG_IS_CMDLINE(MaxGCMinorPauseMillis)) {
    warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
            "and will likely be removed in future release");
  }
  if (FLAG_IS_CMDLINE(DefaultMaxRAMFraction)) {
    warning("DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. "
        "Use MaxRAMFraction instead.");
  }
  if (FLAG_IS_CMDLINE(UseCMSCompactAtFullCollection)) {
    warning("UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.");
  }
  if (FLAG_IS_CMDLINE(CMSFullGCsBeforeCompaction)) {
    warning("CMSFullGCsBeforeCompaction is deprecated and will likely be removed in a future release.");
  }
  if (FLAG_IS_CMDLINE(UseCMSCollectionPassing)) {
    warning("UseCMSCollectionPassing is deprecated and will likely be removed in a future release.");
  }
}
bool Arguments::check_stack_pages()
{
  bool status = true;
  status = status && verify_min_value(StackYellowPages, 1, "StackYellowPages");
  status = status && verify_min_value(StackRedPages, 1, "StackRedPages");
  status = status && verify_interval(StackShadowPages, 1, 50, "StackShadowPages");
  return status;
}
bool Arguments::check_vm_args_consistency() {
  bool status = true;
#if (defined(PRODUCT) && defined(SOLARIS))
  if (!UseBoundThreads && !UseStackBanging) {
    jio_fprintf(defaultStream::error_stream(),
                "-UseStackBanging conflicts with -UseBoundThreads\n");
     status = false;
  }
#endif
  if (TLABRefillWasteFraction == 0) {
    jio_fprintf(defaultStream::error_stream(),
                "TLABRefillWasteFraction should be a denominator, "
                "not " SIZE_FORMAT "\n",
                TLABRefillWasteFraction);
    status = false;
  }
  status = status && verify_interval(AdaptiveSizePolicyWeight, 0, 100,
                              "AdaptiveSizePolicyWeight");
  status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
  status = status && verify_interval(StringTableSize, minimumStringTableSize,
    (max_uintx / StringTable::bucket_size()), "StringTable size");
  status = status && verify_interval(SymbolTableSize, minimumSymbolTableSize,
    (max_uintx / SymbolTable::bucket_size()), "SymbolTable size");
  {
    FormatBuffer<80> err_msg("%s","");
    if (!verify_MinHeapFreeRatio(err_msg, MinHeapFreeRatio)) {
      jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
      status = false;
    } else if (!verify_MaxHeapFreeRatio(err_msg, MaxHeapFreeRatio)) {
      jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
      status = false;
    }
  }
  status = status && verify_percentage(MinMetaspaceFreeRatio, "MinMetaspaceFreeRatio");
  status = status && verify_percentage(MaxMetaspaceFreeRatio, "MaxMetaspaceFreeRatio");
  if (MinMetaspaceFreeRatio > MaxMetaspaceFreeRatio) {
    jio_fprintf(defaultStream::error_stream(),
                "MinMetaspaceFreeRatio (%s" UINTX_FORMAT ") must be less than or "
                "equal to MaxMetaspaceFreeRatio (%s" UINTX_FORMAT ")\n",
                FLAG_IS_DEFAULT(MinMetaspaceFreeRatio) ? "Default: " : "",
                MinMetaspaceFreeRatio,
                FLAG_IS_DEFAULT(MaxMetaspaceFreeRatio) ? "Default: " : "",
                MaxMetaspaceFreeRatio);
    status = false;
  }
  MinMetaspaceFreeRatio = MIN2(MinMetaspaceFreeRatio, (uintx) 99);
  if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) {
    MarkSweepAlwaysCompactCount = 1;  // Move objects every gc.
  }
  if (UseParallelOldGC && ParallelOldGCSplitALot) {
    if (!FLAG_IS_CMDLINE(NewRatio)) {
      FLAG_SET_CMDLINE(uintx, NewRatio, 2);
    }
    if (!FLAG_IS_CMDLINE(ScavengeBeforeFullGC)) {
      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
    }
  }
  status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
  status = status && verify_percentage(GCTimeLimit, "GCTimeLimit");
  if (GCTimeLimit == 100) {
    FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
  }
  status = status && check_gc_consistency();
  status = status && check_stack_pages();
  if (CMSIncrementalMode) {
    if (!UseConcMarkSweepGC) {
      jio_fprintf(defaultStream::error_stream(),
                  "error:  invalid argument combination.\n"
                  "The CMS collector (-XX:+UseConcMarkSweepGC) must be "
                  "selected in order\nto use CMSIncrementalMode.\n");
      status = false;
    } else {
      status = status && verify_percentage(CMSIncrementalDutyCycle,
                                  "CMSIncrementalDutyCycle");
      status = status && verify_percentage(CMSIncrementalDutyCycleMin,
                                  "CMSIncrementalDutyCycleMin");
      status = status && verify_percentage(CMSIncrementalSafetyFactor,
                                  "CMSIncrementalSafetyFactor");
      status = status && verify_percentage(CMSIncrementalOffset,
                                  "CMSIncrementalOffset");
      status = status && verify_percentage(CMSExpAvgFactor,
                                  "CMSExpAvgFactor");
      if (CMSInitiatingOccupancyFraction < 0) {
        FLAG_SET_DEFAULT(CMSInitiatingOccupancyFraction, 1);
      }
    }
  }
  if (UseConcMarkSweepGC && FLSVerifyAllHeapReferences) {
    if (VerifyDuringStartup) {
      warning("Heap verification at start-up disabled "
              "(due to current incompatibility with FLSVerifyAllHeapReferences)");
      VerifyDuringStartup = false; // Disable verification at start-up
    }
    if (VerifyBeforeExit) {
      warning("Heap verification at shutdown disabled "
              "(due to current incompatibility with FLSVerifyAllHeapReferences)");
      VerifyBeforeExit = false; // Disable verification at shutdown
    }
  }
  if (!UseAsyncConcMarkSweepGC &&
      (ExplicitGCInvokesConcurrent ||
       ExplicitGCInvokesConcurrentAndUnloadsClasses)) {
    jio_fprintf(defaultStream::error_stream(),
                "error: +ExplicitGCInvokesConcurrent[AndUnloadsClasses] conflicts"
                " with -UseAsyncConcMarkSweepGC");
    status = false;
  }
  status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk");
#if INCLUDE_ALL_GCS
  if (UseG1GC) {
    status = status && verify_percentage(G1NewSizePercent, "G1NewSizePercent");
    status = status && verify_percentage(G1MaxNewSizePercent, "G1MaxNewSizePercent");
    status = status && verify_interval(G1NewSizePercent, 0, G1MaxNewSizePercent, "G1NewSizePercent");
    status = status && verify_percentage(InitiatingHeapOccupancyPercent,
                                         "InitiatingHeapOccupancyPercent");
    status = status && verify_min_value(G1RefProcDrainInterval, 1,
                                        "G1RefProcDrainInterval");
    status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1,
                                        "G1ConcMarkStepDurationMillis");
    status = status && verify_interval(G1ConcRSHotCardLimit, 0, max_jubyte,
                                       "G1ConcRSHotCardLimit");
    status = status && verify_interval(G1ConcRSLogCacheSize, 0, 27,
                                       "G1ConcRSLogCacheSize");
    status = status && verify_interval(StringDeduplicationAgeThreshold, 1, markOopDesc::max_age,
                                       "StringDeduplicationAgeThreshold");
  }
  if (UseConcMarkSweepGC) {
    status = status && verify_min_value(CMSOldPLABNumRefills, 1, "CMSOldPLABNumRefills");
    status = status && verify_min_value(CMSOldPLABToleranceFactor, 1, "CMSOldPLABToleranceFactor");
    status = status && verify_min_value(CMSOldPLABMax, 1, "CMSOldPLABMax");
    status = status && verify_interval(CMSOldPLABMin, 1, CMSOldPLABMax, "CMSOldPLABMin");
    status = status && verify_min_value(CMSYoungGenPerWorker, 1, "CMSYoungGenPerWorker");
    status = status && verify_min_value(CMSSamplingGrain, 1, "CMSSamplingGrain");
    status = status && verify_interval(CMS_SweepWeight, 0, 100, "CMS_SweepWeight");
    status = status && verify_interval(CMS_FLSWeight, 0, 100, "CMS_FLSWeight");
    status = status && verify_interval(FLSCoalescePolicy, 0, 4, "FLSCoalescePolicy");
    status = status && verify_min_value(CMSRescanMultiple, 1, "CMSRescanMultiple");
    status = status && verify_min_value(CMSConcMarkMultiple, 1, "CMSConcMarkMultiple");
    status = status && verify_interval(CMSPrecleanIter, 0, 9, "CMSPrecleanIter");
    status = status && verify_min_value(CMSPrecleanDenominator, 1, "CMSPrecleanDenominator");
    status = status && verify_interval(CMSPrecleanNumerator, 0, CMSPrecleanDenominator - 1, "CMSPrecleanNumerator");
    status = status && verify_percentage(CMSBootstrapOccupancy, "CMSBootstrapOccupancy");
    status = status && verify_min_value(CMSPrecleanThreshold, 100, "CMSPrecleanThreshold");
    status = status && verify_percentage(CMSScheduleRemarkEdenPenetration, "CMSScheduleRemarkEdenPenetration");
    status = status && verify_min_value(CMSScheduleRemarkSamplingRatio, 1, "CMSScheduleRemarkSamplingRatio");
    status = status && verify_min_value(CMSBitMapYieldQuantum, 1, "CMSBitMapYieldQuantum");
    status = status && verify_percentage(CMSTriggerRatio, "CMSTriggerRatio");
    status = status && verify_percentage(CMSIsTooFullPercentage, "CMSIsTooFullPercentage");
  }
  if (UseParallelGC || UseParallelOldGC) {
    status = status && verify_interval(ParallelOldDeadWoodLimiterMean, 0, 100, "ParallelOldDeadWoodLimiterMean");
    status = status && verify_interval(ParallelOldDeadWoodLimiterStdDev, 0, 100, "ParallelOldDeadWoodLimiterStdDev");
    status = status && verify_percentage(YoungGenerationSizeIncrement, "YoungGenerationSizeIncrement");
    status = status && verify_percentage(TenuredGenerationSizeIncrement, "TenuredGenerationSizeIncrement");
    status = status && verify_min_value(YoungGenerationSizeSupplementDecay, 1, "YoungGenerationSizeSupplementDecay");
    status = status && verify_min_value(TenuredGenerationSizeSupplementDecay, 1, "TenuredGenerationSizeSupplementDecay");
    status = status && verify_min_value(ParGCCardsPerStrideChunk, 1, "ParGCCardsPerStrideChunk");
    status = status && verify_min_value(ParallelOldGCSplitInterval, 0, "ParallelOldGCSplitInterval");
  }
#endif // INCLUDE_ALL_GCS
  status = status && verify_interval(RefDiscoveryPolicy,
                                     ReferenceProcessor::DiscoveryPolicyMin,
                                     ReferenceProcessor::DiscoveryPolicyMax,
                                     "RefDiscoveryPolicy");
  status = status && verify_interval(TLABWasteTargetPercent,
                                     1, 100, "TLABWasteTargetPercent");
  status = status && verify_object_alignment();
  status = status && verify_interval(CompressedClassSpaceSize, 1*M, 3*G,
                                      "CompressedClassSpaceSize");
  status = status && verify_interval(MarkStackSizeMax,
                                  1, (max_jint - 1), "MarkStackSizeMax");
  status = status && verify_interval(NUMAChunkResizeWeight, 0, 100, "NUMAChunkResizeWeight");
  status = status && verify_min_value(LogEventsBufferEntries, 1, "LogEventsBufferEntries");
  status = status && verify_min_value(HeapSizePerGCThread, (uintx) os::vm_page_size(), "HeapSizePerGCThread");
  status = status && verify_min_value(GCTaskTimeStampEntries, 1, "GCTaskTimeStampEntries");
  status = status && verify_percentage(ParallelGCBufferWastePct, "ParallelGCBufferWastePct");
  status = status && verify_interval(TargetPLABWastePct, 1, 100, "TargetPLABWastePct");
  status = status && verify_min_value(ParGCStridesPerThread, 1, "ParGCStridesPerThread");
  status = status && verify_min_value(MinRAMFraction, 1, "MinRAMFraction");
  status = status && verify_min_value(InitialRAMFraction, 1, "InitialRAMFraction");
  status = status && verify_min_value(MaxRAMFraction, 1, "MaxRAMFraction");
  status = status && verify_min_value(DefaultMaxRAMFraction, 1, "DefaultMaxRAMFraction");
  status = status && verify_interval(AdaptiveTimeWeight, 0, 100, "AdaptiveTimeWeight");
  status = status && verify_min_value(AdaptiveSizeDecrementScaleFactor, 1, "AdaptiveSizeDecrementScaleFactor");
  status = status && verify_interval(TLABAllocationWeight, 0, 100, "TLABAllocationWeight");
  status = status && verify_min_value(MinTLABSize, 1, "MinTLABSize");
  status = status && verify_min_value(TLABRefillWasteFraction, 1, "TLABRefillWasteFraction");
  status = status && verify_percentage(YoungGenerationSizeSupplement, "YoungGenerationSizeSupplement");
  status = status && verify_percentage(TenuredGenerationSizeSupplement, "TenuredGenerationSizeSupplement");
  status = status && verify_interval(MaxTenuringThreshold, 0, 15, "MaxTenuringThreshold");
  status = status && verify_interval(InitialTenuringThreshold, 0, MaxTenuringThreshold, "MaxTenuringThreshold");
  status = status && verify_percentage(TargetSurvivorRatio, "TargetSurvivorRatio");
  status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio");
  status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount");
#ifdef COMPILER1
  status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize");
#endif
  if (PrintNMTStatistics) {
#if INCLUDE_NMT
    if (MemTracker::tracking_level() == NMT_off) {
#endif // INCLUDE_NMT
      warning("PrintNMTStatistics is disabled, because native memory tracking is not enabled");
      PrintNMTStatistics = false;
#if INCLUDE_NMT
    }
#endif
  }
  if (ContendedPaddingWidth < 0 || ContendedPaddingWidth > 8192) {
    jio_fprintf(defaultStream::error_stream(),
                "ContendedPaddingWidth=" INTX_FORMAT " must be in between %d and %d\n",
                ContendedPaddingWidth, 0, 8192);
    status = false;
  }
  if ((ContendedPaddingWidth % BytesPerLong) != 0) {
    jio_fprintf(defaultStream::error_stream(),
                "ContendedPaddingWidth=" INTX_FORMAT " must be a multiple of %d\n",
                ContendedPaddingWidth, BytesPerLong);
    status = false;
  }
  uint min_code_cache_size = (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3)) + CodeCacheMinimumFreeSpace;
  if (InitialCodeCacheSize < (uintx)os::vm_page_size()) {
    jio_fprintf(defaultStream::error_stream(),
                "Invalid InitialCodeCacheSize=%dK. Must be at least %dK.\n", InitialCodeCacheSize/K,
                os::vm_page_size()/K);
    status = false;
  } else if (ReservedCodeCacheSize < InitialCodeCacheSize) {
    jio_fprintf(defaultStream::error_stream(),
                "Invalid ReservedCodeCacheSize: %dK. Must be at least InitialCodeCacheSize=%dK.\n",
                ReservedCodeCacheSize/K, InitialCodeCacheSize/K);
    status = false;
  } else if (ReservedCodeCacheSize < min_code_cache_size) {
    jio_fprintf(defaultStream::error_stream(),
                "Invalid ReservedCodeCacheSize=%dK. Must be at least %uK.\n", ReservedCodeCacheSize/K,
                min_code_cache_size/K);
    status = false;
  } else if (ReservedCodeCacheSize > 2*G) {
    jio_fprintf(defaultStream::error_stream(),
                "Invalid ReservedCodeCacheSize=%dM. Must be at most %uM.\n", ReservedCodeCacheSize/M,
                (2*G)/M);
    status = false;
  }
  status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
  status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
  if (!FLAG_IS_DEFAULT(CICompilerCount) && !FLAG_IS_DEFAULT(CICompilerCountPerCPU) && CICompilerCountPerCPU) {
    warning("The VM option CICompilerCountPerCPU overrides CICompilerCount.");
  }
#ifdef COMPILER1
  status &= verify_interval(SafepointPollOffset, 0, os::vm_page_size() - BytesPerWord, "SafepointPollOffset");
#endif
  int min_number_of_compiler_threads = get_min_number_of_compiler_threads();
  assert(min_number_of_compiler_threads <= CI_COMPILER_COUNT, "minimum should be less or equal default number");
  status &=verify_min_value(CICompilerCount, min_number_of_compiler_threads, "CICompilerCount");
  return status;
}
bool Arguments::is_bad_option(const JavaVMOption* option, jboolean ignore,
  const char* option_type) {
  if (ignore) return false;
  const char* spacer = " ";
  if (option_type == NULL) {
    option_type = ++spacer; // Set both to the empty string.
  }
  if (os::obsolete_option(option)) {
    jio_fprintf(defaultStream::error_stream(),
                "Obsolete %s%soption: %s\n", option_type, spacer,
      option->optionString);
    return false;
  } else {
    jio_fprintf(defaultStream::error_stream(),
                "Unrecognized %s%soption: %s\n", option_type, spacer,
      option->optionString);
    return true;
  }
}
static const char* user_assertion_options[] = {
  "-da", "-ea", "-disableassertions", "-enableassertions", 0
};
static const char* system_assertion_options[] = {
  "-dsa", "-esa", "-disablesystemassertions", "-enablesystemassertions", 0
};
static bool match_option(const JavaVMOption* option, const char** names, const char** tail,
  bool tail_allowed) {
  for (/* empty */; *names != NULL; ++names) {
    if (match_option(option, *names, tail)) {
      if (**tail == '\0' || tail_allowed && **tail == ':') {
        return true;
      }
    }
  }
  return false;
}
bool Arguments::parse_uintx(const char* value,
                            uintx* uintx_arg,
                            uintx min_size) {
  bool value_is_positive = !(*value == '-');
  if (value_is_positive) {
    julong n;
    bool good_return = atomull(value, &n);
    if (good_return) {
      bool above_minimum = n >= min_size;
      bool value_is_too_large = n > max_uintx;
      if (above_minimum && !value_is_too_large) {
        return true;
      }
    }
  }
  return false;
}
Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
                                                  julong* long_arg,
                                                  julong min_size) {
  if (!atomull(s, long_arg)) return arg_unreadable;
  return check_memory_size(*long_arg, min_size);
}
jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
  SysClassPath scp(Arguments::get_sysclasspath());
  bool scp_assembly_required = false;
  Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
  Arguments::_UseOnStackReplacement    = UseOnStackReplacement;
  Arguments::_ClipInlining             = ClipInlining;
  Arguments::_BackgroundCompilation    = BackgroundCompilation;
  set_mode_flags(_mixed);
  jint result = parse_java_tool_options_environment_variable(&scp, &scp_assembly_required);
  if (result != JNI_OK) {
    return result;
  }
  result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, Flag::COMMAND_LINE);
  if (result != JNI_OK) {
    return result;
  }
  result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
  if (result != JNI_OK) {
    return result;
  }
  os::init_container_support();
  result = finalize_vm_init_args(&scp, scp_assembly_required);
  if (result != JNI_OK) {
    return result;
  }
  return JNI_OK;
}
bool valid_hprof_or_jdwp_agent(char *name, bool is_path) {
  char *_name;
  const char *_hprof = "hprof", *_jdwp = "jdwp";
  size_t _len_hprof, _len_jdwp, _len_prefix;
  if (is_path) {
    if ((_name = strrchr(name, (int) *os::file_separator())) == NULL) {
      return false;
    }
    _name++;  // skip past last path separator
    _len_prefix = strlen(JNI_LIB_PREFIX);
    if (strncmp(_name, JNI_LIB_PREFIX, _len_prefix) != 0) {
      return false;
    }
    _name += _len_prefix;
    _len_hprof = strlen(_hprof);
    _len_jdwp = strlen(_jdwp);
    if (strncmp(_name, _hprof, _len_hprof) == 0) {
      _name += _len_hprof;
    }
    else if (strncmp(_name, _jdwp, _len_jdwp) == 0) {
      _name += _len_jdwp;
    }
    else {
      return false;
    }
    if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
      return false;
    }
    return true;
  }
  if (strcmp(name, _hprof) == 0 || strcmp(name, _jdwp) == 0) {
    return true;
  }
  return false;
}
jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
                                       SysClassPath* scp_p,
                                       bool* scp_assembly_required_p,
                                       Flag::Flags origin) {
  const char* tail;
  for (int index = 0; index < args->nOptions; index++) {
    bool is_absolute_path = false;  // for -agentpath vs -agentlib
    const JavaVMOption* option = args->options + index;
    if (!match_option(option, "-Djava.class.path", &tail) &&
        !match_option(option, "-Dsun.java.command", &tail) &&
        !match_option(option, "-Dsun.java.launcher", &tail)) {
        build_jvm_args(option->optionString);
    }
    if (match_option(option, "-verbose", &tail)) {
      if (!strcmp(tail, ":class") || !strcmp(tail, "")) {
        FLAG_SET_CMDLINE(bool, TraceClassLoading, true);
        FLAG_SET_CMDLINE(bool, TraceClassUnloading, true);
      } else if (!strcmp(tail, ":gc")) {
        FLAG_SET_CMDLINE(bool, PrintGC, true);
      } else if (!strcmp(tail, ":jni")) {
        FLAG_SET_CMDLINE(bool, PrintJNIResolving, true);
      }
    } else if (match_option(option, user_assertion_options, &tail, true)) {
      bool enable = option->optionString[1] == 'e';     // char after '-' is 'e'
      if (*tail == '\0') {
        JavaAssertions::setUserClassDefault(enable);
      } else {
        assert(*tail == ':', "bogus match by match_option()");
        JavaAssertions::addOption(tail + 1, enable);
      }
    } else if (match_option(option, system_assertion_options, &tail, false)) {
      bool enable = option->optionString[1] == 'e';     // char after '-' is 'e'
      JavaAssertions::setSystemClassDefault(enable);
    } else if (match_option(option, "-Xbootclasspath:", &tail)) {
      scp_p->reset_path(tail);
    } else if (match_option(option, "-Xbootclasspath/a:", &tail)) {
      scp_p->add_suffix(tail);
    } else if (match_option(option, "-Xbootclasspath/p:", &tail)) {
      scp_p->add_prefix(tail);
    } else if (match_option(option, "-Xrun", &tail)) {
      if (tail != NULL) {
        const char* pos = strchr(tail, ':');
        size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
        char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
        name[len] = '\0';
        char *options = NULL;
        if(pos != NULL) {
          size_t len2 = strlen(pos+1) + 1; // options start after ':'.  Final zero must be copied.
          options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtInternal), pos+1, len2);
        }
#if !INCLUDE_JVMTI
        if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
          jio_fprintf(defaultStream::error_stream(),
            "Profiling and debugging agents are not supported in this VM\n");
          return JNI_ERR;
        }
#endif // !INCLUDE_JVMTI
        add_init_library(name, options);
      }
    } else if (match_option(option, "-agentlib:", &tail) ||
          (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
      if(tail != NULL) {
        const char* pos = strchr(tail, '=');
        size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
        char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
        name[len] = '\0';
        char *options = NULL;
        if(pos != NULL) {
          size_t length = strlen(pos + 1) + 1;
          options = NEW_C_HEAP_ARRAY(char, length, mtInternal);
          jio_snprintf(options, length, "%s", pos + 1);
        }
#if !INCLUDE_JVMTI
        if (valid_hprof_or_jdwp_agent(name, is_absolute_path)) {
          jio_fprintf(defaultStream::error_stream(),
            "Profiling and debugging agents are not supported in this VM\n");
          return JNI_ERR;
        }
#endif // !INCLUDE_JVMTI
        add_init_agent(name, options, is_absolute_path);
      }
    } else if (match_option(option, "-javaagent:", &tail)) {
#if !INCLUDE_JVMTI
      jio_fprintf(defaultStream::error_stream(),
        "Instrumentation agents are not supported in this VM\n");
      return JNI_ERR;
#else
      if(tail != NULL) {
        size_t length = strlen(tail) + 1;
        char *options = NEW_C_HEAP_ARRAY(char, length, mtInternal);
        jio_snprintf(options, length, "%s", tail);
        add_init_agent("instrument", options, false);
      }
#endif // !INCLUDE_JVMTI
    } else if (match_option(option, "-Xnoclassgc", &tail)) {
      FLAG_SET_CMDLINE(bool, ClassUnloading, false);
    } else if (match_option(option, "-Xincgc", &tail)) {
      FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true);
      FLAG_SET_CMDLINE(bool, CMSIncrementalMode, true);
    } else if (match_option(option, "-Xnoincgc", &tail)) {
      FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false);
      FLAG_SET_CMDLINE(bool, CMSIncrementalMode, false);
    } else if (match_option(option, "-Xconcgc", &tail)) {
      FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true);
    } else if (match_option(option, "-Xnoconcgc", &tail)) {
      FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false);
    } else if (match_option(option, "-Xbatch", &tail)) {
      FLAG_SET_CMDLINE(bool, BackgroundCompilation, false);
    } else if (match_option(option, "-Xmn", &tail)) {
      julong long_initial_young_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_initial_young_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid initial young generation size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, MaxNewSize, (uintx)long_initial_young_size);
      FLAG_SET_CMDLINE(uintx, NewSize, (uintx)long_initial_young_size);
    } else if (match_option(option, "-Xms", &tail)) {
      julong long_initial_heap_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_initial_heap_size, 0);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid initial heap size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      set_min_heap_size((uintx)long_initial_heap_size);
      FLAG_SET_CMDLINE(uintx, InitialHeapSize, (uintx)long_initial_heap_size);
    } else if (match_option(option, "-Xmx", &tail) || match_option(option, "-XX:MaxHeapSize=", &tail)) {
      julong long_max_heap_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_max_heap_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid maximum heap size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, MaxHeapSize, (uintx)long_max_heap_size);
    } else if (match_option(option, "-Xmaxf", &tail)) {
      char* err;
      int maxf = (int)(strtod(tail, &err) * 100);
      if (*err != '\0' || *tail == '\0' || maxf < 0 || maxf > 100) {
        jio_fprintf(defaultStream::error_stream(),
                    "Bad max heap free percentage size: %s\n",
                    option->optionString);
        return JNI_EINVAL;
      } else {
        FLAG_SET_CMDLINE(uintx, MaxHeapFreeRatio, maxf);
      }
    } else if (match_option(option, "-Xminf", &tail)) {
      char* err;
      int minf = (int)(strtod(tail, &err) * 100);
      if (*err != '\0' || *tail == '\0' || minf < 0 || minf > 100) {
        jio_fprintf(defaultStream::error_stream(),
                    "Bad min heap free percentage size: %s\n",
                    option->optionString);
        return JNI_EINVAL;
      } else {
        FLAG_SET_CMDLINE(uintx, MinHeapFreeRatio, minf);
      }
    } else if (match_option(option, "-Xss", &tail)) {
      julong long_ThreadStackSize = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_ThreadStackSize, 1000);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid thread stack size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(intx, ThreadStackSize,
                              round_to((int)long_ThreadStackSize, K) / K);
    } else if (match_option(option, "-Xoss", &tail)) {
    } else if (match_option(option, "-XX:CodeCacheExpansionSize=", &tail)) {
      julong long_CodeCacheExpansionSize = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_CodeCacheExpansionSize, os::vm_page_size());
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                   "Invalid argument: %s. Must be at least %luK.\n", option->optionString,
                   os::vm_page_size()/K);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, CodeCacheExpansionSize, (uintx)long_CodeCacheExpansionSize);
    } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
               match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
      julong long_ReservedCodeCacheSize = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid maximum code cache size: %s.\n", option->optionString);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize);
      } else if (match_option(option, "-XX:IncreaseFirstTierCompileThresholdAt=", &tail)) {
        uintx uint_IncreaseFirstTierCompileThresholdAt = 0;
        if (!parse_uintx(tail, &uint_IncreaseFirstTierCompileThresholdAt, 0) || uint_IncreaseFirstTierCompileThresholdAt > 99) {
          jio_fprintf(defaultStream::error_stream(),
                      "Invalid value for IncreaseFirstTierCompileThresholdAt: %s. Should be between 0 and 99.\n",
                      option->optionString);
          return JNI_EINVAL;
        }
        FLAG_SET_CMDLINE(uintx, IncreaseFirstTierCompileThresholdAt, (uintx)uint_IncreaseFirstTierCompileThresholdAt);
    } else if (match_option(option, "-green", &tail)) {
      jio_fprintf(defaultStream::error_stream(),
                  "Green threads support not available\n");
          return JNI_EINVAL;
    } else if (match_option(option, "-native", &tail)) {
    } else if (match_option(option, "-Xsqnopause", &tail)) {
    } else if (match_option(option, "-Xrs", &tail)) {
      FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true);
    } else if (match_option(option, "-Xusealtsigs", &tail)) {
      FLAG_SET_CMDLINE(bool, UseAltSigs, true);
    } else if (match_option(option, "-Xoptimize", &tail)) {
    } else if (match_option(option, "-Xprof", &tail)) {
#if INCLUDE_FPROF
      _has_profile = true;
#else // INCLUDE_FPROF
      jio_fprintf(defaultStream::error_stream(),
        "Flat profiling is not supported in this VM.\n");
      return JNI_ERR;
#endif // INCLUDE_FPROF
    } else if (match_option(option, "-Xconcurrentio", &tail)) {
      FLAG_SET_CMDLINE(bool, UseLWPSynchronization, true);
      FLAG_SET_CMDLINE(bool, BackgroundCompilation, false);
      FLAG_SET_CMDLINE(intx, DeferThrSuspendLoopCount, 1);
      FLAG_SET_CMDLINE(bool, UseTLAB, false);
      FLAG_SET_CMDLINE(uintx, NewSizeThreadIncrease, 16 * K);  // 20Kb per thread added to new generation
    } else if (match_option(option, "-Xinternalversion", &tail)) {
      jio_fprintf(defaultStream::output_stream(), "%s\n",
                  VM_Version::internal_vm_info_string());
      vm_exit(0);
#ifndef PRODUCT
    } else if (match_option(option, "-Xprintflags", &tail)) {
      CommandLineFlags::printFlags(tty, false);
      vm_exit(0);
#endif
    } else if (match_option(option, "-D", &tail)) {
      if (CheckEndorsedAndExtDirs) {
        if (match_option(option, "-Djava.endorsed.dirs=", &tail)) {
          jio_fprintf(defaultStream::output_stream(),
            "-Djava.endorsed.dirs will not be supported in a future release.\n"
            "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
          return JNI_EINVAL;
        }
        if (match_option(option, "-Djava.ext.dirs=", &tail)) {
          jio_fprintf(defaultStream::output_stream(),
            "-Djava.ext.dirs will not be supported in a future release.\n"
            "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
          return JNI_EINVAL;
        }
      }
      if (!add_property(tail)) {
        return JNI_ENOMEM;
      }
      if (match_option(option, "-Dcom.sun.management", &tail)) {
#if INCLUDE_MANAGEMENT
        FLAG_SET_CMDLINE(bool, ManagementServer, true);
#else
        jio_fprintf(defaultStream::output_stream(),
          "-Dcom.sun.management is not supported in this VM.\n");
        return JNI_ERR;
#endif
      }
    } else if (match_option(option, "-Xint", &tail)) {
          set_mode_flags(_int);
    } else if (match_option(option, "-Xmixed", &tail)) {
          set_mode_flags(_mixed);
    } else if (match_option(option, "-Xcomp", &tail)) {
          set_mode_flags(_comp);
    } else if (match_option(option, "-Xshare:dump", &tail)) {
      FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true);
      set_mode_flags(_int);     // Prevent compilation, which creates objects
    } else if (match_option(option, "-Xshare:on", &tail)) {
      FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
      FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
    } else if (match_option(option, "-Xshare:auto", &tail)) {
      FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
      FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
    } else if (match_option(option, "-Xshare:off", &tail)) {
      FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
      FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
    } else if (match_option(option, "-Xverify", &tail)) {
      if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
        FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, true);
        FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true);
      } else if (strcmp(tail, ":remote") == 0) {
        FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false);
        FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true);
      } else if (strcmp(tail, ":none") == 0) {
        FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false);
        FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, false);
      } else if (is_bad_option(option, args->ignoreUnrecognized, "verification")) {
        return JNI_EINVAL;
      }
    } else if (match_option(option, "-Xdebug", &tail)) {
      set_xdebug_mode(true);
    } else if (match_option(option, "-Xnoagent", &tail)) {
    } else if (match_option(option, "-Xboundthreads", &tail)) {
      FLAG_SET_CMDLINE(bool, UseBoundThreads, true);
    } else if (match_option(option, "-Xloggc:", &tail)) {
      _gc_log_filename = strdup(tail);
     if (!is_filename_valid(_gc_log_filename)) {
       jio_fprintf(defaultStream::output_stream(),
                  "Invalid file name for use with -Xloggc: Filename can only contain the "
                  "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n"
                  "Note %%p or %%t can only be used once\n", _gc_log_filename);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(bool, PrintGC, true);
      FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true);
    } else if (match_option(option, "-Xcheck", &tail)) {
      if (!strcmp(tail, ":jni")) {
#if !INCLUDE_JNI_CHECK
        warning("JNI CHECKING is not supported in this VM");
#else
        CheckJNICalls = true;
#endif // INCLUDE_JNI_CHECK
      } else if (is_bad_option(option, args->ignoreUnrecognized,
                                     "check")) {
        return JNI_EINVAL;
      }
    } else if (match_option(option, "vfprintf", &tail)) {
      _vfprintf_hook = CAST_TO_FN_PTR(vfprintf_hook_t, option->extraInfo);
    } else if (match_option(option, "exit", &tail)) {
      _exit_hook = CAST_TO_FN_PTR(exit_hook_t, option->extraInfo);
    } else if (match_option(option, "abort", &tail)) {
      _abort_hook = CAST_TO_FN_PTR(abort_hook_t, option->extraInfo);
    } else if (match_option(option, "-XX:+NeverTenure", &tail)) {
      FLAG_SET_CMDLINE(bool, AlwaysTenure, false);
      FLAG_SET_CMDLINE(bool, NeverTenure, true);
    } else if (match_option(option, "-XX:+AlwaysTenure", &tail)) {
      FLAG_SET_CMDLINE(bool, NeverTenure, false);
      FLAG_SET_CMDLINE(bool, AlwaysTenure, true);
    } else if (match_option(option, "-XX:+CMSPermGenSweepingEnabled", &tail) ||
               match_option(option, "-XX:-CMSPermGenSweepingEnabled", &tail)) {
      jio_fprintf(defaultStream::error_stream(),
        "Please use CMSClassUnloadingEnabled in place of "
        "CMSPermGenSweepingEnabled in the future\n");
    } else if (match_option(option, "-XX:+UseGCTimeLimit", &tail)) {
      FLAG_SET_CMDLINE(bool, UseGCOverheadLimit, true);
      jio_fprintf(defaultStream::error_stream(),
        "Please use -XX:+UseGCOverheadLimit in place of "
        "-XX:+UseGCTimeLimit in the future\n");
    } else if (match_option(option, "-XX:-UseGCTimeLimit", &tail)) {
      FLAG_SET_CMDLINE(bool, UseGCOverheadLimit, false);
      jio_fprintf(defaultStream::error_stream(),
        "Please use -XX:-UseGCOverheadLimit in place of "
        "-XX:-UseGCTimeLimit in the future\n");
    } else if (match_option(option, "-XX:MaxTLERatio=", &tail)) {
    } else if (match_option(option, "-XX:+ResizeTLE", &tail)) {
      FLAG_SET_CMDLINE(bool, ResizeTLAB, true);
    } else if (match_option(option, "-XX:-ResizeTLE", &tail)) {
      FLAG_SET_CMDLINE(bool, ResizeTLAB, false);
    } else if (match_option(option, "-XX:+PrintTLE", &tail)) {
      FLAG_SET_CMDLINE(bool, PrintTLAB, true);
    } else if (match_option(option, "-XX:-PrintTLE", &tail)) {
      FLAG_SET_CMDLINE(bool, PrintTLAB, false);
    } else if (match_option(option, "-XX:TLEFragmentationRatio=", &tail)) {
    } else if (match_option(option, "-XX:TLESize=", &tail)) {
      julong long_tlab_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &long_tlab_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid TLAB size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, TLABSize, long_tlab_size);
    } else if (match_option(option, "-XX:TLEThreadRatio=", &tail)) {
    } else if (match_option(option, "-XX:+UseTLE", &tail)) {
      FLAG_SET_CMDLINE(bool, UseTLAB, true);
    } else if (match_option(option, "-XX:-UseTLE", &tail)) {
      FLAG_SET_CMDLINE(bool, UseTLAB, false);
    } else if (match_option(option, "-XX:+DisplayVMOutputToStderr", &tail)) {
      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false);
      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true);
    } else if (match_option(option, "-XX:+DisplayVMOutputToStdout", &tail)) {
      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false);
      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true);
    } else if (match_option(option, "-XX:+ErrorFileToStderr", &tail)) {
      FLAG_SET_CMDLINE(bool, ErrorFileToStdout, false);
      FLAG_SET_CMDLINE(bool, ErrorFileToStderr, true);
    } else if (match_option(option, "-XX:+ErrorFileToStdout", &tail)) {
      FLAG_SET_CMDLINE(bool, ErrorFileToStderr, false);
      FLAG_SET_CMDLINE(bool, ErrorFileToStdout, true);
    } else if (match_option(option, "-XX:+ExtendedDTraceProbes", &tail)) {
#if defined(DTRACE_ENABLED)
      FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true);
      FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true);
      FLAG_SET_CMDLINE(bool, DTraceAllocProbes, true);
      FLAG_SET_CMDLINE(bool, DTraceMonitorProbes, true);
#else // defined(DTRACE_ENABLED)
      jio_fprintf(defaultStream::error_stream(),
                  "ExtendedDTraceProbes flag is not applicable for this configuration\n");
      return JNI_EINVAL;
#endif // defined(DTRACE_ENABLED)
#ifdef ASSERT
    } else if (match_option(option, "-XX:+FullGCALot", &tail)) {
      FLAG_SET_CMDLINE(bool, FullGCALot, true);
      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
#endif
    } else if (match_option(option, "-XX:CMSParPromoteBlocksToClaim=", &tail)) {
      julong cms_blocks_to_claim = (julong)atol(tail);
      FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, cms_blocks_to_claim);
      jio_fprintf(defaultStream::error_stream(),
        "Please use -XX:OldPLABSize in place of "
        "-XX:CMSParPromoteBlocksToClaim in the future\n");
    } else if (match_option(option, "-XX:ParCMSPromoteBlocksToClaim=", &tail)) {
      julong cms_blocks_to_claim = (julong)atol(tail);
      FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, cms_blocks_to_claim);
      jio_fprintf(defaultStream::error_stream(),
        "Please use -XX:OldPLABSize in place of "
        "-XX:ParCMSPromoteBlocksToClaim in the future\n");
    } else if (match_option(option, "-XX:ParallelGCOldGenAllocBufferSize=", &tail)) {
      julong old_plab_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &old_plab_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid old PLAB size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, OldPLABSize, old_plab_size);
      jio_fprintf(defaultStream::error_stream(),
                  "Please use -XX:OldPLABSize in place of "
                  "-XX:ParallelGCOldGenAllocBufferSize in the future\n");
    } else if (match_option(option, "-XX:ParallelGCToSpaceAllocBufferSize=", &tail)) {
      julong young_plab_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &young_plab_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid young PLAB size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, YoungPLABSize, young_plab_size);
      jio_fprintf(defaultStream::error_stream(),
                  "Please use -XX:YoungPLABSize in place of "
                  "-XX:ParallelGCToSpaceAllocBufferSize in the future\n");
    } else if (match_option(option, "-XX:CMSMarkStackSize=", &tail) ||
               match_option(option, "-XX:G1MarkStackSize=", &tail)) {
      julong stack_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &stack_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid mark stack size: %s\n", option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, MarkStackSize, stack_size);
    } else if (match_option(option, "-XX:CMSMarkStackSizeMax=", &tail)) {
      julong max_stack_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &max_stack_size, 1);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid maximum mark stack size: %s\n",
                    option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, MarkStackSizeMax, max_stack_size);
    } else if (match_option(option, "-XX:ParallelMarkingThreads=", &tail) ||
               match_option(option, "-XX:ParallelCMSThreads=", &tail)) {
      uintx conc_threads = 0;
      if (!parse_uintx(tail, &conc_threads, 1)) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid concurrent threads: %s\n", option->optionString);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, ConcGCThreads, conc_threads);
    } else if (match_option(option, "-XX:MaxDirectMemorySize=", &tail)) {
      julong max_direct_memory_size = 0;
      ArgsRange errcode = parse_memory_size(tail, &max_direct_memory_size, 0);
      if (errcode != arg_in_range) {
        jio_fprintf(defaultStream::error_stream(),
                    "Invalid maximum direct memory size: %s\n",
                    option->optionString);
        describe_range_error(errcode);
        return JNI_EINVAL;
      }
      FLAG_SET_CMDLINE(uintx, MaxDirectMemorySize, max_direct_memory_size);
    } else if (match_option(option, "-XX:+UseVMInterruptibleIO", &tail)) {
      warning("-XX:+UseVMInterruptibleIO is obsolete and will be removed in a future release.");
      FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true);
#if !INCLUDE_MANAGEMENT
    } else if (match_option(option, "-XX:+ManagementServer", &tail)) {
        jio_fprintf(defaultStream::error_stream(),
          "ManagementServer is not supported in this VM.\n");
        return JNI_ERR;
#endif // INCLUDE_MANAGEMENT
#if INCLUDE_JFR
    } else if (match_jfr_option(&option)) {
      return JNI_EINVAL;
#endif
    } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
      if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
        if (!process_argument(tail, args->ignoreUnrecognized, origin)) {
          return JNI_EINVAL;
        }
      }
    } else if (is_bad_option(option, args->ignoreUnrecognized)) {
      return JNI_ERR;
    }
  }
  if (PrintSharedArchiveAndExit) {
    FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
    FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
    FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
  }
#ifdef LINUX
 if (JDK_Version::current().compare_major(6) <= 0 &&
      FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
    FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
  }
#endif // LINUX
  fix_appclasspath();
  return JNI_OK;
}
void Arguments::fix_appclasspath() {
  if (IgnoreEmptyClassPaths) {
    const char separator = *os::path_separator();
    const char* src = _java_class_path->value();
    while (*src == separator) {
      src ++;
    }
    char* copy = os::strdup(src, mtInternal);
    for (char* tail = copy + strlen(copy) - 1; tail >= copy && *tail == separator; tail--) {
    }
    char from[3] = {separator, separator, '\0'};
    char to  [2] = {separator, '\0'};
    while (StringUtils::replace_no_expand(copy, from, to) > 0) {
    }
    _java_class_path->set_value(copy);
    FreeHeap(copy); // a copy was made by set_value, so don't need this anymore
  }
  if (!PrintSharedArchiveAndExit) {
    ClassLoader::trace_class_path(tty, "[classpath: ", _java_class_path->value());
  }
}
static bool has_jar_files(const char* directory) {
  DIR* dir = os::opendir(directory);
  if (dir == NULL) return false;
  struct dirent *entry;
  bool hasJarFile = false;
  while (!hasJarFile && (entry = os::readdir(dir)) != NULL) {
    const char* name = entry->d_name;
    const char* ext = name + strlen(name) - 4;
    hasJarFile = ext > name && (os::file_name_strcmp(ext, ".jar") == 0);
  }
  os::closedir(dir);
  return hasJarFile ;
}
static int check_non_empty_dirs(const char* path, const char* type, const char* skip) {
  const char separator = *os::path_separator();
  const char* const end = path + strlen(path);
  int nonEmptyDirs = 0;
  while (path < end) {
    const char* tmp_end = strchr(path, separator);
    if (tmp_end == NULL) {
      if ((skip == NULL || strcmp(path, skip) != 0) && has_jar_files(path)) {
        nonEmptyDirs++;
        jio_fprintf(defaultStream::output_stream(),
          "Non-empty %s directory: %s\n", type, path);
      }
      path = end;
    } else {
      char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
      memcpy(dirpath, path, tmp_end - path);
      dirpath[tmp_end - path] = '\0';
      if ((skip == NULL || strcmp(dirpath, skip) != 0) && has_jar_files(dirpath)) {
        nonEmptyDirs++;
        jio_fprintf(defaultStream::output_stream(),
          "Non-empty %s directory: %s\n", type, dirpath);
      }
      FREE_C_HEAP_ARRAY(char, dirpath, mtInternal);
      path = tmp_end + 1;
    }
  }
  return nonEmptyDirs;
}
static bool check_endorsed_and_ext_dirs() {
  if (!CheckEndorsedAndExtDirs)
    return true;
  char endorsedDir[JVM_MAXPATHLEN];
  char extDir[JVM_MAXPATHLEN];
  const char* fileSep = os::file_separator();
  jio_snprintf(endorsedDir, sizeof(endorsedDir), "%s%slib%sendorsed",
               Arguments::get_java_home(), fileSep, fileSep);
  jio_snprintf(extDir, sizeof(extDir), "%s%slib%sext",
               Arguments::get_java_home(), fileSep, fileSep);
  int nonEmptyDirs = check_non_empty_dirs(Arguments::get_endorsed_dir(), "endorsed", NULL);
  nonEmptyDirs += check_non_empty_dirs(Arguments::get_ext_dirs(), "extension", extDir);
  static const char* jdk_ext_jars[] = {
      "access-bridge-32.jar",
      "access-bridge-64.jar",
      "access-bridge.jar",
      "cldrdata.jar",
      "dnsns.jar",
      "jaccess.jar",
      "jfxrt.jar",
      "localedata.jar",
      "nashorn.jar",
      "sunec.jar",
      "sunjce_provider.jar",
      "sunmscapi.jar",
      "sunpkcs11.jar",
      "ucrypto.jar",
      "zipfs.jar",
      NULL
  };
  DIR* dir = os::opendir(extDir);
  if (dir != NULL) {
    int num_ext_jars = 0;
    struct dirent *entry;
    while ((entry = os::readdir(dir)) != NULL) {
      const char* name = entry->d_name;
      const char* ext = name + strlen(name) - 4;
      if (ext > name && (os::file_name_strcmp(ext, ".jar") == 0)) {
        bool is_jdk_jar = false;
        const char* jarfile = NULL;
        for (int i=0; (jarfile = jdk_ext_jars[i]) != NULL; i++) {
          if (os::file_name_strcmp(name, jarfile) == 0) {
            is_jdk_jar = true;
            break;
          }
        }
        if (!is_jdk_jar) {
          jio_fprintf(defaultStream::output_stream(),
            "%s installed in <JAVA_HOME>/lib/ext\n", name);
          num_ext_jars++;
        }
      }
    }
    os::closedir(dir);
    if (num_ext_jars > 0) {
      nonEmptyDirs += 1;
    }
  }
  dir = os::opendir(endorsedDir);
  if (dir != NULL) {
    jio_fprintf(defaultStream::output_stream(), "<JAVA_HOME>/lib/endorsed exists\n");
    os::closedir(dir);
    nonEmptyDirs += 1;
  }
  if (nonEmptyDirs > 0) {
    jio_fprintf(defaultStream::output_stream(),
      "Endorsed standards override mechanism and extension mechanism "
      "will not be supported in a future release.\n"
      "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
    return false;
  }
  return true;
}
jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required) {
  scp_p->expand_endorsed();
  if (scp_assembly_required || scp_p->get_endorsed() != NULL) {
    Arguments::set_sysclasspath(scp_p->combined_path());
  }
  if (!check_endorsed_and_ext_dirs()) {
    return JNI_ERR;
  }
  if (AggressiveHeap) {
    jint result = set_aggressive_heap_flags();
    if (result != JNI_OK) {
      return result;
    }
  }
  if (java_compiler() && !xdebug_mode()) {
    set_mode_flags(_int);
  }
  if (CompileThreshold == 0) {
    set_mode_flags(_int);
  }
  if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
    FLAG_SET_ERGO(uintx, InitialTenuringThreshold, MaxTenuringThreshold);
  }
#ifndef COMPILER2
  if (FLAG_IS_DEFAULT(UseLargePages) &&
      MaxHeapSize < LargePageHeapSizeThreshold) {
    FLAG_SET_DEFAULT(UseLargePages, false);
  }
#else
  if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
    FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
  }
#endif
#ifndef TIERED
  UNSUPPORTED_OPTION(TieredCompilation, "TieredCompilation");
#endif
  if (os::is_headless_jre()) {
    const char* headless = Arguments::get_property("java.awt.headless");
    if (headless == NULL) {
      char envbuffer[128];
      if (!os::getenv("JAVA_AWT_HEADLESS", envbuffer, sizeof(envbuffer))) {
        if (!add_property("java.awt.headless=true")) {
          return JNI_ENOMEM;
        }
      } else {
        char buffer[256];
        jio_snprintf(buffer, 256, "java.awt.headless=%s", envbuffer);
        if (!add_property(buffer)) {
          return JNI_ENOMEM;
        }
      }
    }
  }
  if (!check_vm_args_consistency()) {
    return JNI_ERR;
  }
  return JNI_OK;
}
jint Arguments::parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) {
  return parse_options_environment_variable("_JAVA_OPTIONS", scp_p,
                                            scp_assembly_required_p);
}
jint Arguments::parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) {
  return parse_options_environment_variable("JAVA_TOOL_OPTIONS", scp_p,
                                            scp_assembly_required_p);
}
jint Arguments::parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p) {
  const int N_MAX_OPTIONS = 64;
  const int OPTION_BUFFER_SIZE = 1024;
  char buffer[OPTION_BUFFER_SIZE];
  if (os::getenv(name, buffer, sizeof(buffer)) &&
      !os::have_special_privileges()) {
    JavaVMOption options[N_MAX_OPTIONS];      // Construct option array
    jio_fprintf(defaultStream::error_stream(),
                "Picked up %s: %s\n", name, buffer);
    char* rd = buffer;                        // pointer to the input string (rd)
    int i;
    for (i = 0; i < N_MAX_OPTIONS;) {         // repeat for all options in the input string
      while (isspace(*rd)) rd++;              // skip whitespace
      if (*rd == 0) break;                    // we re done when the input string is read completely
      char* wrt = rd;
      options[i++].optionString = wrt;        // Fill in option
      while (*rd != 0 && !isspace(*rd)) {     // unquoted strings terminate with a space or NULL
        if (*rd == '\'' || *rd == '"') {      // handle a quoted string
          int quote = *rd;                    // matching quote to look for
          rd++;                               // don't copy open quote
          while (*rd != quote) {              // include everything (even spaces) up until quote
            if (*rd == 0) {                   // string termination means unmatched string
              jio_fprintf(defaultStream::error_stream(),
                          "Unmatched quote in %s\n", name);
              return JNI_ERR;
            }
          }
          rd++;                               // don't copy close quote
        } else {
        }
      }
      if (*rd++ == 0) {
        break;
      }
    }
    JavaVMInitArgs vm_args;
    vm_args.version = JNI_VERSION_1_2;
    vm_args.options = options;
    vm_args.nOptions = i;
    vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
    if (PrintVMOptions) {
      const char* tail;
      for (int i = 0; i < vm_args.nOptions; i++) {
        const JavaVMOption *option = vm_args.options + i;
        if (match_option(option, "-XX:", &tail)) {
          logOption(tail);
        }
      }
    }
    return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, Flag::ENVIRON_VAR));
  }
  return JNI_OK;
}
void Arguments::set_shared_spaces_flags() {
  if (DumpSharedSpaces) {
    if (FailOverToOldVerifier) {
      FLAG_SET_DEFAULT(FailOverToOldVerifier, false);
    }
    if (RequireSharedSpaces) {
      warning("cannot dump shared archive while using shared archive");
    }
    UseSharedSpaces = false;
#ifdef _LP64
    if (!UseCompressedOops || !UseCompressedClassPointers) {
      vm_exit_during_initialization(
        "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
    }
  } else {
    if (!UseCompressedOops || !UseCompressedClassPointers) {
      no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
    }
#endif
  }
}
#if !INCLUDE_ALL_GCS
static void force_serial_gc() {
  FLAG_SET_DEFAULT(UseSerialGC, true);
  FLAG_SET_DEFAULT(CMSIncrementalMode, false);  // special CMS suboption
  UNSUPPORTED_GC_OPTION(UseG1GC);
  UNSUPPORTED_GC_OPTION(UseParallelGC);
  UNSUPPORTED_GC_OPTION(UseParallelOldGC);
  UNSUPPORTED_GC_OPTION(UseConcMarkSweepGC);
  UNSUPPORTED_GC_OPTION(UseParNewGC);
}
#endif // INCLUDE_ALL_GCS
static char* get_shared_archive_path() {
  char *shared_archive_path;
  if (SharedArchiveFile == NULL) {
    char jvm_path[JVM_MAXPATHLEN];
    os::jvm_path(jvm_path, sizeof(jvm_path));
    char *end = strrchr(jvm_path, *os::file_separator());
    if (end != NULL) *end = '\0';
    size_t jvm_path_len = strlen(jvm_path);
    size_t file_sep_len = strlen(os::file_separator());
    const size_t len = jvm_path_len + file_sep_len + 20;
    shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
    if (shared_archive_path != NULL) {
      jio_snprintf(shared_archive_path, len, "%s%sclasses.jsa",
        jvm_path, os::file_separator());
    }
  } else {
    shared_archive_path = os::strdup(SharedArchiveFile, mtInternal);
  }
  return shared_archive_path;
}
#ifndef PRODUCT
static bool use_vm_log() {
  if (LogCompilation || !FLAG_IS_DEFAULT(LogFile) ||
      PrintCompilation || PrintInlining || PrintDependencies || PrintNativeNMethods ||
      PrintDebugInfo || PrintRelocations || PrintNMethods || PrintExceptionHandlers ||
      PrintAssembly || TraceDeoptimization || TraceDependencies ||
      (VerifyDependencies && FLAG_IS_CMDLINE(VerifyDependencies))) {
    return true;
  }
#ifdef COMPILER1
  if (PrintC1Statistics) {
    return true;
  }
#endif // COMPILER1
#ifdef COMPILER2
  if (PrintOptoAssembly || PrintOptoStatistics) {
    return true;
  }
#endif // COMPILER2
  return false;
}
#endif // PRODUCT
jint Arguments::parse(const JavaVMInitArgs* args) {
  const char* tail;
  const char* hotspotrc = ".hotspotrc";
  bool settings_file_specified = false;
  bool needs_hotspotrc_warning = false;
  ArgumentsExt::process_options(args);
  const char* flags_file;
  int index;
  for (index = 0; index < args->nOptions; index++) {
    const JavaVMOption *option = args->options + index;
    if (match_option(option, "-XX:Flags=", &tail)) {
      flags_file = tail;
      settings_file_specified = true;
    }
    if (match_option(option, "-XX:+PrintVMOptions", &tail)) {
      PrintVMOptions = true;
    }
    if (match_option(option, "-XX:-PrintVMOptions", &tail)) {
      PrintVMOptions = false;
    }
    if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) {
      IgnoreUnrecognizedVMOptions = true;
    }
    if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) {
      IgnoreUnrecognizedVMOptions = false;
    }
    if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) {
      CommandLineFlags::printFlags(tty, false);
      vm_exit(0);
    }
    if (match_option(option, "-XX:NativeMemoryTracking", &tail)) {
#if INCLUDE_NMT
      if (!MemTracker::check_launcher_nmt_support(tail)) {
        warning("Native Memory Tracking did not setup properly, using wrong launcher?");
      }
      if (MemTracker::verify_nmt_option()) {
        if (MemTracker::tracking_level() >= NMT_summary) {
          MemTracker::init();
        }
      } else {
        vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
      }
#else
      jio_fprintf(defaultStream::error_stream(),
        "Native Memory Tracking is not supported in this VM\n");
      return JNI_ERR;
#endif
    }
#ifndef PRODUCT
    if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
      CommandLineFlags::printFlags(tty, true);
      vm_exit(0);
    }
#endif
  }
  if (IgnoreUnrecognizedVMOptions) {
  }
  if (settings_file_specified) {
    if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
      return JNI_EINVAL;
    }
  } else {
#ifdef ASSERT
    if (!process_settings_file(".hotspotrc", false, args->ignoreUnrecognized)) {
      return JNI_EINVAL;
    }
#else
    struct stat buf;
    if (os::stat(hotspotrc, &buf) == 0) {
      needs_hotspotrc_warning = true;
    }
#endif
  }
  if (PrintVMOptions) {
    for (index = 0; index < args->nOptions; index++) {
      const JavaVMOption *option = args->options + index;
      if (match_option(option, "-XX:", &tail)) {
        logOption(tail);
      }
    }
  }
  jint result = parse_vm_init_args(args);
  if (result != JNI_OK) {
    return result;
  }
  SharedArchivePath = get_shared_archive_path();
  if (SharedArchivePath == NULL) {
    return JNI_ENOMEM;
  }
  if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
    VerifySharedSpaces = true;
  }
  if (needs_hotspotrc_warning) {
    warning("%s file is present but has been ignored.  "
            "Run with -XX:Flags=%s to load the file.",
            hotspotrc, hotspotrc);
  }
#ifdef _ALLBSD_SOURCE  // UseLargePages is not yet supported on BSD.
  UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages");
#endif
#if INCLUDE_ALL_GCS
  #if (defined JAVASE_EMBEDDED || defined ARM)
    UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
  #endif
#endif
#ifndef PRODUCT
  if (TraceBytecodesAt != 0) {
    TraceBytecodes = true;
  }
  if (CountCompiledCalls) {
    if (UseCounterDecay) {
      warning("UseCounterDecay disabled because CountCalls is set");
      UseCounterDecay = false;
    }
  }
#endif // PRODUCT
  if (!JDK_Version::is_gte_jdk17x_version()) {
    if (EnableInvokeDynamic) {
      if (!FLAG_IS_DEFAULT(EnableInvokeDynamic)) {
        warning("JSR 292 is not supported before 1.7.  Disabling support.");
      }
      EnableInvokeDynamic = false;
    }
  }
  if (EnableInvokeDynamic && ScavengeRootsInCode == 0) {
    if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {
      warning("forcing ScavengeRootsInCode non-zero because EnableInvokeDynamic is true");
    }
    ScavengeRootsInCode = 1;
  }
  if (PrintGCDetails) {
    PrintGC = true;
  }
  if (!JDK_Version::is_gte_jdk18x_version()) {
    if (FLAG_IS_DEFAULT(PrintGCCause)) {
      FLAG_SET_DEFAULT(PrintGCCause, false);
    }
  }
  set_object_alignment();
#if !INCLUDE_ALL_GCS
  force_serial_gc();
#endif // INCLUDE_ALL_GCS
#if !INCLUDE_CDS
  if (DumpSharedSpaces || RequireSharedSpaces) {
    jio_fprintf(defaultStream::error_stream(),
      "Shared spaces are not supported in this VM\n");
    return JNI_ERR;
  }
  if ((UseSharedSpaces && FLAG_IS_CMDLINE(UseSharedSpaces)) || PrintSharedSpaces) {
    warning("Shared spaces are not supported in this VM");
    FLAG_SET_DEFAULT(UseSharedSpaces, false);
    FLAG_SET_DEFAULT(PrintSharedSpaces, false);
  }
  no_shared_spaces("CDS Disabled");
#endif // INCLUDE_CDS
  return JNI_OK;
}
jint Arguments::apply_ergo() {
  set_ergonomics_flags();
  set_shared_spaces_flags();
#if defined(SPARC)
  if (FLAG_IS_DEFAULT(AssumeMP)) {
    FLAG_SET_DEFAULT(AssumeMP, true);
  }
#endif
  if (!check_gc_consistency()) {
    return JNI_EINVAL;
  }
  if (TieredCompilation) {
    set_tiered_flags();
  } else {
    if (CompilationPolicyChoice >= 2) {
      vm_exit_during_initialization(
        "Incompatible compilation policy selected", NULL);
    }
  }
  if (FLAG_IS_DEFAULT(NmethodSweepFraction)) {
    FLAG_SET_DEFAULT(NmethodSweepFraction, 1 + ReservedCodeCacheSize / (16 * M));
  }
  set_heap_size();
  ArgumentsExt::set_gc_specific_flags();
  Metaspace::ergo_initialize();
  set_bytecode_flags();
  set_aggressive_opts_flags();
  if (UseHeavyMonitors
#ifdef COMPILER1
      || !UseFastLocking
#endif // COMPILER1
    ) {
    if (!FLAG_IS_DEFAULT(UseBiasedLocking) && UseBiasedLocking) {
      warning("Biased Locking is not supported with locking debug flags"
              "; ignoring UseBiasedLocking flag." );
    }
    UseBiasedLocking = false;
  }
#ifdef ZERO
  FLAG_SET_DEFAULT(ProfileInterpreter, false);
  FLAG_SET_DEFAULT(UseBiasedLocking, false);
  LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false));
  LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedClassPointers, false));
#endif // CC_INTERP
#ifdef COMPILER2
  if (!EliminateLocks) {
    EliminateNestedLocks = false;
  }
  if (!Inline) {
    IncrementalInline = false;
  }
#ifndef PRODUCT
  if (!IncrementalInline) {
    AlwaysIncrementalInline = false;
  }
#endif
  if (IncrementalInline && FLAG_IS_DEFAULT(MaxNodeLimit)) {
    FLAG_SET_DEFAULT(MaxNodeLimit, (intx)75000);
  }
  if (!UseTypeSpeculation && FLAG_IS_DEFAULT(TypeProfileLevel)) {
    FLAG_SET_DEFAULT(TypeProfileLevel, 0);
  }
#endif
  if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
    warning("PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output");
    DebugNonSafepoints = true;
  }
  if (FLAG_IS_CMDLINE(CompressedClassSpaceSize) && !UseCompressedClassPointers) {
    warning("Setting CompressedClassSpaceSize has no effect when compressed class pointers are not used");
  }
  if (UseOnStackReplacement && !UseLoopCounter) {
    warning("On-stack-replacement requires loop counters; enabling loop counters");
    FLAG_SET_DEFAULT(UseLoopCounter, true);
  }
#ifndef PRODUCT
  if (CompileTheWorld) {
    if (FLAG_IS_DEFAULT(NmethodSweepFraction)) {
      NmethodSweepFraction = 1;
    }
  }
  if (!LogVMOutput && FLAG_IS_DEFAULT(LogVMOutput)) {
    if (use_vm_log()) {
      LogVMOutput = true;
    }
  }
#endif // PRODUCT
  if (PrintCommandLineFlags) {
    CommandLineFlags::printSetFlags(tty);
  }
  if (UseBiasedLocking) {
    if (!VM_Version::use_biased_locking() &&
        !(FLAG_IS_CMDLINE(UseBiasedLocking))) {
      UseBiasedLocking = false;
    }
  }
#ifdef COMPILER2
  if (!UseBiasedLocking || EmitSync != 0) {
    UseOptoBiasInlining = false;
  }
#endif
  if (Arguments::created_by_gamma_launcher() && os::is_debugger_attached()) {
    bool set = false;
    CommandLineFlags::wasSetOnCmdline("PauseAtExit", &set);
    if (!set) {
      FLAG_SET_DEFAULT(PauseAtExit, true);
    }
  }
  return JNI_OK;
}
jint Arguments::adjust_after_os() {
  if (UseNUMA) {
    if (UseParallelGC || UseParallelOldGC) {
      if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
         FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
      }
    }
    if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
      FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
    }
  }
  return JNI_OK;
}
int Arguments::PropertyList_count(SystemProperty* pl) {
  int count = 0;
  while(pl != NULL) {
    count++;
    pl = pl->next();
  }
  return count;
}
const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
  assert(key != NULL, "just checking");
  SystemProperty* prop;
  for (prop = pl; prop != NULL; prop = prop->next()) {
    if (strcmp(key, prop->key()) == 0) return prop->value();
  }
  return NULL;
}
const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
  int count = 0;
  const char* ret_val = NULL;
  while(pl != NULL) {
    if(count >= index) {
      ret_val = pl->key();
      break;
    }
    count++;
    pl = pl->next();
  }
  return ret_val;
}
char* Arguments::PropertyList_get_value_at(SystemProperty* pl, int index) {
  int count = 0;
  char* ret_val = NULL;
  while(pl != NULL) {
    if(count >= index) {
      ret_val = pl->value();
      break;
    }
    count++;
    pl = pl->next();
  }
  return ret_val;
}
void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
  SystemProperty* p = *plist;
  if (p == NULL) {
  } else {
    while (p->next() != NULL) {
      p = p->next();
    }
    p->set_next(new_p);
  }
}
void Arguments::PropertyList_add(SystemProperty** plist, const char* k, char* v) {
  if (plist == NULL)
    return;
  SystemProperty* new_p = new SystemProperty(k, v, true);
  PropertyList_add(plist, new_p);
}
void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, char* v, jboolean append) {
  if (plist == NULL)
    return;
  SystemProperty* prop;
  for (prop = *plist; prop != NULL; prop = prop->next()) {
    if (strcmp(k, prop->key()) == 0) {
      if (append) {
        prop->append_value(v);
      } else {
        prop->set_value(v);
      }
      return;
    }
  }
  PropertyList_add(plist, k, v);
}
bool Arguments::copy_expand_pid(const char* src, size_t srclen,
                                char* buf, size_t buflen) {
  const char* p = src;
  char* b = buf;
  const char* src_end = &src[srclen];
  char* buf_end = &buf[buflen - 1];
  while (p < src_end && b < buf_end) {
    if (*p == '%') {
      switch (*(++p)) {
      case '%':         // "%%" ==> "%"
        break;
      case 'p':  {       //  "%p" ==> current process id
        size_t buf_sz = buf_end - b + 1;
        int ret = jio_snprintf(b, buf_sz, "%d", os::current_process_id());
        if (ret < 0 || ret >= (int)buf_sz) {
          return false;
        } else {
          b += ret;
          assert(*b == '\0', "fail in copy_expand_pid");
          if (p == src_end && b == buf_end + 1) {
            return true;
          }
        }
        p++;
        break;
      }
      default :
      }
    } else {
    }
  }
  return (p == src_end); // return false if not all of the source was copied
}
C:\hotspot-69087d08d473\src\share\vm/runtime/arguments.hpp
#ifndef SHARE_VM_RUNTIME_ARGUMENTS_HPP
#define SHARE_VM_RUNTIME_ARGUMENTS_HPP
#include "runtime/java.hpp"
#include "runtime/perfData.hpp"
#include "utilities/debug.hpp"
#include "utilities/top.hpp"
extern "C" {
  typedef void (JNICALL *abort_hook_t)(void);
  typedef void (JNICALL *exit_hook_t)(jint code);
  typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args)  ATTRIBUTE_PRINTF(2, 0);
}
class SysClassPath;
class SystemProperty: public CHeapObj<mtInternal> {
 private:
  char*           _key;
  char*           _value;
  SystemProperty* _next;
  bool            _writeable;
  bool writeable()   { return _writeable; }
 public:
  const char* key() const                   { return _key; }
  char* value() const                       { return _value; }
  SystemProperty* next() const              { return _next; }
  void set_next(SystemProperty* next)       { _next = next; }
  bool set_value(char *value) {
    if (writeable()) {
      if (_value != NULL) {
        FreeHeap(_value);
      }
      _value = AllocateHeap(strlen(value)+1, mtInternal);
      if (_value != NULL) {
        strcpy(_value, value);
      }
      return true;
    }
    return false;
  }
  void append_value(const char *value) {
    char *sp;
    size_t len = 0;
    if (value != NULL) {
      len = strlen(value);
      if (_value != NULL) {
        len += strlen(_value);
      }
      sp = AllocateHeap(len+2, mtInternal);
      if (sp != NULL) {
        if (_value != NULL) {
          strcpy(sp, _value);
          strcat(sp, os::path_separator());
          strcat(sp, value);
          FreeHeap(_value);
        } else {
          strcpy(sp, value);
        }
        _value = sp;
      }
    }
  }
  SystemProperty(const char* key, const char* value, bool writeable) {
    if (key == NULL) {
      _key = NULL;
    } else {
      _key = AllocateHeap(strlen(key)+1, mtInternal);
      strcpy(_key, key);
    }
    if (value == NULL) {
      _value = NULL;
    } else {
      _value = AllocateHeap(strlen(value)+1, mtInternal);
      strcpy(_value, value);
    }
    _next = NULL;
    _writeable = writeable;
  }
};
class AgentLibrary : public CHeapObj<mtInternal> {
  friend class AgentLibraryList;
public:
  enum AgentState {
    agent_invalid = 0,
    agent_valid   = 1
  };
 private:
  char*           _name;
  char*           _options;
  void*           _os_lib;
  bool            _is_absolute_path;
  bool            _is_static_lib;
  AgentState      _state;
  AgentLibrary*   _next;
 public:
  const char* name() const                  { return _name; }
  char* options() const                     { return _options; }
  bool is_absolute_path() const             { return _is_absolute_path; }
  void* os_lib() const                      { return _os_lib; }
  void set_os_lib(void* os_lib)             { _os_lib = os_lib; }
  AgentLibrary* next() const                { return _next; }
  bool is_static_lib() const                { return _is_static_lib; }
  void set_static_lib(bool is_static_lib)   { _is_static_lib = is_static_lib; }
  bool valid()                              { return (_state == agent_valid); }
  void set_valid()                          { _state = agent_valid; }
  void set_invalid()                        { _state = agent_invalid; }
  AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
    _name = AllocateHeap(strlen(name)+1, mtInternal);
    strcpy(_name, name);
    if (options == NULL) {
      _options = NULL;
    } else {
      _options = AllocateHeap(strlen(options)+1, mtInternal);
      strcpy(_options, options);
    }
    _is_absolute_path = is_absolute_path;
    _os_lib = os_lib;
    _next = NULL;
    _state = agent_invalid;
    _is_static_lib = false;
  }
};
class AgentLibraryList VALUE_OBJ_CLASS_SPEC {
 private:
  AgentLibrary*   _first;
  AgentLibrary*   _last;
 public:
  bool is_empty() const                     { return _first == NULL; }
  AgentLibrary* first() const               { return _first; }
  void add(AgentLibrary* lib) {
    if (is_empty()) {
      _first = _last = lib;
    } else {
      _last->_next = lib;
      _last = lib;
    }
    lib->_next = NULL;
  }
  void remove(AgentLibrary* lib) {
    AgentLibrary* curr;
    AgentLibrary* prev = NULL;
    for (curr = first(); curr != NULL; prev = curr, curr = curr->next()) {
      if (curr == lib) {
        break;
      }
    }
    assert(curr != NULL, "always should be found");
    if (curr != NULL) {
      if (prev == NULL) {
        _first = curr->_next;
      } else {
        prev->_next = curr->_next;
      }
      if (curr == _last) {
        _last = prev;
      }
      curr->_next = NULL;
    }
  }
  AgentLibraryList() {
    _first = NULL;
    _last = NULL;
  }
};
class Arguments : AllStatic {
  friend class VMStructs;
  friend class JvmtiExport;
 public:
  enum Mode {
    _int,       // corresponds to -Xint
    _mixed,     // corresponds to -Xmixed
    _comp       // corresponds to -Xcomp
  };
  enum ArgsRange {
    arg_unreadable = -3,
    arg_too_small  = -2,
    arg_too_big    = -1,
    arg_in_range   = 0
  };
 private:
  static char** _jvm_flags_array;
  static int    _num_jvm_flags;
  static char** _jvm_args_array;
  static int    _num_jvm_args;
  static char* _java_command;
  static SystemProperty* _system_properties;
  static SystemProperty *_java_ext_dirs;
  static SystemProperty *_java_endorsed_dirs;
  static SystemProperty *_sun_boot_library_path;
  static SystemProperty *_java_library_path;
  static SystemProperty *_java_home;
  static SystemProperty *_java_class_path;
  static SystemProperty *_sun_boot_class_path;
  static char* _meta_index_path;
  static char* _meta_index_dir;
  static const char* _java_vendor_url_bug;
  static const char* _sun_java_launcher;
  static int    _sun_java_launcher_pid;
  static bool   _created_by_gamma_launcher;
  static bool   _has_profile;
  static const char*  _gc_log_filename;
  static size_t  _conservative_max_heap_alignment;
  static uintx _min_heap_size;
  static uintx _min_heap_free_ratio;
  static uintx _max_heap_free_ratio;
  static AgentLibraryList _libraryList;
  static void add_init_library(const char* name, char* options)
    { _libraryList.add(new AgentLibrary(name, options, false, NULL)); }
  static AgentLibraryList _agentList;
  static void add_init_agent(const char* name, char* options, bool absolute_path)
    { _agentList.add(new AgentLibrary(name, options, absolute_path, NULL)); }
  static void add_loaded_agent(AgentLibrary *agentLib)
    { _agentList.add(agentLib); }
  static void add_loaded_agent(const char* name, char* options, bool absolute_path, void* os_lib)
    { _agentList.add(new AgentLibrary(name, options, absolute_path, os_lib)); }
  static Mode _mode;
  static void set_mode_flags(Mode mode);
  static bool _java_compiler;
  static void set_java_compiler(bool arg) { _java_compiler = arg; }
  static bool java_compiler()   { return _java_compiler; }
  static bool _xdebug_mode;
  static void set_xdebug_mode(bool arg) { _xdebug_mode = arg; }
  static bool xdebug_mode()             { return _xdebug_mode; }
  static bool _AlwaysCompileLoopMethods;
  static bool _UseOnStackReplacement;
  static bool _BackgroundCompilation;
  static bool _ClipInlining;
  static bool _CIDynamicCompilePriority;
  static void set_tiered_flags();
  static int  get_min_number_of_compiler_threads();
  static void set_parnew_gc_flags();
  static void set_cms_and_parnew_gc_flags();
  static void set_parallel_gc_flags();
  static void set_g1_gc_flags();
  static void set_conservative_max_heap_alignment();
  static void set_use_compressed_oops();
  static void set_use_compressed_klass_ptrs();
  static void select_gc();
  static void set_ergonomics_flags();
  static void set_shared_spaces_flags();
  static julong limit_by_allocatable_memory(julong size);
  static void set_heap_size();
  static bool should_auto_select_low_pause_collector();
  static void set_bytecode_flags();
  static abort_hook_t     _abort_hook;
  static exit_hook_t      _exit_hook;
  static vfprintf_hook_t  _vfprintf_hook;
  static bool add_property(const char* prop);
  static void set_aggressive_opts_flags();
  static jint set_aggressive_heap_flags();
  static void do_pd_flag_adjustments();
  static bool parse_argument(const char* arg, Flag::Flags origin);
  static bool process_argument(const char* arg, jboolean ignore_unrecognized, Flag::Flags origin);
  static void process_java_launcher_argument(const char*, void*);
  static void process_java_compiler_argument(char* arg);
  static jint parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p);
  static jint parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
  static jint parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
  static jint parse_vm_init_args(const JavaVMInitArgs* args);
  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin);
  static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required);
  static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
  static bool is_bad_option(const JavaVMOption* option, jboolean ignore) {
    return is_bad_option(option, ignore, NULL);
  }
  static bool is_percentage(uintx val) {
    return val <= 100;
  }
  static bool verify_interval(uintx val, uintx min,
                              uintx max, const char* name);
  static bool verify_min_value(intx val, intx min, const char* name);
  static bool verify_percentage(uintx value, const char* name);
  static void describe_range_error(ArgsRange errcode);
  static ArgsRange check_memory_size(julong size, julong min_size);
  static ArgsRange parse_memory_size(const char* s, julong* long_arg,
                                     julong min_size);
  static bool parse_uintx(const char* value, uintx* uintx_arg,
                          uintx min_size);
  static void build_jvm_args(const char* arg);
  static void build_jvm_flags(const char* arg);
  static void add_string(char*** bldarray, int* count, const char* arg);
  static const char* build_resource_string(char** args, int count);
  static bool methodExists(
    char* className, char* methodName,
    int classesNum, char** classes, bool* allMethods,
    int methodsNum, char** methods, bool* allClasses
  );
  static void parseOnlyLine(
    const char* line,
    short* classesNum, short* classesMax, char*** classes, bool** allMethods,
    short* methodsNum, short* methodsMax, char*** methods, bool** allClasses
  );
  static bool is_newly_obsolete(const char* s, JDK_Version* buffer);
  static short  CompileOnlyClassesNum;
  static short  CompileOnlyClassesMax;
  static char** CompileOnlyClasses;
  static bool*  CompileOnlyAllMethods;
  static short  CompileOnlyMethodsNum;
  static short  CompileOnlyMethodsMax;
  static char** CompileOnlyMethods;
  static bool*  CompileOnlyAllClasses;
  static short  InterpretOnlyClassesNum;
  static short  InterpretOnlyClassesMax;
  static char** InterpretOnlyClasses;
  static bool*  InterpretOnlyAllMethods;
  static bool   CheckCompileOnly;
  static char*  SharedArchivePath;
 public:
  static jint parse(const JavaVMInitArgs* args);
  static jint apply_ergo();
  static jint adjust_after_os();
  static void set_gc_specific_flags();
  static inline bool gc_selected(); // whether a gc has been selected
  static void select_gc_ergonomically();
  static bool verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio);
  static bool verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio);
  static bool check_gc_consistency();        // Check user-selected gc
  static void check_deprecated_gcs();
  static void check_deprecated_gc_flags();
  static bool check_vm_args_consistency();
  static bool check_stack_pages();
  static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized);
  static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; }
  static size_t max_heap_for_compressed_oops();
  static char** jvm_flags_array()          { return _jvm_flags_array; }
  static char** jvm_args_array()           { return _jvm_args_array; }
  static int num_jvm_flags()               { return _num_jvm_flags; }
  static int num_jvm_args()                { return _num_jvm_args; }
  static const char* java_command()        { return _java_command; }
  static void print_on(outputStream* st);
  static const char* jvm_flags()           { return build_resource_string(_jvm_flags_array, _num_jvm_flags); }
  static const char* jvm_args()            { return build_resource_string(_jvm_args_array, _num_jvm_args); }
  static void print_jvm_flags_on(outputStream* st);
  static void print_jvm_args_on(outputStream* st);
  static SystemProperty*  system_properties()   { return _system_properties; }
  static const char*    get_property(const char* key);
  static const char* java_vendor_url_bug()  { return _java_vendor_url_bug; }
  static const char* sun_java_launcher()    { return _sun_java_launcher; }
  static bool created_by_java_launcher();
  static bool created_by_gamma_launcher();
  static int sun_java_launcher_pid()        { return _sun_java_launcher_pid; }
  static const char* gc_log_filename()      { return _gc_log_filename; }
  static bool has_profile()                 { return _has_profile; }
  static uintx min_heap_size()              { return _min_heap_size; }
  static void  set_min_heap_size(uintx v)   { _min_heap_size = v;  }
  static uintx min_heap_free_ratio()        { return _min_heap_free_ratio; }
  static uintx max_heap_free_ratio()        { return _max_heap_free_ratio; }
  static AgentLibrary* libraries()          { return _libraryList.first(); }
  static bool init_libraries_at_startup()   { return !_libraryList.is_empty(); }
  static void convert_library_to_agent(AgentLibrary* lib)
                                            { _libraryList.remove(lib);
                                              _agentList.add(lib); }
  static AgentLibrary* agents()             { return _agentList.first(); }
  static bool init_agents_at_startup()      { return !_agentList.is_empty(); }
  static abort_hook_t    abort_hook()       { return _abort_hook; }
  static exit_hook_t     exit_hook()        { return _exit_hook; }
  static vfprintf_hook_t vfprintf_hook()    { return _vfprintf_hook; }
  static bool GetCheckCompileOnly ()        { return CheckCompileOnly; }
  static const char* GetSharedArchivePath() { return SharedArchivePath; }
  static bool CompileMethod(char* className, char* methodName) {
    return
      methodExists(
        className, methodName,
        CompileOnlyClassesNum, CompileOnlyClasses, CompileOnlyAllMethods,
        CompileOnlyMethodsNum, CompileOnlyMethods, CompileOnlyAllClasses
      );
  }
  static void process_sun_java_launcher_properties(JavaVMInitArgs* args);
  static void init_system_properties();
  static void init_version_specific_system_properties();
  static void PropertyList_add(SystemProperty** plist, SystemProperty *element);
  static void PropertyList_add(SystemProperty** plist, const char* k, char* v);
  static void PropertyList_unique_add(SystemProperty** plist, const char* k, char* v) {
    PropertyList_unique_add(plist, k, v, false);
  }
  static void PropertyList_unique_add(SystemProperty** plist, const char* k, char* v, jboolean append);
  static const char* PropertyList_get_value(SystemProperty* plist, const char* key);
  static int  PropertyList_count(SystemProperty* pl);
  static const char* PropertyList_get_key_at(SystemProperty* pl,int index);
  static char* PropertyList_get_value_at(SystemProperty* pl,int index);
  static void set_dll_dir(char *value) { _sun_boot_library_path->set_value(value); }
  static void set_java_home(char *value) { _java_home->set_value(value); }
  static void set_library_path(char *value) { _java_library_path->set_value(value); }
  static void set_ext_dirs(char *value) { _java_ext_dirs->set_value(value); }
  static void set_endorsed_dirs(char *value) { _java_endorsed_dirs->set_value(value); }
  static void set_sysclasspath(char *value) { _sun_boot_class_path->set_value(value); }
  static void append_sysclasspath(const char *value) { _sun_boot_class_path->append_value(value); }
  static void set_meta_index_path(char* meta_index_path, char* meta_index_dir) {
    _meta_index_path = meta_index_path;
    _meta_index_dir  = meta_index_dir;
  }
  static char* get_java_home() { return _java_home->value(); }
  static char* get_dll_dir() { return _sun_boot_library_path->value(); }
  static char* get_endorsed_dir() { return _java_endorsed_dirs->value(); }
  static char* get_sysclasspath() { return _sun_boot_class_path->value(); }
  static char* get_meta_index_path() { return _meta_index_path; }
  static char* get_meta_index_dir()  { return _meta_index_dir;  }
  static char* get_ext_dirs() { return _java_ext_dirs->value(); }
  static char* get_appclasspath() { return _java_class_path->value(); }
  static void  fix_appclasspath();
  static Mode mode()                { return _mode; }
  static bool is_interpreter_only() { return mode() == _int; }
  static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
};
bool Arguments::gc_selected() {
  return UseConcMarkSweepGC || UseG1GC || UseParallelGC || UseParallelOldGC ||
    UseParNewGC || UseSerialGC;
}
#endif // SHARE_VM_RUNTIME_ARGUMENTS_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/arguments_ext.hpp
#ifndef SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
#define SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
#include "memory/allocation.hpp"
#include "runtime/arguments.hpp"
class ArgumentsExt: AllStatic {
public:
  static inline void set_gc_specific_flags();
  static        void process_options(const JavaVMInitArgs* args) {}
};
void ArgumentsExt::set_gc_specific_flags() {
  Arguments::set_gc_specific_flags();
}
#endif // SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/atomic.cpp
#include "precompiled.hpp"
#include "runtime/atomic.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "os_aix.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
#include "runtime/atomic.inline.hpp"
jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
  assert(sizeof(jbyte) == 1, "assumption.");
  uintptr_t dest_addr = (uintptr_t)dest;
  uintptr_t offset = dest_addr % sizeof(jint);
  volatile jint* dest_int = (volatile jint*)(dest_addr - offset);
  jint cur = *dest_int;
  jbyte* cur_as_bytes = (jbyte*)(&cur);
  jint new_val = cur;
  jbyte* new_val_as_bytes = (jbyte*)(&new_val);
  new_val_as_bytes[offset] = exchange_value;
  while (cur_as_bytes[offset] == compare_value) {
    jint res = cmpxchg(new_val, dest_int, cur);
    if (res == cur) break;
    cur = res;
    new_val = cur;
    new_val_as_bytes[offset] = exchange_value;
  }
  return cur_as_bytes[offset];
}
unsigned Atomic::xchg(unsigned int exchange_value, volatile unsigned int* dest) {
  assert(sizeof(unsigned int) == sizeof(jint), "more work to do");
  return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest);
}
unsigned Atomic::cmpxchg(unsigned int exchange_value,
                         volatile unsigned int* dest, unsigned int compare_value) {
  assert(sizeof(unsigned int) == sizeof(jint), "more work to do");
  return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest,
                                       (jint)compare_value);
}
jlong Atomic::add(jlong    add_value, volatile jlong*    dest) {
  jlong old = load(dest);
  jlong new_value = old + add_value;
  while (old != cmpxchg(new_value, dest, old)) {
    old = load(dest);
    new_value = old + add_value;
  }
  return old;
}
void Atomic::inc(volatile short* dest) {
#ifdef VM_LITTLE_ENDIAN
  assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
  (void)Atomic::add(0x10000, (volatile int*)(dest-1));
#else
  assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
  (void)Atomic::add(0x10000, (volatile int*)(dest));
#endif
}
void Atomic::dec(volatile short* dest) {
#ifdef VM_LITTLE_ENDIAN
  assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
  (void)Atomic::add(-0x10000, (volatile int*)(dest-1));
#else
  assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
  (void)Atomic::add(-0x10000, (volatile int*)(dest));
#endif
}
C:\hotspot-69087d08d473\src\share\vm/runtime/atomic.hpp
#ifndef SHARE_VM_RUNTIME_ATOMIC_HPP
#define SHARE_VM_RUNTIME_ATOMIC_HPP
#include "memory/allocation.hpp"
class Atomic : AllStatic {
 public:
  inline static void store    (jbyte    store_value, jbyte*    dest);
  inline static void store    (jshort   store_value, jshort*   dest);
  inline static void store    (jint     store_value, jint*     dest);
  inline static void store    (jlong    store_value, jlong*    dest);
  inline static void store_ptr(intptr_t store_value, intptr_t* dest);
  inline static void store_ptr(void*    store_value, void*     dest);
  inline static void store    (jbyte    store_value, volatile jbyte*    dest);
  inline static void store    (jshort   store_value, volatile jshort*   dest);
  inline static void store    (jint     store_value, volatile jint*     dest);
  inline static void store    (jlong    store_value, volatile jlong*    dest);
  inline static void store_ptr(intptr_t store_value, volatile intptr_t* dest);
  inline static void store_ptr(void*    store_value, volatile void*     dest);
  inline static jlong load(volatile jlong* src);
  inline static jint     add    (jint     add_value, volatile jint*     dest);
  inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
  inline static void*    add_ptr(intptr_t add_value, volatile void*     dest);
         static jlong    add    (jlong    add_value, volatile jlong*    dest);
  inline static void inc    (volatile jint*     dest);
         static void inc    (volatile jshort*   dest);
  inline static void inc_ptr(volatile intptr_t* dest);
  inline static void inc_ptr(volatile void*     dest);
  inline static void dec    (volatile jint*     dest);
         static void dec    (volatile jshort*    dest);
  inline static void dec_ptr(volatile intptr_t* dest);
  inline static void dec_ptr(volatile void*     dest);
  inline static jint         xchg(jint         exchange_value, volatile jint*         dest);
         static unsigned int xchg(unsigned int exchange_value, volatile unsigned int* dest);
  inline static intptr_t xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest);
  inline static void*    xchg_ptr(void*    exchange_value, volatile void*   dest);
         static jbyte    cmpxchg    (jbyte    exchange_value, volatile jbyte*    dest, jbyte    compare_value);
  inline static jint     cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value);
  inline static jlong    cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value);
         static unsigned int cmpxchg(unsigned int exchange_value,
                                     volatile unsigned int* dest,
                                     unsigned int compare_value);
  inline static intptr_t cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value);
  inline static void*    cmpxchg_ptr(void*    exchange_value, volatile void*     dest, void*    compare_value);
};
#ifdef VM_LITTLE_ENDIAN
#define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \
    non_atomic_decl; \
    atomic_decl
#else
#define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \
    atomic_decl ; \
    non_atomic_decl
#endif
#endif // SHARE_VM_RUNTIME_ATOMIC_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/atomic.inline.hpp
#ifndef SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP
#define SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP
#include "runtime/atomic.hpp"
#ifdef TARGET_OS_ARCH_linux_x86
# include "atomic_linux_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_sparc
# include "atomic_linux_sparc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_zero
# include "atomic_linux_zero.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_arm
# include "atomic_linux_arm.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_ppc
# include "atomic_linux_ppc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_aarch64
# include "atomic_linux_aarch64.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_x86
# include "atomic_solaris_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_sparc
# include "atomic_solaris_sparc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_windows_x86
# include "atomic_windows_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_aix_ppc
# include "atomic_aix_ppc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_x86
# include "atomic_bsd_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_zero
# include "atomic_bsd_zero.inline.hpp"
#endif
#endif // SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/basicLock.cpp
#include "precompiled.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/synchronizer.hpp"
void BasicLock::print_on(outputStream* st) const {
  st->print("monitor");
  markOop moop = displaced_header();
  if (moop != NULL)
    moop->print_on(st);
}
void BasicLock::move_to(oop obj, BasicLock* dest) {
  if (displaced_header()->is_neutral()) {
    ObjectSynchronizer::inflate_helper(obj);
  } else {
  }
  intptr_t dh = (intptr_t) displaced_header();
  dest->set_displaced_header(displaced_header());
}
C:\hotspot-69087d08d473\src\share\vm/runtime/basicLock.hpp
#ifndef SHARE_VM_RUNTIME_BASICLOCK_HPP
#define SHARE_VM_RUNTIME_BASICLOCK_HPP
#include "oops/markOop.hpp"
#include "runtime/handles.hpp"
#include "utilities/top.hpp"
class BasicLock VALUE_OBJ_CLASS_SPEC {
  friend class VMStructs;
 private:
  volatile markOop _displaced_header;
 public:
  markOop      displaced_header() const               { return _displaced_header; }
  void         set_displaced_header(markOop header)   { _displaced_header = header; }
  void print_on(outputStream* st) const;
  void move_to(oop obj, BasicLock* dest);
  static int displaced_header_offset_in_bytes()       { return offset_of(BasicLock, _displaced_header); }
};
class BasicObjectLock VALUE_OBJ_CLASS_SPEC {
  friend class VMStructs;
 private:
  BasicLock _lock;                                    // the lock, must be double word aligned
  oop       _obj;                                     // object holds the lock;
 public:
  oop      obj() const                                { return _obj;  }
  void set_obj(oop obj)                               { _obj = obj; }
  BasicLock* lock()                                   { return &_lock; }
  static int size()                                   { return sizeof(BasicObjectLock)/wordSize; }
  void oops_do(OopClosure* f) { f->do_oop(&_obj); }
  static int obj_offset_in_bytes()                    { return offset_of(BasicObjectLock, _obj);  }
  static int lock_offset_in_bytes()                   { return offset_of(BasicObjectLock, _lock); }
};
#endif // SHARE_VM_RUNTIME_BASICLOCK_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/biasedLocking.cpp
#include "precompiled.hpp"
#include "oops/klass.inline.hpp"
#include "oops/markOop.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/task.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "jfr/support/jfrThreadId.hpp"
#include "jfr/jfrEvents.hpp"
static bool _biased_locking_enabled = false;
BiasedLockingCounters BiasedLocking::_counters;
static GrowableArray<Handle>*  _preserved_oop_stack  = NULL;
static GrowableArray<markOop>* _preserved_mark_stack = NULL;
static void enable_biased_locking(Klass* k) {
  k->set_prototype_header(markOopDesc::biased_locking_prototype());
}
class VM_EnableBiasedLocking: public VM_Operation {
 private:
  bool _is_cheap_allocated;
 public:
  VM_EnableBiasedLocking(bool is_cheap_allocated) { _is_cheap_allocated = is_cheap_allocated; }
  VMOp_Type type() const          { return VMOp_EnableBiasedLocking; }
  Mode evaluation_mode() const    { return _is_cheap_allocated ? _async_safepoint : _safepoint; }
  bool is_cheap_allocated() const { return _is_cheap_allocated; }
  void doit() {
    SystemDictionary::classes_do(enable_biased_locking);
    _biased_locking_enabled = true;
    if (TraceBiasedLocking) {
      tty->print_cr("Biased locking enabled");
    }
  }
  bool allow_nested_vm_operations() const        { return false; }
};
class EnableBiasedLockingTask : public PeriodicTask {
 public:
  EnableBiasedLockingTask(size_t interval_time) : PeriodicTask(interval_time) {}
  virtual void task() {
    VM_EnableBiasedLocking *op = new VM_EnableBiasedLocking(true);
    VMThread::execute(op);
    delete this;
  }
};
void BiasedLocking::init() {
  if (UseBiasedLocking) {
    if (BiasedLockingStartupDelay > 0) {
      EnableBiasedLockingTask* task = new EnableBiasedLockingTask(BiasedLockingStartupDelay);
      task->enroll();
    } else {
      VM_EnableBiasedLocking op(false);
      VMThread::execute(&op);
    }
  }
}
bool BiasedLocking::enabled() {
  return _biased_locking_enabled;
}
static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thread) {
  GrowableArray<MonitorInfo*>* info = thread->cached_monitor_info();
  if (info != NULL) {
    return info;
  }
  info = new GrowableArray<MonitorInfo*>();
  if (thread->has_last_Java_frame()) {
    RegisterMap rm(thread);
    for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) {
      GrowableArray<MonitorInfo*> *monitors = vf->monitors();
      if (monitors != NULL) {
        int len = monitors->length();
        for (int i = len - 1; i >= 0; i--) {
          MonitorInfo* mon_info = monitors->at(i);
          if (mon_info->eliminated()) continue;
          oop owner = mon_info->owner();
          if (owner != NULL) {
            info->append(mon_info);
          }
        }
      }
    }
  }
  thread->set_cached_monitor_info(info);
  return info;
}
static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
  markOop mark = obj->mark();
  if (!mark->has_bias_pattern()) {
    if (TraceBiasedLocking) {
      ResourceMark rm;
      tty->print_cr("  (Skipping revocation of object of type %s because it's no longer biased)",
                    obj->klass()->external_name());
    }
    return BiasedLocking::NOT_BIASED;
  }
  uint age = mark->age();
  markOop   biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
  markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
  if (TraceBiasedLocking && (Verbose || !is_bulk)) {
    ResourceMark rm;
    tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
                  p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
  }
  JavaThread* biased_thread = mark->biased_locker();
  if (biased_thread == NULL) {
    if (!allow_rebias) {
      obj->set_mark(unbiased_prototype);
    }
    if (TraceBiasedLocking && (Verbose || !is_bulk)) {
      tty->print_cr("  Revoked bias of anonymously-biased object");
    }
    return BiasedLocking::BIAS_REVOKED;
  }
  bool thread_is_alive = false;
  if (requesting_thread == biased_thread) {
    thread_is_alive = true;
  } else {
    for (JavaThread* cur_thread = Threads::first(); cur_thread != NULL; cur_thread = cur_thread->next()) {
      if (cur_thread == biased_thread) {
        thread_is_alive = true;
        break;
      }
    }
  }
  if (!thread_is_alive) {
    if (allow_rebias) {
      obj->set_mark(biased_prototype);
    } else {
      obj->set_mark(unbiased_prototype);
    }
    if (TraceBiasedLocking && (Verbose || !is_bulk)) {
      tty->print_cr("  Revoked bias of object biased toward dead thread");
    }
    return BiasedLocking::BIAS_REVOKED;
  }
  GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread);
  BasicLock* highest_lock = NULL;
  for (int i = 0; i < cached_monitor_info->length(); i++) {
    MonitorInfo* mon_info = cached_monitor_info->at(i);
    if (mon_info->owner() == obj) {
      if (TraceBiasedLocking && Verbose) {
        tty->print_cr("   mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
                      p2i((void *) mon_info->owner()),
                      p2i((void *) obj));
      }
      markOop mark = markOopDesc::encode((BasicLock*) NULL);
      highest_lock = mon_info->lock();
      highest_lock->set_displaced_header(mark);
    } else {
      if (TraceBiasedLocking && Verbose) {
        tty->print_cr("   mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
                      p2i((void *) mon_info->owner()),
                      p2i((void *) obj));
      }
    }
  }
  if (highest_lock != NULL) {
    highest_lock->set_displaced_header(unbiased_prototype);
    obj->release_set_mark(markOopDesc::encode(highest_lock));
    assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
    if (TraceBiasedLocking && (Verbose || !is_bulk)) {
      tty->print_cr("  Revoked bias of currently-locked object");
    }
  } else {
    if (TraceBiasedLocking && (Verbose || !is_bulk)) {
      tty->print_cr("  Revoked bias of currently-unlocked object");
    }
    if (allow_rebias) {
      obj->set_mark(biased_prototype);
    } else {
      obj->set_mark(unbiased_prototype);
    }
  }
#if INCLUDE_JFR
  if (biased_locker != NULL) {
  }
#endif // INCLUDE_JFR
  return BiasedLocking::BIAS_REVOKED;
}
enum HeuristicsResult {
  HR_NOT_BIASED    = 1,
  HR_SINGLE_REVOKE = 2,
  HR_BULK_REBIAS   = 3,
  HR_BULK_REVOKE   = 4
};
static HeuristicsResult update_heuristics(oop o, bool allow_rebias) {
  markOop mark = o->mark();
  if (!mark->has_bias_pattern()) {
    return HR_NOT_BIASED;
  }
  Klass* k = o->klass();
  jlong cur_time = os::javaTimeMillis();
  jlong last_bulk_revocation_time = k->last_biased_lock_bulk_revocation_time();
  int revocation_count = k->biased_lock_revocation_count();
  if ((revocation_count >= BiasedLockingBulkRebiasThreshold) &&
      (revocation_count <  BiasedLockingBulkRevokeThreshold) &&
      (last_bulk_revocation_time != 0) &&
      (cur_time - last_bulk_revocation_time >= BiasedLockingDecayTime)) {
    k->set_biased_lock_revocation_count(0);
    revocation_count = 0;
  }
  if (revocation_count <= BiasedLockingBulkRevokeThreshold) {
    revocation_count = k->atomic_incr_biased_lock_revocation_count();
  }
  if (revocation_count == BiasedLockingBulkRevokeThreshold) {
    return HR_BULK_REVOKE;
  }
  if (revocation_count == BiasedLockingBulkRebiasThreshold) {
    return HR_BULK_REBIAS;
  }
  return HR_SINGLE_REVOKE;
}
static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
                                                                   bool bulk_rebias,
                                                                   bool attempt_rebias_of_object,
                                                                   JavaThread* requesting_thread) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
  if (TraceBiasedLocking) {
    tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
                  INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
                  (bulk_rebias ? "rebias" : "revoke"),
                  p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name());
  }
  jlong cur_time = os::javaTimeMillis();
  o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
  Klass* k_o = o->klass();
  Klass* klass = k_o;
  if (bulk_rebias) {
    if (klass->prototype_header()->has_bias_pattern()) {
      int prev_epoch = klass->prototype_header()->bias_epoch();
      klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch());
      int cur_epoch = klass->prototype_header()->bias_epoch();
      for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
        GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
        for (int i = 0; i < cached_monitor_info->length(); i++) {
          MonitorInfo* mon_info = cached_monitor_info->at(i);
          oop owner = mon_info->owner();
          markOop mark = owner->mark();
          if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
            assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
            owner->set_mark(mark->set_bias_epoch(cur_epoch));
          }
        }
      }
    }
    revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
  } else {
    if (TraceBiasedLocking) {
      ResourceMark rm;
      tty->print_cr("* Disabling biased locking for type %s", klass->external_name());
    }
    klass->set_prototype_header(markOopDesc::prototype());
    for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
      GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
      for (int i = 0; i < cached_monitor_info->length(); i++) {
        MonitorInfo* mon_info = cached_monitor_info->at(i);
        oop owner = mon_info->owner();
        markOop mark = owner->mark();
        if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
          revoke_bias(owner, false, true, requesting_thread, NULL);
        }
      }
    }
    revoke_bias(o, false, true, requesting_thread, NULL);
  }
  if (TraceBiasedLocking) {
    tty->print_cr("* Ending bulk revocation");
  }
  BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
  if (attempt_rebias_of_object &&
      o->mark()->has_bias_pattern() &&
      klass->prototype_header()->has_bias_pattern()) {
    markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(),
                                           klass->prototype_header()->bias_epoch());
    o->set_mark(new_mark);
    status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
    if (TraceBiasedLocking) {
      tty->print_cr("  Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
    }
  }
  assert(!o->mark()->has_bias_pattern() ||
         (attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)),
         "bug in bulk bias revocation");
  return status_code;
}
static void clean_up_cached_monitor_info() {
  for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
    thr->set_cached_monitor_info(NULL);
  }
}
class VM_RevokeBias : public VM_Operation {
protected:
  Handle* _obj;
  GrowableArray<Handle>* _objs;
  JavaThread* _requesting_thread;
  BiasedLocking::Condition _status_code;
  traceid _biased_locker_id;
public:
  VM_RevokeBias(Handle* obj, JavaThread* requesting_thread)
    : _obj(obj)
    , _objs(NULL)
    , _requesting_thread(requesting_thread)
    , _status_code(BiasedLocking::NOT_BIASED)
    , _biased_locker_id(0) {}
  VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread)
    : _obj(NULL)
    , _objs(objs)
    , _requesting_thread(requesting_thread)
    , _status_code(BiasedLocking::NOT_BIASED)
    , _biased_locker_id(0) {}
  virtual VMOp_Type type() const { return VMOp_RevokeBias; }
  virtual bool doit_prologue() {
    if (_obj != NULL) {
      markOop mark = (*_obj)()->mark();
      if (mark->has_bias_pattern()) {
        return true;
      }
    } else {
      for ( int i = 0 ; i < _objs->length(); i++ ) {
        markOop mark = (_objs->at(i))()->mark();
        if (mark->has_bias_pattern()) {
          return true;
        }
      }
    }
    return false;
  }
  virtual void doit() {
    if (_obj != NULL) {
      if (TraceBiasedLocking) {
        tty->print_cr("Revoking bias with potentially per-thread safepoint:");
      }
      JavaThread* biased_locker = NULL;
      _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker);
#if INCLUDE_JFR
      if (biased_locker != NULL) {
        _biased_locker_id = JFR_THREAD_ID(biased_locker);
      }
#endif // INCLUDE_JFR
      clean_up_cached_monitor_info();
      return;
    } else {
      if (TraceBiasedLocking) {
        tty->print_cr("Revoking bias with global safepoint:");
      }
      BiasedLocking::revoke_at_safepoint(_objs);
    }
  }
  BiasedLocking::Condition status_code() const {
    return _status_code;
  }
  traceid biased_locker() const {
    return _biased_locker_id;
  }
};
class VM_BulkRevokeBias : public VM_RevokeBias {
private:
  bool _bulk_rebias;
  bool _attempt_rebias_of_object;
public:
  VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread,
                    bool bulk_rebias,
                    bool attempt_rebias_of_object)
    : VM_RevokeBias(obj, requesting_thread)
    , _bulk_rebias(bulk_rebias)
    , _attempt_rebias_of_object(attempt_rebias_of_object) {}
  virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; }
  virtual bool doit_prologue()   { return true; }
  virtual void doit() {
    _status_code = bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
    clean_up_cached_monitor_info();
  }
};
BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
  assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
  markOop mark = obj->mark();
  if (mark->is_biased_anonymously() && !attempt_rebias) {
    markOop biased_value       = mark;
    markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
    markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);
    if (res_mark == biased_value) {
      return BIAS_REVOKED;
    }
  } else if (mark->has_bias_pattern()) {
    Klass* k = obj->klass();
    markOop prototype_header = k->prototype_header();
    if (!prototype_header->has_bias_pattern()) {
      markOop biased_value       = mark;
      markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, obj->mark_addr(), mark);
      assert(!(*(obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked");
      return BIAS_REVOKED;
    } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
      if (attempt_rebias) {
        assert(THREAD->is_Java_thread(), "");
        markOop biased_value       = mark;
        markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
        markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, obj->mark_addr(), mark);
        if (res_mark == biased_value) {
          return BIAS_REVOKED_AND_REBIASED;
        }
      } else {
        markOop biased_value       = mark;
        markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
        markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);
        if (res_mark == biased_value) {
          return BIAS_REVOKED;
        }
      }
    }
  }
  HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
  if (heuristics == HR_NOT_BIASED) {
    return NOT_BIASED;
  } else if (heuristics == HR_SINGLE_REVOKE) {
    Klass *k = obj->klass();
    markOop prototype_header = k->prototype_header();
    if (mark->biased_locker() == THREAD &&
        prototype_header->bias_epoch() == mark->bias_epoch()) {
      ResourceMark rm;
      if (TraceBiasedLocking) {
        tty->print_cr("Revoking bias by walking my own stack:");
      }
      EventBiasedLockSelfRevocation event;
      BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
      ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
      assert(cond == BIAS_REVOKED, "why not?");
      if (event.should_commit()) {
        event.set_lockClass(k);
        event.commit();
      }
      return cond;
    } else {
      EventBiasedLockRevocation event;
      VM_RevokeBias revoke(&obj, (JavaThread*) THREAD);
      VMThread::execute(&revoke);
      if (event.should_commit() && (revoke.status_code() != NOT_BIASED)) {
        event.set_lockClass(k);
        event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1);
        event.set_previousOwner(revoke.biased_locker());
        event.commit();
      }
      return revoke.status_code();
    }
  }
  assert((heuristics == HR_BULK_REVOKE) ||
         (heuristics == HR_BULK_REBIAS), "?");
  EventBiasedLockClassRevocation event;
  VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD,
                                (heuristics == HR_BULK_REBIAS),
                                attempt_rebias);
  VMThread::execute(&bulk_revoke);
  if (event.should_commit()) {
    event.set_revokedClass(obj->klass());
    event.set_disableBiasing((heuristics != HR_BULK_REBIAS));
    event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1);
    event.commit();
  }
  return bulk_revoke.status_code();
}
void BiasedLocking::revoke(GrowableArray<Handle>* objs) {
  assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
  if (objs->length() == 0) {
    return;
  }
  VM_RevokeBias revoke(objs, JavaThread::current());
  VMThread::execute(&revoke);
}
void BiasedLocking::revoke_at_safepoint(Handle h_obj) {
  assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
  oop obj = h_obj();
  HeuristicsResult heuristics = update_heuristics(obj, false);
  if (heuristics == HR_SINGLE_REVOKE) {
    revoke_bias(obj, false, false, NULL, NULL);
  } else if ((heuristics == HR_BULK_REBIAS) ||
             (heuristics == HR_BULK_REVOKE)) {
    bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
  }
  clean_up_cached_monitor_info();
}
void BiasedLocking::revoke_at_safepoint(GrowableArray<Handle>* objs) {
  assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
  int len = objs->length();
  for (int i = 0; i < len; i++) {
    oop obj = (objs->at(i))();
    HeuristicsResult heuristics = update_heuristics(obj, false);
    if (heuristics == HR_SINGLE_REVOKE) {
      revoke_bias(obj, false, false, NULL, NULL);
    } else if ((heuristics == HR_BULK_REBIAS) ||
               (heuristics == HR_BULK_REVOKE)) {
      bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
    }
  }
  clean_up_cached_monitor_info();
}
void BiasedLocking::preserve_marks() {
  if (!UseBiasedLocking)
    return;
  assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
  assert(_preserved_oop_stack  == NULL, "double initialization");
  assert(_preserved_mark_stack == NULL, "double initialization");
  _preserved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(10, true);
  _preserved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Handle>(10, true);
  ResourceMark rm;
  Thread* cur = Thread::current();
  for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
    if (thread->has_last_Java_frame()) {
      RegisterMap rm(thread);
      for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) {
        GrowableArray<MonitorInfo*> *monitors = vf->monitors();
        if (monitors != NULL) {
          int len = monitors->length();
          for (int i = len - 1; i >= 0; i--) {
            MonitorInfo* mon_info = monitors->at(i);
            if (mon_info->owner_is_scalar_replaced()) continue;
            oop owner = mon_info->owner();
            if (owner != NULL) {
              markOop mark = owner->mark();
              if (mark->has_bias_pattern()) {
                _preserved_oop_stack->push(Handle(cur, owner));
                _preserved_mark_stack->push(mark);
              }
            }
          }
        }
      }
    }
  }
}
void BiasedLocking::restore_marks() {
  if (!UseBiasedLocking)
    return;
  assert(_preserved_oop_stack  != NULL, "double free");
  assert(_preserved_mark_stack != NULL, "double free");
  int len = _preserved_oop_stack->length();
  for (int i = 0; i < len; i++) {
    Handle owner = _preserved_oop_stack->at(i);
    markOop mark = _preserved_mark_stack->at(i);
    owner->set_mark(mark);
  }
  delete _preserved_oop_stack;
  _preserved_oop_stack = NULL;
  delete _preserved_mark_stack;
  _preserved_mark_stack = NULL;
}
int* BiasedLocking::total_entry_count_addr()                   { return _counters.total_entry_count_addr(); }
int* BiasedLocking::biased_lock_entry_count_addr()             { return _counters.biased_lock_entry_count_addr(); }
int* BiasedLocking::anonymously_biased_lock_entry_count_addr() { return _counters.anonymously_biased_lock_entry_count_addr(); }
int* BiasedLocking::rebiased_lock_entry_count_addr()           { return _counters.rebiased_lock_entry_count_addr(); }
int* BiasedLocking::revoked_lock_entry_count_addr()            { return _counters.revoked_lock_entry_count_addr(); }
int* BiasedLocking::fast_path_entry_count_addr()               { return _counters.fast_path_entry_count_addr(); }
int* BiasedLocking::slow_path_entry_count_addr()               { return _counters.slow_path_entry_count_addr(); }
int BiasedLockingCounters::slow_path_entry_count() {
  if (_slow_path_entry_count != 0) {
    return _slow_path_entry_count;
  }
  int sum = _biased_lock_entry_count   + _anonymously_biased_lock_entry_count +
            _rebiased_lock_entry_count + _revoked_lock_entry_count +
            _fast_path_entry_count;
  return _total_entry_count - sum;
}
void BiasedLockingCounters::print_on(outputStream* st) {
  tty->print_cr("# total entries: %d", _total_entry_count);
  tty->print_cr("# biased lock entries: %d", _biased_lock_entry_count);
  tty->print_cr("# anonymously biased lock entries: %d", _anonymously_biased_lock_entry_count);
  tty->print_cr("# rebiased lock entries: %d", _rebiased_lock_entry_count);
  tty->print_cr("# revoked lock entries: %d", _revoked_lock_entry_count);
  tty->print_cr("# fast path lock entries: %d", _fast_path_entry_count);
  tty->print_cr("# slow path lock entries: %d", slow_path_entry_count());
}
C:\hotspot-69087d08d473\src\share\vm/runtime/biasedLocking.hpp
#ifndef SHARE_VM_RUNTIME_BIASEDLOCKING_HPP
#define SHARE_VM_RUNTIME_BIASEDLOCKING_HPP
#include "runtime/handles.hpp"
#include "utilities/growableArray.hpp"
class BiasedLockingCounters VALUE_OBJ_CLASS_SPEC {
 private:
  int _total_entry_count;
  int _biased_lock_entry_count;
  int _anonymously_biased_lock_entry_count;
  int _rebiased_lock_entry_count;
  int _revoked_lock_entry_count;
  int _fast_path_entry_count;
  int _slow_path_entry_count;
 public:
  BiasedLockingCounters() :
    _total_entry_count(0),
    _biased_lock_entry_count(0),
    _anonymously_biased_lock_entry_count(0),
    _rebiased_lock_entry_count(0),
    _revoked_lock_entry_count(0),
    _fast_path_entry_count(0),
    _slow_path_entry_count(0) {}
  int slow_path_entry_count(); // Compute this field if necessary
  int* total_entry_count_addr()                   { return &_total_entry_count; }
  int* biased_lock_entry_count_addr()             { return &_biased_lock_entry_count; }
  int* anonymously_biased_lock_entry_count_addr() { return &_anonymously_biased_lock_entry_count; }
  int* rebiased_lock_entry_count_addr()           { return &_rebiased_lock_entry_count; }
  int* revoked_lock_entry_count_addr()            { return &_revoked_lock_entry_count; }
  int* fast_path_entry_count_addr()               { return &_fast_path_entry_count; }
  int* slow_path_entry_count_addr()               { return &_slow_path_entry_count; }
  bool nonzero() { return _total_entry_count > 0; }
  void print_on(outputStream* st);
  void print() { print_on(tty); }
};
class BiasedLocking : AllStatic {
private:
  static BiasedLockingCounters _counters;
public:
  static int* total_entry_count_addr();
  static int* biased_lock_entry_count_addr();
  static int* anonymously_biased_lock_entry_count_addr();
  static int* rebiased_lock_entry_count_addr();
  static int* revoked_lock_entry_count_addr();
  static int* fast_path_entry_count_addr();
  static int* slow_path_entry_count_addr();
  enum Condition {
    NOT_BIASED = 1,
    BIAS_REVOKED = 2,
    BIAS_REVOKED_AND_REBIASED = 3
  };
  static void init();
  static bool enabled();
  static Condition revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS);
  static void revoke(GrowableArray<Handle>* objs);
  static void revoke_at_safepoint(Handle obj);
  static void revoke_at_safepoint(GrowableArray<Handle>* objs);
  static void print_counters() { _counters.print(); }
  static BiasedLockingCounters* counters() { return &_counters; }
  static void preserve_marks();
  static void restore_marks();
};
#endif // SHARE_VM_RUNTIME_BIASEDLOCKING_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/compilationPolicy.cpp
#include "precompiled.hpp"
#include "code/compiledIC.hpp"
#include "code/nmethod.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/compilerOracle.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/advancedThresholdPolicy.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/frame.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/rframe.hpp"
#include "runtime/simpleThresholdPolicy.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.hpp"
#include "runtime/timer.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/events.hpp"
#include "utilities/globalDefinitions.hpp"
CompilationPolicy* CompilationPolicy::_policy;
elapsedTimer       CompilationPolicy::_accumulated_time;
bool               CompilationPolicy::_in_vm_startup;
void compilationPolicy_init() {
  CompilationPolicy::set_in_vm_startup(DelayCompilationDuringStartup);
  switch(CompilationPolicyChoice) {
  case 0:
    CompilationPolicy::set_policy(new SimpleCompPolicy());
    break;
  case 1:
#ifdef COMPILER2
    CompilationPolicy::set_policy(new StackWalkCompPolicy());
#else
    Unimplemented();
#endif
    break;
  case 2:
#ifdef TIERED
    CompilationPolicy::set_policy(new SimpleThresholdPolicy());
#else
    Unimplemented();
#endif
    break;
  case 3:
#ifdef TIERED
    CompilationPolicy::set_policy(new AdvancedThresholdPolicy());
#else
    Unimplemented();
#endif
    break;
  default:
    fatal("CompilationPolicyChoice must be in the range: [0-3]");
  }
  CompilationPolicy::policy()->initialize();
}
void CompilationPolicy::completed_vm_startup() {
  if (TraceCompilationPolicy) {
    tty->print("CompilationPolicy: completed vm startup.\n");
  }
  _in_vm_startup = false;
}
bool CompilationPolicy::must_be_compiled(methodHandle m, int comp_level) {
  if (ReplayCompiles) return false;
  if (m->has_compiled_code()) return false;       // already compiled
  if (!can_be_compiled(m, comp_level)) return false;
  return !UseInterpreter ||                                              // must compile all methods
         (UseCompiler && AlwaysCompileLoopMethods && m->has_loops() && CompileBroker::should_compile_new_jobs()); // eagerly compile loop methods
}
bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) {
  assert(WhiteBoxAPI || comp_level == CompLevel_all || is_compile(comp_level), "illegal compilation level");
  if (m->is_abstract()) return false;
  if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false;
  if (!AbstractInterpreter::can_be_compiled(m)) {
    return false;
  }
  if (comp_level == CompLevel_all) {
    if (TieredCompilation) {
      return !m->is_not_compilable(CompLevel_simple) || !m->is_not_compilable(CompLevel_full_optimization);
    } else {
      return !m->is_not_compilable(CompLevel_highest_tier);
    }
  } else if (is_compile(comp_level)) {
    return !m->is_not_compilable(comp_level);
  }
  return false;
}
bool CompilationPolicy::can_be_osr_compiled(methodHandle m, int comp_level) {
  bool result = false;
  if (comp_level == CompLevel_all) {
    if (TieredCompilation) {
      result = !m->is_not_osr_compilable(CompLevel_simple) || !m->is_not_osr_compilable(CompLevel_full_optimization);
    } else {
      result = !m->is_not_osr_compilable(CompLevel_highest_tier);
    }
  } else if (is_compile(comp_level)) {
    result = !m->is_not_osr_compilable(comp_level);
  }
  return (result && can_be_compiled(m, comp_level));
}
bool CompilationPolicy::is_compilation_enabled() {
  return !delay_compilation_during_startup() && CompileBroker::should_compile_new_jobs();
}
#ifndef PRODUCT
void CompilationPolicy::print_time() {
  tty->print_cr ("Accumulated compilationPolicy times:");
  tty->print_cr ("---------------------------");
  tty->print_cr ("  Total: %3.3f sec.", _accumulated_time.seconds());
}
void NonTieredCompPolicy::trace_osr_completion(nmethod* osr_nm) {
  if (TraceOnStackReplacement) {
    if (osr_nm == NULL) tty->print_cr("compilation failed");
    else tty->print_cr("nmethod " INTPTR_FORMAT, p2i(osr_nm));
  }
}
#endif // !PRODUCT
void NonTieredCompPolicy::initialize() {
  if (CICompilerCountPerCPU) {
    _compiler_count = MAX2(log2_int(os::active_processor_count())-1,1);
    FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count);
  } else {
    _compiler_count = CICompilerCount;
  }
}
int NonTieredCompPolicy::compiler_count(CompLevel comp_level) {
  assert(!TieredCompilation, "This policy should not be used with TieredCompilation");
#ifdef COMPILER2
  if (is_c2_compile(comp_level)) {
    return _compiler_count;
  } else {
    return 0;
  }
#endif
#ifdef COMPILER1
  if (is_c1_compile(comp_level)) {
    return _compiler_count;
  } else {
    return 0;
  }
#endif
  return 0;
}
void NonTieredCompPolicy::reset_counter_for_invocation_event(methodHandle m) {
  MethodCounters* mcs = m->method_counters();
  assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
  mcs->invocation_counter()->set_carry();
  mcs->backedge_counter()->set_carry();
  assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
}
void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) {
  MethodCounters* mcs = m->method_counters();
  assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
  InvocationCounter* i = mcs->invocation_counter();
  InvocationCounter* b = mcs->backedge_counter();
  i->set(i->state(), CompileThreshold);
  b->set(b->state(), CompileThreshold / 2);
}
class CounterDecay : public AllStatic {
  static jlong _last_timestamp;
  static void do_method(Method* m) {
    MethodCounters* mcs = m->method_counters();
    if (mcs != NULL) {
      mcs->invocation_counter()->decay();
    }
  }
public:
  static void decay();
  static bool is_decay_needed() {
    return (os::javaTimeMillis() - _last_timestamp) > CounterDecayMinIntervalLength;
  }
};
jlong CounterDecay::_last_timestamp = 0;
void CounterDecay::decay() {
  _last_timestamp = os::javaTimeMillis();
  assert(SafepointSynchronize::is_at_safepoint(), "can only be executed at a safepoint");
  int nclasses = SystemDictionary::number_of_classes();
  double classes_per_tick = nclasses * (CounterDecayMinIntervalLength * 1e-3 /
                                        CounterHalfLifeTime);
  for (int i = 0; i < classes_per_tick; i++) {
    Klass* k = SystemDictionary::try_get_next_class();
    if (k != NULL && k->oop_is_instance()) {
      InstanceKlass::cast(k)->methods_do(do_method);
    }
  }
}
void NonTieredCompPolicy::do_safepoint_work() {
  if(UseCounterDecay && CounterDecay::is_decay_needed()) {
    CounterDecay::decay();
  }
}
void NonTieredCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
  ScopeDesc* sd = trap_scope;
  MethodCounters* mcs;
  InvocationCounter* c;
  for (; !sd->is_top(); sd = sd->sender()) {
    mcs = sd->method()->method_counters();
    if (mcs != NULL) {
      mcs->invocation_counter()->reset();
    }
  }
  mcs = sd->method()->method_counters();
  if (mcs != NULL) {
    c = mcs->invocation_counter();
    if (is_osr) {
      c->set(c->state(), CompileThreshold);
    } else {
      c->reset();
    }
    mcs->backedge_counter()->reset();
  }
}
void NonTieredCompPolicy::delay_compilation(Method* method) {
  MethodCounters* mcs = method->method_counters();
  if (mcs != NULL) {
    mcs->invocation_counter()->decay();
    mcs->backedge_counter()->decay();
  }
}
void NonTieredCompPolicy::disable_compilation(Method* method) {
  MethodCounters* mcs = method->method_counters();
  if (mcs != NULL) {
    mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
    mcs->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
  }
}
CompileTask* NonTieredCompPolicy::select_task(CompileQueue* compile_queue) {
  return compile_queue->first();
}
bool NonTieredCompPolicy::is_mature(Method* method) {
  MethodData* mdo = method->method_data();
  assert(mdo != NULL, "Should be");
  uint current = mdo->mileage_of(method);
  uint initial = mdo->creation_mileage();
  if (current < initial)
    return true;  // some sort of overflow
  uint target;
  if (ProfileMaturityPercentage <= 0)
    target = (uint) -ProfileMaturityPercentage;  // absolute value
  else
    target = (uint)( (ProfileMaturityPercentage * CompileThreshold) / 100 );
  return (current >= initial + target);
}
nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci,
                                    int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
  assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
  NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
  if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
    if (bci != InvocationEntryBci) {
      reset_counter_for_back_branch_event(method);
      return NULL;
    }
  }
  if (CompileTheWorld || ReplayCompiles) {
    if (bci == InvocationEntryBci) {
      reset_counter_for_invocation_event(method);
    } else {
      reset_counter_for_back_branch_event(method);
    }
    return NULL;
  }
  if (bci == InvocationEntryBci) {
    if (!method->has_compiled_code() && UseCompiler) {
      method_invocation_event(method, thread);
    } else {
      reset_counter_for_invocation_event(method);
    }
    return NULL;
  } else {
    nmethod* osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
    NOT_PRODUCT(trace_osr_request(method, osr_nm, bci));
    if (osr_nm == NULL && UseCompiler) {
      method_back_branch_event(method, bci, thread);
      osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
    }
    if (osr_nm == NULL) {
      reset_counter_for_back_branch_event(method);
      return NULL;
    }
    return osr_nm;
  }
  return NULL;
}
#ifndef PRODUCT
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) {
  if (TraceInvocationCounterOverflow) {
    MethodCounters* mcs = m->method_counters();
    assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
    InvocationCounter* ic = mcs->invocation_counter();
    InvocationCounter* bc = mcs->backedge_counter();
    ResourceMark rm;
    const char* msg =
      bci == InvocationEntryBci
      ? "comp-policy cntr ovfl @ %d in entry of "
      : "comp-policy cntr ovfl @ %d in loop of ";
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
    tty->print(msg, bci);
PRAGMA_DIAG_POP
    m->print_value();
    tty->cr();
    ic->print();
    bc->print();
    if (ProfileInterpreter) {
      if (bci != InvocationEntryBci) {
        MethodData* mdo = m->method_data();
        if (mdo != NULL) {
          int count = mdo->bci_to_data(branch_bci)->as_JumpData()->taken();
          tty->print_cr("back branch count = %d", count);
        }
      }
    }
  }
}
void NonTieredCompPolicy::trace_osr_request(methodHandle method, nmethod* osr, int bci) {
  if (TraceOnStackReplacement) {
    ResourceMark rm;
    tty->print(osr != NULL ? "Reused OSR entry for " : "Requesting OSR entry for ");
    method->print_short_name(tty);
    tty->print_cr(" at bci %d", bci);
  }
}
#endif // !PRODUCT
void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
  const int comp_level = CompLevel_highest_tier;
  const int hot_count = m->invocation_count();
  reset_counter_for_invocation_event(m);
  const char* comment = "count";
  if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
    nmethod* nm = m->code();
    if (nm == NULL ) {
      CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
    }
  }
}
void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
  const int comp_level = CompLevel_highest_tier;
  const int hot_count = m->backedge_count();
  const char* comment = "backedge_count";
  if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
    CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
    NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
  }
}
#ifdef COMPILER2
const char* StackWalkCompPolicy::_msg = NULL;
void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
  const int comp_level = CompLevel_highest_tier;
  const int hot_count = m->invocation_count();
  reset_counter_for_invocation_event(m);
  const char* comment = "count";
  if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m, comp_level)) {
    ResourceMark rm(thread);
    frame       fr     = thread->last_frame();
    assert(fr.is_interpreted_frame(), "must be interpreted");
    assert(fr.interpreter_frame_method() == m(), "bad method");
    if (TraceCompilationPolicy) {
      tty->print("method invocation trigger: ");
      m->print_short_name(tty);
      tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", p2i((address)m()), m->code_size());
    }
    RegisterMap reg_map(thread, false);
    javaVFrame* triggerVF = thread->last_java_vframe(&reg_map);
    RFrame* first = new InterpretedRFrame(triggerVF->fr(), thread, m);
    if (first->top_method()->code() != NULL) {
      if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, p2i(first->top_method()->code()));
    } else {
      if (TimeCompilationPolicy) accumulated_time()->start();
      GrowableArray<RFrame*>* stack = new GrowableArray<RFrame*>(50);
      stack->push(first);
      RFrame* top = findTopInlinableFrame(stack);
      if (TimeCompilationPolicy) accumulated_time()->stop();
      assert(top != NULL, "findTopInlinableFrame returned null");
      if (TraceCompilationPolicy) top->print();
      CompileBroker::compile_method(top->top_method(), InvocationEntryBci, comp_level,
                                    m, hot_count, comment, thread);
    }
  }
}
void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
  const int comp_level = CompLevel_highest_tier;
  const int hot_count = m->backedge_count();
  const char* comment = "backedge_count";
  if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
    CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
    NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
  }
}
RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack) {
  RFrame* current = stack->at(0); // current choice for stopping
  assert( current && !current->is_compiled(), "" );
  const char* msg = NULL;
  while (1) {
    RFrame* next = senderOf(current, stack);
    if( !next )               // No next frame up the stack?
      break;                  // Then compile with current frame
    methodHandle m = current->top_method();
    methodHandle next_m = next->top_method();
    if (TraceCompilationPolicy && Verbose) {
      tty->print("[caller: ");
      next_m->print_short_name(tty);
      tty->print("] ");
    }
    if( !Inline ) {           // Inlining turned off
      msg = "Inlining turned off";
      break;
    }
    if (next_m->is_not_compilable()) { // Did fail to compile this before/
      msg = "caller not compilable";
      break;
    }
    if (next->num() > MaxRecompilationSearchLength) {
      msg = "don't go up any further: > MaxRecompilationSearchLength";
      break;
    }
    if (next->distance() > MaxInterpretedSearchLength) {
      msg = "don't go up any further: next > MaxInterpretedSearchLength";
      break;
    }
    if (next->is_compiled()) {
      msg = "not going up into optimized code";
      break;
    }
    if( current->is_interpreted() && next_m->has_compiled_code() ) {
      msg = "not going up -- already compiled caller";
      break;
    }
    int invcnt = 0;             // Caller counts
    if (ProfileInterpreter) {
      invcnt = next_m->interpreter_invocation_count();
    }
    int cnt = 0;                // Call site counts
    if (ProfileInterpreter && next_m->method_data() != NULL) {
      ResourceMark rm;
      int bci = next->top_vframe()->bci();
      ProfileData* data = next_m->method_data()->bci_to_data(bci);
      if (data != NULL && data->is_CounterData())
        cnt = data->as_CounterData()->count();
    }
    int freq = (invcnt) ? cnt/invcnt : cnt;
    if ((msg = shouldInline(m, freq, cnt)) != NULL) {
      break;
    }
    if ((msg = shouldNotInline(m)) != NULL) {
      break;
    }
    if (!can_be_compiled(next_m, CompLevel_any)) {
      msg = "caller cannot be compiled";
      break;
    }
    if( next_m->name() == vmSymbols::class_initializer_name() ) {
      msg = "do not compile class initializer (OSR ok)";
      break;
    }
    if (TraceCompilationPolicy && Verbose) {
      tty->print("\n\t     check caller: ");
      next_m->print_short_name(tty);
      tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", p2i((address)next_m()), next_m->code_size());
    }
    current = next;
  }
  assert( !current || !current->is_compiled(), "" );
  if (TraceCompilationPolicy && msg) tty->print("(%s)\n", msg);
  return current;
}
RFrame* StackWalkCompPolicy::senderOf(RFrame* rf, GrowableArray<RFrame*>* stack) {
  RFrame* sender = rf->caller();
  if (sender && sender->num() == stack->length()) stack->push(sender);
  return sender;
}
const char* StackWalkCompPolicy::shouldInline(methodHandle m, float freq, int cnt) {
  int max_size = MaxInlineSize;
  int cost = m->code_size();
  if (m->interpreter_throwout_count() > InlineThrowCount && cost < InlineThrowMaxSize ) {
    return NULL;
  }
  if ((freq >= InlineFrequencyRatio) || (cnt >= InlineFrequencyCount)) {
    if (TraceFrequencyInlining) {
      tty->print("(Inlined frequent method)\n");
      m->print();
    }
    max_size = FreqInlineSize;
  }
  if (cost > max_size) {
    return (_msg = "too big");
  }
  return NULL;
}
const char* StackWalkCompPolicy::shouldNotInline(methodHandle m) {
  if (m->is_abstract()) return (_msg = "abstract method");
  if (!m->method_holder()->is_initialized()) return (_msg = "method holder not initialized");
  if (m->is_native()) return (_msg = "native method");
  nmethod* m_code = m->code();
  if (m_code != NULL && m_code->code_size() > InlineSmallCode)
    return (_msg = "already compiled into a big method");
  if (m->code_size() <= MaxTrivialSize) return NULL;
  if (UseInterpreter) {     // don't use counts with -Xcomp
    if ((m->code() == NULL) && m->was_never_executed()) return (_msg = "never executed");
    if (!m->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return (_msg = "executed < MinInliningThreshold times");
  }
  if (Method::has_unloaded_classes_in_signature(m, JavaThread::current())) return (_msg = "unloaded signature classes");
  return NULL;
}
#endif // COMPILER2
C:\hotspot-69087d08d473\src\share\vm/runtime/compilationPolicy.hpp
#ifndef SHARE_VM_RUNTIME_COMPILATIONPOLICY_HPP
#define SHARE_VM_RUNTIME_COMPILATIONPOLICY_HPP
#include "code/nmethod.hpp"
#include "compiler/compileBroker.hpp"
#include "memory/allocation.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/growableArray.hpp"
class CompileTask;
class CompileQueue;
class CompilationPolicy : public CHeapObj<mtCompiler> {
  static CompilationPolicy* _policy;
  static elapsedTimer       _accumulated_time;
  static bool               _in_vm_startup;
public:
  static  void set_in_vm_startup(bool in_vm_startup) { _in_vm_startup = in_vm_startup; }
  static  void completed_vm_startup();
  static  bool delay_compilation_during_startup()    { return _in_vm_startup; }
  static bool must_be_compiled(methodHandle m, int comp_level = CompLevel_all);
  static bool can_be_compiled(methodHandle m, int comp_level = CompLevel_all);
  static bool can_be_osr_compiled(methodHandle m, int comp_level = CompLevel_all);
  static bool is_compilation_enabled();
  static void set_policy(CompilationPolicy* policy) { _policy = policy; }
  static CompilationPolicy* policy()                { return _policy; }
  elapsedTimer* accumulated_time() { return &_accumulated_time; }
  void print_time() PRODUCT_RETURN;
  virtual CompLevel initial_compile_level() = 0;
  virtual int compiler_count(CompLevel comp_level) = 0;
  virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) = 0;
  virtual void do_safepoint_work() = 0;
  virtual void reprofile(ScopeDesc* trap_scope, bool is_osr) = 0;
  virtual void delay_compilation(Method* method) = 0;
  virtual void disable_compilation(Method* method) = 0;
  virtual CompileTask* select_task(CompileQueue* compile_queue) = 0;
  virtual bool is_mature(Method* method) = 0;
  virtual void initialize() = 0;
  virtual bool should_not_inline(ciEnv* env, ciMethod* method) { return false; }
};
class NonTieredCompPolicy : public CompilationPolicy {
  int _compiler_count;
protected:
  static void trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci);
  static void trace_osr_request(methodHandle method, nmethod* osr, int bci);
  static void trace_osr_completion(nmethod* osr_nm);
  void reset_counter_for_invocation_event(methodHandle method);
  void reset_counter_for_back_branch_event(methodHandle method);
public:
  NonTieredCompPolicy() : _compiler_count(0) { }
  virtual CompLevel initial_compile_level() { return CompLevel_highest_tier; }
  virtual int compiler_count(CompLevel comp_level);
  virtual void do_safepoint_work();
  virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
  virtual void delay_compilation(Method* method);
  virtual void disable_compilation(Method* method);
  virtual bool is_mature(Method* method);
  virtual void initialize();
  virtual CompileTask* select_task(CompileQueue* compile_queue);
  virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
  virtual void method_invocation_event(methodHandle m, JavaThread* thread) = 0;
  virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread) = 0;
};
class SimpleCompPolicy : public NonTieredCompPolicy {
 public:
  virtual void method_invocation_event(methodHandle m, JavaThread* thread);
  virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
};
#ifdef COMPILER2
class StackWalkCompPolicy : public NonTieredCompPolicy {
 public:
  virtual void method_invocation_event(methodHandle m, JavaThread* thread);
  virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
 private:
  RFrame* findTopInlinableFrame(GrowableArray<RFrame*>* stack);
  RFrame* senderOf(RFrame* rf, GrowableArray<RFrame*>* stack);
  static const char* _msg;            // reason for not inlining
  static const char* shouldInline   (methodHandle callee, float frequency, int cnt);
  static const char* shouldNotInline(methodHandle callee);
};
#endif
#endif // SHARE_VM_RUNTIME_COMPILATIONPOLICY_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/deoptimization.cpp
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/debugInfoRec.hpp"
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframeArray.hpp"
#include "runtime/vframe_hp.hpp"
#include "utilities/events.hpp"
#include "utilities/xmlstream.hpp"
#ifdef TARGET_ARCH_x86
# include "vmreg_x86.inline.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "vmreg_aarch64.inline.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "vmreg_sparc.inline.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "vmreg_zero.inline.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "vmreg_arm.inline.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "vmreg_ppc.inline.hpp"
#endif
#ifdef COMPILER2
#if defined AD_MD_HPP
# include AD_MD_HPP
#elif defined TARGET_ARCH_MODEL_x86_32
# include "adfiles/ad_x86_32.hpp"
#elif defined TARGET_ARCH_MODEL_x86_64
# include "adfiles/ad_x86_64.hpp"
#elif defined TARGET_ARCH_MODEL_aarch64
# include "adfiles/ad_aarch64.hpp"
#elif defined TARGET_ARCH_MODEL_sparc
# include "adfiles/ad_sparc.hpp"
#elif defined TARGET_ARCH_MODEL_zero
# include "adfiles/ad_zero.hpp"
#elif defined TARGET_ARCH_MODEL_ppc_64
# include "adfiles/ad_ppc_64.hpp"
#endif
#endif // COMPILER2
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
bool DeoptimizationMarker::_is_active = false;
Deoptimization::UnrollBlock::UnrollBlock(int  size_of_deoptimized_frame,
                                         int  caller_adjustment,
                                         int  caller_actual_parameters,
                                         int  number_of_frames,
                                         intptr_t* frame_sizes,
                                         address* frame_pcs,
                                         BasicType return_type) {
  _size_of_deoptimized_frame = size_of_deoptimized_frame;
  _caller_adjustment         = caller_adjustment;
  _caller_actual_parameters  = caller_actual_parameters;
  _number_of_frames          = number_of_frames;
  _frame_sizes               = frame_sizes;
  _frame_pcs                 = frame_pcs;
  _register_block            = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2, mtCompiler);
  _return_type               = return_type;
  _initial_info              = 0;
  _counter_temp              = 0;
  _unpack_kind               = 0;
  _sender_sp_temp            = 0;
  _total_frame_sizes         = size_of_frames();
}
Deoptimization::UnrollBlock::~UnrollBlock() {
  FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes, mtCompiler);
  FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs, mtCompiler);
  FREE_C_HEAP_ARRAY(intptr_t, _register_block, mtCompiler);
}
intptr_t* Deoptimization::UnrollBlock::value_addr_at(int register_number) const {
  assert(register_number < RegisterMap::reg_count, "checking register number");
  return &_register_block[register_number * 2];
}
int Deoptimization::UnrollBlock::size_of_frames() const {
  int result = _caller_adjustment;
  for (int index = 0; index < number_of_frames(); index++) {
    result += frame_sizes()[index];
  }
  return result;
}
void Deoptimization::UnrollBlock::print() {
  ttyLocker ttyl;
  tty->print_cr("UnrollBlock");
  tty->print_cr("  size_of_deoptimized_frame = %d", _size_of_deoptimized_frame);
  tty->print(   "  frame_sizes: ");
  for (int index = 0; index < number_of_frames(); index++) {
    tty->print("%d ", frame_sizes()[index]);
  }
  tty->cr();
}
JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread))
  thread->inc_in_deopt_handler();
  return fetch_unroll_info_helper(thread);
JRT_END
Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread) {
  DeoptResourceMark* dmark = new DeoptResourceMark(thread);
  assert(thread->deopt_mark() == NULL, "Pending deopt!");
  thread->set_deopt_mark(dmark);
  frame stub_frame = thread->last_frame(); // Makes stack walkable as side effect
  RegisterMap map(thread, true);
  RegisterMap dummy_map(thread, false);
  frame deoptee = stub_frame.sender(&map);
  assert(thread->deopt_nmethod() == NULL, "Pending deopt!");
  thread->set_deopt_nmethod(deoptee.cb()->as_nmethod_or_null());
  if (VerifyStack) {
    thread->validate_frame_layout();
  }
  assert(deoptee.is_compiled_frame(), "Wrong frame type");
  GrowableArray<compiledVFrame*>* chunk = new GrowableArray<compiledVFrame*>(10);
  vframe* vf = vframe::new_vframe(&deoptee, &map, thread);
  while (!vf->is_top()) {
    assert(vf->is_compiled_frame(), "Wrong frame type");
    chunk->push(compiledVFrame::cast(vf));
    vf = vf->sender();
  }
  assert(vf->is_compiled_frame(), "Wrong frame type");
  chunk->push(compiledVFrame::cast(vf));
  bool realloc_failures = false;
#ifdef COMPILER2
  if (DoEscapeAnalysis || EliminateNestedLocks) {
    if (EliminateAllocations) {
      assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
      GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
      bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution();
      Handle return_value;
      if (save_oop_result) {
        oop result = deoptee.saved_oop_result(&map);
        assert(result == NULL || result->is_oop(), "must be oop");
        return_value = Handle(thread, result);
        assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
        if (TraceDeoptimization) {
          ttyLocker ttyl;
          tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread);
        }
      }
      if (objects != NULL) {
        JRT_BLOCK
          realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);
        JRT_END
        reassign_fields(&deoptee, &map, objects, realloc_failures);
#ifndef PRODUCT
        if (TraceDeoptimization) {
          ttyLocker ttyl;
          tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread);
          print_objects(objects, realloc_failures);
        }
#endif
      }
      if (save_oop_result) {
        deoptee.set_saved_oop_result(&map, return_value());
      }
    }
    if (EliminateLocks) {
#ifndef PRODUCT
      bool first = true;
#endif
      for (int i = 0; i < chunk->length(); i++) {
        compiledVFrame* cvf = chunk->at(i);
        assert (cvf->scope() != NULL,"expect only compiled java frames");
        GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
        if (monitors->is_nonempty()) {
          relock_objects(monitors, thread, realloc_failures);
#ifndef PRODUCT
          if (TraceDeoptimization) {
            ttyLocker ttyl;
            for (int j = 0; j < monitors->length(); j++) {
              MonitorInfo* mi = monitors->at(j);
              if (mi->eliminated()) {
                if (first) {
                  first = false;
                  tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread);
                }
                if (mi->owner_is_scalar_replaced()) {
                  Klass* k = java_lang_Class::as_Klass(mi->owner_klass());
                  tty->print_cr("     failed reallocation for klass %s", k->external_name());
                } else {
                  tty->print_cr("     object <" INTPTR_FORMAT "> locked", (void *)mi->owner());
                }
              }
            }
          }
#endif
        }
      }
    }
  }
#endif // COMPILER2
  No_Safepoint_Verifier no_safepoint;
  vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures);
#ifdef COMPILER2
  if (realloc_failures) {
    pop_frames_failed_reallocs(thread, array);
  }
#endif
  assert(thread->vframe_array_head() == NULL, "Pending deopt!");
  thread->set_vframe_array_head(array);
  if (thread->deferred_locals() != NULL) {
    GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread->deferred_locals();
    int i = 0;
    do {
      if (list->at(i)->id() == array->original().id()) {
        jvmtiDeferredLocalVariableSet* dlv = list->at(i);
        list->remove_at(i);
        delete dlv;
      } else {
        i++;
      }
    } while ( i < list->length() );
    if (list->length() == 0) {
      thread->set_deferred_locals(NULL);
      delete list;
    }
  }
#ifndef SHARK
  CodeBlob* cb = stub_frame.cb();
  assert(cb->frame_size() >= 0, "Unexpected frame size");
  intptr_t* unpack_sp = stub_frame.sp() + cb->frame_size();
  nmethod* deoptee_nm = deoptee.cb()->as_nmethod_or_null();
  if (deoptee_nm != NULL && deoptee_nm->is_method_handle_return(deoptee.pc()))
    unpack_sp = deoptee.unextended_sp();
#ifdef ASSERT
  assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking");
#endif
#else
  intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp();
#endif // !SHARK
  guarantee(array->unextended_sp() == unpack_sp, "vframe_array_head must contain the vframeArray to unpack");
  int number_of_frames = array->frames();
  intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames, mtCompiler);
  address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1, mtCompiler);
  int popframe_extra_args = 0;
  frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0);
  if (JvmtiExport::can_pop_frame() && thread->popframe_forcing_deopt_reexecution()) {
    popframe_extra_args = in_words(thread->popframe_preserved_args_size_in_words());
  }
  frame deopt_sender = stub_frame.sender(&dummy_map); // First is the deoptee frame
  deopt_sender = deopt_sender.sender(&dummy_map);     // Now deoptee caller
  bool caller_was_method_handle = false;
  if (deopt_sender.is_interpreted_frame()) {
    methodHandle method = deopt_sender.interpreter_frame_method();
    Bytecode_invoke cur = Bytecode_invoke_check(method, deopt_sender.interpreter_frame_bci());
    if (cur.is_invokedynamic() || cur.is_invokehandle()) {
      caller_was_method_handle = true;
    }
  }
  int callee_parameters = 0;
  int callee_locals = 0;
  for (int index = 0; index < array->frames(); index++ ) {
    frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(callee_parameters,
                                                                                                    callee_locals,
                                                                                                    index == 0,
                                                                                                    popframe_extra_args);
    frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0) - frame::pc_return_offset;
    callee_parameters = array->element(index)->method()->size_of_parameters();
    callee_locals = array->element(index)->method()->max_locals();
    popframe_extra_args = 0;
  }
  BasicType return_type;
  {
    HandleMark hm;
    methodHandle method(thread, array->element(0)->method());
    Bytecode_invoke invoke = Bytecode_invoke_check(method, array->element(0)->bci());
    return_type = invoke.is_valid() ? invoke.result_type() : T_ILLEGAL;
  }
  int caller_adjustment = 0;
  if (deopt_sender.is_compiled_frame() || caller_was_method_handle) {
    caller_adjustment = last_frame_adjust(0, callee_locals);
  } else if (callee_locals > callee_parameters) {
    caller_adjustment = last_frame_adjust(callee_parameters, callee_locals);
  }
  frame_pcs[0] = deopt_sender.raw_pc();
#ifndef SHARK
  assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc");
#endif // SHARK
  UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
                                      caller_adjustment * BytesPerWord,
                                      caller_was_method_handle ? 0 : callee_parameters,
                                      number_of_frames,
                                      frame_sizes,
                                      frame_pcs,
                                      return_type);
  info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info());
  if (array->frames() > 1) {
    if (VerifyStack && TraceDeoptimization) {
      ttyLocker ttyl;
      tty->print_cr("Deoptimizing method containing inlining");
    }
  }
  array->set_unroll_block(info);
  return info;
}
void Deoptimization::cleanup_deopt_info(JavaThread *thread,
                                        vframeArray *array) {
  if (array == NULL) {
    array = thread->vframe_array_head();
  }
  thread->set_vframe_array_head(NULL);
  vframeArray* old_array = thread->vframe_array_last();
  thread->set_vframe_array_last(array);
  if (old_array != NULL) {
    UnrollBlock* old_info = old_array->unroll_block();
    old_array->set_unroll_block(NULL);
    delete old_info;
    delete old_array;
  }
  delete thread->deopt_mark();
  thread->set_deopt_mark(NULL);
  thread->set_deopt_nmethod(NULL);
  if (JvmtiExport::can_pop_frame()) {
#ifndef CC_INTERP
    thread->clear_popframe_condition();
#else
    if (thread->popframe_forcing_deopt_reexecution())
        thread->clear_popframe_condition();
#endif /* CC_INTERP */
  }
  thread->dec_in_deopt_handler();
}
JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_mode))
  ResetNoHandleMark rnhm; // No-op in release/product versions
  HandleMark hm;
  frame stub_frame = thread->last_frame();
  vframeArray* array = thread->vframe_array_head();
#ifndef PRODUCT
  if (TraceDeoptimization) {
    ttyLocker ttyl;
    tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode);
  }
#endif
  Events::log(thread, "DEOPT UNPACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT " mode %d",
              stub_frame.pc(), stub_frame.sp(), exec_mode);
  UnrollBlock* info = array->unroll_block();
  array->unpack_to_stack(stub_frame, exec_mode, info->caller_actual_parameters());
  BasicType bt = info->return_type();
  if (exec_mode == Unpack_exception)
    bt = T_OBJECT;
  cleanup_deopt_info(thread, array);
#ifndef PRODUCT
  if (VerifyStack) {
    ResourceMark res_mark;
    thread->validate_frame_layout();
    vframeArray* cur_array = thread->vframe_array_last();
    RegisterMap rm(thread, false);
    rm.set_include_argument_oops(false);
    bool is_top_frame = true;
    int callee_size_of_parameters = 0;
    int callee_max_locals = 0;
    for (int i = 0; i < cur_array->frames(); i++) {
      vframeArrayElement* el = cur_array->element(i);
      frame* iframe = el->iframe();
      guarantee(iframe->is_interpreted_frame(), "Wrong frame type");
      InterpreterOopMap mask;
      int cur_invoke_parameter_size = 0;
      bool try_next_mask = false;
      int next_mask_expression_stack_size = -1;
      int top_frame_expression_stack_adjustment = 0;
      methodHandle mh(thread, iframe->interpreter_frame_method());
      OopMapCache::compute_one_oop_map(mh, iframe->interpreter_frame_bci(), &mask);
      BytecodeStream str(mh);
      str.set_start(iframe->interpreter_frame_bci());
      int max_bci = mh->code_size();
      assert(str.bci() < max_bci, "bci in interpreter frame out of bounds");
      Bytecodes::Code cur_code = str.next();
      if (cur_code == Bytecodes::_invokevirtual   ||
          cur_code == Bytecodes::_invokespecial   ||
          cur_code == Bytecodes::_invokestatic    ||
          cur_code == Bytecodes::_invokeinterface ||
          cur_code == Bytecodes::_invokedynamic) {
        Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
        Symbol* signature = invoke.signature();
        ArgumentSizeComputer asc(signature);
        cur_invoke_parameter_size = asc.size();
        if (invoke.has_receiver()) {
          ++cur_invoke_parameter_size;
        }
        if (i != 0 && !invoke.is_invokedynamic() && MethodHandles::has_member_arg(invoke.klass(), invoke.name())) {
          callee_size_of_parameters++;
        }
      }
      if (str.bci() < max_bci) {
        Bytecodes::Code bc = str.next();
        if (bc >= 0) {
          switch (cur_code) {
            case Bytecodes::_invokevirtual:
            case Bytecodes::_invokespecial:
            case Bytecodes::_invokestatic:
            case Bytecodes::_invokeinterface:
            case Bytecodes::_invokedynamic:
            case Bytecodes::_athrow:
              break;
            default: {
              InterpreterOopMap next_mask;
              OopMapCache::compute_one_oop_map(mh, str.bci(), &next_mask);
              next_mask_expression_stack_size = next_mask.expression_stack_size();
              BasicType bytecode_result_type = Bytecodes::result_type(cur_code);
              if (bytecode_result_type != T_ILLEGAL) {
                top_frame_expression_stack_adjustment = type2size[bytecode_result_type];
              }
              assert(top_frame_expression_stack_adjustment >= 0, "");
              try_next_mask = true;
              break;
            }
          }
        }
      }
      if (!(
            (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + callee_size_of_parameters) ||
            (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + callee_max_locals) ||
            (try_next_mask &&
             (iframe->interpreter_frame_expression_stack_size() == (next_mask_expression_stack_size -
                                                                    top_frame_expression_stack_adjustment))) ||
            (is_top_frame && (exec_mode == Unpack_exception) && iframe->interpreter_frame_expression_stack_size() == 0) ||
            (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute || el->should_reexecute()) &&
             (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size))
            )) {
        ttyLocker ttyl;
        tty->print_cr("Wrong number of expression stack elements during deoptimization");
        tty->print_cr("  Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1);
        tty->print_cr("  Fabricated interpreter frame had %d expression stack elements",
                      iframe->interpreter_frame_expression_stack_size());
        tty->print_cr("  Interpreter oop map had %d expression stack elements", mask.expression_stack_size());
        tty->print_cr("  try_next_mask = %d", try_next_mask);
        tty->print_cr("  next_mask_expression_stack_size = %d", next_mask_expression_stack_size);
        tty->print_cr("  callee_size_of_parameters = %d", callee_size_of_parameters);
        tty->print_cr("  callee_max_locals = %d", callee_max_locals);
        tty->print_cr("  top_frame_expression_stack_adjustment = %d", top_frame_expression_stack_adjustment);
        tty->print_cr("  exec_mode = %d", exec_mode);
        tty->print_cr("  cur_invoke_parameter_size = %d", cur_invoke_parameter_size);
        tty->print_cr("  Thread = " INTPTR_FORMAT ", thread ID = " UINTX_FORMAT, thread, thread->osthread()->thread_id());
        tty->print_cr("  Interpreted frames:");
        for (int k = 0; k < cur_array->frames(); k++) {
          vframeArrayElement* el = cur_array->element(k);
          tty->print_cr("    %s (bci %d)", el->method()->name_and_sig_as_C_string(), el->bci());
        }
        cur_array->print_on_2(tty);
        guarantee(false, "wrong number of expression stack elements during deopt");
      }
      VerifyOopClosure verify;
      iframe->oops_interpreted_do(&verify, NULL, &rm, false);
      callee_size_of_parameters = mh->size_of_parameters();
      callee_max_locals = mh->max_locals();
      is_top_frame = false;
    }
  }
#endif /* !PRODUCT */
  return bt;
JRT_END
int Deoptimization::deoptimize_dependents() {
  Threads::deoptimized_wrt_marked_nmethods();
  return 0;
}
#ifdef COMPILER2
bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
  Handle pending_exception(thread->pending_exception());
  const char* exception_file = thread->exception_file();
  int exception_line = thread->exception_line();
  thread->clear_pending_exception();
  bool failures = false;
  for (int i = 0; i < objects->length(); i++) {
    assert(objects->at(i)->is_object(), "invalid debug information");
    ObjectValue* sv = (ObjectValue*) objects->at(i);
    KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
    oop obj = NULL;
    if (k->oop_is_instance()) {
      InstanceKlass* ik = InstanceKlass::cast(k());
      obj = ik->allocate_instance(THREAD);
    } else if (k->oop_is_typeArray()) {
      TypeArrayKlass* ak = TypeArrayKlass::cast(k());
      assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length");
      int len = sv->field_size() / type2size[ak->element_type()];
      obj = ak->allocate(len, THREAD);
    } else if (k->oop_is_objArray()) {
      ObjArrayKlass* ak = ObjArrayKlass::cast(k());
      obj = ak->allocate(sv->field_size(), THREAD);
    }
    if (obj == NULL) {
      failures = true;
    }
    assert(sv->value().is_null(), "redundant reallocation");
    assert(obj != NULL || HAS_PENDING_EXCEPTION, "allocation should succeed or we should get an exception");
    CLEAR_PENDING_EXCEPTION;
    sv->set_value(obj);
  }
  if (failures) {
    THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), failures);
  } else if (pending_exception.not_null()) {
    thread->set_pending_exception(pending_exception(), exception_file, exception_line);
  }
  return failures;
}
class FieldReassigner: public FieldClosure {
  frame* _fr;
  RegisterMap* _reg_map;
  ObjectValue* _sv;
  InstanceKlass* _ik;
  oop _obj;
  int _i;
public:
  FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) :
    _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {}
  int i() const { return _i; }
  void do_field(fieldDescriptor* fd) {
    intptr_t val;
    StackValue* value =
      StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i()));
    int offset = fd->offset();
    switch (fd->field_type()) {
    case T_OBJECT: case T_ARRAY:
      assert(value->type() == T_OBJECT, "Agreement.");
      _obj->obj_field_put(offset, value->get_obj()());
      break;
    case T_LONG: case T_DOUBLE: {
      assert(value->type() == T_INT, "Agreement.");
      StackValue* low =
        StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i));
#ifdef _LP64
      jlong res = (jlong)low->get_int();
#else
#ifdef SPARC
      jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());
#else
      jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
#endif //SPARC
#endif
      _obj->long_field_put(offset, res);
      break;
    }
    case T_INT: case T_FLOAT: // 4 bytes.
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      _obj->int_field_put(offset, (jint)*((jint*)&val));
      break;
    case T_SHORT:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      _obj->short_field_put(offset, (jshort)*((jint*)&val));
      break;
    case T_CHAR:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      _obj->char_field_put(offset, (jchar)*((jint*)&val));
      break;
    case T_BYTE:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      _obj->byte_field_put(offset, (jbyte)*((jint*)&val));
      break;
    case T_BOOLEAN:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      _obj->bool_field_put(offset, (jboolean)*((jint*)&val));
      break;
    default:
      ShouldNotReachHere();
    }
    _i++;
  }
};
void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
  int index = 0;
  intptr_t val;
  for (int i = 0; i < sv->field_size(); i++) {
    StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
    switch(type) {
    case T_LONG: case T_DOUBLE: {
      assert(value->type() == T_INT, "Agreement.");
      StackValue* low =
        StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
#ifdef _LP64
      jlong res = (jlong)low->get_int();
#else
#ifdef SPARC
      jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());
#else
      jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
#endif //SPARC
#endif
      obj->long_at_put(index, res);
      break;
    }
    case T_INT: case T_FLOAT: // 4 bytes.
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      obj->int_at_put(index, (jint)*((jint*)&val));
      break;
    case T_SHORT:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      obj->short_at_put(index, (jshort)*((jint*)&val));
      break;
    case T_CHAR:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      obj->char_at_put(index, (jchar)*((jint*)&val));
      break;
    case T_BYTE:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      obj->byte_at_put(index, (jbyte)*((jint*)&val));
      break;
    case T_BOOLEAN:
      assert(value->type() == T_INT, "Agreement.");
      val = value->get_int();
      obj->bool_at_put(index, (jboolean)*((jint*)&val));
      break;
      default:
        ShouldNotReachHere();
    }
    index++;
  }
}
void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) {
  for (int i = 0; i < sv->field_size(); i++) {
    StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
    assert(value->type() == T_OBJECT, "object element expected");
    obj->obj_at_put(i, value->get_obj()());
  }
}
void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
  for (int i = 0; i < objects->length(); i++) {
    ObjectValue* sv = (ObjectValue*) objects->at(i);
    KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
    Handle obj = sv->value();
    assert(obj.not_null() || realloc_failures, "reallocation was missed");
    if (obj.is_null()) {
      continue;
    }
    if (k->oop_is_instance()) {
      InstanceKlass* ik = InstanceKlass::cast(k());
      FieldReassigner reassign(fr, reg_map, sv, obj());
      ik->do_nonstatic_fields(&reassign);
    } else if (k->oop_is_typeArray()) {
      TypeArrayKlass* ak = TypeArrayKlass::cast(k());
      reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());
    } else if (k->oop_is_objArray()) {
      reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj());
    }
  }
}
void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures) {
  for (int i = 0; i < monitors->length(); i++) {
    MonitorInfo* mon_info = monitors->at(i);
    if (mon_info->eliminated()) {
      assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed");
      if (!mon_info->owner_is_scalar_replaced()) {
        Handle obj = Handle(mon_info->owner());
        markOop mark = obj->mark();
        if (UseBiasedLocking && mark->has_bias_pattern()) {
          assert(mark->is_biased_anonymously() ||
                 mark->biased_locker() == thread, "should be locked to current thread");
          markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
          obj->set_mark(unbiased_prototype);
        }
        BasicLock* lock = mon_info->lock();
        ObjectSynchronizer::slow_enter(obj, lock, thread);
        assert(mon_info->owner()->is_locked(), "object must be locked now");
      }
    }
  }
}
#ifndef PRODUCT
void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
  fieldDescriptor fd;
  for (int i = 0; i < objects->length(); i++) {
    ObjectValue* sv = (ObjectValue*) objects->at(i);
    KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
    Handle obj = sv->value();
    tty->print("     object <" INTPTR_FORMAT "> of type ", (void *)sv->value()());
    k->print_value();
    assert(obj.not_null() || realloc_failures, "reallocation was missed");
    if (obj.is_null()) {
      tty->print(" allocation failed");
    } else {
      tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize);
    }
    tty->cr();
    if (Verbose && !obj.is_null()) {
      k->oop_print_on(obj(), tty);
    }
  }
}
#endif
#endif // COMPILER2
vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
  Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp());
#ifndef PRODUCT
  if (TraceDeoptimization) {
    ttyLocker ttyl;
    tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", thread);
    fr.print_on(tty);
    tty->print_cr("     Virtual frames (innermost first):");
    for (int index = 0; index < chunk->length(); index++) {
      compiledVFrame* vf = chunk->at(index);
      tty->print("       %2d - ", index);
      vf->print_value();
      int bci = chunk->at(index)->raw_bci();
      const char* code_name;
      if (bci == SynchronizationEntryBCI) {
        code_name = "sync entry";
      } else {
        Bytecodes::Code code = vf->method()->code_at(bci);
        code_name = Bytecodes::name(code);
      }
      tty->print(" - %s", code_name);
      tty->print_cr(" @ bci %d ", bci);
      if (Verbose) {
        vf->print();
        tty->cr();
      }
    }
  }
#endif
  frame caller = fr.sender(reg_map);
  int frame_size = caller.sp() - fr.sp();
  frame sender = caller;
  vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr, realloc_failures);
  assert(array->structural_compare(thread, chunk), "just checking");
#ifndef PRODUCT
  if (TraceDeoptimization) {
    ttyLocker ttyl;
    tty->print_cr("     Created vframeArray " INTPTR_FORMAT, array);
  }
#endif // PRODUCT
  return array;
}
#ifdef COMPILER2
void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) {
  assert(thread->frames_to_pop_failed_realloc() == 0, "missed frames to pop?");
  thread->set_frames_to_pop_failed_realloc(array->frames());
  for (int i = 0; i < array->frames(); i++) {
    MonitorChunk* monitors = array->element(i)->monitors();
    if (monitors != NULL) {
      for (int j = 0; j < monitors->number_of_monitors(); j++) {
        BasicObjectLock* src = monitors->at(j);
        if (src->obj() != NULL) {
          ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread);
        }
      }
      array->element(i)->free_monitors(thread);
#ifdef ASSERT
      array->element(i)->set_removed_monitors();
#endif
    }
  }
}
#endif
static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) {
  GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
  for (int i = 0; i < monitors->length(); i++) {
    MonitorInfo* mon_info = monitors->at(i);
    if (!mon_info->eliminated() && mon_info->owner() != NULL) {
      objects_to_revoke->append(Handle(mon_info->owner()));
    }
  }
}
void Deoptimization::revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) {
  if (!UseBiasedLocking) {
    return;
  }
  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
  if (map == NULL || !map->update_map()) {
    StackFrameStream sfs(thread, true);
    bool found = false;
    while (!found && !sfs.is_done()) {
      frame* cur = sfs.current();
      sfs.next();
      found = cur->id() == fr.id();
    }
    assert(found, "frame to be deoptimized not found on target thread's stack");
    map = sfs.register_map();
  }
  vframe* vf = vframe::new_vframe(&fr, map, thread);
  compiledVFrame* cvf = compiledVFrame::cast(vf);
  while (!cvf->is_top()) {
    collect_monitors(cvf, objects_to_revoke);
    cvf = compiledVFrame::cast(cvf->sender());
  }
  collect_monitors(cvf, objects_to_revoke);
  if (SafepointSynchronize::is_at_safepoint()) {
    BiasedLocking::revoke_at_safepoint(objects_to_revoke);
  } else {
    BiasedLocking::revoke(objects_to_revoke);
  }
}
void Deoptimization::revoke_biases_of_monitors(CodeBlob* cb) {
  if (!UseBiasedLocking) {
    return;
  }
  assert(SafepointSynchronize::is_at_safepoint(), "must only be called from safepoint");
  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
  for (JavaThread* jt = Threads::first(); jt != NULL ; jt = jt->next()) {
    if (jt->has_last_Java_frame()) {
      StackFrameStream sfs(jt, true);
      while (!sfs.is_done()) {
        frame* cur = sfs.current();
        if (cb->contains(cur->pc())) {
          vframe* vf = vframe::new_vframe(cur, sfs.register_map(), jt);
          compiledVFrame* cvf = compiledVFrame::cast(vf);
          while (!cvf->is_top()) {
            collect_monitors(cvf, objects_to_revoke);
            cvf = compiledVFrame::cast(cvf->sender());
          }
          collect_monitors(cvf, objects_to_revoke);
        }
        sfs.next();
      }
    }
  }
  BiasedLocking::revoke_at_safepoint(objects_to_revoke);
}
void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr) {
  assert(fr.can_be_deoptimized(), "checking frame type");
  gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal);
  fr.deoptimize(thread);
}
void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) {
  if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) {
    return;
  }
  ResourceMark rm;
  DeoptimizationMarker dm;
  if (UseBiasedLocking) {
    revoke_biases_of_monitors(thread, fr, map);
  }
  deoptimize_single_frame(thread, fr);
}
void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id) {
  assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(),
         "can only deoptimize other thread at a safepoint");
  RegisterMap reg_map(thread, UseBiasedLocking);
  frame fr = thread->last_frame();
  while (fr.id() != id) {
    fr = fr.sender(&reg_map);
  }
  deoptimize(thread, fr, &reg_map);
}
void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) {
  if (thread == Thread::current()) {
    Deoptimization::deoptimize_frame_internal(thread, id);
  } else {
    VM_DeoptimizeFrame deopt(thread, id);
    VMThread::execute(&deopt);
  }
}
JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address))
{
  thread->popframe_preserve_args(in_ByteSize(bytes_to_save), start_address);
}
JRT_END
#if defined(COMPILER2) || defined(SHARK)
void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
  if (constant_pool->tag_at(index).is_unresolved_klass()) {
    Klass* tk = constant_pool->klass_at(index, CHECK);
    return;
  }
  if (!constant_pool->tag_at(index).is_symbol()) return;
  Handle class_loader (THREAD, constant_pool->pool_holder()->class_loader());
  Symbol*  symbol  = constant_pool->symbol_at(index);
  if (symbol->byte_at(0) != '(') {
    Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain());
    SystemDictionary::resolve_or_null(symbol, class_loader, protection_domain, CHECK);
    return;
  }
  ResourceMark rm(THREAD);
  for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) {
    if (ss.is_object()) {
      Symbol* class_name = ss.as_symbol(CHECK);
      Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain());
      SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK);
    }
  }
}
void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index) {
  EXCEPTION_MARK;
  load_class_by_index(constant_pool, index, THREAD);
  if (HAS_PENDING_EXCEPTION) {
    CLEAR_PENDING_EXCEPTION;
    assert(THREAD->is_Java_thread(), "only a java thread can be here");
    JavaThread* thread = (JavaThread*)THREAD;
    bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
    if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
    assert(guard_pages_enabled, "stack banging in uncommon trap blob may cause crash");
  }
}
JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint trap_request)) {
  HandleMark hm;
  thread->inc_in_deopt_handler();
  RegisterMap reg_map(thread, UseBiasedLocking);
  frame stub_frame = thread->last_frame();
  frame fr = stub_frame.sender(&reg_map);
  nmethodLocker nl(fr.pc());
  Events::log(thread, "Uncommon trap: trap_request=" PTR32_FORMAT " fr.pc=" INTPTR_FORMAT,
              trap_request, fr.pc());
  {
    ResourceMark rm;
    revoke_biases_of_monitors(thread, fr, &reg_map);
    DeoptReason reason = trap_request_reason(trap_request);
    DeoptAction action = trap_request_action(trap_request);
    jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1
    vframe*  vf  = vframe::new_vframe(&fr, &reg_map, thread);
    compiledVFrame* cvf = compiledVFrame::cast(vf);
    nmethod* nm = cvf->code();
    ScopeDesc*      trap_scope  = cvf->scope();
    methodHandle    trap_method = trap_scope->method();
    int             trap_bci    = trap_scope->bci();
    Bytecodes::Code trap_bc     = trap_method->java_code_at(trap_bci);
    gather_statistics(reason, action, trap_bc);
    bool create_if_missing = ProfileTraps RTM_OPT_ONLY( || UseRTMLocking );
    MethodData* trap_mdo =
      get_method_data(thread, trap_method, create_if_missing);
    Events::log_deopt_message(thread, "Uncommon trap: reason=%s action=%s pc=" INTPTR_FORMAT " method=%s @ %d",
                              trap_reason_name(reason), trap_action_name(action), fr.pc(),
                              trap_method->name_and_sig_as_C_string(), trap_bci);
    if (TraceDeoptimization || LogCompilation) {
      ResourceMark rm;
      ttyLocker ttyl;
      char buf[100];
      if (xtty != NULL) {
        xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT "' %s",
                         os::current_thread_id(),
                         format_trap_request(buf, sizeof(buf), trap_request));
        nm->log_identity(xtty);
      }
      Symbol* class_name = NULL;
      bool unresolved = false;
      if (unloaded_class_index >= 0) {
        constantPoolHandle constants (THREAD, trap_method->constants());
        if (constants->tag_at(unloaded_class_index).is_unresolved_klass()) {
          class_name = constants->klass_name_at(unloaded_class_index);
          unresolved = true;
          if (xtty != NULL)
            xtty->print(" unresolved='1'");
        } else if (constants->tag_at(unloaded_class_index).is_symbol()) {
          class_name = constants->symbol_at(unloaded_class_index);
        }
        if (xtty != NULL)
          xtty->name(class_name);
      }
      if (xtty != NULL && trap_mdo != NULL) {
        int dcnt = trap_mdo->trap_count(reason);
        if (dcnt != 0)
          xtty->print(" count='%d'", dcnt);
        ProfileData* pdata = trap_mdo->bci_to_data(trap_bci);
        int dos = (pdata == NULL)? 0: pdata->trap_state();
        if (dos != 0) {
          xtty->print(" state='%s'", format_trap_state(buf, sizeof(buf), dos));
          if (trap_state_is_recompiled(dos)) {
            int recnt2 = trap_mdo->overflow_recompile_count();
            if (recnt2 != 0)
              xtty->print(" recompiles2='%d'", recnt2);
          }
        }
      }
      if (xtty != NULL) {
        xtty->stamp();
        xtty->end_head();
      }
      if (TraceDeoptimization) {  // make noise on the tty
        tty->print("Uncommon trap occurred in");
        nm->method()->print_short_name(tty);
        tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d",
                   fr.pc(),
                   os::current_thread_id(),
                   trap_reason_name(reason),
                   trap_action_name(action),
                   unloaded_class_index);
        if (class_name != NULL) {
          tty->print(unresolved ? " unresolved class: " : " symbol: ");
          class_name->print_symbol_on(tty);
        }
        tty->cr();
      }
      if (xtty != NULL) {
        for (ScopeDesc* sd = trap_scope; ; sd = sd->sender()) {
          xtty->begin_elem("jvms bci='%d'", sd->bci());
          xtty->method(sd->method());
          xtty->end_elem();
          if (sd->is_top())  break;
        }
        xtty->tail("uncommon_trap");
      }
    }
    if (unloaded_class_index >= 0) {
      constantPoolHandle constants(THREAD, trap_method->constants());
      load_class_by_index(constants, unloaded_class_index);
    }
    bool injected_profile_trap = trap_method->has_injected_profile() &&
                                 (reason == Reason_intrinsic || reason == Reason_unreached);
    bool update_trap_state = !injected_profile_trap;
    bool make_not_entrant = false;
    bool make_not_compilable = false;
    bool reprofile = false;
    switch (action) {
    case Action_none:
      update_trap_state = false;
      break;
    case Action_maybe_recompile:
      break;
    case Action_reinterpret:
      make_not_entrant = true;
      reprofile = true;
      break;
    case Action_make_not_entrant:
      make_not_entrant = true;
      break;
    case Action_make_not_compilable:
      make_not_entrant = true;
      make_not_compilable = true;
      break;
    default:
      ShouldNotReachHere();
    }
    bool inc_recompile_count = false;
    ProfileData* pdata = NULL;
    if (ProfileTraps && update_trap_state && trap_mdo != NULL) {
      assert(trap_mdo == get_method_data(thread, trap_method, false), "sanity");
      uint this_trap_count = 0;
      bool maybe_prior_trap = false;
      bool maybe_prior_recompile = false;
      pdata = query_update_method_data(trap_mdo, trap_bci, reason,
                                   nm->method(),
                                   this_trap_count,
                                   maybe_prior_trap,
                                   maybe_prior_recompile);
      DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason);
      if (per_bc_reason != Reason_none) {
        if (maybe_prior_trap
            && this_trap_count >= (uint)PerBytecodeTrapLimit) {
          make_not_entrant = true;
        }
        if (make_not_entrant && maybe_prior_recompile) {
          inc_recompile_count = maybe_prior_trap;
        }
      } else {
        make_not_entrant = true;
      }
      if (this_trap_count >= per_method_trap_limit(reason)) {
        make_not_entrant = true;
      }
      if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) {
        reprofile = true;
      }
    }
    if (make_not_entrant) {
      if (!nm->make_not_entrant()) {
        return; // the call did not change nmethod's state
      }
      if (pdata != NULL) {
        int tstate0 = pdata->trap_state();
        int tstate1 = trap_state_set_recompiled(tstate0, true);
        if (tstate1 != tstate0)
          pdata->set_trap_state(tstate1);
      }
#if INCLUDE_RTM_OPT
      if ((reason != Reason_rtm_state_change) && (trap_mdo != NULL) &&
          UseRTMDeopt && (nm->rtm_state() != ProfileRTM)) {
        trap_mdo->atomic_set_rtm_state(ProfileRTM);
      }
#endif
    }
    if (inc_recompile_count) {
      trap_mdo->inc_overflow_recompile_count();
      if ((uint)trap_mdo->overflow_recompile_count() >
          (uint)PerBytecodeRecompilationCutoff) {
        if (trap_method() == nm->method()) {
          make_not_compilable = true;
        } else {
          trap_method->set_not_compilable(CompLevel_full_optimization, true, "overflow_recompile_count > PerBytecodeRecompilationCutoff");
        }
      }
    }
    if (reprofile) {
      CompilationPolicy::policy()->reprofile(trap_scope, nm->is_osr_method());
    }
    if (make_not_compilable && !nm->method()->is_not_compilable(CompLevel_full_optimization)) {
      assert(make_not_entrant, "consistent");
      nm->method()->set_not_compilable(CompLevel_full_optimization);
    }
  } // Free marked resources
}
JRT_END
MethodData*
Deoptimization::get_method_data(JavaThread* thread, methodHandle m,
                                bool create_if_missing) {
  Thread* THREAD = thread;
  MethodData* mdo = m()->method_data();
  if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) {
    Method::build_interpreter_method_data(m, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
      CLEAR_PENDING_EXCEPTION;
    }
    mdo = m()->method_data();
  }
  return mdo;
}
ProfileData*
Deoptimization::query_update_method_data(MethodData* trap_mdo,
                                         int trap_bci,
                                         Deoptimization::DeoptReason reason,
                                         Method* compiled_method,
                                         uint& ret_this_trap_count,
                                         bool& ret_maybe_prior_trap,
                                         bool& ret_maybe_prior_recompile) {
  uint prior_trap_count = trap_mdo->trap_count(reason);
  uint this_trap_count  = trap_mdo->inc_trap_count(reason);
  bool maybe_prior_trap      = (prior_trap_count != 0);
  bool maybe_prior_recompile = (trap_mdo->decompile_count() != 0);
  ProfileData* pdata = NULL;
  DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason);
  if (per_bc_reason != Reason_none) {
    pdata = trap_mdo->allocate_bci_to_data(trap_bci, reason_is_speculate(reason) ? compiled_method : NULL);
    if (pdata != NULL) {
      if (reason_is_speculate(reason) && !pdata->is_SpeculativeTrapData()) {
        if (LogCompilation && xtty != NULL) {
          ttyLocker ttyl;
          xtty->elem("speculative_traps_oom");
        }
      }
      int tstate0 = pdata->trap_state();
      if (!trap_state_has_reason(tstate0, per_bc_reason))
        maybe_prior_trap = false;
      if (!trap_state_is_recompiled(tstate0))
        maybe_prior_recompile = false;
      int tstate1 = tstate0;
      tstate1 = trap_state_add_reason(tstate1, per_bc_reason);
      if (tstate1 != tstate0)
        pdata->set_trap_state(tstate1);
    } else {
      if (LogCompilation && xtty != NULL) {
        ttyLocker ttyl;
        xtty->elem("missing_mdp bci='%d'", trap_bci);
      }
    }
  }
  ret_this_trap_count = this_trap_count;
  ret_maybe_prior_trap = maybe_prior_trap;
  ret_maybe_prior_recompile = maybe_prior_recompile;
  return pdata;
}
void
Deoptimization::update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason) {
  ResourceMark rm;
  uint ignore_this_trap_count;
  bool ignore_maybe_prior_trap;
  bool ignore_maybe_prior_recompile;
  assert(!reason_is_speculate(reason), "reason speculate only used by compiler");
  query_update_method_data(trap_mdo, trap_bci,
                           (DeoptReason)reason,
                           NULL,
                           ignore_this_trap_count,
                           ignore_maybe_prior_trap,
                           ignore_maybe_prior_recompile);
}
Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request) {
  {
    uncommon_trap_inner(thread, trap_request);
  }
  return fetch_unroll_info_helper(thread);
}
const int DS_REASON_MASK   = DataLayout::trap_mask >> 1;
const int DS_RECOMPILE_BIT = DataLayout::trap_mask - DS_REASON_MASK;
Deoptimization::DeoptReason
Deoptimization::trap_state_reason(int trap_state) {
  assert(DS_REASON_MASK >= Reason_RECORDED_LIMIT, "enough bits");
  int recompile_bit = (trap_state & DS_RECOMPILE_BIT);
  trap_state -= recompile_bit;
  if (trap_state == DS_REASON_MASK) {
    return Reason_many;
  } else {
    assert((int)Reason_none == 0, "state=0 => Reason_none");
    return (DeoptReason)trap_state;
  }
}
int Deoptimization::trap_state_has_reason(int trap_state, int reason) {
  assert(reason_is_recorded_per_bytecode((DeoptReason)reason), "valid reason");
  assert(DS_REASON_MASK >= Reason_RECORDED_LIMIT, "enough bits");
  int recompile_bit = (trap_state & DS_RECOMPILE_BIT);
  trap_state -= recompile_bit;
  if (trap_state == DS_REASON_MASK) {
    return -1;  // true, unspecifically (bottom of state lattice)
  } else if (trap_state == reason) {
    return 1;   // true, definitely
  } else if (trap_state == 0) {
    return 0;   // false, definitely (top of state lattice)
  } else {
    return 0;   // false, definitely
  }
}
int Deoptimization::trap_state_add_reason(int trap_state, int reason) {
  assert(reason_is_recorded_per_bytecode((DeoptReason)reason) || reason == Reason_many, "valid reason");
  int recompile_bit = (trap_state & DS_RECOMPILE_BIT);
  trap_state -= recompile_bit;
  if (trap_state == DS_REASON_MASK) {
    return trap_state + recompile_bit;     // already at state lattice bottom
  } else if (trap_state == reason) {
    return trap_state + recompile_bit;     // the condition is already true
  } else if (trap_state == 0) {
    return reason + recompile_bit;          // no condition has yet been true
  } else {
    return DS_REASON_MASK + recompile_bit;  // fall to state lattice bottom
  }
}
bool Deoptimization::trap_state_is_recompiled(int trap_state) {
  return (trap_state & DS_RECOMPILE_BIT) != 0;
}
int Deoptimization::trap_state_set_recompiled(int trap_state, bool z) {
  if (z)  return trap_state |  DS_RECOMPILE_BIT;
  else    return trap_state & ~DS_RECOMPILE_BIT;
}
const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
                                              int trap_state) {
  DeoptReason reason      = trap_state_reason(trap_state);
  bool        recomp_flag = trap_state_is_recompiled(trap_state);
  int decoded_state = 0;
  if (reason_is_recorded_per_bytecode(reason) || reason == Reason_many)
    decoded_state = trap_state_add_reason(decoded_state, reason);
  if (recomp_flag)
    decoded_state = trap_state_set_recompiled(decoded_state, recomp_flag);
  size_t len;
  if (decoded_state != trap_state) {
    len = jio_snprintf(buf, buflen, "#%d", trap_state);
  } else {
    len = jio_snprintf(buf, buflen, "%s%s",
                       trap_reason_name(reason),
                       recomp_flag ? " recompiled" : "");
  }
  return buf;
}
Deoptimization::DeoptAction Deoptimization::_unloaded_action
  = Deoptimization::Action_reinterpret;
const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = {
  "none",
  "null_check",
  "null_assert",
  "range_check",
  "class_check",
  "array_check",
  "intrinsic",
  "bimorphic",
  "unloaded",
  "uninitialized",
  "unreached",
  "unhandled",
  "constraint",
  "div0_check",
  "age",
  "predicate",
  "loop_limit_check",
  "speculate_class_check",
  "rtm_state_change",
  "unstable_if"
};
const char* Deoptimization::_trap_action_name[Action_LIMIT] = {
  "none",
  "maybe_recompile",
  "reinterpret",
  "make_not_entrant",
  "make_not_compilable"
};
const char* Deoptimization::trap_reason_name(int reason) {
  if (reason == Reason_many)  return "many";
  if ((uint)reason < Reason_LIMIT)
    return _trap_reason_name[reason];
  static char buf[20];
  sprintf(buf, "reason%d", reason);
  return buf;
}
const char* Deoptimization::trap_action_name(int action) {
  if ((uint)action < Action_LIMIT)
    return _trap_action_name[action];
  static char buf[20];
  sprintf(buf, "action%d", action);
  return buf;
}
const char* Deoptimization::format_trap_request(char* buf, size_t buflen,
                                                int trap_request) {
  jint unloaded_class_index = trap_request_index(trap_request);
  const char* reason = trap_reason_name(trap_request_reason(trap_request));
  const char* action = trap_action_name(trap_request_action(trap_request));
  size_t len;
  if (unloaded_class_index < 0) {
    len = jio_snprintf(buf, buflen, "reason='%s' action='%s'",
                       reason, action);
  } else {
    len = jio_snprintf(buf, buflen, "reason='%s' action='%s' index='%d'",
                       reason, action, unloaded_class_index);
  }
  return buf;
}
juint Deoptimization::_deoptimization_hist
        [Deoptimization::Reason_LIMIT]
    [1 + Deoptimization::Action_LIMIT]
        [Deoptimization::BC_CASE_LIMIT]
  = {0};
enum {
  LSB_BITS = 8,
  LSB_MASK = right_n_bits(LSB_BITS)
};
void Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action,
                                       Bytecodes::Code bc) {
  assert(reason >= 0 && reason < Reason_LIMIT, "oob");
  assert(action >= 0 && action < Action_LIMIT, "oob");
  _deoptimization_hist[Reason_none][0][0] += 1;  // total
  _deoptimization_hist[reason][0][0]      += 1;  // per-reason total
  juint* cases = _deoptimization_hist[reason][1+action];
  juint* bc_counter_addr = NULL;
  juint  bc_counter      = 0;
  if (bc != Bytecodes::_illegal) {
    for (int bc_case = 0; bc_case < BC_CASE_LIMIT; bc_case++) {
      juint* counter_addr = &cases[bc_case];
      juint  counter = *counter_addr;
      if ((counter == 0 && bc_counter_addr == NULL)
          || (Bytecodes::Code)(counter & LSB_MASK) == bc) {
        bc_counter_addr = counter_addr;
        bc_counter = counter | bc;
      }
    }
  }
  if (bc_counter_addr == NULL) {
    bc_counter_addr = &cases[BC_CASE_LIMIT-1];
    bc_counter = (*bc_counter_addr & ~LSB_MASK);  // clear LSB
  }
}
jint Deoptimization::total_deoptimization_count() {
  return _deoptimization_hist[Reason_none][0][0];
}
jint Deoptimization::deoptimization_count(DeoptReason reason) {
  assert(reason >= 0 && reason < Reason_LIMIT, "oob");
  return _deoptimization_hist[reason][0][0];
}
void Deoptimization::print_statistics() {
  juint total = total_deoptimization_count();
  juint account = total;
  if (total != 0) {
    ttyLocker ttyl;
    if (xtty != NULL)  xtty->head("statistics type='deoptimization'");
    tty->print_cr("Deoptimization traps recorded:");
    #define PRINT_STAT_LINE(name, r) \
      tty->print_cr("  %4d (%4.1f%%) %s", (int)(r), ((r) * 100.0) / total, name);
    PRINT_STAT_LINE("total", total);
    for (int reason = 0; reason < Reason_LIMIT; reason++) {
      for (int action = 0; action < Action_LIMIT; action++) {
        juint* cases = _deoptimization_hist[reason][1+action];
        for (int bc_case = 0; bc_case < BC_CASE_LIMIT; bc_case++) {
          juint counter = cases[bc_case];
          if (counter != 0) {
            char name[1*K];
            Bytecodes::Code bc = (Bytecodes::Code)(counter & LSB_MASK);
            if (bc_case == BC_CASE_LIMIT && (int)bc == 0)
              bc = Bytecodes::_illegal;
            sprintf(name, "%s/%s/%s",
                    trap_reason_name(reason),
                    trap_action_name(action),
                    Bytecodes::is_defined(bc)? Bytecodes::name(bc): "other");
            juint r = counter >> LSB_BITS;
            tty->print_cr("  %40s: " UINT32_FORMAT " (%.1f%%)", name, r, (r * 100.0) / total);
            account -= r;
          }
        }
      }
    }
    if (account != 0) {
      PRINT_STAT_LINE("unaccounted", account);
    }
    #undef PRINT_STAT_LINE
    if (xtty != NULL)  xtty->tail("statistics");
  }
}
#else // COMPILER2 || SHARK
bool Deoptimization::trap_state_is_recompiled(int trap_state) {
  return false;
}
const char* Deoptimization::trap_reason_name(int reason) {
  return "unknown";
}
void Deoptimization::print_statistics() {
}
void
Deoptimization::update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason) {
}
int Deoptimization::trap_state_has_reason(int trap_state, int reason) {
  return 0;
}
void Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action,
                                       Bytecodes::Code bc) {
}
const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
                                              int trap_state) {
  jio_snprintf(buf, buflen, "#%d", trap_state);
  return buf;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值