// mCookie is nulled out if the DexFile has been closed but mInternalCookie sticks around until
// the object is finalized. Since they always point to the same array if mCookie is not null we
// just use the mInternalCookie field. We will update one or both of these fields later.
- // TODO Should I get the class from the classloader or directly?
art::ArtField* internal_cookie_field = java_dex_file_obj->GetClass()->FindDeclaredInstanceField(
"mInternalCookie", "Ljava/lang/Object;");
// TODO Add check that mCookie is either null or same as mInternalCookie
return internal_cookie_field->GetObject(java_dex_file_obj.Get())->AsLongArray();
}
-// TODO Really wishing I had that mirror of java.lang.DexFile now.
art::ObjPtr<art::mirror::LongArray> ClassLoaderHelper::AllocateNewDexFileCookie(
art::Thread* self,
art::Handle<art::mirror::LongArray> cookie,
return nullptr;
}
// Copy the oat-dex field at the start.
- // TODO Should I clear this field?
- // TODO This is a really crappy thing here with the first element being different.
new_cookie->SetWithoutChecks<false>(0, cookie->GetWithoutChecks(0));
// This must match the casts in runtime/native/dalvik_system_DexFile.cc:ConvertDexFilesToJavaArray
new_cookie->SetWithoutChecks<false>(
// This makes cleanup easier (since we unambiguously own the bytes) and also is useful since we
// will need to keep the original bytes around unaltered for subsequent RetransformClasses calls
// to get the passed in bytes.
- // TODO Implement saving the original bytes.
unsigned char* class_bytes_copy = nullptr;
jvmtiError res = env->Allocate(definitions[i].class_byte_count, &class_bytes_copy);
if (res != OK) {
}
bool Redefiner::ClassRedefinition::CheckClass() {
- // TODO Might just want to put it in a ObjPtr and NoSuspend assert.
art::StackHandleScope<1> hs(driver_->self_);
// Easy check that only 1 class def is present.
if (dex_file_->NumClassDefs() != 1) {
return true;
}
-// TODO Move this to use IsRedefinable when that function is made.
bool Redefiner::ClassRedefinition::CheckRedefinable() {
std::string err;
art::StackHandleScope<1> hs(driver_->self_);
DISALLOW_COPY_AND_ASSIGN(RedefinitionDataHolder);
};
-// TODO Stash and update soft failure state
bool Redefiner::ClassRedefinition::CheckVerification(int32_t klass_index,
const RedefinitionDataHolder& holder) {
DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
ClassLoaderHelper::FindSourceDexFileObject(driver_->self_, loader)));
holder->SetJavaDexFile(klass_index, dex_file_obj.Get());
if (dex_file_obj == nullptr) {
- // TODO Better error msg.
RecordFailure(ERR(INTERNAL), "Unable to find dex file!");
return false;
}
self_->TransitionFromRunnableToSuspended(art::ThreadState::kNative);
runtime_->GetThreadList()->SuspendAll(
"Final installation of redefined Classes!", /*long_suspend*/true);
- // TODO We need to invalidate all breakpoints in the redefined class with the debugger.
- // TODO We need to deal with any instrumentation/debugger deoptimized_methods_.
- // TODO We need to update all debugger MethodIDs so they note the method they point to is
- // obsolete or implement some other well defined semantics.
- // TODO We need to decide on & implement semantics for JNI jmethodids when we redefine methods.
counter = 0;
for (Redefiner::ClassRedefinition& redef : redefinitions_) {
art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition");
}
const art::DexFile::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx,
new_type_list);
- // TODO Return false, cleanup.
CHECK(proto_id != nullptr || old_type_list == nullptr);
const art::DexFile::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
*new_name_id,
*proto_id);
- // TODO Return false, cleanup.
CHECK(method_id != nullptr);
uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
method.SetDexMethodIndex(dex_method_idx);
dex_file_->FindTypeId(field.GetDeclaringClass()->GetDescriptor(&declaring_class_name));
const art::DexFile::StringId* new_name_id = dex_file_->FindStringId(field.GetName());
const art::DexFile::TypeId* new_type_id = dex_file_->FindTypeId(field.GetTypeDescriptor());
- // TODO Handle error, cleanup.
CHECK(new_name_id != nullptr && new_type_id != nullptr && new_declaring_id != nullptr);
const art::DexFile::FieldId* new_field_id =
dex_file_->FindFieldId(*new_declaring_id, *new_name_id, *new_type_id);