summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2013-09-19 02:56:49 -0700
committerIan Rogers <irogers@google.com>2013-09-19 15:17:12 -0700
commit8b2c0b9abc3f520495f4387ea040132ba85cae69 (patch)
tree13ea7e5c4e3d1804ec8d420d36f7ea5ab18f6ac0
parent5712d5d04640925970db9c98938ffaf806b3962c (diff)
downloadart-8b2c0b9abc3f520495f4387ea040132ba85cae69.tar.gz
art-8b2c0b9abc3f520495f4387ea040132ba85cae69.tar.bz2
art-8b2c0b9abc3f520495f4387ea040132ba85cae69.zip
Use class def index from java.lang.Class.
Bug: 10244719 Depends on: https://googleplex-android-review.git.corp.google.com/362363 This removes the computation of the dex file index, when necessary this is computed by searching the dex file. Its only necessary in dalvik.system.DexFile.defineClassNative and DexFile::FindInClassPath, the latter not showing up significantly in profiling with this change. Change-Id: I20c73a3b17d86286428ab0fd21bc13f51f36c85c
-rw-r--r--compiler/dex/compiler_ir.h2
-rw-r--r--compiler/dex/dex_to_dex_compiler.cc2
-rw-r--r--compiler/dex/frontend.cc6
-rw-r--r--compiler/dex/frontend.h2
-rw-r--r--compiler/dex/mir_graph.cc2
-rw-r--r--compiler/dex/mir_graph.h2
-rw-r--r--compiler/dex/quick/codegen_util.cc22
-rw-r--r--compiler/driver/compiler_driver.cc49
-rw-r--r--compiler/driver/compiler_driver.h27
-rw-r--r--compiler/driver/dex_compilation_unit.cc2
-rw-r--r--compiler/driver/dex_compilation_unit.h6
-rw-r--r--compiler/image_writer.cc1
-rw-r--r--compiler/llvm/compiler_llvm.cc4
-rw-r--r--compiler/sea_ir/frontend.cc6
-rw-r--r--compiler/sea_ir/ir/sea.cc4
-rw-r--r--compiler/sea_ir/ir/sea.h6
-rw-r--r--oatdump/oatdump.cc32
-rw-r--r--runtime/Android.mk1
-rw-r--r--runtime/class_linker.cc111
-rw-r--r--runtime/class_linker.h4
-rw-r--r--runtime/class_linker_test.cc12
-rw-r--r--runtime/dex_file.cc91
-rw-r--r--runtime/dex_file.h44
-rw-r--r--runtime/entrypoints/quick/quick_invoke_entrypoints.cc2
-rw-r--r--runtime/mirror/art_method-inl.h2
-rw-r--r--runtime/mirror/class.cc23
-rw-r--r--runtime/mirror/class.h31
-rw-r--r--runtime/mirror/dex_cache.h1
-rw-r--r--runtime/mirror/proxy.h3
-rw-r--r--runtime/mirror/string.h2
-rw-r--r--runtime/native/dalvik_system_DexFile.cc2
-rw-r--r--runtime/native/java_lang_Class.cc31
-rw-r--r--runtime/native/java_lang_DexCache.cc56
-rw-r--r--runtime/oat_file.cc2
-rw-r--r--runtime/oat_file.h2
-rw-r--r--runtime/object_utils.h87
-rw-r--r--runtime/runtime.cc5
-rw-r--r--runtime/thread.cc2
-rw-r--r--runtime/verifier/method_verifier.cc96
-rw-r--r--runtime/verifier/method_verifier.h19
-rw-r--r--runtime/verifier/method_verifier_test.cc3
-rw-r--r--test/100-reflect2/expected.txt2
42 files changed, 397 insertions, 412 deletions
diff --git a/compiler/dex/compiler_ir.h b/compiler/dex/compiler_ir.h
index 26d0923baa..6607562b13 100644
--- a/compiler/dex/compiler_ir.h
+++ b/compiler/dex/compiler_ir.h
@@ -77,7 +77,7 @@ struct CompilationUnit {
ClassLinker* class_linker; // Linker to resolve fields and methods.
const DexFile* dex_file; // DexFile containing the method being compiled.
jobject class_loader; // compiling method's class loader.
- uint32_t class_def_idx; // compiling method's defining class definition index.
+ uint16_t class_def_idx; // compiling method's defining class definition index.
uint32_t method_idx; // compiling method's index into method_ids of DexFile.
const DexFile::CodeItem* code_item; // compiling method's DexFile code_item.
uint32_t access_flags; // compiling method's access flags.
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index ffd7905dfe..abafbc5830 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -280,7 +280,7 @@ void DexCompiler::CompileInvokeVirtual(Instruction* inst,
extern "C" void ArtCompileDEX(art::CompilerDriver& compiler, const art::DexFile::CodeItem* code_item,
uint32_t access_flags, art::InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+ uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
const art::DexFile& dex_file,
art::DexToDexCompilationLevel dex_to_dex_compilation_level) {
if (dex_to_dex_compilation_level != art::kDontDexToDexCompile) {
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 23036495ce..fefcab9e87 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -110,7 +110,7 @@ static CompiledMethod* CompileMethod(CompilerDriver& compiler,
const CompilerBackend compiler_backend,
const DexFile::CodeItem* code_item,
uint32_t access_flags, InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx,
+ uint16_t class_def_idx, uint32_t method_idx,
jobject class_loader, const DexFile& dex_file
#if defined(ART_USE_PORTABLE_COMPILER)
, llvm::LlvmCompilationUnit* llvm_compilation_unit
@@ -273,7 +273,7 @@ CompiledMethod* CompileOneMethod(CompilerDriver& compiler,
const DexFile::CodeItem* code_item,
uint32_t access_flags,
InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const DexFile& dex_file,
@@ -292,7 +292,7 @@ extern "C" art::CompiledMethod*
ArtQuickCompileMethod(art::CompilerDriver& compiler,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags, art::InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+ uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
const art::DexFile& dex_file) {
// TODO: check method fingerprint here to determine appropriate backend type. Until then, use build default
art::CompilerBackend backend = compiler.GetCompilerBackend();
diff --git a/compiler/dex/frontend.h b/compiler/dex/frontend.h
index bafa46892c..6c33d109e3 100644
--- a/compiler/dex/frontend.h
+++ b/compiler/dex/frontend.h
@@ -117,7 +117,7 @@ extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
- uint32_t class_dex_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index c72283e689..c234298a88 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -504,7 +504,7 @@ BasicBlock* MIRGraph::ProcessCanThrow(BasicBlock* cur_block, MIR* insn, int cur_
/* Parse a Dex method and insert it into the MIRGraph at the current insert point. */
void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
- InvokeType invoke_type, uint32_t class_def_idx,
+ InvokeType invoke_type, uint16_t class_def_idx,
uint32_t method_idx, jobject class_loader, const DexFile& dex_file) {
current_code_item_ = code_item;
method_stack_.push_back(std::make_pair(current_method_, current_offset_));
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 0244daec9d..9d4ab98f67 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -357,7 +357,7 @@ class MIRGraph {
* actually the index of the method in the m_units_ array).
*/
void InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
- InvokeType invoke_type, uint32_t class_def_idx,
+ InvokeType invoke_type, uint16_t class_def_idx,
uint32_t method_idx, jobject class_loader, const DexFile& dex_file);
/* Find existing block */
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index f13ab2db01..4ce752fb39 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -385,11 +385,12 @@ void Mir2Lir::InstallLiteralPools() {
while (data_lir != NULL) {
uint32_t target = data_lir->operands[0];
cu_->compiler_driver->AddCodePatch(cu_->dex_file,
- cu_->method_idx,
- cu_->invoke_type,
- target,
- static_cast<InvokeType>(data_lir->operands[1]),
- code_buffer_.size());
+ cu_->class_def_idx,
+ cu_->method_idx,
+ cu_->invoke_type,
+ target,
+ static_cast<InvokeType>(data_lir->operands[1]),
+ code_buffer_.size());
const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
// unique based on target to ensure code deduplication works
uint32_t unique_patch_value = reinterpret_cast<uint32_t>(&id);
@@ -400,11 +401,12 @@ void Mir2Lir::InstallLiteralPools() {
while (data_lir != NULL) {
uint32_t target = data_lir->operands[0];
cu_->compiler_driver->AddMethodPatch(cu_->dex_file,
- cu_->method_idx,
- cu_->invoke_type,
- target,
- static_cast<InvokeType>(data_lir->operands[1]),
- code_buffer_.size());
+ cu_->class_def_idx,
+ cu_->method_idx,
+ cu_->invoke_type,
+ target,
+ static_cast<InvokeType>(data_lir->operands[1]),
+ code_buffer_.size());
const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
// unique based on target to ensure code deduplication works
uint32_t unique_patch_value = reinterpret_cast<uint32_t>(&id);
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 8d521de72f..658370f1fd 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -293,7 +293,7 @@ extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
@@ -301,7 +301,7 @@ extern "C" art::CompiledMethod* ArtQuickCompileMethod(art::CompilerDriver& compi
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
@@ -310,7 +310,7 @@ extern "C" art::CompiledMethod* ArtCompileDEX(art::CompilerDriver& compiler,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
@@ -319,7 +319,7 @@ extern "C" art::CompiledMethod* SeaIrCompileMethod(art::CompilerDriver& compiler
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
@@ -540,7 +540,7 @@ void CompilerDriver::CompileOne(const mirror::ArtMethod* method, base::TimingLog
Thread* self = Thread::Current();
jobject jclass_loader;
const DexFile* dex_file;
- uint32_t class_def_idx;
+ uint16_t class_def_idx;
{
ScopedObjectAccessUnchecked soa(self);
ScopedLocalRef<jobject>
@@ -1304,13 +1304,15 @@ bool CompilerDriver::IsSafeCast(const MethodReference& mr, uint32_t dex_pc) {
void CompilerDriver::AddCodePatch(const DexFile* dex_file,
- uint32_t referrer_method_idx,
- InvokeType referrer_invoke_type,
- uint32_t target_method_idx,
- InvokeType target_invoke_type,
- size_t literal_offset) {
+ uint16_t referrer_class_def_idx,
+ uint32_t referrer_method_idx,
+ InvokeType referrer_invoke_type,
+ uint32_t target_method_idx,
+ InvokeType target_invoke_type,
+ size_t literal_offset) {
MutexLock mu(Thread::Current(), compiled_methods_lock_);
code_to_patch_.push_back(new PatchInformation(dex_file,
+ referrer_class_def_idx,
referrer_method_idx,
referrer_invoke_type,
target_method_idx,
@@ -1318,13 +1320,15 @@ void CompilerDriver::AddCodePatch(const DexFile* dex_file,
literal_offset));
}
void CompilerDriver::AddMethodPatch(const DexFile* dex_file,
- uint32_t referrer_method_idx,
- InvokeType referrer_invoke_type,
- uint32_t target_method_idx,
- InvokeType target_invoke_type,
- size_t literal_offset) {
+ uint16_t referrer_class_def_idx,
+ uint32_t referrer_method_idx,
+ InvokeType referrer_invoke_type,
+ uint32_t target_method_idx,
+ InvokeType target_invoke_type,
+ size_t literal_offset) {
MutexLock mu(Thread::Current(), compiled_methods_lock_);
methods_to_patch_.push_back(new PatchInformation(dex_file,
+ referrer_class_def_idx,
referrer_method_idx,
referrer_invoke_type,
target_method_idx,
@@ -1625,10 +1629,12 @@ static void VerifyClass(const ParallelCompilationManager* manager, size_t class_
*/
mirror::DexCache* dex_cache = manager->GetClassLinker()->FindDexCache(*manager->GetDexFile());
std::string error_msg;
- if (verifier::MethodVerifier::VerifyClass(manager->GetDexFile(),
+ const DexFile* dex_file = manager->GetDexFile();
+ const DexFile::ClassDef* class_def = &dex_file->GetClassDef(class_def_index);
+ if (verifier::MethodVerifier::VerifyClass(dex_file,
dex_cache,
soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()),
- class_def_index, error_msg, true) ==
+ class_def, true, &error_msg) ==
verifier::MethodVerifier::kHardFailure) {
const DexFile::ClassDef& class_def = manager->GetDexFile()->GetClassDef(class_def_index);
LOG(ERROR) << "Verification failed on class "
@@ -2137,7 +2143,8 @@ static void InitializeClass(const ParallelCompilationManager* manager, size_t cl
}
// If successfully initialized place in SSB array.
if (klass->IsInitialized()) {
- klass->GetDexCache()->GetInitializedStaticStorage()->Set(klass->GetDexTypeIndex(), klass);
+ int32_t ssb_index = klass->GetDexTypeIndex();
+ klass->GetDexCache()->GetInitializedStaticStorage()->Set(ssb_index, klass);
}
}
// Record the final class status if necessary.
@@ -2264,7 +2271,7 @@ void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_fil
}
void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
- InvokeType invoke_type, uint32_t class_def_idx,
+ InvokeType invoke_type, uint16_t class_def_idx,
uint32_t method_idx, jobject class_loader,
const DexFile& dex_file,
DexToDexCompilationLevel dex_to_dex_compilation_level) {
@@ -2387,13 +2394,13 @@ void CompilerDriver::SetBitcodeFileName(std::string const& filename) {
void CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
- size_t class_def_index) {
+ uint16_t class_def_index) {
WriterMutexLock mu(self, freezing_constructor_lock_);
freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
}
bool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
- size_t class_def_index) {
+ uint16_t class_def_index) {
ReaderMutexLock mu(self, freezing_constructor_lock_);
return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
}
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index b4ec0c134b..66c9cbf91a 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -145,8 +145,9 @@ class CompilerDriver {
CompiledMethod* GetCompiledMethod(MethodReference ref) const
LOCKS_EXCLUDED(compiled_methods_lock_);
- void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, size_t class_def_index);
- bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, size_t class_def_index);
+ void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
+ uint16_t class_def_index);
+ bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, uint16_t class_def_index);
// Callbacks from compiler to see what runtime checks must be generated.
@@ -192,6 +193,7 @@ class CompilerDriver {
// Record patch information for later fix up.
void AddCodePatch(const DexFile* dex_file,
+ uint16_t referrer_class_def_idx,
uint32_t referrer_method_idx,
InvokeType referrer_invoke_type,
uint32_t target_method_idx,
@@ -199,6 +201,7 @@ class CompilerDriver {
size_t literal_offset)
LOCKS_EXCLUDED(compiled_methods_lock_);
void AddMethodPatch(const DexFile* dex_file,
+ uint16_t referrer_class_def_idx,
uint32_t referrer_method_idx,
InvokeType referrer_invoke_type,
uint32_t target_method_idx,
@@ -249,6 +252,9 @@ class CompilerDriver {
const DexFile& GetDexFile() const {
return *dex_file_;
}
+ uint16_t GetReferrerClassDefIdx() const {
+ return referrer_class_def_idx_;
+ }
uint32_t GetReferrerMethodIdx() const {
return referrer_method_idx_;
}
@@ -267,12 +273,14 @@ class CompilerDriver {
private:
PatchInformation(const DexFile* dex_file,
+ uint16_t referrer_class_def_idx,
uint32_t referrer_method_idx,
InvokeType referrer_invoke_type,
uint32_t target_method_idx,
InvokeType target_invoke_type,
size_t literal_offset)
: dex_file_(dex_file),
+ referrer_class_def_idx_(referrer_class_def_idx),
referrer_method_idx_(referrer_method_idx),
referrer_invoke_type_(referrer_invoke_type),
target_method_idx_(target_method_idx),
@@ -281,12 +289,13 @@ class CompilerDriver {
CHECK(dex_file_ != NULL);
}
- const DexFile* dex_file_;
- uint32_t referrer_method_idx_;
- InvokeType referrer_invoke_type_;
- uint32_t target_method_idx_;
- InvokeType target_invoke_type_;
- size_t literal_offset_;
+ const DexFile* const dex_file_;
+ const uint16_t referrer_class_def_idx_;
+ const uint32_t referrer_method_idx_;
+ const InvokeType referrer_invoke_type_;
+ const uint32_t target_method_idx_;
+ const InvokeType target_invoke_type_;
+ const size_t literal_offset_;
friend class CompilerDriver;
DISALLOW_COPY_AND_ASSIGN(PatchInformation);
@@ -358,7 +367,7 @@ class CompilerDriver {
ThreadPool& thread_pool, base::TimingLogger& timings)
LOCKS_EXCLUDED(Locks::mutator_lock_);
void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
- InvokeType invoke_type, uint32_t class_def_idx, uint32_t method_idx,
+ InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx,
jobject class_loader, const DexFile& dex_file,
DexToDexCompilationLevel dex_to_dex_compilation_level)
LOCKS_EXCLUDED(compiled_methods_lock_);
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index eb8941b15f..c441d09ab2 100644
--- a/compiler/driver/dex_compilation_unit.cc
+++ b/compiler/driver/dex_compilation_unit.cc
@@ -39,7 +39,7 @@ DexCompilationUnit::DexCompilationUnit(CompilationUnit* cu,
ClassLinker* class_linker,
const DexFile& dex_file,
const DexFile::CodeItem* code_item,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
uint32_t access_flags)
: cu_(cu),
diff --git a/compiler/driver/dex_compilation_unit.h b/compiler/driver/dex_compilation_unit.h
index 465139b34f..3df50ffec6 100644
--- a/compiler/driver/dex_compilation_unit.h
+++ b/compiler/driver/dex_compilation_unit.h
@@ -36,7 +36,7 @@ class DexCompilationUnit {
DexCompilationUnit(CompilationUnit* cu, jobject class_loader, ClassLinker* class_linker,
const DexFile& dex_file, const DexFile::CodeItem* code_item,
- uint32_t class_def_idx, uint32_t method_idx, uint32_t access_flags);
+ uint16_t class_def_idx, uint32_t method_idx, uint32_t access_flags);
CompilationUnit* GetCompilationUnit() const {
return cu_;
@@ -54,7 +54,7 @@ class DexCompilationUnit {
return dex_file_;
}
- uint32_t GetClassDefIndex() const {
+ uint16_t GetClassDefIndex() const {
return class_def_idx_;
}
@@ -108,7 +108,7 @@ class DexCompilationUnit {
const DexFile* const dex_file_;
const DexFile::CodeItem* const code_item_;
- const uint32_t class_def_idx_;
+ const uint16_t class_def_idx_;
const uint32_t dex_method_idx_;
const uint32_t access_flags_;
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index d1859e6f98..f82c6fb40f 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -699,6 +699,7 @@ void ImageWriter::PatchOatCodeAndMethods() {
void ImageWriter::SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
const void* oat_code = class_linker->GetOatCodeFor(patch->GetDexFile(),
+ patch->GetReferrerClassDefIdx(),
patch->GetReferrerMethodIdx());
OatHeader& oat_header = const_cast<OatHeader&>(oat_file_->GetOatHeader());
// TODO: make this Thumb2 specific
diff --git a/compiler/llvm/compiler_llvm.cc b/compiler/llvm/compiler_llvm.cc
index 0df3c476fc..d59afd48b7 100644
--- a/compiler/llvm/compiler_llvm.cc
+++ b/compiler/llvm/compiler_llvm.cc
@@ -40,7 +40,7 @@ void CompileOneMethod(CompilerDriver& driver,
const CompilerBackend compilerBackend,
const DexFile::CodeItem* code_item,
uint32_t access_flags, InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+ uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
const DexFile& dex_file,
llvm::LlvmCompilationUnit* llvm_info);
}
@@ -203,7 +203,7 @@ extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file) {
diff --git a/compiler/sea_ir/frontend.cc b/compiler/sea_ir/frontend.cc
index 93f6f25461..3512911f43 100644
--- a/compiler/sea_ir/frontend.cc
+++ b/compiler/sea_ir/frontend.cc
@@ -41,7 +41,7 @@ static CompiledMethod* CompileMethodWithSeaIr(CompilerDriver& compiler,
const CompilerBackend compiler_backend,
const DexFile::CodeItem* code_item,
uint32_t method_access_flags, InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx,
+ uint16_t class_def_idx, uint32_t method_idx,
jobject class_loader, const DexFile& dex_file
#if defined(ART_USE_PORTABLE_COMPILER)
, llvm::LlvmCompilationUnit* llvm_compilation_unit
@@ -69,7 +69,7 @@ CompiledMethod* SeaIrCompileOneMethod(CompilerDriver& compiler,
const DexFile::CodeItem* code_item,
uint32_t method_access_flags,
InvokeType invoke_type,
- uint32_t class_def_idx,
+ uint16_t class_def_idx,
uint32_t method_idx,
jobject class_loader,
const DexFile& dex_file,
@@ -86,7 +86,7 @@ extern "C" art::CompiledMethod*
SeaIrCompileMethod(art::CompilerDriver& compiler,
const art::DexFile::CodeItem* code_item,
uint32_t method_access_flags, art::InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+ uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
const art::DexFile& dex_file) {
// TODO: Check method fingerprint here to determine appropriate backend type.
// Until then, use build default
diff --git a/compiler/sea_ir/ir/sea.cc b/compiler/sea_ir/ir/sea.cc
index 5ccaba6ad9..0734b21f12 100644
--- a/compiler/sea_ir/ir/sea.cc
+++ b/compiler/sea_ir/ir/sea.cc
@@ -191,7 +191,7 @@ void SeaGraph::InsertSignatureNodes(const art::DexFile::CodeItem* code_item, Reg
}
void SeaGraph::BuildMethodSeaGraph(const art::DexFile::CodeItem* code_item,
- const art::DexFile& dex_file, uint32_t class_def_idx,
+ const art::DexFile& dex_file, uint16_t class_def_idx,
uint32_t method_idx, uint32_t method_access_flags) {
code_item_ = code_item;
class_def_idx_ = class_def_idx;
@@ -409,7 +409,7 @@ CodeGenData* SeaGraph::GenerateLLVM(const std::string& function_name,
CodeGenData* SeaGraph::CompileMethod(
const std::string& function_name,
- const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+ const art::DexFile::CodeItem* code_item, uint16_t class_def_idx,
uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file) {
// Two passes: Builds the intermediate structure (non-SSA) of the sea-ir for the function.
BuildMethodSeaGraph(code_item, dex_file, class_def_idx, method_idx, method_access_flags);
diff --git a/compiler/sea_ir/ir/sea.h b/compiler/sea_ir/ir/sea.h
index 92c2043dbd..26b16be019 100644
--- a/compiler/sea_ir/ir/sea.h
+++ b/compiler/sea_ir/ir/sea.h
@@ -262,7 +262,7 @@ class SeaGraph: IVisitable {
static SeaGraph* GetGraph(const art::DexFile&);
CodeGenData* CompileMethod(const std::string& function_name,
- const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+ const art::DexFile::CodeItem* code_item, uint16_t class_def_idx,
uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file);
// Returns all regions corresponding to this SeaGraph.
std::vector<Region*>* GetRegions() {
@@ -288,7 +288,7 @@ class SeaGraph: IVisitable {
}
TypeInference* ti_;
- uint32_t class_def_idx_;
+ uint16_t class_def_idx_;
uint32_t method_idx_;
uint32_t method_access_flags_;
@@ -311,7 +311,7 @@ class SeaGraph: IVisitable {
// Builds the non-SSA sea-ir representation of the function @code_item from @dex_file
// with class id @class_def_idx and method id @method_idx.
void BuildMethodSeaGraph(const art::DexFile::CodeItem* code_item,
- const art::DexFile& dex_file, uint32_t class_def_idx,
+ const art::DexFile& dex_file, uint16_t class_def_idx,
uint32_t method_idx, uint32_t method_access_flags);
// Computes immediate dominators for each region.
// Precondition: ComputeMethodSeaGraph()
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index cf1b6af809..fc9e00c2cb 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -176,9 +176,10 @@ class OatDumper {
CHECK(oat_dex_file != NULL);
UniquePtr<const DexFile> dex_file(oat_dex_file->OpenDexFile());
if (dex_file.get() != NULL) {
- uint32_t class_def_index;
- bool found = dex_file->FindClassDefIndex(mh.GetDeclaringClassDescriptor(), class_def_index);
- if (found) {
+ const DexFile::ClassDef* class_def =
+ dex_file->FindClassDef(mh.GetDeclaringClassDescriptor());
+ if (class_def != NULL) {
+ uint16_t class_def_index = dex_file->GetIndexForClassDef(*class_def);
const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_index);
CHECK(oat_class != NULL);
size_t method_index = m->GetMethodIndex();
@@ -284,18 +285,17 @@ class OatDumper {
}
ClassDataItemIterator it(dex_file, class_data);
SkipAllFields(it);
- uint32_t class_def_idx = dex_file.GetIndexForClassDef(class_def);
uint32_t class_method_idx = 0;
while (it.HasNextDirectMethod()) {
const OatFile::OatMethod oat_method = oat_class.GetOatMethod(class_method_idx);
- DumpOatMethod(os, class_def_idx, class_method_idx, oat_method, dex_file,
+ DumpOatMethod(os, class_def, class_method_idx, oat_method, dex_file,
it.GetMemberIndex(), it.GetMethodCodeItem(), it.GetMemberAccessFlags());
class_method_idx++;
it.Next();
}
while (it.HasNextVirtualMethod()) {
const OatFile::OatMethod oat_method = oat_class.GetOatMethod(class_method_idx);
- DumpOatMethod(os, class_def_idx, class_method_idx, oat_method, dex_file,
+ DumpOatMethod(os, class_def, class_method_idx, oat_method, dex_file,
it.GetMemberIndex(), it.GetMethodCodeItem(), it.GetMemberAccessFlags());
class_method_idx++;
it.Next();
@@ -304,7 +304,8 @@ class OatDumper {
os << std::flush;
}
- void DumpOatMethod(std::ostream& os, uint32_t class_def_idx, uint32_t class_method_index,
+ void DumpOatMethod(std::ostream& os, const DexFile::ClassDef& class_def,
+ uint32_t class_method_index,
const OatFile::OatMethod& oat_method, const DexFile& dex_file,
uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
uint32_t method_access_flags) {
@@ -323,7 +324,8 @@ class OatDumper {
indent1_os << "VERIFIER TYPE ANALYSIS:\n";
Indenter indent2_filter(indent1_os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indent2_os(&indent2_filter);
- DumpVerifier(indent2_os, dex_method_idx, &dex_file, class_def_idx, code_item, method_access_flags);
+ DumpVerifier(indent2_os, dex_method_idx, &dex_file, class_def, code_item,
+ method_access_flags);
}
{
indent1_os << "OAT DATA:\n";
@@ -363,7 +365,7 @@ class OatDumper {
oat_method.GetCode() != NULL ? "..." : "");
Indenter indent2_filter(indent1_os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indent2_os(&indent2_filter);
- DumpCode(indent2_os, oat_method, dex_method_idx, &dex_file, class_def_idx, code_item,
+ DumpCode(indent2_os, oat_method, dex_method_idx, &dex_file, class_def, code_item,
method_access_flags);
}
}
@@ -554,7 +556,7 @@ class OatDumper {
void DumpVRegsAtDexPc(std::ostream& os, const OatFile::OatMethod& oat_method,
uint32_t dex_method_idx, const DexFile* dex_file,
- uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+ const DexFile::ClassDef& class_def, const DexFile::CodeItem* code_item,
uint32_t method_access_flags, uint32_t dex_pc) {
static UniquePtr<verifier::MethodVerifier> verifier;
static const DexFile* verified_dex_file = NULL;
@@ -563,7 +565,7 @@ class OatDumper {
ScopedObjectAccess soa(Thread::Current());
mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
mirror::ClassLoader* class_loader = NULL;
- verifier.reset(new verifier::MethodVerifier(dex_file, dex_cache, class_loader, class_def_idx,
+ verifier.reset(new verifier::MethodVerifier(dex_file, dex_cache, class_loader, &class_def,
code_item, dex_method_idx, NULL,
method_access_flags, true, true));
verifier->Verify();
@@ -615,21 +617,21 @@ class OatDumper {
}
void DumpVerifier(std::ostream& os, uint32_t dex_method_idx, const DexFile* dex_file,
- uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+ const DexFile::ClassDef& class_def, const DexFile::CodeItem* code_item,
uint32_t method_access_flags) {
if ((method_access_flags & kAccNative) == 0) {
ScopedObjectAccess soa(Thread::Current());
mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
mirror::ClassLoader* class_loader = NULL;
verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache,
- class_loader, class_def_idx, code_item, NULL,
+ class_loader, &class_def, code_item, NULL,
method_access_flags);
}
}
void DumpCode(std::ostream& os, const OatFile::OatMethod& oat_method,
uint32_t dex_method_idx, const DexFile* dex_file,
- uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+ const DexFile::ClassDef& class_def, const DexFile::CodeItem* code_item,
uint32_t method_access_flags) {
const void* code = oat_method.GetCode();
size_t code_size = oat_method.GetCodeSize();
@@ -647,7 +649,7 @@ class OatDumper {
if (dex_pc != DexFile::kDexNoIndex) {
DumpGcMapAtNativePcOffset(os, oat_method, code_item, offset);
if (kDumpVRegs) {
- DumpVRegsAtDexPc(os, oat_method, dex_method_idx, dex_file, class_def_idx, code_item,
+ DumpVRegsAtDexPc(os, oat_method, dex_method_idx, dex_file, class_def, code_item,
method_access_flags, dex_pc);
}
}
diff --git a/runtime/Android.mk b/runtime/Android.mk
index e324060ecb..5edf7592d9 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -91,6 +91,7 @@ LIBART_COMMON_SRC_FILES := \
native/dalvik_system_VMStack.cc \
native/dalvik_system_Zygote.cc \
native/java_lang_Class.cc \
+ native/java_lang_DexCache.cc \
native/java_lang_Object.cc \
native/java_lang_Runtime.cc \
native/java_lang_String.cc \
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c19f8724bb..15eab9d165 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -475,40 +475,33 @@ void ClassLinker::FinishInit() {
// as the types of the field can't be resolved prior to the runtime being
// fully initialized
mirror::Class* java_lang_ref_Reference = GetClassRoot(kJavaLangRefReference);
- mirror::Class* java_lang_ref_ReferenceQueue = FindSystemClass("Ljava/lang/ref/ReferenceQueue;");
- mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
-
- const DexFile& java_lang_dex = *java_lang_ref_Reference->GetDexCache()->GetDexFile();
+ mirror::Class* java_lang_ref_FinalizerReference =
+ FindSystemClass("Ljava/lang/ref/FinalizerReference;");
mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
FieldHelper fh(pendingNext, this);
CHECK_STREQ(fh.GetName(), "pendingNext");
- CHECK_EQ(java_lang_dex.GetFieldId(pendingNext->GetDexFieldIndex()).type_idx_,
- java_lang_ref_Reference->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
mirror::ArtField* queue = java_lang_ref_Reference->GetInstanceField(1);
fh.ChangeField(queue);
CHECK_STREQ(fh.GetName(), "queue");
- CHECK_EQ(java_lang_dex.GetFieldId(queue->GetDexFieldIndex()).type_idx_,
- java_lang_ref_ReferenceQueue->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;");
mirror::ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2);
fh.ChangeField(queueNext);
CHECK_STREQ(fh.GetName(), "queueNext");
- CHECK_EQ(java_lang_dex.GetFieldId(queueNext->GetDexFieldIndex()).type_idx_,
- java_lang_ref_Reference->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
mirror::ArtField* referent = java_lang_ref_Reference->GetInstanceField(3);
fh.ChangeField(referent);
CHECK_STREQ(fh.GetName(), "referent");
- CHECK_EQ(java_lang_dex.GetFieldId(referent->GetDexFieldIndex()).type_idx_,
- GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;");
mirror::ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
fh.ChangeField(zombie);
CHECK_STREQ(fh.GetName(), "zombie");
- CHECK_EQ(java_lang_dex.GetFieldId(zombie->GetDexFieldIndex()).type_idx_,
- GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;");
gc::Heap* heap = Runtime::Current()->GetHeap();
heap->SetReferenceOffsets(referent->GetOffset(),
@@ -1234,8 +1227,10 @@ mirror::Class* ClassLinker::AllocClass(Thread* self, mirror::Class* java_lang_Cl
return NULL;
}
mirror::Class* klass = k->AsClass();
- klass->SetPrimitiveType(Primitive::kPrimNot); // default to not being primitive
+ klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive.
klass->SetClassSize(class_size);
+ klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index.
+ klass->SetDexTypeIndex(DexFile::kDexNoIndex16); // Default to no valid type index.
return klass;
}
@@ -1499,26 +1494,21 @@ size_t ClassLinker::SizeOfClass(const DexFile& dex_file,
return size;
}
-const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, const char* descriptor) {
- DCHECK(descriptor != NULL);
+const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, uint16_t class_def_idx) {
+ DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
- CHECK(oat_file != NULL) << dex_file.GetLocation() << " " << descriptor;
+ CHECK(oat_file != NULL) << dex_file.GetLocation();
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
- CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << descriptor;
- uint32_t class_def_index;
- bool found = dex_file.FindClassDefIndex(descriptor, class_def_index);
- CHECK(found) << dex_file.GetLocation() << " " << descriptor;
- const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_index);
- CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << descriptor;
+ CHECK(oat_dex_file != NULL) << dex_file.GetLocation();
+ const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_idx);
+ CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << class_def_idx;
return oat_class;
}
-static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint32_t method_idx) {
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
- const DexFile::TypeId& type_id = dex_file.GetTypeId(method_id.class_idx_);
- const DexFile::ClassDef* class_def = dex_file.FindClassDef(dex_file.GetTypeDescriptor(type_id));
- CHECK(class_def != NULL);
- const byte* class_data = dex_file.GetClassData(*class_def);
+static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint16_t class_def_idx,
+ uint32_t method_idx) {
+ const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
+ const byte* class_data = dex_file.GetClassData(class_def);
CHECK(class_data != NULL);
ClassDataItemIterator it(dex_file, class_data);
// Skip fields
@@ -1572,11 +1562,13 @@ const OatFile::OatMethod ClassLinker::GetOatMethodFor(const mirror::ArtMethod* m
}
CHECK(found) << "Didn't find oat method index for virtual method: " << PrettyMethod(method);
}
- ClassHelper kh(declaring_class);
- UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(kh.GetDexFile(), kh.GetDescriptor()));
+ UniquePtr<const OatFile::OatClass>
+ oat_class(GetOatClass(*declaring_class->GetDexCache()->GetDexFile(),
+ declaring_class->GetDexClassDefIndex()));
CHECK(oat_class.get() != NULL);
DCHECK_EQ(oat_method_index,
GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
+ method->GetDeclaringClass()->GetDexClassDefIndex(),
method->GetDexMethodIndex()));
return oat_class->GetOatMethod(oat_method_index);
@@ -1600,12 +1592,11 @@ const void* ClassLinker::GetOatCodeFor(const mirror::ArtMethod* method) {
return result;
}
-const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx) {
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
- const char* descriptor = dex_file.GetTypeDescriptor(dex_file.GetTypeId(method_id.class_idx_));
- uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, method_idx);
- UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, descriptor));
- CHECK(oat_class.get() != NULL);
+const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
+ uint32_t method_idx) {
+ UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, class_def_idx));
+ CHECK(oat_class.get() != nullptr);
+ uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, class_def_idx, method_idx);
return oat_class->GetOatMethod(oat_method_idx).GetCode();
}
@@ -1642,7 +1633,7 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) {
// OAT file unavailable
return;
}
- UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, kh.GetDescriptor()));
+ UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
CHECK(oat_class.get() != NULL);
ClassDataItemIterator it(dex_file, class_data);
// Skip fields
@@ -1734,6 +1725,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file,
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
klass->SetStatus(mirror::Class::kStatusIdx, NULL);
+ klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
klass->SetDexTypeIndex(dex_class_def.class_idx_);
// Load fields fields.
@@ -1781,7 +1773,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file,
UniquePtr<const OatFile::OatClass> oat_class;
if (Runtime::Current()->IsStarted() && !Runtime::Current()->UseCompileTimeClassPath()) {
- oat_class.reset(GetOatClass(dex_file, descriptor));
+ oat_class.reset(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
}
// Load methods.
@@ -1876,7 +1868,8 @@ mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file
if (klass->GetClassLoader() != NULL) { // All non-boot finalizer methods are flagged
klass->SetFinalizable();
} else {
- StringPiece klass_descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
+ ClassHelper kh(klass.get());
+ StringPiece klass_descriptor(kh.GetDescriptor());
// The Enum class declares a "final" finalize() method to prevent subclasses from
// introducing a finalizer. We don't want to set the finalizable flag for Enum or its
// subclasses, so we exclude it here.
@@ -2342,12 +2335,16 @@ mirror::Class* ClassLinker::LookupClassFromImage(const char* descriptor) {
const DexFile* dex_file = dex_cache->GetDexFile();
// First search using the class def map, but don't bother for non-class types.
if (descriptor[0] == 'L') {
- const DexFile::ClassDef* class_def = dex_file->FindClassDef(descriptor);
- if (class_def != NULL) {
- mirror::Class* klass = dex_cache->GetResolvedType(class_def->class_idx_);
- if (klass != NULL) {
- self->EndAssertNoThreadSuspension(old_no_suspend_cause);
- return klass;
+ const DexFile::StringId* descriptor_string_id = dex_file->FindStringId(descriptor);
+ if (descriptor_string_id != NULL) {
+ const DexFile::TypeId* type_id =
+ dex_file->FindTypeId(dex_file->GetIndexForStringId(*descriptor_string_id));
+ if (type_id != NULL) {
+ mirror::Class* klass = dex_cache->GetResolvedType(dex_file->GetIndexForTypeId(*type_id));
+ if (klass != NULL) {
+ self->EndAssertNoThreadSuspension(old_no_suspend_cause);
+ return klass;
+ }
}
}
}
@@ -2458,8 +2455,9 @@ void ClassLinker::VerifyClass(mirror::Class* klass) {
verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
std::string error_msg;
if (!preverified) {
- verifier_failure = verifier::MethodVerifier::VerifyClass(klass, error_msg,
- Runtime::Current()->IsCompiler());
+ verifier_failure = verifier::MethodVerifier::VerifyClass(klass,
+ Runtime::Current()->IsCompiler(),
+ &error_msg);
}
if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) {
if (!preverified && verifier_failure != verifier::MethodVerifier::kNoFailure) {
@@ -2530,7 +2528,6 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class
}
}
-
const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
// Make this work with gtests, which do not set up the image properly.
// TODO: we should clean up gtests to set up the image path properly.
@@ -2542,9 +2539,7 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass);
const char* descriptor = ClassHelper(klass).GetDescriptor();
- uint32_t class_def_index;
- bool found = dex_file.FindClassDefIndex(descriptor, class_def_index);
- CHECK(found) << dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
+ uint16_t class_def_index = klass->GetDexClassDefIndex();
UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(class_def_index));
CHECK(oat_class.get() != NULL)
<< dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
@@ -2657,8 +2652,6 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
klass->SetStatus(mirror::Class::kStatusIdx, self);
- klass->SetDexTypeIndex(DexFile::kDexNoIndex16);
-
// Instance fields are inherited, but we add a couple of static fields...
{
mirror::ObjectArray<mirror::ArtField>* sfields = AllocArtFieldArray(self, 2);
@@ -3265,10 +3258,8 @@ bool ClassLinker::LinkClass(SirtRef<mirror::Class>& klass,
bool ClassLinker::LoadSuperAndInterfaces(SirtRef<mirror::Class>& klass, const DexFile& dex_file) {
CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus());
- StringPiece descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
- const DexFile::ClassDef* class_def = dex_file.FindClassDef(descriptor);
- CHECK(class_def != NULL);
- uint16_t super_class_idx = class_def->superclass_idx_;
+ const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex());
+ uint16_t super_class_idx = class_def.superclass_idx_;
if (super_class_idx != DexFile::kDexNoIndex16) {
mirror::Class* super_class = ResolveType(dex_file, super_class_idx, klass.get());
if (super_class == NULL) {
@@ -3284,7 +3275,7 @@ bool ClassLinker::LoadSuperAndInterfaces(SirtRef<mirror::Class>& klass, const De
}
klass->SetSuperClass(super_class);
}
- const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(*class_def);
+ const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(class_def);
if (interfaces != NULL) {
for (size_t i = 0; i < interfaces->Size(); i++) {
uint16_t idx = interfaces->GetTypeItem(i).type_idx_;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 20efbb43a9..3ffcf14447 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -329,7 +329,7 @@ class ClassLinker {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get the oat code for a method from a method index.
- const void* GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx)
+ const void* GetOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
pid_t GetClassesLockOwner(); // For SignalCatcher.
@@ -424,7 +424,7 @@ class ClassLinker {
void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds the associated oat class for a dex_file and descriptor
- const OatFile::OatClass* GetOatClass(const DexFile& dex_file, const char* descriptor)
+ const OatFile::OatClass* GetOatClass(const DexFile& dex_file, uint16_t class_def_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 0fa0ffbc56..bea1139679 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -508,6 +508,7 @@ struct ClassOffsets : public CheckOffsets<mirror::Class> {
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, access_flags_), "accessFlags"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, class_size_), "classSize"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, clinit_thread_id_), "clinitThreadId"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, dex_class_def_idx_), "dexClassDefIndex"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, dex_type_idx_), "dexTypeIndex"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_instance_fields_), "numReferenceInstanceFields"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_static_fields_), "numReferenceStaticFields"));
@@ -570,10 +571,6 @@ struct ProxyOffsets : public CheckOffsets<mirror::Proxy> {
struct ClassClassOffsets : public CheckOffsets<mirror::ClassClass> {
ClassClassOffsets() : CheckOffsets<mirror::ClassClass>(true, "Ljava/lang/Class;") {
- // padding 32-bit
- CHECK_EQ(OFFSETOF_MEMBER(mirror::ClassClass, padding_) + 4,
- OFFSETOF_MEMBER(mirror::ClassClass, serialVersionUID_));
-
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ClassClass, serialVersionUID_), "serialVersionUID"));
};
@@ -585,11 +582,11 @@ struct StringClassOffsets : public CheckOffsets<mirror::StringClass> {
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, ASCII_), "ASCII"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, CASE_INSENSITIVE_ORDER_), "CASE_INSENSITIVE_ORDER"));
- // padding 32-bit
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, REPLACEMENT_CHAR_), "REPLACEMENT_CHAR"));
-
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, serialVersionUID_), "serialVersionUID"));
+
+ // alphabetical 32-bit
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, REPLACEMENT_CHAR_), "REPLACEMENT_CHAR"));
};
};
@@ -606,6 +603,7 @@ struct ArtMethodClassOffsets : public CheckOffsets<mirror::ArtMethodClass> {
struct DexCacheOffsets : public CheckOffsets<mirror::DexCache> {
DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") {
// alphabetical references
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_), "dex"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, initialized_static_storage_), "initializedStaticStorage"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, location_), "location"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_fields_), "resolvedFields"));
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 4fd9a608c1..e81c456ccf 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -48,7 +48,7 @@ namespace art {
const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
-DexFile::ClassPathEntry DexFile::FindInClassPath(const StringPiece& descriptor,
+DexFile::ClassPathEntry DexFile::FindInClassPath(const char* descriptor,
const ClassPath& class_path) {
for (size_t i = 0; i != class_path.size(); ++i) {
const DexFile* dex_file = class_path[i];
@@ -251,56 +251,11 @@ DexFile::~DexFile() {
// the global reference table is otherwise empty!
}
-class ScopedJniMonitorLock {
- public:
- ScopedJniMonitorLock(JNIEnv* env, jobject locked) : env_(env), locked_(locked) {
- env->MonitorEnter(locked_);
- }
- ~ScopedJniMonitorLock() {
- env_->MonitorExit(locked_);
- }
- private:
- JNIEnv* const env_;
- const jobject locked_;
-};
-
-jobject DexFile::GetDexObject(JNIEnv* env) const {
- {
- ScopedJniMonitorLock lock(env, WellKnownClasses::com_android_dex_Dex);
- if (dex_object_ != NULL) {
- return dex_object_;
- }
- }
- void* address = const_cast<void*>(reinterpret_cast<const void*>(begin_));
- jobject byte_buffer = env->NewDirectByteBuffer(address, size_);
- if (byte_buffer == NULL) {
- return NULL;
- }
-
- ScopedJniMonitorLock lock(env, WellKnownClasses::com_android_dex_Dex);
- // Re-test to see if someone beat us to the creation when we had the lock released.
- if (dex_object_ != NULL) {
- return dex_object_;
- }
- jvalue args[1];
- args[0].l = byte_buffer;
- jobject local = env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
- WellKnownClasses::com_android_dex_Dex_create,
- args);
- if (local == NULL) {
- return NULL;
- }
-
- dex_object_ = env->NewGlobalRef(local);
- return dex_object_;
-}
-
bool DexFile::Init() {
InitMembers();
if (!CheckMagicAndVersion()) {
return false;
}
- InitIndex();
return true;
}
@@ -351,28 +306,36 @@ uint32_t DexFile::GetVersion() const {
return atoi(version);
}
-void DexFile::InitIndex() {
- CHECK_EQ(index_.size(), 0U) << GetLocation();
- for (size_t i = 0; i < NumClassDefs(); ++i) {
- const ClassDef& class_def = GetClassDef(i);
- const char* descriptor = GetClassDescriptor(class_def);
- index_.Put(descriptor, i);
+const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const {
+ size_t num_class_defs = NumClassDefs();
+ if (num_class_defs == 0) {
+ return NULL;
}
-}
-
-bool DexFile::FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const {
- Index::const_iterator it = index_.find(descriptor);
- if (it == index_.end()) {
- return false;
+ const StringId* string_id = FindStringId(descriptor);
+ if (string_id == NULL) {
+ return NULL;
}
- idx = it->second;
- return true;
+ const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
+ if (type_id == NULL) {
+ return NULL;
+ }
+ uint16_t type_idx = GetIndexForTypeId(*type_id);
+ for (size_t i = 0; i < num_class_defs; ++i) {
+ const ClassDef& class_def = GetClassDef(i);
+ if (class_def.class_idx_ == type_idx) {
+ return &class_def;
+ }
+ }
+ return NULL;
}
-const DexFile::ClassDef* DexFile::FindClassDef(const StringPiece& descriptor) const {
- uint32_t idx;
- if (FindClassDefIndex(descriptor, idx)) {
- return &GetClassDef(idx);
+const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
+ size_t num_class_defs = NumClassDefs();
+ for (size_t i = 0; i < num_class_defs; ++i) {
+ const ClassDef& class_def = GetClassDef(i);
+ if (class_def.class_idx_ == type_idx) {
+ return &class_def;
+ }
}
return NULL;
}
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 26635ae255..7be5cb848f 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -339,7 +339,7 @@ class DexFile {
typedef std::vector<const DexFile*> ClassPath;
// Search a collection of DexFiles for a descriptor
- static ClassPathEntry FindInClassPath(const StringPiece& descriptor,
+ static ClassPathEntry FindInClassPath(const char* descriptor,
const ClassPath& class_path);
// Returns the checksum of a file for comparison with GetLocationChecksum().
@@ -376,10 +376,6 @@ class DexFile {
return location_checksum_;
}
- // Returns a com.android.dex.Dex object corresponding to the mapped-in dex file.
- // Used by managed code to implement annotations.
- jobject GetDexObject(JNIEnv* env) const;
-
const Header& GetHeader() const {
DCHECK(header_ != NULL) << GetLocation();
return *header_;
@@ -584,12 +580,12 @@ class DexFile {
}
// Returns the ClassDef at the specified index.
- const ClassDef& GetClassDef(uint32_t idx) const {
+ const ClassDef& GetClassDef(uint16_t idx) const {
DCHECK_LT(idx, NumClassDefs()) << GetLocation();
return class_defs_[idx];
}
- uint32_t GetIndexForClassDef(const ClassDef& class_def) const {
+ uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
CHECK_GE(&class_def, class_defs_) << GetLocation();
CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
return &class_def - class_defs_;
@@ -601,10 +597,10 @@ class DexFile {
}
// Looks up a class definition by its class descriptor.
- const ClassDef* FindClassDef(const StringPiece& descriptor) const;
+ const ClassDef* FindClassDef(const char* descriptor) const;
- // Looks up a class definition index by its class descriptor.
- bool FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const;
+ // Looks up a class definition by its type index.
+ const ClassDef* FindClassDef(uint16_t type_idx) const;
const TypeList* GetInterfacesList(const ClassDef& class_def) const {
if (class_def.interfaces_off_ == 0) {
@@ -809,6 +805,14 @@ class DexFile {
bool DisableWrite() const;
+ const byte* Begin() const {
+ return begin_;
+ }
+
+ size_t Size() const {
+ return size_;
+ }
+
private:
// Opens a .dex file
static const DexFile* OpenFile(const std::string& filename,
@@ -840,7 +844,6 @@ class DexFile {
location_(location),
location_checksum_(location_checksum),
mem_map_(mem_map),
- dex_object_(NULL),
modification_lock("DEX modification lock"),
header_(0),
string_ids_(0),
@@ -853,23 +856,12 @@ class DexFile {
CHECK_GT(size_, 0U) << GetLocation();
}
- const byte* Begin() const {
- return begin_;
- }
-
- size_t Size() const {
- return size_;
- }
-
// Top-level initializer that calls other Init methods.
bool Init();
// Caches pointers into to the various file sections.
void InitMembers();
- // Builds the index of descriptors to class definitions.
- void InitIndex();
-
// Returns true if the header magic and version numbers are of the expected values.
bool CheckMagicAndVersion() const;
@@ -877,10 +869,6 @@ class DexFile {
DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
void* context, const byte* stream, LocalInfo* local_in_reg) const;
- // The index of descriptors to class definition indexes (as opposed to type id indexes)
- typedef SafeMap<const StringPiece, uint32_t> Index;
- Index index_;
-
// The base address of the memory mapping.
const byte* const begin_;
@@ -898,10 +886,6 @@ class DexFile {
// Manages the underlying memory allocation.
UniquePtr<MemMap> mem_map_;
- // A cached com.android.dex.Dex instance, possibly NULL. Use GetDexObject.
- // TODO: this is mutable as it shouldn't be here. We should move it to the dex cache or similar.
- mutable jobject dex_object_;
-
// The DEX-to-DEX compiler uses this lock to ensure thread safety when
// enabling write access to a read-only DEX file.
// TODO: move to Locks::dex_file_modification_lock.
diff --git a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
index 1d8022f803..07c1c015aa 100644
--- a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
@@ -32,7 +32,7 @@ extern "C" uint64_t artInvokeInterfaceTrampoline(mirror::ArtMethod* interface_me
Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* method;
- if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex16)) {
+ if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) {
method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
if (UNLIKELY(method == NULL)) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 224b2ba0d4..ccf3e59f18 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -178,7 +178,7 @@ inline uint32_t ArtMethod::GetOatNativeGcMapOffset() const {
}
inline bool ArtMethod::IsRuntimeMethod() const {
- return GetDexMethodIndex() == DexFile::kDexNoIndex16;
+ return GetDexMethodIndex() == DexFile::kDexNoIndex;
}
inline bool ArtMethod::IsCalleeSaveMethod() const {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 328c67deb1..c128eded0a 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -119,7 +119,10 @@ void Class::SetDexCache(DexCache* new_dex_cache) {
}
void Class::SetClassSize(size_t new_class_size) {
- DCHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+ if (kIsDebugBuild && (new_class_size < GetClassSize())) {
+ DumpClass(LOG(ERROR), kDumpClassFullDetail);
+ CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+ }
SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false);
}
@@ -291,22 +294,8 @@ bool Class::IsInSamePackage(const Class* that) const {
return true;
}
// Compare the package part of the descriptor string.
- if (LIKELY(!klass1->IsProxyClass() && !klass2->IsProxyClass())) {
- ClassHelper kh(klass1);
- const DexFile* dex_file1 = &kh.GetDexFile();
- const DexFile::TypeId* type_id1 = &dex_file1->GetTypeId(klass1->GetDexTypeIndex());
- const char* descriptor1 = dex_file1->GetTypeDescriptor(*type_id1);
- kh.ChangeClass(klass2);
- const DexFile* dex_file2 = &kh.GetDexFile();
- const DexFile::TypeId* type_id2 = &dex_file2->GetTypeId(klass2->GetDexTypeIndex());
- const char* descriptor2 = dex_file2->GetTypeDescriptor(*type_id2);
- return IsInSamePackage(descriptor1, descriptor2);
- }
- ClassHelper kh(klass1);
- std::string descriptor1(kh.GetDescriptor());
- kh.ChangeClass(klass2);
- std::string descriptor2(kh.GetDescriptor());
- return IsInSamePackage(descriptor1, descriptor2);
+ return IsInSamePackage(ClassHelper(klass1).GetDescriptor(),
+ ClassHelper(klass2).GetDescriptor());
}
bool Class::IsClassClass() const {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 99f3850b9b..d97b603ad8 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -726,6 +726,14 @@ class MANAGED Class : public StaticStorageBase {
return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), false);
}
+ uint16_t GetDexClassDefIndex() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), false);
+ }
+
+ void SetDexClassDefIndex(uint16_t class_def_idx) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), class_def_idx, false);
+ }
+
uint16_t GetDexTypeIndex() const {
return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), false);
}
@@ -807,7 +815,7 @@ class MANAGED Class : public StaticStorageBase {
// If class verify fails, we must return same error on subsequent tries.
Class* verify_error_class_;
- // virtual methods defined in this class; invoked through vtable
+ // Virtual methods defined in this class; invoked through vtable.
ObjectArray<ArtMethod>* virtual_methods_;
// Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
@@ -816,24 +824,28 @@ class MANAGED Class : public StaticStorageBase {
// virtual_ methods_ for miranda methods.
ObjectArray<ArtMethod>* vtable_;
- // access flags; low 16 bits are defined by VM spec
+ // Access flags; low 16 bits are defined by VM spec.
uint32_t access_flags_;
// Total size of the Class instance; used when allocating storage on gc heap.
// See also object_size_.
size_t class_size_;
- // tid used to check for recursive <clinit> invocation
+ // Tid used to check for recursive <clinit> invocation.
pid_t clinit_thread_id_;
- // type index from dex file
+ // ClassDef index in dex file, -1 if no class definition such as an array.
+ // TODO: really 16bits
+ int32_t dex_class_def_idx_;
+
+ // Type index in dex file.
// TODO: really 16bits
- uint32_t dex_type_idx_;
+ int32_t dex_type_idx_;
- // number of instance fields that are object refs
+ // Number of instance fields that are object refs.
size_t num_reference_instance_fields_;
- // number of static fields that are object refs
+ // Number of static fields that are object refs,
size_t num_reference_static_fields_;
// Total object size; used when allocating storage on gc heap.
@@ -841,7 +853,7 @@ class MANAGED Class : public StaticStorageBase {
// See also class_size_.
size_t object_size_;
- // primitive type value, or Primitive::kPrimNot (0); set for generated prim classes
+ // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes.
Primitive::Type primitive_type_;
// Bitmap of offsets of ifields.
@@ -850,7 +862,7 @@ class MANAGED Class : public StaticStorageBase {
// Bitmap of offsets of sfields.
uint32_t reference_static_offsets_;
- // state of class initialization
+ // State of class initialization.
Status status_;
// TODO: ?
@@ -873,7 +885,6 @@ std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
class MANAGED ClassClass : public Class {
private:
- int32_t padding_;
int64_t serialVersionUID_;
friend struct art::ClassClassOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 6cfab9e425..0522f134af 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -164,6 +164,7 @@ class MANAGED DexCache : public Object {
}
private:
+ Object* dex_;
ObjectArray<StaticStorageBase>* initialized_static_storage_;
String* location_;
ObjectArray<ArtField>* resolved_fields_;
diff --git a/runtime/mirror/proxy.h b/runtime/mirror/proxy.h
index 7c5bc39429..18a84dcbdb 100644
--- a/runtime/mirror/proxy.h
+++ b/runtime/mirror/proxy.h
@@ -25,6 +25,8 @@ struct ProxyOffsets;
namespace mirror {
+// All proxy objects have a class which is a synthesized proxy class. The synthesized proxy class
+// has the static fields used to implement reflection on proxy objects.
class MANAGED SynthesizedProxyClass : public Class {
public:
ObjectArray<Class>* GetInterfaces() {
@@ -41,6 +43,7 @@ class MANAGED SynthesizedProxyClass : public Class {
DISALLOW_IMPLICIT_CONSTRUCTORS(SynthesizedProxyClass);
};
+// C++ mirror of java.lang.reflect.Proxy.
class MANAGED Proxy : public Object {
private:
Object* h_;
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 01d8f318ff..1879f04bef 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -156,8 +156,8 @@ class MANAGED StringClass : public Class {
private:
CharArray* ASCII_;
Object* CASE_INSENSITIVE_ORDER_;
- uint32_t REPLACEMENT_CHAR_;
int64_t serialVersionUID_;
+ uint32_t REPLACEMENT_CHAR_;
friend struct art::StringClassOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
};
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 2f4e427bb6..d2a6c0edb4 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -150,7 +150,7 @@ static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, j
return NULL;
}
const std::string descriptor(DotToDescriptor(class_name.c_str()));
- const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor);
+ const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor.c_str());
if (dex_class_def == NULL) {
VLOG(class_linker) << "Failed to find dex_class_def";
return NULL;
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index a7296996da..d3011cb013 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -78,35 +78,6 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean
return soa.AddLocalReference<jclass>(c);
}
-static jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) {
- ScopedObjectAccess soa(env);
- mirror::Class* c = DecodeClass(soa, javaClass);
- if (c->IsPrimitive() || c->IsArrayClass() || c->IsProxyClass()) {
- return 0; // primitive, array and proxy classes don't have class definitions
- }
- const DexFile::ClassDef* class_def = ClassHelper(c).GetClassDef();
- if (class_def == NULL) {
- return 0; // not found
- } else {
- return class_def->annotations_off_;
- }
-}
-
-static jobject Class_getDex(JNIEnv* env, jobject javaClass) {
- ScopedObjectAccess soa(env);
- mirror::Class* c = DecodeClass(soa, javaClass);
-
- mirror::DexCache* dex_cache = c->GetDexCache();
- if (dex_cache == NULL) {
- return NULL;
- }
- const DexFile* dex_file = dex_cache->GetDexFile();
- if (dex_file == NULL) {
- return NULL;
- }
- return dex_file->GetDexObject(env);
-}
-
static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
mirror::Class* c = DecodeClass(soa, javaThis);
@@ -122,8 +93,6 @@ static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) {
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
- NATIVE_METHOD(Class, getAnnotationDirectoryOffset, "()I"),
- NATIVE_METHOD(Class, getDex, "()Lcom/android/dex/Dex;"),
NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
NATIVE_METHOD(Class, getProxyInterfaces, "()[Ljava/lang/Class;"),
};
diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc
new file mode 100644
index 0000000000..f8eeb2906e
--- /dev/null
+++ b/runtime/native/java_lang_DexCache.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dex_file.h"
+#include "mirror/dex_cache.h"
+#include "mirror/object-inl.h"
+#include "scoped_thread_state_change.h"
+#include "well_known_classes.h"
+
+namespace art {
+
+static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) {
+ ScopedObjectAccess soa(env);
+ mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache);
+ // Should only be called while holding the lock on the dex cache.
+ DCHECK_EQ(dex_cache->GetThinLockId(), soa.Self()->GetThinLockId());
+ const DexFile* dex_file = dex_cache->GetDexFile();
+ if (dex_file == NULL) {
+ return NULL;
+ }
+ void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
+ jobject byte_buffer = env->NewDirectByteBuffer(address, dex_file->Size());
+ if (byte_buffer == NULL) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return NULL;
+ }
+
+ jvalue args[1];
+ args[0].l = byte_buffer;
+ return env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
+ WellKnownClasses::com_android_dex_Dex_create,
+ args);
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(DexCache, getDexNative, "()Lcom/android/dex/Dex;"),
+};
+
+void register_java_lang_DexCache(JNIEnv* env) {
+ REGISTER_NATIVE_METHODS("java/lang/DexCache");
+}
+
+} // namespace art
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index afa823dbd9..4c970172b4 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -365,7 +365,7 @@ const DexFile* OatFile::OatDexFile::OpenDexFile() const {
dex_file_location_checksum_);
}
-const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_index) const {
+const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index];
const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 325ebb2914..bbd2615b66 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -183,7 +183,7 @@ class OatFile {
}
// Returns the OatClass for the class specified by the given DexFile class_def_index.
- const OatClass* GetOatClass(uint32_t class_def_index) const;
+ const OatClass* GetOatClass(uint16_t class_def_index) const;
~OatDexFile();
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 29102437a2..6ee3016179 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -68,8 +68,7 @@ class ClassHelper {
public:
ClassHelper(const mirror::Class* c = NULL, ClassLinker* l = NULL)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : class_def_(NULL),
- class_linker_(l),
+ : class_linker_(l),
dex_cache_(NULL),
dex_file_(NULL),
interface_type_list_(NULL),
@@ -92,7 +91,6 @@ class ClassHelper {
}
klass_ = new_c;
interface_type_list_ = NULL;
- class_def_ = NULL;
}
// The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
@@ -108,7 +106,7 @@ class ClassHelper {
return descriptor_.c_str();
} else {
const DexFile& dex_file = GetDexFile();
- const DexFile::TypeId& type_id = dex_file.GetTypeId(klass_->GetDexTypeIndex());
+ const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
return dex_file.GetTypeDescriptor(type_id);
}
}
@@ -124,14 +122,13 @@ class ClassHelper {
return descriptor_.c_str();
}
- const DexFile::ClassDef* GetClassDef()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::ClassDef* result = class_def_;
- if (result == NULL) {
- result = GetDexFile().FindClassDef(GetDescriptor());
- class_def_ = result;
+ const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(klass_ != nullptr);
+ uint16_t class_def_idx = klass_->GetDexClassDefIndex();
+ if (class_def_idx == DexFile::kDexNoIndex16) {
+ return nullptr;
}
- return result;
+ return &GetDexFile().GetClassDef(class_def_idx);
}
uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -187,7 +184,7 @@ class ClassHelper {
const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string descriptor(GetDescriptor());
const DexFile& dex_file = GetDexFile();
- const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
+ const DexFile::ClassDef* dex_class_def = GetClassDef();
CHECK(dex_class_def != NULL);
return dex_file.GetSourceFile(*dex_class_def);
}
@@ -242,7 +239,6 @@ class ClassHelper {
return result;
}
- const DexFile::ClassDef* class_def_;
ClassLinker* class_linker_;
mirror::DexCache* dex_cache_;
const DexFile* dex_file_;
@@ -327,12 +323,15 @@ class FieldHelper {
// If you need it longer, copy it into a std::string.
const char* GetDeclaringClassDescriptor()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uint16_t type_idx = field_->GetDeclaringClass()->GetDexTypeIndex();
- if (type_idx != DexFile::kDexNoIndex16) {
+ uint32_t field_index = field_->GetDexFieldIndex();
+ if (!field_->GetDeclaringClass()->IsProxyClass()) {
const DexFile& dex_file = GetDexFile();
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
+ const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+ return dex_file.GetFieldDeclaringClassDescriptor(field_id);
} else {
- // Most likely a proxy class.
+ DCHECK(field_->IsStatic());
+ DCHECK_LT(field_index, 2U);
+ // 0 == Class[] interfaces; 1 == Class[][] throws;
ClassHelper kh(field_->GetDeclaringClass());
declaring_class_descriptor_ = kh.GetDescriptor();
return declaring_class_descriptor_.c_str();
@@ -418,7 +417,7 @@ class MethodHelper {
const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (dex_method_idx != DexFile::kDexNoIndex16) {
+ if (dex_method_idx != DexFile::kDexNoIndex) {
return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
} else {
Runtime* runtime = Runtime::Current();
@@ -464,21 +463,19 @@ class MethodHelper {
const std::string GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (dex_method_idx != DexFile::kDexNoIndex16) {
+ if (dex_method_idx != DexFile::kDexNoIndex) {
return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
} else {
return "<no signature>";
}
}
- const DexFile::ProtoId& GetPrototype()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
}
- const DexFile::TypeList* GetParameterTypeList()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile::ProtoId& proto = GetPrototype();
return GetDexFile().GetProtoParameters(proto);
}
@@ -491,8 +488,7 @@ class MethodHelper {
return GetClassFromTypeIdx(return_type_idx);
}
- const char* GetReturnTypeDescriptor()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
@@ -500,8 +496,7 @@ class MethodHelper {
return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
}
- int32_t GetLineNumFromDexPC(uint32_t dex_pc)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (dex_pc == DexFile::kDexNoIndex) {
return method_->IsNative() ? -2 : -1;
} else {
@@ -510,35 +505,29 @@ class MethodHelper {
}
}
- const char* GetDeclaringClassDescriptor()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Class* klass = method_->GetDeclaringClass();
- DCHECK(!klass->IsProxyClass());
- uint16_t type_idx = klass->GetDexTypeIndex();
+ const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
+ uint32_t dex_method_idx = method_->GetDexMethodIndex();
+ if (dex_method_idx != DexFile::kDexNoIndex) {
+ return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
+ } else {
+ return "<runtime method>";
+ }
}
- const char* GetDeclaringClassSourceFile()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const char* descriptor = GetDeclaringClassDescriptor();
- const DexFile& dex_file = GetDexFile();
- const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
- CHECK(dex_class_def != NULL);
- return dex_file.GetSourceFile(*dex_class_def);
+ const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return ClassHelper(method_->GetDeclaringClass()).GetSourceFile();
}
- uint32_t GetClassDefIndex()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const char* descriptor = GetDeclaringClassDescriptor();
- const DexFile& dex_file = GetDexFile();
- uint32_t index;
- CHECK(dex_file.FindClassDefIndex(descriptor, index));
- return index;
+ uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return method_->GetDeclaringClass()->GetDexClassDefIndex();
}
- mirror::ClassLoader* GetClassLoader()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetDexFile().GetClassDef(GetClassDefIndex());
+ }
+
+ mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return method_->GetDeclaringClass()->GetClassLoader();
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index c37b7830c8..05f4566d85 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1007,6 +1007,7 @@ void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) {
REGISTER(register_dalvik_system_VMStack);
REGISTER(register_dalvik_system_Zygote);
REGISTER(register_java_lang_Class);
+ REGISTER(register_java_lang_DexCache);
REGISTER(register_java_lang_Object);
REGISTER(register_java_lang_Runtime);
REGISTER(register_java_lang_String);
@@ -1175,7 +1176,7 @@ mirror::ArtMethod* Runtime::CreateResolutionMethod() {
method(self, down_cast<mirror::ArtMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for resolution method saves
- method->SetDexMethodIndex(DexFile::kDexNoIndex16);
+ method->SetDexMethodIndex(DexFile::kDexNoIndex);
// When compiling, the code pointer will get set later when the image is loaded.
Runtime* r = Runtime::Current();
ClassLinker* cl = r->GetClassLinker();
@@ -1191,7 +1192,7 @@ mirror::ArtMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_se
method(self, down_cast<mirror::ArtMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for callee saves
- method->SetDexMethodIndex(DexFile::kDexNoIndex16);
+ method->SetDexMethodIndex(DexFile::kDexNoIndex);
method->SetEntryPointFromCompiledCode(NULL);
if ((instruction_set == kThumb2) || (instruction_set == kArm)) {
uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6) | (1 << art::arm::R7) |
diff --git a/runtime/thread.cc b/runtime/thread.cc
index d7d4b1fa97..68370508d3 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1816,7 +1816,7 @@ class CatchBlockStackVisitor : public StackVisitor {
uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, NULL, m, new_dex_pc);
verifier::MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), code_item,
+ &mh.GetClassDef(), code_item,
m->GetDexMethodIndex(), m, m->GetAccessFlags(), false, true);
verifier.Verify();
std::vector<int32_t> kinds = verifier.DescribeVRegs(dex_pc);
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index fa00c61017..9811926b16 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -74,50 +74,51 @@ void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* fl
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const mirror::Class* klass,
- std::string& error,
- bool allow_soft_failures) {
+ bool allow_soft_failures,
+ std::string* error) {
if (klass->IsVerified()) {
return kNoFailure;
}
mirror::Class* super = klass->GetSuperClass();
if (super == NULL && StringPiece(ClassHelper(klass).GetDescriptor()) != "Ljava/lang/Object;") {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that has no super class";
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that has no super class";
return kHardFailure;
}
if (super != NULL && super->IsFinal()) {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that attempts to sub-class final class ";
- error += PrettyDescriptor(super);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that attempts to sub-class final class ";
+ *error += PrettyDescriptor(super);
return kHardFailure;
}
ClassHelper kh(klass);
const DexFile& dex_file = kh.GetDexFile();
- uint32_t class_def_idx;
- if (!dex_file.FindClassDefIndex(kh.GetDescriptor(), class_def_idx)) {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that isn't present in dex file ";
- error += dex_file.GetLocation();
+ const DexFile::ClassDef* class_def = kh.GetClassDef();
+ if (class_def == NULL) {
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that isn't present in dex file ";
+ *error += dex_file.GetLocation();
return kHardFailure;
}
return VerifyClass(&dex_file,
kh.GetDexCache(),
klass->GetClassLoader(),
- class_def_idx, error,
- allow_soft_failures);
+ class_def,
+ allow_soft_failures,
+ error);
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
mirror::DexCache* dex_cache,
mirror::ClassLoader* class_loader,
- uint32_t class_def_idx,
- std::string& error,
- bool allow_soft_failures) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
- const byte* class_data = dex_file->GetClassData(class_def);
+ const DexFile::ClassDef* class_def,
+ bool allow_soft_failures,
+ std::string* error) {
+ DCHECK(class_def != nullptr);
+ const byte* class_data = dex_file->GetClassData(*class_def);
if (class_data == NULL) {
// empty class, probably a marker interface
return kNoFailure;
@@ -139,7 +140,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
continue;
}
previous_direct_method_idx = method_idx;
- InvokeType type = it.GetMethodInvokeType(class_def);
+ InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
@@ -151,7 +152,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -160,12 +161,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
if (result == kHardFailure) {
hard_fail = true;
if (error_count > 0) {
- error += "\n";
+ *error += "\n";
}
- error = "Verifier rejected class ";
- error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
- error += " due to bad method ";
- error += PrettyMethod(method_idx, *dex_file);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+ *error += " due to bad method ";
+ *error += PrettyMethod(method_idx, *dex_file);
}
++error_count;
}
@@ -181,7 +182,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
continue;
}
previous_virtual_method_idx = method_idx;
- InvokeType type = it.GetMethodInvokeType(class_def);
+ InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
@@ -193,7 +194,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -202,12 +203,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
if (result == kHardFailure) {
hard_fail = true;
if (error_count > 0) {
- error += "\n";
+ *error += "\n";
}
- error = "Verifier rejected class ";
- error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
- error += " due to bad method ";
- error += PrettyMethod(method_idx, *dex_file);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+ *error += " due to bad method ";
+ *error += PrettyMethod(method_idx, *dex_file);
}
++error_count;
}
@@ -224,7 +225,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
const DexFile* dex_file,
mirror::DexCache* dex_cache,
mirror::ClassLoader* class_loader,
- uint32_t class_def_idx,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
uint32_t method_access_flags,
@@ -232,7 +233,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
MethodVerifier::FailureKind result = kNoFailure;
uint64_t start_ns = NanoTime();
- MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def_idx, code_item, method_idx,
+ MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def, code_item, method_idx,
method, method_access_flags, true, allow_soft_failures);
if (verifier_.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
@@ -267,11 +268,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
uint32_t method_access_flags) {
- MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
+ MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def, code_item,
dex_method_idx, method, method_access_flags, true, true);
verifier.Verify();
verifier.DumpFailures(os);
@@ -280,7 +282,8 @@ void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_i
}
MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
uint32_t dex_method_idx, mirror::ArtMethod* method,
uint32_t method_access_flags, bool can_load_classes,
@@ -293,7 +296,7 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_ca
dex_file_(dex_file),
dex_cache_(dex_cache),
class_loader_(class_loader),
- class_def_idx_(class_def_idx),
+ class_def_(class_def),
code_item_(code_item),
declaring_class_(NULL),
interesting_dex_pc_(-1),
@@ -306,13 +309,14 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_ca
allow_soft_failures_(allow_soft_failures),
has_check_casts_(false),
has_virtual_or_interface_invokes_(false) {
+ DCHECK(class_def != NULL);
}
void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
std::vector<uint32_t>& monitor_enter_dex_pcs) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = &monitor_enter_dex_pcs;
@@ -334,7 +338,7 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -362,7 +366,7 @@ mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m
uint32_t dex_pc) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
@@ -448,7 +452,7 @@ std::ostream& MethodVerifier::Fail(VerifyError error) {
// marked as rejected to prevent it from being compiled.
case VERIFY_ERROR_BAD_CLASS_HARD: {
if (Runtime::Current()->IsCompiler()) {
- ClassReference ref(dex_file_, class_def_idx_);
+ ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_));
AddRejectedClass(ref);
}
have_pending_hard_failure_ = true;
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 70442fbc04..073a2f76be 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -145,17 +145,19 @@ class MethodVerifier {
};
/* Verify a class. Returns "kNoFailure" on success. */
- static FailureKind VerifyClass(const mirror::Class* klass, std::string& error,
- bool allow_soft_failures)
+ static FailureKind VerifyClass(const mirror::Class* klass, bool allow_soft_failures,
+ std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static FailureKind VerifyClass(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
- std::string& error, bool allow_soft_failures)
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
+ bool allow_soft_failures, std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file,
mirror::DexCache* dex_cache, mirror::ClassLoader* class_loader,
- uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+ const DexFile::ClassDef* class_def,
+ const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -222,7 +224,7 @@ class MethodVerifier {
}
MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader, const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
uint32_t method_idx, mirror::ArtMethod* method,
uint32_t access_flags, bool can_load_classes, bool allow_soft_failures)
@@ -262,7 +264,8 @@ class MethodVerifier {
*/
static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def_idx,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags,
bool allow_soft_failures)
@@ -690,7 +693,7 @@ class MethodVerifier {
mirror::DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_);
// The class loader for the declaring class of the method.
mirror::ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_);
- const uint32_t class_def_idx_; // The class def index of the declaring class of the method.
+ const DexFile::ClassDef* const class_def_; // The class def of the declaring class of the method.
const DexFile::CodeItem* const code_item_; // The code item containing the code for the method.
const RegType* declaring_class_; // Lazily computed reg type of the method's declaring class.
// Instruction widths and flags, one entry per code unit.
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 611b7c06eb..a56abba3cf 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -34,7 +34,8 @@ class MethodVerifierTest : public CommonTest {
// Verify the class
std::string error_msg;
- ASSERT_TRUE(MethodVerifier::VerifyClass(klass, error_msg, true) == MethodVerifier::kNoFailure) << error_msg;
+ ASSERT_TRUE(MethodVerifier::VerifyClass(klass, true, &error_msg) == MethodVerifier::kNoFailure)
+ << error_msg;
}
void VerifyDexFile(const DexFile* dex)
diff --git a/test/100-reflect2/expected.txt b/test/100-reflect2/expected.txt
index 3d87ebc559..967f167f37 100644
--- a/test/100-reflect2/expected.txt
+++ b/test/100-reflect2/expected.txt
@@ -35,7 +35,7 @@ z (class java.lang.Character)
62 (class java.lang.Long)
14 (class java.lang.Short)
[public java.lang.String(), java.lang.String(int,int,char[]), public java.lang.String(java.lang.String), public java.lang.String(java.lang.StringBuffer), public java.lang.String(java.lang.StringBuilder), public java.lang.String(byte[]), public java.lang.String(byte[],int), public java.lang.String(byte[],int,int), public java.lang.String(byte[],int,int,int), public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],int,int,java.nio.charset.Charset), public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],java.nio.charset.Charset), public java.lang.String(char[]), public java.lang.String(char[],int,int), public java.lang.String(int[],int,int)]
-[private final char[] java.lang.String.value, private final int java.lang.String.count, private int java.lang.String.hashCode, private final int java.lang.String.offset, private static final char[] java.lang.String.ASCII, public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER, private static final char java.lang.String.REPLACEMENT_CHAR, private static final long java.lang.String.serialVersionUID]
+[private final char[] java.lang.String.value, private final int java.lang.String.count, private int java.lang.String.hashCode, private final int java.lang.String.offset, private static final char[] java.lang.String.ASCII, public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER, private static final long java.lang.String.serialVersionUID, private static final char java.lang.String.REPLACEMENT_CHAR]
[void java.lang.String._getChars(int,int,char[],int), public char java.lang.String.charAt(int), public int java.lang.String.codePointAt(int), public int java.lang.String.codePointBefore(int), public int java.lang.String.codePointCount(int,int), public volatile int java.lang.String.compareTo(java.lang.Object), public native int java.lang.String.compareTo(java.lang.String), public int java.lang.String.compareToIgnoreCase(java.lang.String), public java.lang.String java.lang.String.concat(java.lang.String), public boolean java.lang.String.contains(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.StringBuffer), public boolean java.lang.String.endsWith(java.lang.String), public boolean java.lang.String.equals(java.lang.Object), public boolean java.lang.String.equalsIgnoreCase(java.lang.String), public void java.lang.String.getBytes(int,int,byte[],int), public [B java.lang.String.getBytes(), public [B java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException, public [B java.lang.String.getBytes(java.nio.charset.Charset), public void java.lang.String.getChars(int,int,char[],int), public int java.lang.String.hashCode(), public int java.lang.String.indexOf(int), public int java.lang.String.indexOf(int,int), public int java.lang.String.indexOf(java.lang.String), public int java.lang.String.indexOf(java.lang.String,int), public native java.lang.String java.lang.String.intern(), public boolean java.lang.String.isEmpty(), public int java.lang.String.lastIndexOf(int), public int java.lang.String.lastIndexOf(int,int), public int java.lang.String.lastIndexOf(java.lang.String), public int java.lang.String.lastIndexOf(java.lang.String,int), public int java.lang.String.length(), public boolean java.lang.String.matches(java.lang.String), public int java.lang.String.offsetByCodePoints(int,int), public boolean java.lang.String.regionMatches(int,java.lang.String,int,int), public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int), public java.lang.String java.lang.String.replace(char,char), public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence), public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String), public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String), public [Ljava.lang.String; java.lang.String.split(java.lang.String), public [Ljava.lang.String; java.lang.String.split(java.lang.String,int), public boolean java.lang.String.startsWith(java.lang.String), public boolean java.lang.String.startsWith(java.lang.String,int), public java.lang.CharSequence java.lang.String.subSequence(int,int), public java.lang.String java.lang.String.substring(int), public java.lang.String java.lang.String.substring(int,int), public [C java.lang.String.toCharArray(), public java.lang.String java.lang.String.toLowerCase(), public java.lang.String java.lang.String.toLowerCase(java.util.Locale), public java.lang.String java.lang.String.toString(), public java.lang.String java.lang.String.toUpperCase(), public java.lang.String java.lang.String.toUpperCase(java.util.Locale), public java.lang.String java.lang.String.trim(), public static java.lang.String java.lang.String.copyValueOf(char[]), public static java.lang.String java.lang.String.copyValueOf(char[],int,int), private java.lang.StringIndexOutOfBoundsException java.lang.String.failedBoundsCheck(int,int,int), private native int java.lang.String.fastIndexOf(int,int), private char java.lang.String.foldCase(char), public static transient java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[]), public static transient java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[]), private java.lang.StringIndexOutOfBoundsException java.lang.String.indexAndLength(int), private static int java.lang.String.indexOf(java.lang.String,java.lang.String,int,int,char), private int java.lang.String.indexOfSupplementary(int,int), private int java.lang.String.lastIndexOfSupplementary(int,int), private java.lang.StringIndexOutOfBoundsException java.lang.String.startEndAndLength(int,int), public static java.lang.String java.lang.String.valueOf(char), public static java.lang.String java.lang.String.valueOf(double), public static java.lang.String java.lang.String.valueOf(float), public static java.lang.String java.lang.String.valueOf(int), public static java.lang.String java.lang.String.valueOf(long), public static java.lang.String java.lang.String.valueOf(java.lang.Object), public static java.lang.String java.lang.String.valueOf(boolean), public static java.lang.String java.lang.String.valueOf(char[]), public static java.lang.String java.lang.String.valueOf(char[],int,int)]
[]
[interface java.io.Serializable, interface java.lang.Comparable, interface java.lang.CharSequence]