sssssss10


ciKlass* ciMethod::return_profiled_type(int bci) {
  if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) {
    ciProfileData* data = method_data()->bci_to_data(bci);
    if (data != NULL) {
      if (data->is_VirtualCallTypeData()) {
        assert_virtual_call_type_ok(bci);
        ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
        ciKlass* type = call->valid_return_type();
        if (type != NULL && !call->return_maybe_null()) {
          return type;
        }
      } else if (data->is_CallTypeData()) {
        assert_call_type_ok(bci);
        ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
        ciKlass* type = call->valid_return_type();
        if (type != NULL && !call->return_maybe_null()) {
          return type;
        }
      }
    }
  }
  return NULL;
}
ciKlass* ciMethod::parameter_profiled_type(int i) {
  if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
    ciParametersTypeData* parameters = method_data()->parameters_type_data();
    if (parameters != NULL && i < parameters->number_of_parameters()) {
      ciKlass* type = parameters->valid_parameter_type(i);
      if (type != NULL && !parameters->parameter_maybe_null(i)) {
        return type;
      }
    }
  }
  return NULL;
}
ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
                                            ciInstanceKlass* callee_holder,
                                            ciInstanceKlass* actual_recv,
                                            bool check_access) {
  check_is_loaded();
  if (actual_recv->is_interface()) {
    return NULL;
  }
  ciMethod* root_m = resolve_invoke(caller, actual_recv, check_access);
  if (root_m == NULL) {
    return NULL;
  }
  assert(!root_m->is_abstract(), "resolve_invoke promise");
  if (root_m->can_be_statically_bound()) {
    return root_m;
  }
  if (actual_recv->is_leaf_type() && actual_recv == root_m->holder()) {
    return root_m;
  }
  if (!UseCHA)  return NULL;
  VM_ENTRY_MARK;
  if (root_m->get_Method()->is_default_method()) {
    return NULL;
  }
  methodHandle target;
  {
    MutexLocker locker(Compile_lock);
    Klass* context = actual_recv->get_Klass();
    target = Dependencies::find_unique_concrete_method(context,
                                                       root_m->get_Method());
  }
#ifndef PRODUCT
  if (TraceDependencies && target() != NULL && target() != root_m->get_Method()) {
    tty->print("found a non-root unique target method");
    tty->print_cr("  context = %s", InstanceKlass::cast(actual_recv->get_Klass())->external_name());
    tty->print("  method  = ");
    target->print_short_name(tty);
    tty->cr();
  }
#endif //PRODUCT
  if (target() == NULL) {
    return NULL;
  }
  if (target() == root_m->get_Method()) {
    return root_m;
  }
  if (!root_m->is_public() &&
      !root_m->is_protected()) {
    return NULL;
  }
  return CURRENT_THREAD_ENV->get_method(target());
}
ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access) {
   check_is_loaded();
   VM_ENTRY_MARK;
   KlassHandle caller_klass (THREAD, caller->get_Klass());
   KlassHandle h_recv       (THREAD, exact_receiver->get_Klass());
   KlassHandle h_resolved   (THREAD, holder()->get_Klass());
   Symbol* h_name      = name()->get_symbol();
   Symbol* h_signature = signature()->get_symbol();
   methodHandle m;
   if (h_recv->oop_is_array()
        ||
       InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
     if (holder()->is_interface()) {
       m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
     } else {
       m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
     }
   }
   if (m.is_null()) {
     return NULL;
   }
   ciMethod* result = this;
   if (m() != get_Method()) {
     result = CURRENT_THREAD_ENV->get_method(m());
   }
   if (result->is_abstract()) {
     return NULL;
   } else {
     return result;
   }
}
int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
   check_is_loaded();
   int vtable_index = Method::invalid_vtable_index;
   if (!receiver->is_interface()
       && (!receiver->is_instance_klass() ||
           receiver->as_instance_klass()->is_linked())) {
     VM_ENTRY_MARK;
     KlassHandle caller_klass (THREAD, caller->get_Klass());
     KlassHandle h_recv       (THREAD, receiver->get_Klass());
     Symbol* h_name = name()->get_symbol();
     Symbol* h_signature = signature()->get_symbol();
     vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
     if (vtable_index == Method::nonvirtual_vtable_index) {
       vtable_index = Method::invalid_vtable_index;
     }
   }
   return vtable_index;
}
int ciMethod::interpreter_call_site_count(int bci) {
  if (method_data() != NULL) {
    ResourceMark rm;
    ciProfileData* data = method_data()->bci_to_data(bci);
    if (data != NULL && data->is_CounterData()) {
      return scale_count(data->as_CounterData()->count());
    }
  }
  return -1;  // unknown
}
ciField* ciMethod::get_field_at_bci(int bci, bool &will_link) {
  ciBytecodeStream iter(this);
  iter.reset_to_bci(bci);
  iter.next();
  return iter.get_field(will_link);
}
ciMethod* ciMethod::get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature) {
  ciBytecodeStream iter(this);
  iter.reset_to_bci(bci);
  iter.next();
  return iter.get_method(will_link, declared_signature);
}
int ciMethod::scale_count(int count, float prof_factor) {
  if (count > 0 && method_data() != NULL) {
    int counter_life;
    int method_life = interpreter_invocation_count();
    if (TieredCompilation) {
      counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count());
    } else {
      int current_mileage = method_data()->current_mileage();
      int creation_mileage = method_data()->creation_mileage();
      counter_life = current_mileage - creation_mileage;
    }
    if (counter_life > method_life)
      counter_life = method_life;
    if (0 < counter_life && counter_life <= method_life) {
      count = (int)((double)count * prof_factor * method_life / counter_life + 0.5);
      count = (count > 0) ? count : 1;
    }
  }
  return count;
}
bool ciMethod::is_ignored_by_security_stack_walk() const {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->is_ignored_by_security_stack_walk();
}
bool ciMethod::is_method_handle_intrinsic() const {
  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
  return (MethodHandles::is_signature_polymorphic(iid) &&
          MethodHandles::is_signature_polymorphic_intrinsic(iid));
}
bool ciMethod::is_compiled_lambda_form() const {
  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
  return iid == vmIntrinsics::_compiledLambdaForm;
}
bool ciMethod::is_object_initializer() const {
   return name() == ciSymbol::object_initializer_name();
}
bool ciMethod::has_member_arg() const {
  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
  return (MethodHandles::is_signature_polymorphic(iid) &&
          MethodHandles::has_member_arg(iid));
}
bool ciMethod::ensure_method_data(methodHandle h_m) {
  EXCEPTION_CONTEXT;
  if (is_native() || is_abstract() || h_m()->is_accessor()) {
    return true;
  }
  if (h_m()->method_data() == NULL) {
    Method::build_interpreter_method_data(h_m, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
    }
  }
  if (h_m()->method_data() != NULL) {
    _method_data = CURRENT_ENV->get_method_data(h_m()->method_data());
    _method_data->load_data();
    return true;
  } else {
    _method_data = CURRENT_ENV->get_empty_methodData();
    return false;
  }
}
bool ciMethod::ensure_method_data() {
  bool result = true;
  if (_method_data == NULL || _method_data->is_empty()) {
    GUARDED_VM_ENTRY({
      result = ensure_method_data(get_Method());
    });
  }
  return result;
}
ciMethodData* ciMethod::method_data() {
  if (_method_data != NULL) {
    return _method_data;
  }
  VM_ENTRY_MARK;
  ciEnv* env = CURRENT_ENV;
  Thread* my_thread = JavaThread::current();
  methodHandle h_m(my_thread, get_Method());
  if (h_m()->method_data() != NULL) {
    _method_data = CURRENT_ENV->get_method_data(h_m()->method_data());
    _method_data->load_data();
  } else {
    _method_data = CURRENT_ENV->get_empty_methodData();
  }
  return _method_data;
}
ciMethodData* ciMethod::method_data_or_null() {
  ciMethodData *md = method_data();
  if (md->is_empty()) {
    return NULL;
  }
  return md;
}
MethodCounters* ciMethod::ensure_method_counters() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  MethodCounters* method_counters = mh->get_method_counters(CHECK_NULL);
  return method_counters;
}
bool ciMethod::should_exclude() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  bool ignore;
  return CompilerOracle::should_exclude(mh, ignore);
}
bool ciMethod::should_inline() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::should_inline(mh);
}
bool ciMethod::should_not_inline() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::should_not_inline(mh);
}
bool ciMethod::should_print_assembly() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::should_print(mh);
}
bool ciMethod::break_at_execute() {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::should_break_at(mh);
}
bool ciMethod::has_option(const char* option) {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::has_option_string(mh, option);
}
template<typename T>
bool ciMethod::has_option_value(const char* option, T& value) {
  check_is_loaded();
  VM_ENTRY_MARK;
  methodHandle mh(THREAD, get_Method());
  return CompilerOracle::has_option_value(mh, option, value);
}
template bool ciMethod::has_option_value<intx>(const char* option, intx& value);
template bool ciMethod::has_option_value<uintx>(const char* option, uintx& value);
template bool ciMethod::has_option_value<bool>(const char* option, bool& value);
template bool ciMethod::has_option_value<ccstr>(const char* option, ccstr& value);
bool ciMethod::can_be_compiled() {
  check_is_loaded();
  ciEnv* env = CURRENT_ENV;
  if (is_c1_compile(env->comp_level())) {
    return _is_c1_compilable;
  }
  return _is_c2_compilable;
}
void ciMethod::set_not_compilable(const char* reason) {
  check_is_loaded();
  VM_ENTRY_MARK;
  ciEnv* env = CURRENT_ENV;
  if (is_c1_compile(env->comp_level())) {
    _is_c1_compilable = false;
  } else {
    _is_c2_compilable = false;
  }
  get_Method()->set_not_compilable(env->comp_level(), true, reason);
}
bool ciMethod::can_be_osr_compiled(int entry_bci) {
  check_is_loaded();
  VM_ENTRY_MARK;
  ciEnv* env = CURRENT_ENV;
  return !get_Method()->is_not_osr_compilable(env->comp_level());
}
bool ciMethod::has_compiled_code() {
  return instructions_size() > 0;
}
int ciMethod::comp_level() {
  check_is_loaded();
  VM_ENTRY_MARK;
  nmethod* nm = get_Method()->code();
  if (nm != NULL) return nm->comp_level();
  return 0;
}
int ciMethod::highest_osr_comp_level() {
  check_is_loaded();
  VM_ENTRY_MARK;
  return get_Method()->highest_osr_comp_level();
}
int ciMethod::code_size_for_inlining() {
  check_is_loaded();
  if (get_Method()->force_inline()) {
    return 1;
  }
  return code_size();
}
int ciMethod::instructions_size() {
  if (_instructions_size == -1) {
    GUARDED_VM_ENTRY(
                     nmethod* code = get_Method()->code();
                     if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {
                       _instructions_size = code->insts_end() - code->verified_entry_point();
                     } else {
                       _instructions_size = 0;
                     }
                     );
  }
  return _instructions_size;
}
void ciMethod::log_nmethod_identity(xmlStream* log) {
  GUARDED_VM_ENTRY(
    nmethod* code = get_Method()->code();
    if (code != NULL) {
      code->log_identity(log);
    }
  )
}
bool ciMethod::is_not_reached(int bci) {
  check_is_loaded();
  VM_ENTRY_MARK;
  return Interpreter::is_not_reached(
               methodHandle(THREAD, get_Method()), bci);
}
bool ciMethod::was_executed_more_than(int times) {
  VM_ENTRY_MARK;
  return get_Method()->was_executed_more_than(times);
}
bool ciMethod::has_unloaded_classes_in_signature() {
  VM_ENTRY_MARK;
  {
    EXCEPTION_MARK;
    methodHandle m(THREAD, get_Method());
    bool has_unloaded = Method::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD);
    if( HAS_PENDING_EXCEPTION ) {
      CLEAR_PENDING_EXCEPTION;
      return true;     // Declare that we may have unloaded classes
    }
    return has_unloaded;
  }
}
bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {
  VM_ENTRY_MARK;
  return get_Method()->is_klass_loaded(refinfo_index, must_be_resolved);
}
bool ciMethod::check_call(int refinfo_index, bool is_static) const {
  VM_ENTRY_MARK;
  {
    EXCEPTION_MARK;
    HandleMark hm(THREAD);
    constantPoolHandle pool (THREAD, get_Method()->constants());
    methodHandle spec_method;
    KlassHandle  spec_klass;
    Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);
    LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
      return false;
    } else {
      return (spec_method->is_static() == is_static);
    }
  }
  return false;
}
void ciMethod::print_codes_on(outputStream* st) {
  check_is_loaded();
  GUARDED_VM_ENTRY(get_Method()->print_codes_on(st);)
}
#define FETCH_FLAG_FROM_VM(flag_accessor) { \
  check_is_loaded(); \
  VM_ENTRY_MARK; \
  return get_Method()->flag_accessor(); \
}
bool ciMethod::is_empty_method() const {         FETCH_FLAG_FROM_VM(is_empty_method); }
bool ciMethod::is_vanilla_constructor() const {  FETCH_FLAG_FROM_VM(is_vanilla_constructor); }
bool ciMethod::has_loops      () const {         FETCH_FLAG_FROM_VM(has_loops); }
bool ciMethod::has_jsrs       () const {         FETCH_FLAG_FROM_VM(has_jsrs);  }
bool ciMethod::is_accessor    () const {         FETCH_FLAG_FROM_VM(is_accessor); }
bool ciMethod::is_initializer () const {         FETCH_FLAG_FROM_VM(is_initializer); }
bool ciMethod::is_boxing_method() const {
  if (holder()->is_box_klass()) {
    switch (intrinsic_id()) {
      case vmIntrinsics::_Boolean_valueOf:
      case vmIntrinsics::_Byte_valueOf:
      case vmIntrinsics::_Character_valueOf:
      case vmIntrinsics::_Short_valueOf:
      case vmIntrinsics::_Integer_valueOf:
      case vmIntrinsics::_Long_valueOf:
      case vmIntrinsics::_Float_valueOf:
      case vmIntrinsics::_Double_valueOf:
        return true;
      default:
        return false;
    }
  }
  return false;
}
bool ciMethod::is_unboxing_method() const {
  if (holder()->is_box_klass()) {
    switch (intrinsic_id()) {
      case vmIntrinsics::_booleanValue:
      case vmIntrinsics::_byteValue:
      case vmIntrinsics::_charValue:
      case vmIntrinsics::_shortValue:
      case vmIntrinsics::_intValue:
      case vmIntrinsics::_longValue:
      case vmIntrinsics::_floatValue:
      case vmIntrinsics::_doubleValue:
        return true;
      default:
        return false;
    }
  }
  return false;
}
BCEscapeAnalyzer  *ciMethod::get_bcea() {
#ifdef COMPILER2
  if (_bcea == NULL) {
    _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL);
  }
  return _bcea;
#else // COMPILER2
  ShouldNotReachHere();
  return NULL;
#endif // COMPILER2
}
ciMethodBlocks  *ciMethod::get_method_blocks() {
  Arena *arena = CURRENT_ENV->arena();
  if (_method_blocks == NULL) {
    _method_blocks = new (arena) ciMethodBlocks(arena, this);
  }
  return _method_blocks;
}
#undef FETCH_FLAG_FROM_VM
void ciMethod::dump_name_as_ascii(outputStream* st) {
  Method* method = get_Method();
  st->print("%s %s %s",
            method->klass_name()->as_quoted_ascii(),
            method->name()->as_quoted_ascii(),
            method->signature()->as_quoted_ascii());
}
void ciMethod::dump_replay_data(outputStream* st) {
  ResourceMark rm;
  Method* method = get_Method();
  MethodCounters* mcs = method->method_counters();
  st->print("ciMethod ");
  dump_name_as_ascii(st);
  st->print_cr(" %d %d %d %d %d",
               mcs == NULL ? 0 : mcs->invocation_counter()->raw_counter(),
               mcs == NULL ? 0 : mcs->backedge_counter()->raw_counter(),
               interpreter_invocation_count(),
               interpreter_throwout_count(),
               _instructions_size);
}
void ciMethod::print_codes_on(int from, int to, outputStream* st) {
  check_is_loaded();
  GUARDED_VM_ENTRY(get_Method()->print_codes_on(from, to, st);)
}
void ciMethod::print_name(outputStream* st) {
  check_is_loaded();
  GUARDED_VM_ENTRY(get_Method()->print_name(st);)
}
void ciMethod::print_short_name(outputStream* st) {
  if (is_loaded()) {
    GUARDED_VM_ENTRY(get_Method()->print_short_name(st););
  } else {
    holder()->print_name_on(st);
    st->print("::");
    name()->print_symbol_on(st);
    if (WizardMode)
      signature()->as_symbol()->print_symbol_on(st);
  }
}
void ciMethod::print_impl(outputStream* st) {
  ciMetadata::print_impl(st);
  st->print(" name=");
  name()->print_symbol_on(st);
  st->print(" holder=");
  holder()->print_name_on(st);
  st->print(" signature=");
  signature()->as_symbol()->print_symbol_on(st);
  if (is_loaded()) {
    st->print(" loaded=true");
    st->print(" arg_size=%d", arg_size());
    st->print(" flags=");
    flags().print_member_flags(st);
  } else {
    st->print(" loaded=false");
  }
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethod.hpp
#ifndef SHARE_VM_CI_CIMETHOD_HPP
#define SHARE_VM_CI_CIMETHOD_HPP
#include "ci/ciFlags.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciObject.hpp"
#include "ci/ciSignature.hpp"
#include "compiler/methodLiveness.hpp"
#include "prims/methodHandles.hpp"
#include "utilities/bitMap.hpp"
class ciMethodBlocks;
class MethodLiveness;
class BitMap;
class Arena;
class BCEscapeAnalyzer;
class ciMethod : public ciMetadata {
  friend class CompileBroker;
  CI_PACKAGE_ACCESS
  friend class ciEnv;
  friend class ciExceptionHandlerStream;
  friend class ciBytecodeStream;
  friend class ciMethodHandle;
  friend class ciReplay;
 private:
  ciFlags          _flags;
  ciSymbol*        _name;
  ciInstanceKlass* _holder;
  ciSignature*     _signature;
  ciMethodData*    _method_data;
  ciMethodBlocks*   _method_blocks;
  int _code_size;
  int _max_stack;
  int _max_locals;
  vmIntrinsics::ID _intrinsic_id;
  int _handler_count;
  int _interpreter_invocation_count;
  int _interpreter_throwout_count;
  int _instructions_size;
  int _size_of_parameters;
  bool _uses_monitors;
  bool _balanced_monitors;
  bool _is_c1_compilable;
  bool _is_c2_compilable;
  bool _can_be_statically_bound;
  address              _code;
  ciExceptionHandler** _exception_handlers;
  MethodLiveness* _liveness;
#if defined(COMPILER2) || defined(SHARK)
  ciTypeFlow*         _flow;
  BCEscapeAnalyzer*   _bcea;
#endif
  ciMethod(methodHandle h_m, ciInstanceKlass* holder);
  ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor);
  oop loader() const                             { return _holder->loader(); }
  const char* type_string()                      { return "ciMethod"; }
  void print_impl(outputStream* st);
  void load_code();
  void check_is_loaded() const                   { assert(is_loaded(), "not loaded"); }
  bool ensure_method_data(methodHandle h_m);
  void code_at_put(int bci, Bytecodes::Code code) {
    Bytecodes::check(code);
    assert(0 <= bci && bci < code_size(), "valid bci");
    address bcp = _code + bci;
  }
  void assert_virtual_call_type_ok(int bci);
  void assert_call_type_ok(int bci);
 public:
  ciFlags flags() const                          { check_is_loaded(); return _flags; }
  ciSymbol* name() const                         { return _name; }
  ciInstanceKlass* holder() const                { return _holder; }
  ciMethodData* method_data();
  ciMethodData* method_data_or_null();
  ciSignature* signature() const                 { return _signature; }
  ciType*      return_type() const               { return _signature->return_type(); }
  int          arg_size_no_receiver() const      { return _signature->size(); }
  int          arg_size() const                  {
    check_is_loaded();
    return _signature->size() + (_flags.is_static() ? 0 : 1);
  }
  int invoke_arg_size(Bytecodes::Code code) const {
    if (is_loaded()) {
      return arg_size();
    } else {
      int arg_size = _signature->size();
      if (code != Bytecodes::_invokestatic &&
          code != Bytecodes::_invokedynamic) {
        arg_size++;
      }
      return arg_size;
    }
  }
  Method* get_Method() const {
    Method* m = (Method*)_metadata;
    assert(m != NULL, "illegal use of unloaded method");
    return m;
  }
  address code()                                 { if (_code == NULL) load_code(); return _code; }
  int code_size() const                          { check_is_loaded(); return _code_size; }
  int max_stack() const                          { check_is_loaded(); return _max_stack; }
  int max_locals() const                         { check_is_loaded(); return _max_locals; }
  vmIntrinsics::ID intrinsic_id() const          { check_is_loaded(); return _intrinsic_id; }
  bool has_exception_handlers() const            { check_is_loaded(); return _handler_count > 0; }
  int exception_table_length() const             { check_is_loaded(); return _handler_count; }
  int interpreter_invocation_count() const       { check_is_loaded(); return _interpreter_invocation_count; }
  int interpreter_throwout_count() const         { check_is_loaded(); return _interpreter_throwout_count; }
  int size_of_parameters() const                 { check_is_loaded(); return _size_of_parameters; }
  int code_size_for_inlining();
  bool caller_sensitive()   const { return get_Method()->caller_sensitive();   }
  bool force_inline()       const { return get_Method()->force_inline();       }
  bool dont_inline()        const { return get_Method()->dont_inline();        }
  int comp_level();
  int highest_osr_comp_level();
  Bytecodes::Code java_code_at_bci(int bci) {
    address bcp = code() + bci;
    return Bytecodes::java_code_at(NULL, bcp);
  }
  Bytecodes::Code raw_code_at_bci(int bci) {
    address bcp = code() + bci;
    return Bytecodes::code_at(NULL, bcp);
  }
  BCEscapeAnalyzer  *get_bcea();
  ciMethodBlocks    *get_method_blocks();
  bool    has_linenumber_table() const;          // length unknown until decompression
  u_char* compressed_linenumber_table() const;   // not preserved by gc
  int line_number_from_bci(int bci) const;
  int           vtable_index();
#ifdef SHARK
  int           itable_index();
#endif // SHARK
  address       native_entry();
  address       interpreter_entry();
  bool          has_monitor_bytecodes() const    { return _uses_monitors; }
  bool          has_balanced_monitors();
  MethodLivenessResult raw_liveness_at_bci(int bci);
  MethodLivenessResult liveness_at_bci(int bci);
  BitMap  live_local_oops_at_bci(int bci);
#ifdef COMPILER1
  const BitMap  bci_block_start();
#endif
  ciTypeFlow*   get_flow_analysis();
  ciTypeFlow*   get_osr_flow_analysis(int osr_bci);  // alternate entry point
  ciCallProfile call_profile_at_bci(int bci);
  int           interpreter_call_site_count(int bci);
  ciKlass*      argument_profiled_type(int bci, int i);
  ciKlass*      parameter_profiled_type(int i);
  ciKlass*      return_profiled_type(int bci);
  ciField*      get_field_at_bci( int bci, bool &will_link);
  ciMethod*     get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature);
  ciSignature*  get_declared_signature_at_bci(int bci) {
    bool ignored_will_link;
    ciSignature* declared_signature;
    get_method_at_bci(bci, ignored_will_link, &declared_signature);
    assert(declared_signature != NULL, "cannot be null");
    return declared_signature;
  }
  ciMethod*     get_method_at_bci(int bci) {
    bool ignored_will_link;
    ciSignature* ignored_declared_signature;
    return get_method_at_bci(bci, ignored_will_link, &ignored_declared_signature);
  }
  ciMethod* find_monomorphic_target(ciInstanceKlass* caller,
                                    ciInstanceKlass* callee_holder,
                                    ciInstanceKlass* actual_receiver,
                                    bool check_access = true);
  ciMethod* resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access = true);
  int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
  bool should_exclude();
  bool should_inline();
  bool should_not_inline();
  bool should_print_assembly();
  bool break_at_execute();
  bool has_option(const char *option);
  template<typename T>
  bool has_option_value(const char* option, T& value);
  bool can_be_compiled();
  bool can_be_osr_compiled(int entry_bci);
  void set_not_compilable(const char* reason = NULL);
  bool has_compiled_code();
  void log_nmethod_identity(xmlStream* log);
  bool is_not_reached(int bci);
  bool was_executed_more_than(int times);
  bool has_unloaded_classes_in_signature();
  bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
  bool check_call(int refinfo_index, bool is_static) const;
  bool ensure_method_data();  // make sure it exists in the VM also
  MethodCounters* ensure_method_counters();
  int instructions_size();
  int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
  bool is_ignored_by_security_stack_walk() const;
  bool is_method_handle_intrinsic()  const;
  bool is_compiled_lambda_form() const;
  bool has_member_arg() const;
  bool is_method() const                         { return true; }
  bool is_public      () const                   { return flags().is_public(); }
  bool is_private     () const                   { return flags().is_private(); }
  bool is_protected   () const                   { return flags().is_protected(); }
  bool is_static      () const                   { return flags().is_static(); }
  bool is_final       () const                   { return flags().is_final(); }
  bool is_synchronized() const                   { return flags().is_synchronized(); }
  bool is_native      () const                   { return flags().is_native(); }
  bool is_interface   () const                   { return flags().is_interface(); }
  bool is_abstract    () const                   { return flags().is_abstract(); }
  bool is_strict      () const                   { return flags().is_strict(); }
  bool is_empty_method() const;
  bool is_vanilla_constructor() const;
  bool is_final_method() const                   { return is_final() || holder()->is_final(); }
  bool has_loops      () const;
  bool has_jsrs       () const;
  bool is_accessor    () const;
  bool is_initializer () const;
  bool can_be_statically_bound() const           { return _can_be_statically_bound; }
  bool is_boxing_method() const;
  bool is_unboxing_method() const;
  bool is_object_initializer() const;
  void dump_name_as_ascii(outputStream* st);
  void dump_replay_data(outputStream* st);
  void print_codes_on(outputStream* st);
  void print_codes() {
    print_codes_on(tty);
  }
  void print_codes_on(int from, int to, outputStream* st);
  void print_name(outputStream* st = tty);
  void print_short_name(outputStream* st = tty);
};
#endif // SHARE_VM_CI_CIMETHOD_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodBlocks.cpp
#include "precompiled.hpp"
#include "ci/ciMethodBlocks.hpp"
#include "ci/ciStreams.hpp"
#include "interpreter/bytecode.hpp"
#include "utilities/copy.hpp"
ciBlock *ciMethodBlocks::block_containing(int bci) {
  ciBlock *blk = _bci_to_block[bci];
  return blk;
}
bool ciMethodBlocks::is_block_start(int bci) {
  assert(bci >=0 && bci < _code_size, "valid bytecode range");
  ciBlock *b = _bci_to_block[bci];
  assert(b != NULL, "must have block for bytecode");
  return b->start_bci() == bci;
}
ciBlock *ciMethodBlocks::split_block_at(int bci) {
  ciBlock *former_block = block_containing(bci);
  ciBlock *new_block = new(_arena) ciBlock(_method, _num_blocks++, former_block->start_bci());
  _blocks->append(new_block);
  assert(former_block != NULL, "must not be NULL");
  new_block->set_limit_bci(bci);
  former_block->set_start_bci(bci);
  for (int pos=bci-1; pos >= 0; pos--) {
    ciBlock *current_block = block_containing(pos);
    if (current_block == former_block) {
      _bci_to_block[pos] = new_block;
    } else if (current_block == NULL) {
      continue;
    } else {
      break;
    }
  }
  if (former_block->is_handler()) {
    int ex_start = former_block->ex_start_bci();
    int ex_end = former_block->ex_limit_bci();
    new_block->set_exception_range(ex_start, ex_end);
    former_block->clear_exception_handler();
  }
  return former_block;
}
ciBlock *ciMethodBlocks::make_block_at(int bci) {
  ciBlock *cb = block_containing(bci);
  if (cb == NULL ) {
    ciBlock *nb = new(_arena) ciBlock(_method, _num_blocks++, bci);
    _blocks->append(nb);
     _bci_to_block[bci] = nb;
    return nb;
  } else if (cb->start_bci() == bci) {
    return cb;
  } else {
    return split_block_at(bci);
  }
}
ciBlock *ciMethodBlocks::make_dummy_block() {
  ciBlock *dum = new(_arena) ciBlock(_method, -1, 0);
  return dum;
}
void ciMethodBlocks::do_analysis() {
  ciBytecodeStream s(_method);
  ciBlock *cur_block = block_containing(0);
  int limit_bci = _method->code_size();
  while (s.next() != ciBytecodeStream::EOBC()) {
    int bci = s.cur_bci();
    assert(cur_block != NULL, "must always have a current block");
    ciBlock *new_block = block_containing(bci);
    if (new_block == NULL || new_block == cur_block) {
      _bci_to_block[bci] = cur_block;
    } else {
      cur_block->set_limit_bci(bci);
      cur_block = new_block;
    }
    switch (s.cur_bc()) {
      case Bytecodes::_ifeq        :
      case Bytecodes::_ifne        :
      case Bytecodes::_iflt        :
      case Bytecodes::_ifge        :
      case Bytecodes::_ifgt        :
      case Bytecodes::_ifle        :
      case Bytecodes::_if_icmpeq   :
      case Bytecodes::_if_icmpne   :
      case Bytecodes::_if_icmplt   :
      case Bytecodes::_if_icmpge   :
      case Bytecodes::_if_icmpgt   :
      case Bytecodes::_if_icmple   :
      case Bytecodes::_if_acmpeq   :
      case Bytecodes::_if_acmpne   :
      case Bytecodes::_ifnull      :
      case Bytecodes::_ifnonnull   :
      {
        cur_block->set_control_bci(bci);
        ciBlock *fall_through = make_block_at(s.next_bci());
        int dest_bci = s.get_dest();
        ciBlock *dest = make_block_at(dest_bci);
        break;
      }
      case Bytecodes::_goto        :
      {
        cur_block->set_control_bci(bci);
        if (s.next_bci() < limit_bci) {
          (void) make_block_at(s.next_bci());
        }
        int dest_bci = s.get_dest();
        ciBlock *dest = make_block_at(dest_bci);
        break;
      }
      case Bytecodes::_jsr         :
      {
        cur_block->set_control_bci(bci);
        ciBlock *ret = make_block_at(s.next_bci());
        int dest_bci = s.get_dest();
        ciBlock *dest = make_block_at(dest_bci);
        break;
      }
      case Bytecodes::_tableswitch :
        {
          cur_block->set_control_bci(bci);
          Bytecode_tableswitch sw(&s);
          int len = sw.length();
          ciBlock *dest;
          int dest_bci;
          for (int i = 0; i < len; i++) {
            dest_bci = s.cur_bci() + sw.dest_offset_at(i);
            dest = make_block_at(dest_bci);
          }
          dest_bci = s.cur_bci() + sw.default_offset();
          make_block_at(dest_bci);
          if (s.next_bci() < limit_bci) {
            dest = make_block_at(s.next_bci());
          }
        }
        break;
      case Bytecodes::_lookupswitch:
        {
          cur_block->set_control_bci(bci);
          Bytecode_lookupswitch sw(&s);
          int len = sw.number_of_pairs();
          ciBlock *dest;
          int dest_bci;
          for (int i = 0; i < len; i++) {
            dest_bci = s.cur_bci() + sw.pair_at(i).offset();
            dest = make_block_at(dest_bci);
          }
          dest_bci = s.cur_bci() + sw.default_offset();
          dest = make_block_at(dest_bci);
          if (s.next_bci() < limit_bci) {
            dest = make_block_at(s.next_bci());
          }
        }
        break;
      case Bytecodes::_goto_w      :
      {
        cur_block->set_control_bci(bci);
        if (s.next_bci() < limit_bci) {
          (void) make_block_at(s.next_bci());
        }
        int dest_bci = s.get_far_dest();
        ciBlock *dest = make_block_at(dest_bci);
        break;
      }
      case Bytecodes::_jsr_w       :
      {
        cur_block->set_control_bci(bci);
        ciBlock *ret = make_block_at(s.next_bci());
        int dest_bci = s.get_far_dest();
        ciBlock *dest = make_block_at(dest_bci);
        break;
      }
      case Bytecodes::_athrow      :
        cur_block->set_may_throw();
      case Bytecodes::_ret         :
      case Bytecodes::_ireturn     :
      case Bytecodes::_lreturn     :
      case Bytecodes::_freturn     :
      case Bytecodes::_dreturn     :
      case Bytecodes::_areturn     :
      case Bytecodes::_return      :
        cur_block->set_control_bci(bci);
        if (s.next_bci() < limit_bci) {
          (void) make_block_at(s.next_bci());
        }
        break;
    }
  }
  cur_block->set_limit_bci(limit_bci);
}
ciMethodBlocks::ciMethodBlocks(Arena *arena, ciMethod *meth): _method(meth),
                          _arena(arena), _num_blocks(0), _code_size(meth->code_size()) {
  int block_estimate = _code_size / 8;
  _blocks =  new(_arena) GrowableArray<ciBlock *>(_arena, block_estimate, 0, NULL);
  int b2bsize = _code_size * sizeof(ciBlock **);
  _bci_to_block = (ciBlock **) arena->Amalloc(b2bsize);
  Copy::zero_to_words((HeapWord*) _bci_to_block, b2bsize / sizeof(HeapWord));
  ciBlock *b = new(arena) ciBlock(_method, _num_blocks++, 0);
  _blocks->append(b);
  _bci_to_block[0] = b;
  if (meth->has_exception_handlers()) {
    for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) {
      ciExceptionHandler* handler = str.handler();
      ciBlock *eb = make_block_at(handler->handler_bci());
      int ex_start = handler->start();
      int ex_end = handler->limit();
      (void) make_block_at(ex_start);
      if (ex_end < _code_size)
        (void) make_block_at(ex_end);
      if (eb->is_handler()) {
        int old_ex_start = eb->ex_start_bci();
        int old_ex_end   = eb->ex_limit_bci();
        if (ex_start > old_ex_start)
          ex_start = old_ex_start;
        if (ex_end < old_ex_end)
          ex_end = old_ex_end;
        eb->clear_exception_handler(); // Reset exception information
      }
      eb->set_exception_range(ex_start, ex_end);
    }
  }
  do_analysis();
  if (meth->has_exception_handlers()) {
    for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) {
      ciExceptionHandler* handler = str.handler();
      int ex_start = handler->start();
      int ex_end = handler->limit();
      int bci = ex_start;
      while (bci < ex_end) {
        ciBlock *b = block_containing(bci);
        b->set_has_handler();
        bci = b->limit_bci();
      }
    }
  }
}
void ciMethodBlocks::clear_processed() {
  for (int i = 0; i < _blocks->length(); i++)
    _blocks->at(i)->clear_processed();
}
#ifndef PRODUCT
void ciMethodBlocks::dump() {
  tty->print("---- blocks for method: ");
  _method->print();
  tty->cr();
  for (int i = 0; i < _blocks->length(); i++) {
    tty->print("  B%d: ", i); _blocks->at(i)->dump();
  }
}
#endif
ciBlock::ciBlock(ciMethod *method, int index, int start_bci) :
#ifndef PRODUCT
                         _method(method),
