static Location::Type location_type(SharkValue** addr, bool maybe_two_word) { // low addresses this end // Type 32-bit 64-bit // ---------------------------------------------------- // stack[0] local[3] jobject oop oop // stack[1] local[2] NULL normal lng // stack[2] local[1] jlong normal invalid // stack[3] local[0] jint normal normal // // high addresses this end SharkValue *value = *addr; if (value) { if (value->is_jobject()) return Location::oop; #ifdef _LP64 if (value->is_two_word()) return Location::invalid; #endif // _LP64 return Location::normal; } else { if (maybe_two_word) { value = *(addr - 1); if (value && value->is_two_word()) { #ifdef _LP64 if (value->is_jlong()) return Location::lng; if (value->is_jdouble()) return Location::dbl; ShouldNotReachHere(); #else return Location::normal; #endif // _LP64 } } return Location::invalid; } }
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; }