ssssssss14


void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) {
  if (!StackTraceInThrowable) return;
  ResourceMark rm(THREAD);
  set_backtrace(throwable(), NULL);
  if (JDK_Version::is_gte_jdk14x_version()) {
    clear_stacktrace(throwable());
  }
  int max_depth = MaxJavaStackTraceDepth;
  JavaThread* thread = (JavaThread*)THREAD;
  BacktraceBuilder bt(CHECK);
  if (!thread->has_last_Java_frame()) {
    if (max_depth >= 1 && method() != NULL) {
      bt.push(method(), 0, CHECK);
      set_backtrace(throwable(), bt.backtrace());
    }
    return;
  }
#ifdef ASSERT
  vframeStream st(thread);
  methodHandle st_method(THREAD, st.method());
#endif
  int total_count = 0;
  RegisterMap map(thread, false);
  int decode_offset = 0;
  nmethod* nm = NULL;
  bool skip_fillInStackTrace_check = false;
  bool skip_throwableInit_check = false;
  bool skip_hidden = !ShowHiddenFrames;
  for (frame fr = thread->last_frame(); max_depth != total_count;) {
    Method* method = NULL;
    int bci = 0;
    if (decode_offset != 0) {
      DebugInfoReadStream stream(nm, decode_offset);
      decode_offset = stream.read_int();
      method = (Method*)nm->metadata_at(stream.read_int());
      bci = stream.read_bci();
    } else {
      if (fr.is_first_frame()) break;
      address pc = fr.pc();
      if (fr.is_interpreted_frame()) {
        intptr_t bcx = fr.interpreter_frame_bcx();
        method = fr.interpreter_frame_method();
        bci =  fr.is_bci(bcx) ? bcx : method->bci_from((address)bcx);
        fr = fr.sender(&map);
      } else {
        CodeBlob* cb = fr.cb();
        fr = fr.sender(&map);
        if (cb == NULL || !cb->is_nmethod()) {
          continue;
        }
        nm = (nmethod*)cb;
        if (nm->method()->is_native()) {
          method = nm->method();
          bci = 0;
        } else {
          PcDesc* pd = nm->pc_desc_at(pc);
          decode_offset = pd->scope_decode_offset();
          continue;
        }
      }
    }
#ifdef ASSERT
    assert(st_method() == method && st.bci() == bci,
           "Wrong stack trace");
    st.next();
    if (!st.at_end()) {
      st_method = st.method();
    }
#endif
    if (!skip_fillInStackTrace_check) {
      if ((method->name() == vmSymbols::fillInStackTrace_name() ||
           method->name() == vmSymbols::fillInStackTrace0_name()) &&
          throwable->is_a(method->method_holder())) {
        continue;
      }
      else {
        skip_fillInStackTrace_check = true; // gone past them all
      }
    }
    if (!skip_throwableInit_check) {
      assert(skip_fillInStackTrace_check, "logic error in backtrace filtering");
      if (method->name() == vmSymbols::object_initializer_name() &&
          throwable->is_a(method->method_holder())) {
        continue;
      } else {
        skip_throwableInit_check = true;
      }
    }
    if (method->is_hidden()) {
      if (skip_hidden)  continue;
    }
    bt.push(method, bci, CHECK);
    total_count++;
  }
  set_backtrace(throwable(), bt.backtrace());
}
void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method) {
  if (!StackTraceInThrowable) {
    return;
  }
  if (!Universe::should_fill_in_stack_trace(throwable)) {
    return;
  }
  PRESERVE_EXCEPTION_MARK;
  JavaThread* thread = JavaThread::active();
  fill_in_stack_trace(throwable, method, thread);
  CLEAR_PENDING_EXCEPTION;
}
void java_lang_Throwable::allocate_backtrace(Handle throwable, TRAPS) {
  if (!StackTraceInThrowable) return;
  BacktraceBuilder bt(CHECK);   // creates a backtrace
  set_backtrace(throwable(), bt.backtrace());
}
void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle throwable) {
  if (!StackTraceInThrowable) return;
  assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check");
  JavaThread* THREAD = JavaThread::current();
  objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable()));
  assert(backtrace.not_null(), "backtrace should have been preallocated");
  ResourceMark rm(THREAD);
  vframeStream st(THREAD);
  BacktraceBuilder bt(backtrace);
  typeArrayOop methods = BacktraceBuilder::get_methods(backtrace);
  int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth);
  int chunk_count = 0;
  for (;!st.at_end(); st.next()) {
    bt.push(st.method(), st.bci(), CHECK);
    chunk_count++;
    if (chunk_count >= max_chunks) break;
  }
  if (JDK_Version::is_gte_jdk17x_version()) {
      java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
      assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
  }
}
int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) {
  if (throwable == NULL) {
    THROW_0(vmSymbols::java_lang_NullPointerException());
  }
  objArrayOop chunk = objArrayOop(backtrace(throwable));
  int depth = 0;
  if (chunk != NULL) {
    while (true) {
      objArrayOop next = objArrayOop(chunk->obj_at(trace_next_offset));
      if (next == NULL) break;
      depth += trace_chunk_size;
      chunk = next;
    }
    assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check");
    objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
    assert(mirrors != NULL, "sanity check");
    for (int i = 0; i < mirrors->length(); i++) {
      if (mirrors->obj_at(i) == NULL) break;
      depth++;
    }
  }
  return depth;
}
oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS) {
  if (throwable == NULL) {
    THROW_0(vmSymbols::java_lang_NullPointerException());
  }
  if (index < 0) {
    THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
  }
  objArrayOop chunk = objArrayOop(backtrace(throwable));
  int skip_chunks = index / trace_chunk_size;
  int chunk_index = index % trace_chunk_size;
  while (chunk != NULL && skip_chunks > 0) {
    chunk = objArrayOop(chunk->obj_at(trace_next_offset));
        skip_chunks--;
  }
  if (chunk == NULL) {
    THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
  }
  typeArrayOop methods = BacktraceBuilder::get_methods(chunk);
  typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk);
  objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
  typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk);
  assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
  int method = methods->ushort_at(chunk_index);
  int version = version_at(bcis->int_at(chunk_index));
  int bci = bci_at(bcis->int_at(chunk_index));
  int cpref = cprefs->ushort_at(chunk_index);
  Handle mirror(THREAD, mirrors->obj_at(chunk_index));
  if (mirror.is_null()) {
    THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
  }
  oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, cpref, CHECK_0);
  return element;
}
oop java_lang_StackTraceElement::create(Handle mirror, int method_id,
                                        int version, int bci, int cpref, TRAPS) {
  Klass* k = SystemDictionary::StackTraceElement_klass();
  assert(k != NULL, "must be loaded in 1.4+");
  instanceKlassHandle ik (THREAD, k);
  if (ik->should_be_initialized()) {
    ik->initialize(CHECK_0);
  }
  Handle element = ik->allocate_instance_handle(CHECK_0);
  ResourceMark rm(THREAD);
  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
  const char* str = holder->external_name();
  oop classname = StringTable::intern((char*) str, CHECK_0);
  java_lang_StackTraceElement::set_declaringClass(element(), classname);
  Method* method = holder->method_with_orig_idnum(method_id, version);
  Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
  oop methodname = StringTable::intern(sym, CHECK_0);
  java_lang_StackTraceElement::set_methodName(element(), methodname);
  if (!version_matches(method, version)) {
    java_lang_StackTraceElement::set_fileName(element(), NULL);
    java_lang_StackTraceElement::set_lineNumber(element(), -1);
  } else {
    holder = holder->get_klass_version(version);
    assert(holder != NULL, "sanity check");
    Symbol* source = holder->source_file_name();
    if (ShowHiddenFrames && source == NULL)
      source = vmSymbols::unknown_class_name();
    oop filename = StringTable::intern(source, CHECK_0);
    java_lang_StackTraceElement::set_fileName(element(), filename);
    int line_number = get_line_number(method, bci);
    java_lang_StackTraceElement::set_lineNumber(element(), line_number);
  }
  return element();
}
oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
  Handle mirror (THREAD, method->method_holder()->java_mirror());
  int method_id = method->orig_method_idnum();
  int cpref = method->name_index();
  return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD);
}
void java_lang_reflect_AccessibleObject::compute_offsets() {
  Klass* k = SystemDictionary::reflect_AccessibleObject_klass();
  compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature());
}
jboolean java_lang_reflect_AccessibleObject::override(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return (jboolean) reflect->bool_field(override_offset);
}
void java_lang_reflect_AccessibleObject::set_override(oop reflect, jboolean value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  reflect->bool_field_put(override_offset, (int) value);
}
void java_lang_reflect_Method::compute_offsets() {
  Klass* k = SystemDictionary::reflect_Method_klass();
  compute_offset(clazz_offset,          k, vmSymbols::clazz_name(),          vmSymbols::class_signature());
  compute_offset(name_offset,           k, vmSymbols::name_name(),           vmSymbols::string_signature());
  compute_offset(returnType_offset,     k, vmSymbols::returnType_name(),     vmSymbols::class_signature());
  compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature());
  compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature());
  compute_offset(slot_offset,           k, vmSymbols::slot_name(),           vmSymbols::int_signature());
  compute_offset(modifiers_offset,      k, vmSymbols::modifiers_name(),      vmSymbols::int_signature());
  signature_offset = -1;
  annotations_offset = -1;
  parameter_annotations_offset = -1;
  annotation_default_offset = -1;
  type_annotations_offset = -1;
  compute_optional_offset(signature_offset,             k, vmSymbols::signature_name(),             vmSymbols::string_signature());
  compute_optional_offset(annotations_offset,           k, vmSymbols::annotations_name(),           vmSymbols::byte_array_signature());
  compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
  compute_optional_offset(annotation_default_offset,    k, vmSymbols::annotation_default_name(),    vmSymbols::byte_array_signature());
  compute_optional_offset(type_annotations_offset,      k, vmSymbols::type_annotations_name(),      vmSymbols::byte_array_signature());
}
Handle java_lang_reflect_Method::create(TRAPS) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  Klass* klass = SystemDictionary::reflect_Method_klass();
  assert(InstanceKlass::cast(klass)->is_initialized(), "must be initialized");
  return InstanceKlass::cast(klass)->allocate_instance_handle(THREAD);
}
oop java_lang_reflect_Method::clazz(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return reflect->obj_field(clazz_offset);
}
void java_lang_reflect_Method::set_clazz(oop reflect, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
   reflect->obj_field_put(clazz_offset, value);
}
int java_lang_reflect_Method::slot(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return reflect->int_field(slot_offset);
}
void java_lang_reflect_Method::set_slot(oop reflect, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  reflect->int_field_put(slot_offset, value);
}
oop java_lang_reflect_Method::name(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return method->obj_field(name_offset);
}
void java_lang_reflect_Method::set_name(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  method->obj_field_put(name_offset, value);
}
oop java_lang_reflect_Method::return_type(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return method->obj_field(returnType_offset);
}
void java_lang_reflect_Method::set_return_type(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  method->obj_field_put(returnType_offset, value);
}
oop java_lang_reflect_Method::parameter_types(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return method->obj_field(parameterTypes_offset);
}
void java_lang_reflect_Method::set_parameter_types(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  method->obj_field_put(parameterTypes_offset, value);
}
oop java_lang_reflect_Method::exception_types(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return method->obj_field(exceptionTypes_offset);
}
void java_lang_reflect_Method::set_exception_types(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  method->obj_field_put(exceptionTypes_offset, value);
}
int java_lang_reflect_Method::modifiers(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return method->int_field(modifiers_offset);
}
void java_lang_reflect_Method::set_modifiers(oop method, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  method->int_field_put(modifiers_offset, value);
}
bool java_lang_reflect_Method::has_signature_field() {
  return (signature_offset >= 0);
}
oop java_lang_reflect_Method::signature(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_signature_field(), "signature field must be present");
  return method->obj_field(signature_offset);
}
void java_lang_reflect_Method::set_signature(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_signature_field(), "signature field must be present");
  method->obj_field_put(signature_offset, value);
}
bool java_lang_reflect_Method::has_annotations_field() {
  return (annotations_offset >= 0);
}
oop java_lang_reflect_Method::annotations(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotations_field(), "annotations field must be present");
  return method->obj_field(annotations_offset);
}
void java_lang_reflect_Method::set_annotations(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotations_field(), "annotations field must be present");
  method->obj_field_put(annotations_offset, value);
}
bool java_lang_reflect_Method::has_parameter_annotations_field() {
  return (parameter_annotations_offset >= 0);
}
oop java_lang_reflect_Method::parameter_annotations(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_parameter_annotations_field(), "parameter annotations field must be present");
  return method->obj_field(parameter_annotations_offset);
}
void java_lang_reflect_Method::set_parameter_annotations(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_parameter_annotations_field(), "parameter annotations field must be present");
  method->obj_field_put(parameter_annotations_offset, value);
}
bool java_lang_reflect_Method::has_annotation_default_field() {
  return (annotation_default_offset >= 0);
}
oop java_lang_reflect_Method::annotation_default(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotation_default_field(), "annotation default field must be present");
  return method->obj_field(annotation_default_offset);
}
void java_lang_reflect_Method::set_annotation_default(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotation_default_field(), "annotation default field must be present");
  method->obj_field_put(annotation_default_offset, value);
}
bool java_lang_reflect_Method::has_type_annotations_field() {
  return (type_annotations_offset >= 0);
}
oop java_lang_reflect_Method::type_annotations(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_type_annotations_field(), "type_annotations field must be present");
  return method->obj_field(type_annotations_offset);
}
void java_lang_reflect_Method::set_type_annotations(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_type_annotations_field(), "type_annotations field must be present");
  method->obj_field_put(type_annotations_offset, value);
}
void java_lang_reflect_Constructor::compute_offsets() {
  Klass* k = SystemDictionary::reflect_Constructor_klass();
  compute_offset(clazz_offset,          k, vmSymbols::clazz_name(),          vmSymbols::class_signature());
  compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature());
  compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature());
  compute_offset(slot_offset,           k, vmSymbols::slot_name(),           vmSymbols::int_signature());
  compute_offset(modifiers_offset,      k, vmSymbols::modifiers_name(),      vmSymbols::int_signature());
  signature_offset = -1;
  annotations_offset = -1;
  parameter_annotations_offset = -1;
  type_annotations_offset = -1;
  compute_optional_offset(signature_offset,             k, vmSymbols::signature_name(),             vmSymbols::string_signature());
  compute_optional_offset(annotations_offset,           k, vmSymbols::annotations_name(),           vmSymbols::byte_array_signature());
  compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
  compute_optional_offset(type_annotations_offset,      k, vmSymbols::type_annotations_name(),      vmSymbols::byte_array_signature());
}
Handle java_lang_reflect_Constructor::create(TRAPS) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  Symbol* name = vmSymbols::java_lang_reflect_Constructor();
  Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
  instanceKlassHandle klass (THREAD, k);
  klass->initialize(CHECK_NH);
  return klass->allocate_instance_handle(CHECK_NH);
}
oop java_lang_reflect_Constructor::clazz(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return reflect->obj_field(clazz_offset);
}
void java_lang_reflect_Constructor::set_clazz(oop reflect, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
   reflect->obj_field_put(clazz_offset, value);
}
oop java_lang_reflect_Constructor::parameter_types(oop constructor) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return constructor->obj_field(parameterTypes_offset);
}
void java_lang_reflect_Constructor::set_parameter_types(oop constructor, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  constructor->obj_field_put(parameterTypes_offset, value);
}
oop java_lang_reflect_Constructor::exception_types(oop constructor) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return constructor->obj_field(exceptionTypes_offset);
}
void java_lang_reflect_Constructor::set_exception_types(oop constructor, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  constructor->obj_field_put(exceptionTypes_offset, value);
}
int java_lang_reflect_Constructor::slot(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return reflect->int_field(slot_offset);
}
void java_lang_reflect_Constructor::set_slot(oop reflect, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  reflect->int_field_put(slot_offset, value);
}
int java_lang_reflect_Constructor::modifiers(oop constructor) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return constructor->int_field(modifiers_offset);
}
void java_lang_reflect_Constructor::set_modifiers(oop constructor, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  constructor->int_field_put(modifiers_offset, value);
}
bool java_lang_reflect_Constructor::has_signature_field() {
  return (signature_offset >= 0);
}
oop java_lang_reflect_Constructor::signature(oop constructor) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_signature_field(), "signature field must be present");
  return constructor->obj_field(signature_offset);
}
void java_lang_reflect_Constructor::set_signature(oop constructor, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_signature_field(), "signature field must be present");
  constructor->obj_field_put(signature_offset, value);
}
bool java_lang_reflect_Constructor::has_annotations_field() {
  return (annotations_offset >= 0);
}
oop java_lang_reflect_Constructor::annotations(oop constructor) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotations_field(), "annotations field must be present");
  return constructor->obj_field(annotations_offset);
}
void java_lang_reflect_Constructor::set_annotations(oop constructor, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotations_field(), "annotations field must be present");
  constructor->obj_field_put(annotations_offset, value);
}
bool java_lang_reflect_Constructor::has_parameter_annotations_field() {
  return (parameter_annotations_offset >= 0);
}
oop java_lang_reflect_Constructor::parameter_annotations(oop method) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_parameter_annotations_field(), "parameter annotations field must be present");
  return method->obj_field(parameter_annotations_offset);
}
void java_lang_reflect_Constructor::set_parameter_annotations(oop method, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_parameter_annotations_field(), "parameter annotations field must be present");
  method->obj_field_put(parameter_annotations_offset, value);
}
bool java_lang_reflect_Constructor::has_type_annotations_field() {
  return (type_annotations_offset >= 0);
}
oop java_lang_reflect_Constructor::type_annotations(oop constructor) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_type_annotations_field(), "type_annotations field must be present");
  return constructor->obj_field(type_annotations_offset);
}
void java_lang_reflect_Constructor::set_type_annotations(oop constructor, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_type_annotations_field(), "type_annotations field must be present");
  constructor->obj_field_put(type_annotations_offset, value);
}
void java_lang_reflect_Field::compute_offsets() {
  Klass* k = SystemDictionary::reflect_Field_klass();
  compute_offset(clazz_offset,     k, vmSymbols::clazz_name(),     vmSymbols::class_signature());
  compute_offset(name_offset,      k, vmSymbols::name_name(),      vmSymbols::string_signature());
  compute_offset(type_offset,      k, vmSymbols::type_name(),      vmSymbols::class_signature());
  compute_offset(slot_offset,      k, vmSymbols::slot_name(),      vmSymbols::int_signature());
  compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature());
  signature_offset = -1;
  annotations_offset = -1;
  type_annotations_offset = -1;
  compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
  compute_optional_offset(annotations_offset,  k, vmSymbols::annotations_name(),  vmSymbols::byte_array_signature());
  compute_optional_offset(type_annotations_offset,  k, vmSymbols::type_annotations_name(),  vmSymbols::byte_array_signature());
}
Handle java_lang_reflect_Field::create(TRAPS) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  Symbol* name = vmSymbols::java_lang_reflect_Field();
  Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
  instanceKlassHandle klass (THREAD, k);
  klass->initialize(CHECK_NH);
  return klass->allocate_instance_handle(CHECK_NH);
}
oop java_lang_reflect_Field::clazz(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return reflect->obj_field(clazz_offset);
}
void java_lang_reflect_Field::set_clazz(oop reflect, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
   reflect->obj_field_put(clazz_offset, value);
}
oop java_lang_reflect_Field::name(oop field) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return field->obj_field(name_offset);
}
void java_lang_reflect_Field::set_name(oop field, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  field->obj_field_put(name_offset, value);
}
oop java_lang_reflect_Field::type(oop field) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return field->obj_field(type_offset);
}
void java_lang_reflect_Field::set_type(oop field, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  field->obj_field_put(type_offset, value);
}
int java_lang_reflect_Field::slot(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return reflect->int_field(slot_offset);
}
void java_lang_reflect_Field::set_slot(oop reflect, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  reflect->int_field_put(slot_offset, value);
}
int java_lang_reflect_Field::modifiers(oop field) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return field->int_field(modifiers_offset);
}
void java_lang_reflect_Field::set_modifiers(oop field, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  field->int_field_put(modifiers_offset, value);
}
bool java_lang_reflect_Field::has_signature_field() {
  return (signature_offset >= 0);
}
oop java_lang_reflect_Field::signature(oop field) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_signature_field(), "signature field must be present");
  return field->obj_field(signature_offset);
}
void java_lang_reflect_Field::set_signature(oop field, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_signature_field(), "signature field must be present");
  field->obj_field_put(signature_offset, value);
}
bool java_lang_reflect_Field::has_annotations_field() {
  return (annotations_offset >= 0);
}
oop java_lang_reflect_Field::annotations(oop field) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotations_field(), "annotations field must be present");
  return field->obj_field(annotations_offset);
}
void java_lang_reflect_Field::set_annotations(oop field, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_annotations_field(), "annotations field must be present");
  field->obj_field_put(annotations_offset, value);
}
bool java_lang_reflect_Field::has_type_annotations_field() {
  return (type_annotations_offset >= 0);
}
oop java_lang_reflect_Field::type_annotations(oop field) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_type_annotations_field(), "type_annotations field must be present");
  return field->obj_field(type_annotations_offset);
}
void java_lang_reflect_Field::set_type_annotations(oop field, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  assert(has_type_annotations_field(), "type_annotations field must be present");
  field->obj_field_put(type_annotations_offset, value);
}
void sun_reflect_ConstantPool::compute_offsets() {
  Klass* k = SystemDictionary::reflect_ConstantPool_klass();
  if (k != NULL) {
    compute_offset(_oop_offset, k, vmSymbols::ConstantPool_name(), vmSymbols::object_signature());
  }
}
void java_lang_reflect_Parameter::compute_offsets() {
  Klass* k = SystemDictionary::reflect_Parameter_klass();
  if(NULL != k) {
    compute_offset(name_offset,        k, vmSymbols::name_name(),        vmSymbols::string_signature());
    compute_offset(modifiers_offset,   k, vmSymbols::modifiers_name(),   vmSymbols::int_signature());
    compute_offset(index_offset,       k, vmSymbols::index_name(),       vmSymbols::int_signature());
    compute_offset(executable_offset,  k, vmSymbols::executable_name(),  vmSymbols::executable_signature());
  }
}
Handle java_lang_reflect_Parameter::create(TRAPS) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  Symbol* name = vmSymbols::java_lang_reflect_Parameter();
  Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
  instanceKlassHandle klass (THREAD, k);
  klass->initialize(CHECK_NH);
  return klass->allocate_instance_handle(CHECK_NH);
}
oop java_lang_reflect_Parameter::name(oop param) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return param->obj_field(name_offset);
}
void java_lang_reflect_Parameter::set_name(oop param, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  param->obj_field_put(name_offset, value);
}
int java_lang_reflect_Parameter::modifiers(oop param) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return param->int_field(modifiers_offset);
}
void java_lang_reflect_Parameter::set_modifiers(oop param, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  param->int_field_put(modifiers_offset, value);
}
int java_lang_reflect_Parameter::index(oop param) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return param->int_field(index_offset);
}
void java_lang_reflect_Parameter::set_index(oop param, int value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  param->int_field_put(index_offset, value);
}
oop java_lang_reflect_Parameter::executable(oop param) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  return param->obj_field(executable_offset);
}
void java_lang_reflect_Parameter::set_executable(oop param, oop value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  param->obj_field_put(executable_offset, value);
}
Handle sun_reflect_ConstantPool::create(TRAPS) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  Klass* k = SystemDictionary::reflect_ConstantPool_klass();
  instanceKlassHandle klass (THREAD, k);
  klass->initialize(CHECK_NH);
  return klass->allocate_instance_handle(CHECK_NH);
}
void sun_reflect_ConstantPool::set_cp(oop reflect, ConstantPool* value) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  oop mirror = value->pool_holder()->java_mirror();
  reflect->obj_field_put(_oop_offset, mirror);
}
ConstantPool* sun_reflect_ConstantPool::get_cp(oop reflect) {
  assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
  oop mirror = reflect->obj_field(_oop_offset);
  Klass* k = java_lang_Class::as_Klass(mirror);
  assert(k->oop_is_instance(), "Must be");
  return InstanceKlass::cast(k)->constants();
}
void sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets() {
  Klass* k = SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass();
  if (k != NULL) {
    compute_offset(_base_offset, k,
                   vmSymbols::base_name(), vmSymbols::object_signature());
  }
}
oop java_lang_boxing_object::initialize_and_allocate(BasicType type, TRAPS) {
  Klass* k = SystemDictionary::box_klass(type);
  if (k == NULL)  return NULL;
  instanceKlassHandle h (THREAD, k);
  if (!h->is_initialized())  h->initialize(CHECK_0);
  return h->allocate_instance(THREAD);
}
oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
  oop box = initialize_and_allocate(type, CHECK_0);
  if (box == NULL)  return NULL;
  switch (type) {
    case T_BOOLEAN:
      box->bool_field_put(value_offset, value->z);
      break;
    case T_CHAR:
      box->char_field_put(value_offset, value->c);
      break;
    case T_FLOAT:
      box->float_field_put(value_offset, value->f);
      break;
    case T_DOUBLE:
      box->double_field_put(long_value_offset, value->d);
      break;
    case T_BYTE:
      box->byte_field_put(value_offset, value->b);
      break;
    case T_SHORT:
      box->short_field_put(value_offset, value->s);
      break;
    case T_INT:
      box->int_field_put(value_offset, value->i);
      break;
    case T_LONG:
      box->long_field_put(long_value_offset, value->j);
      break;
    default:
      return NULL;
  }
  return box;
}
BasicType java_lang_boxing_object::basic_type(oop box) {
  if (box == NULL)  return T_ILLEGAL;
  BasicType type = SystemDictionary::box_klass_type(box->klass());
  if (type == T_OBJECT)         // 'unknown' value returned by SD::bkt
    return T_ILLEGAL;
  return type;
}
BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
  BasicType type = SystemDictionary::box_klass_type(box->klass());
  switch (type) {
  case T_BOOLEAN:
    value->z = box->bool_field(value_offset);
    break;
  case T_CHAR:
    value->c = box->char_field(value_offset);
    break;
  case T_FLOAT:
    value->f = box->float_field(value_offset);
    break;
  case T_DOUBLE:
    value->d = box->double_field(long_value_offset);
    break;
  case T_BYTE:
    value->b = box->byte_field(value_offset);
    break;
  case T_SHORT:
    value->s = box->short_field(value_offset);
    break;
  case T_INT:
    value->i = box->int_field(value_offset);
    break;
  case T_LONG:
    value->j = box->long_field(long_value_offset);
    break;
  default:
    return T_ILLEGAL;
  } // end switch
  return type;
}
BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
  BasicType type = SystemDictionary::box_klass_type(box->klass());
  switch (type) {
  case T_BOOLEAN:
    box->bool_field_put(value_offset, value->z);
    break;
  case T_CHAR:
    box->char_field_put(value_offset, value->c);
    break;
  case T_FLOAT:
    box->float_field_put(value_offset, value->f);
    break;
  case T_DOUBLE:
    box->double_field_put(long_value_offset, value->d);
    break;
  case T_BYTE:
    box->byte_field_put(value_offset, value->b);
    break;
  case T_SHORT:
    box->short_field_put(value_offset, value->s);
    break;
  case T_INT:
    box->int_field_put(value_offset, value->i);
    break;
  case T_LONG:
    box->long_field_put(long_value_offset, value->j);
    break;
  default:
    return T_ILLEGAL;
  } // end switch
  return type;
}
void java_lang_boxing_object::print(BasicType type, jvalue* value, outputStream* st) {
  switch (type) {
  case T_BOOLEAN:   st->print("%s", value->z ? "true" : "false");   break;
  case T_CHAR:      st->print("%d", value->c);                      break;
  case T_BYTE:      st->print("%d", value->b);                      break;
  case T_SHORT:     st->print("%d", value->s);                      break;
  case T_INT:       st->print("%d", value->i);                      break;
  case T_LONG:      st->print(INT64_FORMAT, value->j);              break;
  case T_FLOAT:     st->print("%f", value->f);                      break;
  case T_DOUBLE:    st->print("%lf", value->d);                     break;
  default:          st->print("type %d?", type);                    break;
  }
}
HeapWord *java_lang_ref_Reference::pending_list_lock_addr() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass());
  address addr = ik->static_field_addr(static_lock_offset);
  return (HeapWord*) addr;
}
oop java_lang_ref_Reference::pending_list_lock() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass());
  address addr = ik->static_field_addr(static_lock_offset);
  if (UseCompressedOops) {
    return oopDesc::load_decode_heap_oop((narrowOop *)addr);
  } else {
    return oopDesc::load_decode_heap_oop((oop*)addr);
  }
}
HeapWord *java_lang_ref_Reference::pending_list_addr() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass());
  address addr = ik->static_field_addr(static_pending_offset);
  return (HeapWord*)addr;
}
oop java_lang_ref_Reference::pending_list() {
  char *addr = (char *)pending_list_addr();
  if (UseCompressedOops) {
    return oopDesc::load_decode_heap_oop((narrowOop *)addr);
  } else {
    return oopDesc::load_decode_heap_oop((oop*)addr);
  }
}
jlong java_lang_ref_SoftReference::timestamp(oop ref) {
  return ref->long_field(timestamp_offset);
}
jlong java_lang_ref_SoftReference::clock() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::SoftReference_klass());
  jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
  return *offset;
}
void java_lang_ref_SoftReference::set_clock(jlong value) {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::SoftReference_klass());
  jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
}
oop java_lang_ref_ReferenceQueue::NULL_queue() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::ReferenceQueue_klass());
  oop mirror = ik->java_mirror();
  return mirror->obj_field(static_NULL_queue_offset);
}
oop java_lang_ref_ReferenceQueue::ENQUEUED_queue() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::ReferenceQueue_klass());
  oop mirror = ik->java_mirror();
  return mirror->obj_field(static_ENQUEUED_queue_offset);
}
void java_lang_ref_ReferenceQueue::compute_offsets() {
  Klass* k = SystemDictionary::ReferenceQueue_klass();
  compute_offset(static_NULL_queue_offset,
                 k,
                 vmSymbols::referencequeue_null_name(),
                 vmSymbols::referencequeue_signature());
  compute_offset(static_ENQUEUED_queue_offset,
                 k,
                 vmSymbols::referencequeue_enqueued_name(),
                 vmSymbols::referencequeue_signature());
}
int java_lang_invoke_DirectMethodHandle::_member_offset;
oop java_lang_invoke_DirectMethodHandle::member(oop dmh) {
  oop member_name = NULL;
  bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh);
  assert(is_dmh, "a DirectMethodHandle oop is expected");
  if (is_dmh) {
    member_name = dmh->obj_field(member_offset_in_bytes());
  }
  return member_name;
}
void java_lang_invoke_DirectMethodHandle::compute_offsets() {
  Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass();
  if (klass_oop != NULL && EnableInvokeDynamic) {
    compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature());
  }
}
int java_lang_invoke_MethodHandle::_type_offset;
int java_lang_invoke_MethodHandle::_form_offset;
int java_lang_invoke_MemberName::_clazz_offset;
int java_lang_invoke_MemberName::_name_offset;
int java_lang_invoke_MemberName::_type_offset;
int java_lang_invoke_MemberName::_flags_offset;
int java_lang_invoke_MemberName::_vmtarget_offset;
int java_lang_invoke_MemberName::_vmloader_offset;
int java_lang_invoke_MemberName::_vmindex_offset;
int java_lang_invoke_LambdaForm::_vmentry_offset;
void java_lang_invoke_MethodHandle::compute_offsets() {
  Klass* klass_oop = SystemDictionary::MethodHandle_klass();
  if (klass_oop != NULL && EnableInvokeDynamic) {
    compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature());
    compute_optional_offset(_form_offset, klass_oop, vmSymbols::form_name(), vmSymbols::java_lang_invoke_LambdaForm_signature());
    if (_form_offset == 0) {
      EnableInvokeDynamic = false;
    }
  }
}
void java_lang_invoke_MemberName::compute_offsets() {
  Klass* klass_oop = SystemDictionary::MemberName_klass();
  if (klass_oop != NULL && EnableInvokeDynamic) {
    compute_offset(_clazz_offset,     klass_oop, vmSymbols::clazz_name(),     vmSymbols::class_signature());
    compute_offset(_name_offset,      klass_oop, vmSymbols::name_name(),      vmSymbols::string_signature());
    compute_offset(_type_offset,      klass_oop, vmSymbols::type_name(),      vmSymbols::object_signature());
    compute_offset(_flags_offset,     klass_oop, vmSymbols::flags_name(),     vmSymbols::int_signature());
    MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
  }
}
void java_lang_invoke_LambdaForm::compute_offsets() {
  Klass* klass_oop = SystemDictionary::LambdaForm_klass();
  if (klass_oop != NULL && EnableInvokeDynamic) {
    compute_offset(_vmentry_offset, klass_oop, vmSymbols::vmentry_name(), vmSymbols::java_lang_invoke_MemberName_signature());
  }
}
oop java_lang_invoke_MethodHandle::type(oop mh) {
  return mh->obj_field(_type_offset);
}
void java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) {
  mh->obj_field_put(_type_offset, mtype);
}
oop java_lang_invoke_MethodHandle::form(oop mh) {
  assert(_form_offset != 0, "");
  return mh->obj_field(_form_offset);
}
void java_lang_invoke_MethodHandle::set_form(oop mh, oop lform) {
  assert(_form_offset != 0, "");
  mh->obj_field_put(_form_offset, lform);
}
oop java_lang_invoke_MemberName::clazz(oop mname) {
  assert(is_instance(mname), "wrong type");
  return mname->obj_field(_clazz_offset);
}
void java_lang_invoke_MemberName::set_clazz(oop mname, oop clazz) {
  assert(is_instance(mname), "wrong type");
  mname->obj_field_put(_clazz_offset, clazz);
}
oop java_lang_invoke_MemberName::name(oop mname) {
  assert(is_instance(mname), "wrong type");
  return mname->obj_field(_name_offset);
}
void java_lang_invoke_MemberName::set_name(oop mname, oop name) {
  assert(is_instance(mname), "wrong type");
  mname->obj_field_put(_name_offset, name);
}
oop java_lang_invoke_MemberName::type(oop mname) {
  assert(is_instance(mname), "wrong type");
  return mname->obj_field(_type_offset);
}
void java_lang_invoke_MemberName::set_type(oop mname, oop type) {
  assert(is_instance(mname), "wrong type");
  mname->obj_field_put(_type_offset, type);
}
int java_lang_invoke_MemberName::flags(oop mname) {
  assert(is_instance(mname), "wrong type");
  return mname->int_field(_flags_offset);
}
void java_lang_invoke_MemberName::set_flags(oop mname, int flags) {
  assert(is_instance(mname), "wrong type");
  mname->int_field_put(_flags_offset, flags);
}
Metadata* java_lang_invoke_MemberName::vmtarget(oop mname) {
  assert(is_instance(mname), "wrong type");
  return (Metadata*)mname->address_field(_vmtarget_offset);
}
bool java_lang_invoke_MemberName::is_method(oop mname) {
  assert(is_instance(mname), "must be MemberName");
  return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
}
void java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) {
  assert(is_instance(mname), "wrong type");
  oop dependency = NULL;
  if (ref != NULL) {
    switch (flags(mname) & (MN_IS_METHOD |
                            MN_IS_CONSTRUCTOR |
                            MN_IS_FIELD)) {
    case MN_IS_METHOD:
    case MN_IS_CONSTRUCTOR:
      assert(ref->is_method(), "should be a method");
      dependency = ((Method*)ref)->method_holder()->java_mirror();
      break;
    case MN_IS_FIELD:
      assert(ref->is_klass(), "should be a class");
      dependency = ((Klass*)ref)->java_mirror();
      break;
    default:
      ShouldNotReachHere();
    }
  }
  mname->address_field_put(_vmtarget_offset, (address)ref);
  mname->obj_field_put(_vmloader_offset, dependency);
}
intptr_t java_lang_invoke_MemberName::vmindex(oop mname) {
  assert(is_instance(mname), "wrong type");
  return (intptr_t) mname->address_field(_vmindex_offset);
}
void java_lang_invoke_MemberName::set_vmindex(oop mname, intptr_t index) {
  assert(is_instance(mname), "wrong type");
  mname->address_field_put(_vmindex_offset, (address) index);
}
bool java_lang_invoke_MemberName::equals(oop mn1, oop mn2) {
  if (mn1 == mn2) {
     return true;
  }
  return (vmtarget(mn1) == vmtarget(mn2) && flags(mn1) == flags(mn2) &&
          vmindex(mn1) == vmindex(mn2) &&
          clazz(mn1) == clazz(mn2));
}
oop java_lang_invoke_LambdaForm::vmentry(oop lform) {
  assert(is_instance(lform), "wrong type");
  return lform->obj_field(_vmentry_offset);
}
int java_lang_invoke_MethodType::_rtype_offset;
int java_lang_invoke_MethodType::_ptypes_offset;
void java_lang_invoke_MethodType::compute_offsets() {
  Klass* k = SystemDictionary::MethodType_klass();
  if (k != NULL) {
    compute_offset(_rtype_offset,  k, vmSymbols::rtype_name(),  vmSymbols::class_signature());
    compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature());
  }
}
void java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) {
  st->print("(");
  objArrayOop pts = ptypes(mt);
  for (int i = 0, limit = pts->length(); i < limit; i++) {
    java_lang_Class::print_signature(pts->obj_at(i), st);
  }
  st->print(")");
  java_lang_Class::print_signature(rtype(mt), st);
}
Symbol* java_lang_invoke_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
  ResourceMark rm;
  stringStream buffer(128);
  print_signature(mt, &buffer);
  const char* sigstr =       buffer.base();
  int         siglen = (int) buffer.size();
  Symbol *name;
  if (!intern_if_not_found) {
    name = SymbolTable::probe(sigstr, siglen);
  } else {
    name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
  }
  return name;
}
bool java_lang_invoke_MethodType::equals(oop mt1, oop mt2) {
  if (mt1 == mt2)
    return true;
  if (rtype(mt1) != rtype(mt2))
    return false;
  if (ptype_count(mt1) != ptype_count(mt2))
    return false;
  for (int i = ptype_count(mt1) - 1; i >= 0; i--) {
    if (ptype(mt1, i) != ptype(mt2, i))
      return false;
  }
  return true;
}
oop java_lang_invoke_MethodType::rtype(oop mt) {
  assert(is_instance(mt), "must be a MethodType");
  return mt->obj_field(_rtype_offset);
}
objArrayOop java_lang_invoke_MethodType::ptypes(oop mt) {
  assert(is_instance(mt), "must be a MethodType");
  return (objArrayOop) mt->obj_field(_ptypes_offset);
}
oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
  return ptypes(mt)->obj_at(idx);
}
int java_lang_invoke_MethodType::ptype_count(oop mt) {
  return ptypes(mt)->length();
}
int java_lang_invoke_MethodType::ptype_slot_count(oop mt) {
  objArrayOop pts = ptypes(mt);
  int count = pts->length();
  int slots = 0;
  for (int i = 0; i < count; i++) {
    BasicType bt = java_lang_Class::as_BasicType(pts->obj_at(i));
    slots += type2size[bt];
  }
  return slots;
}
int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
  BasicType bt = java_lang_Class::as_BasicType(rtype(mt));
  return type2size[bt];
}
int java_lang_invoke_CallSite::_target_offset;
void java_lang_invoke_CallSite::compute_offsets() {
  if (!EnableInvokeDynamic)  return;
  Klass* k = SystemDictionary::CallSite_klass();
  if (k != NULL) {
    compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
  }
}
int java_security_AccessControlContext::_context_offset = 0;
int java_security_AccessControlContext::_privilegedContext_offset = 0;
int java_security_AccessControlContext::_isPrivileged_offset = 0;
int java_security_AccessControlContext::_isAuthorized_offset = -1;
void java_security_AccessControlContext::compute_offsets() {
  assert(_isPrivileged_offset == 0, "offsets should be initialized only once");
  fieldDescriptor fd;
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::AccessControlContext_klass());
  if (!ik->find_local_field(vmSymbols::context_name(), vmSymbols::protectiondomain_signature(), &fd)) {
    fatal("Invalid layout of java.security.AccessControlContext");
  }
  _context_offset = fd.offset();
  if (!ik->find_local_field(vmSymbols::privilegedContext_name(), vmSymbols::accesscontrolcontext_signature(), &fd)) {
    fatal("Invalid layout of java.security.AccessControlContext");
  }
  _privilegedContext_offset = fd.offset();
  if (!ik->find_local_field(vmSymbols::isPrivileged_name(), vmSymbols::bool_signature(), &fd)) {
    fatal("Invalid layout of java.security.AccessControlContext");
  }
  _isPrivileged_offset = fd.offset();
  if (ik->find_local_field(vmSymbols::isAuthorized_name(), vmSymbols::bool_signature(), &fd)) {
    _isAuthorized_offset = fd.offset();
  }
}
bool java_security_AccessControlContext::is_authorized(Handle context) {
  assert(context.not_null() && context->klass() == SystemDictionary::AccessControlContext_klass(), "Invalid type");
  assert(_isAuthorized_offset != -1, "should be set");
  return context->bool_field(_isAuthorized_offset) != 0;
}
oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) {
  assert(_isPrivileged_offset != 0, "offsets should have been initialized");
  InstanceKlass::cast(SystemDictionary::AccessControlContext_klass())->initialize(CHECK_0);
  oop result = InstanceKlass::cast(SystemDictionary::AccessControlContext_klass())->allocate_instance(CHECK_0);
  result->obj_field_put(_context_offset, context());
  result->obj_field_put(_privilegedContext_offset, privileged_context());
  result->bool_field_put(_isPrivileged_offset, isPrivileged);
  if (_isAuthorized_offset != -1) {
    result->bool_field_put(_isAuthorized_offset, true);
  }
  return result;
}
bool java_lang_ClassLoader::offsets_computed = false;
int  java_lang_ClassLoader::_loader_data_offset = -1;
int  java_lang_ClassLoader::parallelCapable_offset = -1;
ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
    assert(loader != NULL && loader->is_oop(), "loader must be oop");
    return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
}
ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
  return *java_lang_ClassLoader::loader_data_addr(loader);
}
void java_lang_ClassLoader::compute_offsets() {
  assert(!offsets_computed, "offsets should be initialized only once");
  offsets_computed = true;
  Klass* k1 = SystemDictionary::ClassLoader_klass();
  compute_optional_offset(parallelCapable_offset,
    k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature());
  CLASSLOADER_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
oop java_lang_ClassLoader::parent(oop loader) {
  assert(is_instance(loader), "loader must be oop");
  return loader->obj_field(parent_offset);
}
bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
  assert(is_instance(loader), "loader must be oop");
  assert(cl == NULL || is_instance(cl), "cl argument must be oop");
  oop acl = loader;
  debug_only(jint loop_count = 0);
  do {
    acl = parent(acl);
    if (cl == acl) {
      return true;
    }
    assert(++loop_count > 0, "loop_count overflow");
  } while (acl != NULL);
  return false;
}
bool java_lang_ClassLoader::parallelCapable(oop class_loader) {
  if (!JDK_Version::is_gte_jdk17x_version()
     || parallelCapable_offset == -1) {
     return false;
  }
  return (class_loader->obj_field(parallelCapable_offset) != NULL);
}
bool java_lang_ClassLoader::is_trusted_loader(oop loader) {
  loader = non_reflection_class_loader(loader);
  oop cl = SystemDictionary::java_system_loader();
  while(cl != NULL) {
    if (cl == loader) return true;
    cl = parent(cl);
  }
  return false;
}
oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) {
  if (loader != NULL) {
    Klass* delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass();
    if (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)) {
      return parent(loader);
    }
  }
  return loader;
}
int java_lang_System::in_offset_in_bytes() {
  return (InstanceMirrorKlass::offset_of_static_fields() + static_in_offset);
}
int java_lang_System::out_offset_in_bytes() {
  return (InstanceMirrorKlass::offset_of_static_fields() + static_out_offset);
}
int java_lang_System::err_offset_in_bytes() {
  return (InstanceMirrorKlass::offset_of_static_fields() + static_err_offset);
}
bool java_lang_System::has_security_manager() {
  InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::System_klass());
  address addr = ik->static_field_addr(static_security_offset);
  if (UseCompressedOops) {
    return oopDesc::load_decode_heap_oop((narrowOop *)addr) != NULL;
  } else {
    return oopDesc::load_decode_heap_oop((oop*)addr) != NULL;
  }
}
int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
int java_lang_Class::_oop_size_offset;
int java_lang_Class::_static_oop_field_count_offset;
int java_lang_Class::_class_loader_offset;
int java_lang_Class::_protection_domain_offset;
int java_lang_Class::_init_lock_offset;
int java_lang_Class::_signers_offset;
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
int java_lang_Throwable::backtrace_offset;
int java_lang_Throwable::detailMessage_offset;
int java_lang_Throwable::cause_offset;
int java_lang_Throwable::stackTrace_offset;
int java_lang_Throwable::static_unassigned_stacktrace_offset;
int java_lang_reflect_AccessibleObject::override_offset;
int java_lang_reflect_Method::clazz_offset;
int java_lang_reflect_Method::name_offset;
int java_lang_reflect_Method::returnType_offset;
int java_lang_reflect_Method::parameterTypes_offset;
int java_lang_reflect_Method::exceptionTypes_offset;
int java_lang_reflect_Method::slot_offset;
int java_lang_reflect_Method::modifiers_offset;
int java_lang_reflect_Method::signature_offset;
int java_lang_reflect_Method::annotations_offset;
int java_lang_reflect_Method::parameter_annotations_offset;
int java_lang_reflect_Method::annotation_default_offset;
int java_lang_reflect_Method::type_annotations_offset;
int java_lang_reflect_Constructor::clazz_offset;
int java_lang_reflect_Constructor::parameterTypes_offset;
int java_lang_reflect_Constructor::exceptionTypes_offset;
int java_lang_reflect_Constructor::slot_offset;
int java_lang_reflect_Constructor::modifiers_offset;
int java_lang_reflect_Constructor::signature_offset;
int java_lang_reflect_Constructor::annotations_offset;
int java_lang_reflect_Constructor::parameter_annotations_offset;
int java_lang_reflect_Constructor::type_annotations_offset;
int java_lang_reflect_Field::clazz_offset;
int java_lang_reflect_Field::name_offset;
int java_lang_reflect_Field::type_offset;
int java_lang_reflect_Field::slot_offset;
int java_lang_reflect_Field::modifiers_offset;
int java_lang_reflect_Field::signature_offset;
int java_lang_reflect_Field::annotations_offset;
int java_lang_reflect_Field::type_annotations_offset;
int java_lang_reflect_Parameter::name_offset;
int java_lang_reflect_Parameter::modifiers_offset;
int java_lang_reflect_Parameter::index_offset;
int java_lang_reflect_Parameter::executable_offset;
int java_lang_boxing_object::value_offset;
int java_lang_boxing_object::long_value_offset;
int java_lang_ref_Reference::referent_offset;
int java_lang_ref_Reference::queue_offset;
int java_lang_ref_Reference::next_offset;
int java_lang_ref_Reference::discovered_offset;
int java_lang_ref_Reference::static_lock_offset;
int java_lang_ref_Reference::static_pending_offset;
int java_lang_ref_Reference::number_of_fake_oop_fields;
int java_lang_ref_ReferenceQueue::static_NULL_queue_offset;
int java_lang_ref_ReferenceQueue::static_ENQUEUED_queue_offset;
int java_lang_ref_SoftReference::timestamp_offset;
int java_lang_ref_SoftReference::static_clock_offset;
int java_lang_ClassLoader::parent_offset;
int java_lang_System::static_in_offset;
int java_lang_System::static_out_offset;
int java_lang_System::static_err_offset;
int java_lang_System::static_security_offset;
int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
int java_lang_StackTraceElement::fileName_offset;
int java_lang_StackTraceElement::lineNumber_offset;
int java_lang_AssertionStatusDirectives::classes_offset;
int java_lang_AssertionStatusDirectives::classEnabled_offset;
int java_lang_AssertionStatusDirectives::packages_offset;
int java_lang_AssertionStatusDirectives::packageEnabled_offset;
int java_lang_AssertionStatusDirectives::deflt_offset;
int java_nio_Buffer::_limit_offset;
int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset = 0;
int sun_reflect_ConstantPool::_oop_offset;
int sun_reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
void java_lang_StackTraceElement::set_fileName(oop element, oop value) {
  element->obj_field_put(fileName_offset, value);
}
void java_lang_StackTraceElement::set_declaringClass(oop element, oop value) {
  element->obj_field_put(declaringClass_offset, value);
}
void java_lang_StackTraceElement::set_methodName(oop element, oop value) {
  element->obj_field_put(methodName_offset, value);
}
void java_lang_StackTraceElement::set_lineNumber(oop element, int value) {
  element->int_field_put(lineNumber_offset, value);
}
void java_lang_AssertionStatusDirectives::set_classes(oop o, oop val) {
  o->obj_field_put(classes_offset, val);
}
void java_lang_AssertionStatusDirectives::set_classEnabled(oop o, oop val) {
  o->obj_field_put(classEnabled_offset, val);
}
void java_lang_AssertionStatusDirectives::set_packages(oop o, oop val) {
  o->obj_field_put(packages_offset, val);
}
void java_lang_AssertionStatusDirectives::set_packageEnabled(oop o, oop val) {
  o->obj_field_put(packageEnabled_offset, val);
}
void java_lang_AssertionStatusDirectives::set_deflt(oop o, bool val) {
  o->bool_field_put(deflt_offset, val);
}
int java_nio_Buffer::limit_offset() {
  return _limit_offset;
}
void java_nio_Buffer::compute_offsets() {
  Klass* k = SystemDictionary::nio_Buffer_klass();
  assert(k != NULL, "must be loaded in 1.4+");
  compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature());
}
void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
  if (_owner_offset != 0) return;
  assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later");
  SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK);
  Klass* k = SystemDictionary::abstract_ownable_synchronizer_klass();
  compute_offset(_owner_offset, k,
                 vmSymbols::exclusive_owner_thread_name(), vmSymbols::thread_signature());
}
oop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(oop obj) {
  assert(_owner_offset != 0, "Must be initialized");
  return obj->obj_field(_owner_offset);
}
void JavaClasses::compute_hard_coded_offsets() {
  const int x = heapOopSize;
  const int header = instanceOopDesc::base_offset_in_bytes();
  java_lang_Throwable::backtrace_offset  = java_lang_Throwable::hc_backtrace_offset  * x + header;
  java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
  java_lang_Throwable::cause_offset      = java_lang_Throwable::hc_cause_offset      * x + header;
  java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
  java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset *  x;
  java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;
  java_lang_boxing_object::long_value_offset = align_size_up((java_lang_boxing_object::hc_value_offset + header), BytesPerLong);
  java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header;
  java_lang_ref_Reference::queue_offset = java_lang_ref_Reference::hc_queue_offset * x + header;
  java_lang_ref_Reference::next_offset  = java_lang_ref_Reference::hc_next_offset * x + header;
  java_lang_ref_Reference::discovered_offset  = java_lang_ref_Reference::hc_discovered_offset * x + header;
  java_lang_ref_Reference::static_lock_offset = java_lang_ref_Reference::hc_static_lock_offset *  x;
  java_lang_ref_Reference::static_pending_offset = java_lang_ref_Reference::hc_static_pending_offset * x;
  java_lang_ref_Reference::number_of_fake_oop_fields = 1;
  java_lang_ref_SoftReference::timestamp_offset = align_size_up((java_lang_ref_SoftReference::hc_timestamp_offset * x + header), BytesPerLong);
  java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x;
  java_lang_ClassLoader::parent_offset = java_lang_ClassLoader::hc_parent_offset * x + header;
  java_lang_System::static_in_offset  = java_lang_System::hc_static_in_offset  * x;
  java_lang_System::static_out_offset = java_lang_System::hc_static_out_offset * x;
  java_lang_System::static_err_offset = java_lang_System::hc_static_err_offset * x;
  java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x;
  java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset  * x + header;
  java_lang_StackTraceElement::methodName_offset = java_lang_StackTraceElement::hc_methodName_offset * x + header;
  java_lang_StackTraceElement::fileName_offset   = java_lang_StackTraceElement::hc_fileName_offset   * x + header;
  java_lang_StackTraceElement::lineNumber_offset = java_lang_StackTraceElement::hc_lineNumber_offset * x + header;
  java_lang_AssertionStatusDirectives::classes_offset = java_lang_AssertionStatusDirectives::hc_classes_offset * x + header;
  java_lang_AssertionStatusDirectives::classEnabled_offset = java_lang_AssertionStatusDirectives::hc_classEnabled_offset * x + header;
  java_lang_AssertionStatusDirectives::packages_offset = java_lang_AssertionStatusDirectives::hc_packages_offset * x + header;
  java_lang_AssertionStatusDirectives::packageEnabled_offset = java_lang_AssertionStatusDirectives::hc_packageEnabled_offset * x + header;
  java_lang_AssertionStatusDirectives::deflt_offset = java_lang_AssertionStatusDirectives::hc_deflt_offset * x + header;
}
void JavaClasses::compute_offsets() {
  java_lang_ClassLoader::compute_offsets();
  java_lang_Thread::compute_offsets();
  java_lang_ThreadGroup::compute_offsets();
  if (EnableInvokeDynamic) {
    java_lang_invoke_MethodHandle::compute_offsets();
    java_lang_invoke_DirectMethodHandle::compute_offsets();
    java_lang_invoke_MemberName::compute_offsets();
    java_lang_invoke_LambdaForm::compute_offsets();
    java_lang_invoke_MethodType::compute_offsets();
    java_lang_invoke_CallSite::compute_offsets();
  }
  java_security_AccessControlContext::compute_offsets();
  java_lang_reflect_AccessibleObject::compute_offsets();
  java_lang_reflect_Method::compute_offsets();
  java_lang_reflect_Constructor::compute_offsets();
  java_lang_reflect_Field::compute_offsets();
  if (JDK_Version::is_gte_jdk14x_version()) {
    java_nio_Buffer::compute_offsets();
  }
  if (JDK_Version::is_gte_jdk15x_version()) {
    sun_reflect_ConstantPool::compute_offsets();
    sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
  }
  if (JDK_Version::is_jdk18x_version())
    java_lang_reflect_Parameter::compute_offsets();
  java_lang_ref_ReferenceQueue::compute_offsets();
  AbstractAssembler::update_delayed_values();
}
#ifndef PRODUCT
bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
  EXCEPTION_MARK;
  fieldDescriptor fd;
  TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
  Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
  instanceKlassHandle h_klass (THREAD, k);
  TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
  TempNewSymbol f_sig  = SymbolTable::new_symbol(field_sig, CATCH);
  if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
    tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name);
    return false;
  }
  if (fd.is_static()) {
    tty->print_cr("Nonstatic field %s.%s appears to be static", klass_name, field_name);
    return false;
  }
  if (fd.offset() == hardcoded_offset ) {
    return true;
  } else {
    tty->print_cr("Offset of nonstatic field %s.%s is hardcoded as %d but should really be %d.",
                  klass_name, field_name, hardcoded_offset, fd.offset());
    return false;
  }
}
bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
  EXCEPTION_MARK;
  fieldDescriptor fd;
  TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
  Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
  instanceKlassHandle h_klass (THREAD, k);
  TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
  TempNewSymbol f_sig  = SymbolTable::new_symbol(field_sig, CATCH);
  if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
    tty->print_cr("Static field %s.%s not found", klass_name, field_name);
    return false;
  }
  if (!fd.is_static()) {
    tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
    return false;
  }
  if (fd.offset() == hardcoded_offset + InstanceMirrorKlass::offset_of_static_fields()) {
    return true;
  } else {
    tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - InstanceMirrorKlass::offset_of_static_fields());
    return false;
  }
}
bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) {
  EXCEPTION_MARK;
  fieldDescriptor fd;
  TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
  Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
  instanceKlassHandle h_klass (THREAD, k);
  TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
  TempNewSymbol f_sig  = SymbolTable::new_symbol(field_sig, CATCH);
  if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
    tty->print_cr("Static field %s.%s not found", klass_name, field_name);
    return false;
  }
  if (!fd.is_static() || !fd.has_initial_value()) {
    tty->print_cr("Static field %s.%s appears to be non-constant", klass_name, field_name);
    return false;
  }
  if (!fd.initial_value_tag().is_int()) {
    tty->print_cr("Static field %s.%s is not an int", klass_name, field_name);
    return false;
  }
  jint field_value = fd.int_initial_value();
  if (field_value == hardcoded_constant) {
    return true;
  } else {
    tty->print_cr("Constant value of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_constant, field_value);
    return false;
  }
}
void JavaClasses::check_offsets() {
  bool valid = true;
  HandleMark hm;
#define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
  valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig)
