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; }
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; }