bool Parse::push_constant(ciConstant constant, bool require_constant) {
  switch (constant.basic_type()) {
  case T_BOOLEAN:  push( intcon(constant.as_boolean()) ); break;
  case T_INT:      push( intcon(constant.as_int())     ); break;
  case T_CHAR:     push( intcon(constant.as_char())    ); break;
  case T_BYTE:     push( intcon(constant.as_byte())    ); break;
  case T_SHORT:    push( intcon(constant.as_short())   ); break;
  case T_FLOAT:    push( makecon(TypeF::make(constant.as_float())) );  break;
  case T_DOUBLE:   push_pair( makecon(TypeD::make(constant.as_double())) );  break;
  case T_LONG:     push_pair( longcon(constant.as_long()) ); break;
  case T_ARRAY:
  case T_OBJECT: {
    // cases:
    //   can_be_constant    = (oop not scavengable || ScavengeRootsInCode != 0)
    //   should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2)
    // An oop is not scavengable if it is in the perm gen.
    ciObject* oop_constant = constant.as_object();
    if (oop_constant->is_null_object()) {
      push( zerocon(T_OBJECT) );
      break;
    } else if (require_constant || oop_constant->should_be_constant()) {
      push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant)) );
      break;
    } else {
      // we cannot inline the oop, but we can use it later to narrow a type
      return false;
    }
  }
  case T_ILLEGAL: {
    // Invalid ciConstant returned due to OutOfMemoryError in the CI
    assert(C->env()->failing(), "otherwise should not see this");
    // These always occur because of object types; we are going to
    // bail out anyway, so make the stack depths match up
    push( zerocon(T_OBJECT) );
    return false;
  }
  default:
    ShouldNotReachHere();
    return false;
  }

  // success
  return true;
}
示例#2
0
SharkConstant::SharkConstant(ciConstant constant, ciType *type) {
  SharkValue *value = NULL;

  switch (constant.basic_type()) {
  case T_BOOLEAN:
  case T_BYTE:
  case T_CHAR:
  case T_SHORT:
  case T_INT:
    value = SharkValue::jint_constant(constant.as_int());
    break;

  case T_LONG:
    value = SharkValue::jlong_constant(constant.as_long());
    break;

  case T_FLOAT:
    value = SharkValue::jfloat_constant(constant.as_float());
    break;

  case T_DOUBLE:
    value = SharkValue::jdouble_constant(constant.as_double());
    break;

  case T_OBJECT:
  case T_ARRAY:
    break;

  case T_ILLEGAL:
    // out of memory
    _is_loaded = false;
    return;

  default:
    tty->print_cr("Unhandled type %s", type2name(constant.basic_type()));
    ShouldNotReachHere();
  }

  // Handle primitive types.  We create SharkValues for these
  // now; doing so doesn't emit any code, and it allows us to
  // delegate a bunch of stuff to the SharkValue code.
  if (value) {
    _value       = value;
    _is_loaded   = true;
    _is_nonzero  = value->zero_checked();
    _is_two_word = value->is_two_word();
    return;
  }

  // Handle reference types.  This is tricky because some
  // ciObjects are psuedo-objects that refer to oops which
  // have yet to be created.  We need to spot the unloaded
  // objects (which differ between ldc* and get*, thanks!)
  ciObject *object = constant.as_object();
  assert(type != NULL, "shouldn't be");
  if (object->is_klass()) {
    // The constant returned for a klass is the ciKlass
    // for the entry, but we want the java_mirror.
    ciKlass *klass = object->as_klass();
    if (!klass->is_loaded()) {
      _is_loaded = false;
      return;
    }
    object = klass->java_mirror();
  }
  if (object->is_null_object() || !object->can_be_constant()) {
    _is_loaded = false;
    return;
  }

  _value       = NULL;
  _object      = object;
  _type        = type;
  _is_loaded   = true;
  _is_nonzero  = true;
  _is_two_word = false;
}