#define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
  valid &= check_offset(klass_name, cpp_klass_name :: long_ ## field_name ## _offset, #field_name, field_sig)
#define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
  valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig)
#define CHECK_CONSTANT(klass_name, cpp_klass_name, field_name, field_sig) \
  valid &= check_constant(klass_name, cpp_klass_name :: field_name, #field_name, field_sig)
  CHECK_OFFSET("java/lang/String", java_lang_String, value, "[C");
  if (java_lang_String::has_offset_field()) {
    CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I");
    CHECK_OFFSET("java/lang/String", java_lang_String, count, "I");
  }
  if (java_lang_String::has_hash_field()) {
    CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
  }
  CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, backtrace, "Ljava/lang/Object;");
  CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, detailMessage, "Ljava/lang/String;");
  CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, cause, "Ljava/lang/Throwable;");
  CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, stackTrace, "[Ljava/lang/StackTraceElement;");
  CHECK_OFFSET("java/lang/Boolean",   java_lang_boxing_object, value, "Z");
  CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
  CHECK_OFFSET("java/lang/Float",     java_lang_boxing_object, value, "F");
  CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
  CHECK_OFFSET("java/lang/Byte",      java_lang_boxing_object, value, "B");
  CHECK_OFFSET("java/lang/Short",     java_lang_boxing_object, value, "S");
  CHECK_OFFSET("java/lang/Integer",   java_lang_boxing_object, value, "I");
  CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
  CHECK_OFFSET("java/lang/ClassLoader", java_lang_ClassLoader, parent,      "Ljava/lang/ClassLoader;");
  CHECK_STATIC_OFFSET("java/lang/System", java_lang_System,  in, "Ljava/io/InputStream;");
  CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, out, "Ljava/io/PrintStream;");
  CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, err, "Ljava/io/PrintStream;");
  CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, security, "Ljava/lang/SecurityManager;");
  CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;");
  CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;");
  CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement,   fileName, "Ljava/lang/String;");
  CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, lineNumber, "I");
  CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, referent, "Ljava/lang/Object;");
  CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, queue, "Ljava/lang/ref/ReferenceQueue;");
  CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, next, "Ljava/lang/ref/Reference;");
  CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, lock, "Ljava/lang/ref/Reference$Lock;");
  CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, pending, "Ljava/lang/ref/Reference;");
  CHECK_OFFSET("java/lang/ref/SoftReference", java_lang_ref_SoftReference, timestamp, "J");
  CHECK_STATIC_OFFSET("java/lang/ref/SoftReference", java_lang_ref_SoftReference, clock, "J");
  if (CheckAssertionStatusDirectives && JDK_Version::is_gte_jdk14x_version()) {
    const char* nm = "java/lang/AssertionStatusDirectives";
    const char* sig = "[Ljava/lang/String;";
    CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, classes, sig);
    CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, classEnabled, "[Z");
    CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, packages, sig);
    CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, packageEnabled, "[Z");
    CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, deflt, "Z");
  }
  if (!valid) vm_exit_during_initialization("Hard-coded field offset verification failed");
}
#endif // PRODUCT
int InjectedField::compute_offset() {
  Klass* klass_oop = klass();
  for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
    if (!may_be_java && !fs.access_flags().is_internal()) {
      continue;
    }
    if (fs.name() == name() && fs.signature() == signature()) {
      return fs.offset();
    }
  }
  ResourceMark rm;
  tty->print_cr("Invalid layout of %s at %s/%s%s", InstanceKlass::cast(klass_oop)->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
#ifndef PRODUCT
  klass_oop->print();
  tty->print_cr("all fields:");
  for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
    tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
  }