#endif
                         _idx(index), _flags(0), _start_bci(start_bci), _limit_bci(-1), _control_bci(fall_through_bci),
                         _ex_start_bci(-1), _ex_limit_bci(-1) {
}
void ciBlock::set_exception_range(int start_bci, int limit_bci)  {
   assert(limit_bci >= start_bci, "valid range");
   assert(!is_handler() && _ex_start_bci == -1 && _ex_limit_bci == -1, "must not be handler");
   _ex_start_bci = start_bci;
   _ex_limit_bci = limit_bci;
   set_handler();
}
#ifndef PRODUCT
static const char *flagnames[] = {
  "Processed",
  "Handler",
  "MayThrow",
  "Jsr",
  "Ret",
  "RetTarget",
  "HasHandler",
};
void ciBlock::dump() {
  tty->print(" [%d .. %d), {", _start_bci, _limit_bci);
  for (int i = 0; i < 8; i++) {
    if ((_flags & (1 << i)) != 0) {
      tty->print(" %s", flagnames[i]);
    }
  }
  tty->print(" ]");
  if (is_handler())
    tty->print(" handles(%d..%d)", _ex_start_bci, _ex_limit_bci);
  tty->cr();
}
void ciBlock::print_on(outputStream* st) const {
  st->print_cr("--------------------------------------------------------");
  st->print   ("ciBlock [%d - %d) control : ", start_bci(), limit_bci());
  if (control_bci() == fall_through_bci) {
    st->print_cr("%d:fall through", limit_bci());
  } else {
    st->print_cr("%d:%s", control_bci(),
        Bytecodes::name(method()->java_code_at_bci(control_bci())));
  }
  if (Verbose || WizardMode) {
    method()->print_codes_on(start_bci(), limit_bci(), st);
  }
}
#endif
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodBlocks.hpp
#ifndef SHARE_VM_CI_CIMETHODBLOCKS_HPP
#define SHARE_VM_CI_CIMETHODBLOCKS_HPP
#include "ci/ciMethod.hpp"
#include "memory/resourceArea.hpp"
#include "utilities/growableArray.hpp"
class ciBlock;
typedef short ciBlockIndex;
class ciMethodBlocks : public ResourceObj {
private:
  ciMethod *_method;
  Arena *_arena;
  GrowableArray<ciBlock *>  *_blocks;
  ciBlock  **_bci_to_block;
  int _num_blocks;
  int _code_size;
  void do_analysis();
public:
  ciMethodBlocks(Arena *arena, ciMethod *meth);
  ciBlock *block_containing(int bci);
  ciBlock *block(int index)  { return _blocks->at(index); }
  ciBlock *make_block_at(int bci);
  ciBlock *split_block_at(int bci);
  bool is_block_start(int bci);
  int num_blocks()  { return _num_blocks;}
  void clear_processed();
  ciBlock *make_dummy_block(); // a block not associated with a bci
#ifndef PRODUCT
  void dump();
#endif
};
class ciBlock : public ResourceObj {
private:
  int _idx;
  int _start_bci;
  int _limit_bci;
  int _control_bci;
  uint _flags;
  int _ex_start_bci;
  int _ex_limit_bci;
#ifndef PRODUCT
  ciMethod *_method;
#endif
  enum {
    Processed   = (1 << 0),
    Handler     = (1 << 1),
    MayThrow    = (1 << 2),
    DoesJsr     = (1 << 3),
    DoesRet     = (1 << 4),
    RetTarget   = (1 << 5),
    HasHandler  = (1 << 6)
  };
public:
  enum {
    fall_through_bci = -1
  };
  ciBlock(ciMethod *method, int index, int start_bci);
  int start_bci() const         { return _start_bci; }
  int limit_bci() const         { return _limit_bci; }
  int control_bci() const       { return _control_bci; }
  int index() const             { return _idx; }
  void set_start_bci(int bci)   { _start_bci = bci; }
  void set_limit_bci(int bci)   { _limit_bci = bci; }
  void set_control_bci(int bci) { _control_bci = bci;}
  void set_exception_range(int start_bci, int limit_bci);
  int ex_start_bci() const      { return _ex_start_bci; }
  int ex_limit_bci() const      { return _ex_limit_bci; }
  bool contains(int bci) const { return start_bci() <= bci && bci < limit_bci(); }
  bool  processed() const           { return (_flags & Processed) != 0; }
  bool  is_handler() const          { return (_flags & Handler) != 0; }
  bool  may_throw() const           { return (_flags & MayThrow) != 0; }
  bool  does_jsr() const            { return (_flags & DoesJsr) != 0; }
  bool  does_ret() const            { return (_flags & DoesRet) != 0; }
  bool  has_handler() const         { return (_flags & HasHandler) != 0; }
  bool  is_ret_target() const       { return (_flags & RetTarget) != 0; }
  void  set_processed()             { _flags |= Processed; }
  void  clear_processed()           { _flags &= ~Processed; }
  void  set_handler()               { _flags |= Handler; }
  void  set_may_throw()             { _flags |= MayThrow; }
  void  set_does_jsr()              { _flags |= DoesJsr; }
  void  clear_does_jsr()            { _flags &= ~DoesJsr; }
  void  set_does_ret()              { _flags |= DoesRet; }
  void  clear_does_ret()            { _flags &= ~DoesRet; }
  void  set_is_ret_target()         { _flags |= RetTarget; }
  void  set_has_handler()           { _flags |= HasHandler; }
  void  clear_exception_handler()   { _flags &= ~Handler; _ex_start_bci = -1; _ex_limit_bci = -1; }
#ifndef PRODUCT
  ciMethod *method() const          { return _method; }
  void dump();
  void print_on(outputStream* st) const  PRODUCT_RETURN;
#endif
};
#endif // SHARE_VM_CI_CIMETHODBLOCKS_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodData.cpp
#include "precompiled.hpp"
#include "ci/ciMetadata.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/deoptimization.hpp"
#include "utilities/copy.hpp"
ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
  assert(md != NULL, "no null method data");
  Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
  _data = NULL;
  _data_size = 0;
  _extra_data_size = 0;
  _current_mileage = 0;
  _invocation_counter = 0;
  _backedge_counter = 0;
  _state = empty_state;
  _saw_free_extra_data = false;
  _hint_di = first_di();
  _eflags = _arg_local = _arg_stack = _arg_returned = 0;
  _parameters = NULL;
}
ciMethodData::ciMethodData() : ciMetadata(NULL) {
  Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
  _data = NULL;
  _data_size = 0;
  _extra_data_size = 0;
  _current_mileage = 0;
  _invocation_counter = 0;
  _backedge_counter = 0;
  _state = empty_state;
  _saw_free_extra_data = false;
  _hint_di = first_di();
  _eflags = _arg_local = _arg_stack = _arg_returned = 0;
  _parameters = NULL;
}
void ciMethodData::load_extra_data() {
  MethodData* mdo = get_MethodData();
  DataLayout* dp_src  = mdo->extra_data_base();
  DataLayout* end_src = mdo->extra_data_limit();
  DataLayout* dp_dst  = extra_data_base();
  for (;; dp_src = MethodData::next_extra(dp_src), dp_dst = MethodData::next_extra(dp_dst)) {
    assert(dp_src < end_src, "moved past end of extra data");
    switch(dp_dst->tag()) {
    case DataLayout::speculative_trap_data_tag: {
      ciSpeculativeTrapData* data_dst = new ciSpeculativeTrapData(dp_dst);
      SpeculativeTrapData* data_src = new SpeculativeTrapData(dp_src);
      data_dst->translate_from(data_src);
      break;
    }
    case DataLayout::bit_data_tag:
      break;
    case DataLayout::no_tag:
    case DataLayout::arg_info_data_tag:
      return;
    default:
      fatal(err_msg("bad tag = %d", dp_dst->tag()));
    }
  }
}
void ciMethodData::load_data() {
  MethodData* mdo = get_MethodData();
  if (mdo == NULL) {
    return;
  }
  Copy::disjoint_words_atomic((HeapWord*) mdo,
                              (HeapWord*) &_orig,
                              sizeof(_orig) / HeapWordSize);
  Arena* arena = CURRENT_ENV->arena();
  _data_size = mdo->data_size();
  _extra_data_size = mdo->extra_data_size();
  int total_size = _data_size + _extra_data_size;
  _data = (intptr_t *) arena->Amalloc(total_size);
  Copy::disjoint_words_atomic((HeapWord*) mdo->data_base(),
                              (HeapWord*) _data,
                              total_size / HeapWordSize);
  ResourceMark rm;
  ciProfileData* ci_data = first_data();
  ProfileData* data = mdo->first_data();
  while (is_valid(ci_data)) {
    ci_data->translate_from(data);
    ci_data = next_data(ci_data);
    data = mdo->next_data(data);
  }
  if (mdo->parameters_type_data() != NULL) {
    _parameters = data_layout_at(mdo->parameters_type_data_di());
    ciParametersTypeData* parameters = new ciParametersTypeData(_parameters);
    parameters->translate_from(mdo->parameters_type_data());
  }
  load_extra_data();
  _current_mileage = MethodData::mileage_of(mdo->method());
  _invocation_counter = mdo->invocation_count();
  _backedge_counter = mdo->backedge_count();
  _state = mdo->is_mature()? mature_state: immature_state;
  _eflags = mdo->eflags();
  _arg_local = mdo->arg_local();
  _arg_stack = mdo->arg_stack();
  _arg_returned  = mdo->arg_returned();
#ifndef PRODUCT
  if (ReplayCompiles) {
    ciReplay::initialize(this);
  }
#endif
}
void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
  for (uint row = 0; row < row_limit(); row++) {
    Klass* k = data->as_ReceiverTypeData()->receiver(row);
    if (k != NULL) {
      ciKlass* klass = CURRENT_ENV->get_klass(k);
      CURRENT_ENV->ensure_metadata_alive(klass);
      set_receiver(row, klass);
    }
  }
}
void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) {
  for (int i = 0; i < _number_of_entries; i++) {
    intptr_t k = entries->type(i);
    TypeStackSlotEntries::set_type(i, translate_klass(k));
  }
}
void ciReturnTypeEntry::translate_type_data_from(const ReturnTypeEntry* ret) {
  intptr_t k = ret->type();
  set_type(translate_klass(k));
}
void ciSpeculativeTrapData::translate_from(const ProfileData* data) {
  Method* m = data->as_SpeculativeTrapData()->method();
  ciMethod* ci_m = CURRENT_ENV->get_method(m);
  CURRENT_ENV->ensure_metadata_alive(ci_m);
  set_method(ci_m);
}
ciProfileData* ciMethodData::data_at(int data_index) {
  if (out_of_bounds(data_index)) {
    return NULL;
  }
  DataLayout* data_layout = data_layout_at(data_index);
  switch (data_layout->tag()) {
  case DataLayout::no_tag:
  default:
    ShouldNotReachHere();
    return NULL;
  case DataLayout::bit_data_tag:
    return new ciBitData(data_layout);
  case DataLayout::counter_data_tag:
    return new ciCounterData(data_layout);
  case DataLayout::jump_data_tag:
    return new ciJumpData(data_layout);
  case DataLayout::receiver_type_data_tag:
    return new ciReceiverTypeData(data_layout);
  case DataLayout::virtual_call_data_tag:
    return new ciVirtualCallData(data_layout);
  case DataLayout::ret_data_tag:
    return new ciRetData(data_layout);
  case DataLayout::branch_data_tag:
    return new ciBranchData(data_layout);
  case DataLayout::multi_branch_data_tag:
    return new ciMultiBranchData(data_layout);
  case DataLayout::arg_info_data_tag:
    return new ciArgInfoData(data_layout);
  case DataLayout::call_type_data_tag:
    return new ciCallTypeData(data_layout);
  case DataLayout::virtual_call_type_data_tag:
    return new ciVirtualCallTypeData(data_layout);
  case DataLayout::parameters_type_data_tag:
    return new ciParametersTypeData(data_layout);
  };
}
ciProfileData* ciMethodData::next_data(ciProfileData* current) {
  int current_index = dp_to_di(current->dp());
  int next_index = current_index + current->size_in_bytes();
  ciProfileData* next = data_at(next_index);
  return next;
}
ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) {
  DataLayout* dp  = data_layout_at(data_size());
  DataLayout* end = data_layout_at(data_size() + extra_data_size());
  two_free_slots = false;
  for (;dp < end; dp = MethodData::next_extra(dp)) {
    switch(dp->tag()) {
    case DataLayout::no_tag:
      _saw_free_extra_data = true;  // observed an empty slot (common case)
      two_free_slots = (MethodData::next_extra(dp)->tag() == DataLayout::no_tag);
      return NULL;
    case DataLayout::arg_info_data_tag:
      return NULL; // ArgInfoData is at the end of extra data section.
    case DataLayout::bit_data_tag:
      if (m == NULL && dp->bci() == bci) {
        return new ciBitData(dp);
      }
      break;
    case DataLayout::speculative_trap_data_tag: {
      ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp);
      if (m != NULL && data->method() == m && dp->bci() == bci) {
        return data;
      }
      break;
    }
    default:
      fatal(err_msg("bad tag = %d", dp->tag()));
    }
  }
  return NULL;
}
ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) {
  if (m == NULL) {
    ciProfileData* data = data_before(bci);
    for ( ; is_valid(data); data = next_data(data)) {
      if (data->bci() == bci) {
        set_hint_di(dp_to_di(data->dp()));
        return data;
      } else if (data->bci() > bci) {
        break;
      }
    }
  }
  bool two_free_slots = false;
  ciProfileData* result = bci_to_extra_data(bci, m, two_free_slots);
  if (result != NULL) {
    return result;
  }
  if (m != NULL && !two_free_slots) {
    return bci_to_data(bci, NULL);
  }
  return NULL;
}
int ciMethodData::has_trap_at(ciProfileData* data, int reason) {
  typedef Deoptimization::DeoptReason DR_t;
  int per_bc_reason
    = Deoptimization::reason_recorded_per_bytecode_if_any((DR_t) reason);
  if (trap_count(reason) == 0) {
    return 0;
  } else if (per_bc_reason == Deoptimization::Reason_none) {
    return -1;
  } else if (data == NULL) {
    if (_saw_free_extra_data)
      return 0;                 // Q.E.D.
    else
      return -1;                // bail with a conservative answer
  } else {
    return Deoptimization::trap_state_has_reason(data->trap_state(), per_bc_reason);
  }
}
int ciMethodData::trap_recompiled_at(ciProfileData* data) {
  if (data == NULL) {
    return (_saw_free_extra_data? 0: -1);  // (see previous method)
  } else {
    return Deoptimization::trap_state_is_recompiled(data->trap_state())? 1: 0;
  }
}
void ciMethodData::clear_escape_info() {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    mdo->clear_escape_info();
    ArgInfoData *aid = arg_info();
    int arg_count = (aid == NULL) ? 0 : aid->number_of_args();
    for (int i = 0; i < arg_count; i++) {
      set_arg_modified(i, 0);
    }
  }
  _eflags = _arg_local = _arg_stack = _arg_returned = 0;
}
void ciMethodData::update_escape_info() {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if ( mdo != NULL) {
    mdo->set_eflags(_eflags);
    mdo->set_arg_local(_arg_local);
    mdo->set_arg_stack(_arg_stack);
    mdo->set_arg_returned(_arg_returned);
    int arg_count = mdo->method()->size_of_parameters();
    for (int i = 0; i < arg_count; i++) {
      mdo->set_arg_modified(i, arg_modified(i));
    }
  }
}
void ciMethodData::set_compilation_stats(short loops, short blocks) {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    mdo->set_num_loops(loops);
    mdo->set_num_blocks(blocks);
  }
}
void ciMethodData::set_would_profile(bool p) {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    mdo->set_would_profile(p);
  }
}
void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    ProfileData* data = mdo->bci_to_data(bci);
    if (data != NULL) {
      if (data->is_CallTypeData()) {
        data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
      } else {
        assert(data->is_VirtualCallTypeData(), "no arguments!");
        data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
      }
    }
  }
}
void ciMethodData::set_parameter_type(int i, ciKlass* k) {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    mdo->parameters_type_data()->set_type(i, k->get_Klass());
  }
}
void ciMethodData::set_return_type(int bci, ciKlass* k) {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    ProfileData* data = mdo->bci_to_data(bci);
    if (data != NULL) {
      if (data->is_CallTypeData()) {
        data->as_CallTypeData()->set_return_type(k->get_Klass());
      } else {
        assert(data->is_VirtualCallTypeData(), "no arguments!");
        data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
      }
    }
  }
}
bool ciMethodData::has_escape_info() {
  return eflag_set(MethodData::estimated);
}
void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
  set_bits(_eflags, f);
}
void ciMethodData::clear_eflag(MethodData::EscapeFlag f) {
  clear_bits(_eflags, f);
}
bool ciMethodData::eflag_set(MethodData::EscapeFlag f) const {
  return mask_bits(_eflags, f) != 0;
}
void ciMethodData::set_arg_local(int i) {
  set_nth_bit(_arg_local, i);
}
void ciMethodData::set_arg_stack(int i) {
  set_nth_bit(_arg_stack, i);
}
void ciMethodData::set_arg_returned(int i) {
  set_nth_bit(_arg_returned, i);
}
void ciMethodData::set_arg_modified(int arg, uint val) {
  ArgInfoData *aid = arg_info();
  if (aid == NULL)
    return;
  assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
  aid->set_arg_modified(arg, val);
}
bool ciMethodData::is_arg_local(int i) const {
  return is_set_nth_bit(_arg_local, i);
}
bool ciMethodData::is_arg_stack(int i) const {
  return is_set_nth_bit(_arg_stack, i);
}
bool ciMethodData::is_arg_returned(int i) const {
  return is_set_nth_bit(_arg_returned, i);
}
uint ciMethodData::arg_modified(int arg) const {
  ArgInfoData *aid = arg_info();
  if (aid == NULL)
    return 0;
  assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
  return aid->arg_modified(arg);
}
ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) {
  ByteSize data_offset = MethodData::data_offset();
  int cell_offset = dp_to_di(data->dp());
  int offset = in_bytes(data_offset) + cell_offset + in_bytes(slot_offset_in_data);
  return in_ByteSize(offset);
}
ciArgInfoData *ciMethodData::arg_info() const {
  DataLayout* dp  = data_layout_at(data_size());
  DataLayout* end = data_layout_at(data_size() + extra_data_size());
  for (; dp < end; dp = MethodData::next_extra(dp)) {
    if (dp->tag() == DataLayout::arg_info_data_tag)
      return new ciArgInfoData(dp);
  }
  return NULL;
}
void ciMethodData::print_impl(outputStream* st) {
  ciMetadata::print_impl(st);
}
void ciMethodData::dump_replay_data(outputStream* out) {
  ResourceMark rm;
  MethodData* mdo = get_MethodData();
  Method* method = mdo->method();
  Klass* holder = method->method_holder();
  out->print("ciMethodData %s %s %s %d %d",
             holder->name()->as_quoted_ascii(),
             method->name()->as_quoted_ascii(),
             method->signature()->as_quoted_ascii(),
             _state,
             current_mileage());
  unsigned char* orig = (unsigned char*)&_orig;
  int length = sizeof(_orig);
  out->print(" orig %d", length);
  for (int i = 0; i < length; i++) {
    out->print(" %d", orig[i]);
  }
  int elements = data_size() / sizeof(intptr_t);
  out->print(" data %d", elements);
  for (int i = 0; i < elements; i++) {
#ifdef _LP64
    out->print(" 0x%" FORMAT64_MODIFIER "x", data()[i]);
#else
    out->print(" 0x%x", data()[i]);
#endif
  }
  int count = 0;
  for (int round = 0; round < 2; round++) {
    if (round == 1) out->print(" oops %d", count);
    ProfileData* pdata = first_data();
    for ( ; is_valid(pdata); pdata = next_data(pdata)) {
      if (pdata->is_ReceiverTypeData()) {
        ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
        for (uint i = 0; i < vdata->row_limit(); i++) {
          ciKlass* k = vdata->receiver(i);
          if (k != NULL) {
            if (round == 0) {
              count++;
            } else {
              out->print(" %d %s", (int)(dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t)), k->name()->as_quoted_ascii());
            }
          }
        }
      } else if (pdata->is_VirtualCallData()) {
        ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
        for (uint i = 0; i < vdata->row_limit(); i++) {
          ciKlass* k = vdata->receiver(i);
          if (k != NULL) {
            if (round == 0) {
              count++;
            } else {
              out->print(" %d %s", (int)(dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t)), k->name()->as_quoted_ascii());
            }
          }
        }
      }
    }
  }
  out->cr();
}
#ifndef PRODUCT
void ciMethodData::print() {
  print_data_on(tty);
}
void ciMethodData::print_data_on(outputStream* st) {
  ResourceMark rm;
  ciProfileData* data;
  for (data = first_data(); is_valid(data); data = next_data(data)) {
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
  }
  st->print_cr("--- Extra data:");
  DataLayout* dp  = data_layout_at(data_size());
  DataLayout* end = data_layout_at(data_size() + extra_data_size());
  for (;; dp = MethodData::next_extra(dp)) {
    assert(dp < end, "moved past end of extra data");
    switch (dp->tag()) {
    case DataLayout::no_tag:
      continue;
    case DataLayout::bit_data_tag:
      data = new BitData(dp);
      break;
    case DataLayout::arg_info_data_tag:
      data = new ciArgInfoData(dp);
      dp = end; // ArgInfoData is at the end of extra data section.
      break;
    default:
      fatal(err_msg("unexpected tag %d", dp->tag()));
    }
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
    if (dp >= end) return;
  }
}
void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) {
  if (TypeEntries::is_type_none(k)) {
    st->print("none");
  } else if (TypeEntries::is_type_unknown(k)) {
    st->print("unknown");
  } else {
    valid_ciklass(k)->print_name_on(st);
  }
  if (TypeEntries::was_null_seen(k)) {
    st->print(" (null seen)");
  }
}
void ciTypeStackSlotEntries::print_data_on(outputStream* st) const {
  for (int i = 0; i < _number_of_entries; i++) {
    _pd->tab(st);
    st->print("%d: stack (%u) ", i, stack_slot(i));
    print_ciklass(st, type(i));
    st->cr();
  }
}
void ciReturnTypeEntry::print_data_on(outputStream* st) const {
  _pd->tab(st);
  st->print("ret ");
  print_ciklass(st, type());
  st->cr();
}
void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const {
  print_shared(st, "ciCallTypeData", extra);
  if (has_arguments()) {
    tab(st, true);
    st->print("argument types");
    args()->print_data_on(st);
  }
  if (has_return()) {
    tab(st, true);
    st->print("return type");
    ret()->print_data_on(st);
  }
}
void ciReceiverTypeData::print_receiver_data_on(outputStream* st) const {
  uint row;
  int entries = 0;
  for (row = 0; row < row_limit(); row++) {
    if (receiver(row) != NULL)  entries++;
  }
  st->print_cr("count(%u) entries(%u)", count(), entries);
  for (row = 0; row < row_limit(); row++) {
    if (receiver(row) != NULL) {
      tab(st);
      receiver(row)->print_name_on(st);
      st->print_cr("(%u)", receiver_count(row));
    }
  }
}
void ciReceiverTypeData::print_data_on(outputStream* st, const char* extra) const {
  print_shared(st, "ciReceiverTypeData", extra);
  print_receiver_data_on(st);
}
void ciVirtualCallData::print_data_on(outputStream* st, const char* extra) const {
  print_shared(st, "ciVirtualCallData", extra);
  rtd_super()->print_receiver_data_on(st);
}
void ciVirtualCallTypeData::print_data_on(outputStream* st, const char* extra) const {
  print_shared(st, "ciVirtualCallTypeData", extra);
  rtd_super()->print_receiver_data_on(st);
  if (has_arguments()) {
    tab(st, true);
    st->print("argument types");
    args()->print_data_on(st);
  }
  if (has_return()) {
    tab(st, true);
    st->print("return type");
    ret()->print_data_on(st);
  }
}
void ciParametersTypeData::print_data_on(outputStream* st, const char* extra) const {
  st->print_cr("ciParametersTypeData");
  parameters()->print_data_on(st);
}
void ciSpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const {
  st->print_cr("ciSpeculativeTrapData");
  tab(st);
  method()->print_short_name(st);
  st->cr();
}
#endif
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodData.hpp
#ifndef SHARE_VM_CI_CIMETHODDATA_HPP
#define SHARE_VM_CI_CIMETHODDATA_HPP
#include "ci/ciClassList.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciObject.hpp"
#include "ci/ciUtilities.hpp"
#include "oops/methodData.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/deoptimization.hpp"
class ciBitData;
class ciCounterData;
class ciJumpData;
class ciReceiverTypeData;
class ciRetData;
class ciBranchData;
class ciArrayData;
class ciMultiBranchData;
class ciArgInfoData;
class ciCallTypeData;
class ciVirtualCallTypeData;
class ciParametersTypeData;
class ciSpeculativeTrapData;;
typedef ProfileData ciProfileData;
class ciBitData : public BitData {
public:
  ciBitData(DataLayout* layout) : BitData(layout) {};
};
class ciCounterData : public CounterData {
public:
  ciCounterData(DataLayout* layout) : CounterData(layout) {};
};
class ciJumpData : public JumpData {
public:
  ciJumpData(DataLayout* layout) : JumpData(layout) {};
};
class ciTypeEntries {
protected:
  static intptr_t translate_klass(intptr_t k) {
    Klass* v = TypeEntries::valid_klass(k);
    if (v != NULL) {
      ciKlass* klass = CURRENT_ENV->get_klass(v);
      CURRENT_ENV->ensure_metadata_alive(klass);
      return with_status(klass, k);
    }
    return with_status(NULL, k);
  }
public:
  static ciKlass* valid_ciklass(intptr_t k) {
    if (!TypeEntries::is_type_none(k) &&
        !TypeEntries::is_type_unknown(k)) {
      ciKlass* res = (ciKlass*)TypeEntries::klass_part(k);
      assert(res != NULL, "invalid");
      return res;
    } else {
      return NULL;
    }
  }
  static intptr_t with_status(ciKlass* k, intptr_t in) {
    return TypeEntries::with_status((intptr_t)k, in);
  }
#ifndef PRODUCT
  static void print_ciklass(outputStream* st, intptr_t k);
#endif
};
class ciTypeStackSlotEntries : public TypeStackSlotEntries, ciTypeEntries {
public:
  void translate_type_data_from(const TypeStackSlotEntries* args);
  ciKlass* valid_type(int i) const {
    return valid_ciklass(type(i));
  }
  bool maybe_null(int i) const {
    return was_null_seen(type(i));
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st) const;
#endif
};
class ciReturnTypeEntry : public ReturnTypeEntry, ciTypeEntries {
public:
  void translate_type_data_from(const ReturnTypeEntry* ret);
  ciKlass* valid_type() const {
    return valid_ciklass(type());
  }
  bool maybe_null() const {
    return was_null_seen(type());
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st) const;
#endif
};
class ciCallTypeData : public CallTypeData {
public:
  ciCallTypeData(DataLayout* layout) : CallTypeData(layout) {}
  ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)CallTypeData::args(); }
  ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)CallTypeData::ret(); }
  void translate_from(const ProfileData* data) {
    if (has_arguments()) {
      args()->translate_type_data_from(data->as_CallTypeData()->args());
    }
    if (has_return()) {
      ret()->translate_type_data_from(data->as_CallTypeData()->ret());
    }
  }
  intptr_t argument_type(int i) const {
    assert(has_arguments(), "no arg type profiling data");
    return args()->type(i);
  }
  ciKlass* valid_argument_type(int i) const {
    assert(has_arguments(), "no arg type profiling data");
    return args()->valid_type(i);
  }
  intptr_t return_type() const {
    assert(has_return(), "no ret type profiling data");
    return ret()->type();
  }
  ciKlass* valid_return_type() const {
    assert(has_return(), "no ret type profiling data");
    return ret()->valid_type();
  }
  bool argument_maybe_null(int i) const {
    return args()->maybe_null(i);
  }
  bool return_maybe_null() const {
    return ret()->maybe_null();
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st, const char* extra) const;
#endif
};
class ciReceiverTypeData : public ReceiverTypeData {
public:
  ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {};
  void set_receiver(uint row, ciKlass* recv) {
    assert((uint)row < row_limit(), "oob");
    set_intptr_at(receiver0_offset + row * receiver_type_row_cell_count,
                  (intptr_t) recv);
  }
  ciKlass* receiver(uint row) const {
    assert((uint)row < row_limit(), "oob");
    ciKlass* recv = (ciKlass*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count);
    assert(recv == NULL || recv->is_klass(), "wrong type");
    return recv;
  }
  virtual void translate_from(const ProfileData* data) {
    translate_receiver_data_from(data);
  }
  void translate_receiver_data_from(const ProfileData* data);
#ifndef PRODUCT
  void print_data_on(outputStream* st, const char* extra) const;
  void print_receiver_data_on(outputStream* st) const;
#endif
};
class ciVirtualCallData : public VirtualCallData {
  ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
public:
  ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {};
  void set_receiver(uint row, ciKlass* recv) {
    rtd_super()->set_receiver(row, recv);
  }
  ciKlass* receiver(uint row) {
    return rtd_super()->receiver(row);
  }
  virtual void translate_from(const ProfileData* data) {
    rtd_super()->translate_receiver_data_from(data);
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st, const char* extra) const;
#endif
};
class ciVirtualCallTypeData : public VirtualCallTypeData {
private:
  ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
public:
  ciVirtualCallTypeData(DataLayout* layout) : VirtualCallTypeData(layout) {}
  void set_receiver(uint row, ciKlass* recv) {
    rtd_super()->set_receiver(row, recv);
  }
  ciKlass* receiver(uint row) const {
    return rtd_super()->receiver(row);
  }
  ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); }
  ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)VirtualCallTypeData::ret(); }
  virtual void translate_from(const ProfileData* data) {
    rtd_super()->translate_receiver_data_from(data);
    if (has_arguments()) {
      args()->translate_type_data_from(data->as_VirtualCallTypeData()->args());
    }
    if (has_return()) {
      ret()->translate_type_data_from(data->as_VirtualCallTypeData()->ret());
    }
  }
  intptr_t argument_type(int i) const {
    assert(has_arguments(), "no arg type profiling data");
    return args()->type(i);
  }
  ciKlass* valid_argument_type(int i) const {
    assert(has_arguments(), "no arg type profiling data");
    return args()->valid_type(i);
  }
  intptr_t return_type() const {
    assert(has_return(), "no ret type profiling data");
    return ret()->type();
  }
  ciKlass* valid_return_type() const {
    assert(has_return(), "no ret type profiling data");
    return ret()->valid_type();
  }
  bool argument_maybe_null(int i) const {
    return args()->maybe_null(i);
  }
  bool return_maybe_null() const {
    return ret()->maybe_null();
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st, const char* extra) const;
#endif
};
class ciRetData : public RetData {
public:
  ciRetData(DataLayout* layout) : RetData(layout) {};
};
class ciBranchData : public BranchData {
public:
  ciBranchData(DataLayout* layout) : BranchData(layout) {};
};
class ciArrayData : public ArrayData {
public:
  ciArrayData(DataLayout* layout) : ArrayData(layout) {};
};
class ciMultiBranchData : public MultiBranchData {
public:
  ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {};
};
class ciArgInfoData : public ArgInfoData {
public:
  ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {};
};
class ciParametersTypeData : public ParametersTypeData {
public:
  ciParametersTypeData(DataLayout* layout) : ParametersTypeData(layout) {}
  virtual void translate_from(const ProfileData* data) {
    parameters()->translate_type_data_from(data->as_ParametersTypeData()->parameters());
  }
  ciTypeStackSlotEntries* parameters() const { return (ciTypeStackSlotEntries*)ParametersTypeData::parameters(); }
  ciKlass* valid_parameter_type(int i) const {
    return parameters()->valid_type(i);
  }
  bool parameter_maybe_null(int i) const {
    return parameters()->maybe_null(i);
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st, const char* extra) const;
#endif
};
class ciSpeculativeTrapData : public SpeculativeTrapData {
public:
  ciSpeculativeTrapData(DataLayout* layout) : SpeculativeTrapData(layout) {}
  virtual void translate_from(const ProfileData* data);
  ciMethod* method() const {
    return (ciMethod*)intptr_at(method_offset);
  }
  void set_method(ciMethod* m) {
    set_intptr_at(method_offset, (intptr_t)m);
  }
#ifndef PRODUCT
  void print_data_on(outputStream* st, const char* extra) const;
#endif
};
class ciMethodData : public ciMetadata {
  CI_PACKAGE_ACCESS
  friend class ciReplay;
private:
  int _data_size;
  int _extra_data_size;
  intptr_t* _data;
  int _hint_di;
  enum { empty_state, immature_state, mature_state };
  u_char _state;
  u_char _saw_free_extra_data;
  intx              _eflags;          // flags on escape information
  intx              _arg_local;       // bit set of non-escaping arguments
  intx              _arg_stack;       // bit set of stack-allocatable arguments
  intx              _arg_returned;    // bit set of returned arguments
  int _current_mileage;
  int _invocation_counter;
  int _backedge_counter;
  MethodData _orig;
  DataLayout* _parameters;
  ciMethodData(MethodData* md);
  ciMethodData();
  int data_size() const { return _data_size; }
  int extra_data_size() const { return _extra_data_size; }
  intptr_t * data() const { return _data; }
  MethodData* get_MethodData() const {
    return (MethodData*)_metadata;
  }
  const char* type_string()                      { return "ciMethodData"; }
  void print_impl(outputStream* st);
  DataLayout* data_layout_at(int data_index) const {
    assert(data_index % sizeof(intptr_t) == 0, "unaligned");
    return (DataLayout*) (((address)_data) + data_index);
  }
  bool out_of_bounds(int data_index) {
    return data_index >= data_size();
  }
  int      hint_di() const  { return _hint_di; }
  void set_hint_di(int di)  {
    assert(!out_of_bounds(di), "hint_di out of bounds");
    _hint_di = di;
  }
  ciProfileData* data_before(int bci) {
    if (data_size() == 0)
      return NULL;
    int hint = hint_di();
    if (data_layout_at(hint)->bci() <= bci)
      return data_at(hint);
    return first_data();
  }
  int first_di() { return 0; }
  ciArgInfoData *arg_info() const;
  address data_base() const {
    return (address) _data;
  }
  DataLayout* limit_data_position() const {
    return (DataLayout*)((address)data_base() + _data_size);
  }
  void load_extra_data();
  ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots);
