oop* InterpretedIC::inline_cache_miss() {
  NoGCVerifier noGC;

  // get ic info
  frame           f         = DeltaProcess::active()->last_frame();
  InterpretedIC*  ic        = f.current_interpretedIC();
  Bytecodes::Code send_code = ic->send_code();

  oop receiver = ic->argument_spec() == Bytecodes::args_only // Are we at a self or super send?
    ? f.receiver()                                //  yes: take receiver of frame
    : f.expr(ic->nof_arguments());                //  no:  take receiver pushed before the arguments

  // do the lookup
  klassOop klass = receiver->klass();
  LookupResult result = Bytecodes::is_super_send(send_code)
    ? interpreter_super_lookup(ic->selector())
    : interpreter_normal_lookup(klass, ic->selector());

  // tracing
  if (TraceInlineCacheMiss) {
    std->print("IC miss, ");  trace_inline_cache_miss(ic, klass, result);
  }
  // handle the lookup result
  if (!result.is_empty()) {
    update_inline_cache(ic, &f, ic->send_code(), klass, result);
    return NULL;
  } else {
    return cacheMissResult(does_not_understand(receiver, ic, &f), 
      ic->nof_arguments() + (ic->argument_spec() == Bytecodes::args_only ? 0 : 1))->objs(1);
  }
}
void InterpretedIC::inline_cache_miss() {
  NoGCVerifier noGC;  

  // get ic info
  frame           f         = DeltaProcess::active()->last_frame();
  InterpretedIC*  ic        = f.current_interpretedIC();
  Bytecodes::Code send_code = ic->send_code();

  oop receiver = ic->argument_spec() == Bytecodes::args_only // Are we at a self or super send?
               ? f.receiver()                                //  yes: take receiver of frame
	       : f.expr(ic->nof_arguments());                //  no:  take receiver pushed before the arguments

  // do the lookup
  klassOop klass = receiver->klass();
  LookupResult result = Bytecodes::is_super_send(send_code)
                      ? interpreter_super_lookup(ic->selector())
                      : interpreter_normal_lookup(klass, ic->selector());

  // tracing
  if (TraceMessageSend) std->print_cr("inline cache miss");
  if (TraceLookup)      trace_inline_cache_miss(ic, klass, result);

  // handle the lookup result
  if (!result.is_empty()) 
    update_inline_cache(ic, &f, send_code, klass, result);
  else {
    does_not_understand(receiver, ic, &f);
    // If the program continues we'll redo the inline_cache_miss
    if (!have_nlr_through_C) inline_cache_miss();
  }
}
Exemple #3
0
 LookupResult lookup(klassOop klass, symbolOop selector) {
   if (!match(klass, selector)) {
     _result = interpreter_normal_lookup(klass, selector);
     if (!_result.is_empty()) {
       _key.initialize(klass, selector);
     }
   }
   return _result;
 }
void InterpretedIC::replace(LookupResult result, klassOop receiver_klass) {
  // IC entries before modification - used for loging only
  Bytecodes::Code code_before  = send_code();
  oop             word1_before = first_word();
  oop             word2_before = second_word();
  int             transition   = 0;
  // modify IC
  guarantee(word2_before == receiver_klass, "klass should be the same");
  if (result.is_empty()) {
    clear();
    transition = 1;
  } else if (result.is_method()) {
    if (send_type() == Bytecodes::megamorphic_send) {
      set(send_code(), result.method(), receiver_klass);
      transition = 2;
    } else {
      // Please Fix this Robert
      // implement set_monomorphic(klass, method)
      clear();
      transition = 3;
    }
  } else {
    if (send_type() == Bytecodes::megamorphic_send) {
      set(send_code(), oop(result.entry()), receiver_klass);
      transition = 4;
    } else {
      assert(result.is_entry(), "must be jump table entry");
      // a jump table entry of a nmethod is found so let's update the current send
      set(Bytecodes::compiled_send_code_for(send_code()), oop(result.entry()), receiver_klass);
      transition = 5;
    }
  }
  // IC entries after modification - used for loging only
  Bytecodes::Code code_after  = send_code();
  oop             word1_after = first_word();
  oop             word2_after = second_word();
  // log modification
  LOG_EVENT3("InterpretedIC::replace: IC at 0x%x: entry for klass 0x%x replaced (transition %d)", this, receiver_klass, transition);
  LOG_EVENT3("  from (%s, 0x%x, 0x%x)", Bytecodes::name(code_before), word1_before, word2_before);
  LOG_EVENT3("  to   (%s, 0x%x, 0x%x)", Bytecodes::name(code_after ), word1_after , word2_after );
}