#endif //PRODUCT
  vm_exit_during_initialization("Invalid layout of preloaded class: use -XX:+TraceClassLoading to see the origin of the problem class");
  return -1;
}
void javaClasses_init() {
  JavaClasses::compute_offsets();
  JavaClasses::check_offsets();
  FilteredFieldsMap::initialize();  // must be done after computing offsets.
}
C:\hotspot-69087d08d473\src\share\vm/classfile/javaClasses.hpp
#ifndef SHARE_VM_CLASSFILE_JAVACLASSES_HPP
#define SHARE_VM_CLASSFILE_JAVACLASSES_HPP
#include "classfile/systemDictionary.hpp"
#include "jvmtifiles/jvmti.h"
#include "oops/oop.hpp"
#include "runtime/os.hpp"
#include "utilities/utf8.hpp"
class java_lang_String : AllStatic {
 private:
  static int value_offset;
  static int offset_offset;
  static int count_offset;
  static int hash_offset;
  static bool initialized;
  static Handle basic_create(int length, TRAPS);
  static void set_offset(oop string, int offset) {
    assert(initialized, "Must be initialized");
    if (offset_offset > 0) {
      string->int_field_put(offset_offset, offset);
    }
  }
  static void set_count( oop string, int count) {
    assert(initialized, "Must be initialized");
    if (count_offset > 0) {
      string->int_field_put(count_offset,  count);
    }
  }
 public:
  static void compute_offsets();
  static Handle create_from_unicode(jchar* unicode, int len, TRAPS);
  static oop    create_oop_from_unicode(jchar* unicode, int len, TRAPS);
  static Handle create_from_str(const char* utf8_str, TRAPS);
  static oop    create_oop_from_str(const char* utf8_str, TRAPS);
  static Handle create_from_symbol(Symbol* symbol, TRAPS);
  static Handle create_from_platform_dependent_str(const char* str, TRAPS);
  static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
  static bool has_offset_field()  {
    assert(initialized, "Must be initialized");
    return (offset_offset > 0);
  }
  static bool has_count_field()  {
    assert(initialized, "Must be initialized");
    return (count_offset > 0);
  }
  static bool has_hash_field()  {
    assert(initialized, "Must be initialized");
    return (hash_offset > 0);
  }
  static int value_offset_in_bytes()  {
    assert(initialized && (value_offset > 0), "Must be initialized");
    return value_offset;
  }
  static int count_offset_in_bytes()  {
    assert(initialized && (count_offset > 0), "Must be initialized");
    return count_offset;
  }
  static int offset_offset_in_bytes() {
    assert(initialized && (offset_offset > 0), "Must be initialized");
    return offset_offset;
  }
  static int hash_offset_in_bytes()   {
    assert(initialized && (hash_offset > 0), "Must be initialized");
    return hash_offset;
  }
  static void set_value(oop string, typeArrayOop buffer) {
    assert(initialized && (value_offset > 0), "Must be initialized");
    string->obj_field_put(value_offset, (oop)buffer);
  }
  static void set_hash(oop string, unsigned int hash) {
    assert(initialized && (hash_offset > 0), "Must be initialized");
    string->int_field_put(hash_offset, hash);
  }
  static typeArrayOop value(oop java_string) {
    assert(initialized && (value_offset > 0), "Must be initialized");
    assert(is_instance(java_string), "must be java_string");
    return (typeArrayOop) java_string->obj_field(value_offset);
  }
  static unsigned int hash(oop java_string) {
    assert(initialized && (hash_offset > 0), "Must be initialized");
    assert(is_instance(java_string), "must be java_string");
    return java_string->int_field(hash_offset);
  }
  static int offset(oop java_string) {
    assert(initialized, "Must be initialized");
    assert(is_instance(java_string), "must be java_string");
    if (offset_offset > 0) {
      return java_string->int_field(offset_offset);
    } else {
      return 0;
    }
  }
  static int length(oop java_string) {
    assert(initialized, "Must be initialized");
    assert(is_instance(java_string), "must be java_string");
    if (count_offset > 0) {
      return java_string->int_field(count_offset);
    } else {
      return ((typeArrayOop)java_string->obj_field(value_offset))->length();
    }
  }
  static int utf8_length(oop java_string);
  static char*  as_utf8_string(oop java_string);
  static char*  as_utf8_string(oop java_string, char* buf, int buflen);
  static char*  as_utf8_string(oop java_string, int start, int len);
  static char*  as_platform_dependent_str(Handle java_string, TRAPS);
  static jchar* as_unicode_string(oop java_string, int& length, TRAPS);
  static char*  as_quoted_ascii(oop java_string);
  template <typename T> static unsigned int hash_code(T* s, int len) {
    unsigned int h = 0;
    while (len-- > 0) {
      h = 31*h + (unsigned int) *s;
      s++;
    }
    return h;
  }
  static unsigned int hash_code(oop java_string);
  static unsigned int hash_string(oop java_string);
  static bool equals(oop java_string, jchar* chars, int len);
  static bool equals(oop str1, oop str2);
  static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); }
  static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); }
  static Symbol* as_symbol(Handle java_string, TRAPS);
  static Symbol* as_symbol_or_null(oop java_string);
  static bool is_instance(oop obj) {
    return obj != NULL && obj->klass() == SystemDictionary::String_klass();
  }
  static void print(oop java_string, outputStream* st);
  friend class JavaClasses;
};
#define CLASS_INJECTED_FIELDS(macro)                                       \
  macro(java_lang_Class, klass,                  intptr_signature,  false) \
  macro(java_lang_Class, array_klass,            intptr_signature,  false) \
  macro(java_lang_Class, oop_size,               int_signature,     false) \
  macro(java_lang_Class, static_oop_field_count, int_signature,     false) \
  macro(java_lang_Class, protection_domain,      object_signature,  false) \
  macro(java_lang_Class, init_lock,              object_signature,  false) \
  macro(java_lang_Class, signers,                object_signature,  false)
class java_lang_Class : AllStatic {
  friend class VMStructs;
 private:
  static int _klass_offset;
  static int _array_klass_offset;
  static int _oop_size_offset;
  static int _static_oop_field_count_offset;
  static int _protection_domain_offset;
  static int _init_lock_offset;
  static int _signers_offset;
  static int _class_loader_offset;
  static bool offsets_computed;
  static int classRedefinedCount_offset;
  static GrowableArray<Klass*>* _fixup_mirror_list;
  static void set_init_lock(oop java_class, oop init_lock);
  static void set_protection_domain(oop java_class, oop protection_domain);
  static void set_class_loader(oop java_class, oop class_loader);
  static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
 public:
  static void compute_offsets();
  static void create_mirror(KlassHandle k, Handle class_loader,
                            Handle protection_domain, TRAPS);
  static void fixup_mirror(KlassHandle k, TRAPS);
  static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
  static Klass* as_Klass(oop java_class);
  static void set_klass(oop java_class, Klass* klass);
  static BasicType as_BasicType(oop java_class, Klass** reference_klass = NULL);
  static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) {
    Klass* refk_oop = NULL;
    BasicType result = as_BasicType(java_class, &refk_oop);
    (*reference_klass) = KlassHandle(refk_oop);
    return result;
  }
  static Symbol* as_signature(oop java_class, bool intern_if_not_found, TRAPS);
  static void print_signature(oop java_class, outputStream *st);
  static const char* as_external_name(oop java_class);
  static bool is_instance(oop obj) {
    return obj != NULL && obj->klass() == SystemDictionary::Class_klass();
  }
  static bool is_primitive(oop java_class);
  static BasicType primitive_type(oop java_class);
  static oop primitive_mirror(BasicType t);
  static Klass* array_klass(oop java_class);
  static void set_array_klass(oop java_class, Klass* klass);
  static int klass_offset_in_bytes()                { return _klass_offset; }
  static int array_klass_offset_in_bytes()          { return _array_klass_offset; }
  static int classRedefinedCount(oop the_class_mirror);
  static void set_classRedefinedCount(oop the_class_mirror, int value);
  static oop  protection_domain(oop java_class);
  static oop  init_lock(oop java_class);
  static objArrayOop  signers(oop java_class);
  static void set_signers(oop java_class, objArrayOop signers);
  static oop class_loader(oop java_class);
  static int oop_size(oop java_class);
  static void set_oop_size(oop java_class, int size);
  static int static_oop_field_count(oop java_class);
  static void set_static_oop_field_count(oop java_class, int size);
  static GrowableArray<Klass*>* fixup_mirror_list() {
    return _fixup_mirror_list;
  }
  static void set_fixup_mirror_list(GrowableArray<Klass*>* v) {
    _fixup_mirror_list = v;
  }
  friend class JavaClasses;
  friend class InstanceKlass;   // verification code accesses offsets
  friend class ClassFileParser; // access to number_of_fake_fields
};
class java_lang_Thread : AllStatic {
 private:
  static int _name_offset;
  static int _group_offset;
  static int _contextClassLoader_offset;
  static int _inheritedAccessControlContext_offset;
  static int _priority_offset;
  static int _eetop_offset;
  static int _daemon_offset;
  static int _stillborn_offset;
  static int _stackSize_offset;
  static int _tid_offset;
  static int _thread_status_offset;
  static int _park_blocker_offset;
  static int _park_event_offset ;
  static void compute_offsets();
 public:
  static oop create();
  static JavaThread* thread(oop java_thread);
  static void set_thread(oop java_thread, JavaThread* thread);
  static oop name(oop java_thread);
  static void set_name(oop java_thread, oop name);
  static ThreadPriority priority(oop java_thread);
  static void set_priority(oop java_thread, ThreadPriority priority);
  static oop  threadGroup(oop java_thread);
  static bool is_stillborn(oop java_thread);
  static void set_stillborn(oop java_thread);
  static bool is_alive(oop java_thread);
  static bool is_daemon(oop java_thread);
  static void set_daemon(oop java_thread);
  static oop context_class_loader(oop java_thread);
  static oop inherited_access_control_context(oop java_thread);
  static jlong stackSize(oop java_thread);
  static jlong thread_id(oop java_thread);
  static oop park_blocker(oop java_thread);
  static jlong park_event(oop java_thread);
  static bool set_park_event(oop java_thread, jlong ptr);
  enum ThreadStatus {
    NEW                      = 0,
    RUNNABLE                 = JVMTI_THREAD_STATE_ALIVE +          // runnable / running
                               JVMTI_THREAD_STATE_RUNNABLE,
    SLEEPING                 = JVMTI_THREAD_STATE_ALIVE +          // Thread.sleep()
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                               JVMTI_THREAD_STATE_SLEEPING,
    IN_OBJECT_WAIT           = JVMTI_THREAD_STATE_ALIVE +          // Object.wait()
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
                               JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
    IN_OBJECT_WAIT_TIMED     = JVMTI_THREAD_STATE_ALIVE +          // Object.wait(long)
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                               JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
    PARKED                   = JVMTI_THREAD_STATE_ALIVE +          // LockSupport.park()
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
                               JVMTI_THREAD_STATE_PARKED,
    PARKED_TIMED             = JVMTI_THREAD_STATE_ALIVE +          // LockSupport.park(long)
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                               JVMTI_THREAD_STATE_PARKED,
    BLOCKED_ON_MONITOR_ENTER = JVMTI_THREAD_STATE_ALIVE +          // (re-)entering a synchronization block
                               JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER,
    TERMINATED               = JVMTI_THREAD_STATE_TERMINATED
  };
  static void set_thread_status(oop java_thread_oop, ThreadStatus status);
  static ThreadStatus get_thread_status(oop java_thread_oop);
  static const char*  thread_status_name(oop java_thread_oop);
  friend class JavaClasses;
};
class java_lang_ThreadGroup : AllStatic {
 private:
  static int _parent_offset;
  static int _name_offset;
  static int _threads_offset;
  static int _groups_offset;
  static int _maxPriority_offset;
  static int _destroyed_offset;
  static int _daemon_offset;
  static int _vmAllowSuspension_offset;
  static int _nthreads_offset;
  static int _ngroups_offset;
  static void compute_offsets();
 public:
  static oop  parent(oop java_thread_group);
  static typeArrayOop name(oop java_thread_group);
  static int nthreads(oop java_thread_group);
  static objArrayOop threads(oop java_thread_group);
  static int ngroups(oop java_thread_group);
  static objArrayOop groups(oop java_thread_group);
  static ThreadPriority maxPriority(oop java_thread_group);
  static bool is_destroyed(oop java_thread_group);
  static bool is_daemon(oop java_thread_group);
  static bool is_vmAllowSuspension(oop java_thread_group);
  friend class JavaClasses;
};
class java_lang_Throwable: AllStatic {
  friend class BacktraceBuilder;
 private:
  enum {
    hc_backtrace_offset     =  0,
    hc_detailMessage_offset =  1,
    hc_cause_offset         =  2,  // New since 1.4
    hc_stackTrace_offset    =  3   // New since 1.4
  };
  enum {
      hc_static_unassigned_stacktrace_offset = 0  // New since 1.7
  };
  enum {
    trace_methods_offset = 0,
    trace_bcis_offset    = 1,
    trace_mirrors_offset = 2,
    trace_cprefs_offset  = 3,
    trace_next_offset    = 4,
    trace_size           = 5,
    trace_chunk_size     = 32
  };
  static int backtrace_offset;
  static int detailMessage_offset;
  static int cause_offset;
  static int stackTrace_offset;
  static int static_unassigned_stacktrace_offset;
  static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci, int cpref);
  static void clear_stacktrace(oop throwable);
  static const char* no_stack_trace_message();
  static void set_stacktrace(oop throwable, oop st_element_array);
  static oop unassigned_stacktrace();
 public:
  static oop backtrace(oop throwable);
  static void set_backtrace(oop throwable, oop value);
  static int get_backtrace_offset() { return backtrace_offset;}
  static int get_detailMessage_offset() { return detailMessage_offset;}
  static oop message(oop throwable);
  static oop message(Handle throwable);
  static void set_message(oop throwable, oop value);
  static Symbol* detail_message(oop throwable);
  static void print_stack_element(outputStream *st, Handle mirror, int method,
                                  int version, int bci, int cpref);
  static void print_stack_element(outputStream *st, methodHandle method, int bci);
  static void print_stack_usage(Handle stream);
  static void allocate_backtrace(Handle throwable, TRAPS);
  static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable);
  static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS);
  static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle());
  static oop  get_stack_trace_element(oop throwable, int index, TRAPS);
  static int  get_stack_trace_depth(oop throwable, TRAPS);
  static void print(oop throwable, outputStream* st);
  static void print(Handle throwable, outputStream* st);
  static void print_stack_trace(oop throwable, outputStream* st);
  friend class JavaClasses;
};
class java_lang_reflect_AccessibleObject: AllStatic {
 private:
  static int override_offset;
  static void compute_offsets();
 public:
  static jboolean override(oop reflect);
  static void set_override(oop reflect, jboolean value);
  friend class JavaClasses;
};
class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject {
 private:
  static int clazz_offset;
  static int name_offset;
  static int returnType_offset;
  static int parameterTypes_offset;
  static int exceptionTypes_offset;
  static int slot_offset;
  static int modifiers_offset;
  static int signature_offset;
  static int annotations_offset;
  static int parameter_annotations_offset;
  static int annotation_default_offset;
  static int type_annotations_offset;
  static void compute_offsets();
 public:
  static Handle create(TRAPS);
  static oop clazz(oop reflect);
  static void set_clazz(oop reflect, oop value);
  static oop name(oop method);
  static void set_name(oop method, oop value);
  static oop return_type(oop method);
  static void set_return_type(oop method, oop value);
  static oop parameter_types(oop method);
  static void set_parameter_types(oop method, oop value);
  static oop exception_types(oop method);
  static void set_exception_types(oop method, oop value);
  static int slot(oop reflect);
  static void set_slot(oop reflect, int value);
  static int modifiers(oop method);
  static void set_modifiers(oop method, int value);
  static bool has_signature_field();
  static oop signature(oop method);
  static void set_signature(oop method, oop value);
  static bool has_annotations_field();
  static oop annotations(oop method);
  static void set_annotations(oop method, oop value);
  static bool has_parameter_annotations_field();
  static oop parameter_annotations(oop method);
  static void set_parameter_annotations(oop method, oop value);
  static bool has_annotation_default_field();
  static oop annotation_default(oop method);
  static void set_annotation_default(oop method, oop value);
  static bool has_type_annotations_field();
  static oop type_annotations(oop method);
  static void set_type_annotations(oop method, oop value);
  friend class JavaClasses;
};
class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject {
 private:
  static int clazz_offset;
  static int parameterTypes_offset;
  static int exceptionTypes_offset;
  static int slot_offset;
  static int modifiers_offset;
  static int signature_offset;
  static int annotations_offset;
  static int parameter_annotations_offset;
  static int type_annotations_offset;
  static void compute_offsets();
 public:
  static Handle create(TRAPS);
  static oop clazz(oop reflect);
  static void set_clazz(oop reflect, oop value);
  static oop parameter_types(oop constructor);
  static void set_parameter_types(oop constructor, oop value);
  static oop exception_types(oop constructor);
  static void set_exception_types(oop constructor, oop value);
  static int slot(oop reflect);
  static void set_slot(oop reflect, int value);
  static int modifiers(oop constructor);
  static void set_modifiers(oop constructor, int value);
  static bool has_signature_field();
  static oop signature(oop constructor);
  static void set_signature(oop constructor, oop value);
  static bool has_annotations_field();
  static oop annotations(oop constructor);
  static void set_annotations(oop constructor, oop value);
  static bool has_parameter_annotations_field();
  static oop parameter_annotations(oop method);
  static void set_parameter_annotations(oop method, oop value);
  static bool has_type_annotations_field();
  static oop type_annotations(oop constructor);
  static void set_type_annotations(oop constructor, oop value);
  friend class JavaClasses;
};
class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject {
 private:
  static int clazz_offset;
  static int name_offset;
  static int type_offset;
  static int slot_offset;
  static int modifiers_offset;
  static int signature_offset;
  static int annotations_offset;
  static int type_annotations_offset;
  static void compute_offsets();
 public:
  static Handle create(TRAPS);
  static oop clazz(oop reflect);
  static void set_clazz(oop reflect, oop value);
  static oop name(oop field);
  static void set_name(oop field, oop value);
  static oop type(oop field);
  static void set_type(oop field, oop value);
  static int slot(oop reflect);
  static void set_slot(oop reflect, int value);
  static int modifiers(oop field);
  static void set_modifiers(oop field, int value);
  static bool has_signature_field();
  static oop signature(oop constructor);
  static void set_signature(oop constructor, oop value);
  static bool has_annotations_field();
  static oop annotations(oop constructor);
  static void set_annotations(oop constructor, oop value);
  static bool has_parameter_annotations_field();
  static oop parameter_annotations(oop method);
  static void set_parameter_annotations(oop method, oop value);
  static bool has_annotation_default_field();
  static oop annotation_default(oop method);
  static void set_annotation_default(oop method, oop value);
  static bool has_type_annotations_field();
  static oop type_annotations(oop field);
  static void set_type_annotations(oop field, oop value);
  friend class JavaClasses;
};
class java_lang_reflect_Parameter {
 private:
  static int name_offset;
  static int modifiers_offset;
  static int index_offset;
  static int executable_offset;
  static void compute_offsets();
 public:
  static Handle create(TRAPS);
  static oop name(oop field);
  static void set_name(oop field, oop value);
  static int index(oop reflect);
  static void set_index(oop reflect, int value);
  static int modifiers(oop reflect);
  static void set_modifiers(oop reflect, int value);
  static oop executable(oop constructor);
  static void set_executable(oop constructor, oop value);
  friend class JavaClasses;
};
class sun_reflect_ConstantPool {
 private:
  static int _oop_offset;
  static void compute_offsets();
 public:
  static Handle create(TRAPS);
  static void set_cp(oop reflect, ConstantPool* value);
  static int oop_offset() {
    return _oop_offset;
  }
  static ConstantPool* get_cp(oop reflect);
  friend class JavaClasses;
};
class sun_reflect_UnsafeStaticFieldAccessorImpl {
 private:
  static int _base_offset;
  static void compute_offsets();
 public:
  static int base_offset() {
    return _base_offset;
  }
  friend class JavaClasses;
};
class java_lang_boxing_object: AllStatic {
 private:
  enum {
   hc_value_offset = 0
  };
  static int value_offset;
  static int long_value_offset;
  static oop initialize_and_allocate(BasicType type, TRAPS);
 public:
  static oop create(BasicType type, jvalue* value, TRAPS);
  static BasicType get_value(oop box, jvalue* value);
  static BasicType set_value(oop box, jvalue* value);
  static BasicType basic_type(oop box);
  static bool is_instance(oop box)                 { return basic_type(box) != T_ILLEGAL; }
  static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
  static void print(oop box, outputStream* st)     { jvalue value;  print(get_value(box, &value), &value, st); }
  static void print(BasicType type, jvalue* value, outputStream* st);
  static int value_offset_in_bytes(BasicType type) {
    return ( type == T_LONG || type == T_DOUBLE ) ? long_value_offset :
                                                    value_offset;
  }
  friend class JavaClasses;
};
class java_lang_ref_Reference: AllStatic {
 public:
  enum {
   hc_referent_offset   = 0,
   hc_queue_offset      = 1,
   hc_next_offset       = 2,
   hc_discovered_offset = 3  // Is not last, see SoftRefs.
  };
  enum {
   hc_static_lock_offset    = 0,
   hc_static_pending_offset = 1
  };
  static int referent_offset;
  static int queue_offset;
  static int next_offset;
  static int discovered_offset;
  static int static_lock_offset;
  static int static_pending_offset;
  static int number_of_fake_oop_fields;
  static oop referent(oop ref) {
    return ref->obj_field(referent_offset);
  }
  static void set_referent(oop ref, oop value) {
    ref->obj_field_put(referent_offset, value);
  }
  static void set_referent_raw(oop ref, oop value) {
    ref->obj_field_put_raw(referent_offset, value);
  }
  static HeapWord* referent_addr(oop ref) {
    return ref->obj_field_addr<HeapWord>(referent_offset);
  }
  static oop next(oop ref) {
    return ref->obj_field(next_offset);
  }
  static void set_next(oop ref, oop value) {
    ref->obj_field_put(next_offset, value);
  }
  static void set_next_raw(oop ref, oop value) {
    ref->obj_field_put_raw(next_offset, value);
  }
  static HeapWord* next_addr(oop ref) {
    return ref->obj_field_addr<HeapWord>(next_offset);
  }
  static oop discovered(oop ref) {
    return ref->obj_field(discovered_offset);
  }
  static void set_discovered(oop ref, oop value) {
    ref->obj_field_put(discovered_offset, value);
  }
  static void set_discovered_raw(oop ref, oop value) {
    ref->obj_field_put_raw(discovered_offset, value);
  }
  static HeapWord* discovered_addr(oop ref) {
    return ref->obj_field_addr<HeapWord>(discovered_offset);
  }
  static inline oop queue(oop ref) {
    return ref->obj_field(queue_offset);
  }
  static inline void set_queue(oop ref, oop value) {
    return ref->obj_field_put(queue_offset, value);
  }
  static oop  pending_list_lock();
  static oop  pending_list();
  static HeapWord*  pending_list_lock_addr();
  static HeapWord*  pending_list_addr();
};
class java_lang_ref_SoftReference: public java_lang_ref_Reference {
 public:
  enum {
   hc_timestamp_offset  = hc_discovered_offset + 1
  };
  enum {
   hc_static_clock_offset = 0
  };
  static int timestamp_offset;
  static int static_clock_offset;
  static jlong timestamp(oop ref);
  static jlong clock();
  static void set_clock(jlong value);
};
class java_lang_ref_ReferenceQueue: public AllStatic {
public:
  static int static_NULL_queue_offset;
  static int static_ENQUEUED_queue_offset;
  static oop NULL_queue();
  static oop ENQUEUED_queue();
  static void compute_offsets();
};
class MethodHandleEntry;
class java_lang_invoke_MethodHandle: AllStatic {
  friend class JavaClasses;
 private:
  static int _type_offset;               // the MethodType of this MH
  static int _form_offset;               // the LambdaForm of this MH
  static void compute_offsets();
 public:
  static oop            type(oop mh);
  static void       set_type(oop mh, oop mtype);
  static oop            form(oop mh);
  static void       set_form(oop mh, oop lform);
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(SystemDictionary::MethodHandle_klass());
  }
  static bool is_instance(oop obj) {
    return obj != NULL && is_subclass(obj->klass());
  }
  static int type_offset_in_bytes()             { return _type_offset; }
  static int form_offset_in_bytes()             { return _form_offset; }
};
class java_lang_invoke_DirectMethodHandle: AllStatic {
  friend class JavaClasses;
 private:
  static int _member_offset;               // the MemberName of this DMH
  static void compute_offsets();
 public:
  static oop  member(oop mh);
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_klass());
  }
  static bool is_instance(oop obj) {
    return obj != NULL && is_subclass(obj->klass());
  }
  static int member_offset_in_bytes()           { return _member_offset; }
};
class java_lang_invoke_LambdaForm: AllStatic {
  friend class JavaClasses;
 private:
  static int _vmentry_offset;  // type is MemberName
  static void compute_offsets();
 public:
  static oop            vmentry(oop lform);
  static void       set_vmentry(oop lform, oop invoker);
  static bool is_subclass(Klass* klass) {
    return SystemDictionary::LambdaForm_klass() != NULL &&
      klass->is_subclass_of(SystemDictionary::LambdaForm_klass());
  }
  static bool is_instance(oop obj) {
    return obj != NULL && is_subclass(obj->klass());
  }
  static int vmentry_offset_in_bytes()          { return _vmentry_offset; }
};
#define MEMBERNAME_INJECTED_FIELDS(macro)                               \
  macro(java_lang_invoke_MemberName, vmloader, object_signature, false) \
  macro(java_lang_invoke_MemberName, vmindex,  intptr_signature, false) \
  macro(java_lang_invoke_MemberName, vmtarget, intptr_signature, false)