public:
  bool is_method_data() const { return true; }
  bool is_empty()  { return _state == empty_state; }
  bool is_mature() { return _state == mature_state; }
  int creation_mileage() { return _orig.creation_mileage(); }
  int current_mileage()  { return _current_mileage; }
  int invocation_count() { return _invocation_counter; }
  int backedge_count()   { return _backedge_counter;   }
#if INCLUDE_RTM_OPT
  int rtm_state() {
    if (is_empty()) {
      return NoRTM;
    } else {
      return get_MethodData()->rtm_state();
    }
  }
#endif
  void set_would_profile(bool p);
  void set_compilation_stats(short loops, short blocks);
  void set_argument_type(int bci, int i, ciKlass* k);
  void set_parameter_type(int i, ciKlass* k);
  void set_return_type(int bci, ciKlass* k);
  void load_data();
  int dp_to_di(address dp) {
    return dp - ((address)_data);
  }
  ciProfileData* data_at(int data_index);
  ciProfileData* first_data() { return data_at(first_di()); }
  ciProfileData* next_data(ciProfileData* current);
  bool is_valid(ciProfileData* current) { return current != NULL; }
  DataLayout* extra_data_base() const { return limit_data_position(); }
  ciProfileData* bci_to_data(int bci, ciMethod* m = NULL);
  uint overflow_trap_count() const {
    return _orig.overflow_trap_count();
  }
  uint overflow_recompile_count() const {
    return _orig.overflow_recompile_count();
  }
  uint decompile_count() const {
    return _orig.decompile_count();
  }
  uint trap_count(int reason) const {
    return _orig.trap_count(reason);
  }
  uint trap_reason_limit() const { return _orig.trap_reason_limit(); }
  uint trap_count_limit()  const { return _orig.trap_count_limit(); }
  int has_trap_at(ciProfileData* data, int reason);
  int has_trap_at(int bci, ciMethod* m, int reason) {
    assert((m != NULL) == Deoptimization::reason_is_speculate(reason), "inconsistent method/reason");
    return has_trap_at(bci_to_data(bci, m), reason);
  }
  int trap_recompiled_at(ciProfileData* data);
  int trap_recompiled_at(int bci, ciMethod* m) {
    return trap_recompiled_at(bci_to_data(bci, m));
  }
  void clear_escape_info();
  bool has_escape_info();
  void update_escape_info();
  void set_eflag(MethodData::EscapeFlag f);
  void clear_eflag(MethodData::EscapeFlag f);
  bool eflag_set(MethodData::EscapeFlag f) const;
  void set_arg_local(int i);
  void set_arg_stack(int i);
  void set_arg_returned(int i);
  void set_arg_modified(int arg, uint val);
  bool is_arg_local(int i) const;
  bool is_arg_stack(int i) const;
  bool is_arg_returned(int i) const;
  uint arg_modified(int arg) const;
  ciParametersTypeData* parameters_type_data() const {
    return _parameters != NULL ? new ciParametersTypeData(_parameters) : NULL;
  }
  ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data);
  int      byte_offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { return in_bytes(offset_of_slot(data, slot_offset_in_data)); }
#ifndef PRODUCT
  void print();
  void print_data_on(outputStream* st);
#endif
  void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIMETHODDATA_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodHandle.cpp
#include "precompiled.hpp"
#include "ci/ciClassList.hpp"
#include "ci/ciMethodHandle.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/javaClasses.hpp"
ciMethod* ciMethodHandle::get_vmtarget() const {
  VM_ENTRY_MARK;
  oop form_oop     = java_lang_invoke_MethodHandle::form(get_oop());
  oop vmentry_oop  = java_lang_invoke_LambdaForm::vmentry(form_oop);
  Metadata* vmtarget = java_lang_invoke_MemberName::vmtarget(vmentry_oop);
  if (vmtarget->is_method())
    return CURRENT_ENV->get_method((Method*) vmtarget);
  assert(false, "");
  return NULL;
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodHandle.hpp
#ifndef SHARE_VM_CI_CIMETHODHANDLE_HPP
#define SHARE_VM_CI_CIMETHODHANDLE_HPP
#include "ci/ciClassList.hpp"
#include "ci/ciInstance.hpp"
class ciMethodHandle : public ciInstance {
public:
  ciMethodHandle(instanceHandle h_i) : ciInstance(h_i) {}
  bool is_method_handle() const { return true; }
  ciMethod* get_vmtarget() const;
};
#endif // SHARE_VM_CI_CIMETHODHANDLE_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciMethodType.hpp
#ifndef SHARE_VM_CI_CIMETHODTYPE_HPP
#define SHARE_VM_CI_CIMETHODTYPE_HPP
#include "ci/ciInstance.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/javaClasses.hpp"
class ciMethodType : public ciInstance {
private:
  ciType* class_to_citype(oop klass_oop) const {
    if (java_lang_Class::is_primitive(klass_oop)) {
      BasicType bt = java_lang_Class::primitive_type(klass_oop);
      return ciType::make(bt);
    } else {
      Klass* k = java_lang_Class::as_Klass(klass_oop);
      return CURRENT_ENV->get_klass(k);
    }
  }
public:
  ciMethodType(instanceHandle h_i) : ciInstance(h_i) {}
  bool is_method_type() const { return true; }
  ciType* rtype() const {
    GUARDED_VM_ENTRY(
      oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
      return class_to_citype(rtype);
    )
  }
  int ptype_count() const {
    GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_count(get_oop());)
  }
  int ptype_slot_count() const {
    GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_slot_count(get_oop());)
  }
  ciType* ptype_at(int index) const {
    GUARDED_VM_ENTRY(
      oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
      return class_to_citype(ptype);
    )
  }
};
#endif // SHARE_VM_CI_CIMETHODTYPE_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciNullObject.cpp
#include "precompiled.hpp"
#include "ci/ciNullObject.hpp"
void ciNullObject::print_impl(outputStream* st) {
  ciObject::print_impl(st);
  st->print(" unique");
}
ciNullObject* ciNullObject::make() {
  return CURRENT_ENV->_null_object_instance->as_null_object();
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciNullObject.hpp
#ifndef SHARE_VM_CI_CINULLOBJECT_HPP
#define SHARE_VM_CI_CINULLOBJECT_HPP
#include "ci/ciClassList.hpp"
#include "ci/ciObject.hpp"
#include "ci/ciUtilities.hpp"
class ciNullObject : public ciObject {
  CI_PACKAGE_ACCESS
private:
  ciNullObject() : ciObject() {}
  const char* type_string() { return "ciNullObject"; }
  void print_impl(outputStream* st);
public:
  bool is_java_object() { return true; }
  bool is_null_object() const { return true; }
  bool is_classless() const   { return true; }
  static ciNullObject* make();
};
#endif // SHARE_VM_CI_CINULLOBJECT_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciObjArray.cpp
#include "precompiled.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciObjArray.hpp"
#include "ci/ciUtilities.hpp"
#include "oops/objArrayOop.hpp"
ciObject* ciObjArray::obj_at(int index) {
  VM_ENTRY_MARK;
  objArrayOop array = get_objArrayOop();
  if (index < 0 || index >= array->length()) return NULL;
  oop o = array->obj_at(index);
  if (o == NULL) {
    return ciNullObject::make();
  } else {
    return CURRENT_ENV->get_object(o);
  }
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciObjArray.hpp
#ifndef SHARE_VM_CI_CIOBJARRAY_HPP
#define SHARE_VM_CI_CIOBJARRAY_HPP
#include "ci/ciArray.hpp"
#include "ci/ciClassList.hpp"
#include "oops/objArrayOop.hpp"
class ciObjArray : public ciArray {
  CI_PACKAGE_ACCESS
protected:
  ciObjArray(objArrayHandle h_o) : ciArray(h_o) {}
  ciObjArray(ciKlass* klass, int len) : ciArray(klass, len) {}
  objArrayOop get_objArrayOop() {
    return (objArrayOop)get_oop();
  }
  const char* type_string() { return "ciObjArray"; }
public:
  bool is_obj_array() { return true; }
  ciObject* obj_at(int index);
};
#endif // SHARE_VM_CI_CIOBJARRAY_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciObjArrayKlass.cpp
#include "precompiled.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciUtilities.hpp"
#include "oops/objArrayKlass.hpp"
ciObjArrayKlass::ciObjArrayKlass(KlassHandle h_k) : ciArrayKlass(h_k) {
  assert(get_Klass()->oop_is_objArray(), "wrong type");
  Klass* element_Klass = get_ObjArrayKlass()->bottom_klass();
  _base_element_klass = CURRENT_ENV->get_klass(element_Klass);
  assert(_base_element_klass->is_instance_klass() ||
         _base_element_klass->is_type_array_klass(), "bad base klass");
  if (dimension() == 1) {
    _element_klass = _base_element_klass;
  } else {
    _element_klass = NULL;
  }
  if (!ciObjectFactory::is_initialized()) {
    assert(_element_klass->is_java_lang_Object(), "only arrays of object are shared");
  }
}
ciObjArrayKlass::ciObjArrayKlass(ciSymbol* array_name,
                                 ciKlass* base_element_klass,
                                 int dimension)
  : ciArrayKlass(array_name,
                 dimension, T_OBJECT) {
    _base_element_klass = base_element_klass;
    assert(_base_element_klass->is_instance_klass() ||
           _base_element_klass->is_type_array_klass(), "bad base klass");
    if (dimension == 1) {
      _element_klass = base_element_klass;
    } else {
      _element_klass = NULL;
    }
}
ciKlass* ciObjArrayKlass::element_klass() {
  if (_element_klass == NULL) {
    assert(dimension() > 1, "_element_klass should not be NULL");
    if (is_loaded()) {
      VM_ENTRY_MARK;
      Klass* element_Klass = get_ObjArrayKlass()->element_klass();
      _element_klass = CURRENT_THREAD_ENV->get_klass(element_Klass);
    } else {
      VM_ENTRY_MARK;
      _element_klass = CURRENT_THREAD_ENV->get_klass_by_name_impl(
                          this,
                          constantPoolHandle(),
                          construct_array_name(base_element_klass()->name(),
                                               dimension() - 1),
                          false);
    }
  }
  return _element_klass;
}
ciSymbol* ciObjArrayKlass::construct_array_name(ciSymbol* element_name,
                                                int dimension) {
  EXCEPTION_CONTEXT;
  int element_len = element_name->utf8_length();
  Symbol* base_name_sym = element_name->get_symbol();
  char* name;
  if (base_name_sym->byte_at(0) == '[' ||
      (base_name_sym->byte_at(0) == 'L' &&  // watch package name 'Lxx'
       base_name_sym->byte_at(element_len-1) == ';')) {
    int new_len = element_len + dimension + 1; // for the ['s and '\0'
    name = CURRENT_THREAD_ENV->name_buffer(new_len);
    int pos = 0;
    for ( ; pos < dimension; pos++) {
      name[pos] = '[';
    }
    strncpy(name+pos, (char*)element_name->base(), element_len);
    name[new_len-1] = '\0';
  } else {
    int new_len =   3                       // for L, ;, and '\0'
                  + dimension               // for ['s
                  + element_len;
    name = CURRENT_THREAD_ENV->name_buffer(new_len);
    int pos = 0;
    for ( ; pos < dimension; pos++) {
      name[pos] = '[';
    }
    name[pos++] = 'L';
    strncpy(name+pos, (char*)element_name->base(), element_len);
    name[new_len-2] = ';';
    name[new_len-1] = '\0';
  }
  return ciSymbol::make(name);
}
ciObjArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass) {
  if (element_klass->is_loaded()) {
    EXCEPTION_CONTEXT;
    Klass* array = element_klass->get_Klass()->array_klass(THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
      CURRENT_THREAD_ENV->record_out_of_memory_failure();
      return ciEnv::unloaded_ciobjarrayklass();
    }
    return CURRENT_THREAD_ENV->get_obj_array_klass(array);
  }
  ciSymbol* array_name = construct_array_name(element_klass->name(), 1);
  if (array_name == ciEnv::unloaded_cisymbol()) {
    return ciEnv::unloaded_ciobjarrayklass();
  }
  return
    CURRENT_ENV->get_unloaded_klass(element_klass, array_name)
                        ->as_obj_array_klass();
}
ciObjArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass) {
  GUARDED_VM_ENTRY(return make_impl(element_klass);)
}
ciKlass* ciObjArrayKlass::exact_klass() {
  ciType* base = base_element_type();
  if (base->is_instance_klass()) {
    ciInstanceKlass* ik = base->as_instance_klass();
    if (ik->exact_klass() != NULL) {
      return this;
    }
  } else if (base->is_primitive_type()) {
    return this;
  }
  return NULL;
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciObjArrayKlass.hpp
#ifndef SHARE_VM_CI_CIOBJARRAYKLASS_HPP
#define SHARE_VM_CI_CIOBJARRAYKLASS_HPP
#include "ci/ciArrayKlass.hpp"
class ciObjArrayKlass : public ciArrayKlass {
  CI_PACKAGE_ACCESS
  friend class ciEnv;
private:
  ciKlass* _element_klass;
  ciKlass* _base_element_klass;
protected:
  ciObjArrayKlass(KlassHandle h_k);
  ciObjArrayKlass(ciSymbol* array_name,
                  ciKlass* base_element_klass,
                  int dimension);
  ObjArrayKlass* get_ObjArrayKlass() {
    return (ObjArrayKlass*)get_Klass();
  }
  static ciObjArrayKlass* make_impl(ciKlass* element_klass);
  static ciSymbol* construct_array_name(ciSymbol* element_name,
                                        int       dimension);
  const char* type_string() { return "ciObjArrayKlass"; }
  oop     loader()        { return _base_element_klass->loader(); }
  jobject loader_handle() { return _base_element_klass->loader_handle(); }
  oop     protection_domain()        { return _base_element_klass->protection_domain(); }
  jobject protection_domain_handle() { return _base_element_klass->protection_domain_handle(); }
public:
  ciKlass* element_klass();
  ciKlass* base_element_klass() { return _base_element_klass; }
  bool is_obj_array_klass() const { return true; }
  static ciObjArrayKlass* make(ciKlass* element_klass);
  virtual ciKlass* exact_klass();
};
#endif // SHARE_VM_CI_CIOBJARRAYKLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciObject.cpp
#include "precompiled.hpp"
#include "ci/ciObject.hpp"
#include "ci/ciUtilities.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "oops/oop.inline2.hpp"
ciObject::ciObject(oop o) {
  ASSERT_IN_VM;
  if (ciObjectFactory::is_initialized()) {
    _handle = JNIHandles::make_local(o);
  } else {
    _handle = JNIHandles::make_global(o);
  }
  _klass = NULL;
  init_flags_from(o);
}
ciObject::ciObject(Handle h) {
  ASSERT_IN_VM;
  if (ciObjectFactory::is_initialized()) {
    _handle = JNIHandles::make_local(h());
  } else {
    _handle = JNIHandles::make_global(h);
  }
  _klass = NULL;
  init_flags_from(h());
}
ciObject::ciObject(ciKlass* klass) {
  ASSERT_IN_VM;
  assert(klass != NULL, "must supply klass");
  _handle = NULL;
  _klass = klass;
}
ciObject::ciObject() {
  ASSERT_IN_VM;
  _handle = NULL;
  _klass = NULL;
}
ciKlass* ciObject::klass() {
  if (_klass == NULL) {
    if (_handle == NULL) {
      assert(is_null_object(), "must be null object");
      ShouldNotReachHere();
      return NULL;
    }
    GUARDED_VM_ENTRY(
      oop o = get_oop();
      _klass = CURRENT_ENV->get_klass(o->klass());
    );
  }
  return _klass;
}
bool ciObject::equals(ciObject* obj) {
  return (this == obj);
}
int ciObject::hash() {
  return ident() * 31;
}
jobject ciObject::constant_encoding() {
  assert(is_null_object() || handle() != NULL, "cannot embed null pointer");
  assert(can_be_constant(), "oop must be NULL or perm");
  return handle();
}
bool ciObject::can_be_constant() {
  if (ScavengeRootsInCode >= 1)  return true;  // now everybody can encode as a constant
  return handle() == NULL;
}
bool ciObject::should_be_constant() {
  if (ScavengeRootsInCode >= 2)  return true;  // force everybody to be a constant
  if (is_null_object()) return true;
  ciEnv* env = CURRENT_ENV;
    if (klass() == env->String_klass() || klass() == env->Class_klass()) {
      return true;
    }
  if (EnableInvokeDynamic &&
      (klass()->is_subclass_of(env->MethodHandle_klass()) ||
       klass()->is_subclass_of(env->CallSite_klass()))) {
    assert(ScavengeRootsInCode >= 1, "must be");
    return true;
  }
  return handle() == NULL;
}
void ciObject::init_flags_from(oop x) {
  int flags = 0;
  if (x != NULL) {
    assert(Universe::heap()->is_in_reserved(x), "must be");
    if (x->is_scavengable())
      flags |= SCAVENGABLE_FLAG;
  }
  _ident |= flags;
}
void ciObject::print(outputStream* st) {
  st->print("<%s", type_string());
  GUARDED_VM_ENTRY(print_impl(st);)
  st->print(" ident=%d %s address=" INTPTR_FORMAT ">", ident(),
        is_scavengable() ? "SCAVENGABLE" : "",
        p2i((address)this));
}
void ciObject::print_oop(outputStream* st) {
  if (is_null_object()) {
    st->print_cr("NULL");
  } else if (!is_loaded()) {
    st->print_cr("UNLOADED");
  } else {
    GUARDED_VM_ENTRY(get_oop()->print_on(st);)
  }
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciObject.hpp
#ifndef SHARE_VM_CI_CIOBJECT_HPP
#define SHARE_VM_CI_CIOBJECT_HPP
#include "ci/ciBaseObject.hpp"
#include "ci/ciClassList.hpp"
#include "memory/allocation.hpp"
#include "runtime/handles.hpp"
#include "runtime/jniHandles.hpp"
class ciObject : public ciBaseObject {
  CI_PACKAGE_ACCESS
  friend class ciEnv;
private:
  jobject  _handle;
  ciKlass* _klass;
protected:
  ciObject();
  ciObject(oop o);
  ciObject(Handle h);
  ciObject(ciKlass* klass);
  jobject      handle()  const { return _handle; }
  oop get_oop() const {
    assert(_handle != NULL, "null oop");
    return JNIHandles::resolve_non_null(_handle);
  }
  void init_flags_from(oop x);
  virtual void print_impl(outputStream* st) {}
  virtual const char* type_string() { return "ciObject"; }
public:
  ciKlass* klass();
  bool equals(ciObject* obj);
  int hash();
  bool can_be_constant();
  bool should_be_constant();
  bool is_scavengable() { return (_ident & SCAVENGABLE_FLAG) != 0; }
  jobject constant_encoding();
  virtual bool is_object() const            { return true; }
  virtual bool is_null_object()       const { return false; }
  virtual bool is_call_site()         const { return false; }
  virtual bool is_cpcache()           const { return false; }
  virtual bool is_instance()                { return false; }
  virtual bool is_member_name()       const { return false; }
  virtual bool is_method_handle()     const { return false; }
  virtual bool is_method_type()       const { return false; }
  virtual bool is_array()                   { return false; }
  virtual bool is_obj_array()               { return false; }
  virtual bool is_type_array()              { return false; }
  virtual bool is_classless() const         { return false; }
  virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
  bool is_loaded() const {
    return handle() != NULL || is_classless();
  }
  ciNullObject* as_null_object() {
    assert(is_null_object(), "bad cast");
    return (ciNullObject*)this;
  }
  ciCallSite* as_call_site() {
    assert(is_call_site(), "bad cast");
    return (ciCallSite*)this;
  }
  ciInstance* as_instance() {
    assert(is_instance(), "bad cast");
    return (ciInstance*)this;
  }
  ciMemberName* as_member_name() {
    assert(is_member_name(), "bad cast");
    return (ciMemberName*)this;
  }
  ciMethodHandle* as_method_handle() {
    assert(is_method_handle(), "bad cast");
    return (ciMethodHandle*)this;
  }
  ciMethodType* as_method_type() {
    assert(is_method_type(), "bad cast");
    return (ciMethodType*)this;
  }
  ciArray* as_array() {
    assert(is_array(), "bad cast");
    return (ciArray*)this;
  }
  ciObjArray* as_obj_array() {
    assert(is_obj_array(), "bad cast");
    return (ciObjArray*)this;
  }
  ciTypeArray* as_type_array() {
    assert(is_type_array(), "bad cast");
    return (ciTypeArray*)this;
  }
  void print(outputStream* st);
  void print() { print(tty); }  // GDB cannot handle default arguments
  void print_oop(outputStream* st = tty);
};
#endif // SHARE_VM_CI_CIOBJECT_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciObjectFactory.cpp
#include "precompiled.hpp"
#include "ci/ciCallSite.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMemberName.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciMethodHandle.hpp"
#include "ci/ciMethodType.hpp"
#include "ci/ciNullObject.hpp"
#include "ci/ciObjArray.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciObject.hpp"
#include "ci/ciObjectFactory.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "runtime/fieldType.hpp"
#if INCLUDE_ALL_GCS
# include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#endif
GrowableArray<ciMetadata*>* ciObjectFactory::_shared_ci_metadata = NULL;
ciSymbol*                 ciObjectFactory::_shared_ci_symbols[vmSymbols::SID_LIMIT];
int                       ciObjectFactory::_shared_ident_limit = 0;
volatile bool             ciObjectFactory::_initialized = false;
ciObjectFactory::ciObjectFactory(Arena* arena,
                                 int expected_size) {
  for (int i = 0; i < NON_PERM_BUCKETS; i++) {
    _non_perm_bucket[i] = NULL;
  }
  _non_perm_count = 0;
  _next_ident = _shared_ident_limit;
  _arena = arena;
  _ci_metadata = new (arena) GrowableArray<ciMetadata*>(arena, expected_size, 0, NULL);
  if (_shared_ci_metadata != NULL) {
    _ci_metadata->appendAll(_shared_ci_metadata);
  }
  _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL);
  _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL);
  _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL);
  _return_addresses =
    new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL);
  _symbols = new (arena) GrowableArray<ciSymbol*>(arena, 100, 0, NULL);
}
void ciObjectFactory::initialize() {
  ASSERT_IN_VM;
  JavaThread* thread = JavaThread::current();
  HandleMark  handle_mark(thread);
  Arena* arena = new (mtCompiler) Arena(mtCompiler);
  ciEnv initial(arena);
  ciEnv* env = ciEnv::current();
  env->_factory->init_shared_objects();
  _initialized = true;
}
void ciObjectFactory::init_shared_objects() {
  _next_ident = 1;  // start numbering CI objects at 1
  {
    int i;
    for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) {
      Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i);
      assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping");
      ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i);
      init_ident_of(sym);
      _shared_ci_symbols[i] = sym;
    }
