示例#1
0
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);
  }
}
示例#2
0
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();
  }
}
示例#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;
 }
示例#4
0
oop InterpretedIC::does_not_understand(oop receiver, InterpretedIC* ic, frame* f) {
  memOop msg;
  symbolOop sel;
  {
    // message not understood...
    BlockScavenge bs; // make sure that no scavenge happens
    klassOop msgKlass = klassOop(Universe::find_global("Message"));
    oop obj = msgKlass->klass_part()->allocateObject();
    assert(obj->is_mem(), "just checkin'...");
    msg = memOop(obj);
    int nofArgs = ic->selector()->number_of_arguments();
    objArrayOop args = oopFactory::new_objArray(nofArgs);
    for (int i = 1; i <= nofArgs; i++) {
      args->obj_at_put(i, f->expr(nofArgs - i));
    }
    // for now: assume instance variables are there...
    // later: should check this or use a VM interface:
    // msg->set_receiver(recv);
    // msg->set_selector(ic->selector());
    // msg->set_arguments(args);
    msg->raw_at_put(2, receiver);
    msg->raw_at_put(3, ic->selector());
    msg->raw_at_put(4, args);
    sel = oopFactory::new_symbol("doesNotUnderstand:");
    if (interpreter_normal_lookup(receiver->klass(), sel).is_empty()) {
      // doesNotUnderstand: not found ==> process error
      { ResourceMark rm;
      std->print("LOOKUP ERROR\n");
      sel->print_value(); std->print(" not found\n");
      }
      if (DeltaProcess::active()->is_scheduler()) {
        DeltaProcess::active()->trace_stack();
        fatal("lookup error in scheduler");
      } else {
        DeltaProcess::active()->suspend(::lookup_error);
      }
      ShouldNotReachHere();
    }
  }
  // return marked result of doesNotUnderstand: message
  return Delta::call(receiver, sel, msg);

  // Solution: use an nmethod-like stub-routine called from
  // within a (possibly one-element) PIC (in order to keep
  // the method selector in the IC. That stub does the
  // Delta:call and pops the right number of arguments
  // taken from the selector (the no. of arguments from
  // the selector can be optimized).
}
示例#5
0
void InterpretedIC_Iterator::init_iteration() {
  _pic = NULL;
  _index = 0;
  // determine initial state
  switch (_ic->send_type()) {
    case Bytecodes::interpreted_send:
      if (_ic->is_empty()) {
        // anamorphic call site (has never been executed => no type information)
        _number_of_targets = 0;
        _info = anamorphic;
      } else {
        // monomorphic call site
        _number_of_targets = 1;
        _info = monomorphic;
        set_klass(_ic->second_word());
        set_method(_ic->first_word());
      }
      break;
    case Bytecodes::compiled_send   :
      _number_of_targets = 1;
      _info = monomorphic;
      set_klass(_ic->second_word());
      assert(_ic->first_word()->is_smi(), "must have jumpTableEntry");
      set_method(_ic->first_word());
      assert(is_compiled(), "bad type");
      break;
    case Bytecodes::accessor_send   : // fall through
    case Bytecodes::primitive_send  :
      _number_of_targets = 1;
      _info = monomorphic;
      set_klass(_ic->second_word());
      set_method(_ic->first_word());
      assert(is_interpreted(), "bad type");
      break;
    case Bytecodes::megamorphic_send:
      // no type information stored
      _number_of_targets = 0;
      _info = megamorphic;
      break;
    case Bytecodes::polymorphic_send:
      // information on many types
      _pic = objArrayOop(_ic->second_word());
      _number_of_targets = _pic->length() / 2;
      _info = polymorphic;
      set_klass(_pic->obj_at(2));
      set_method(_pic->obj_at(1));
      break;
    case Bytecodes::predicted_send:
      if (_ic->is_empty() || _ic->second_word() == smiKlassObj) {
        _number_of_targets = 1;
        _info = monomorphic;
      } else {
        _number_of_targets = 2;
        _info = polymorphic;
      }
      set_klass(smiKlassObj);
      set_method(interpreter_normal_lookup(smiKlassObj, selector()).value());
      assert(_method != NULL && _method->is_mem(), "this method must be there");
      break;
    default: ShouldNotReachHere();
  }
  assert((number_of_targets() > 1) == (_info == polymorphic), "inconsistency");
}