class java_lang_invoke_MemberName: AllStatic {
  friend class JavaClasses;
 private:
  static int _clazz_offset;
  static int _name_offset;
  static int _type_offset;
  static int _flags_offset;
  static int _vmtarget_offset;
  static int _vmloader_offset;
  static int _vmindex_offset;
  static void compute_offsets();
 public:
  static oop            clazz(oop mname);
  static void       set_clazz(oop mname, oop clazz);
  static oop            type(oop mname);
  static void       set_type(oop mname, oop type);
  static oop            name(oop mname);
  static void       set_name(oop mname, oop name);
  static int            flags(oop mname);
  static void       set_flags(oop mname, int flags);
  static Metadata*      vmtarget(oop mname);
  static void       set_vmtarget(oop mname, Metadata* target);
  static intptr_t       vmindex(oop mname);
  static void       set_vmindex(oop mname, intptr_t index);
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(SystemDictionary::MemberName_klass());
  }
  static bool is_instance(oop obj) {
    return obj != NULL && is_subclass(obj->klass());
  }
  static bool is_method(oop obj);
  enum {
    MN_IS_METHOD            = 0x00010000, // method (not constructor)
    MN_IS_CONSTRUCTOR       = 0x00020000, // constructor
    MN_IS_FIELD             = 0x00040000, // field
    MN_IS_TYPE              = 0x00080000, // nested type
    MN_CALLER_SENSITIVE     = 0x00100000, // @CallerSensitive annotation detected
    MN_REFERENCE_KIND_SHIFT = 24, // refKind
    MN_REFERENCE_KIND_MASK  = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
    MN_SEARCH_SUPERCLASSES  = 0x00100000, // walk super classes
    MN_SEARCH_INTERFACES    = 0x00200000  // walk implemented interfaces
  };
  static int clazz_offset_in_bytes()            { return _clazz_offset; }
  static int type_offset_in_bytes()             { return _type_offset; }
  static int name_offset_in_bytes()             { return _name_offset; }
  static int flags_offset_in_bytes()            { return _flags_offset; }
  static int vmtarget_offset_in_bytes()         { return _vmtarget_offset; }
  static int vmindex_offset_in_bytes()          { return _vmindex_offset; }
  static bool equals(oop mt1, oop mt2);
};
class java_lang_invoke_MethodType: AllStatic {
  friend class JavaClasses;
 private:
  static int _rtype_offset;
  static int _ptypes_offset;
  static void compute_offsets();
 public:
  static oop            rtype(oop mt);
  static objArrayOop    ptypes(oop mt);
  static oop            ptype(oop mt, int index);
  static int            ptype_count(oop mt);
  static int            ptype_slot_count(oop mt);  // extra counts for long/double
  static int            rtype_slot_count(oop mt);  // extra counts for long/double
  static Symbol*        as_signature(oop mt, bool intern_if_not_found, TRAPS);
  static void           print_signature(oop mt, outputStream* st);
  static bool is_instance(oop obj) {
    return obj != NULL && obj->klass() == SystemDictionary::MethodType_klass();
  }
  static bool equals(oop mt1, oop mt2);
  static int rtype_offset_in_bytes()            { return _rtype_offset; }
  static int ptypes_offset_in_bytes()           { return _ptypes_offset; }
};
class java_lang_invoke_CallSite: AllStatic {
  friend class JavaClasses;
private:
  static int _target_offset;
  static void compute_offsets();
public:
  static oop              target(         oop site)             { return site->obj_field(             _target_offset);         }
  static void         set_target(         oop site, oop target) {        site->obj_field_put(         _target_offset, target); }
  static volatile oop     target_volatile(oop site)             { return oop((oopDesc *)(site->obj_field_volatile(_target_offset))); }
  static void         set_target_volatile(oop site, oop target) {        site->obj_field_put_volatile(_target_offset, target); }
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(SystemDictionary::CallSite_klass());
  }
  static bool is_instance(oop obj) {
    return obj != NULL && is_subclass(obj->klass());
  }
  static int target_offset_in_bytes()           { return _target_offset; }
};
class java_security_AccessControlContext: AllStatic {
 private:
  static int _context_offset;
  static int _privilegedContext_offset;
  static int _isPrivileged_offset;
  static int _isAuthorized_offset;
  static void compute_offsets();
 public:
  static oop create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS);
  static bool is_authorized(Handle context);
  friend class JavaClasses;
};
#define CLASSLOADER_INJECTED_FIELDS(macro)                            \
  macro(java_lang_ClassLoader, loader_data,  intptr_signature, false)
class java_lang_ClassLoader : AllStatic {
 private:
  enum {
   hc_parent_offset = 0
  };
  static int _loader_data_offset;
  static bool offsets_computed;
  static int parent_offset;
  static int parallelCapable_offset;
 public:
  static void compute_offsets();
  static ClassLoaderData** loader_data_addr(oop loader);
  static ClassLoaderData* loader_data(oop loader);
  static oop parent(oop loader);
  static bool isAncestor(oop loader, oop cl);
  static bool parallelCapable(oop the_class_mirror);
  static bool is_trusted_loader(oop loader);
  static oop  non_reflection_class_loader(oop loader);
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(SystemDictionary::ClassLoader_klass());
  }
  static bool is_instance(oop obj) {
    return obj != NULL && is_subclass(obj->klass());
  }
  friend class JavaClasses;
  friend class ClassFileParser; // access to number_of_fake_fields
};
class java_lang_System : AllStatic {
 private:
  enum {
   hc_static_in_offset  = 0,
   hc_static_out_offset = 1,
   hc_static_err_offset = 2,
   hc_static_security_offset = 3
  };
  static int  static_in_offset;
  static int static_out_offset;
  static int static_err_offset;
  static int static_security_offset;
 public:
  static int  in_offset_in_bytes();
  static int out_offset_in_bytes();
  static int err_offset_in_bytes();
  static bool has_security_manager();
  friend class JavaClasses;
};
class java_lang_StackTraceElement: AllStatic {
 private:
  enum {
    hc_declaringClass_offset  = 0,
    hc_methodName_offset = 1,
    hc_fileName_offset   = 2,
    hc_lineNumber_offset = 3
  };
  static int declaringClass_offset;
  static int methodName_offset;
  static int fileName_offset;
  static int lineNumber_offset;
 public:
  static void set_declaringClass(oop element, oop value);
  static void set_methodName(oop element, oop value);
  static void set_fileName(oop element, oop value);
  static void set_lineNumber(oop element, int value);
  static oop create(Handle mirror, int method, int version, int bci, int cpref, TRAPS);
  static oop create(methodHandle method, int bci, TRAPS);
  friend class JavaClasses;
};
class java_lang_AssertionStatusDirectives: AllStatic {
 private:
  enum {
    hc_classes_offset,
    hc_classEnabled_offset,
    hc_packages_offset,
    hc_packageEnabled_offset,
    hc_deflt_offset
  };
  static int classes_offset;
  static int classEnabled_offset;
  static int packages_offset;
  static int packageEnabled_offset;
  static int deflt_offset;
 public:
  static void set_classes(oop obj, oop val);
  static void set_classEnabled(oop obj, oop val);
  static void set_packages(oop obj, oop val);
  static void set_packageEnabled(oop obj, oop val);
  static void set_deflt(oop obj, bool val);
  friend class JavaClasses;
};
class java_nio_Buffer: AllStatic {
 private:
  static int _limit_offset;
 public:
  static int  limit_offset();
  static void compute_offsets();
};
class java_util_concurrent_locks_AbstractOwnableSynchronizer : AllStatic {
 private:
  static int  _owner_offset;
 public:
  static void initialize(TRAPS);
  static oop  get_owner_threadObj(oop obj);
};
class InjectedField {
 public:
  const SystemDictionary::WKID klass_id;
  const vmSymbols::SID name_index;
  const vmSymbols::SID signature_index;
  const bool           may_be_java;
  Klass* klass() const    { return SystemDictionary::well_known_klass(klass_id); }
  Symbol* name() const      { return lookup_symbol(name_index); }
  Symbol* signature() const { return lookup_symbol(signature_index); }
  int compute_offset();
  static Symbol* lookup_symbol(int symbol_index) {
    return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
  }
};
#define DECLARE_INJECTED_FIELD_ENUM(klass, name, signature, may_be_java) \
  klass##_##name##_enum,
#define ALL_INJECTED_FIELDS(macro)          \
  CLASS_INJECTED_FIELDS(macro)              \
  CLASSLOADER_INJECTED_FIELDS(macro)        \
  MEMBERNAME_INJECTED_FIELDS(macro)
class JavaClasses : AllStatic {
 private:
  static InjectedField _injected_fields[];
  static bool check_offset(const char *klass_name, int offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
  static bool check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
  static bool check_constant(const char *klass_name, int constant, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
 public:
  enum InjectedFieldID {
    ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD_ENUM)
    MAX_enum
  };
  static int compute_injected_offset(InjectedFieldID id);
  static void compute_hard_coded_offsets();
  static void compute_offsets();
  static void check_offsets() PRODUCT_RETURN;
  static InjectedField* get_injected(Symbol* class_name, int* field_count);
};
#undef DECLARE_INJECTED_FIELD_ENUM
#endif // SHARE_VM_CLASSFILE_JAVACLASSES_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/loaderConstraints.cpp
#include "precompiled.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/loaderConstraints.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/safepoint.hpp"
#include "utilities/hashtable.inline.hpp"
void LoaderConstraintEntry::set_loader(int i, oop p) {
  set_loader_data(i, ClassLoaderData::class_loader_data(p));
}
LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
  : Hashtable<Klass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
LoaderConstraintEntry* LoaderConstraintTable::new_entry(
                                 unsigned int hash, Symbol* name,
                                 Klass* klass, int num_loaders,
                                 int max_loaders) {
  LoaderConstraintEntry* entry;
  entry = (LoaderConstraintEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass);
  entry->set_name(name);
  entry->set_num_loaders(num_loaders);
  entry->set_max_loaders(max_loaders);
  return entry;
}
void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
  entry->name()->decrement_refcount();
  Hashtable<Klass*, mtClass>::free_entry(entry);
}
void LoaderConstraintTable::classes_do(KlassClosure* f) {
  for (int index = 0; index < table_size(); index++) {
    for (LoaderConstraintEntry* probe = bucket(index);
                                probe != NULL;
                                probe = probe->next()) {
      if (probe->klass() != NULL) {
        f->do_klass(probe->klass());
      }
        }
      }
    }
LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
                                    Symbol* name, Handle loader) {
  unsigned int hash = compute_hash(name);
  int index = hash_to_index(hash);
  LoaderConstraintEntry** pp = bucket_addr(index);
  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
  while (*pp) {
    LoaderConstraintEntry* p = *pp;
    if (p->hash() == hash) {
      if (p->name() == name) {
        for (int i = p->num_loaders() - 1; i >= 0; i--) {
          if (p->loader_data(i) == loader_data) {
            return pp;
          }
        }
      }
    }
    pp = p->next_addr();
  }
  return pp;
}
void LoaderConstraintTable::purge_loader_constraints() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  for (int index = 0; index < table_size(); index++) {
    LoaderConstraintEntry** p = bucket_addr(index);
    while(*p) {
      LoaderConstraintEntry* probe = *p;
      Klass* klass = probe->klass();
      if (klass != NULL &&
          klass->class_loader_data()->is_unloading()) {
        probe->set_klass(NULL);
        if (TraceLoaderConstraints) {
          ResourceMark rm;
          tty->print_cr("[Purging class object from constraint for name %s,"
                     " loader list:",
                     probe->name()->as_C_string());
          for (int i = 0; i < probe->num_loaders(); i++) {
            tty->print_cr("[   [%d]: %s", i,
                          probe->loader_data(i)->loader_name());
          }
        }
      }
      int n = 0;
      while (n < probe->num_loaders()) {
        if (probe->loader_data(n)->is_unloading()) {
            if (TraceLoaderConstraints) {
              ResourceMark rm;
              tty->print_cr("[Purging loader %s from constraint for name %s",
                            probe->loader_data(n)->loader_name(),
                            probe->name()->as_C_string()
                            );
            }
            int num = probe->num_loaders() - 1;
            probe->set_num_loaders(num);
          probe->set_loader_data(n, probe->loader_data(num));
          probe->set_loader_data(num, NULL);
            if (TraceLoaderConstraints) {
              ResourceMark rm;
              tty->print_cr("[New loader list:");
              for (int i = 0; i < probe->num_loaders(); i++) {
                tty->print_cr("[   [%d]: %s", i,
                              probe->loader_data(i)->loader_name());
              }
            }
            continue;  // current element replaced, so restart without
          }
        n++;
      }
      if (probe->num_loaders() < 2) {
            if (TraceLoaderConstraints) {
              ResourceMark rm;
              tty->print("[Purging complete constraint for name %s\n",
                         probe->name()->as_C_string());
            }
        FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass);
        free_entry(probe);
      } else {
#ifdef ASSERT
        if (probe->klass() != NULL) {
          ClassLoaderData* loader_data =
            probe->klass()->class_loader_data();
          assert(!loader_data->is_unloading(), "klass should be live");
        }
#endif
        p = probe->next_addr();
      }
    }
  }
}
bool LoaderConstraintTable::add_entry(Symbol* class_name,
                                      Klass* klass1, Handle class_loader1,
                                      Klass* klass2, Handle class_loader2) {
  int failure_code = 0; // encode different reasons for failing
  if (klass1 != NULL && klass2 != NULL && klass1 != klass2) {
    failure_code = 1;
  } else {
    Klass* klass = klass1 != NULL ? klass1 : klass2;
    LoaderConstraintEntry** pp1 = find_loader_constraint(class_name,
                                                         class_loader1);
    if (*pp1 != NULL && (*pp1)->klass() != NULL) {
      if (klass != NULL) {
        if (klass != (*pp1)->klass()) {
          failure_code = 2;
        }
      } else {
        klass = (*pp1)->klass();
      }
    }
    LoaderConstraintEntry** pp2 = find_loader_constraint(class_name,
                                                         class_loader2);
    if (*pp2 != NULL && (*pp2)->klass() != NULL) {
      if (klass != NULL) {
        if (klass != (*pp2)->klass()) {
          failure_code = 3;
        }
      } else {
        klass = (*pp2)->klass();
      }
    }
    if (failure_code == 0) {
      if (*pp1 == NULL && *pp2 == NULL) {
        unsigned int hash = compute_hash(class_name);
        int index = hash_to_index(hash);
        LoaderConstraintEntry* p;
        p = new_entry(hash, class_name, klass, 2, 2);
        p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
        p->set_loader(0, class_loader1());
        p->set_loader(1, class_loader2());
        p->set_klass(klass);
        p->set_next(bucket(index));
        set_entry(index, p);
        if (TraceLoaderConstraints) {
          ResourceMark rm;
          tty->print("[Adding new constraint for name: %s, loader[0]: %s,"
                     " loader[1]: %s ]\n",
                     class_name->as_C_string(),
                     SystemDictionary::loader_name(class_loader1()),
                     SystemDictionary::loader_name(class_loader2())
                     );
        }
      } else if (*pp1 == *pp2) {
        if ((*pp1)->klass() == NULL) {
          (*pp1)->set_klass(klass);
          if (TraceLoaderConstraints) {
            ResourceMark rm;
            tty->print("[Setting class object in existing constraint for"
                       " name: %s and loader %s ]\n",
                       class_name->as_C_string(),
                       SystemDictionary::loader_name(class_loader1())
                       );
          }
        } else {
          assert((*pp1)->klass() == klass, "loader constraints corrupted");
        }
      } else if (*pp1 == NULL) {
        extend_loader_constraint(*pp2, class_loader1, klass);
      } else if (*pp2 == NULL) {
        extend_loader_constraint(*pp1, class_loader2, klass);
      } else {
        merge_loader_constraints(pp1, pp2, klass);
      }
    }
  }
  if (failure_code != 0 && TraceLoaderConstraints) {
    ResourceMark rm;
    const char* reason = "";
    switch(failure_code) {
    case 1: reason = "the class objects presented by loader[0] and loader[1]"
              " are different"; break;
    case 2: reason = "the class object presented by loader[0] does not match"
              " the stored class object in the constraint"; break;
    case 3: reason = "the class object presented by loader[1] does not match"
              " the stored class object in the constraint"; break;
    default: reason = "unknown reason code";
    }
    tty->print("[Failed to add constraint for name: %s, loader[0]: %s,"
               " loader[1]: %s, Reason: %s ]\n",
               class_name->as_C_string(),
               SystemDictionary::loader_name(class_loader1()),
               SystemDictionary::loader_name(class_loader2()),
               reason
               );
  }
  return failure_code == 0;
}
bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
                                                   Handle loader,
                                                   Symbol* name) {
  LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
  if (p && p->klass() != NULL && p->klass() != k()) {
    if (TraceLoaderConstraints) {
      ResourceMark rm;
      tty->print("[Constraint check failed for name %s, loader %s: "
                 "the presented class object differs from that stored ]\n",
                 name->as_C_string(),
                 SystemDictionary::loader_name(loader()));
    }
    return false;
  } else {
    if (p && p->klass() == NULL) {
      p->set_klass(k());
      if (TraceLoaderConstraints) {
        ResourceMark rm;
        tty->print("[Updating constraint for name %s, loader %s, "
                   "by setting class object ]\n",
                   name->as_C_string(),
                   SystemDictionary::loader_name(loader()));
      }
    }
    return true;
  }
}
Klass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
                                                       Handle loader) {
  LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
  if (p != NULL && p->klass() != NULL) {
    if (p->klass()->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
      return NULL;
    }
    return p->klass();
  }
  return NULL;
}
void LoaderConstraintTable::ensure_loader_constraint_capacity(
                                                     LoaderConstraintEntry *p,
                                                    int nfree) {
    if (p->max_loaders() - p->num_loaders() < nfree) {
        int n = nfree + p->num_loaders();
        ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
        memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
        p->set_max_loaders(n);
        FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass);
        p->set_loaders(new_loaders);
    }
}
void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
                                                     Handle loader,
                                                     Klass* klass) {
  ensure_loader_constraint_capacity(p, 1);
  int num = p->num_loaders();
  p->set_loader(num, loader());
  p->set_num_loaders(num + 1);
  if (TraceLoaderConstraints) {
    ResourceMark rm;
    tty->print("[Extending constraint for name %s by adding loader[%d]: %s %s",
               p->name()->as_C_string(),
               num,
               SystemDictionary::loader_name(loader()),
               (p->klass() == NULL ? " and setting class object ]\n" : " ]\n")
               );
  }
  if (p->klass() == NULL) {
    p->set_klass(klass);
  } else {
    assert(klass == NULL || p->klass() == klass, "constraints corrupted");
  }
}
void LoaderConstraintTable::merge_loader_constraints(
                                                   LoaderConstraintEntry** pp1,
                                                   LoaderConstraintEntry** pp2,
                                                   Klass* klass) {
  if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
    LoaderConstraintEntry** tmp = pp2;
    pp2 = pp1;
    pp1 = tmp;
  }
  LoaderConstraintEntry* p1 = *pp1;
  LoaderConstraintEntry* p2 = *pp2;
  ensure_loader_constraint_capacity(p1, p2->num_loaders());
  for (int i = 0; i < p2->num_loaders(); i++) {
    int num = p1->num_loaders();
    p1->set_loader_data(num, p2->loader_data(i));
    p1->set_num_loaders(num + 1);
  }
  if (TraceLoaderConstraints) {
    ResourceMark rm;
    tty->print_cr("[Merged constraints for name %s, new loader list:",
                  p1->name()->as_C_string()
                  );
    for (int i = 0; i < p1->num_loaders(); i++) {
      tty->print_cr("[   [%d]: %s", i,
                    p1->loader_data(i)->loader_name());
    }
    if (p1->klass() == NULL) {
      tty->print_cr("[... and setting class object]");
    }
  }
  if (p2->klass() != NULL) {
    assert(p2->klass() == klass, "constraints corrupted");
  }
  if (p1->klass() == NULL) {
    p1->set_klass(klass);
  } else {
    assert(p1->klass() == klass, "constraints corrupted");
  }
  FREE_C_HEAP_ARRAY(oop, p2->loaders(), mtClass);
  free_entry(p2);
  return;
}
void LoaderConstraintTable::verify(Dictionary* dictionary,
                                   PlaceholderTable* placeholders) {
  Thread *thread = Thread::current();
  for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
    for (LoaderConstraintEntry* probe = bucket(cindex);
                                probe != NULL;
                                probe = probe->next()) {
      if (probe->klass() != NULL) {
        InstanceKlass* ik = InstanceKlass::cast(probe->klass());
        guarantee(ik->name() == probe->name(), "name should match");
        Symbol* name = ik->name();
        ClassLoaderData* loader_data = ik->class_loader_data();
        unsigned int d_hash = dictionary->compute_hash(name, loader_data);
        int d_index = dictionary->hash_to_index(d_hash);
        Klass* k = dictionary->find_class(d_index, d_hash, name, loader_data);
        if (k != NULL) {
          guarantee(k == probe->klass(), "klass should be in dictionary");
        } else {
          unsigned int p_hash = placeholders->compute_hash(name, loader_data);
          int p_index = placeholders->hash_to_index(p_hash);
          PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash,
                                                            name, loader_data);
          guarantee(entry != NULL, "klass should be in the placeholders");
        }
      }
      for (int n = 0; n< probe->num_loaders(); n++) {
        assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing");
      }
    }
  }
}
#ifndef PRODUCT
void LoaderConstraintTable::print() {
  ResourceMark rm;
  assert_locked_or_safepoint(SystemDictionary_lock);
  tty->print_cr("Java loader constraints (entries=%d)", _loader_constraint_size);
  for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
    for (LoaderConstraintEntry* probe = bucket(cindex);
                                probe != NULL;
                                probe = probe->next()) {
      tty->print("%4d: ", cindex);
      probe->name()->print();
      tty->print(" , loaders:");
      for (int n = 0; n < probe->num_loaders(); n++) {
        probe->loader_data(n)->print_value();
        tty->print(", ");
      }
      tty->cr();
    }
  }
}
#endif
C:\hotspot-69087d08d473\src\share\vm/classfile/loaderConstraints.hpp
#ifndef SHARE_VM_CLASSFILE_LOADERCONSTRAINTS_HPP
#define SHARE_VM_CLASSFILE_LOADERCONSTRAINTS_HPP
#include "classfile/dictionary.hpp"
#include "classfile/placeholders.hpp"
#include "utilities/hashtable.hpp"
class LoaderConstraintEntry;
class Symbol;
class LoaderConstraintTable : public Hashtable<Klass*, mtClass> {
  friend class VMStructs;
private:
  enum Constants {
    _loader_constraint_size = 107,                     // number of entries in constraint table
    _nof_buckets            = 1009                     // number of buckets in hash table
  };
  LoaderConstraintEntry** find_loader_constraint(Symbol* name,
                                                 Handle loader);
public:
  LoaderConstraintTable(int nof_buckets);
  LoaderConstraintEntry* new_entry(unsigned int hash, Symbol* name,
                                   Klass* klass, int num_loaders,
                                   int max_loaders);
  void free_entry(LoaderConstraintEntry *entry);
  LoaderConstraintEntry* bucket(int i) {
    return (LoaderConstraintEntry*)Hashtable<Klass*, mtClass>::bucket(i);
  }
  LoaderConstraintEntry** bucket_addr(int i) {
    return (LoaderConstraintEntry**)Hashtable<Klass*, mtClass>::bucket_addr(i);
  }
  void classes_do(KlassClosure* f);
  bool add_entry(Symbol* name, Klass* klass1, Handle loader1,
                                    Klass* klass2, Handle loader2);
  Klass* find_constrained_klass(Symbol* name, Handle loader);
  void ensure_loader_constraint_capacity(LoaderConstraintEntry *p, int nfree);
  void extend_loader_constraint(LoaderConstraintEntry* p, Handle loader,
                                Klass* klass);
  void merge_loader_constraints(LoaderConstraintEntry** pp1,
                                LoaderConstraintEntry** pp2, Klass* klass);
  bool check_or_update(instanceKlassHandle k, Handle loader,
                              Symbol* name);
  void purge_loader_constraints();
  void verify(Dictionary* dictionary, PlaceholderTable* placeholders);
#ifndef PRODUCT
  void print();
#endif
};
class LoaderConstraintEntry : public HashtableEntry<Klass*, mtClass> {
  friend class VMStructs;
private:
  Symbol*                _name;                   // class name
  int                    _num_loaders;
  int                    _max_loaders;
  ClassLoaderData**              _loaders;                // initiating loaders
public:
  Klass* klass() { return literal(); }
  Klass** klass_addr() { return literal_addr(); }
  void set_klass(Klass* k) { set_literal(k); }
  LoaderConstraintEntry* next() {
    return (LoaderConstraintEntry*)HashtableEntry<Klass*, mtClass>::next();
  }
  LoaderConstraintEntry** next_addr() {
    return (LoaderConstraintEntry**)HashtableEntry<Klass*, mtClass>::next_addr();
  }
  void set_next(LoaderConstraintEntry* next) {
    HashtableEntry<Klass*, mtClass>::set_next(next);
  }
  Symbol* name() { return _name; }
  void set_name(Symbol* name) {
    _name = name;
    if (name != NULL) name->increment_refcount();
  }
  int num_loaders() { return _num_loaders; }
  void set_num_loaders(int i) { _num_loaders = i; }
  int max_loaders() { return _max_loaders; }
  void set_max_loaders(int i) { _max_loaders = i; }
  ClassLoaderData** loaders() { return _loaders; }
  void set_loaders(ClassLoaderData** loaders) { _loaders = loaders; }
  ClassLoaderData* loader_data(int i) { return _loaders[i]; }
  void set_loader_data(int i, ClassLoaderData* p) { _loaders[i] = p; }
  void set_loader(int i, oop p);
};
#endif // SHARE_VM_CLASSFILE_LOADERCONSTRAINTS_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/metadataOnStackMark.cpp
#include "precompiled.hpp"
#include "classfile/metadataOnStackMark.hpp"
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
#include "oops/metadata.hpp"
#include "prims/jvmtiImpl.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.hpp"
#include "services/threadService.hpp"
#include "utilities/chunkedList.hpp"
volatile MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
volatile MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL;
NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
MetadataOnStackMark::MetadataOnStackMark(bool has_redefined_a_class) {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
  assert(_used_buffers == NULL, "sanity check");
  NOT_PRODUCT(_is_active = true;)
  Threads::metadata_do(Metadata::mark_on_stack);
  if (has_redefined_a_class) {
    CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
  }
  CompileBroker::mark_on_stack();
  JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
  ThreadService::metadata_do(Metadata::mark_on_stack);
}
MetadataOnStackMark::~MetadataOnStackMark() {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
  retire_buffer_for_thread(Thread::current());
  MetadataOnStackBuffer* buffer = const_cast<MetadataOnStackBuffer* >(_used_buffers);
  while (buffer != NULL) {
    size_t size = buffer->size();
    for (size_t i  = 0; i < size; i++) {
      Metadata* md = buffer->at(i);
      md->set_on_stack(false);
    }
    MetadataOnStackBuffer* next = buffer->next_used();
    buffer->clear();
    buffer->set_next_used(NULL);
    buffer->set_next_free(const_cast<MetadataOnStackBuffer*>(_free_buffers));
    _free_buffers = buffer;
    buffer = next;
  }
  _used_buffers = NULL;
  NOT_PRODUCT(_is_active = false;)
}
void MetadataOnStackMark::retire_buffer(MetadataOnStackBuffer* buffer) {
  if (buffer == NULL) {
    return;
  }
  MetadataOnStackBuffer* old_head;
  do {
    old_head = const_cast<MetadataOnStackBuffer*>(_used_buffers);
    buffer->set_next_used(old_head);
  } while (Atomic::cmpxchg_ptr(buffer, &_used_buffers, old_head) != old_head);
}
void MetadataOnStackMark::retire_buffer_for_thread(Thread* thread) {
  retire_buffer(thread->metadata_on_stack_buffer());
  thread->set_metadata_on_stack_buffer(NULL);
}
bool MetadataOnStackMark::has_buffer_for_thread(Thread* thread) {
  return thread->metadata_on_stack_buffer() != NULL;
}
MetadataOnStackBuffer* MetadataOnStackMark::allocate_buffer() {
  MetadataOnStackBuffer* allocated;
  MetadataOnStackBuffer* new_head;
  do {
    allocated = const_cast<MetadataOnStackBuffer*>(_free_buffers);
    if (allocated == NULL) {
      break;
    }
    new_head = allocated->next_free();
  } while (Atomic::cmpxchg_ptr(new_head, &_free_buffers, allocated) != allocated);
  if (allocated == NULL) {
    allocated = new MetadataOnStackBuffer();
  }
  assert(!allocated->is_full(), err_msg("Should not be full: " PTR_FORMAT, p2i(allocated)));
  return allocated;
}
void MetadataOnStackMark::record(Metadata* m, Thread* thread) {
  assert(_is_active, "metadata on stack marking is active");
  MetadataOnStackBuffer* buffer =  thread->metadata_on_stack_buffer();
  if (buffer != NULL && buffer->is_full()) {
    retire_buffer(buffer);
    buffer = NULL;
  }
  if (buffer == NULL) {
    buffer = allocate_buffer();
    thread->set_metadata_on_stack_buffer(buffer);
  }
  buffer->push(m);
}
C:\hotspot-69087d08d473\src\share\vm/classfile/metadataOnStackMark.hpp
#ifndef SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
#define SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
#include "memory/allocation.hpp"
#include "utilities/chunkedList.hpp"
class Metadata;
typedef ChunkedList<Metadata*, mtInternal> MetadataOnStackBuffer;
class MetadataOnStackMark : public StackObj {
  NOT_PRODUCT(static bool _is_active;)
  static volatile MetadataOnStackBuffer* _used_buffers;
  static volatile MetadataOnStackBuffer* _free_buffers;
  static MetadataOnStackBuffer* allocate_buffer();
  static void retire_buffer(MetadataOnStackBuffer* buffer);
 public:
  MetadataOnStackMark(bool has_redefined_a_class);
   ~MetadataOnStackMark();
  static void record(Metadata* m, Thread* thread);
  static void retire_buffer_for_thread(Thread* thread);
  static bool has_buffer_for_thread(Thread* thread);
};
#endif // SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/placeholders.cpp
#include "precompiled.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/systemDictionary.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldType.hpp"
#include "utilities/hashtable.inline.hpp"
PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
                                              ClassLoaderData* loader_data,
                                              bool havesupername,
                                              Symbol* supername) {
  PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
  name->increment_refcount();
  entry->set_loader_data(loader_data);
  entry->set_havesupername(havesupername);
  entry->set_supername(supername);
  entry->set_superThreadQ(NULL);
  entry->set_loadInstanceThreadQ(NULL);
  entry->set_defineThreadQ(NULL);
  entry->set_definer(NULL);
  entry->set_instance_klass(NULL);
  return entry;
}
void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
  entry->literal()->decrement_refcount();
  if (entry->supername() != NULL) entry->supername()->decrement_refcount();
  Hashtable<Symbol*, mtClass>::free_entry(entry);
}
void PlaceholderTable::add_entry(int index, unsigned int hash,
                                 Symbol* class_name, ClassLoaderData* loader_data,
                                 bool havesupername, Symbol* supername){
  assert_locked_or_safepoint(SystemDictionary_lock);
  assert(class_name != NULL, "adding NULL obj");
  PlaceholderEntry* entry = new_entry(hash, class_name, loader_data, havesupername, supername);
  add_entry(index, entry);
}
void PlaceholderTable::remove_entry(int index, unsigned int hash,
                                    Symbol* class_name,
                                    ClassLoaderData* loader_data) {
  assert_locked_or_safepoint(SystemDictionary_lock);
  PlaceholderEntry** p = bucket_addr(index);
  while (*p) {
    PlaceholderEntry *probe = *p;
    if (probe->hash() == hash && probe->equals(class_name, loader_data)) {
      free_entry(probe);
      return;
    }
    p = probe->next_addr();
  }
}
PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
                                       Symbol* class_name,
                                       ClassLoaderData* loader_data) {
  assert_locked_or_safepoint(SystemDictionary_lock);
  for (PlaceholderEntry *place_probe = bucket(index);
                         place_probe != NULL;
                         place_probe = place_probe->next()) {
    if (place_probe->hash() == hash &&
        place_probe->equals(class_name, loader_data)) {
      return place_probe;
    }
  }
  return NULL;
}
Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
                                       Symbol* class_name,
                                       ClassLoaderData* loader_data) {
  PlaceholderEntry* probe = get_entry(index, hash, class_name, loader_data);
  return (probe? probe->klassname(): (Symbol*)NULL);
}
PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
                                                 Symbol* name,
                                                 ClassLoaderData* loader_data,
                                                 classloadAction action,
                                                 Symbol* supername,
                                                 Thread* thread) {
  PlaceholderEntry* probe = get_entry(index, hash, name, loader_data);
  if (probe == NULL) {
    add_entry(index, hash, name, loader_data, (action == LOAD_SUPER), supername);
    probe = get_entry(index, hash, name, loader_data);
  } else {
    if (action == LOAD_SUPER) {
      probe->set_havesupername(true);
      probe->set_supername(supername);
    }
  }
  if (probe) probe->add_seen_thread(thread, action);
  return probe;
}
void PlaceholderTable::find_and_remove(int index, unsigned int hash,
                                       Symbol* name, ClassLoaderData* loader_data,
                                       classloadAction action,
                                       Thread* thread) {
    assert_locked_or_safepoint(SystemDictionary_lock);
    PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
    if (probe != NULL) {
       probe->remove_seen_thread(thread, action);
       if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
          && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
         remove_entry(index, hash, name, loader_data);
       }
    }
  }