#ifdef ASSERT
    for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) {
      Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i);
      ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i);
      assert(sym->get_symbol() == vmsym, "oop must match");
    }
    assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check");
#endif
  }
  _ci_metadata = new (_arena) GrowableArray<ciMetadata*>(_arena, 64, 0, NULL);
  for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) {
    BasicType t = (BasicType)i;
    if (type2name(t) != NULL && t != T_OBJECT && t != T_ARRAY && t != T_NARROWOOP && t != T_NARROWKLASS) {
      ciType::_basic_types[t] = new (_arena) ciType(t);
      init_ident_of(ciType::_basic_types[t]);
    }
  }
  ciEnv::_null_object_instance = new (_arena) ciNullObject();
  init_ident_of(ciEnv::_null_object_instance);
#define WK_KLASS_DEFN(name, ignore_s, opt)                              \
  if (SystemDictionary::name() != NULL) \
    ciEnv::_##name = get_metadata(SystemDictionary::name())->as_instance_klass();
  WK_KLASSES_DO(WK_KLASS_DEFN)
#undef WK_KLASS_DEFN
  for (int len = -1; len != _ci_metadata->length(); ) {
    len = _ci_metadata->length();
    for (int i2 = 0; i2 < len; i2++) {
      ciMetadata* obj = _ci_metadata->at(i2);
      assert (obj->is_metadata(), "what else would it be?");
      if (obj->is_loaded() && obj->is_instance_klass()) {
        obj->as_instance_klass()->compute_nonstatic_fields();
      }
    }
  }
  ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol());
  ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL);
  init_ident_of(ciEnv::_unloaded_ciinstance_klass);
  ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1);
  init_ident_of(ciEnv::_unloaded_ciobjarrayklass);
  assert(ciEnv::_unloaded_ciobjarrayklass->is_obj_array_klass(), "just checking");
  get_metadata(Universe::boolArrayKlassObj());
  get_metadata(Universe::charArrayKlassObj());
  get_metadata(Universe::singleArrayKlassObj());
  get_metadata(Universe::doubleArrayKlassObj());
  get_metadata(Universe::byteArrayKlassObj());
  get_metadata(Universe::shortArrayKlassObj());
  get_metadata(Universe::intArrayKlassObj());
  get_metadata(Universe::longArrayKlassObj());
  assert(_non_perm_count == 0, "no shared non-perm objects");
  _shared_ident_limit = _next_ident;
  _shared_ci_metadata = _ci_metadata;
}
ciSymbol* ciObjectFactory::get_symbol(Symbol* key) {
  vmSymbols::SID sid = vmSymbols::find_sid(key);
  if (sid != vmSymbols::NO_SID) {
    return vm_symbol_at(sid);
  }
  assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, "");
  ciSymbol* s = new (arena()) ciSymbol(key, vmSymbols::NO_SID);
  _symbols->push(s);
  return s;
}
void ciObjectFactory::remove_symbols() {
  for (int i = 0; i < _symbols->length(); i++) {
    ciSymbol* s = _symbols->at(i);
    s->get_symbol()->decrement_refcount();
  }
}
ciObject* ciObjectFactory::get(oop key) {
  ASSERT_IN_VM;
  assert(Universe::heap()->is_in_reserved(key), "must be");
  NonPermObject* &bucket = find_non_perm(key);
  if (bucket != NULL) {
    return bucket->object();
  }
  Handle keyHandle(key);
  ciObject* new_object = create_new_object(keyHandle());
  assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
  init_ident_of(new_object);
  assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be");
  insert_non_perm(bucket, keyHandle(), new_object);
  return new_object;
}
ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
  ASSERT_IN_VM;
#ifdef ASSERT
  if (CIObjectFactoryVerify) {
    Metadata* last = NULL;
    for (int j = 0; j< _ci_metadata->length(); j++) {
      Metadata* o = _ci_metadata->at(j)->constant_encoding();
      assert(last < o, "out of order");
      last = o;
    }
  }
#endif // ASSERT
  int len = _ci_metadata->length();
  int index = find(key, _ci_metadata);
#ifdef ASSERT
  if (CIObjectFactoryVerify) {
    for (int i=0; i<_ci_metadata->length(); i++) {
      if (_ci_metadata->at(i)->constant_encoding() == key) {
        assert(index == i, " bad lookup");
      }
    }
  }
#endif
  if (!is_found_at(index, key, _ci_metadata)) {
    ciMetadata* new_object = create_new_metadata(key);
    init_ident_of(new_object);
    assert(new_object->is_metadata(), "must be");
    if (len != _ci_metadata->length()) {
      index = find(key, _ci_metadata);
    }
    assert(!is_found_at(index, key, _ci_metadata), "no double insert");
    insert(index, new_object, _ci_metadata);
    return new_object;
  }
  return _ci_metadata->at(index)->as_metadata();
}
ciObject* ciObjectFactory::create_new_object(oop o) {
  EXCEPTION_CONTEXT;
  if (o->is_instance()) {
    instanceHandle h_i(THREAD, (instanceOop)o);
    if (java_lang_invoke_CallSite::is_instance(o))
      return new (arena()) ciCallSite(h_i);
    else if (java_lang_invoke_MemberName::is_instance(o))
      return new (arena()) ciMemberName(h_i);
    else if (java_lang_invoke_MethodHandle::is_instance(o))
      return new (arena()) ciMethodHandle(h_i);
    else if (java_lang_invoke_MethodType::is_instance(o))
      return new (arena()) ciMethodType(h_i);
    else
      return new (arena()) ciInstance(h_i);
  } else if (o->is_objArray()) {
    objArrayHandle h_oa(THREAD, (objArrayOop)o);
    return new (arena()) ciObjArray(h_oa);
  } else if (o->is_typeArray()) {
    typeArrayHandle h_ta(THREAD, (typeArrayOop)o);
    return new (arena()) ciTypeArray(h_ta);
  }
  ShouldNotReachHere();
  return NULL;
}
ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) {
  EXCEPTION_CONTEXT;
  if (_initialized && o->is_klass()) {
    Klass* holder = ((Klass*)o);
    if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
      ciObject* h = get(holder->klass_holder());
    }
  }
  if (o->is_klass()) {
    KlassHandle h_k(THREAD, (Klass*)o);
    Klass* k = (Klass*)o;
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (Method*)o);
    ciEnv *env = CURRENT_THREAD_ENV;
    ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder());
    return new (arena()) ciMethod(h_m, holder);
  } else if (o->is_methodData()) {
    methodHandle h_m(THREAD, ((MethodData*)o)->method());
    return new (arena()) ciMethodData((MethodData*)o);
  }
  ShouldNotReachHere();
  return NULL;
}
void ciObjectFactory::ensure_metadata_alive(ciMetadata* m) {
  ASSERT_IN_VM; // We're handling raw oops here.
#if INCLUDE_ALL_GCS
  if (!UseG1GC) {
    return;
  }
  Klass* metadata_owner_klass;
  if (m->is_klass()) {
    metadata_owner_klass = m->as_klass()->get_Klass();
  } else if (m->is_method()) {
    metadata_owner_klass = m->as_method()->get_Method()->constants()->pool_holder();
  } else {
    fatal("Not implemented for other types of metadata");
    return;
  }
  oop metadata_holder = metadata_owner_klass->klass_holder();
  if (metadata_holder != NULL) {
    G1SATBCardTableModRefBS::enqueue(metadata_holder);
  }
#endif
}
ciMethod* ciObjectFactory::get_unloaded_method(ciInstanceKlass* holder,
                                               ciSymbol*        name,
                                               ciSymbol*        signature,
                                               ciInstanceKlass* accessor) {
  ciSignature* that = NULL;
  for (int i = 0; i < _unloaded_methods->length(); i++) {
    ciMethod* entry = _unloaded_methods->at(i);
    if (entry->holder()->equals(holder) &&
        entry->name()->equals(name) &&
        entry->signature()->as_symbol()->equals(signature)) {
      if (entry->signature()->accessing_klass() == accessor) {
        return entry;
      } else {
        if (that == NULL)  that = new (arena()) ciSignature(accessor, constantPoolHandle(), signature);
        if (entry->signature()->equals(that)) {
          return entry;
        }
      }
    }
  }
  ciMethod* new_method = new (arena()) ciMethod(holder, name, signature, accessor);
  init_ident_of(new_method);
  _unloaded_methods->append(new_method);
  return new_method;
}
ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass,
                                             ciSymbol* name,
                                             bool create_if_not_found) {
  EXCEPTION_CONTEXT;
  oop loader = NULL;
  oop domain = NULL;
  if (accessing_klass != NULL) {
    loader = accessing_klass->loader();
    domain = accessing_klass->protection_domain();
  }
  for (int i=0; i<_unloaded_klasses->length(); i++) {
    ciKlass* entry = _unloaded_klasses->at(i);
    if (entry->name()->equals(name) &&
        entry->loader() == loader &&
        entry->protection_domain() == domain) {
      return entry;
    }
  }
  if (!create_if_not_found)
    return NULL;
  ciKlass* new_klass = NULL;
  if (name->byte_at(0) == '[') {
    FieldArrayInfo fd;
    BasicType element_type = FieldType::get_array_info(name->get_symbol(),
                                                       fd, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
      CURRENT_THREAD_ENV->record_out_of_memory_failure();
      return ciEnv::_unloaded_ciobjarrayklass;
    }
    int dimension = fd.dimension();
    assert(element_type != T_ARRAY, "unsuccessful decomposition");
    ciKlass* element_klass = NULL;
    if (element_type == T_OBJECT) {
      ciEnv *env = CURRENT_THREAD_ENV;
      ciSymbol* ci_name = env->get_symbol(fd.object_key());
      element_klass =
        env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass();
    } else {
      assert(dimension > 1, "one dimensional type arrays are always loaded.");
      dimension--;
      element_klass = ciTypeArrayKlass::make(element_type);
    }
    new_klass = new (arena()) ciObjArrayKlass(name, element_klass, dimension);
  } else {
    jobject loader_handle = NULL;
    jobject domain_handle = NULL;
    if (accessing_klass != NULL) {
      loader_handle = accessing_klass->loader_handle();
      domain_handle = accessing_klass->protection_domain_handle();
    }
    new_klass = new (arena()) ciInstanceKlass(name, loader_handle, domain_handle);
  }
  init_ident_of(new_klass);
  _unloaded_klasses->append(new_klass);
  return new_klass;
}
ciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_klass) {
  for (int i=0; i<_unloaded_instances->length(); i++) {
    ciInstance* entry = _unloaded_instances->at(i);
    if (entry->klass()->equals(instance_klass)) {
      return entry;
    }
  }
  ciInstance* new_instance = new (arena()) ciInstance(instance_klass);
  init_ident_of(new_instance);
  _unloaded_instances->append(new_instance);
  assert(!new_instance->is_loaded(), "");
  assert(new_instance->klass() == instance_klass, "");
  return new_instance;
}
ciInstance* ciObjectFactory::get_unloaded_klass_mirror(ciKlass*  type) {
  assert(ciEnv::_Class_klass != NULL, "");
  return get_unloaded_instance(ciEnv::_Class_klass->as_instance_klass());
}
ciInstance* ciObjectFactory::get_unloaded_method_handle_constant(ciKlass*  holder,
                                                                 ciSymbol* name,
                                                                 ciSymbol* signature,
                                                                 int       ref_kind) {
  if (ciEnv::_MethodHandle_klass == NULL)  return NULL;
  return get_unloaded_instance(ciEnv::_MethodHandle_klass->as_instance_klass());
}
ciInstance* ciObjectFactory::get_unloaded_method_type_constant(ciSymbol* signature) {
  if (ciEnv::_MethodType_klass == NULL)  return NULL;
  return get_unloaded_instance(ciEnv::_MethodType_klass->as_instance_klass());
}
ciInstance* ciObjectFactory::get_unloaded_object_constant() {
  if (ciEnv::_Object_klass == NULL)  return NULL;
  return get_unloaded_instance(ciEnv::_Object_klass->as_instance_klass());
}
ciMethodData* ciObjectFactory::get_empty_methodData() {
  ciMethodData* new_methodData = new (arena()) ciMethodData();
  init_ident_of(new_methodData);
  return new_methodData;
}
ciReturnAddress* ciObjectFactory::get_return_address(int bci) {
  for (int i=0; i<_return_addresses->length(); i++) {
    ciReturnAddress* entry = _return_addresses->at(i);
    if (entry->bci() == bci) {
      return entry;
    }
  }
  ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci);
  init_ident_of(new_ret_addr);
  _return_addresses->append(new_ret_addr);
  return new_ret_addr;
}
void ciObjectFactory::init_ident_of(ciBaseObject* obj) {
  obj->set_ident(_next_ident++);
}
int ciObjectFactory::find(Metadata* key, GrowableArray<ciMetadata*>* objects) {
  int min = 0;
  int max = objects->length()-1;
  while (max >= min) {
    int mid = (max + min) / 2;
    Metadata* value = objects->at(mid)->constant_encoding();
    if (value < key) {
      min = mid + 1;
    } else if (value > key) {
      max = mid - 1;
    } else {
      return mid;
    }
  }
  return min;
}
bool ciObjectFactory::is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects) {
  return (index < objects->length() &&
          objects->at(index)->constant_encoding() == key);
}
void ciObjectFactory::insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects) {
  int len = objects->length();
  if (len == index) {
    objects->append(obj);
  } else {
    objects->append(objects->at(len-1));
    int pos;
    for (pos = len-2; pos >= index; pos--) {
      objects->at_put(pos+1,objects->at(pos));
    }
    objects->at_put(index, obj);
  }
}
static ciObjectFactory::NonPermObject* emptyBucket = NULL;
ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
  assert(Universe::heap()->is_in_reserved(key), "must be");
  ciMetadata* klass = get_metadata(key->klass());
  NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
  for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {
    if (is_equal(p, key))  break;
  }
  return (*bp);
}
inline ciObjectFactory::NonPermObject::NonPermObject(ciObjectFactory::NonPermObject* &bucket, oop key, ciObject* object) {
  assert(ciObjectFactory::is_initialized(), "");
  _object = object;
  _next = bucket;
  bucket = this;
}
void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, oop key, ciObject* obj) {
  assert(Universe::heap()->is_in_reserved_or_null(key), "must be");
  assert(&where != &emptyBucket, "must not try to fill empty bucket");
  NonPermObject* p = new (arena()) NonPermObject(where, key, obj);
  assert(where == p && is_equal(p, key) && p->object() == obj, "entry must match");
  assert(find_non_perm(key) == p, "must find the same spot");
  ++_non_perm_count;
}
ciSymbol* ciObjectFactory::vm_symbol_at(int index) {
  assert(index >= vmSymbols::FIRST_SID && index < vmSymbols::SID_LIMIT, "oob");
  return _shared_ci_symbols[index];
}
void ciObjectFactory::metadata_do(void f(Metadata*)) {
  if (_ci_metadata == NULL) return;
  for (int j = 0; j< _ci_metadata->length(); j++) {
    Metadata* o = _ci_metadata->at(j)->constant_encoding();
    f(o);
  }
}
void ciObjectFactory::print_contents_impl() {
  int len = _ci_metadata->length();
  tty->print_cr("ciObjectFactory (%d) meta data contents:", len);
  for (int i=0; i<len; i++) {
    _ci_metadata->at(i)->print();
    tty->cr();
  }
}
void ciObjectFactory::print_contents() {
  print();
  tty->cr();
  GUARDED_VM_ENTRY(print_contents_impl();)
}
void ciObjectFactory::print() {
  tty->print("<ciObjectFactory oops=%d metadata=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>",
             _non_perm_count, _ci_metadata->length(), _unloaded_methods->length(),
             _unloaded_instances->length(),
             _unloaded_klasses->length());
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciObjectFactory.hpp
#ifndef SHARE_VM_CI_CIOBJECTFACTORY_HPP
#define SHARE_VM_CI_CIOBJECTFACTORY_HPP
#include "ci/ciClassList.hpp"
#include "ci/ciObject.hpp"
#include "utilities/growableArray.hpp"
class ciObjectFactory : public ResourceObj {
  friend class VMStructs;
  friend class ciEnv;
private:
  static volatile bool _initialized;
  static GrowableArray<ciMetadata*>* _shared_ci_metadata;
  static ciSymbol*                 _shared_ci_symbols[];
  static int                       _shared_ident_limit;
  Arena*                    _arena;
  GrowableArray<ciMetadata*>*        _ci_metadata;
  GrowableArray<ciMethod*>* _unloaded_methods;
  GrowableArray<ciKlass*>* _unloaded_klasses;
  GrowableArray<ciInstance*>* _unloaded_instances;
  GrowableArray<ciReturnAddress*>* _return_addresses;
  GrowableArray<ciSymbol*>* _symbols;  // keep list of symbols created
  int                       _next_ident;
public:
  struct NonPermObject : public ResourceObj {
    ciObject*      _object;
    NonPermObject* _next;
    inline NonPermObject(NonPermObject* &bucket, oop key, ciObject* object);
    ciObject*     object()  { return _object; }
    NonPermObject* &next()  { return _next; }
  };
private:
  enum { NON_PERM_BUCKETS = 61 };
  NonPermObject* _non_perm_bucket[NON_PERM_BUCKETS];
  int _non_perm_count;
  int find(Metadata* key, GrowableArray<ciMetadata*>* objects);
  bool is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects);
  void insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects);
  ciObject* create_new_object(oop o);
  ciMetadata* create_new_metadata(Metadata* o);
  void ensure_metadata_alive(ciMetadata* m);
  static bool is_equal(NonPermObject* p, oop key) {
    return p->object()->get_oop() == key;
  }
  NonPermObject* &find_non_perm(oop key);
  void insert_non_perm(NonPermObject* &where, oop key, ciObject* obj);
  void init_ident_of(ciBaseObject* obj);
  Arena* arena() { return _arena; }
  void print_contents_impl();
  ciInstance* get_unloaded_instance(ciInstanceKlass* klass);
