src/share/vm/c1/c1_LIRGenerator.cpp

changeset 5914
d13d7aba8c12
parent 5907
c775af091fe9
child 5921
ce0cc25bc5e2
     1.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Oct 09 11:05:17 2013 -0700
     1.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Oct 09 16:32:21 2013 +0200
     1.3 @@ -2571,6 +2571,78 @@
     1.4  }
     1.5  
     1.6  
     1.7 +ciKlass* LIRGenerator::profile_arg_type(ciMethodData* md, int md_base_offset, int md_offset, intptr_t profiled_k, Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_k) {
     1.8 +  ciKlass* result = NULL;
     1.9 +  bool do_null = !not_null && !TypeEntries::was_null_seen(profiled_k);
    1.10 +  bool do_update = !TypeEntries::is_type_unknown(profiled_k);
    1.11 +  // known not to be null or null bit already set and already set to
    1.12 +  // unknown: nothing we can do to improve profiling
    1.13 +  if (!do_null && !do_update) {
    1.14 +    return result;
    1.15 +  }
    1.16 +
    1.17 +  ciKlass* exact_klass = NULL;
    1.18 +  Compilation* comp = Compilation::current();
    1.19 +  if (do_update) {
    1.20 +    // try to find exact type, using CHA if possible, so that loading
    1.21 +    // the klass from the object can be avoided
    1.22 +    ciType* type = arg->exact_type();
    1.23 +    if (type == NULL) {
    1.24 +      type = arg->declared_type();
    1.25 +      type = comp->cha_exact_type(type);
    1.26 +    }
    1.27 +    assert(type == NULL || type->is_klass(), "type should be class");
    1.28 +    exact_klass = (type != NULL && type->is_loaded()) ? (ciKlass*)type : NULL;
    1.29 +
    1.30 +    do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass;
    1.31 +  }
    1.32 +
    1.33 +  if (!do_null && !do_update) {
    1.34 +    return result;
    1.35 +  }
    1.36 +
    1.37 +  ciKlass* exact_signature_k = NULL;
    1.38 +  if (do_update) {
    1.39 +    // Is the type from the signature exact (the only one possible)?
    1.40 +    exact_signature_k = signature_k->exact_klass();
    1.41 +    if (exact_signature_k == NULL) {
    1.42 +      exact_signature_k = comp->cha_exact_type(signature_k);
    1.43 +    } else {
    1.44 +      result = exact_signature_k;
    1.45 +      do_update = false;
    1.46 +      // Known statically. No need to emit any code: prevent
    1.47 +      // LIR_Assembler::emit_profile_type() from emitting useless code
    1.48 +      profiled_k = ciTypeEntries::with_status(result, profiled_k);
    1.49 +    }
    1.50 +    if (exact_signature_k != NULL && exact_klass != exact_signature_k) {
    1.51 +      assert(exact_klass == NULL, "arg and signature disagree?");
    1.52 +      // sometimes the type of the signature is better than the best type
    1.53 +      // the compiler has
    1.54 +      exact_klass = exact_signature_k;
    1.55 +      do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass;
    1.56 +    }
    1.57 +  }
    1.58 +
    1.59 +  if (!do_null && !do_update) {
    1.60 +    return result;
    1.61 +  }
    1.62 +
    1.63 +  if (mdp == LIR_OprFact::illegalOpr) {
    1.64 +    mdp = new_register(T_METADATA);
    1.65 +    __ metadata2reg(md->constant_encoding(), mdp);
    1.66 +    if (md_base_offset != 0) {
    1.67 +      LIR_Address* base_type_address = new LIR_Address(mdp, md_base_offset, T_ADDRESS);
    1.68 +      mdp = new_pointer_register();
    1.69 +      __ leal(LIR_OprFact::address(base_type_address), mdp);
    1.70 +    }
    1.71 +  }
    1.72 +  LIRItem value(arg, this);
    1.73 +  value.load_item();
    1.74 +  __ profile_type(new LIR_Address(mdp, md_offset, T_METADATA),
    1.75 +                  value.result(), exact_klass, profiled_k, new_pointer_register(), not_null, exact_signature_k != NULL);
    1.76 +  return result;
    1.77 +}
    1.78 +
    1.79  void LIRGenerator::do_Base(Base* x) {
    1.80    __ std_entry(LIR_OprFact::illegalOpr);
    1.81    // Emit moves from physical registers / stack slots to virtual registers
    1.82 @@ -3004,12 +3076,52 @@
    1.83    }
    1.84  }
    1.85  
    1.86 +void LIRGenerator::profile_arguments(ProfileCall* x) {
    1.87 +  if (MethodData::profile_arguments()) {
    1.88 +    int bci = x->bci_of_invoke();
    1.89 +    ciMethodData* md = x->method()->method_data_or_null();
    1.90 +    ciProfileData* data = md->bci_to_data(bci);
    1.91 +    if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
    1.92 +      ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset();
    1.93 +      int base_offset = md->byte_offset_of_slot(data, extra);
    1.94 +      LIR_Opr mdp = LIR_OprFact::illegalOpr;
    1.95 +      ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args();
    1.96 +
    1.97 +      Bytecodes::Code bc = x->method()->java_code_at_bci(bci);
    1.98 +      int start = 0;
    1.99 +      int stop = args->number_of_arguments();
   1.100 +      if (x->nb_profiled_args() < stop) {
   1.101 +        // if called through method handle invoke, some arguments may have been popped
   1.102 +        stop = x->nb_profiled_args();
   1.103 +      }
   1.104 +      ciSignature* sig = x->callee()->signature();
   1.105 +      // method handle call to virtual method
   1.106 +      bool has_receiver = x->inlined() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc);
   1.107 +      ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL);
   1.108 +      for (int i = 0; i < stop; i++) {
   1.109 +        int off = in_bytes(TypeStackSlotEntries::type_offset(i)) - in_bytes(TypeStackSlotEntries::args_data_offset());
   1.110 +        ciKlass* exact = profile_arg_type(md, base_offset, off,
   1.111 +                                          args->type(i), x->profiled_arg_at(i+start), mdp,
   1.112 +                                          !x->arg_needs_null_check(i+start), sig_stream.next_klass());
   1.113 +        if (exact != NULL) {
   1.114 +          md->set_argument_type(bci, i, exact);
   1.115 +        }
   1.116 +      }
   1.117 +    }
   1.118 +  }
   1.119 +}
   1.120 +
   1.121  void LIRGenerator::do_ProfileCall(ProfileCall* x) {
   1.122    // Need recv in a temporary register so it interferes with the other temporaries
   1.123    LIR_Opr recv = LIR_OprFact::illegalOpr;
   1.124    LIR_Opr mdo = new_register(T_OBJECT);
   1.125    // tmp is used to hold the counters on SPARC
   1.126    LIR_Opr tmp = new_pointer_register();
   1.127 +
   1.128 +  if (x->nb_profiled_args() > 0) {
   1.129 +    profile_arguments(x);
   1.130 +  }
   1.131 +
   1.132    if (x->recv() != NULL) {
   1.133      LIRItem value(x->recv(), this);
   1.134      value.load_item();

mercurial