PlaceholderTable::PlaceholderTable(int table_size)
    : TwoOopHashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
}
void PlaceholderTable::classes_do(KlassClosure* f) {
  for (int index = 0; index < table_size(); index++) {
    for (PlaceholderEntry* probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
      probe->classes_do(f);
    }
  }
}
void PlaceholderEntry::classes_do(KlassClosure* closure) {
  assert(klassname() != NULL, "should have a non-null klass");
  if (_instanceKlass != NULL) {
    closure->do_klass(instance_klass());
  }
}
void PlaceholderTable::entries_do(void f(Symbol*)) {
  for (int index = 0; index < table_size(); index++) {
    for (PlaceholderEntry* probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
      f(probe->klassname());
    }
  }
}
#ifndef PRODUCT
void PlaceholderEntry::print() const {
  klassname()->print_value();
  if (loader_data() != NULL) {
    tty->print(", loader ");
    loader_data()->print_value();
  }
  if (supername() != NULL) {
    tty->print(", supername ");
    supername()->print_value();
  }
  if (definer() != NULL) {
    tty->print(", definer ");
    definer()->print_value();
  }
  if (instance_klass() != NULL) {
    tty->print(", InstanceKlass ");
    instance_klass()->print_value();
  }
  tty->print("\n");
  tty->print("loadInstanceThreadQ threads:");
  loadInstanceThreadQ()->printActionQ();
  tty->print("\n");
  tty->print("superThreadQ threads:");
  superThreadQ()->printActionQ();
  tty->print("\n");
  tty->print("defineThreadQ threads:");
  defineThreadQ()->printActionQ();
  tty->print("\n");
}
#endif
void PlaceholderEntry::verify() const {
  guarantee(loader_data() != NULL, "Must have been setup.");
  guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
            "checking type of _loader");
  guarantee(instance_klass() == NULL
            || instance_klass()->oop_is_instance(),
            "checking type of instance_klass result");
}
void PlaceholderTable::verify() {
  int element_count = 0;
  for (int pindex = 0; pindex < table_size(); pindex++) {
    for (PlaceholderEntry* probe = bucket(pindex);
                           probe != NULL;
                           probe = probe->next()) {
      probe->verify();
      element_count++;  // both klasses and place holders count
    }
  }
  guarantee(number_of_entries() == element_count,
            "Verify of system dictionary failed");
}
#ifndef PRODUCT
void PlaceholderTable::print() {
  for (int pindex = 0; pindex < table_size(); pindex++) {
    for (PlaceholderEntry* probe = bucket(pindex);
                           probe != NULL;
                           probe = probe->next()) {
      if (Verbose) tty->print("%4d: ", pindex);
      tty->print(" place holder ");
      probe->print();
      tty->cr();
    }
  }
}
#endif
C:\hotspot-69087d08d473\src\share\vm/classfile/placeholders.hpp
#ifndef SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
#define SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
#include "runtime/thread.hpp"
#include "utilities/hashtable.hpp"
class PlaceholderEntry;
class PlaceholderTable : public TwoOopHashtable<Symbol*, mtClass> {
  friend class VMStructs;
public:
  PlaceholderTable(int table_size);
  PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
  void free_entry(PlaceholderEntry* entry);
  PlaceholderEntry* bucket(int i) {
    return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
  }
  PlaceholderEntry** bucket_addr(int i) {
    return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
  }
  void add_entry(int index, PlaceholderEntry* new_entry) {
    Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry);
  }
  void add_entry(int index, unsigned int hash, Symbol* name,
                ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
  Symbol* find_entry(int index, unsigned int hash,
                       Symbol* name, ClassLoaderData* loader_data);
  PlaceholderEntry* get_entry(int index, unsigned int hash,
                       Symbol* name, ClassLoaderData* loader_data);
 enum classloadAction {
    LOAD_INSTANCE = 1,             // calling load_instance_class
    LOAD_SUPER = 2,                // loading superclass for this class
    DEFINE_CLASS = 3               // find_or_define class
 };
  PlaceholderEntry* find_and_add(int index, unsigned int hash,
                                 Symbol* name, ClassLoaderData* loader_data,
                                 classloadAction action, Symbol* supername,
                                 Thread* thread);
  void remove_entry(int index, unsigned int hash,
                    Symbol* name, ClassLoaderData* loader_data);
  void find_and_remove(int index, unsigned int hash,
                       Symbol* name, ClassLoaderData* loader_data,
                       classloadAction action, Thread* thread);
  void classes_do(KlassClosure* f);
  void entries_do(void f(Symbol*));
#ifndef PRODUCT
  void print();
#endif
  void verify();
};
class SeenThread: public CHeapObj<mtInternal> {
private:
   Thread *_thread;
   SeenThread* _stnext;
   SeenThread* _stprev;
public:
   SeenThread(Thread *thread) {
       _thread = thread;
       _stnext = NULL;
       _stprev = NULL;
   }
   Thread* thread()                const { return _thread;}
   void set_thread(Thread *thread) { _thread = thread; }
   SeenThread* next()              const { return _stnext;}
   void set_next(SeenThread *seen) { _stnext = seen; }
   void set_prev(SeenThread *seen) { _stprev = seen; }
#ifndef PRODUCT
  void printActionQ() {
    SeenThread* seen = this;
    while (seen != NULL) {
      seen->thread()->print_value();
      tty->print(", ");
      seen = seen->next();
    }
  }
#endif // PRODUCT
};
class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
  friend class VMStructs;
 private:
  ClassLoaderData*  _loader_data;   // initiating loader
  bool              _havesupername; // distinguish between null supername, and unknown
  Symbol*           _supername;
  Thread*           _definer;       // owner of define token
  Klass*            _instanceKlass; // InstanceKlass from successful define
  SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
  SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
  SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
 public:
  Symbol*            klassname()           const { return literal(); }
  ClassLoaderData*   loader_data()         const { return _loader_data; }
  void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
  bool               havesupername()       const { return _havesupername; }
  void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
  Symbol*            supername()           const { return _supername; }
  void               set_supername(Symbol* supername) {
    _supername = supername;
    if (_supername != NULL) _supername->increment_refcount();
  }
  Thread*            definer()             const {return _definer; }
  void               set_definer(Thread* definer) { _definer = definer; }
  Klass*             instance_klass()      const {return _instanceKlass; }
  void               set_instance_klass(Klass* ik) { _instanceKlass = ik; }
  SeenThread*        superThreadQ()        const { return _superThreadQ; }
  void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
  SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
  void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
  SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
  void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
  PlaceholderEntry* next() const {
    return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
  }
  PlaceholderEntry** next_addr() {
    return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
  }
  bool equals(Symbol* class_name, ClassLoaderData* loader) const {
    return (klassname() == class_name && loader_data() == loader);
  }
  SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
    SeenThread* queuehead = NULL;
    switch (action) {
      case PlaceholderTable::LOAD_INSTANCE:
         queuehead = _loadInstanceThreadQ;
         break;
      case PlaceholderTable::LOAD_SUPER:
         queuehead = _superThreadQ;
         break;
      case PlaceholderTable::DEFINE_CLASS:
         queuehead = _defineThreadQ;
         break;
      default: Unimplemented();
    }
    return queuehead;
  }
  void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
    switch (action) {
      case PlaceholderTable::LOAD_INSTANCE:
         _loadInstanceThreadQ = seenthread;
         break;
      case PlaceholderTable::LOAD_SUPER:
         _superThreadQ = seenthread;
         break;
      case PlaceholderTable::DEFINE_CLASS:
         _defineThreadQ = seenthread;
         break;
      default: Unimplemented();
    }
    return;
  }
  bool super_load_in_progress() {
     return (_superThreadQ != NULL);
  }
  bool instance_load_in_progress() {
    return (_loadInstanceThreadQ != NULL);
  }
  bool define_class_in_progress() {
    return (_defineThreadQ != NULL);
  }
  void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
    assert_lock_strong(SystemDictionary_lock);
    SeenThread* threadEntry = new SeenThread(thread);
    SeenThread* seen = actionToQueue(action);
    if (seen == NULL) {
      set_threadQ(threadEntry, action);
      return;
    }
    SeenThread* next;
    while ((next = seen->next()) != NULL) {
      seen = next;
    }
    seen->set_next(threadEntry);
    threadEntry->set_prev(seen);
    return;
  }
  bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
    assert_lock_strong(SystemDictionary_lock);
    SeenThread* threadQ = actionToQueue(action);
    SeenThread* seen = threadQ;
    while (seen) {
      if (thread == seen->thread()) {
        return true;
      }
      seen = seen->next();
    }
    return false;
  }
  bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
    assert_lock_strong(SystemDictionary_lock);
    SeenThread* threadQ = actionToQueue(action);
    SeenThread* seen = threadQ;
    SeenThread* prev = NULL;
    while (seen) {
      if (thread == seen->thread()) {
        if (prev) {
          prev->set_next(seen->next());
        } else {
          set_threadQ(seen->next(), action);
        }
        if (seen->next()) {
          seen->next()->set_prev(prev);
        }
        delete seen;
        break;
      }
      prev = seen;
      seen = seen->next();
    }
    return (actionToQueue(action) == NULL);
  }
  void classes_do(KlassClosure* closure);
  void print() const  PRODUCT_RETURN;
  void verify() const;
};
#endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/resolutionErrors.cpp
#include "precompiled.hpp"
#include "classfile/resolutionErrors.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/safepoint.hpp"
#include "utilities/hashtable.inline.hpp"
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
                                     constantPoolHandle pool, int cp_index,
                                     Symbol* error, Symbol* message)
{
  assert_locked_or_safepoint(SystemDictionary_lock);
  assert(!pool.is_null() && error != NULL, "adding NULL obj");
  ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error, message);
  add_entry(index, entry);
}
ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int hash,
                                                       constantPoolHandle pool, int cp_index)
{
  assert_locked_or_safepoint(SystemDictionary_lock);
  for (ResolutionErrorEntry *error_probe = bucket(index);
                         error_probe != NULL;
                         error_probe = error_probe->next()) {
  if (error_probe->hash() == hash && error_probe->pool() == pool()) {
      return error_probe;;
    }
  }
  return NULL;
}
void ResolutionErrorEntry::set_error(Symbol* e) {
  assert(e != NULL, "must set a value");
  _error = e;
  _error->increment_refcount();
}
void ResolutionErrorEntry::set_message(Symbol* c) {
  assert(c != NULL, "must set a value");
  _message = c;
  _message->increment_refcount();
}
ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool,
                                                      int cp_index, Symbol* error,
                                                      Symbol* message)
{
  ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool);
  entry->set_cp_index(cp_index);
  entry->set_error(error);
  entry->set_message(message);
  return entry;
}
void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
  assert(entry->error() != NULL, "error should be set");
  entry->error()->decrement_refcount();
  entry->message()->decrement_refcount();
  Hashtable<ConstantPool*, mtClass>::free_entry(entry);
}
ResolutionErrorTable::ResolutionErrorTable(int table_size)
    : Hashtable<ConstantPool*, mtClass>(table_size, sizeof(ResolutionErrorEntry)) {
}
void ResolutionErrorTable::delete_entry(ConstantPool* c) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  for (int i = 0; i < table_size(); i++) {
    for (ResolutionErrorEntry** p = bucket_addr(i); *p != NULL; ) {
      ResolutionErrorEntry* entry = *p;
      assert(entry->pool() != NULL, "resolution error table is corrupt");
      if (entry->pool() == c) {
        free_entry(entry);
      } else {
        p = entry->next_addr();
      }
    }
  }
}
void ResolutionErrorTable::purge_resolution_errors() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  for (int i = 0; i < table_size(); i++) {
    for (ResolutionErrorEntry** p = bucket_addr(i); *p != NULL; ) {
      ResolutionErrorEntry* entry = *p;
      assert(entry->pool() != (ConstantPool*)NULL, "resolution error table is corrupt");
      ConstantPool* pool = entry->pool();
      assert(pool->pool_holder() != NULL, "Constant pool without a class?");
      ClassLoaderData* loader_data =
              pool->pool_holder()->class_loader_data();
      if (!loader_data->is_unloading()) {
        p = entry->next_addr();
      } else {
        free_entry(entry);
      }
    }
  }
}
C:\hotspot-69087d08d473\src\share\vm/classfile/resolutionErrors.hpp
#ifndef SHARE_VM_CLASSFILE_RESOLUTIONERRORS_HPP
#define SHARE_VM_CLASSFILE_RESOLUTIONERRORS_HPP
#include "oops/constantPool.hpp"
#include "utilities/hashtable.hpp"
class ResolutionErrorEntry;
class ResolutionErrorTable : public Hashtable<ConstantPool*, mtClass> {
public:
  ResolutionErrorTable(int table_size);
  ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index,
                                  Symbol* error, Symbol* message);
  void free_entry(ResolutionErrorEntry *entry);
  ResolutionErrorEntry* bucket(int i) {
    return (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::bucket(i);
  }
  ResolutionErrorEntry** bucket_addr(int i) {
    return (ResolutionErrorEntry**)Hashtable<ConstantPool*, mtClass>::bucket_addr(i);
  }
  void add_entry(int index, ResolutionErrorEntry* new_entry) {
    Hashtable<ConstantPool*, mtClass>::add_entry(index,
      (HashtableEntry<ConstantPool*, mtClass>*)new_entry);
  }
  void add_entry(int index, unsigned int hash,
                 constantPoolHandle pool, int which, Symbol* error, Symbol* message);
  ResolutionErrorEntry* find_entry(int index, unsigned int hash,
                                   constantPoolHandle pool, int cp_index);
  unsigned int compute_hash(constantPoolHandle pool, int cp_index) {
    return (unsigned int) pool->identity_hash() + cp_index;
  }
  void purge_resolution_errors();
  void delete_entry(ConstantPool* c);
};
class ResolutionErrorEntry : public HashtableEntry<ConstantPool*, mtClass> {
 private:
  int               _cp_index;
  Symbol*           _error;
  Symbol*           _message;
 public:
  ConstantPool*      pool() const               { return literal(); }
  int                cp_index() const           { return _cp_index; }
  void               set_cp_index(int cp_index) { _cp_index = cp_index; }
  Symbol*            error() const              { return _error; }
  void               set_error(Symbol* e);
  Symbol*            message() const            { return _message; }
  void               set_message(Symbol* c);
  ResolutionErrorEntry* next() const {
    return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next();
  }
  ResolutionErrorEntry** next_addr() {
    return (ResolutionErrorEntry**)HashtableEntry<ConstantPool*, mtClass>::next_addr();
  }
};
#endif // SHARE_VM_CLASSFILE_RESOLUTIONERRORS_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/sharedClassUtil.hpp
#ifndef SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
#define SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
#include "classfile/sharedPathsMiscInfo.hpp"
#include "memory/filemap.hpp"
class SharedClassUtil : AllStatic {
public:
  static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
    return new SharedPathsMiscInfo();
  }
  static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
    return new SharedPathsMiscInfo(buf, size);
  }
  static FileMapInfo::FileMapHeader* allocate_file_map_header() {
    return new FileMapInfo::FileMapHeader();
  }
  static size_t file_map_header_size() {
    return sizeof(FileMapInfo::FileMapHeader);
  }
  static size_t shared_class_path_entry_size() {
    return sizeof(SharedClassPathEntry);
  }
  static void update_shared_classpath(ClassPathEntry *cpe,
                                      SharedClassPathEntry* ent,
                                      time_t timestamp,
                                      long filesize, TRAPS) {
    ent->_timestamp = timestamp;
    ent->_filesize  = filesize;
  }
  static void initialize(TRAPS) {}
  inline static bool is_shared_boot_class(Klass* klass) {
    return (klass->_shared_class_path_index >= 0);
  }
};
#endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/sharedPathsMiscInfo.cpp
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/sharedPathsMiscInfo.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/metaspaceShared.hpp"
#include "runtime/arguments.hpp"
void SharedPathsMiscInfo::add_path(const char* path, int type) {
  if (TraceClassPaths) {
    tty->print("[type=%s] ", type_name(type));
    trace_class_path("[Add misc shared path ", path);
  }
  write(path, strlen(path) + 1);
  write_jint(jint(type));
}
void SharedPathsMiscInfo::ensure_size(size_t needed_bytes) {
  assert(_allocated, "cannot modify buffer during validation.");
  int used = get_used_bytes();
  int target = used + int(needed_bytes);
  if (target > _buf_size) {
    _buf_size = _buf_size * 2 + (int)needed_bytes;
    _buf_start = REALLOC_C_HEAP_ARRAY(char, _buf_start, _buf_size, mtClass);
    _cur_ptr = _buf_start + used;
    _end_ptr = _buf_start + _buf_size;
  }
}
void SharedPathsMiscInfo::write(const void* ptr, size_t size) {
  ensure_size(size);
  memcpy(_cur_ptr, ptr, size);
  _cur_ptr += size;
}
bool SharedPathsMiscInfo::read(void* ptr, size_t size) {
  if (_cur_ptr + size <= _end_ptr) {
    memcpy(ptr, _cur_ptr, size);
    _cur_ptr += size;
    return true;
  }
  return false;
}
bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
  ClassLoader::trace_class_path(tty, msg, name);
  MetaspaceShared::set_archive_loading_failed();
  return false;
}
bool SharedPathsMiscInfo::check() {
  _end_ptr -= sizeof(jint);
  if (_cur_ptr >= _end_ptr) {
    return fail("Truncated archive file header");
  }
  if (*_end_ptr != 0) {
    return fail("Corrupted archive file header");
  }
  while (_cur_ptr < _end_ptr) {
    jint type;
    const char* path = _cur_ptr;
    _cur_ptr += strlen(path) + 1;
    if (!read_jint(&type)) {
      return fail("Corrupted archive file header");
    }
    if (TraceClassPaths) {
      tty->print("[type=%s ", type_name(type));
      print_path(tty, type, path);
      tty->print_cr("]");
    }
    if (!check(type, path)) {
      if (!PrintSharedArchiveAndExit) {
        return false;
      }
    } else {
      trace_class_path("[ok");
    }
  }
  return true;
}
bool SharedPathsMiscInfo::check(jint type, const char* path) {
  switch (type) {
  case BOOT:
    if (strcmp(path, Arguments::get_sysclasspath()) != 0) {
      return fail("[BOOT classpath mismatch, actual: -Dsun.boot.class.path=", Arguments::get_sysclasspath());
    }
    break;
  case NON_EXIST: // fall-through
  case REQUIRED:
    {
      struct stat st;
      if (os::stat(path, &st) != 0) {
        if (type == REQUIRED) {
          return fail("Required file doesn't exist");
        }
      } else {
        if (type == NON_EXIST) {
          return fail("File must not exist");
        }
        time_t    timestamp;
        long      filesize;
        if (!read_time(&timestamp) || !read_long(&filesize)) {
          return fail("Corrupted archive file header");
        }
        if (timestamp != st.st_mtime) {
          return fail("Timestamp mismatch");
        }
        if (filesize != st.st_size) {
          return fail("File size mismatch");
        }
      }
    }
    break;
  default:
    return fail("Corrupted archive file header");
  }
  return true;
}
C:\hotspot-69087d08d473\src\share\vm/classfile/sharedPathsMiscInfo.hpp
#ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
#define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
#include "runtime/os.hpp"
class SharedPathsMiscInfo : public CHeapObj<mtClass> {
protected:
  char* _buf_start;
  char* _cur_ptr;
  char* _end_ptr;
  int   _buf_size;
  bool  _allocated;   // was _buf_start allocated by me?
  void ensure_size(size_t needed_bytes);
  void add_path(const char* path, int type);
  void write(const void* ptr, size_t size);
  bool read(void* ptr, size_t size);
  static void trace_class_path(const char* msg, const char* name = NULL) {
    ClassLoader::trace_class_path(tty, msg, name);
  }
protected:
  static bool fail(const char* msg, const char* name = NULL);
  virtual bool check(jint type, const char* path);
public:
  enum {
    INITIAL_BUF_SIZE = 128
  };
  SharedPathsMiscInfo() {
    _buf_size = INITIAL_BUF_SIZE;
    _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
    _allocated = true;
  }
  SharedPathsMiscInfo(char *buff, int size) {
    _cur_ptr = _buf_start = buff;
    _end_ptr = _buf_start + size;
    _buf_size = size;
    _allocated = false;
  }
  ~SharedPathsMiscInfo() {
    if (_allocated) {
      FREE_C_HEAP_ARRAY(char, _buf_start, mtClass);
    }
  }
  int get_used_bytes() {
    return _cur_ptr - _buf_start;
  }
  void* buffer() {
    return _buf_start;
  }
  void add_nonexist_path(const char* path) {
    add_path(path, NON_EXIST);
  }
  void add_required_file(const char* path) {
    add_path(path, REQUIRED);
    struct stat st;
    if (os::stat(path, &st) != 0) {
      assert(0, "sanity");
      ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
    }
    write_time(st.st_mtime);
    write_long(st.st_size);
  }
  void add_boot_classpath(const char* path) {
    add_path(path, BOOT);
  }
  int write_jint(jint num) {
    write(&num, sizeof(num));
    return 0;
  }
  void write_time(time_t t) {
    write(&t, sizeof(t));
  }
  void write_long(long l) {
    write(&l, sizeof(l));
  }
  bool dump_to_file(int fd) {
    int n = get_used_bytes();
    return (os::write(fd, _buf_start, n) == (size_t)n);
  }
  enum {
    BOOT      = 1,
    NON_EXIST = 2,
    REQUIRED  = 3
  };
  virtual const char* type_name(int type) {
    switch (type) {
    case BOOT:      return "BOOT";
    case NON_EXIST: return "NON_EXIST";
    case REQUIRED:  return "REQUIRED";
    default:        ShouldNotReachHere(); return "?";
    }
  }
  virtual void print_path(outputStream* out, int type, const char* path) {
    switch (type) {
    case BOOT:
      out->print("Expecting -Dsun.boot.class.path=%s", path);
      break;
    case NON_EXIST:
      out->print("Expecting that %s does not exist", path);
      break;
    case REQUIRED:
      out->print("Expecting that file %s must exist and is not altered", path);
      break;
    default:
      ShouldNotReachHere();
    }
  }
  bool check();
  bool read_jint(jint *ptr) {
    return read(ptr, sizeof(jint));
  }
  bool read_long(long *ptr) {
    return read(ptr, sizeof(long));
  }
  bool read_time(time_t *ptr) {
    return read(ptr, sizeof(time_t));
  }
};
#endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/stackMapFrame.cpp
#include "precompiled.hpp"
#include "classfile/stackMapFrame.hpp"
#include "classfile/verifier.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/globalDefinitions.hpp"
StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* v) :
                      _offset(0), _locals_size(0), _stack_size(0),
                      _stack_mark(0), _flags(0), _max_locals(max_locals),
                      _max_stack(max_stack), _verifier(v) {
  Thread* thr = v->thread();
  _locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals);
  _stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack);
  int32_t i;
  for(i = 0; i < max_locals; i++) {
    _locals[i] = VerificationType::bogus_type();
  }
  for(i = 0; i < max_stack; i++) {
    _stack[i] = VerificationType::bogus_type();
  }
}
StackMapFrame* StackMapFrame::frame_in_exception_handler(u1 flags) {
  Thread* thr = _verifier->thread();
  VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, 1);
  StackMapFrame* frame = new StackMapFrame(_offset, flags, _locals_size, 0, _max_locals, _max_stack, _locals, stack, _verifier);
  return frame;
}
void StackMapFrame::initialize_object(
    VerificationType old_object, VerificationType new_object) {
  int32_t i;
  for (i = 0; i < _max_locals; i++) {
    if (_locals[i].equals(old_object)) {
      _locals[i] = new_object;
    }
  }
  for (i = 0; i < _stack_size; i++) {
    if (_stack[i].equals(old_object)) {
      _stack[i] = new_object;
    }
  }
  if (old_object == VerificationType::uninitialized_this_type()) {
    _flags = 0;
  }
}
VerificationType StackMapFrame::set_locals_from_arg(
    const methodHandle m, VerificationType thisKlass, TRAPS) {
  SignatureStream ss(m->signature());
  int init_local_num = 0;
  if (!m->is_static()) {
    init_local_num++;
    if (m->name() == vmSymbols::object_initializer_name() &&
       thisKlass.name() != vmSymbols::java_lang_Object()) {
      _locals[0] = VerificationType::uninitialized_this_type();
      _flags |= FLAG_THIS_UNINIT;
    } else {
      _locals[0] = thisKlass;
    }
  }
  while(!ss.at_return_type()) {
    init_local_num += _verifier->change_sig_to_verificationType(
      &ss, &_locals[init_local_num],
      CHECK_VERIFY_(verifier(), VerificationType::bogus_type()));
    ss.next();
  }
  _locals_size = init_local_num;
  switch (ss.type()) {
    case T_OBJECT:
    case T_ARRAY:
    {
      Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
      Symbol* sig_copy =
        verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(),
                                 CHECK_(VerificationType::bogus_type()));
      assert(sig_copy == sig, "symbols don't match");
      return VerificationType::reference_type(sig_copy);
    }
    case T_INT:     return VerificationType::integer_type();
    case T_BYTE:    return VerificationType::byte_type();
    case T_CHAR:    return VerificationType::char_type();
    case T_SHORT:   return VerificationType::short_type();
    case T_BOOLEAN: return VerificationType::boolean_type();
    case T_FLOAT:   return VerificationType::float_type();
    case T_DOUBLE:  return VerificationType::double_type();
    case T_LONG:    return VerificationType::long_type();
    case T_VOID:    return VerificationType::bogus_type();
    default:
      ShouldNotReachHere();
  }
  return VerificationType::bogus_type();
}
void StackMapFrame::copy_locals(const StackMapFrame* src) {
  int32_t len = src->locals_size() < _locals_size ?
    src->locals_size() : _locals_size;
  for (int32_t i = 0; i < len; i++) {
    _locals[i] = src->locals()[i];
  }
}
void StackMapFrame::copy_stack(const StackMapFrame* src) {
  int32_t len = src->stack_size() < _stack_size ?
    src->stack_size() : _stack_size;
  for (int32_t i = 0; i < len; i++) {
    _stack[i] = src->stack()[i];
  }
}
int StackMapFrame::is_assignable_to(
    VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
  int32_t i = 0;
  for (i = 0; i < len; i++) {
    if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) {
      break;
    }
  }
  return i;
}
bool StackMapFrame::is_assignable_to(
    const StackMapFrame* target, ErrorContext* ctx, TRAPS) const {
  if (_max_locals != target->max_locals()) {
        _offset, (StackMapFrame*)this, (StackMapFrame*)target);
    return false;
  }
  if (_stack_size != target->stack_size()) {
        _offset, (StackMapFrame*)this, (StackMapFrame*)target);
    return false;
  }
  int mismatch_loc;
  mismatch_loc = is_assignable_to(
    _locals, target->locals(), target->locals_size(), THREAD);
  if (mismatch_loc != target->locals_size()) {
        TypeOrigin::local(mismatch_loc, (StackMapFrame*)this),
        TypeOrigin::sm_local(mismatch_loc, (StackMapFrame*)target));
    return false;
  }
  mismatch_loc = is_assignable_to(_stack, target->stack(), _stack_size, THREAD);
  if (mismatch_loc != _stack_size) {
        TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this),
        TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target));
    return false;
  }
  if ((_flags | target->flags()) == target->flags()) {
    return true;
  } else {
        (StackMapFrame*)this, (StackMapFrame*)target);
    return false;
  }
}
VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
  if (_stack_size <= 0) {
    verifier()->verify_error(
        ErrorContext::stack_underflow(_offset, this),
        "Operand stack underflow");
    return VerificationType::bogus_type();
  }
  VerificationType top = _stack[--_stack_size];
  bool subtype = type.is_assignable_from(
    top, verifier(), false, CHECK_(VerificationType::bogus_type()));
  if (!subtype) {
    verifier()->verify_error(
        ErrorContext::bad_type(_offset, stack_top_ctx(),
            TypeOrigin::implicit(type)),
        "Bad type on operand stack");
    return VerificationType::bogus_type();
  }
  return top;
}
VerificationType StackMapFrame::get_local(
    int32_t index, VerificationType type, TRAPS) {
  if (index >= _max_locals) {
    verifier()->verify_error(
        ErrorContext::bad_local_index(_offset, index),
        "Local variable table overflow");
    return VerificationType::bogus_type();
  }
  bool subtype = type.is_assignable_from(_locals[index],
    verifier(), false, CHECK_(VerificationType::bogus_type()));
  if (!subtype) {
    verifier()->verify_error(
        ErrorContext::bad_type(_offset,
          TypeOrigin::local(index, this),
          TypeOrigin::implicit(type)),
        "Bad local variable type");
    return VerificationType::bogus_type();
  }
  if(index >= _locals_size) { _locals_size = index + 1; }
  return _locals[index];
}
void StackMapFrame::get_local_2(
    int32_t index, VerificationType type1, VerificationType type2, TRAPS) {
  assert(type1.is_long() || type1.is_double(), "must be long/double");
  assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
  if (index >= _locals_size - 1) {
    verifier()->verify_error(
        ErrorContext::bad_local_index(_offset, index),
        "get long/double overflows locals");
    return;
  }
  bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK);
  if (!subtype) {
    verifier()->verify_error(
        ErrorContext::bad_type(_offset,
            TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
        "Bad local variable type");
  } else {
    subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK);
    if (!subtype) {
      verifier()->verify_error(
          ErrorContext::bad_type(_offset,
              TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)),
          "Bad local variable type");
    }
  }
}
void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) {
  assert(!type.is_check(), "Must be a real type");
  if (index >= _max_locals) {
    verifier()->verify_error(
        ErrorContext::bad_local_index(_offset, index),
        "Local variable table overflow");
    return;
  }
  if (_locals[index].is_double() || _locals[index].is_long()) {
    assert((index + 1) < _locals_size, "Local variable table overflow");
    _locals[index + 1] = VerificationType::bogus_type();
  }
  if (_locals[index].is_double2() || _locals[index].is_long2()) {
    assert(index >= 1, "Local variable table underflow");
    _locals[index - 1] = VerificationType::bogus_type();
  }
  _locals[index] = type;
  if (index >= _locals_size) {
#ifdef ASSERT
    for (int i=_locals_size; i<index; i++) {
      assert(_locals[i] == VerificationType::bogus_type(),
             "holes must be bogus type");
    }
#endif
    _locals_size = index + 1;
  }
}
void StackMapFrame::set_local_2(
    int32_t index, VerificationType type1, VerificationType type2, TRAPS) {
  assert(type1.is_long() || type1.is_double(), "must be long/double");
  assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
  if (index >= _max_locals - 1) {
    verifier()->verify_error(
        ErrorContext::bad_local_index(_offset, index),
        "Local variable table overflow");
    return;
  }
  if (_locals[index+1].is_double() || _locals[index+1].is_long()) {
    assert((index + 2) < _locals_size, "Local variable table overflow");
    _locals[index + 2] = VerificationType::bogus_type();
  }
  if (_locals[index].is_double2() || _locals[index].is_long2()) {
    assert(index >= 1, "Local variable table underflow");
    _locals[index - 1] = VerificationType::bogus_type();
  }
  _locals[index] = type1;
  _locals[index+1] = type2;
  if (index >= _locals_size - 1) {
#ifdef ASSERT
    for (int i=_locals_size; i<index; i++) {
      assert(_locals[i] == VerificationType::bogus_type(),
             "holes must be bogus type");
    }
#endif
    _locals_size = index + 2;
  }
}
TypeOrigin StackMapFrame::stack_top_ctx() {
  return TypeOrigin::stack(_stack_size, this);
}
void StackMapFrame::print_on(outputStream* str) const {
  str->indent().print_cr("bci: @%d", _offset);
  str->indent().print_cr("flags: {%s }",
      flag_this_uninit() ? " flagThisUninit" : "");
  str->indent().print("locals: {");
  for (int32_t i = 0; i < _locals_size; ++i) {
    str->print(" ");
    _locals[i].print_on(str);
    if (i != _locals_size - 1) {
      str->print(",");
    }
  }
  str->print_cr(" }");
  str->indent().print("stack: {");
  for (int32_t j = 0; j < _stack_size; ++j) {
    str->print(" ");
    _stack[j].print_on(str);
    if (j != _stack_size - 1) {
      str->print(",");
    }
  }
  str->print_cr(" }");
}
C:\hotspot-69087d08d473\src\share\vm/classfile/stackMapFrame.hpp
#ifndef SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP
#define SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/signature.hpp"
#include "utilities/exceptions.hpp"
class TypeContext;
enum {
  FLAG_THIS_UNINIT = 0x01
};
class StackMapFrame : public ResourceObj {
 private:
  int32_t _offset;
  int32_t _locals_size;  // number of valid type elements in _locals
  int32_t _stack_size;   // number of valid type elements in _stack
  int32_t _stack_mark;   // Records the size of the stack prior to an
  int32_t _max_locals;
  int32_t _max_stack;
  u1 _flags;
  VerificationType* _locals; // local variable type array
  VerificationType* _stack;  // operand stack type array
  ClassVerifier* _verifier;  // the verifier verifying this method
  StackMapFrame(const StackMapFrame& cp) :
      _offset(cp._offset), _locals_size(cp._locals_size),
      _stack_size(cp._stack_size), _stack_mark(cp._stack_mark),
      _max_locals(cp._max_locals), _max_stack(cp._max_stack),
      _flags(cp._flags) {
    _locals = NEW_RESOURCE_ARRAY(VerificationType, _max_locals);
    for (int i = 0; i < _max_locals; ++i) {
      if (i < _locals_size) {
        _locals[i] = cp._locals[i];
      } else {
        _locals[i] = VerificationType::bogus_type();
      }
    }
    int ss = MAX2(_stack_size, _stack_mark);
    _stack = NEW_RESOURCE_ARRAY(VerificationType, _max_stack);
    for (int i = 0; i < _max_stack; ++i) {
      if (i < ss) {
        _stack[i] = cp._stack[i];
      } else {
        _stack[i] = VerificationType::bogus_type();
      }
    }
    _verifier = NULL;
  }
 public:
  StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* verifier);
  StackMapFrame(int32_t offset,
                u1 flags,
                u2 locals_size,
                u2 stack_size,
                u2 max_locals,
                u2 max_stack,
                VerificationType* locals,
                VerificationType* stack,
                ClassVerifier* v) : _offset(offset), _flags(flags),
                                    _locals_size(locals_size),
                                    _stack_size(stack_size),
                                    _stack_mark(-1),
                                    _max_locals(max_locals),
                                    _max_stack(max_stack),
                                    _locals(locals), _stack(stack),
                                    _verifier(v) { }
  static StackMapFrame* copy(StackMapFrame* smf) {
    return new StackMapFrame(*smf);
  }
  inline void set_offset(int32_t offset)      { _offset = offset; }
  inline void set_verifier(ClassVerifier* v)  { _verifier = v; }
  inline void set_flags(u1 flags)             { _flags = flags; }
  inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; }
  inline void set_stack_size(u2 stack_size)   { _stack_size = _stack_mark = stack_size; }
  inline void clear_stack()                   { _stack_size = 0; }
  inline int32_t offset()   const             { return _offset; }
  inline ClassVerifier* verifier() const      { return _verifier; }
  inline u1 flags() const                     { return _flags; }
  inline int32_t locals_size() const          { return _locals_size; }
  inline VerificationType* locals() const     { return _locals; }
  inline int32_t stack_size() const           { return _stack_size; }
  inline VerificationType* stack() const      { return _stack; }
  inline int32_t max_locals() const           { return _max_locals; }
  inline int32_t max_stack() const            { return _max_stack; }
  inline bool flag_this_uninit() const        { return _flags & FLAG_THIS_UNINIT; }
  inline void reset() {
    int32_t i;
    for (i = 0; i < _max_locals; i++) {
      _locals[i] = VerificationType::bogus_type();
    }
    for (i = 0; i < _max_stack; i++) {
      _stack[i] = VerificationType::bogus_type();
    }
  }
  StackMapFrame* frame_in_exception_handler(u1 flags);
  VerificationType set_locals_from_arg(
    const methodHandle m, VerificationType thisKlass, TRAPS);
  void initialize_object(
    VerificationType old_object, VerificationType new_object);
  void copy_locals(const StackMapFrame* src);
  void copy_stack(const StackMapFrame* src);
  bool is_assignable_to(
      const StackMapFrame* target, ErrorContext* ctx, TRAPS) const;
  inline void set_mark() {
#ifdef ASSERT
    if (_stack_mark != -1) {
      for (int i = _stack_mark - 1; i >= _stack_size; --i) {
        _stack[i] = VerificationType::bogus_type();
      }
    }
#endif // def ASSERT
    _stack_mark = _stack_size;
  }
  void restore() {
    if (_stack_mark != -1) {
      _stack_size = _stack_mark;
    }
  }
  inline void push_stack(VerificationType type, TRAPS) {
    assert(!type.is_check(), "Must be a real type");
    if (_stack_size >= _max_stack) {
      verifier()->verify_error(
          ErrorContext::stack_overflow(_offset, this),
          "Operand stack overflow");
      return;
    }
    _stack[_stack_size++] = type;
  }
  inline void push_stack_2(
      VerificationType type1, VerificationType type2, TRAPS) {
    assert(type1.is_long() || type1.is_double(), "must be long/double");
    assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
    if (_stack_size >= _max_stack - 1) {
      verifier()->verify_error(
          ErrorContext::stack_overflow(_offset, this),
          "Operand stack overflow");
      return;
    }
    _stack[_stack_size++] = type1;
    _stack[_stack_size++] = type2;
  }
  inline VerificationType pop_stack(TRAPS) {
    if (_stack_size <= 0) {
      verifier()->verify_error(
          ErrorContext::stack_underflow(_offset, this),
          "Operand stack underflow");
      return VerificationType::bogus_type();
    }
    VerificationType top = _stack[--_stack_size];
    return top;
  }
  inline VerificationType pop_stack(VerificationType type, TRAPS) {
    if (_stack_size != 0) {
      VerificationType top = _stack[_stack_size - 1];
      bool subtype = type.is_assignable_from(
        top, verifier(), false, CHECK_(VerificationType::bogus_type()));
      if (subtype) {
        --_stack_size;
        return top;
      }
    }
    return pop_stack_ex(type, THREAD);
  }
  inline void pop_stack_2(
      VerificationType type1, VerificationType type2, TRAPS) {
    assert(type1.is_long2() || type1.is_double2(), "must be long/double");
    assert(type2.is_long() || type2.is_double(), "must be long/double_2");
    if (_stack_size >= 2) {
      VerificationType top1 = _stack[_stack_size - 1];
      bool subtype1 = type1.is_assignable_from(top1, verifier(), false, CHECK);
      VerificationType top2 = _stack[_stack_size - 2];
      bool subtype2 = type2.is_assignable_from(top2, verifier(), false, CHECK);
      if (subtype1 && subtype2) {
        _stack_size -= 2;
        return;
      }
    }
    pop_stack_ex(type1, THREAD);
    pop_stack_ex(type2, THREAD);
  }
  VerificationType local_at(int index) {
    return _locals[index];
  }
  VerificationType stack_at(int index) {
    return _stack[index];
  }
  VerificationType pop_stack_ex(VerificationType type, TRAPS);
  VerificationType get_local(int32_t index, VerificationType type, TRAPS);
  void get_local_2(
    int32_t index, VerificationType type1, VerificationType type2, TRAPS);
  void set_local(int32_t index, VerificationType type, TRAPS);
  void set_local_2(
    int32_t index, VerificationType type1, VerificationType type2, TRAPS);
  int is_assignable_to(
    VerificationType* src, VerificationType* target, int32_t len, TRAPS) const;
  TypeOrigin stack_top_ctx();
  void print_on(outputStream* str) const;
};
#endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/stackMapTable.cpp
#include "precompiled.hpp"
#include "classfile/stackMapTable.hpp"
#include "classfile/verifier.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldType.hpp"
#include "runtime/handles.inline.hpp"
StackMapTable::StackMapTable(StackMapReader* reader, StackMapFrame* init_frame,
                             u2 max_locals, u2 max_stack,
                             char* code_data, int code_len, TRAPS) {
  _code_length = code_len;
  _frame_count = reader->get_frame_count();
  if (_frame_count > 0) {
    _frame_array = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD,
                                                StackMapFrame*, _frame_count);
    StackMapFrame* pre_frame = init_frame;
    for (int32_t i = 0; i < _frame_count; i++) {
      StackMapFrame* frame = reader->next(
        pre_frame, i == 0, max_locals, max_stack,
        CHECK_VERIFY(pre_frame->verifier()));
      _frame_array[i] = frame;
      int offset = frame->offset();
      if (offset >= code_len || code_data[offset] == 0) {
        frame->verifier()->verify_error(
            ErrorContext::bad_stackmap(i, frame),
            "StackMapTable error: bad offset");
        return;
      }
      pre_frame = frame;
    }
  }
  reader->check_end(CHECK);
}
int StackMapTable::get_index_from_offset(int32_t offset) const {
  int i = 0;
  for (; i < _frame_count; i++) {
    if (_frame_array[i]->offset() == offset) {
      return i;
    }
  }
  return i;  // frame with offset doesn't exist in the array
}
bool StackMapTable::match_stackmap(
    StackMapFrame* frame, int32_t target,
    bool match, bool update, ErrorContext* ctx, TRAPS) const {
  int index = get_index_from_offset(target);
  return match_stackmap(frame, target, index, match, update, ctx, THREAD);
}
bool StackMapTable::match_stackmap(
    StackMapFrame* frame, int32_t target, int32_t frame_index,
    bool match, bool update, ErrorContext* ctx, TRAPS) const {
  if (frame_index < 0 || frame_index >= _frame_count) {
    frame->verifier()->verify_error(
    return false;
  }
  StackMapFrame *stackmap_frame = _frame_array[frame_index];
  bool result = true;
  if (match) {
    result = frame->is_assignable_to(stackmap_frame,
        ctx, CHECK_VERIFY_(frame->verifier(), result));
  }
  if (update) {
    int lsize = stackmap_frame->locals_size();
    int ssize = stackmap_frame->stack_size();
    if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
      frame->reset();
    }
    frame->set_locals_size(lsize);
    frame->copy_locals(stackmap_frame);
    frame->set_stack_size(ssize);
    frame->copy_stack(stackmap_frame);
    frame->set_flags(stackmap_frame->flags());
  }
  return result;
}
void StackMapTable::check_jump_target(
    StackMapFrame* frame, int32_t target, TRAPS) const {
  ErrorContext ctx;
  bool match = match_stackmap(
    frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
  if (!match || (target < 0 || target >= _code_length)) {
    frame->verifier()->verify_error(ctx,
        "Inconsistent stackmap frames at branch target %d", target);
  }
}
void StackMapTable::print_on(outputStream* str) const {
  str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
  str->indent().print_cr("table = { ");
  {
    streamIndentor si(str);
    for (int32_t i = 0; i < _frame_count; ++i) {
      _frame_array[i]->print_on(str);
    }
  }
  str->print_cr(" }");
}
int32_t StackMapReader::chop(
    VerificationType* locals, int32_t length, int32_t chops) {
  if (locals == NULL) return -1;
  int32_t pos = length - 1;
  for (int32_t i=0; i<chops; i++) {
    if (locals[pos].is_category2_2nd()) {
      pos -= 2;
    } else {
      pos --;
    }
    if (pos<0 && i<(chops-1)) return -1;
  }
  return pos+1;
}
VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
  u1 tag = _stream->get_u1(THREAD);
  if (tag < (u1)ITEM_UninitializedThis) {
    return VerificationType::from_tag(tag);
  }
  if (tag == ITEM_Object) {
    u2 class_index = _stream->get_u2(THREAD);
    int nconstants = _cp->length();
    if ((class_index <= 0 || class_index >= nconstants) ||
        (!_cp->tag_at(class_index).is_klass() &&
         !_cp->tag_at(class_index).is_unresolved_klass())) {
      _stream->stackmap_format_error("bad class index", THREAD);
      return VerificationType::bogus_type();
    }
    return VerificationType::reference_type(_cp->klass_name_at(class_index));
  }
  if (tag == ITEM_UninitializedThis) {
    if (flags != NULL) {
    }
    return VerificationType::uninitialized_this_type();
  }
  if (tag == ITEM_Uninitialized) {
    u2 offset = _stream->get_u2(THREAD);
    if (offset >= _code_length ||
        _code_data[offset] != ClassVerifier::NEW_OFFSET) {
      _verifier->class_format_error(
        "StackMapTable format error: bad offset for Uninitialized");
      return VerificationType::bogus_type();
    }
    return VerificationType::uninitialized_type(offset);
  }
  _stream->stackmap_format_error("bad verification type", THREAD);
  return VerificationType::bogus_type();
}
StackMapFrame* StackMapReader::next(
    StackMapFrame* pre_frame, bool first, u2 max_locals, u2 max_stack, TRAPS) {
  StackMapFrame* frame;
  int offset;
  VerificationType* locals = NULL;
  u1 frame_type = _stream->get_u1(THREAD);
  if (frame_type < 64) {
    if (first) {
      offset = frame_type;
      if (pre_frame->locals_size() > 0) {
        locals = NEW_RESOURCE_ARRAY_IN_THREAD(
          THREAD, VerificationType, pre_frame->locals_size());
      }
    } else {
      offset = pre_frame->offset() + frame_type + 1;
      locals = pre_frame->locals();
    }
    frame = new StackMapFrame(
      offset, pre_frame->flags(), pre_frame->locals_size(), 0,
      max_locals, max_stack, locals, NULL, _verifier);
    if (first && locals != NULL) {
      frame->copy_locals(pre_frame);
    }
    return frame;
  }
  if (frame_type < 128) {
    if (first) {
      offset = frame_type - 64;
      if (pre_frame->locals_size() > 0) {
        locals = NEW_RESOURCE_ARRAY_IN_THREAD(
          THREAD, VerificationType, pre_frame->locals_size());
      }
    } else {
      offset = pre_frame->offset() + frame_type - 63;
      locals = pre_frame->locals();
    }
    VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
      THREAD, VerificationType, 2);
    u2 stack_size = 1;
    stack[0] = parse_verification_type(NULL, CHECK_VERIFY_(_verifier, NULL));
    if (stack[0].is_category2()) {
      stack[1] = stack[0].to_category2_2nd();
      stack_size = 2;
    }
    check_verification_type_array_size(
      stack_size, max_stack, CHECK_VERIFY_(_verifier, NULL));
    frame = new StackMapFrame(
      offset, pre_frame->flags(), pre_frame->locals_size(), stack_size,
      max_locals, max_stack, locals, stack, _verifier);
    if (first && locals != NULL) {
      frame->copy_locals(pre_frame);
    }
    return frame;
  }
  u2 offset_delta = _stream->get_u2(THREAD);
  if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
    _stream->stackmap_format_error(
      "reserved frame type", CHECK_VERIFY_(_verifier, NULL));
  }
  if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
    if (first) {
      offset = offset_delta;
      if (pre_frame->locals_size() > 0) {
        locals = NEW_RESOURCE_ARRAY_IN_THREAD(
          THREAD, VerificationType, pre_frame->locals_size());
      }
    } else {
      offset = pre_frame->offset() + offset_delta + 1;
      locals = pre_frame->locals();
    }
    VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
      THREAD, VerificationType, 2);
    u2 stack_size = 1;
    stack[0] = parse_verification_type(NULL, CHECK_VERIFY_(_verifier, NULL));
    if (stack[0].is_category2()) {
      stack[1] = stack[0].to_category2_2nd();
      stack_size = 2;
    }
    check_verification_type_array_size(
      stack_size, max_stack, CHECK_VERIFY_(_verifier, NULL));
    frame = new StackMapFrame(
      offset, pre_frame->flags(), pre_frame->locals_size(), stack_size,
      max_locals, max_stack, locals, stack, _verifier);
    if (first && locals != NULL) {
      frame->copy_locals(pre_frame);
    }
    return frame;
  }
  if (frame_type <= SAME_EXTENDED) {
    locals = pre_frame->locals();
    int length = pre_frame->locals_size();
    int chops = SAME_EXTENDED - frame_type;
    int new_length = length;
    u1 flags = pre_frame->flags();
    if (chops != 0) {
      new_length = chop(locals, length, chops);
      check_verification_type_array_size(
        new_length, max_locals, CHECK_VERIFY_(_verifier, NULL));
      flags = 0;
      for (int i=0; i<new_length; i++) {
        if (locals[i].is_uninitialized_this()) {
          flags |= FLAG_THIS_UNINIT;
          break;
        }
      }
    }
    if (first) {
      offset = offset_delta;
      if (new_length > 0) {
        locals = NEW_RESOURCE_ARRAY_IN_THREAD(
          THREAD, VerificationType, new_length);
      } else {
        locals = NULL;
      }
    } else {
      offset = pre_frame->offset() + offset_delta + 1;
    }
    frame = new StackMapFrame(
      offset, flags, new_length, 0, max_locals, max_stack,
      locals, NULL, _verifier);
    if (first && locals != NULL) {
      frame->copy_locals(pre_frame);
    }
    return frame;
  } else if (frame_type < SAME_EXTENDED + 4) {
    int appends = frame_type - SAME_EXTENDED;
    int real_length = pre_frame->locals_size();
    int new_length = real_length + appends*2;
    locals = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, new_length);
    VerificationType* pre_locals = pre_frame->locals();
    int i;
    for (i=0; i<pre_frame->locals_size(); i++) {
      locals[i] = pre_locals[i];
    }
    u1 flags = pre_frame->flags();
    for (i=0; i<appends; i++) {
      locals[real_length] = parse_verification_type(&flags, THREAD);
      if (locals[real_length].is_category2()) {
        locals[real_length + 1] = locals[real_length].to_category2_2nd();
        ++real_length;
      }
      ++real_length;
    }
    check_verification_type_array_size(
      real_length, max_locals, CHECK_VERIFY_(_verifier, NULL));
    if (first) {
      offset = offset_delta;
    } else {
      offset = pre_frame->offset() + offset_delta + 1;
    }
    frame = new StackMapFrame(
      offset, flags, real_length, 0, max_locals,
      max_stack, locals, NULL, _verifier);
    return frame;
  }
  if (frame_type == FULL) {
    u1 flags = 0;
    u2 locals_size = _stream->get_u2(THREAD);
    int real_locals_size = 0;
    if (locals_size > 0) {
      locals = NEW_RESOURCE_ARRAY_IN_THREAD(
        THREAD, VerificationType, locals_size*2);
    }
    int i;
    for (i=0; i<locals_size; i++) {
      locals[real_locals_size] = parse_verification_type(&flags, THREAD);
      if (locals[real_locals_size].is_category2()) {
        locals[real_locals_size + 1] =
          locals[real_locals_size].to_category2_2nd();
        ++real_locals_size;
      }
      ++real_locals_size;
    }
    check_verification_type_array_size(
      real_locals_size, max_locals, CHECK_VERIFY_(_verifier, NULL));
    u2 stack_size = _stream->get_u2(THREAD);
    int real_stack_size = 0;
    VerificationType* stack = NULL;
    if (stack_size > 0) {
      stack = NEW_RESOURCE_ARRAY_IN_THREAD(
        THREAD, VerificationType, stack_size*2);
    }
    for (i=0; i<stack_size; i++) {
      stack[real_stack_size] = parse_verification_type(NULL, THREAD);
      if (stack[real_stack_size].is_category2()) {
        stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd();
        ++real_stack_size;
      }
      ++real_stack_size;
    }
    check_verification_type_array_size(
      real_stack_size, max_stack, CHECK_VERIFY_(_verifier, NULL));
    if (first) {
      offset = offset_delta;
    } else {
      offset = pre_frame->offset() + offset_delta + 1;
    }
    frame = new StackMapFrame(
      offset, flags, real_locals_size, real_stack_size,
      max_locals, max_stack, locals, stack, _verifier);
    return frame;
  }
  _stream->stackmap_format_error(
    "reserved frame type", CHECK_VERIFY_(pre_frame->verifier(), NULL));
  return NULL;
}
C:\hotspot-69087d08d473\src\share\vm/classfile/stackMapTable.hpp
#ifndef SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP
#define SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP
#include "classfile/stackMapFrame.hpp"
#include "classfile/verifier.hpp"
#include "memory/allocation.hpp"
#include "oops/constantPool.hpp"
#include "oops/method.hpp"
#include "utilities/globalDefinitions.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "bytes_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif
class StackMapReader;
class StackMapTable : public StackObj {
 private:
  int32_t              _code_length;
  int32_t              _frame_count;     // Stackmap frame count
  StackMapFrame**       _frame_array;
 public:
  StackMapTable(StackMapReader* reader, StackMapFrame* init_frame,
                u2 max_locals, u2 max_stack,
                char* code_data, int code_len, TRAPS);
  inline int32_t get_frame_count() const { return _frame_count; }
  inline int get_offset(int index) const {
    return _frame_array[index]->offset();
  }
  bool match_stackmap(
    StackMapFrame* current_frame, int32_t offset,
    bool match, bool update, ErrorContext* ctx, TRAPS) const;
  bool match_stackmap(
    StackMapFrame* current_frame, int32_t offset, int32_t frame_index,
    bool match, bool update, ErrorContext* ctx, TRAPS) const;
  void check_jump_target(StackMapFrame* frame, int32_t target, TRAPS) const;
  int get_index_from_offset(int32_t offset) const;
  void print_on(outputStream* str) const;
};
class StackMapStream : StackObj {
 private:
  Array<u1>* _data;
  int _index;
 public:
  StackMapStream(Array<u1>* ah)
    : _data(ah), _index(0) {
  }
  u1 get_u1(TRAPS) {
    if (_data == NULL || _index >= _data->length()) {
      stackmap_format_error("access beyond the end of attribute", CHECK_0);
    }
    return _data->at(_index++);
  }
  u2 get_u2(TRAPS) {
    if (_data == NULL || _index >= _data->length() - 1) {
      stackmap_format_error("access beyond the end of attribute", CHECK_0);
    }
    u2 res = Bytes::get_Java_u2(_data->adr_at(_index));
    _index += 2;
    return res;
  }
  bool at_end() {
    return (_data == NULL) || (_index == _data->length());
  }
  static void stackmap_format_error(const char* msg, TRAPS);
};
class StackMapReader : StackObj {
 private:
  constantPoolHandle  _cp;
  ClassVerifier* _verifier;
  StackMapStream* _stream;
  char* _code_data;
  int32_t _code_length;
  int32_t  _frame_count;       // frame count
  int32_t chop(VerificationType* locals, int32_t length, int32_t chops);
  VerificationType parse_verification_type(u1* flags, TRAPS);
  void check_verification_type_array_size(
      int32_t size, int32_t max_size, TRAPS) {
    if (size < 0 || size > max_size) {
      _verifier->class_format_error(
        "StackMapTable format error: bad type array size");
    }
  }
  enum {
    SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
    SAME_EXTENDED = 251,
    FULL = 255
  };
 public:
  StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data,
                 int32_t code_len, TRAPS) :
                 _verifier(v), _stream(stream),
                 _code_data(code_data), _code_length(code_len) {
    methodHandle m = v->method();
    if (m->has_stackmap_table()) {
      _cp = constantPoolHandle(THREAD, m->constants());
      _frame_count = _stream->get_u2(CHECK);
    } else {
      _frame_count = 0;
    }
  }
  inline int32_t get_frame_count() const                { return _frame_count; }
  StackMapFrame* next(StackMapFrame* pre_frame, bool first,
                      u2 max_locals, u2 max_stack, TRAPS);
  void check_end(TRAPS) {
    if (!_stream->at_end()) {
      StackMapStream::stackmap_format_error("wrong attribute size", CHECK);
    }
  }
};
#endif // SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/stackMapTableFormat.hpp
#ifndef SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
#define SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
#include "classfile/verificationType.hpp"
class verification_type_info {
 private:
  address tag_addr() const { return (address)this; }
  address cpool_index_addr() const { return tag_addr() + sizeof(u1); }
  address bci_addr() const { return cpool_index_addr(); }
 protected:
  verification_type_info() {}
  verification_type_info(const verification_type_info&) {}
 public:
  static verification_type_info* at(address addr) {
    return (verification_type_info*)addr;
  }
  static verification_type_info* create_at(address addr, u1 tag) {
    verification_type_info* vti = (verification_type_info*)addr;
    vti->set_tag(tag);
    return vti;
  }
  static verification_type_info* create_object_at(address addr, u2 cp_idx) {
    verification_type_info* vti = (verification_type_info*)addr;
    vti->set_tag(ITEM_Object);
    vti->set_cpool_index(cp_idx);
    return vti;
  }
  static verification_type_info* create_uninit_at(address addr, u2 bci) {
    verification_type_info* vti = (verification_type_info*)addr;
    vti->set_tag(ITEM_Uninitialized);
    vti->set_bci(bci);
    return vti;
  }
  static size_t calculate_size(u1 tag) {
    if (tag == ITEM_Object || tag == ITEM_Uninitialized) {
      return sizeof(u1) + sizeof(u2);
    } else {
      return sizeof(u1);
    }
  }
  static size_t max_size() { return sizeof(u1) + sizeof(u2); }
  u1 tag() const { return *(u1*)tag_addr(); }
  void set_tag(u1 tag) { *((u1*)tag_addr()) = tag; }
  bool is_object() const { return tag() == ITEM_Object; }
  bool is_uninitialized() const { return tag() == ITEM_Uninitialized; }
  u2 cpool_index() const {
    assert(is_object(), "This type has no cp_index");
    return Bytes::get_Java_u2(cpool_index_addr());
  }
  void set_cpool_index(u2 idx) {
    assert(is_object(), "This type has no cp_index");
    Bytes::put_Java_u2(cpool_index_addr(), idx);
  }
  u2 bci() const {
    assert(is_uninitialized(), "This type has no bci");
    return Bytes::get_Java_u2(bci_addr());
  }
  void set_bci(u2 bci) {
    assert(is_uninitialized(), "This type has no bci");
    Bytes::put_Java_u2(bci_addr(), bci);
  }
  void copy_from(verification_type_info* from) {
    set_tag(from->tag());
    if (from->is_object()) {
      set_cpool_index(from->cpool_index());
    } else if (from->is_uninitialized()) {
      set_bci(from->bci());
    }
  }
  size_t size() const {
    return calculate_size(tag());
  }
  verification_type_info* next() {
    return (verification_type_info*)((address)this + size());
  }
  bool verify(address start, address end) {
    return ((address)this >= start &&
            (address)this < end &&
            (bci_addr() + sizeof(u2) <= end ||
                !is_object() && !is_uninitialized()));
  }
  void print_on(outputStream* st) {
    switch (tag()) {
      case ITEM_Top: st->print("Top"); break;
      case ITEM_Integer: st->print("Integer"); break;
      case ITEM_Float: st->print("Float"); break;
      case ITEM_Double: st->print("Double"); break;
      case ITEM_Long: st->print("Long"); break;
      case ITEM_Null: st->print("Null"); break;
      case ITEM_UninitializedThis:
        st->print("UninitializedThis"); break;
      case ITEM_Uninitialized:
        st->print("Uninitialized[#%d]", bci()); break;
      case ITEM_Object:
        st->print("Object[#%d]", cpool_index()); break;
      default:
        assert(false, "Bad verification_type_info");
    }
  }
};
#define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
  macro(same_frame, arg1, arg2) \
  macro(same_frame_extended, arg1, arg2) \
  macro(same_locals_1_stack_item_frame, arg1, arg2) \
  macro(same_locals_1_stack_item_extended, arg1, arg2) \
  macro(chop_frame, arg1, arg2) \
  macro(append_frame, arg1, arg2) \
  macro(full_frame, arg1, arg2)