public:
  static bool is_initialized() { return _initialized; }
  static void initialize();
  void init_shared_objects();
  void remove_symbols();
  ciObjectFactory(Arena* arena, int expected_size);
  ciObject* get(oop key);
  ciMetadata* get_metadata(Metadata* key);
  ciSymbol* get_symbol(Symbol* key);
  static ciSymbol* vm_symbol_at(int index);
  ciMethod* get_unloaded_method(ciInstanceKlass* holder,
                                ciSymbol*        name,
                                ciSymbol*        signature,
                                ciInstanceKlass* accessor);
  ciKlass* get_unloaded_klass(ciKlass* accessing_klass,
                              ciSymbol* name,
                              bool create_if_not_found);
  ciInstance* get_unloaded_klass_mirror(ciKlass* type);
  ciInstance* get_unloaded_method_handle_constant(ciKlass*  holder,
                                                  ciSymbol* name,
                                                  ciSymbol* signature,
                                                  int       ref_kind);
  ciInstance* get_unloaded_method_type_constant(ciSymbol* signature);
  ciInstance* get_unloaded_object_constant();
  ciMethodData* get_empty_methodData();
  ciReturnAddress* get_return_address(int bci);
  GrowableArray<ciMetadata*>* get_ci_metadata() const { return _ci_metadata; }
  void metadata_do(void f(Metadata*));
  void print_contents();
  void print();
};
#endif // SHARE_VM_CI_CIOBJECTFACTORY_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciReplay.cpp
#include "precompiled.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciUtilities.hpp"
#include "compiler/compileBroker.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "utilities/copy.hpp"
#include "utilities/macros.hpp"
#ifndef PRODUCT
typedef struct _ciMethodDataRecord {
  const char* _klass_name;
  const char* _method_name;
  const char* _signature;
  int _state;
  int _current_mileage;
  intptr_t* _data;
  char*     _orig_data;
  jobject*  _oops_handles;
  int*      _oops_offsets;
  int       _data_length;
  int       _orig_data_length;
  int       _oops_length;
} ciMethodDataRecord;
typedef struct _ciMethodRecord {
  const char* _klass_name;
  const char* _method_name;
  const char* _signature;
  int _instructions_size;
  int _interpreter_invocation_count;
  int _interpreter_throwout_count;
  int _invocation_counter;
  int _backedge_counter;
} ciMethodRecord;
typedef struct _ciInlineRecord {
  const char* _klass_name;
  const char* _method_name;
  const char* _signature;
  int _inline_depth;
  int _inline_bci;
} ciInlineRecord;
class  CompileReplay;
static CompileReplay* replay_state;
class CompileReplay : public StackObj {
 private:
  FILE*   _stream;
  Thread* _thread;
  Handle  _protection_domain;
  Handle  _loader;
  GrowableArray<ciMethodRecord*>     _ci_method_records;
  GrowableArray<ciMethodDataRecord*> _ci_method_data_records;
  GrowableArray<ciInlineRecord*>*    _ci_inline_records;
  const char* _error_message;
  char* _bufptr;
  char* _buffer;
  int   _buffer_length;
  int   _buffer_pos;
  ciKlass* _iklass;
  Method*  _imethod;
  int      _entry_bci;
  int      _comp_level;
 public:
  CompileReplay(const char* filename, TRAPS) {
    _thread = THREAD;
    _loader = Handle(_thread, SystemDictionary::java_system_loader());
    _protection_domain = Handle();
    _stream = fopen(filename, "rt");
    if (_stream == NULL) {
      fprintf(stderr, "ERROR: Can't open replay file %s\n", filename);
    }
    _ci_inline_records = NULL;
    _error_message = NULL;
    _buffer_length = 32;
    _buffer = NEW_RESOURCE_ARRAY(char, _buffer_length);
    _bufptr = _buffer;
    _buffer_pos = 0;
    _imethod = NULL;
    _iklass  = NULL;
    _entry_bci  = 0;
    _comp_level = 0;
    test();
  }
  ~CompileReplay() {
    if (_stream != NULL) fclose(_stream);
  }
  void test() {
    strcpy(_buffer, "1 2 foo 4 bar 0x9 \"this is it\"");
    _bufptr = _buffer;
    assert(parse_int("test") == 1, "what");
    assert(parse_int("test") == 2, "what");
    assert(strcmp(parse_string(), "foo") == 0, "what");
    assert(parse_int("test") == 4, "what");
    assert(strcmp(parse_string(), "bar") == 0, "what");
    assert(parse_intptr_t("test") == 9, "what");
    assert(strcmp(parse_quoted_string(), "this is it") == 0, "what");
  }
  bool had_error() {
    return _error_message != NULL || _thread->has_pending_exception();
  }
  bool can_replay() {
    return !(_stream == NULL || had_error());
  }
  void report_error(const char* msg) {
    _error_message = msg;
    for (int i = 0; i < _buffer_pos; i++) {
      if (_buffer[i] == '\0') _buffer[i] = ' ';
    }
  }
  int parse_int(const char* label) {
    if (had_error()) {
      return 0;
    }
    int v = 0;
    int read;
    if (sscanf(_bufptr, "%i%n", &v, &read) != 1) {
      report_error(label);
    } else {
      _bufptr += read;
    }
    return v;
  }
  intptr_t parse_intptr_t(const char* label) {
    if (had_error()) {
      return 0;
    }
    intptr_t v = 0;
    int read;
    if (sscanf(_bufptr, INTPTR_FORMAT "%n", &v, &read) != 1) {
      report_error(label);
    } else {
      _bufptr += read;
    }
    return v;
  }
  void skip_ws() {
    while (*_bufptr == ' ' || *_bufptr == '\t') {
      _bufptr++;
    }
  }
  char* scan_and_terminate(char delim) {
    char* str = _bufptr;
    while (*_bufptr != delim && *_bufptr != '\0') {
      _bufptr++;
    }
    if (*_bufptr != '\0') {
    }
    if (_bufptr == str) {
      return NULL;
    }
    return str;
  }
  char* parse_string() {
    if (had_error()) return NULL;
    skip_ws();
    return scan_and_terminate(' ');
  }
  char* parse_quoted_string() {
    if (had_error()) return NULL;
    skip_ws();
    if (*_bufptr == '"') {
      _bufptr++;
      return scan_and_terminate('"');
    } else {
      return scan_and_terminate(' ');
    }
  }
  const char* parse_escaped_string() {
    char* result = parse_quoted_string();
    if (result != NULL) {
      unescape_string(result);
    }
    return result;
  }
  bool parse_tag_and_count(const char* tag, int& length) {
    const char* t = parse_string();
    if (t == NULL) {
      return false;
    }
    if (strcmp(tag, t) != 0) {
      report_error(tag);
      return false;
    }
    length = parse_int("parse_tag_and_count");
    return !had_error();
  }
  char* parse_data(const char* tag, int& length) {
    if (!parse_tag_and_count(tag, length)) {
      return NULL;
    }
    char * result = NEW_RESOURCE_ARRAY(char, length);
    for (int i = 0; i < length; i++) {
      int val = parse_int("data");
      result[i] = val;
    }
    return result;
  }
  intptr_t* parse_intptr_data(const char* tag, int& length) {
    if (!parse_tag_and_count(tag, length)) {
      return NULL;
    }
    intptr_t* result = NEW_RESOURCE_ARRAY(intptr_t, length);
    for (int i = 0; i < length; i++) {
      skip_ws();
      intptr_t val = parse_intptr_t("data");
      result[i] = val;
    }
    return result;
  }
  Symbol* parse_symbol(TRAPS) {
    const char* str = parse_escaped_string();
    if (str != NULL) {
      Symbol* sym = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
      return sym;
    }
    return NULL;
  }
  Klass* parse_klass(TRAPS) {
    const char* str = parse_escaped_string();
    Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
    if (klass_name != NULL) {
      Klass* k = NULL;
      if (_iklass != NULL) {
        k = (Klass*)_iklass->find_klass(ciSymbol::make(klass_name->as_C_string()))->constant_encoding();
      } else {
        k = SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
      }
      if (HAS_PENDING_EXCEPTION) {
        oop throwable = PENDING_EXCEPTION;
        java_lang_Throwable::print(throwable, tty);
        tty->cr();
        report_error(str);
        return NULL;
      }
      return k;
    }
    return NULL;
  }
  Klass* resolve_klass(const char* klass, TRAPS) {
    Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
    return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
  }
  Method* parse_method(TRAPS) {
    InstanceKlass* k = (InstanceKlass*)parse_klass(CHECK_NULL);
    Symbol* method_name = parse_symbol(CHECK_NULL);
    Symbol* method_signature = parse_symbol(CHECK_NULL);
    Method* m = k->find_method(method_name, method_signature);
    if (m == NULL) {
      report_error("Can't find method");
    }
    return m;
  }
  int get_line(int c) {
    while(c != EOF) {
      if (_buffer_pos + 1 >= _buffer_length) {
        int new_length = _buffer_length * 2;
        _buffer = REALLOC_RESOURCE_ARRAY(char, _buffer, _buffer_length, new_length);
        _buffer_length = new_length;
      }
      if (c == '\n') {
        c = getc(_stream); // get next char
        break;
      } else if (c == '\r') {
      } else {
        _buffer[_buffer_pos++] = c;
      }
      c = getc(_stream);
    }
    _buffer[_buffer_pos] = '\0'; // NL or EOF
    _buffer_pos = 0;
    _bufptr = _buffer;
    return c;
  }
  void process(TRAPS) {
    int line_no = 1;
    int c = getc(_stream);
    while(c != EOF) {
      c = get_line(c);
      process_command(THREAD);
      if (had_error()) {
        tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
        if (ReplayIgnoreInitErrors) {
          CLEAR_PENDING_EXCEPTION;
          _error_message = NULL;
        } else {
          return;
        }
      }
      line_no++;
    }
  }
  void process_command(TRAPS) {
    char* cmd = parse_string();
    if (cmd == NULL) {
      return;
    }
    if (strcmp("#", cmd) == 0) {
    } else if (strcmp("compile", cmd) == 0) {
      process_compile(CHECK);
    } else if (strcmp("ciMethod", cmd) == 0) {
      process_ciMethod(CHECK);
    } else if (strcmp("ciMethodData", cmd) == 0) {
      process_ciMethodData(CHECK);
    } else if (strcmp("staticfield", cmd) == 0) {
      process_staticfield(CHECK);
    } else if (strcmp("ciInstanceKlass", cmd) == 0) {
      process_ciInstanceKlass(CHECK);
    } else if (strcmp("instanceKlass", cmd) == 0) {
      process_instanceKlass(CHECK);
#if INCLUDE_JVMTI
    } else if (strcmp("JvmtiExport", cmd) == 0) {
      process_JvmtiExport(CHECK);
#endif // INCLUDE_JVMTI
    } else {
      report_error("unknown command");
    }
  }
  bool is_valid_comp_level(int comp_level) {
    const int msg_len = 256;
    char* msg = NULL;
    if (!is_compile(comp_level)) {
      msg = NEW_RESOURCE_ARRAY(char, msg_len);
      jio_snprintf(msg, msg_len, "%d isn't compilation level", comp_level);
    } else if (!TieredCompilation && (comp_level != CompLevel_highest_tier)) {
      msg = NEW_RESOURCE_ARRAY(char, msg_len);
      switch (comp_level) {
        case CompLevel_simple:
          jio_snprintf(msg, msg_len, "compilation level %d requires Client VM or TieredCompilation", comp_level);
          break;
        case CompLevel_full_optimization:
          jio_snprintf(msg, msg_len, "compilation level %d requires Server VM", comp_level);
          break;
        default:
          jio_snprintf(msg, msg_len, "compilation level %d requires TieredCompilation", comp_level);
      }
    }
    if (msg != NULL) {
      report_error(msg);
      return false;
    }
    return true;
  }
  void* process_inline(ciMethod* imethod, Method* m, int entry_bci, int comp_level, TRAPS) {
    _imethod    = m;
    _iklass     = imethod->holder();
    _entry_bci  = entry_bci;
    _comp_level = comp_level;
    int line_no = 1;
    int c = getc(_stream);
    while(c != EOF) {
      c = get_line(c);
      char* cmd = parse_string();
      if (cmd == NULL || strcmp("compile", cmd) != 0) {
        return NULL;
      }
      process_compile(CHECK_NULL);
      if (had_error()) {
        tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
        tty->print_cr("%s", _buffer);
        return NULL;
      }
      if (_ci_inline_records != NULL && _ci_inline_records->length() > 0) {
        return _ci_inline_records;
      }
      line_no++;
    }
    return NULL;
  }
  void process_compile(TRAPS) {
    Method* method = parse_method(CHECK);
    if (had_error()) return;
    int entry_bci = parse_int("entry_bci");
    const char* comp_level_label = "comp_level";
    int comp_level = parse_int(comp_level_label);
    if (had_error() && (error_message() == comp_level_label)) {
      comp_level = CompLevel_full_optimization;
    }
    if (!is_valid_comp_level(comp_level)) {
      return;
    }
    if (_imethod != NULL) {
      if (entry_bci != _entry_bci || comp_level != _comp_level) {
        return;
      }
      const char* iklass_name  = _imethod->method_holder()->name()->as_utf8();
      const char* imethod_name = _imethod->name()->as_utf8();
      const char* isignature   = _imethod->signature()->as_utf8();
      const char* klass_name   = method->method_holder()->name()->as_utf8();
      const char* method_name  = method->name()->as_utf8();
      const char* signature    = method->signature()->as_utf8();
      if (strcmp(iklass_name,  klass_name)  != 0 ||
          strcmp(imethod_name, method_name) != 0 ||
          strcmp(isignature,   signature)   != 0) {
        return;
      }
    }
    int inline_count = 0;
    if (parse_tag_and_count("inline", inline_count)) {
      _ci_inline_records = new GrowableArray<ciInlineRecord*>();
      for (int i = 0; i < inline_count; i++) {
        int depth = parse_int("inline_depth");
        int bci = parse_int("inline_bci");
        if (had_error()) {
          break;
        }
        Method* inl_method = parse_method(CHECK);
        if (had_error()) {
          break;
        }
        new_ciInlineRecord(inl_method, bci, depth);
      }
    }
    if (_imethod != NULL) {
      return; // Replay Inlining
    }
    Klass* k = method->method_holder();
    ((InstanceKlass*)k)->initialize(THREAD);
    if (HAS_PENDING_EXCEPTION) {
      oop throwable = PENDING_EXCEPTION;
      java_lang_Throwable::print(throwable, tty);
      tty->cr();
      if (ReplayIgnoreInitErrors) {
        CLEAR_PENDING_EXCEPTION;
        ((InstanceKlass*)k)->set_init_state(InstanceKlass::fully_initialized);
      } else {
        return;
      }
    }
    nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code();
    if (nm != NULL) {
      nm->make_not_entrant();
    }
    replay_state = this;
    CompileBroker::compile_method(method, entry_bci, comp_level,
                                  methodHandle(), 0, "replay", THREAD);
    replay_state = NULL;
    reset();
  }
  void process_ciMethod(TRAPS) {
    Method* method = parse_method(CHECK);
    if (had_error()) return;
    ciMethodRecord* rec = new_ciMethod(method);
    rec->_invocation_counter = parse_int("invocation_counter");
    rec->_backedge_counter = parse_int("backedge_counter");
    rec->_interpreter_invocation_count = parse_int("interpreter_invocation_count");
    rec->_interpreter_throwout_count = parse_int("interpreter_throwout_count");
    rec->_instructions_size = parse_int("instructions_size");
  }
  void process_ciMethodData(TRAPS) {
    Method* method = parse_method(CHECK);
    if (had_error()) return;
    if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
      return;
    }
    method->method_holder()->link_class(CHECK);
    {
      MutexLocker ml(MethodData_lock, THREAD);
      if (method->method_data() == NULL) {
        ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
        MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
        method->set_method_data(method_data);
      }
    }
    ciMethodDataRecord* rec = new_ciMethodData(method);
    rec->_state = parse_int("state");
    rec->_current_mileage = parse_int("current_mileage");
    rec->_orig_data = parse_data("orig", rec->_orig_data_length);
    if (rec->_orig_data == NULL) {
      return;
    }
    rec->_data = parse_intptr_data("data", rec->_data_length);
    if (rec->_data == NULL) {
      return;
    }
    if (!parse_tag_and_count("oops", rec->_oops_length)) {
      return;
    }
    rec->_oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->_oops_length);
    rec->_oops_offsets = NEW_RESOURCE_ARRAY(int, rec->_oops_length);
    for (int i = 0; i < rec->_oops_length; i++) {
      int offset = parse_int("offset");
      if (had_error()) {
        return;
      }
      Klass* k = parse_klass(CHECK);
      rec->_oops_offsets[i] = offset;
      KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler);
      ::new ((void*)kh) KlassHandle(THREAD, k);
      rec->_oops_handles[i] = (jobject)kh;
    }
  }
  void process_instanceKlass(TRAPS) {
    Klass* k = parse_klass(CHECK);
  }
  void process_ciInstanceKlass(TRAPS) {
    InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
    int is_linked = parse_int("is_linked");
    int is_initialized = parse_int("is_initialized");
    int length = parse_int("length");
    if (is_initialized) {
      k->initialize(THREAD);
      if (HAS_PENDING_EXCEPTION) {
        oop throwable = PENDING_EXCEPTION;
        java_lang_Throwable::print(throwable, tty);
        tty->cr();
        if (ReplayIgnoreInitErrors) {
          CLEAR_PENDING_EXCEPTION;
          k->set_init_state(InstanceKlass::fully_initialized);
        } else {
          return;
        }
      }
    } else if (is_linked) {
      k->link_class(CHECK);
    }
    ConstantPool* cp = k->constants();
    if (length != cp->length()) {
      report_error("constant pool length mismatch: wrong class files?");
      return;
    }
    int parsed_two_word = 0;
    for (int i = 1; i < length; i++) {
      int tag = parse_int("tag");
      if (had_error()) {
        return;
      }
      switch (cp->tag_at(i).value()) {
        case JVM_CONSTANT_UnresolvedClass: {
          if (tag == JVM_CONSTANT_Class) {
            tty->print_cr("Resolving klass %s at %d", cp->unresolved_klass_at(i)->as_utf8(), i);
            Klass* k = cp->klass_at(i, CHECK);
          }
          break;
        }
        case JVM_CONSTANT_Long:
        case JVM_CONSTANT_Double:
          parsed_two_word = i + 1;
        case JVM_CONSTANT_ClassIndex:
        case JVM_CONSTANT_StringIndex:
        case JVM_CONSTANT_String:
        case JVM_CONSTANT_UnresolvedClassInError:
        case JVM_CONSTANT_Fieldref:
        case JVM_CONSTANT_Methodref:
        case JVM_CONSTANT_InterfaceMethodref:
        case JVM_CONSTANT_NameAndType:
        case JVM_CONSTANT_Utf8:
        case JVM_CONSTANT_Integer:
        case JVM_CONSTANT_Float:
        case JVM_CONSTANT_MethodHandle:
        case JVM_CONSTANT_MethodType:
        case JVM_CONSTANT_InvokeDynamic:
          if (tag != cp->tag_at(i).value()) {
            report_error("tag mismatch: wrong class files?");
            return;
          }
          break;
        case JVM_CONSTANT_Class:
          if (tag == JVM_CONSTANT_Class) {
          } else if (tag == JVM_CONSTANT_UnresolvedClass) {
            tty->print_cr("Warning: entry was unresolved in the replay data");
          } else {
            report_error("Unexpected tag");
            return;
          }
          break;
        case 0:
          if (parsed_two_word == i) continue;
        default:
          fatal(err_msg_res("Unexpected tag: %d", cp->tag_at(i).value()));
          break;
      }
    }
  }
  void process_staticfield(TRAPS) {
    InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
    if (ReplaySuppressInitializers == 0 ||
        ReplaySuppressInitializers == 2 && k->class_loader() == NULL) {
      return;
    }
    assert(k->is_initialized(), "must be");
    const char* field_name = parse_escaped_string();;
    const char* field_signature = parse_string();
    fieldDescriptor fd;
    Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK);
    Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
    if (!k->find_local_field(name, sig, &fd) ||
        !fd.is_static() ||
        fd.has_initial_value()) {
      report_error(field_name);
      return;
    }
    oop java_mirror = k->java_mirror();
    if (field_signature[0] == '[') {
      int length = parse_int("array length");
      oop value = NULL;
      if (field_signature[1] == '[') {
        ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
        int rank = 0;
        while (field_signature[rank] == '[') {
          rank++;
        }
        int* dims = NEW_RESOURCE_ARRAY(int, rank);
        dims[0] = length;
        for (int i = 1; i < rank; i++) {
          dims[i] = 1; // These aren't relevant to the compiler
        }
        value = kelem->multi_allocate(rank, dims, CHECK);
      } else {
        if (strcmp(field_signature, "[B") == 0) {
          value = oopFactory::new_byteArray(length, CHECK);
        } else if (strcmp(field_signature, "[Z") == 0) {
          value = oopFactory::new_boolArray(length, CHECK);
        } else if (strcmp(field_signature, "[C") == 0) {
          value = oopFactory::new_charArray(length, CHECK);
        } else if (strcmp(field_signature, "[S") == 0) {
          value = oopFactory::new_shortArray(length, CHECK);
        } else if (strcmp(field_signature, "[F") == 0) {
          value = oopFactory::new_singleArray(length, CHECK);
        } else if (strcmp(field_signature, "[D") == 0) {
          value = oopFactory::new_doubleArray(length, CHECK);
        } else if (strcmp(field_signature, "[I") == 0) {
          value = oopFactory::new_intArray(length, CHECK);
        } else if (strcmp(field_signature, "[J") == 0) {
          value = oopFactory::new_longArray(length, CHECK);
        } else if (field_signature[0] == '[' && field_signature[1] == 'L') {
          KlassHandle kelem = resolve_klass(field_signature + 1, CHECK);
          value = oopFactory::new_objArray(kelem(), length, CHECK);
        } else {
          report_error("unhandled array staticfield");
        }
      }
      java_mirror->obj_field_put(fd.offset(), value);
    } else {
      const char* string_value = parse_escaped_string();
      if (strcmp(field_signature, "I") == 0) {
        int value = atoi(string_value);
        java_mirror->int_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "B") == 0) {
        int value = atoi(string_value);
        java_mirror->byte_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "C") == 0) {
        int value = atoi(string_value);
        java_mirror->char_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "S") == 0) {
        int value = atoi(string_value);
        java_mirror->short_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "Z") == 0) {
        int value = atol(string_value);
        java_mirror->bool_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "J") == 0) {
        jlong value;
        if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
          fprintf(stderr, "Error parsing long: %s\n", string_value);
          return;
        }
        java_mirror->long_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "F") == 0) {
        float value = atof(string_value);
        java_mirror->float_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "D") == 0) {
        double value = atof(string_value);
        java_mirror->double_field_put(fd.offset(), value);
      } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
        Handle value = java_lang_String::create_from_str(string_value, CHECK);
        java_mirror->obj_field_put(fd.offset(), value());
      } else if (field_signature[0] == 'L') {
        Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
        KlassHandle kelem = resolve_klass(field_signature, CHECK);
        oop value = ((InstanceKlass*)kelem())->allocate_instance(CHECK);
        java_mirror->obj_field_put(fd.offset(), value);
      } else {
        report_error("unhandled staticfield");
      }
    }
  }
#if INCLUDE_JVMTI
  void process_JvmtiExport(TRAPS) {
    const char* field = parse_string();
    bool value = parse_int("JvmtiExport flag") != 0;
    if (strcmp(field, "can_access_local_variables") == 0) {
      JvmtiExport::set_can_access_local_variables(value);
    } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
      JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
    } else if (strcmp(field, "can_post_on_exceptions") == 0) {
      JvmtiExport::set_can_post_on_exceptions(value);
    } else {
      report_error("Unrecognized JvmtiExport directive");
    }
  }
