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
diff --git a/compiler/dex/compiler_ir.h b/compiler/dex/compiler_ir.h
index 26d0923..6607562 100644
--- a/compiler/dex/compiler_ir.h
+++ b/compiler/dex/compiler_ir.h
@@ -77,7 +77,7 @@
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 ffd7905..abafbc5 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -280,7 +280,7 @@
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 2303649..fefcab9 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -110,7 +110,7 @@
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 @@
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 @@
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 bafa468..6c33d10 100644
--- a/compiler/dex/frontend.h
+++ b/compiler/dex/frontend.h
@@ -117,7 +117,7 @@
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 c72283e..c234298 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -504,7 +504,7 @@
/* 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 0244dae..9d4ab98 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -357,7 +357,7 @@
* 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 f13ab2d..4ce752f 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -385,11 +385,12 @@
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 @@
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 8d521de..658370f 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -293,7 +293,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*/
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 @@
}
// 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::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::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 b4ec0c1..66c9cbf 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -145,8 +145,9 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 eb8941b..c441d09 100644
--- a/compiler/driver/dex_compilation_unit.cc
+++ b/compiler/driver/dex_compilation_unit.cc
@@ -39,7 +39,7 @@
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 465139b..3df50ff 100644
--- a/compiler/driver/dex_compilation_unit.h
+++ b/compiler/driver/dex_compilation_unit.h
@@ -36,7 +36,7 @@
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 @@
return dex_file_;
}
- uint32_t GetClassDefIndex() const {
+ uint16_t GetClassDefIndex() const {
return class_def_idx_;
}
@@ -108,7 +108,7 @@
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 d1859e6..f82c6fb 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -699,6 +699,7 @@
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 0df3c47..d59afd4 100644
--- a/compiler/llvm/compiler_llvm.cc
+++ b/compiler/llvm/compiler_llvm.cc
@@ -40,7 +40,7 @@
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 @@
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 93f6f25..3512911 100644
--- a/compiler/sea_ir/frontend.cc
+++ b/compiler/sea_ir/frontend.cc
@@ -41,7 +41,7 @@
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 @@
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 @@
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 5ccaba6..0734b21 100644
--- a/compiler/sea_ir/ir/sea.cc
+++ b/compiler/sea_ir/ir/sea.cc
@@ -191,7 +191,7 @@
}
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::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 92c2043..26b16be 100644
--- a/compiler/sea_ir/ir/sea.h
+++ b/compiler/sea_ir/ir/sea.h
@@ -262,7 +262,7 @@
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 @@
}
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 @@
// 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 cf1b6af..fc9e00c 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -176,9 +176,10 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 e324060..5edf759 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -91,6 +91,7 @@
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 c19f872..15eab9d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -475,40 +475,33 @@
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
-
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 @@
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 @@
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::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 @@
}
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 20efbb4..3ffcf14 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -329,7 +329,7 @@
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 @@
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 0fa0ffb..bea1139 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -508,6 +508,7 @@
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 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 @@
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 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 4fd9a60..e81c456 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -48,7 +48,7 @@
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 @@
// 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 @@
return atoi(version);
}
-void DexFile::InitIndex() {
- CHECK_EQ(index_.size(), 0U) << GetLocation();
- for (size_t i = 0; i < NumClassDefs(); ++i) {
+const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const {
+ size_t num_class_defs = NumClassDefs();
+ if (num_class_defs == 0) {
+ return NULL;
+ }
+ const StringId* string_id = FindStringId(descriptor);
+ if (string_id == NULL) {
+ return NULL;
+ }
+ 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);
- const char* descriptor = GetClassDescriptor(class_def);
- index_.Put(descriptor, i);
+ if (class_def.class_idx_ == type_idx) {
+ return &class_def;
+ }
}
+ 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;
- }
- idx = it->second;
- return true;
-}
-
-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 26635ae..7be5cb8 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -339,7 +339,7 @@
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 @@
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 @@
}
// 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 @@
}
// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 1d8022f..07c1c01 100644
--- a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
@@ -32,7 +32,7 @@
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 224b2ba..ccf3e59 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -178,7 +178,7 @@
}
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 328c67d..c128ede 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -119,7 +119,10 @@
}
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 @@
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 99f3850..d97b603 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -726,6 +726,14 @@
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 @@
// 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 @@
// 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
- uint32_t dex_type_idx_;
+ int32_t dex_class_def_idx_;
- // number of instance fields that are object refs
+ // Type index in dex file.
+ // TODO: really 16bits
+ int32_t dex_type_idx_;
+
+ // 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 @@
// 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 @@
// 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 @@
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 6cfab9e..0522f13 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -164,6 +164,7 @@
}
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 7c5bc39..18a84dc 100644
--- a/runtime/mirror/proxy.h
+++ b/runtime/mirror/proxy.h
@@ -25,6 +25,8 @@
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 @@
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 01d8f31..1879f04 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -156,8 +156,8 @@
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 2f4e427..d2a6c0e 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -150,7 +150,7 @@
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 a729699..d3011cb 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -78,35 +78,6 @@
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 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 0000000..f8eeb29
--- /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 afa823d..4c97017 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -365,7 +365,7 @@
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 325ebb2..bbd2615 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -183,7 +183,7 @@
}
// 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 2910243..6ee3016 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -68,8 +68,7 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
return result;
}
- const DexFile::ClassDef* class_def_;
ClassLinker* class_linker_;
mirror::DexCache* dex_cache_;
const DexFile* dex_file_;
@@ -327,12 +323,15 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- 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 c37b783..05f4566 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1007,6 +1007,7 @@
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 @@
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 @@
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 d7d4b1f..6837050 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1816,7 +1816,7 @@
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 fa00c61..9811926 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -74,50 +74,51 @@
}
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 @@
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 @@
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -160,12 +161,12 @@
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 @@
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 @@
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -202,12 +203,12 @@
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 @@
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 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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 70442fb..073a2f7 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -145,17 +145,19 @@
};
/* 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 @@
}
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 @@
*/
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 @@
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 611b7c0..a56abba 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -34,7 +34,8 @@
// 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 3d87ebc..967f167 100644
--- a/test/100-reflect2/expected.txt
+++ b/test/100-reflect2/expected.txt
@@ -35,7 +35,7 @@
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]