#define SM_FORWARD_DECL(type, arg1, arg2) class type;
FOR_EACH_STACKMAP_FRAME_TYPE(SM_FORWARD_DECL, x, x)
#undef SM_FORWARD_DECL
class stack_map_frame {
 protected:
  address frame_type_addr() const { return (address)this; }
  stack_map_frame() {}
  stack_map_frame(const stack_map_frame&) {}
 public:
  static stack_map_frame* at(address addr) {
    return (stack_map_frame*)addr;
  }
  stack_map_frame* next() const {
    return at((address)this + size());
  }
  u1 frame_type() const { return *(u1*)frame_type_addr(); }
  void set_frame_type(u1 type) { *((u1*)frame_type_addr()) = type; }
  inline size_t size() const;
  inline int offset_delta() const;
  inline void set_offset_delta(int offset_delta);
  inline int number_of_types() const; // number of types contained in the frame
  inline verification_type_info* types() const; // pointer to first type
  inline bool is_valid_offset(int offset_delta) const;
  inline bool verify(address start, address end) const;
  inline void print_on(outputStream* st, int current_offset) const;
  inline void print_truncated(outputStream* st, int current_offset) const;
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
  inline stackmap_frame_type* as_##stackmap_frame_type() const; \
  bool is_##stackmap_frame_type() { \
    return as_##stackmap_frame_type() != NULL; \
  }
  FOR_EACH_STACKMAP_FRAME_TYPE(FRAME_TYPE_DECL, x, x)