#endif // INCLUDE_JVMTI
  ciMethodRecord* new_ciMethod(Method* method) {
    ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord);
    rec->_klass_name =  method->method_holder()->name()->as_utf8();
    rec->_method_name = method->name()->as_utf8();
    rec->_signature = method->signature()->as_utf8();
    _ci_method_records.append(rec);
    return rec;
  }
  ciMethodRecord* find_ciMethodRecord(Method* method) {
    const char* klass_name =  method->method_holder()->name()->as_utf8();
    const char* method_name = method->name()->as_utf8();
    const char* signature = method->signature()->as_utf8();
    for (int i = 0; i < _ci_method_records.length(); i++) {
      ciMethodRecord* rec = _ci_method_records.at(i);
      if (strcmp(rec->_klass_name, klass_name) == 0 &&
          strcmp(rec->_method_name, method_name) == 0 &&
          strcmp(rec->_signature, signature) == 0) {
        return rec;
      }
    }
    return NULL;
  }
  ciMethodDataRecord* new_ciMethodData(Method* method) {
    ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord);
    rec->_klass_name =  method->method_holder()->name()->as_utf8();
    rec->_method_name = method->name()->as_utf8();
    rec->_signature = method->signature()->as_utf8();
    _ci_method_data_records.append(rec);
    return rec;
  }
  ciMethodDataRecord* find_ciMethodDataRecord(Method* method) {
    const char* klass_name =  method->method_holder()->name()->as_utf8();
    const char* method_name = method->name()->as_utf8();
    const char* signature = method->signature()->as_utf8();
    for (int i = 0; i < _ci_method_data_records.length(); i++) {
      ciMethodDataRecord* rec = _ci_method_data_records.at(i);
      if (strcmp(rec->_klass_name, klass_name) == 0 &&
          strcmp(rec->_method_name, method_name) == 0 &&
          strcmp(rec->_signature, signature) == 0) {
        return rec;
      }
    }
    return NULL;
  }
  ciInlineRecord* new_ciInlineRecord(Method* method, int bci, int depth) {
    ciInlineRecord* rec = NEW_RESOURCE_OBJ(ciInlineRecord);
    rec->_klass_name =  method->method_holder()->name()->as_utf8();
    rec->_method_name = method->name()->as_utf8();
    rec->_signature = method->signature()->as_utf8();
    rec->_inline_bci = bci;
    rec->_inline_depth = depth;
    _ci_inline_records->append(rec);
    return rec;
  }
  ciInlineRecord* find_ciInlineRecord(Method* method, int bci, int depth) {
    if (_ci_inline_records != NULL) {
      return find_ciInlineRecord(_ci_inline_records, method, bci, depth);
    }
    return NULL;
  }
  static ciInlineRecord* find_ciInlineRecord(GrowableArray<ciInlineRecord*>*  records,
                                      Method* method, int bci, int depth) {
    if (records != NULL) {
      const char* klass_name  = method->method_holder()->name()->as_utf8();
      const char* method_name = method->name()->as_utf8();
      const char* signature   = method->signature()->as_utf8();
      for (int i = 0; i < records->length(); i++) {
        ciInlineRecord* rec = records->at(i);
        if ((rec->_inline_bci == bci) &&
            (rec->_inline_depth == depth) &&
            (strcmp(rec->_klass_name, klass_name) == 0) &&
            (strcmp(rec->_method_name, method_name) == 0) &&
            (strcmp(rec->_signature, signature) == 0)) {
          return rec;
        }
      }
    }
    return NULL;
  }
  const char* error_message() {
    return _error_message;
  }
  void reset() {
    _error_message = NULL;
    _ci_method_records.clear();
    _ci_method_data_records.clear();
  }
  static void unescape_string(char* value) {
    char* from = value;
    char* to = value;
    while (*from != '\0') {
      if (*from != '\\') {
      } else {
        switch (from[1]) {
          case 'u': {
            from += 2;
            jchar value=0;
            for (int i=0; i<4; i++) {
              char c = *from++;
              switch (c) {
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                  value = (value << 4) + c - '0';
                  break;
                case 'a': case 'b': case 'c':
                case 'd': case 'e': case 'f':
                  value = (value << 4) + 10 + c - 'a';
                  break;
                case 'A': case 'B': case 'C':
                case 'D': case 'E': case 'F':
                  value = (value << 4) + 10 + c - 'A';
                  break;
                default:
                  ShouldNotReachHere();
              }
            }
            UNICODE::convert_to_utf8(&value, 1, to);
            to++;
            break;
          }
          case 't': *to++ = '\t'; from += 2; break;
          case 'n': *to++ = '\n'; from += 2; break;
          case 'r': *to++ = '\r'; from += 2; break;
          case 'f': *to++ = '\f'; from += 2; break;
          default:
            ShouldNotReachHere();
        }
      }
    }
  }
};
void ciReplay::replay(TRAPS) {
  int exit_code = replay_impl(THREAD);
  Threads::destroy_vm();
  vm_exit(exit_code);
}
void* ciReplay::load_inline_data(ciMethod* method, int entry_bci, int comp_level) {
  if (FLAG_IS_DEFAULT(InlineDataFile)) {
    tty->print_cr("ERROR: no inline replay data file specified (use -XX:InlineDataFile=inline_pid12345.txt).");
    return NULL;
  }
  VM_ENTRY_MARK;
  CompileReplay rp(InlineDataFile, THREAD);
  if (!rp.can_replay()) {
    tty->print_cr("ciReplay: !rp.can_replay()");
    return NULL;
  }
  void* data = rp.process_inline(method, method->get_Method(), entry_bci, comp_level, THREAD);
  if (HAS_PENDING_EXCEPTION) {
    oop throwable = PENDING_EXCEPTION;
    CLEAR_PENDING_EXCEPTION;
    java_lang_Throwable::print(throwable, tty);
    tty->cr();
    java_lang_Throwable::print_stack_trace(throwable, tty);
    tty->cr();
    return NULL;
  }
  if (rp.had_error()) {
    tty->print_cr("ciReplay: Failed on %s", rp.error_message());
    return NULL;
  }
  return data;
}
int ciReplay::replay_impl(TRAPS) {
  HandleMark hm;
  ResourceMark rm;
  BackgroundCompilation = false;
  if (ReplaySuppressInitializers > 2) {
    ReplaySuppressInitializers = 1;
  }
  if (FLAG_IS_DEFAULT(ReplayDataFile)) {
    tty->print_cr("ERROR: no compiler replay data file specified (use -XX:ReplayDataFile=replay_pid12345.txt).");
    return 1;
  }
  CompileReplay rp(ReplayDataFile, THREAD);
  int exit_code = 0;
  if (rp.can_replay()) {
    rp.process(THREAD);
  } else {
    exit_code = 1;
    return exit_code;
  }
  if (HAS_PENDING_EXCEPTION) {
    oop throwable = PENDING_EXCEPTION;
    CLEAR_PENDING_EXCEPTION;
    java_lang_Throwable::print(throwable, tty);
    tty->cr();
    java_lang_Throwable::print_stack_trace(throwable, tty);
    tty->cr();
    exit_code = 2;
  }
  if (rp.had_error()) {
    tty->print_cr("Failed on %s", rp.error_message());
    exit_code = 1;
  }
  return exit_code;
}
void ciReplay::initialize(ciMethodData* m) {
  if (replay_state == NULL) {
    return;
  }
  ASSERT_IN_VM;
  ResourceMark rm;
  Method* method = m->get_MethodData()->method();
  ciMethodDataRecord* rec = replay_state->find_ciMethodDataRecord(method);
  if (rec == NULL) {
    tty->print_cr("Warning: requesting ciMethodData record for method with no data: ");
    method->print_name(tty);
    tty->cr();
  } else {
    m->_state = rec->_state;
    m->_current_mileage = rec->_current_mileage;
    if (rec->_data_length != 0) {
      assert(m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree");
      ciEnv* env = ciEnv::current();
      for (int i = 0; i < rec->_oops_length; i++) {
        KlassHandle *h = (KlassHandle *)rec->_oops_handles[i];
          env->get_metadata((*h)());
      }
#ifdef _LP64
      Copy::conjoint_jlongs_atomic((jlong *)rec->_data, (jlong *)m->_data, rec->_data_length);
#else
      Copy::conjoint_jints_atomic((jint *)rec->_data, (jint *)m->_data, rec->_data_length);
#endif
    }
    Copy::conjoint_jbytes(rec->_orig_data, (char*)&m->_orig, rec->_orig_data_length);
  }
}
bool ciReplay::should_not_inline(ciMethod* method) {
  if (replay_state == NULL) {
    return false;
  }
  VM_ENTRY_MARK;
  return replay_state->find_ciMethodRecord(method->get_Method()) == NULL;
}
bool ciReplay::should_inline(void* data, ciMethod* method, int bci, int inline_depth) {
  if (data != NULL) {
    GrowableArray<ciInlineRecord*>*  records = (GrowableArray<ciInlineRecord*>*)data;
    VM_ENTRY_MARK;
    return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) != NULL;
  } else if (replay_state != NULL) {
    VM_ENTRY_MARK;
    return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) != NULL;
  }
  return false;
}
bool ciReplay::should_not_inline(void* data, ciMethod* method, int bci, int inline_depth) {
  if (data != NULL) {
    GrowableArray<ciInlineRecord*>*  records = (GrowableArray<ciInlineRecord*>*)data;
    VM_ENTRY_MARK;
    return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) == NULL;
  } else if (replay_state != NULL) {
    VM_ENTRY_MARK;
    return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) == NULL;
  }
  return false;
}
void ciReplay::initialize(ciMethod* m) {
  if (replay_state == NULL) {
    return;
  }
  ASSERT_IN_VM;
  ResourceMark rm;
  Method* method = m->get_Method();
  ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
  if (rec == NULL) {
    tty->print_cr("Warning: requesting ciMethod record for method with no data: ");
    method->print_name(tty);
    tty->cr();
  } else {
    EXCEPTION_CONTEXT;
    m->_instructions_size = -1;
    m->_interpreter_invocation_count = rec->_interpreter_invocation_count;
    m->_interpreter_throwout_count = rec->_interpreter_throwout_count;
    MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR);
    guarantee(mcs != NULL, "method counters allocation failed");
    mcs->invocation_counter()->_counter = rec->_invocation_counter;
    mcs->backedge_counter()->_counter = rec->_backedge_counter;
  }
}
bool ciReplay::is_loaded(Method* method) {
  if (replay_state == NULL) {
    return true;
  }
  ASSERT_IN_VM;
  ResourceMark rm;
  ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
  return rec != NULL;
}
#endif // PRODUCT
C:\hotspot-69087d08d473\src\share\vm/ci/ciReplay.hpp
#ifndef SHARE_VM_CI_CIREPLAY_HPP
#define SHARE_VM_CI_CIREPLAY_HPP
#include "ci/ciMethod.hpp"
class ciReplay {
  CI_PACKAGE_ACCESS
#ifndef PRODUCT
 private:
  static int replay_impl(TRAPS);
 public:
  static void replay(TRAPS);
  static void* load_inline_data(ciMethod* method, int entry_bci, int comp_level);
  static void initialize(ciMethodData* method);
  static void initialize(ciMethod* method);
  static bool is_loaded(Method* method);
  static bool is_loaded(Klass* klass);
  static bool should_not_inline(ciMethod* method);
  static bool should_inline(void* data, ciMethod* method, int bci, int inline_depth);
  static bool should_not_inline(void* data, ciMethod* method, int bci, int inline_depth);
#endif
};
#endif // SHARE_VM_CI_CIREPLAY_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciSignature.cpp
#include "precompiled.hpp"
#include "ci/ciMethodType.hpp"
#include "ci/ciSignature.hpp"
#include "ci/ciUtilities.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/signature.hpp"
ciSignature::ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* symbol) {
  ASSERT_IN_VM;
  EXCEPTION_CONTEXT;
  _accessing_klass = accessing_klass;
  _symbol = symbol;
  ciEnv* env = CURRENT_ENV;
  Arena* arena = env->arena();
  _types = new (arena) GrowableArray<ciType*>(arena, 8, 0, NULL);
  int size = 0;
  int count = 0;
  ResourceMark rm(THREAD);
  Symbol* sh = symbol->get_symbol();
  SignatureStream ss(sh);
  for (; ; ss.next()) {
    ciType* type;
    if (!ss.is_object()) {
      type = ciType::make(ss.type());
    } else {
      Symbol* name = ss.as_symbol(THREAD);
      if (HAS_PENDING_EXCEPTION) {
        type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass()
          : (ciType*)ciEnv::unloaded_ciinstance_klass();
        env->record_out_of_memory_failure();
        CLEAR_PENDING_EXCEPTION;
      } else {
        ciSymbol* klass_name = env->get_symbol(name);
        type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
      }
    }
    _types->append(type);
    if (ss.at_return_type()) {
      break;
    }
    size += type->size();
    count++;
  }
  _size = size;
  _count = count;
}
ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol, ciMethodType* method_type) :
  _symbol(symbol),
  _accessing_klass(accessing_klass),
  _size( method_type->ptype_slot_count()),
  _count(method_type->ptype_count())
{
  ASSERT_IN_VM;
  EXCEPTION_CONTEXT;
  Arena* arena = CURRENT_ENV->arena();
  _types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
  for (int i = 0; i < _count; i++) {
    _types->append(method_type->ptype_at(i));
  }
  _types->append(method_type->rtype());
}
ciType* ciSignature::return_type() const {
  return _types->at(_count);
}
ciType* ciSignature::type_at(int index) const {
  assert(index < _count, "out of bounds");
  return _types->at(index);
}
bool ciSignature::equals(ciSignature* that) {
  if (!this->as_symbol()->equals(that->as_symbol()))  return false;
  for (int i = 0; i < _count; i++) {
    if (this->type_at(i) != that->type_at(i))         return false;
  }
  if (this->return_type() != that->return_type())     return false;
  return true;
}
void ciSignature::print_signature() {
  _symbol->print_symbol();
}
void ciSignature::print() {
  tty->print("<ciSignature symbol=");
  print_signature();
 tty->print(" accessing_klass=");
  _accessing_klass->print();
  tty->print(" address=" INTPTR_FORMAT ">", p2i((address)this));
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciSignature.hpp
#ifndef SHARE_VM_CI_CISIGNATURE_HPP
#define SHARE_VM_CI_CISIGNATURE_HPP
#include "ci/ciClassList.hpp"
#include "ci/ciSymbol.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
class ciSignature : public ResourceObj {
private:
  ciSymbol* _symbol;
  ciKlass*  _accessing_klass;
  GrowableArray<ciType*>* _types;
  int _size;   // number of stack slots required for arguments
  int _count;  // number of parameter types in the signature
  friend class ciMethod;
  friend class ciBytecodeStream;
  friend class ciObjectFactory;
  ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
  ciSignature(ciKlass* accessing_klass,                           ciSymbol* signature, ciMethodType* method_type);
  void get_all_klasses();
  Symbol* get_symbol() const                     { return _symbol->get_symbol(); }
public:
  ciSymbol* as_symbol() const                    { return _symbol; }
  ciKlass*  accessing_klass() const              { return _accessing_klass; }
  ciType*   return_type() const;
  ciType*   type_at(int index) const;
  int       size() const                         { return _size; }
  int       count() const                        { return _count; }
  int       arg_size_for_bc(Bytecodes::Code bc)  { return size() + (Bytecodes::has_receiver(bc) ? 1 : 0); }
  bool equals(ciSignature* that);
  void print_signature();
  void print();
};
#endif // SHARE_VM_CI_CISIGNATURE_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciStreams.cpp
#include "precompiled.hpp"
#include "ci/ciCallSite.hpp"
#include "ci/ciConstant.hpp"
#include "ci/ciField.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciUtilities.hpp"
int ciExceptionHandlerStream::count() {
  int save_pos = _pos;
  int save_end = _end;
  int count = 0;
  _pos = -1;
  _end = _method->_handler_count;
  next();
  while (!is_done()) {
    count++;
    next();
  }
  _pos = save_pos;
  _end = save_end;
  return count;
}
int ciExceptionHandlerStream::count_remaining() {
  int save_pos = _pos;
  int save_end = _end;
  int count = 0;
  while (!is_done()) {
    count++;
    next();
  }
  _pos = save_pos;
  _end = save_end;
  return count;
}
Bytecodes::Code ciBytecodeStream::next_wide_or_table(Bytecodes::Code bc) {
  switch (bc) {                // Check for special bytecode handling
  case Bytecodes::_wide:
    assert(Bytecodes::Code(_pc[0]) == Bytecodes::_wide, "");
    bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)_pc[1]);
    assert(Bytecodes::wide_length_for(bc) > 2, "must make progress");
    _pc += Bytecodes::wide_length_for(bc);
    _was_wide = _pc;              // Flag last wide bytecode found
    assert(is_wide(), "accessor works right");
    break;
  case Bytecodes::_lookupswitch:
    _pc++;                      // Skip wide bytecode
    _pc += (_start-_pc)&3;      // Word align
    _table_base = (jint*)_pc;   // Capture for later usage
    _pc = (address)&_table_base[2+ 2*Bytes::get_Java_u4((address)&_table_base[1])];
    break;
  case Bytecodes::_tableswitch: {
    _pc++;                      // Skip wide bytecode
    _pc += (_start-_pc)&3;      // Word align
    _table_base = (jint*)_pc;   // Capture for later usage
    int lo = Bytes::get_Java_u4((address)&_table_base[1]);// Low bound
    int hi = Bytes::get_Java_u4((address)&_table_base[2]);// High bound
    int len = hi - lo + 1;      // Dense table size
    _pc = (address)&_table_base[3+len]; // Skip past table
    break;
  }
  default:
    fatal("unhandled bytecode");
  }
  return bc;
}
void ciBytecodeStream::reset_to_bci( int bci ) {
  _bc_start=_was_wide=0;
  _pc = _start+bci;
}
void ciBytecodeStream::force_bci(int bci) {
  if (bci < 0) {
    reset_to_bci(0);
    _bc_start = _start + bci;
    _bc = EOBC();
  } else {
    reset_to_bci(bci);
    next();
  }
}
int ciBytecodeStream::get_klass_index() const {
  switch(cur_bc()) {
  case Bytecodes::_ldc:
    return get_index_u1();
  case Bytecodes::_ldc_w:
  case Bytecodes::_ldc2_w:
  case Bytecodes::_checkcast:
  case Bytecodes::_instanceof:
  case Bytecodes::_anewarray:
  case Bytecodes::_multianewarray:
  case Bytecodes::_new:
  case Bytecodes::_newarray:
    return get_index_u2();
  default:
    ShouldNotReachHere();
    return 0;
  }
}
ciKlass* ciBytecodeStream::get_klass(bool& will_link) {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(_method->get_Method()->constants());
  return CURRENT_ENV->get_klass_by_index(cpool, get_klass_index(), will_link, _holder);
}
int ciBytecodeStream::get_constant_raw_index() const {
  switch (cur_bc()) {
  case Bytecodes::_ldc:
    return get_index_u1();
  case Bytecodes::_ldc_w:
  case Bytecodes::_ldc2_w:
    return get_index_u2();
  default:
    ShouldNotReachHere();
    return 0;
  }
}
int ciBytecodeStream::get_constant_pool_index() const {
  int index = get_constant_raw_index();
  if (has_cache_index()) {
    VM_ENTRY_MARK;
    constantPoolHandle cpool(_method->get_Method()->constants());
    return cpool->object_to_cp_index(index);
  }
  return index;
}
int ciBytecodeStream::get_constant_cache_index() const {
  return has_cache_index() ? get_constant_raw_index() : -1;
}
ciConstant ciBytecodeStream::get_constant() {
  int pool_index = get_constant_raw_index();
  int cache_index = -1;
  if (has_cache_index()) {
    cache_index = pool_index;
    pool_index = -1;
  }
  VM_ENTRY_MARK;
  constantPoolHandle cpool(_method->get_Method()->constants());
  return CURRENT_ENV->get_constant_by_index(cpool, pool_index, cache_index, _holder);
}
constantTag ciBytecodeStream::get_constant_pool_tag(int index) const {
  VM_ENTRY_MARK;
  return _method->get_Method()->constants()->tag_at(index);
}
int ciBytecodeStream::get_field_index() {
  assert(cur_bc() == Bytecodes::_getfield ||
         cur_bc() == Bytecodes::_putfield ||
         cur_bc() == Bytecodes::_getstatic ||
         cur_bc() == Bytecodes::_putstatic, "wrong bc");
  return get_index_u2_cpcache();
}
ciField* ciBytecodeStream::get_field(bool& will_link) {
  ciField* f = CURRENT_ENV->get_field_by_index(_holder, get_field_index());
  will_link = f->will_link(_holder, _bc);
  return f;
}
ciInstanceKlass* ciBytecodeStream::get_declared_field_holder() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(_method->get_Method()->constants());
  int holder_index = get_field_holder_index();
  bool ignore;
  return CURRENT_ENV->get_klass_by_index(cpool, holder_index, ignore, _holder)
      ->as_instance_klass();
}
int ciBytecodeStream::get_field_holder_index() {
  GUARDED_VM_ENTRY(
    ConstantPool* cpool = _holder->get_instanceKlass()->constants();
    return cpool->klass_ref_index_at(get_field_index());
  )
}
int ciBytecodeStream::get_field_signature_index() {
  VM_ENTRY_MARK;
  ConstantPool* cpool = _holder->get_instanceKlass()->constants();
  int nt_index = cpool->name_and_type_ref_index_at(get_field_index());
  return cpool->signature_ref_index_at(nt_index);
}
int ciBytecodeStream::get_method_index() {
#ifdef ASSERT
  switch (cur_bc()) {
  case Bytecodes::_invokeinterface:
  case Bytecodes::_invokevirtual:
  case Bytecodes::_invokespecial:
  case Bytecodes::_invokestatic:
  case Bytecodes::_invokedynamic:
    break;
  default:
    ShouldNotReachHere();
  }
#endif
  if (has_index_u4())
    return get_index_u4();  // invokedynamic
  return get_index_u2_cpcache();
}
ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_signature_result) {
  VM_ENTRY_MARK;
  ciEnv* env = CURRENT_ENV;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
  will_link = m->is_loaded();
  if (has_method_type()) {
    ciSymbol*     sig_sym     = env->get_symbol(cpool->symbol_at(get_method_signature_index(cpool)));
    ciKlass*      pool_holder = env->get_klass(cpool->pool_holder());
    ciMethodType* method_type = get_method_type();
    ciSignature* declared_signature = new (env->arena()) ciSignature(pool_holder, sig_sym, method_type);
    (*declared_signature_result) = declared_signature;
  } else {
    (*declared_signature_result) = m->signature();
  }
  return m;
}
bool ciBytecodeStream::has_appendix() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(_method->get_Method()->constants());
  return ConstantPool::has_appendix_at_if_loaded(cpool, get_method_index());
}
ciObject* ciBytecodeStream::get_appendix() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(_method->get_Method()->constants());
  oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, get_method_index());
  return CURRENT_ENV->get_object(appendix_oop);
}
bool ciBytecodeStream::has_method_type() {
  GUARDED_VM_ENTRY(
    constantPoolHandle cpool(_method->get_Method()->constants());
    return ConstantPool::has_method_type_at_if_loaded(cpool, get_method_index());
  )
}
ciMethodType* ciBytecodeStream::get_method_type() {
  GUARDED_VM_ENTRY(
    constantPoolHandle cpool(_method->get_Method()->constants());
    oop method_type_oop = ConstantPool::method_type_at_if_loaded(cpool, get_method_index());
    return CURRENT_ENV->get_object(method_type_oop)->as_method_type();
  )
}
ciKlass* ciBytecodeStream::get_declared_method_holder() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(_method->get_Method()->constants());
  bool ignore;
  if (cur_bc() == Bytecodes::_invokedynamic)
    return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_lang_invoke_MethodHandle(), false);
  return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
}
int ciBytecodeStream::get_method_holder_index() {
  ConstantPool* cpool = _method->get_Method()->constants();
  return cpool->klass_ref_index_at(get_method_index());
}
int ciBytecodeStream::get_method_signature_index(const constantPoolHandle& cpool) {
  GUARDED_VM_ENTRY(
    const int method_index = get_method_index();
    const int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
    return cpool->signature_ref_index_at(name_and_type_index);
  )
}
ciObjArray* ciBytecodeStream::get_resolved_references() {
    VM_ENTRY_MARK;
  ConstantPool*        cpool   = _holder->get_instanceKlass()->constants();
  return CURRENT_ENV->get_object(cpool->resolved_references())->as_obj_array();
  }
