SirtRef<mirror::DexCache> dex_cache(self, mh.GetDexCache());
SirtRef<mirror::ClassLoader> class_loader(self, mh.GetClassLoader());
MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(),
- mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
+ mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
true);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
const RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range);
if (actual_arg_type.IsConflict()) { // GetInvocationThis failed.
- return NULL;
+ return nullptr;
} else if (actual_arg_type.IsZero()) { // Invoke on "null" instance: we can't go further.
- return NULL;
+ return nullptr;
}
mirror::Class* this_class = NULL;
if (!actual_arg_type.IsUnresolvedTypes()) {
this_class = actual_arg_type.GetClass();
} else {
const std::string& descriptor(actual_arg_type.GetDescriptor());
- // TODO: Precise or not?
- this_class = reg_types_.FromDescriptor(class_loader_->get(), descriptor.c_str(),
- false).GetClass();
+ // Try to resolve type.
+ const RegType& resolved_arg_type = reg_types_.FromDescriptor(class_loader_->get(),
+ descriptor.c_str(), false);
+ if (!resolved_arg_type.HasClass()) {
+ return nullptr; // Resolution failed.
+ }
+ this_class = resolved_arg_type.GetClass();
if (this_class == NULL) {
Thread* self = Thread::Current();
self->ClearException();
return klass;
}
-void RegTypeCache::ClearException() {
- if (can_load_classes_) {
- DCHECK(Thread::Current()->IsExceptionPending());
- Thread::Current()->ClearException();
- } else {
- DCHECK(!Thread::Current()->IsExceptionPending());
- }
-}
-
const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor,
bool precise) {
// Try looking up the class in the cache first.
} else { // Class not resolved.
// We tried loading the class and failed, this might get an exception raised
// so we want to clear it before we go on.
- ClearException();
+ if (can_load_classes_) {
+ DCHECK(Thread::Current()->IsExceptionPending());
+ Thread::Current()->ClearException();
+ } else {
+ DCHECK(!Thread::Current()->IsExceptionPending());
+ }
if (IsValidDescriptor(descriptor)) {
RegType* entry = new UnresolvedReferenceType(descriptor, entries_.size());
entries_.push_back(entry);
}
}
+RegTypeCache::RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
+ if (kIsDebugBuild && can_load_classes) {
+ Thread::Current()->AssertThreadSuspensionIsAllowable();
+ }
+ entries_.reserve(64);
+ FillPrimitiveAndSmallConstantTypes();
+}
+
RegTypeCache::~RegTypeCache() {
CHECK_LE(primitive_count_, entries_.size());
// Delete only the non primitive types.
class RegTypeCache {
public:
- explicit RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
- entries_.reserve(64);
- FillPrimitiveAndSmallConstantTypes();
- }
+ explicit RegTypeCache(bool can_load_classes);
~RegTypeCache();
static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (!RegTypeCache::primitive_initialized_) {
void FillPrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void ClearException();
bool MatchDescriptor(size_t idx, const char* descriptor, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const ConstantType& FromCat1NonSmallConstant(int32_t value, bool precise)