void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) {
    if (TraceInvocationCounterOverflow) {
        InvocationCounter* ic = m->invocation_counter();
        InvocationCounter* bc = m->backedge_counter();
        ResourceMark rm;
        const char* msg =
            bci == InvocationEntryBci
            ? "comp-policy cntr ovfl @ %d in entry of "
            : "comp-policy cntr ovfl @ %d in loop of ";
        tty->print(msg, bci);
        m->print_value();
        tty->cr();
        ic->print();
        bc->print();
        if (ProfileInterpreter) {
            if (bci != InvocationEntryBci) {
                methodDataOop mdo = m->method_data();
                if (mdo != NULL) {
                    int count = mdo->bci_to_data(branch_bci)->as_JumpData()->taken();
                    tty->print_cr("back branch count = %d", count);
                }
            }
        }
    }
}
void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) {
  if (TraceInvocationCounterOverflow) {
    MethodCounters* mcs = m->method_counters();
    assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
    InvocationCounter* ic = mcs->invocation_counter();
    InvocationCounter* bc = mcs->backedge_counter();
    ResourceMark rm;
    if (bci == InvocationEntryBci) {
      tty->print("comp-policy cntr ovfl @ %d in entry of ", bci);
    } else {
      tty->print("comp-policy cntr ovfl @ %d in loop of ", bci);
    }
    m->print_value();
    tty->cr();
    ic->print();
    bc->print();
    if (ProfileInterpreter) {
      if (bci != InvocationEntryBci) {
        MethodData* mdo = m->method_data();
        if (mdo != NULL) {
          int count = mdo->bci_to_data(branch_bci)->as_JumpData()->taken();
          tty->print_cr("back branch count = %d", count);
        }
      }
    }
  }
}
void NonTieredCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
    ScopeDesc* sd = trap_scope;
    for (; !sd->is_top(); sd = sd->sender()) {
        // Reset ICs of inlined methods, since they can trigger compilations also.
        sd->method()->invocation_counter()->reset();
    }
    InvocationCounter* c = sd->method()->invocation_counter();
    if (is_osr) {
        // It was an OSR method, so bump the count higher.
        c->set(c->state(), CompileThreshold);
    } else {
        c->reset();
    }
    sd->method()->backedge_counter()->reset();
}
void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) {
    // Delay next back-branch event but pump up invocation counter to triger
    // whole method compilation.
    InvocationCounter* i = m->invocation_counter();
    InvocationCounter* b = m->backedge_counter();

    // Don't set invocation_counter's value too low otherwise the method will
    // look like immature (ic < ~5300) which prevents the inlining based on
    // the type profiling.
    i->set(i->state(), CompileThreshold);
    // Don't reset counter too low - it is used to check if OSR method is ready.
    b->set(b->state(), CompileThreshold / 2);
}
Beispiel #5
0
// Get a measure of how much mileage the method has on it.
int methodDataOopDesc::mileage_of(methodOop method) {
  int mileage = 0;
  int iic = method->interpreter_invocation_count();
  if (mileage < iic)  mileage = iic;

  InvocationCounter* ic = method->invocation_counter();
  InvocationCounter* bc = method->backedge_counter();

  int icval = ic->count();
  if (ic->carry()) icval += CompileThreshold;
  if (mileage < icval)  mileage = icval;
  int bcval = bc->count();
  if (bc->carry()) bcval += CompileThreshold;
  if (mileage < bcval)  mileage = bcval;
  return mileage;
}
Beispiel #6
0
// Get a measure of how much mileage the method has on it.
int MethodData::mileage_of(Method* method) {
  int mileage = 0;
  if (TieredCompilation) {
    mileage = MAX2(method->invocation_count(), method->backedge_count());
  } else {
    int iic = method->interpreter_invocation_count();
    if (mileage < iic)  mileage = iic;
    InvocationCounter* ic = method->invocation_counter();
    InvocationCounter* bc = method->backedge_counter();
    int icval = ic->count();
    if (ic->carry()) icval += CompileThreshold;
    if (mileage < icval)  mileage = icval;
    int bcval = bc->count();
    if (bc->carry()) bcval += CompileThreshold;
    if (mileage < bcval)  mileage = bcval;
  }
  return mileage;
}
Beispiel #7
0
int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
  // Make sure method is native and not abstract
  assert(method->is_native() && !method->is_abstract(), "should be");

  JavaThread *thread = (JavaThread *) THREAD;
  ZeroStack *stack = thread->zero_stack();

  // Allocate and initialize our frame
  InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0);
  thread->push_zero_frame(frame);
  interpreterState istate = frame->interpreter_state();
  intptr_t *locals = istate->locals();

  // Update the invocation counter
  if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
    InvocationCounter *counter = method->invocation_counter();
    counter->increment();
    if (counter->reached_InvocationLimit()) {
      CALL_VM_NOCHECK(
        InterpreterRuntime::frequency_counter_overflow(thread, NULL));
      if (HAS_PENDING_EXCEPTION)
        goto unwind_and_return;
    }
  }

  // Lock if necessary
  BasicObjectLock *monitor;
  monitor = NULL;
  if (method->is_synchronized()) {
    monitor = (BasicObjectLock*) istate->stack_base();
    oop lockee = monitor->obj();
    markOop disp = lockee->mark()->set_unlocked();

    monitor->lock()->set_displaced_header(disp);
    if (Atomic::cmpxchg_ptr(monitor, lockee->mark_addr(), disp) != disp) {
      if (thread->is_lock_owned((address) disp->clear_lock_bits())) {
        monitor->lock()->set_displaced_header(NULL);
      }
      else {
        CALL_VM_NOCHECK(InterpreterRuntime::monitorenter(thread, monitor));
        if (HAS_PENDING_EXCEPTION)
          goto unwind_and_return;
      }
    }
  }

  // Get the signature handler
  InterpreterRuntime::SignatureHandler *handler; {
    address handlerAddr = method->signature_handler();
    if (handlerAddr == NULL) {
      CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method));
      if (HAS_PENDING_EXCEPTION)
        goto unlock_unwind_and_return;

      handlerAddr = method->signature_handler();
      assert(handlerAddr != NULL, "eh?");
    }
    if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) {
      CALL_VM_NOCHECK(handlerAddr =
        InterpreterRuntime::slow_signature_handler(thread, method, NULL,NULL));
      if (HAS_PENDING_EXCEPTION)
        goto unlock_unwind_and_return;
    }
    handler = \
      InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
  }

  // Get the native function entry point
  address function;
  function = method->native_function();
  assert(function != NULL, "should be set if signature handler is");

  // Build the argument list
  stack->overflow_check(handler->argument_count() * 2, THREAD);
  if (HAS_PENDING_EXCEPTION)
    goto unlock_unwind_and_return;

  void **arguments;
  void *mirror; {
    arguments =
      (void **) stack->alloc(handler->argument_count() * sizeof(void **));
    void **dst = arguments;

    void *env = thread->jni_environment();
    *(dst++) = &env;

    if (method->is_static()) {
      istate->set_oop_temp(
        method->constants()->pool_holder()->java_mirror());
      mirror = istate->oop_temp_addr();
      *(dst++) = &mirror;
    }

    intptr_t *src = locals;
    for (int i = dst - arguments; i < handler->argument_count(); i++) {
      ffi_type *type = handler->argument_type(i);
      if (type == &ffi_type_pointer) {
        if (*src) {
          stack->push((intptr_t) src);
          *(dst++) = stack->sp();
        }
        else {
          *(dst++) = src;
        }
        src--;
      }
      else if (type->size == 4) {
        *(dst++) = src--;
      }
      else if (type->size == 8) {
        src--;
        *(dst++) = src--;
      }
      else {
        ShouldNotReachHere();
      }
    }
  }

  // Set up the Java frame anchor
  thread->set_last_Java_frame();

  // Change the thread state to _thread_in_native
  ThreadStateTransition::transition_from_java(thread, _thread_in_native);

  // Make the call
  intptr_t result[4 - LogBytesPerWord];
  ffi_call(handler->cif(), (void (*)()) function, result, arguments);

  // Change the thread state back to _thread_in_Java.
  // ThreadStateTransition::transition_from_native() cannot be used
  // here because it does not check for asynchronous exceptions.
  // We have to manage the transition ourself.
  thread->set_thread_state(_thread_in_native_trans);

  // Make sure new state is visible in the GC thread
  if (os::is_MP()) {
    if (UseMembar) {
      OrderAccess::fence();
    }
    else {
      InterfaceSupport::serialize_memory(thread);
    }
  }

  // Handle safepoint operations, pending suspend requests,
  // and pending asynchronous exceptions.
  if (SafepointSynchronize::do_call_back() ||
      thread->has_special_condition_for_native_trans()) {
    JavaThread::check_special_condition_for_native_trans(thread);
    CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops());
  }

  // Finally we can change the thread state to _thread_in_Java.
  thread->set_thread_state(_thread_in_Java);
  fixup_after_potential_safepoint();

  // Clear the frame anchor
  thread->reset_last_Java_frame();

  // If the result was an oop then unbox it and store it in
  // oop_temp where the garbage collector can see it before
  // we release the handle it might be protected by.
  if (handler->result_type() == &ffi_type_pointer) {
    if (result[0])
      istate->set_oop_temp(*(oop *) result[0]);
    else
      istate->set_oop_temp(NULL);
  }

  // Reset handle block
  thread->active_handles()->clear();

 unlock_unwind_and_return:

  // Unlock if necessary
  if (monitor) {
    BasicLock *lock = monitor->lock();
    markOop header = lock->displaced_header();
    oop rcvr = monitor->obj();
    monitor->set_obj(NULL);

    if (header != NULL) {
      if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
        monitor->set_obj(rcvr); {
          HandleMark hm(thread);
          CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(thread, monitor));
        }
      }
    }
  }

 unwind_and_return:

  // Unwind the current activation
  thread->pop_zero_frame();

  // Pop our parameters
  stack->set_sp(stack->sp() + method->size_of_parameters());

  // Push our result
  if (!HAS_PENDING_EXCEPTION) {
    BasicType type = result_type_of(method);
    stack->set_sp(stack->sp() - type2size[type]);

    switch (type) {
    case T_VOID:
      break;

    case T_BOOLEAN:
#ifndef VM_LITTLE_ENDIAN
      result[0] <<= (BitsPerWord - BitsPerByte);
#endif
      SET_LOCALS_INT(*(jboolean *) result != 0, 0);
      break;

    case T_CHAR:
#ifndef VM_LITTLE_ENDIAN
      result[0] <<= (BitsPerWord - BitsPerShort);
#endif
      SET_LOCALS_INT(*(jchar *) result, 0);
      break;

    case T_BYTE:
#ifndef VM_LITTLE_ENDIAN
      result[0] <<= (BitsPerWord - BitsPerByte);
#endif
      SET_LOCALS_INT(*(jbyte *) result, 0);
      break;

    case T_SHORT:
#ifndef VM_LITTLE_ENDIAN
      result[0] <<= (BitsPerWord - BitsPerShort);
#endif
      SET_LOCALS_INT(*(jshort *) result, 0);
      break;

    case T_INT:
#ifndef VM_LITTLE_ENDIAN
      result[0] <<= (BitsPerWord - BitsPerInt);
#endif
      SET_LOCALS_INT(*(jint *) result, 0);
      break;

    case T_LONG:
      SET_LOCALS_LONG(*(jlong *) result, 0);
      break;

    case T_FLOAT:
      SET_LOCALS_FLOAT(*(jfloat *) result, 0);
      break;

    case T_DOUBLE:
      SET_LOCALS_DOUBLE(*(jdouble *) result, 0);
      break;

    case T_OBJECT:
    case T_ARRAY:
      SET_LOCALS_OBJECT(istate->oop_temp(), 0);
      break;

    default:
      ShouldNotReachHere();
    }
  }

  // No deoptimized frames on the stack
  return 0;
}