#undef FRAME_TYPE_DECL
};
class same_frame : public stack_map_frame {
 private:
  static int frame_type_to_offset_delta(u1 frame_type) {
      return frame_type + 1; }
  static u1 offset_delta_to_frame_type(int offset_delta) {
      return (u1)(offset_delta - 1); }
 public:
  static bool is_frame_type(u1 tag) {
    return tag < 64;
  }
  static same_frame* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame id");
    return (same_frame*)addr;
  }
  static same_frame* create_at(address addr, int offset_delta) {
    same_frame* sm = (same_frame*)addr;
    sm->set_offset_delta(offset_delta);
    return sm;
  }
  static size_t calculate_size() { return sizeof(u1); }
  size_t size() const { return calculate_size(); }
  int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }
  void set_offset_delta(int offset_delta) {
    assert(offset_delta <= 64, "Offset too large for same_frame");
    set_frame_type(offset_delta_to_frame_type(offset_delta));
  }
  int number_of_types() const { return 0; }
  verification_type_info* types() const { return NULL; }
  bool is_valid_offset(int offset_delta) const {
    return is_frame_type(offset_delta_to_frame_type(offset_delta));
  }
  bool verify_subtype(address start, address end) const {
    return true;
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("same_frame(@%d)", offset_delta() + current_offset);
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    print_on(st, current_offset);
  }
};
class same_frame_extended : public stack_map_frame {
 private:
  enum { _frame_id = 251 };
  address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
 public:
  static bool is_frame_type(u1 tag) {
    return tag == _frame_id;
  }
  static same_frame_extended* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame type");
    return (same_frame_extended*)addr;
  }
  static same_frame_extended* create_at(address addr, u2 offset_delta) {
    same_frame_extended* sm = (same_frame_extended*)addr;
    sm->set_frame_type(_frame_id);
    sm->set_offset_delta(offset_delta);
    return sm;
  }
  static size_t calculate_size() { return sizeof(u1) + sizeof(u2); }
  size_t size() const { return calculate_size(); }
  int offset_delta() const {
    return Bytes::get_Java_u2(offset_delta_addr()) + 1;
  }
  void set_offset_delta(int offset_delta) {
    Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
  }
  int number_of_types() const { return 0; }
  verification_type_info* types() const { return NULL; }
  bool is_valid_offset(int offset) const { return true; }
  bool verify_subtype(address start, address end) const {
    return frame_type_addr() + size() <= end;
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    print_on(st, current_offset);
  }
};
class same_locals_1_stack_item_frame : public stack_map_frame {
 private:
  address type_addr() const { return frame_type_addr() + sizeof(u1); }
  static int frame_type_to_offset_delta(u1 frame_type) {
      return frame_type - 63; }
  static u1 offset_delta_to_frame_type(int offset_delta) {
      return (u1)(offset_delta + 63); }
 public:
  static bool is_frame_type(u1 tag) {
    return tag >= 64 && tag < 128;
  }
  static same_locals_1_stack_item_frame* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame id");
    return (same_locals_1_stack_item_frame*)addr;
  }
  static same_locals_1_stack_item_frame* create_at(
      address addr, int offset_delta, verification_type_info* vti) {
    same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
    sm->set_offset_delta(offset_delta);
    if (vti != NULL) {
      sm->set_type(vti);
    }
    return sm;
  }
  static size_t calculate_size(verification_type_info* vti) {
    return sizeof(u1) + vti->size();
  }
  static size_t max_size() {
    return sizeof(u1) + verification_type_info::max_size();
  }
  size_t size() const { return calculate_size(types()); }
  int offset_delta() const { return frame_type_to_offset_delta(frame_type()); }
  void set_offset_delta(int offset_delta) {
    assert(offset_delta > 0 && offset_delta <= 64,
           "Offset too large for this frame type");
    set_frame_type(offset_delta_to_frame_type(offset_delta));
  }
  void set_type(verification_type_info* vti) {
    verification_type_info* cur = types();
    cur->copy_from(vti);
  }
  int number_of_types() const { return 1; }
  verification_type_info* types() const {
    return verification_type_info::at(type_addr());
  }
  bool is_valid_offset(int offset_delta) const {
    return is_frame_type(offset_delta_to_frame_type(offset_delta));
  }
  bool verify_subtype(address start, address end) const {
    return types()->verify(start, end);
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("same_locals_1_stack_item_frame(@%d,",
        offset_delta() + current_offset);
    types()->print_on(st);
    st->print(")");
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
              offset_delta() + current_offset);
  }
};
class same_locals_1_stack_item_extended : public stack_map_frame {
 private:
  address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
  address type_addr() const { return offset_delta_addr() + sizeof(u2); }
  enum { _frame_id = 247 };
 public:
  static bool is_frame_type(u1 tag) {
    return tag == _frame_id;
  }
  static same_locals_1_stack_item_extended* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame id");
    return (same_locals_1_stack_item_extended*)addr;
  }
  static same_locals_1_stack_item_extended* create_at(
      address addr, int offset_delta, verification_type_info* vti) {
    same_locals_1_stack_item_extended* sm =
       (same_locals_1_stack_item_extended*)addr;
    sm->set_frame_type(_frame_id);
    sm->set_offset_delta(offset_delta);
    if (vti != NULL) {
      sm->set_type(vti);
    }
    return sm;
  }
  static size_t calculate_size(verification_type_info* vti) {
    return sizeof(u1) + sizeof(u2) + vti->size();
  }
  size_t size() const { return calculate_size(types()); }
  int offset_delta() const {
    return Bytes::get_Java_u2(offset_delta_addr()) + 1;
  }
  void set_offset_delta(int offset_delta) {
    Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
  }
  void set_type(verification_type_info* vti) {
    verification_type_info* cur = types();
    cur->copy_from(vti);
  }
  int number_of_types() const { return 1; }
  verification_type_info* types() const {
    return verification_type_info::at(type_addr());
  }
  bool is_valid_offset(int offset) { return true; }
  bool verify_subtype(address start, address end) const {
    return type_addr() < end && types()->verify(start, end);
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("same_locals_1_stack_item_extended(@%d,",
        offset_delta() + current_offset);
    types()->print_on(st);
    st->print(")");
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",
              offset_delta() + current_offset);
  }
};
class chop_frame : public stack_map_frame {
 private:
  address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
  static int frame_type_to_chops(u1 frame_type) {
    int chop = 251 - frame_type;
    return chop;
  }
  static u1 chops_to_frame_type(int chop) {
    return 251 - chop;
  }
 public:
  static bool is_frame_type(u1 tag) {
    return frame_type_to_chops(tag) > 0 && frame_type_to_chops(tag) < 4;
  }
  static chop_frame* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame id");
    return (chop_frame*)addr;
  }
  static chop_frame* create_at(address addr, int offset_delta, int chops) {
    chop_frame* sm = (chop_frame*)addr;
    sm->set_chops(chops);
    sm->set_offset_delta(offset_delta);
    return sm;
  }
  static size_t calculate_size() {
    return sizeof(u1) + sizeof(u2);
  }
  size_t size() const { return calculate_size(); }
  int offset_delta() const {
    return Bytes::get_Java_u2(offset_delta_addr()) + 1;
  }
  void set_offset_delta(int offset_delta) {
    Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
  }
  int chops() const {
    int chops = frame_type_to_chops(frame_type());
    assert(chops > 0 && chops < 4, "Invalid number of chops in frame");
    return chops;
  }
  void set_chops(int chops) {
    assert(chops > 0 && chops <= 3, "Bad number of chops");
    set_frame_type(chops_to_frame_type(chops));
  }
  int number_of_types() const { return 0; }
  verification_type_info* types() const { return NULL; }
  bool is_valid_offset(int offset) { return true; }
  bool verify_subtype(address start, address end) const {
    return frame_type_addr() + size() <= end;
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    print_on(st, current_offset);
  }
};
class append_frame : public stack_map_frame {
 private:
  address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
  address types_addr() const { return offset_delta_addr() + sizeof(u2); }
  static int frame_type_to_appends(u1 frame_type) {
    int append = frame_type - 251;
    return append;
  }
  static u1 appends_to_frame_type(int appends) {
    assert(appends > 0 && appends < 4, "Invalid append amount");
    return 251 + appends;
  }
 public:
  static bool is_frame_type(u1 tag) {
    return frame_type_to_appends(tag) > 0 && frame_type_to_appends(tag) < 4;
  }
  static append_frame* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame id");
    return (append_frame*)addr;
  }
  static append_frame* create_at(
      address addr, int offset_delta, int appends,
      verification_type_info* types) {
    append_frame* sm = (append_frame*)addr;
    sm->set_appends(appends);
    sm->set_offset_delta(offset_delta);
    if (types != NULL) {
      verification_type_info* cur = sm->types();
      for (int i = 0; i < appends; ++i) {
        cur->copy_from(types);
        cur = cur->next();
        types = types->next();
      }
    }
    return sm;
  }
  static size_t calculate_size(int appends, verification_type_info* types) {
    size_t sz = sizeof(u1) + sizeof(u2);
    for (int i = 0; i < appends; ++i) {
      sz += types->size();
      types = types->next();
    }
    return sz;
  }
  static size_t max_size() {
    return sizeof(u1) + sizeof(u2) + 3 * verification_type_info::max_size();
  }
  size_t size() const { return calculate_size(number_of_types(), types()); }
  int offset_delta() const {
    return Bytes::get_Java_u2(offset_delta_addr()) + 1;
  }
  void set_offset_delta(int offset_delta) {
    Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
  }
  void set_appends(int appends) {
    assert(appends > 0 && appends < 4, "Bad number of appends");
    set_frame_type(appends_to_frame_type(appends));
  }
  int number_of_types() const {
    int appends = frame_type_to_appends(frame_type());
    assert(appends > 0 && appends < 4, "Invalid number of appends in frame");
    return appends;
  }
  verification_type_info* types() const {
    return verification_type_info::at(types_addr());
  }
  bool is_valid_offset(int offset) const { return true; }
  bool verify_subtype(address start, address end) const {
    verification_type_info* vti = types();
    if ((address)vti < end && vti->verify(start, end)) {
      int nof = number_of_types();
      vti = vti->next();
      if (nof < 2 || vti->verify(start, end)) {
        vti = vti->next();
        if (nof < 3 || vti->verify(start, end)) {
          return true;
        }
      }
    }
    return false;
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("append_frame(@%d,", offset_delta() + current_offset);
    verification_type_info* vti = types();
    for (int i = 0; i < number_of_types(); ++i) {
      vti->print_on(st);
      if (i != number_of_types() - 1) {
        st->print(",");
      }
      vti = vti->next();
    }
    st->print(")");
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
              offset_delta() + current_offset);
  }
};
class full_frame : public stack_map_frame {
 private:
  address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
  address num_locals_addr() const { return offset_delta_addr() + sizeof(u2); }
  address locals_addr() const { return num_locals_addr() + sizeof(u2); }
  address stack_slots_addr(address end_of_locals) const {
      return end_of_locals; }
  address stack_addr(address end_of_locals) const {
      return stack_slots_addr(end_of_locals) + sizeof(u2); }
  enum { _frame_id = 255 };
 public:
  static bool is_frame_type(u1 tag) {
    return tag == _frame_id;
  }
  static full_frame* at(address addr) {
    assert(is_frame_type(*addr), "Wrong frame id");
    return (full_frame*)addr;
  }
  static full_frame* create_at(
      address addr, int offset_delta, int num_locals,
      verification_type_info* locals,
      int stack_slots, verification_type_info* stack) {
    full_frame* sm = (full_frame*)addr;
    sm->set_frame_type(_frame_id);
    sm->set_offset_delta(offset_delta);
    sm->set_num_locals(num_locals);
    if (locals != NULL) {
      verification_type_info* cur = sm->locals();
      for (int i = 0; i < num_locals; ++i) {
        cur->copy_from(locals);
        cur = cur->next();
        locals = locals->next();
      }
      address end_of_locals = (address)cur;
      sm->set_stack_slots(end_of_locals, stack_slots);
      cur = sm->stack(end_of_locals);
      for (int i = 0; i < stack_slots; ++i) {
        cur->copy_from(stack);
        cur = cur->next();
        stack = stack->next();
      }
    }
    return sm;
  }
  static size_t calculate_size(
      int num_locals, verification_type_info* locals,
      int stack_slots, verification_type_info* stack) {
    size_t sz = sizeof(u1) + sizeof(u2) + sizeof(u2) + sizeof(u2);
    verification_type_info* vti = locals;
    for (int i = 0; i < num_locals; ++i) {
      sz += vti->size();
      vti = vti->next();
    }
    vti = stack;
    for (int i = 0; i < stack_slots; ++i) {
      sz += vti->size();
      vti = vti->next();
    }
    return sz;
  }
  static size_t max_size(int locals, int stack) {
    return sizeof(u1) + 3 * sizeof(u2) +
        (locals + stack) * verification_type_info::max_size();
  }
  size_t size() const {
    address eol = end_of_locals();
    return calculate_size(num_locals(), locals(), stack_slots(eol), stack(eol));
  }
  int offset_delta() const {
    return Bytes::get_Java_u2(offset_delta_addr()) + 1;
  }
  int num_locals() const { return Bytes::get_Java_u2(num_locals_addr()); }
  verification_type_info* locals() const {
    return verification_type_info::at(locals_addr());
  }
  address end_of_locals() const {
    verification_type_info* vti = locals();
    for (int i = 0; i < num_locals(); ++i) {
      vti = vti->next();
    }
    return (address)vti;
  }
  int stack_slots(address end_of_locals) const {
    return Bytes::get_Java_u2(stack_slots_addr(end_of_locals));
  }
  verification_type_info* stack(address end_of_locals) const {
    return verification_type_info::at(stack_addr(end_of_locals));
  }
  void set_offset_delta(int offset_delta) {
    Bytes::put_Java_u2(offset_delta_addr(), offset_delta - 1);
  }
  void set_num_locals(int num_locals) {
    Bytes::put_Java_u2(num_locals_addr(), num_locals);
  }
  void set_stack_slots(address end_of_locals, int stack_slots) {
    Bytes::put_Java_u2(stack_slots_addr(end_of_locals), stack_slots);
  }
  int number_of_types() const { return num_locals(); }
  verification_type_info* types() const { return locals(); }
  bool is_valid_offset(int offset) { return true; }
  bool verify_subtype(address start, address end) const {
    verification_type_info* vti = types();
    if ((address)vti >= end) {
      return false;
    }
    int count = number_of_types();
    for (int i = 0; i < count; ++i) {
      if (!vti->verify(start, end)) {
        return false;
      }
      vti = vti->next();
    }
    address eol = (address)vti;
    if (eol + sizeof(u2) > end) {
      return false;
    }
    count = stack_slots(eol);
    vti = stack(eol);
    for (int i = 0; i < stack_slots(eol); ++i) {
      if (!vti->verify(start, end)) {
        return false;
      }
      vti = vti->next();
    }
    return true;
  }
  void print_on(outputStream* st, int current_offset = -1) const {
    st->print("full_frame(@%d,{", offset_delta() + current_offset);
    verification_type_info* vti = locals();
    for (int i = 0; i < num_locals(); ++i) {
      vti->print_on(st);
      if (i != num_locals() - 1) {
        st->print(",");
      }
      vti = vti->next();
    }
    st->print("},{");
    address end_of_locals = (address)vti;
    vti = stack(end_of_locals);
    int ss = stack_slots(end_of_locals);
    for (int i = 0; i < ss; ++i) {
      vti->print_on(st);
      if (i != ss - 1) {
        st->print(",");
      }
      vti = vti->next();
    }
    st->print("})");
  }
  void print_truncated(outputStream* st, int current_offset = -1) const {
    st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",
              offset_delta() + current_offset);
  }
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
  stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
  if (item_##stack_frame_type != NULL) { \
    return item_##stack_frame_type->func_name args;  \
  }