C:\hotspot-69087d08d473\src\share\vm/ci/ciStreams.hpp
#ifndef SHARE_VM_CI_CISTREAMS_HPP
#define SHARE_VM_CI_CISTREAMS_HPP
#include "ci/ciClassList.hpp"
#include "ci/ciExceptionHandler.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMethod.hpp"
#include "interpreter/bytecode.hpp"
class ciBytecodeStream : StackObj {
private:
  Bytecodes::Code next_wide_or_table(Bytecodes::Code); // Handle _wide & complicated inline table
  static Bytecodes::Code check_java(Bytecodes::Code c) {
    assert(Bytecodes::is_java_code(c), "should not return _fast bytecodes");
    return c;
  }
  static Bytecodes::Code check_defined(Bytecodes::Code c) {
    assert(Bytecodes::is_defined(c), "");
    return c;
  }
  ciMethod* _method;           // the method
  ciInstanceKlass* _holder;
  address _bc_start;            // Start of current bytecode for table
  address _was_wide;            // Address past last wide bytecode
  jint* _table_base;            // Aligned start of last table or switch
  address _start;                  // Start of bytecodes
  address _end;                    // Past end of bytecodes
  address _pc;                     // Current PC
  Bytecodes::Code _bc;             // Current bytecode
  Bytecodes::Code _raw_bc;         // Current bytecode, raw form
  void reset( address base, unsigned int size ) {
    _bc_start =_was_wide = 0;
    _start = _pc = base; _end = base + size;
  }
  void assert_wide(bool require_wide) const {
    if (require_wide)
         { assert(is_wide(),  "must be a wide instruction"); }
    else { assert(!is_wide(), "must not be a wide instruction"); }
  }
  Bytecode bytecode() const { return Bytecode(this, _bc_start); }
  Bytecode next_bytecode() const { return Bytecode(this, _pc); }
public:
  static Bytecodes::Code EOBC() {
    return Bytecodes::_illegal;
  }
  ciBytecodeStream(ciMethod* m) {
    reset_to_method(m);
  }
  ciBytecodeStream() {
    reset_to_method(NULL);
  }
  ciMethod* method() const { return _method; }
  void reset_to_method(ciMethod* m) {
    _method = m;
    if (m == NULL) {
      _holder = NULL;
      reset(NULL, 0);
    } else {
      _holder = m->holder();
      reset(m->code(), m->code_size());
    }
  }
  void reset_to_bci( int bci );
  void force_bci(int bci);
  void set_max_bci( int max ) {
    _end = _start + max;
  }
  address cur_bcp() const       { return _bc_start; }  // Returns bcp to current instruction
  int next_bci() const          { return _pc - _start; }
  int cur_bci() const           { return _bc_start - _start; }
  int instruction_size() const  { return _pc - _bc_start; }
  Bytecodes::Code cur_bc() const{ return check_java(_bc); }
  Bytecodes::Code cur_bc_raw() const { return check_defined(_raw_bc); }
  Bytecodes::Code next_bc()     { return Bytecodes::java_code((Bytecodes::Code)* _pc); }
  Bytecodes::Code next() {
    _bc_start = _pc;                        // Capture start of bc
    if( _pc >= _end ) return EOBC();        // End-Of-Bytecodes
    _bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)*_pc);
    int csize = Bytecodes::length_for(_bc); // Expected size
    _pc += csize;                           // Bump PC past bytecode
    if (csize == 0) {
      _bc = next_wide_or_table(_bc);
    }
    return check_java(_bc);
  }
  bool is_wide() const { return ( _pc == _was_wide ); }
  bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
  bool has_optional_appendix() { return Bytecodes::has_optional_appendix(cur_bc_raw()); }
  int get_index_u1() const {
    return bytecode().get_index_u1(cur_bc_raw());
  }
  int get_index_u1_cpcache() const {
    return bytecode().get_index_u1_cpcache(cur_bc_raw());
  }
  int get_index() const {
    assert(!has_cache_index(), "else use cpcache variant");
    return (_pc == _was_wide)   // was widened?
      ? get_index_u2(true)      // yes, return wide index
      : get_index_u1();         // no, return narrow index
  }
  int get_index_u2(bool is_wide = false) const {
    return bytecode().get_index_u2(cur_bc_raw(), is_wide);
  }
  int get_index_u2_cpcache() const {
    return bytecode().get_index_u2_cpcache(cur_bc_raw());
  }
  int get_index_u4() const {
    return bytecode().get_index_u4(cur_bc_raw());
  }
  bool has_index_u4() const {
    return bytecode().has_index_u4(cur_bc_raw());
  }
  int get_dimensions() const { return *(unsigned char*)(_pc-1); }
  int get_constant_u1()                     const { return bytecode().get_constant_u1(instruction_size()-1, cur_bc_raw()); }
  int get_constant_u2(bool is_wide = false) const { return bytecode().get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); }
  int get_iinc_con() const {return (_pc==_was_wide) ? (jshort) get_constant_u2(true) : (jbyte) get_constant_u1();}
  int get_dest() const {
    return cur_bci() + bytecode().get_offset_s2(cur_bc_raw());
  }
  int next_get_dest() const {
    assert(_pc < _end, "");
    return next_bci() + next_bytecode().get_offset_s2(Bytecodes::_ifeq);
  }
  int get_far_dest() const {
    return cur_bci() + bytecode().get_offset_s4(cur_bc_raw());
  }
  int get_int_table( int index ) const {
    return Bytes::get_Java_u4((address)&_table_base[index]); }
  int get_tableswitch_length()  { return get_int_table(2)-get_int_table(1)+1; }
  int get_dest_table( int index ) const {
    return cur_bci() + get_int_table(index); }
  int get_constant_raw_index() const;
  int get_constant_pool_index() const;
  int get_constant_cache_index() const;
  int get_field_index();
  int get_method_index();
  ciKlass* get_klass(bool& will_link);
  int get_klass_index() const;
  ciConstant get_constant();
  constantTag get_constant_pool_tag(int index) const;
  bool is_unresolved_klass() const {
    constantTag tag = get_constant_pool_tag(get_klass_index());
    return tag.is_unresolved_klass();
  }
  ciField* get_field(bool& will_link);
  ciInstanceKlass* get_declared_field_holder();
  int      get_field_holder_index();
  int      get_field_signature_index();
  ciMethod*     get_method(bool& will_link, ciSignature* *declared_signature_result);
  bool          has_appendix();
  ciObject*     get_appendix();
  bool          has_method_type();
  ciMethodType* get_method_type();
  ciKlass*      get_declared_method_holder();
  int           get_method_holder_index();
  int           get_method_signature_index(const constantPoolHandle& cpool);
  ciObjArray* get_resolved_references();
};
class ciSignatureStream : public StackObj {
private:
  ciSignature* _sig;
  int          _pos;
  ciKlass*     _holder;
public:
  ciSignatureStream(ciSignature* signature, ciKlass* holder = NULL) {
    _sig = signature;
    _pos = 0;
    _holder = holder;
  }
  bool at_return_type() { return _pos == _sig->count(); }
  bool is_done() { return _pos > _sig->count(); }
  void next() {
    if (_pos <= _sig->count()) {
      _pos++;
    }
  }
  ciType* type() {
    if (at_return_type()) {
      return _sig->return_type();
    } else {
      return _sig->type_at(_pos);
    }
  }
  ciKlass* next_klass() {
    ciKlass* sig_k;
    if (_holder != NULL) {
      sig_k = _holder;
      _holder = NULL;
    } else {
      while (!type()->is_klass()) {
        next();
      }
      assert(!at_return_type(), "passed end of signature");
      sig_k = type()->as_klass();
      next();
    }
    return sig_k;
  }
};
class ciExceptionHandlerStream : public StackObj {
private:
  ciMethod* _method;
  int        _pos;
  int        _end;
  ciInstanceKlass*  _exception_klass;
  int        _bci;
  bool       _is_exact;
public:
  ciExceptionHandlerStream(ciMethod* method) {
    _method = method;
    _method->code();
    _pos = 0;
    _end = _method->_handler_count;
    _exception_klass = NULL;
    _bci    = -1;
    _is_exact = false;
  }
  ciExceptionHandlerStream(ciMethod* method, int bci,
                           ciInstanceKlass* exception_klass = NULL,
                           bool is_exact = false) {
    _method = method;
    _method->code();
    _pos = -1;
    _end = _method->_handler_count + 1; // include the rethrow handler
    _exception_klass = (exception_klass != NULL && exception_klass->is_loaded()
                          ? exception_klass
                          : NULL);
    _bci = bci;
    assert(_bci >= 0, "bci out of range");
    _is_exact = is_exact;
    next();
  }
  int count();
  int count_remaining();
  bool is_done() {
    return (_pos >= _end);
  }
  void next() {
    _pos++;
    if (_bci != -1) {
      while (!is_done()) {
        ciExceptionHandler* handler = _method->_exception_handlers[_pos];
        if (handler->is_in_range(_bci)) {
          if (handler->is_catch_all()) {
            _end = _pos+1;
            return;
          } else if (_exception_klass == NULL || !handler->catch_klass()->is_loaded()) {
            return;
          } else if (_exception_klass->is_subtype_of(handler->catch_klass())) {
            _end = _pos+1;
            return;
          } else if (!_is_exact &&
                     handler->catch_klass()->is_subtype_of(_exception_klass)) {
            return;
          }
        }
        _pos++;
      }
    } else {
      return;
    }
  }
  ciExceptionHandler* handler() {
    return _method->_exception_handlers[_pos];
  }
};
Bytecode::Bytecode(const ciBytecodeStream* stream, address bcp): _bcp(bcp != NULL ? bcp : stream->cur_bcp()), _code(Bytecodes::code_at(NULL, addr_at(0))) {}
Bytecode_lookupswitch::Bytecode_lookupswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); }
Bytecode_tableswitch::Bytecode_tableswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); }
#endif // SHARE_VM_CI_CISTREAMS_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciSymbol.cpp
#include "precompiled.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciUtilities.hpp"
#include "memory/oopFactory.hpp"
ciSymbol::ciSymbol(Symbol* s, vmSymbols::SID sid)
  : _symbol(s), _sid(sid)
{
  assert(_symbol != NULL, "adding null symbol");
  _symbol->increment_refcount();  // increment ref count
  assert(sid_ok(), "must be in vmSymbols");
}
ciSymbol::ciSymbol(Symbol* s)
  : _symbol(s), _sid(vmSymbols::NO_SID)
{
  assert(_symbol != NULL, "adding null symbol");
  _symbol->increment_refcount();  // increment ref count
  assert(sid_ok(), "must not be in vmSymbols");
}
const char* ciSymbol::as_utf8() {
  VM_QUICK_ENTRY_MARK;
  Symbol* s = get_symbol();
  return s->as_utf8();
}
const char* ciSymbol::as_quoted_ascii() {
  GUARDED_VM_QUICK_ENTRY(return get_symbol()->as_quoted_ascii();)
}
const jbyte* ciSymbol::base() {
  GUARDED_VM_ENTRY(return get_symbol()->base();)
}
int ciSymbol::byte_at(int i) {
  GUARDED_VM_ENTRY(return get_symbol()->byte_at(i);)
}
bool ciSymbol::starts_with(const char* prefix, int len) const {
  GUARDED_VM_ENTRY(return get_symbol()->starts_with(prefix, len);)
}
bool ciSymbol::is_signature_polymorphic_name()  const {
  GUARDED_VM_ENTRY(return MethodHandles::is_signature_polymorphic_name(get_symbol());)
}
int ciSymbol::index_of_at(int i, const char* str, int len) const {
  GUARDED_VM_ENTRY(return get_symbol()->index_of_at(i, str, len);)
}
int ciSymbol::utf8_length() {
  GUARDED_VM_ENTRY(return get_symbol()->utf8_length();)
}
void ciSymbol::print_impl(outputStream* st) {
  st->print(" value=");
  print_symbol_on(st);
}
void ciSymbol::print_symbol_on(outputStream *st) {
  GUARDED_VM_ENTRY(get_symbol()->print_symbol_on(st);)
}
ciSymbol* ciSymbol::make_impl(const char* s) {
  EXCEPTION_CONTEXT;
  TempNewSymbol sym = SymbolTable::new_symbol(s, THREAD);
  if (HAS_PENDING_EXCEPTION) {
    CLEAR_PENDING_EXCEPTION;
    CURRENT_THREAD_ENV->record_out_of_memory_failure();
    return ciEnv::_unloaded_cisymbol;
  }
  return CURRENT_THREAD_ENV->get_symbol(sym);
}
ciSymbol* ciSymbol::make(const char* s) {
  GUARDED_VM_ENTRY(return make_impl(s);)
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciSymbol.hpp
#ifndef SHARE_VM_CI_CISYMBOL_HPP
#define SHARE_VM_CI_CISYMBOL_HPP
#include "ci/ciBaseObject.hpp"
#include "ci/ciObject.hpp"
#include "ci/ciObjectFactory.hpp"
#include "classfile/vmSymbols.hpp"
#include "oops/symbol.hpp"
class ciSymbol : public ciBaseObject {
  Symbol* _symbol;
  CI_PACKAGE_ACCESS
  friend class ciEnv;
  friend class ciInstanceKlass;
  friend class ciSignature;
  friend class ciMethod;
  friend class ciField;
  friend class ciObjArrayKlass;
private:
  const vmSymbols::SID _sid;
  DEBUG_ONLY( bool sid_ok() { return vmSymbols::find_sid(get_symbol()) == _sid; } )
  ciSymbol(Symbol* s);  // normal case, for symbols not mentioned in vmSymbols
  ciSymbol(Symbol* s, vmSymbols::SID sid);   // for use with vmSymbols
  Symbol* get_symbol() const { return _symbol; }
  const char* type_string() { return "ciSymbol"; }
  void print_impl(outputStream* st);
  const jbyte* base();
  static ciSymbol* make_impl(const char* s);
public:
  vmSymbols::SID sid() const { return _sid; }
  const char* as_utf8();
  int         utf8_length();
  const char* as_quoted_ascii();
  int         byte_at(int i);
  bool starts_with(const char* prefix, int len) const;
  int index_of_at(int i, const char* str, int len) const;
  void print_symbol_on(outputStream* st);
  void print_symbol() {
    print_symbol_on(tty);
  }
  static ciSymbol* make(const char* s);
#define CI_SYMBOL_DECLARE(name, ignore_def) \
  static ciSymbol* name() { return ciObjectFactory::vm_symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(name)); }
  VM_SYMBOLS_DO(CI_SYMBOL_DECLARE, CI_SYMBOL_DECLARE)
#undef CI_SYMBOL_DECLARE
  void print() {
    _symbol->print();
  }
  virtual bool is_symbol() const       { return true; }
  bool equals(ciSymbol* obj) { return this->_symbol == obj->get_symbol(); }
  bool is_signature_polymorphic_name() const;
};
#endif // SHARE_VM_CI_CISYMBOL_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciType.cpp
#include "precompiled.hpp"
#include "ci/ciEnv.hpp"
#include "ci/ciType.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/systemDictionary.hpp"
#include "oops/oop.inline.hpp"
ciType* ciType::_basic_types[T_CONFLICT+1];
ciType::ciType(BasicType basic_type) : ciMetadata() {
  assert(basic_type >= T_BOOLEAN && basic_type <= T_CONFLICT, "range check");
  _basic_type = basic_type;
}
ciType::ciType(KlassHandle k) : ciMetadata(k()) {
  _basic_type = k()->oop_is_array() ? T_ARRAY : T_OBJECT;
}
bool ciType::is_subtype_of(ciType* type) {
  if (this == type)  return true;
  if (is_klass() && type->is_klass())
    return this->as_klass()->is_subtype_of(type->as_klass());
  return false;
}
const char* ciType::name() {
  if (is_primitive_type()) {
    return type2name(basic_type());
  } else {
    assert(is_klass(), "must be");
    return as_klass()->name()->as_utf8();
  }
}
void ciType::print_impl(outputStream* st) {
  st->print(" type=");
  print_name_on(st);
}
void ciType::print_name_on(outputStream* st) {
  ResourceMark rm;
  st->print("%s", name());
}
ciInstance* ciType::java_mirror() {
  VM_ENTRY_MARK;
  return CURRENT_THREAD_ENV->get_instance(Universe::java_mirror(basic_type()));
}
ciKlass* ciType::box_klass() {
  if (!is_primitive_type())  return this->as_klass();  // reference types are "self boxing"
  if (basic_type() == T_VOID)  return NULL;
  VM_ENTRY_MARK;
  return CURRENT_THREAD_ENV->get_instance_klass(SystemDictionary::box_klass(basic_type()));
}
ciType* ciType::make(BasicType t) {
  assert((uint)t < T_CONFLICT+1, "range check");
  if (t == T_OBJECT)  return ciEnv::_Object_klass;  // java/lang/Object
  assert(_basic_types[t] != NULL, "domain check");
  return _basic_types[t];
}
ciReturnAddress::ciReturnAddress(int bci) : ciType(T_ADDRESS) {
  assert(0 <= bci, "bci cannot be negative");
  _bci = bci;
}
void ciReturnAddress::print_impl(outputStream* st) {
  st->print(" bci=%d", _bci);
}
ciReturnAddress* ciReturnAddress::make(int bci) {
  GUARDED_VM_ENTRY(return CURRENT_ENV->get_return_address(bci);)
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciType.hpp
#ifndef SHARE_VM_CI_CITYPE_HPP
#define SHARE_VM_CI_CITYPE_HPP
#include "ci/ciMetadata.hpp"
class ciType : public ciMetadata {
  CI_PACKAGE_ACCESS
  friend class ciKlass;
  friend class ciReturnAddress;
private:
  BasicType _basic_type;
  ciType(BasicType t);     // for primitive and unloaded types
  ciType(KlassHandle k);   // for subclasses (reference types)
  const char* type_string() { return "ciType"; }
  void print_impl(outputStream* st);
  static ciType* _basic_types[T_CONFLICT+1];
public:
  BasicType basic_type() const              { return _basic_type; }
  bool is_subtype_of(ciType* type);
  virtual ciInstance*    java_mirror();
  ciKlass*  box_klass();
  bool is_primitive_type() const            { return basic_type() != T_OBJECT && basic_type() != T_ARRAY; }
  int size() const                          { return type2size[basic_type()]; }
  bool is_void() const                      { return basic_type() == T_VOID; }
  bool is_one_word() const                  { return size() == 1; }
  bool is_two_word() const                  { return size() == 2; }
  bool is_type() const                      { return true; }
  bool is_classless() const                 { return is_primitive_type(); }
  const char* name();
  virtual void print_name_on(outputStream* st);
  void print_name() {
    print_name_on(tty);
  }
  static ciType* make(BasicType t);
};
class ciReturnAddress : public ciType {
  CI_PACKAGE_ACCESS
private:
  int _bci;
  ciReturnAddress(int bci);
  const char* type_string() { return "ciReturnAddress"; }
  void print_impl(outputStream* st);
public:
  bool is_return_address() const { return true; }
  int  bci() { return _bci; }
  static ciReturnAddress* make(int bci);
};
#endif // SHARE_VM_CI_CITYPE_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciTypeArray.cpp
#include "precompiled.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciUtilities.hpp"
jchar ciTypeArray::char_at(int index) {
  VM_ENTRY_MARK;
  assert(index >= 0 && index < length(), "out of range");
  jchar c = get_typeArrayOop()->char_at(index);
#ifdef ASSERT
  jchar d = element_value(index).as_char();
  assert(c == d, "");
#endif //ASSERT
  return c;
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciTypeArray.hpp
#ifndef SHARE_VM_CI_CITYPEARRAY_HPP
#define SHARE_VM_CI_CITYPEARRAY_HPP
#include "ci/ciArray.hpp"
#include "ci/ciClassList.hpp"
#include "oops/typeArrayOop.hpp"
class ciTypeArray : public ciArray {
  CI_PACKAGE_ACCESS
protected:
  ciTypeArray(typeArrayHandle h_t) : ciArray(h_t) {}
  ciTypeArray(ciKlass* klass, int len) : ciArray(klass, len) {}
  typeArrayOop get_typeArrayOop() {
    return (typeArrayOop)get_oop();
  }
  const char* type_string() { return "ciTypeArray"; }
public:
  bool is_type_array() { return true; }
  jchar char_at(int index);
};
#endif // SHARE_VM_CI_CITYPEARRAY_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciTypeArrayKlass.cpp
#include "precompiled.hpp"
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciUtilities.hpp"
ciTypeArrayKlass::ciTypeArrayKlass(KlassHandle h_k) : ciArrayKlass(h_k) {
  assert(get_Klass()->oop_is_typeArray(), "wrong type");
  assert(element_type() == get_TypeArrayKlass()->element_type(), "");
}
ciTypeArrayKlass* ciTypeArrayKlass::make_impl(BasicType t) {
  Klass* k = Universe::typeArrayKlassObj(t);
  return CURRENT_ENV->get_type_array_klass(k);
}
ciTypeArrayKlass* ciTypeArrayKlass::make(BasicType t) {
  GUARDED_VM_ENTRY(return make_impl(t);)
}
C:\hotspot-69087d08d473\src\share\vm/ci/ciTypeArrayKlass.hpp
#ifndef SHARE_VM_CI_CITYPEARRAYKLASS_HPP
#define SHARE_VM_CI_CITYPEARRAYKLASS_HPP
#include "ci/ciArrayKlass.hpp"
class ciTypeArrayKlass : public ciArrayKlass {
  CI_PACKAGE_ACCESS
protected:
  ciTypeArrayKlass(KlassHandle h_k);
  TypeArrayKlass* get_TypeArrayKlass() {
    return (TypeArrayKlass*)get_Klass();
  }
  const char* type_string() { return "ciTypeArrayKlass"; }
  static ciTypeArrayKlass* make_impl(BasicType type);
public:
  BasicType element_type() {
    return Klass::layout_helper_element_type(layout_helper());
  }
  bool is_type_array_klass() const { return true; }
  static ciTypeArrayKlass* make(BasicType type);
  virtual ciKlass* exact_klass() {
    return this;
  }
};
#endif // SHARE_VM_CI_CITYPEARRAYKLASS_HPP
C:\hotspot-69087d08d473\src\share\vm/ci/ciTypeFlow.cpp
#include "precompiled.hpp"
#include "ci/ciConstant.hpp"
#include "ci/ciField.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciTypeArrayKlass.hpp"
#include "ci/ciTypeFlow.hpp"
#include "compiler/compileLog.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/compile.hpp"
#include "opto/node.hpp"
#include "runtime/deoptimization.hpp"
#include "utilities/growableArray.hpp"
ciTypeFlow::JsrSet::JsrSet(Arena* arena, int default_len) {
  if (arena != NULL) {
    _set = new (arena) GrowableArray<JsrRecord*>(arena, default_len, 0, NULL);
  } else {
    _set = new GrowableArray<JsrRecord*>(4, 0, NULL, false);
  }
}
void ciTypeFlow::JsrSet::copy_into(JsrSet* jsrs) {
  int len = size();
  jsrs->_set->clear();
  for (int i = 0; i < len; i++) {
    jsrs->_set->append(_set->at(i));
  }
}
bool ciTypeFlow::JsrSet::is_compatible_with(JsrSet* other) {
  int size1 = size();
  int size2 = other->size();
  if (size2 == 0) {
    return true;
  } else if (size1 != size2) {
    return false;
  } else {
    for (int i = 0; i < size1; i++) {
      JsrRecord* record1 = record_at(i);
      JsrRecord* record2 = other->record_at(i);
      if (record1->entry_address() != record2->entry_address() ||
          record1->return_address() != record2->return_address()) {
        return false;
      }
    }
    return true;
  }
#if 0
  int pos1 = 0;
  int pos2 = 0;
  int size1 = size();
  int size2 = other->size();
  while (pos1 < size1 && pos2 < size2) {
    JsrRecord* record1 = record_at(pos1);
    JsrRecord* record2 = other->record_at(pos2);
    int entry1 = record1->entry_address();
    int entry2 = record2->entry_address();
    if (entry1 < entry2) {
      pos1++;
    } else if (entry1 > entry2) {
      pos2++;
    } else {
      if (record1->return_address() == record2->return_address()) {
        pos1++;
        pos2++;
      } else {
        return false;
      }
    }
  }
  return true;
#endif
}
void ciTypeFlow::JsrSet::insert_jsr_record(JsrRecord* record) {
  int len = size();
  int entry = record->entry_address();
  int pos = 0;
  for ( ; pos < len; pos++) {
    JsrRecord* current = record_at(pos);
    if (entry == current->entry_address()) {
      _set->at_put(pos, record);
      assert(size() == len, "must be same size");
      return;
    } else if (entry < current->entry_address()) {
      break;
    }
  }
  JsrRecord* swap = record;
  JsrRecord* temp = NULL;
  for ( ; pos < len; pos++) {
    temp = _set->at(pos);
    _set->at_put(pos, swap);
    swap = temp;
  }
  _set->append(swap);
  assert(size() == len+1, "must be larger");
}
void ciTypeFlow::JsrSet::remove_jsr_record(int return_address) {
  int len = size();
  for (int i = 0; i < len; i++) {
    if (record_at(i)->return_address() == return_address) {
      for (int j = i+1; j < len ; j++) {
        _set->at_put(j-1, _set->at(j));
      }
      _set->trunc_to(len-1);
      assert(size() == len-1, "must be smaller");
      return;
    }
  }
  assert(false, "verify: returning from invalid subroutine");
}
void ciTypeFlow::JsrSet::apply_control(ciTypeFlow* analyzer,
                                       ciBytecodeStream* str,
                                       ciTypeFlow::StateVector* state) {
  Bytecodes::Code code = str->cur_bc();
  if (code == Bytecodes::_jsr) {
    JsrRecord* record =
      analyzer->make_jsr_record(str->get_dest(), str->next_bci());
    insert_jsr_record(record);
  } else if (code == Bytecodes::_jsr_w) {
    JsrRecord* record =
      analyzer->make_jsr_record(str->get_far_dest(), str->next_bci());
    insert_jsr_record(record);
  } else if (code == Bytecodes::_ret) {
    Cell local = state->local(str->get_index());
    ciType* return_address = state->type_at(local);
    assert(return_address->is_return_address(), "verify: wrong type");
    if (size() == 0) {
      analyzer->record_failure("OSR in finally clause");
      return;
    }
    remove_jsr_record(return_address->as_return_address()->bci());
  }
}
#ifndef PRODUCT
void ciTypeFlow::JsrSet::print_on(outputStream* st) const {
  st->print("{ ");
  int num_elements = size();
  if (num_elements > 0) {
    int i = 0;
    for( ; i < num_elements - 1; i++) {
      _set->at(i)->print_on(st);
      st->print(", ");
    }
    _set->at(i)->print_on(st);
    st->print(" ");
  }
  st->print("}");
}
#endif
ciType* ciTypeFlow::StateVector::type_meet_internal(ciType* t1, ciType* t2, ciTypeFlow* analyzer) {
  assert(t1 != t2, "checked in caller");
  if (t1->equals(top_type())) {
    return t2;
  } else if (t2->equals(top_type())) {
    return t1;
  } else if (t1->is_primitive_type() || t2->is_primitive_type()) {
    if (t1->equals(null_type())) {
      if (!t2->is_primitive_type() || t2->equals(null_type())) {
        return t2;
      }
    } else if (t2->equals(null_type())) {
      if (!t1->is_primitive_type()) {
        return t1;
      }
    }
    return bottom_type();
  } else {
    ciKlass* object_klass = analyzer->env()->Object_klass();
    ciKlass* k1 = t1->as_klass();
    ciKlass* k2 = t2->as_klass();
    if (k1->equals(object_klass) || k2->equals(object_klass)) {
      return object_klass;
    } else if (!k1->is_loaded() || !k2->is_loaded()) {
      return object_klass;
    } else if (k1->is_interface() != k2->is_interface()) {
      return object_klass;
    } else if (k1->is_array_klass() || k2->is_array_klass()) {
      if (k1->is_obj_array_klass() && k2->is_obj_array_klass()) {
        ciKlass* elem1 = k1->as_obj_array_klass()->element_klass();
        ciKlass* elem2 = k2->as_obj_array_klass()->element_klass();
        ciKlass* elem  = type_meet_internal(elem1, elem2, analyzer)->as_klass();
        if (elem == elem1) {
          assert(k1 == ciObjArrayKlass::make(elem), "shortcut is OK");
          return k1;
        } else if (elem == elem2) {
          assert(k2 == ciObjArrayKlass::make(elem), "shortcut is OK");
          return k2;
        } else {
          return ciObjArrayKlass::make(elem);
        }
      } else {
        return object_klass;
      }
    } else {
      assert(k1->is_instance_klass(), "previous cases handle non-instances");
      assert(k2->is_instance_klass(), "previous cases handle non-instances");
      return k1->least_common_ancestor(k2);
    }
  }
}
ciTypeFlow::StateVector::StateVector(ciTypeFlow* analyzer) {
  _outer = analyzer;
  _stack_size = -1;
  _monitor_count = -1;
  int max_cells = analyzer->max_cells();
  _types = (ciType**)analyzer->arena()->Amalloc(sizeof(ciType*) * max_cells);
  for (int i=0; i<max_cells; i++) {
    _types[i] = top_type();
  }
  _trap_bci = -1;
  _trap_index = 0;
  _def_locals.clear();
}
const ciTypeFlow::StateVector* ciTypeFlow::get_start_state() {
  StateVector* state = new StateVector(this);
  if (is_osr_flow()) {
    ciTypeFlow* non_osr_flow = method()->get_flow_analysis();
    if (non_osr_flow->failing()) {
      record_failure(non_osr_flow->failure_reason());
      return NULL;
    }
    JsrSet* jsrs = new JsrSet(NULL, 16);
    Block* non_osr_block = non_osr_flow->existing_block_at(start_bci(), jsrs);
    if (non_osr_block == NULL) {
      record_failure("cannot reach OSR point");
      return NULL;
    }
    non_osr_block->copy_state_into(state);
    int non_osr_start = non_osr_block->start();
    if (non_osr_start != start_bci()) {
      if (CITraceTypeFlow) {
        tty->print_cr(">> Interpreting pre-OSR block %d:", non_osr_start);
      }
      Block* block = block_at(non_osr_start, jsrs);
      assert(block->limit() == start_bci(), "must flow forward to start");
      flow_block(block, state, jsrs);
    }
    return state;
  }
  state->set_stack_size(-max_locals());
  if (!method()->is_static()) {
    state->push(method()->holder());
    assert(state->tos() == state->local(0), "");
  }
  for (ciSignatureStream str(method()->signature());
       !str.at_return_type();
       str.next()) {
    state->push_translate(str.type());
  }
  Cell cell = state->next_cell(state->tos());
  state->set_stack_size(0);
  int limit = state->limit_cell();
  for (; cell < limit; cell = state->next_cell(cell)) {
    state->set_type_at(cell, state->bottom_type());
  }
  state->set_monitor_count(method()->is_synchronized() ? 1 : 0);
  return state;
}
void ciTypeFlow::StateVector::copy_into(ciTypeFlow::StateVector* copy)
const {
  copy->set_stack_size(stack_size());
  copy->set_monitor_count(monitor_count());
  Cell limit = limit_cell();
  for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
    copy->set_type_at(c, type_at(c));
  }
}
bool ciTypeFlow::StateVector::meet(const ciTypeFlow::StateVector* incoming) {
  if (monitor_count() == -1) {
    set_monitor_count(incoming->monitor_count());
  }
  assert(monitor_count() == incoming->monitor_count(), "monitors must match");
  if (stack_size() == -1) {
    set_stack_size(incoming->stack_size());
    Cell limit = limit_cell();
    #ifdef ASSERT
    { for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
        assert(type_at(c) == top_type(), "");
    } }
    #endif
    for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
      set_type_at(c, incoming->type_at(c));
    }
    return true;  // it is always different the first time
  }
#ifdef ASSERT
  if (stack_size() != incoming->stack_size()) {
    _outer->method()->print_codes();
    tty->print_cr("!!!! Stack size conflict");
    tty->print_cr("Current state:");
    print_on(tty);
    tty->print_cr("Incoming state:");
    ((StateVector*)incoming)->print_on(tty);
  }
#endif
  assert(stack_size() == incoming->stack_size(), "sanity");
  bool different = false;
  Cell limit = limit_cell();
  for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
    ciType* t1 = type_at(c);
    ciType* t2 = incoming->type_at(c);
    if (!t1->equals(t2)) {
      ciType* new_type = type_meet(t1, t2);
      if (!t1->equals(new_type)) {
        set_type_at(c, new_type);
        different = true;
      }
    }
  }
  return different;
}
bool ciTypeFlow::StateVector::meet_exception(ciInstanceKlass* exc,
                                     const ciTypeFlow::StateVector* incoming) {
  if (monitor_count() == -1) {
    set_monitor_count(incoming->monitor_count());
  }
  assert(monitor_count() == incoming->monitor_count(), "monitors must match");
  if (stack_size() == -1) {
    set_stack_size(1);
  }
  assert(stack_size() ==  1, "must have one-element stack");
  bool different = false;
  Cell limit = local(_outer->max_locals()-1);
  for (Cell c = start_cell(); c <= limit; c = next_cell(c)) {
    ciType* t1 = type_at(c);
    ciType* t2 = incoming->type_at(c);
    if (!t1->equals(t2)) {
      ciType* new_type = type_meet(t1, t2);
      if (!t1->equals(new_type)) {
        set_type_at(c, new_type);
        different = true;
      }
    }
  }
  ciType* tos_type = type_at_tos();
  if (!tos_type->equals(exc)) {
    ciType* new_type = type_meet(tos_type, exc);
    if (!tos_type->equals(new_type)) {
      set_type_at_tos(new_type);
      different = true;
    }
  }
  return different;
}
void ciTypeFlow::StateVector::push_translate(ciType* type) {
  BasicType basic_type = type->basic_type();
  if (basic_type == T_BOOLEAN || basic_type == T_CHAR ||
      basic_type == T_BYTE    || basic_type == T_SHORT) {
    push_int();
  } else {
    push(type);
    if (type->is_two_word()) {
      push(half_type(type));
    }
  }
}
void ciTypeFlow::StateVector::do_aaload(ciBytecodeStream* str) {
  pop_int();
  ciObjArrayKlass* array_klass = pop_objArray();
  if (array_klass == NULL) {
    push(null_type());
    return;
  }
  if (!array_klass->is_loaded()) {
    trap(str, array_klass,
         Deoptimization::make_trap_request
         (Deoptimization::Reason_unloaded,
          Deoptimization::Action_reinterpret));
    return;
  }
  ciKlass* element_klass = array_klass->element_klass();
  if (!element_klass->is_loaded() && element_klass->is_instance_klass()) {
    Untested("unloaded array element class in ciTypeFlow");
    trap(str, element_klass,
         Deoptimization::make_trap_request
         (Deoptimization::Reason_unloaded,
          Deoptimization::Action_reinterpret));
  } else {
    push_object(element_klass);
  }
}
void ciTypeFlow::StateVector::do_checkcast(ciBytecodeStream* str) {
  bool will_link;
  ciKlass* klass = str->get_klass(will_link);
  if (!will_link) {
    pop_object();
    do_null_assert(klass);
  } else {
    pop_object();
    push_object(klass);
  }
}
void ciTypeFlow::StateVector::do_getfield(ciBytecodeStream* str) {
  pop_object();
  do_getstatic(str);
}
void ciTypeFlow::StateVector::do_getstatic(ciBytecodeStream* str) {
  bool will_link;
  ciField* field = str->get_field(will_link);
  if (!will_link) {
    trap(str, field->holder(), str->get_field_holder_index());
  } else {
    ciType* field_type = field->type();
    if (!field_type->is_loaded()) {
      do_null_assert(field_type->as_klass());
    } else {
      push_translate(field_type);
    }
  }
}
void ciTypeFlow::StateVector::do_invoke(ciBytecodeStream* str,
                                        bool has_receiver) {
  bool will_link;
  ciSignature* declared_signature = NULL;
  ciMethod* callee = str->get_method(will_link, &declared_signature);
  assert(declared_signature != NULL, "cannot be null");
  if (!will_link) {
    if (str->cur_bc() == Bytecodes::_invokedynamic) {
      trap(str, NULL,
           Deoptimization::make_trap_request
           (Deoptimization::Reason_uninitialized,
            Deoptimization::Action_reinterpret));
    } else {
      ciKlass* unloaded_holder = callee->holder();
      trap(str, unloaded_holder, str->get_method_holder_index());
    }
  } else {
    ciSignatureStream sigstr(declared_signature);
    const int arg_size = declared_signature->size();
    const int stack_base = stack_size() - arg_size;
    int i = 0;
    for( ; !sigstr.at_return_type(); sigstr.next()) {
      ciType* type = sigstr.type();
      ciType* stack_type = type_at(stack(stack_base + i++));
      if (type->is_two_word()) {
        ciType* stack_type2 = type_at(stack(stack_base + i++));
        assert(stack_type2->equals(half_type(type)), "must be 2nd half");
      }
    }
    assert(arg_size == i, "must match");
    for (int j = 0; j < arg_size; j++) {
      pop();
    }
    if (has_receiver) {
      pop_object();
    }
    assert(!sigstr.is_done(), "must have return type");
    ciType* return_type = sigstr.type();
    if (!return_type->is_void()) {
      if (!return_type->is_loaded()) {
        do_null_assert(return_type->as_klass());
      } else {
        push_translate(return_type);
      }
    }
  }
}
void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) {
  push(ciReturnAddress::make(str->next_bci()));
}
void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) {
  ciConstant con = str->get_constant();
  BasicType basic_type = con.basic_type();
  if (basic_type == T_ILLEGAL) {
    push_null();
    outer()->record_failure("ldc did not link");
    return;
  }
  if (basic_type == T_OBJECT || basic_type == T_ARRAY) {
    ciObject* obj = con.as_object();
    if (obj->is_null_object()) {
      push_null();
    } else {
      assert(obj->is_instance() || obj->is_array(), "must be java_mirror of klass");
      push_object(obj->klass());
    }
  } else {
    push_translate(ciType::make(basic_type));
  }
}
void ciTypeFlow::StateVector::do_multianewarray(ciBytecodeStream* str) {
  int dimensions = str->get_dimensions();
  bool will_link;
  ciArrayKlass* array_klass = str->get_klass(will_link)->as_array_klass();
  if (!will_link) {
    trap(str, array_klass, str->get_klass_index());
  } else {
    for (int i = 0; i < dimensions; i++) {
      pop_int();
    }
    push_object(array_klass);
  }
}
void ciTypeFlow::StateVector::do_new(ciBytecodeStream* str) {
  bool will_link;
  ciKlass* klass = str->get_klass(will_link);
  if (!will_link || str->is_unresolved_klass()) {
    trap(str, klass, str->get_klass_index());
  } else {
    push_object(klass);
  }
}
void ciTypeFlow::StateVector::do_newarray(ciBytecodeStream* str) {
  pop_int();
  ciKlass* klass = ciTypeArrayKlass::make((BasicType)str->get_index());
  push_object(klass);
}
void ciTypeFlow::StateVector::do_putfield(ciBytecodeStream* str) {
  do_putstatic(str);
  if (_trap_bci != -1)  return;  // unloaded field holder, etc.
  pop_object();
}
void ciTypeFlow::StateVector::do_putstatic(ciBytecodeStream* str) {
  bool will_link;
  ciField* field = str->get_field(will_link);
  if (!will_link) {
    trap(str, field->holder(), str->get_field_holder_index());
  } else {
    ciType* field_type = field->type();
    ciType* type = pop_value();
    if (field_type->is_two_word()) {
      ciType* type2 = pop_value();
      assert(type2->is_two_word(), "must be 2nd half");
      assert(type == half_type(type2), "must be 2nd half");
    }
  }
}
void ciTypeFlow::StateVector::do_ret(ciBytecodeStream* str) {
  Cell index = local(str->get_index());
  ciType* address = type_at(index);
  assert(address->is_return_address(), "bad return address");
  set_type_at(index, bottom_type());
}
void ciTypeFlow::StateVector::trap(ciBytecodeStream* str, ciKlass* klass, int index) {
  _trap_bci = str->cur_bci();
  _trap_index = index;
  CompileLog* log = outer()->env()->log();
  if (log != NULL) {
    int mid = log->identify(outer()->method());
    int kid = (klass == NULL)? -1: log->identify(klass);
    log->begin_elem("uncommon_trap method='%d' bci='%d'", mid, str->cur_bci());
    char buf[100];
    log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf),
                                                          index));
    if (kid >= 0)
      log->print(" klass='%d'", kid);
    log->end_elem();
  }
}
void ciTypeFlow::StateVector::do_null_assert(ciKlass* unloaded_klass) {
  if (unloaded_klass->is_loaded()) {
    push_object(unloaded_klass);
  } else {
    push_null();
  }
}
bool ciTypeFlow::StateVector::apply_one_bytecode(ciBytecodeStream* str) {
  _trap_bci = -1;
  _trap_index = 0;
  if (CITraceTypeFlow) {
    tty->print_cr(">> Interpreting bytecode %d:%s", str->cur_bci(),
                  Bytecodes::name(str->cur_bc()));
  }
  switch(str->cur_bc()) {
  case Bytecodes::_aaload: do_aaload(str);                       break;
  case Bytecodes::_aastore:
    {
      pop_object();
      pop_int();
      pop_objArray();
      break;
    }
  case Bytecodes::_aconst_null:
    {
      push_null();
      break;
    }
  case Bytecodes::_aload:   load_local_object(str->get_index());    break;
  case Bytecodes::_aload_0: load_local_object(0);                   break;
  case Bytecodes::_aload_1: load_local_object(1);                   break;
  case Bytecodes::_aload_2: load_local_object(2);                   break;
  case Bytecodes::_aload_3: load_local_object(3);                   break;
  case Bytecodes::_anewarray:
    {
      pop_int();
      bool will_link;
      ciKlass* element_klass = str->get_klass(will_link);
      if (!will_link) {
        trap(str, element_klass, str->get_klass_index());
      } else {
        push_object(ciObjArrayKlass::make(element_klass));
      }
      break;
    }
  case Bytecodes::_areturn:
  case Bytecodes::_ifnonnull:
  case Bytecodes::_ifnull:
    {
      pop_object();
      break;
    }
  case Bytecodes::_monitorenter:
    {
      pop_object();
      set_monitor_count(monitor_count() + 1);
      break;
    }
  case Bytecodes::_monitorexit:
    {
      pop_object();
      assert(monitor_count() > 0, "must be a monitor to exit from");
      set_monitor_count(monitor_count() - 1);
      break;
    }
  case Bytecodes::_arraylength:
    {
      pop_array();
      push_int();
      break;
    }
  case Bytecodes::_astore:   store_local_object(str->get_index());  break;
  case Bytecodes::_astore_0: store_local_object(0);                 break;
  case Bytecodes::_astore_1: store_local_object(1);                 break;
  case Bytecodes::_astore_2: store_local_object(2);                 break;
  case Bytecodes::_astore_3: store_local_object(3);                 break;
  case Bytecodes::_athrow:
    {
      NEEDS_CLEANUP;
      pop_object();
      break;
    }
  case Bytecodes::_baload:
  case Bytecodes::_caload:
  case Bytecodes::_iaload:
  case Bytecodes::_saload:
    {
      pop_int();
      ciTypeArrayKlass* array_klass = pop_typeArray();
      push_int();
      break;
    }
  case Bytecodes::_bastore:
  case Bytecodes::_castore:
  case Bytecodes::_iastore:
  case Bytecodes::_sastore:
    {
      pop_int();
      pop_int();
      pop_typeArray();
      break;
    }
  case Bytecodes::_bipush:
  case Bytecodes::_iconst_m1:
  case Bytecodes::_iconst_0:
  case Bytecodes::_iconst_1:
  case Bytecodes::_iconst_2:
  case Bytecodes::_iconst_3:
  case Bytecodes::_iconst_4:
  case Bytecodes::_iconst_5:
  case Bytecodes::_sipush:
    {
      push_int();
      break;
    }
  case Bytecodes::_checkcast: do_checkcast(str);                  break;
  case Bytecodes::_d2f:
    {
      pop_double();
      push_float();
      break;
    }
  case Bytecodes::_d2i:
    {
      pop_double();
      push_int();
      break;
    }
  case Bytecodes::_d2l:
    {
      pop_double();
      push_long();
      break;
    }
  case Bytecodes::_dadd:
  case Bytecodes::_ddiv:
  case Bytecodes::_dmul:
  case Bytecodes::_drem:
  case Bytecodes::_dsub:
    {
      pop_double();
      pop_double();
      push_double();
      break;
    }
  case Bytecodes::_daload:
    {
      pop_int();
      ciTypeArrayKlass* array_klass = pop_typeArray();
      push_double();
      break;
    }
  case Bytecodes::_dastore:
    {
      pop_double();
      pop_int();
      pop_typeArray();
      break;
    }
  case Bytecodes::_dcmpg:
  case Bytecodes::_dcmpl:
    {
      pop_double();
      pop_double();
      push_int();
      break;
    }
  case Bytecodes::_dconst_0:
  case Bytecodes::_dconst_1:
    {
      push_double();
      break;
    }
  case Bytecodes::_dload:   load_local_double(str->get_index());    break;
  case Bytecodes::_dload_0: load_local_double(0);                   break;
  case Bytecodes::_dload_1: load_local_double(1);                   break;
  case Bytecodes::_dload_2: load_local_double(2);                   break;
  case Bytecodes::_dload_3: load_local_double(3);                   break;
  case Bytecodes::_dneg:
    {
      pop_double();
      push_double();
      break;
    }
  case Bytecodes::_dreturn:
    {
      pop_double();
      break;
    }
  case Bytecodes::_dstore:   store_local_double(str->get_index());  break;
  case Bytecodes::_dstore_0: store_local_double(0);                 break;
  case Bytecodes::_dstore_1: store_local_double(1);                 break;
  case Bytecodes::_dstore_2: store_local_double(2);                 break;
  case Bytecodes::_dstore_3: store_local_double(3);                 break;
  case Bytecodes::_dup:
    {
      push(type_at_tos());
      break;
    }
  case Bytecodes::_dup_x1:
    {
      ciType* value1 = pop_value();
      ciType* value2 = pop_value();
      push(value1);
      push(value2);
      push(value1);
      break;
    }
  case Bytecodes::_dup_x2:
    {
      ciType* value1 = pop_value();
      ciType* value2 = pop_value();
      ciType* value3 = pop_value();
      push(value1);
      push(value3);
      push(value2);
      push(value1);
      break;
    }
  case Bytecodes::_dup2:
    {
      ciType* value1 = pop_value();
      ciType* value2 = pop_value();
      push(value2);
      push(value1);
      push(value2);
      push(value1);
      break;
    }
  case Bytecodes::_dup2_x1:
    {
      ciType* value1 = pop_value();
      ciType* value2 = pop_value();
      ciType* value3 = pop_value();
      push(value2);
      push(value1);
      push(value3);
      push(value2);
      push(value1);
      break;
    }
  case Bytecodes::_dup2_x2:
    {
      ciType* value1 = pop_value();
      ciType* value2 = pop_value();
      ciType* value3 = pop_value();
      ciType* value4 = pop_value();
      push(value2);
      push(value1);
      push(value4);
      push(value3);
      push(value2);
      push(value1);
      break;
    }
  case Bytecodes::_f2d:
    {
      pop_float();
      push_double();
      break;
    }
  case Bytecodes::_f2i:
    {
      pop_float();
      push_int();
      break;
    }
  case Bytecodes::_f2l:
    {
      pop_float();
      push_long();
      break;
    }
  case Bytecodes::_fadd:
  case Bytecodes::_fdiv:
  case Bytecodes::_fmul:
  case Bytecodes::_frem:
  case Bytecodes::_fsub:
    {
      pop_float();
      pop_float();
      push_float();
      break;
    }
  case Bytecodes::_faload:
    {
      pop_int();
      ciTypeArrayKlass* array_klass = pop_typeArray();
      push_float();
      break;
    }
  case Bytecodes::_fastore:
    {
      pop_float();
      pop_int();
      ciTypeArrayKlass* array_klass = pop_typeArray();
      break;
    }
  case Bytecodes::_fcmpg:
  case Bytecodes::_fcmpl:
    {
      pop_float();
      pop_float();
      push_int();
      break;
    }
  case Bytecodes::_fconst_0:
  case Bytecodes::_fconst_1:
  case Bytecodes::_fconst_2:
    {
      push_float();
      break;
    }
  case Bytecodes::_fload:   load_local_float(str->get_index());     break;
  case Bytecodes::_fload_0: load_local_float(0);                    break;
  case Bytecodes::_fload_1: load_local_float(1);                    break;
  case Bytecodes::_fload_2: load_local_float(2);                    break;
  case Bytecodes::_fload_3: load_local_float(3);                    break;
  case Bytecodes::_fneg:
    {
      pop_float();
      push_float();
      break;
    }
  case Bytecodes::_freturn:
    {
      pop_float();
      break;
    }
  case Bytecodes::_fstore:    store_local_float(str->get_index());   break;
  case Bytecodes::_fstore_0:  store_local_float(0);                  break;
  case Bytecodes::_fstore_1:  store_local_float(1);                  break;
  case Bytecodes::_fstore_2:  store_local_float(2);                  break;
  case Bytecodes::_fstore_3:  store_local_float(3);                  break;
  case Bytecodes::_getfield:  do_getfield(str);                      break;
  case Bytecodes::_getstatic: do_getstatic(str);                     break;
  case Bytecodes::_goto:
  case Bytecodes::_goto_w:
  case Bytecodes::_nop:
  case Bytecodes::_return:
    {
      break;
    }
  case Bytecodes::_i2b:
  case Bytecodes::_i2c:
  case Bytecodes::_i2s:
  case Bytecodes::_ineg:
    {
      pop_int();
      push_int();
      break;
    }
  case Bytecodes::_i2d:
    {
      pop_int();
      push_double();
      break;
    }
  case Bytecodes::_i2f:
    {
      pop_int();
      push_float();
      break;
    }
  case Bytecodes::_i2l:
    {
      pop_int();
      push_long();
      break;
    }
  case Bytecodes::_iadd:
  case Bytecodes::_iand:
  case Bytecodes::_idiv:
  case Bytecodes::_imul:
  case Bytecodes::_ior:
  case Bytecodes::_irem:
  case Bytecodes::_ishl:
  case Bytecodes::_ishr:
  case Bytecodes::_isub:
  case Bytecodes::_iushr:
  case Bytecodes::_ixor:
    {
      pop_int();
      pop_int();
      push_int();
      break;
    }
  case Bytecodes::_if_acmpeq:
  case Bytecodes::_if_acmpne:
    {
      pop_object();
      pop_object();
      break;
    }
  case Bytecodes::_if_icmpeq:
  case Bytecodes::_if_icmpge:
  case Bytecodes::_if_icmpgt:
  case Bytecodes::_if_icmple:
  case Bytecodes::_if_icmplt:
  case Bytecodes::_if_icmpne:
    {
      pop_int();
      pop_int();
      break;
    }
  case Bytecodes::_ifeq:
  case Bytecodes::_ifle:
  case Bytecodes::_iflt:
  case Bytecodes::_ifge:
  case Bytecodes::_ifgt:
  case Bytecodes::_ifne:
  case Bytecodes::_ireturn:
  case Bytecodes::_lookupswitch:
  case Bytecodes::_tableswitch:
    {
      pop_int();
      break;
    }
  case Bytecodes::_iinc:
    {
      int lnum = str->get_index();
      check_int(local(lnum));
      store_to_local(lnum);
      break;
    }
  case Bytecodes::_iload:   load_local_int(str->get_index()); break;
  case Bytecodes::_iload_0: load_local_int(0);                      break;
  case Bytecodes::_iload_1: load_local_int(1);                      break;
  case Bytecodes::_iload_2: load_local_int(2);                      break;
  case Bytecodes::_iload_3: load_local_int(3);                      break;
  case Bytecodes::_instanceof:
    {
      do_checkcast(str);
      pop_object();
      push_int();
      break;
    }
  case Bytecodes::_invokeinterface: do_invoke(str, true);           break;
  case Bytecodes::_invokespecial:   do_invoke(str, true);           break;
  case Bytecodes::_invokestatic:    do_invoke(str, false);          break;
  case Bytecodes::_invokevirtual:   do_invoke(str, true);           break;
  case Bytecodes::_invokedynamic:   do_invoke(str, false);          break;
  case Bytecodes::_istore:   store_local_int(str->get_index());     break;
  case Bytecodes::_istore_0: store_local_int(0);                    break;
  case Bytecodes::_istore_1: store_local_int(1);                    break;
  case Bytecodes::_istore_2: store_local_int(2);                    break;
  case Bytecodes::_istore_3: store_local_int(3);                    break;
  case Bytecodes::_jsr:
  case Bytecodes::_jsr_w: do_jsr(str);                              break;
  case Bytecodes::_l2d:
    {
      pop_long();
      push_double();
      break;
    }
  case Bytecodes::_l2f:
    {
      pop_long();
      push_float();
      break;
    }
  case Bytecodes::_l2i:
    {
      pop_long();
      push_int();
      break;
    }
  case Bytecodes::_ladd:
  case Bytecodes::_land:
  case Bytecodes::_ldiv:
  case Bytecodes::_lmul:
  case Bytecodes::_lor:
  case Bytecodes::_lrem:
  case Bytecodes::_lsub:
  case Bytecodes::_lxor:
    {
      pop_long();
      pop_long();
      push_long();
      break;
    }
  case Bytecodes::_laload:
    {
      pop_int();
      ciTypeArrayKlass* array_klass = pop_typeArray();
      push_long();
      break;
    }
  case Bytecodes::_lastore:
    {
      pop_long();
      pop_int();
      pop_typeArray();
      break;
    }
  case Bytecodes::_lcmp:
    {
      pop_long();
      pop_long();
      push_int();
      break;
    }
  case Bytecodes::_lconst_0:
  case Bytecodes::_lconst_1:
    {
      push_long();
      break;
    }
  case Bytecodes::_ldc:
  case Bytecodes::_ldc_w:
  case Bytecodes::_ldc2_w:
    {
      do_ldc(str);
      break;
    }
  case Bytecodes::_lload:   load_local_long(str->get_index());      break;
  case Bytecodes::_lload_0: load_local_long(0);                     break;
  case Bytecodes::_lload_1: load_local_long(1);                     break;
  case Bytecodes::_lload_2: load_local_long(2);                     break;
  case Bytecodes::_lload_3: load_local_long(3);                     break;
  case Bytecodes::_lneg:
    {
      pop_long();
      push_long();
      break;
    }
  case Bytecodes::_lreturn:
    {
      pop_long();
      break;
    }
  case Bytecodes::_lshl:
  case Bytecodes::_lshr:
  case Bytecodes::_lushr:
    {
      pop_int();
      pop_long();
      push_long();
      break;
    }
  case Bytecodes::_lstore:   store_local_long(str->get_index());    break;
  case Bytecodes::_lstore_0: store_local_long(0);                   break;
  case Bytecodes::_lstore_1: store_local_long(1);                   break;
  case Bytecodes::_lstore_2: store_local_long(2);                   break;
  case Bytecodes::_lstore_3: store_local_long(3);                   break;
  case Bytecodes::_multianewarray: do_multianewarray(str);          break;
  case Bytecodes::_new:      do_new(str);                           break;
  case Bytecodes::_newarray: do_newarray(str);                      break;
  case Bytecodes::_pop:
    {
      pop();
      break;
    }
  case Bytecodes::_pop2:
    {
      pop();
      pop();
      break;
    }
  case Bytecodes::_putfield:       do_putfield(str);                 break;
  case Bytecodes::_putstatic:      do_putstatic(str);                break;
  case Bytecodes::_ret: do_ret(str);                                 break;
  case Bytecodes::_swap:
    {
      ciType* value1 = pop_value();
      ciType* value2 = pop_value();
      push(value1);
      push(value2);
      break;
    }
  case Bytecodes::_wide:
  default:
    {
      ShouldNotReachHere();
      break;
    }
  }
  if (CITraceTypeFlow) {
    print_on(tty);
  }
  return (_trap_bci != -1);
}
#ifndef PRODUCT
void ciTypeFlow::StateVector::print_cell_on(outputStream* st, Cell c) const {
  ciType* type = type_at(c);
  if (type == top_type()) {
    st->print("top");
  } else if (type == bottom_type()) {
    st->print("bottom");
  } else if (type == null_type()) {
    st->print("null");
  } else if (type == long2_type()) {
    st->print("long2");
  } else if (type == double2_type()) {
    st->print("double2");
  } else if (is_int(type)) {
    st->print("int");
  } else if (is_long(type)) {
    st->print("long");
  } else if (is_float(type)) {
    st->print("float");
  } else if (is_double(type)) {
    st->print("double");
  } else if (type->is_return_address()) {
    st->print("address(%d)", type->as_return_address()->bci());
  } else {
    if (type->is_klass()) {
      type->as_klass()->name()->print_symbol_on(st);
    } else {
      st->print("UNEXPECTED TYPE");
      type->print();
    }
  }
}
void ciTypeFlow::StateVector::print_on(outputStream* st) const {
  int num_locals   = _outer->max_locals();
  int num_stack    = stack_size();
  int num_monitors = monitor_count();
  st->print_cr("  State : locals %d, stack %d, monitors %d", num_locals, num_stack, num_monitors);
  if (num_stack >= 0) {
    int i;
    for (i = 0; i < num_locals; i++) {
      st->print("    local %2d : ", i);
      print_cell_on(st, local(i));
      st->cr();
    }
    for (i = 0; i < num_stack; i++) {
      st->print("    stack %2d : ", i);
      print_cell_on(st, stack(i));
      st->cr();
    }
  }
}
#endif
void ciTypeFlow::SuccIter::next() {
  int succ_ct = _pred->successors()->length();
  int next = _index + 1;
  if (next < succ_ct) {
    _index = next;
    _succ = _pred->successors()->at(next);
    return;
  }
  for (int i = next - succ_ct; i < _pred->exceptions()->length(); i++) {
    ciInstanceKlass* exception_klass = _pred->exc_klasses()->at(i);
    if (exception_klass->is_loaded()) {
      _index = next;
      _succ = _pred->exceptions()->at(i);
      return;
    }
    next++;
  }
  _index = -1;
  _succ = NULL;
}
void ciTypeFlow::SuccIter::set_succ(Block* succ) {
  int succ_ct = _pred->successors()->length();
  if (_index < succ_ct) {
    _pred->successors()->at_put(_index, succ);
  } else {
    int idx = _index - succ_ct;
    _pred->exceptions()->at_put(idx, succ);
  }
}
ciTypeFlow::Block::Block(ciTypeFlow* outer,
                         ciBlock *ciblk,
                         ciTypeFlow::JsrSet* jsrs) {
  _ciblock = ciblk;
  _exceptions = NULL;
  _exc_klasses = NULL;
  _successors = NULL;
  _state = new (outer->arena()) StateVector(outer);
  JsrSet* new_jsrs =
    new (outer->arena()) JsrSet(outer->arena(), jsrs->size());
  jsrs->copy_into(new_jsrs);
  _jsrs = new_jsrs;
  _next = NULL;
  _on_work_list = false;
  _backedge_copy = false;
  _has_monitorenter = false;
  _trap_bci = -1;
  _trap_index = 0;
  df_init();
  if (CITraceTypeFlow) {
    tty->print_cr(">> Created new block");
    print_on(tty);
  }
  assert(this->outer() == outer, "outer link set up");
  assert(!outer->have_block_count(), "must not have mapped blocks yet");
}
void ciTypeFlow::Block::df_init() {
  _pre_order = -1; assert(!has_pre_order(), "");
  _post_order = -1; assert(!has_post_order(), "");
  _loop = NULL;
  _irreducible_entry = false;
  _rpo_next = NULL;
}
GrowableArray<ciTypeFlow::Block*>*
ciTypeFlow::Block::successors(ciBytecodeStream* str,
                              ciTypeFlow::StateVector* state,
                              ciTypeFlow::JsrSet* jsrs) {
  if (_successors == NULL) {
    if (CITraceTypeFlow) {
      tty->print(">> Computing successors for block ");
      print_value_on(tty);
      tty->cr();
    }
    ciTypeFlow* analyzer = outer();
    Arena* arena = analyzer->arena();
    Block* block = NULL;
    bool has_successor = !has_trap() &&
                         (control() != ciBlock::fall_through_bci || limit() < analyzer->code_size());
    if (!has_successor) {
      _successors =
        new (arena) GrowableArray<Block*>(arena, 1, 0, NULL);
    } else if (control() == ciBlock::fall_through_bci) {
      assert(str->cur_bci() == limit(), "bad block end");
      _successors =
        new (arena) GrowableArray<Block*>(arena, 1, 0, NULL);
      Block* block = analyzer->block_at(limit(), _jsrs);
      assert(_successors->length() == FALL_THROUGH, "");
      _successors->append(block);
    } else {
      int current_bci = str->cur_bci();
      int next_bci = str->next_bci();
      int branch_bci = -1;
      Block* target = NULL;
      assert(str->next_bci() == limit(), "bad block end");
      switch (str->cur_bc()) {
      case Bytecodes::_ifeq:         case Bytecodes::_ifne:
      case Bytecodes::_iflt:         case Bytecodes::_ifge:
      case Bytecodes::_ifgt:         case Bytecodes::_ifle:
      case Bytecodes::_if_icmpeq:    case Bytecodes::_if_icmpne:
      case Bytecodes::_if_icmplt:    case Bytecodes::_if_icmpge:
      case Bytecodes::_if_icmpgt:    case Bytecodes::_if_icmple:
      case Bytecodes::_if_acmpeq:    case Bytecodes::_if_acmpne:
      case Bytecodes::_ifnull:       case Bytecodes::_ifnonnull:
        branch_bci = str->get_dest();
        _successors =
          new (arena) GrowableArray<Block*>(arena, 2, 0, NULL);
        assert(_successors->length() == IF_NOT_TAKEN, "");
        _successors->append(analyzer->block_at(next_bci, jsrs));
        assert(_successors->length() == IF_TAKEN, "");
        _successors->append(analyzer->block_at(branch_bci, jsrs));
        break;
      case Bytecodes::_goto:
        branch_bci = str->get_dest();
        _successors =
          new (arena) GrowableArray<Block*>(arena, 1, 0, NULL);
        assert(_successors->length() == GOTO_TARGET, "");
        _successors->append(analyzer->block_at(branch_bci, jsrs));
        break;
      case Bytecodes::_jsr:
        branch_bci = str->get_dest();
        _successors =
          new (arena) GrowableArray<Block*>(arena, 1, 0, NULL);
        assert(_successors->length() == GOTO_TARGET, "");
        _successors->append(analyzer->block_at(branch_bci, jsrs));
        break;
      case Bytecodes::_goto_w:
      case Bytecodes::_jsr_w:
        _successors =
          new (arena) GrowableArray<Block*>(arena, 1, 0, NULL);
        assert(_successors->length() == GOTO_TARGET, "");
        _successors->append(analyzer->block_at(str->get_far_dest(), jsrs));
        break;
      case Bytecodes::_tableswitch:  {
        Bytecode_tableswitch tableswitch(str);
        int len = tableswitch.length();
        _successors =
          new (arena) GrowableArray<Block*>(arena, len+1, 0, NULL);
        int bci = current_bci + tableswitch.default_offset();
        Block* block = analyzer->block_at(bci, jsrs);
        assert(_successors->length() == SWITCH_DEFAULT, "");
        _successors->append(block);
        while (--len >= 0) {
          int bci = current_bci + tableswitch.dest_offset_at(len);
          block = analyzer->block_at(bci, jsrs);
          assert(_successors->length() >= SWITCH_CASES, "");
          _successors->append_if_missing(block);
        }
        break;
      }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值