#define VOID_VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
  stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
  if (item_##stack_frame_type != NULL) { \
    item_##stack_frame_type->func_name args;  \
    return; \
  }
size_t stack_map_frame::size() const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, size, ());
  return 0;
}
int stack_map_frame::offset_delta() const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, offset_delta, ());
  return 0;
}
void stack_map_frame::set_offset_delta(int offset_delta) {
  FOR_EACH_STACKMAP_FRAME_TYPE(
      VOID_VIRTUAL_DISPATCH, set_offset_delta, (offset_delta));
}
int stack_map_frame::number_of_types() const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, number_of_types, ());
  return 0;
}
verification_type_info* stack_map_frame::types() const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, types, ());
  return NULL;
}
bool stack_map_frame::is_valid_offset(int offset) const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VIRTUAL_DISPATCH, is_valid_offset, (offset));
  return true;
}
bool stack_map_frame::verify(address start, address end) const {
  if (frame_type_addr() >= start && frame_type_addr() < end) {
    FOR_EACH_STACKMAP_FRAME_TYPE(
       VIRTUAL_DISPATCH, verify_subtype, (start, end));
  }
  return false;
}
void stack_map_frame::print_on(outputStream* st, int offs = -1) const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
}
void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {
  FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));
}
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
#define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \
stack_frame_type* stack_map_frame::as_##stack_frame_type() const { \
  if (stack_frame_type::is_frame_type(frame_type())) { \
    return (stack_frame_type*)this; \
  } else { \
    return NULL; \
  } \
}
FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
#undef AS_SUBTYPE_DEF
class stack_map_table {
 private:
  address number_of_entries_addr() const {
    return (address)this;
  }
  address entries_addr() const {
    return number_of_entries_addr() + sizeof(u2);
  }
 protected:
  stack_map_table() {}
  stack_map_table(const stack_map_table&) {}
 public:
  static stack_map_table* at(address addr) {
    return (stack_map_table*)addr;
  }
  u2 number_of_entries() const {
    return Bytes::get_Java_u2(number_of_entries_addr());
  }
  stack_map_frame* entries() const {
    return stack_map_frame::at(entries_addr());
  }
  void set_number_of_entries(u2 num) {
    Bytes::put_Java_u2(number_of_entries_addr(), num);
  }
};
class stack_map_table_attribute {
 private:
  address name_index_addr() const {
      return (address)this; }
  address attribute_length_addr() const {
      return name_index_addr() + sizeof(u2); }
  address stack_map_table_addr() const {
      return attribute_length_addr() + sizeof(u4); }
 protected:
  stack_map_table_attribute() {}
  stack_map_table_attribute(const stack_map_table_attribute&) {}
 public:
  static stack_map_table_attribute* at(address addr) {
    return (stack_map_table_attribute*)addr;
  }
  u2 name_index() const {
    return Bytes::get_Java_u2(name_index_addr()); }
  u4 attribute_length() const {
    return Bytes::get_Java_u4(attribute_length_addr()); }
  stack_map_table* table() const {
    return stack_map_table::at(stack_map_table_addr());
  }
  void set_name_index(u2 idx) {
    Bytes::put_Java_u2(name_index_addr(), idx);
  }
  void set_attribute_length(u4 len) {
    Bytes::put_Java_u4(attribute_length_addr(), len);
  }
};
#undef FOR_EACH_STACKMAP_FRAME_TYPE
#endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
C:\hotspot-69087d08d473\src\share\vm/classfile/symbolTable.cpp
#include "precompiled.hpp"
#include "classfile/altHashing.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/hashtable.inline.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/g1StringDedup.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
const int ClaimChunkSize = 32;
SymbolTable* SymbolTable::_the_table = NULL;
Arena* SymbolTable::_arena = NULL;
bool SymbolTable::_needs_rehashing = false;
Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
  assert (len <= Symbol::max_length(), "should be checked by caller");
  Symbol* sym;
  if (DumpSharedSpaces) {
    sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
  } else if (c_heap) {
    sym = new (len, THREAD) Symbol(name, len, 1);
    assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
  } else {
    sym = new (len, arena(), THREAD) Symbol(name, len, -1);
  }
  return sym;
}
void SymbolTable::initialize_symbols(int arena_alloc_size) {
  if (arena_alloc_size == 0) {
    _arena = new (mtSymbol) Arena(mtSymbol);
  } else {
    _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size);
  }
}
void SymbolTable::symbols_do(SymbolClosure *cl) {
  const int n = the_table()->table_size();
  for (int i = 0; i < n; i++) {
    for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
         p != NULL;
         p = p->next()) {
      cl->do_symbol(p->literal_addr());
    }
  }
}
int SymbolTable::_symbols_removed = 0;
int SymbolTable::_symbols_counted = 0;
volatile int SymbolTable::_parallel_claimed_idx = 0;
void SymbolTable::buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context, size_t* memory_total) {
  for (int i = start_idx; i < end_idx; ++i) {
    HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
    HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
    while (entry != NULL) {
      if (entry->is_shared() && !use_alternate_hashcode()) {
        break;
      }
      Symbol* s = entry->literal();
      (*memory_total) += s->size();
      context->_num_processed++;
      assert(s != NULL, "just checking");
      if (s->refcount() == 0) {
        assert(!entry->is_shared(), "shared entries should be kept live");
        delete s;
        context->free_entry(entry);
      } else {
        p = entry->next_addr();
      }
      entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);
    }
  }
}
void SymbolTable::unlink(int* processed, int* removed) {
  size_t memory_total = 0;
  BucketUnlinkContext context;
  buckets_unlink(0, the_table()->table_size(), &context, &memory_total);
  _the_table->bulk_free_entries(&context);
  _symbols_removed = context._num_removed;
  _symbols_counted = context._num_processed;
  if (PrintGCDetails && Verbose && WizardMode) {
    gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed,
                        (memory_total*HeapWordSize)/1024);
  }
}
void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {
  const int limit = the_table()->table_size();
  size_t memory_total = 0;
  BucketUnlinkContext context;
  for (;;) {
    int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
    if (start_idx >= limit) {
      break;
    }
    int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
    buckets_unlink(start_idx, end_idx, &context, &memory_total);
  }
  _the_table->bulk_free_entries(&context);
  Atomic::add(context._num_processed, &_symbols_counted);
  Atomic::add(context._num_removed, &_symbols_removed);
  if (PrintGCDetails && Verbose && WizardMode) {
    gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed,
                        (memory_total*HeapWordSize)/1024);
  }
}
void SymbolTable::rehash_table() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  if (DumpSharedSpaces) return;
  SymbolTable* new_table = new SymbolTable();
  the_table()->move_to(new_table);
  delete _the_table;
  _needs_rehashing = false;
  _the_table = new_table;
}
Symbol* SymbolTable::lookup(int index, const char* name,
                              int len, unsigned int hash) {
  int count = 0;
  for (HashtableEntry<Symbol*, mtSymbol>* e = bucket(index); e != NULL; e = e->next()) {
    count++;  // count all entries in this bucket, not just ones with same hash
    if (e->hash() == hash) {
      Symbol* sym = e->literal();
      if (sym->equals(name, len)) {
        sym->increment_refcount();
        return sym;
      }
    }
  }
  if (count >= rehash_count && !needs_rehashing()) {
    _needs_rehashing = check_rehash_table(count);
  }
  return NULL;
}
unsigned int SymbolTable::hash_symbol(const char* s, int len) {
  return use_alternate_hashcode() ?
           AltHashing::halfsiphash_32(seed(), (const uint8_t*)s, len) :
           java_lang_String::hash_code(s, len);
}
Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
  unsigned int hashValue = hash_symbol(name, len);
  int index = the_table()->hash_to_index(hashValue);
  Symbol* s = the_table()->lookup(index, name, len, hashValue);
  if (s != NULL) return s;
  MutexLocker ml(SymbolTable_lock, THREAD);
  return the_table()->basic_add(index, (u1*)name, len, hashValue, true, THREAD);
}
Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
  char* buffer;
  int index, len;
  unsigned int hashValue;
  char* name;
  {
    debug_only(No_Safepoint_Verifier nsv;)
    name = (char*)sym->base() + begin;
    len = end - begin;
    hashValue = hash_symbol(name, len);
    index = the_table()->hash_to_index(hashValue);
    Symbol* s = the_table()->lookup(index, name, len, hashValue);
    if (s != NULL) return s;
  }
  char stack_buf[128];
  ResourceMark rm(THREAD);
  if (len <= 128) {
    buffer = stack_buf;
  } else {
    buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
  }
  for (int i=0; i<len; i++) {
    buffer[i] = name[i];
  }
  MutexLocker ml(SymbolTable_lock, THREAD);
  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, THREAD);
}
Symbol* SymbolTable::lookup_only(const char* name, int len,
                                   unsigned int& hash) {
  hash = hash_symbol(name, len);
  int index = the_table()->hash_to_index(hash);
  Symbol* s = the_table()->lookup(index, name, len, hash);
  return s;
}
Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){
  unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length());
  int index = the_table()->hash_to_index(hash);
  for (HashtableEntry<Symbol*, mtSymbol>* e = the_table()->bucket(index); e != NULL; e = e->next()) {
    if (e->hash() == hash) {
      Symbol* literal_sym = e->literal();
      if (sym == literal_sym) {
        return e->literal_addr();
      }
    }
  }
  return NULL;
}
Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
  int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
  char stack_buf[128];
  if (utf8_length < (int) sizeof(stack_buf)) {
    char* chars = stack_buf;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup(chars, utf8_length, THREAD);
  } else {
    ResourceMark rm(THREAD);
    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup(chars, utf8_length, THREAD);
  }
}
Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
                                           unsigned int& hash) {
  int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
  char stack_buf[128];
  if (utf8_length < (int) sizeof(stack_buf)) {
    char* chars = stack_buf;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup_only(chars, utf8_length, hash);
  } else {
    ResourceMark rm;
    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup_only(chars, utf8_length, hash);
  }
}
void SymbolTable::add(ClassLoaderData* loader_data, constantPoolHandle cp,
                      int names_count,
                      const char** names, int* lengths, int* cp_indices,
                      unsigned int* hashValues, TRAPS) {
  MutexLocker ml(SymbolTable_lock, THREAD);
  SymbolTable* table = the_table();
  bool added = table->basic_add(loader_data, cp, names_count, names, lengths,
                                cp_indices, hashValues, CHECK);
  if (!added) {
    for (int i=0; i<names_count; i++) {
      int index = table->hash_to_index(hashValues[i]);
      bool c_heap = !loader_data->is_the_null_class_loader_data();
      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], c_heap, CHECK);
      cp->symbol_at_put(cp_indices[i], sym);
    }
  }
}
Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
  unsigned int hash;
  Symbol* result = SymbolTable::lookup_only((char*)name, (int)strlen(name), hash);
  if (result != NULL) {
    return result;
  }
  MutexLocker ml(SymbolTable_lock, THREAD);
  SymbolTable* table = the_table();
  int index = table->hash_to_index(hash);
  return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);
}
Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len,
                               unsigned int hashValue_arg, bool c_heap, TRAPS) {
  assert(!Universe::heap()->is_in_reserved(name),
         "proposed name of symbol must be stable");
  if (len > Symbol::max_length()) {
    THROW_MSG_0(vmSymbols::java_lang_InternalError(),
                "name is too long to represent");
  }
  No_Safepoint_Verifier nsv;
  unsigned int hashValue;
  int index;
  if (use_alternate_hashcode()) {
    hashValue = hash_symbol((const char*)name, len);
    index = hash_to_index(hashValue);
  } else {
    hashValue = hashValue_arg;
    index = index_arg;
  }
  Symbol* test = lookup(index, (char*)name, len, hashValue);
  if (test != NULL) {
    assert(test->refcount() != 0, "lookup should have incremented the count");
    return test;
  }
  Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL);
  assert(sym->equals((char*)name, len), "symbol must be properly initialized");
  HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym);
  add_entry(index, entry);
  return sym;
}
bool SymbolTable::basic_add(ClassLoaderData* loader_data, constantPoolHandle cp,
                            int names_count,
                            const char** names, int* lengths,
                            int* cp_indices, unsigned int* hashValues,
                            TRAPS) {
  for (int i = 0; i< names_count; i++) {
    if (lengths[i] > Symbol::max_length()) {
      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
                  "name is too long to represent");
    }
  }
  No_Safepoint_Verifier nsv;
  for (int i=0; i<names_count; i++) {
    unsigned int hashValue;
    if (use_alternate_hashcode()) {
      hashValue = hash_symbol(names[i], lengths[i]);
    } else {
      hashValue = hashValues[i];
    }
    int index = hash_to_index(hashValue);
    Symbol* test = lookup(index, names[i], lengths[i], hashValue);
    if (test != NULL) {
      cp->symbol_at_put(cp_indices[i], test);
      assert(test->refcount() != 0, "lookup should have incremented the count");
    } else {
      bool c_heap = !loader_data->is_the_null_class_loader_data();
      Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false));
      assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized");  // why wouldn't it be???
      HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym);
      add_entry(index, entry);
      cp->symbol_at_put(cp_indices[i], sym);
    }
  }
  return true;
}
void SymbolTable::verify() {
  for (int i = 0; i < the_table()->table_size(); ++i) {
    HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
    for ( ; p != NULL; p = p->next()) {
      Symbol* s = (Symbol*)(p->literal());
      guarantee(s != NULL, "symbol is NULL");
      unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length());
      guarantee(p->hash() == h, "broken hash in symbol table entry");
      guarantee(the_table()->hash_to_index(h) == i,
                "wrong index in symbol table");
    }
  }
}
void SymbolTable::dump(outputStream* st) {
  the_table()->dump_table(st, "SymbolTable");
}
#ifndef PRODUCT
void SymbolTable::print_histogram() {
  MutexLocker ml(SymbolTable_lock);
  const int results_length = 100;
  int results[results_length];
  int i,j;
  for (j = 0; j < results_length; j++) {
    results[j] = 0;
  }
  int total = 0;
  int max_symbols = 0;
  int out_of_range = 0;
  int memory_total = 0;
  int count = 0;
  for (i = 0; i < the_table()->table_size(); i++) {
    HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
    for ( ; p != NULL; p = p->next()) {
      memory_total += p->literal()->size();
      count++;
      int counter = p->literal()->utf8_length();
      total += counter;
      if (counter < results_length) {
        results[counter]++;
      } else {
        out_of_range++;
      }
      max_symbols = MAX2(max_symbols, counter);
    }
  }
  tty->print_cr("Symbol Table:");
  tty->print_cr("Total number of symbols  %5d", count);
  tty->print_cr("Total size in memory     %5dK",
          (memory_total*HeapWordSize)/1024);
  tty->print_cr("Total counted            %5d", _symbols_counted);
  tty->print_cr("Total removed            %5d", _symbols_removed);
  if (_symbols_counted > 0) {
    tty->print_cr("Percent removed          %3.2f",
          ((float)_symbols_removed/(float)_symbols_counted)* 100);
  }
  tty->print_cr("Reference counts         %5d", Symbol::_total_count);
  tty->print_cr("Symbol arena size        %5d used %5d",
                 arena()->size_in_bytes(), arena()->used());
  tty->print_cr("Histogram of symbol length:");
  tty->print_cr("%8s %5d", "Total  ", total);
  tty->print_cr("%8s %5d", "Maximum", max_symbols);
  tty->print_cr("%8s %3.2f", "Average",
          ((float) total / (float) the_table()->table_size()));
  tty->print_cr("%s", "Histogram:");
  tty->print_cr(" %s %29s", "Length", "Number chains that length");
  for (i = 0; i < results_length; i++) {
    if (results[i] > 0) {
      tty->print_cr("%6d %10d", i, results[i]);
    }
  }
  if (Verbose) {
    int line_length = 70;
    tty->print_cr("%s %30s", " Length", "Number chains that length");
    for (i = 0; i < results_length; i++) {
      if (results[i] > 0) {
        tty->print("%4d", i);
        for (j = 0; (j < results[i]) && (j < line_length);  j++) {
          tty->print("%1s", "*");
        }
        if (j == line_length) {
          tty->print("%1s", "+");
        }
        tty->cr();
      }
    }
  }
  tty->print_cr(" %s %d: %d\n", "Number chains longer than",
                    results_length, out_of_range);
}
void SymbolTable::print() {
  for (int i = 0; i < the_table()->table_size(); ++i) {
    HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
    HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
    if (entry != NULL) {
      while (entry != NULL) {
        tty->print(PTR_FORMAT " ", entry->literal());
        entry->literal()->print();
        tty->print(" %d", entry->literal()->refcount());
        p = entry->next_addr();
        entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);
      }
      tty->cr();
    }
  }
}
#endif // PRODUCT
#ifdef ASSERT
class StableMemoryChecker : public StackObj {
  enum { _bufsize = wordSize*4 };
  address _region;
  jint    _size;
  u1      _save_buf[_bufsize];
  int sample(u1* save_buf) {
    if (_size <= _bufsize) {
      memcpy(save_buf, _region, _size);
      return _size;
    } else {
      memcpy(&save_buf[0],          _region,                      _bufsize/2);
      memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2);
      return (_bufsize/2)*2;
    }
  }
 public:
  StableMemoryChecker(const void* region, jint size) {
    _region = (address) region;
    _size   = size;
    sample(_save_buf);
  }
  bool verify() {
    u1 check_buf[sizeof(_save_buf)];
    int check_size = sample(check_buf);
    return (0 == memcmp(_save_buf, check_buf, check_size));
  }
  void set_region(const void* region) { _region = (address) region; }
};
#endif
StringTable* StringTable::_the_table = NULL;
bool StringTable::_needs_rehashing = false;
volatile int StringTable::_parallel_claimed_idx = 0;
unsigned int StringTable::hash_string(const jchar* s, int len) {
  return use_alternate_hashcode() ? AltHashing::halfsiphash_32(seed(), s, len) :
                                    java_lang_String::hash_code(s, len);
}
oop StringTable::lookup(int index, jchar* name,
                        int len, unsigned int hash) {
  int count = 0;
  for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
    count++;
    if (l->hash() == hash) {
      if (java_lang_String::equals(l->literal(), name, len)) {
        return l->literal();
      }
    }
  }
  if (count >= rehash_count && !needs_rehashing()) {
    _needs_rehashing = check_rehash_table(count);
  }
  return NULL;
}
oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
                           int len, unsigned int hashValue_arg, TRAPS) {
  assert(java_lang_String::equals(string(), name, len),
         "string must be properly initialized");
  No_Safepoint_Verifier nsv;
  unsigned int hashValue;
  int index;
  if (use_alternate_hashcode()) {
    hashValue = hash_string(name, len);
    index = hash_to_index(hashValue);
  } else {
    hashValue = hashValue_arg;
    index = index_arg;
  }
  oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
  if (test != NULL) {
    return test;
  }
  HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
  add_entry(index, entry);
  return string();
}
oop StringTable::lookup(Symbol* symbol) {
  ResourceMark rm;
  int length;
  jchar* chars = symbol->as_unicode(length);
  return lookup(chars, length);
}
static void ensure_string_alive(oop string) {
#if INCLUDE_ALL_GCS
  if (UseG1GC && string != NULL) {
    G1SATBCardTableModRefBS::enqueue(string);
  }
#endif
}
oop StringTable::lookup(jchar* name, int len) {
  unsigned int hash = hash_string(name, len);
  int index = the_table()->hash_to_index(hash);
  oop string = the_table()->lookup(index, name, len, hash);
  ensure_string_alive(string);
  return string;
}
oop StringTable::intern(Handle string_or_null, jchar* name,
                        int len, TRAPS) {
  unsigned int hashValue = hash_string(name, len);
  int index = the_table()->hash_to_index(hashValue);
  oop found_string = the_table()->lookup(index, name, len, hashValue);
  if (found_string != NULL) {
    ensure_string_alive(found_string);
    return found_string;
  }
  debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
  assert(!Universe::heap()->is_in_reserved(name),
         "proposed name of symbol must be stable");
  Handle string;
  if (!string_or_null.is_null()) {
    string = string_or_null;
  } else {
    string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
  }
#if INCLUDE_ALL_GCS
  if (G1StringDedup::is_enabled()) {
    G1StringDedup::deduplicate(string());
  }
#endif
  oop added_or_found;
  {
    MutexLocker ml(StringTable_lock, THREAD);
    added_or_found = the_table()->basic_add(index, string, name, len,
                                  hashValue, CHECK_NULL);
  }
  ensure_string_alive(added_or_found);
  return added_or_found;
}
oop StringTable::intern(Symbol* symbol, TRAPS) {
  if (symbol == NULL) return NULL;
  ResourceMark rm(THREAD);
  int length;
  jchar* chars = symbol->as_unicode(length);
  Handle string;
  oop result = intern(string, chars, length, CHECK_NULL);
  return result;
}
oop StringTable::intern(oop string, TRAPS)
{
  if (string == NULL) return NULL;
  ResourceMark rm(THREAD);
  int length;
  Handle h_string (THREAD, string);
  jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);
  oop result = intern(h_string, chars, length, CHECK_NULL);
  return result;
}
oop StringTable::intern(const char* utf8_string, TRAPS) {
  if (utf8_string == NULL) return NULL;
  ResourceMark rm(THREAD);
  int length = UTF8::unicode_length(utf8_string);
  jchar* chars = NEW_RESOURCE_ARRAY(jchar, length);
  UTF8::convert_to_unicode(utf8_string, chars, length);
  Handle string;
  oop result = intern(string, chars, length, CHECK_NULL);
  return result;
}
void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
  BucketUnlinkContext context;
  buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), &context);
  _the_table->bulk_free_entries(&context);
}
void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  const int limit = the_table()->table_size();
  BucketUnlinkContext context;
  for (;;) {
    int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
    if (start_idx >= limit) {
      break;
    }
    int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
    buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, &context);
  }
  _the_table->bulk_free_entries(&context);
}
void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {
  const int limit = the_table()->table_size();
  assert(0 <= start_idx && start_idx <= limit,
         err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));
  assert(0 <= end_idx && end_idx <= limit,
         err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));
  assert(start_idx <= end_idx,
         err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
                 start_idx, end_idx));
  for (int i = start_idx; i < end_idx; i += 1) {
    HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
    while (entry != NULL) {
      assert(!entry->is_shared(), "CDS not used for the StringTable");
      f->do_oop((oop*)entry->literal_addr());
      entry = entry->next();
    }
  }
}
void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, BucketUnlinkContext* context) {
  const int limit = the_table()->table_size();
  assert(0 <= start_idx && start_idx <= limit,
         err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));
  assert(0 <= end_idx && end_idx <= limit,
         err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));
  assert(start_idx <= end_idx,
         err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
                 start_idx, end_idx));
  for (int i = start_idx; i < end_idx; ++i) {
    HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
    HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
    while (entry != NULL) {
      assert(!entry->is_shared(), "CDS not used for the StringTable");
      if (is_alive->do_object_b(entry->literal())) {
        if (f != NULL) {
          f->do_oop((oop*)entry->literal_addr());
        }
        p = entry->next_addr();
      } else {
        context->free_entry(entry);
      }
      context->_num_processed++;
      entry = *p;
    }
  }
}
void StringTable::oops_do(OopClosure* f) {
  buckets_oops_do(f, 0, the_table()->table_size());
}
void StringTable::possibly_parallel_oops_do(OopClosure* f) {
  const int limit = the_table()->table_size();
  for (;;) {
    int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
    if (start_idx >= limit) {
      break;
    }
    int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
    buckets_oops_do(f, start_idx, end_idx);
  }
}
void StringTable::verify() {
  for (int i = 0; i < the_table()->table_size(); ++i) {
    HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
    for ( ; p != NULL; p = p->next()) {
      oop s = p->literal();
      guarantee(s != NULL, "interned string is NULL");
      unsigned int h = java_lang_String::hash_string(s);
      guarantee(p->hash() == h, "broken hash in string table entry");
      guarantee(the_table()->hash_to_index(h) == i,
                "wrong index in string table");
    }
  }
}
void StringTable::dump(outputStream* st) {
  the_table()->dump_table(st, "StringTable");
}
StringTable::VerifyRetTypes StringTable::compare_entries(
                                      int bkt1, int e_cnt1,
                                      HashtableEntry<oop, mtSymbol>* e_ptr1,
                                      int bkt2, int e_cnt2,
                                      HashtableEntry<oop, mtSymbol>* e_ptr2) {
  oop str1 = e_ptr1->literal();
  oop str2 = e_ptr2->literal();
  if (str1 == str2) {
    tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
                  "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
                  (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2);
    return _verify_fail_continue;
  }
  if (java_lang_String::equals(str1, str2)) {
    tty->print_cr("ERROR: identical String values in entry @ "
                  "bucket[%d][%d] and entry @ bucket[%d][%d]",
                  bkt1, e_cnt1, bkt2, e_cnt2);
    return _verify_fail_continue;
  }
  return _verify_pass;
}
StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,
                                      HashtableEntry<oop, mtSymbol>* e_ptr,
                                      StringTable::VerifyMesgModes mesg_mode) {
  VerifyRetTypes ret = _verify_pass;  // be optimistic
  oop str = e_ptr->literal();
  if (str == NULL) {
    if (mesg_mode == _verify_with_mesgs) {
      tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt,
                    e_cnt);
    }
    return _verify_fail_done;
  }
  if (str->klass() != SystemDictionary::String_klass()) {
    if (mesg_mode == _verify_with_mesgs) {
      tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]",
                    bkt, e_cnt);
    }
    return _verify_fail_done;
  }
  unsigned int h = java_lang_String::hash_string(str);
  if (e_ptr->hash() != h) {
    if (mesg_mode == _verify_with_mesgs) {
      tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "
                    "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h);
    }
    ret = _verify_fail_continue;
  }
  if (the_table()->hash_to_index(h) != bkt) {
    if (mesg_mode == _verify_with_mesgs) {
      tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], "
                    "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h,
                    the_table()->hash_to_index(h));
    }
    ret = _verify_fail_continue;
  }
  return ret;
}
int StringTable::verify_and_compare_entries() {
  assert(StringTable_lock->is_locked(), "sanity check");
  int  fail_cnt = 0;
  for (int bkt = 0; bkt < the_table()->table_size(); bkt++) {
    HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt);
    for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) {
      VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs);
      if (ret != _verify_pass) {
        fail_cnt++;
      }
    }
  }
  bool need_entry_verify = (fail_cnt != 0);
  for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) {
    HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1);
    for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) {
      if (need_entry_verify) {
        VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1,
                                          _verify_quietly);
        if (ret == _verify_fail_done) {
          continue;
        }
      }
      for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) {
        HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2);
        int e_cnt2;
        for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) {
          if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) {
            continue;
          }
          if (need_entry_verify) {
            VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2,
                                              _verify_quietly);
            if (ret == _verify_fail_done) {
              continue;
            }
          }
          if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2)
              != _verify_pass) {
            fail_cnt++;
          }
        }
      }
    }
  }
  return fail_cnt;
}
void StringTable::rehash_table() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  if (DumpSharedSpaces) return;
  StringTable* new_table = new StringTable();
  the_table()->move_to(new_table);
  delete _the_table;
  _needs_rehashing = false;
  _the_table = new_table;
}
C:\hotspot-69087d08d473\src\share\vm/classfile/symbolTable.hpp
#ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
#define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
#include "memory/allocation.inline.hpp"
#include "oops/symbol.hpp"
#include "utilities/hashtable.hpp"
class BoolObjectClosure;
class outputStream;
class TempNewSymbol : public StackObj {
  Symbol* _temp;
 public:
  TempNewSymbol() : _temp(NULL) {}
  TempNewSymbol(Symbol *s) : _temp(s) {}
  void operator=(const TempNewSymbol &s) {
    _temp = s._temp;
    if (_temp !=NULL) _temp->increment_refcount();
  }
  void clear() { if (_temp != NULL)  _temp->decrement_refcount();  _temp = NULL; }
  ~TempNewSymbol() { clear(); }
  Symbol* operator -> () const                   { return _temp; }
  bool    operator == (Symbol* o) const          { return _temp == o; }
  operator Symbol*()                             { return _temp; }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值