diff options
Diffstat (limited to 'src')
74 files changed, 875 insertions, 783 deletions
diff --git a/src/assembler.cc b/src/assembler.cc index 8bd7625947..55c6d077e2 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -2,9 +2,9 @@ #include <algorithm> #include <vector> -#include "src/assembler.h" -#include "src/globals.h" -#include "src/memory_region.h" +#include "assembler.h" +#include "globals.h" +#include "memory_region.h" namespace art { diff --git a/src/assembler.h b/src/assembler.h index c98a6b701c..96d5ff0654 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -3,11 +3,11 @@ #ifndef ART_SRC_ASSEMBLER_H_ #define ART_SRC_ASSEMBLER_H_ -#include "src/logging.h" -#include "src/macros.h" -#include "src/managed_register.h" -#include "src/memory_region.h" -#include "src/offsets.h" +#include "logging.h" +#include "macros.h" +#include "managed_register.h" +#include "memory_region.h" +#include "offsets.h" namespace art { @@ -300,9 +300,9 @@ class AssemblerBuffer { } // namespace art #if defined(__i386__) -#include "src/assembler_x86.h" +#include "assembler_x86.h" #elif defined(__arm__) -#include "src/assembler_arm.h" +#include "assembler_arm.h" #endif #endif // ART_SRC_ASSEMBLER_H_ diff --git a/src/assembler_arm.cc b/src/assembler_arm.cc index d470b90efd..900d8d4355 100644 --- a/src/assembler_arm.cc +++ b/src/assembler_arm.cc @@ -1,9 +1,9 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/assembler.h" -#include "src/logging.h" -#include "src/offsets.h" -#include "src/utils.h" +#include "assembler.h" +#include "logging.h" +#include "offsets.h" +#include "utils.h" namespace art { diff --git a/src/assembler_arm.h b/src/assembler_arm.h index acaf870a58..728fadf5a0 100644 --- a/src/assembler_arm.h +++ b/src/assembler_arm.h @@ -3,11 +3,11 @@ #ifndef ART_SRC_ASSEMBLER_ARM_H_ #define ART_SRC_ASSEMBLER_ARM_H_ -#include "src/constants.h" -#include "src/managed_register.h" -#include "src/logging.h" -#include "src/offsets.h" -#include "src/utils.h" +#include "constants.h" +#include "managed_register.h" +#include "logging.h" +#include "offsets.h" +#include "utils.h" namespace art { diff --git a/src/assembler_x86.cc b/src/assembler_x86.cc index a3d47e3953..e7d048bf58 100644 --- a/src/assembler_x86.cc +++ b/src/assembler_x86.cc @@ -1,11 +1,11 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/assembler.h" -#include "src/casts.h" -#include "src/globals.h" -#include "src/memory_region.h" -#include "src/offsets.h" -#include "src/thread.h" +#include "assembler.h" +#include "casts.h" +#include "globals.h" +#include "memory_region.h" +#include "offsets.h" +#include "thread.h" namespace art { diff --git a/src/assembler_x86.h b/src/assembler_x86.h index e446c51d68..5e691d1e39 100644 --- a/src/assembler_x86.h +++ b/src/assembler_x86.h @@ -3,13 +3,13 @@ #ifndef ART_SRC_ASSEMBLER_X86_H_ #define ART_SRC_ASSEMBLER_X86_H_ -#include "src/assembler.h" -#include "src/constants.h" -#include "src/globals.h" -#include "src/managed_register.h" -#include "src/macros.h" -#include "src/offsets.h" -#include "src/utils.h" +#include "assembler.h" +#include "constants.h" +#include "globals.h" +#include "managed_register.h" +#include "macros.h" +#include "offsets.h" +#include "utils.h" namespace art { diff --git a/src/assembler_x86_test.cc b/src/assembler_x86_test.cc index c0d1495de3..ffe3d0bb78 100644 --- a/src/assembler_x86_test.cc +++ b/src/assembler_x86_test.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/assembler_x86.h" +#include "assembler_x86.h" #include "gtest/gtest.h" diff --git a/src/base64.cc b/src/base64.cc index 7c096880de..a1bb61cf7f 100644 --- a/src/base64.cc +++ b/src/base64.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/globals.h" -#include "src/scoped_ptr.h" +#include "globals.h" +#include "scoped_ptr.h" #include <vector> diff --git a/src/base64.h b/src/base64.h index 160046db63..a4344ea672 100644 --- a/src/base64.h +++ b/src/base64.h @@ -3,7 +3,7 @@ #ifndef ART_SRC_BASE64_H_ #define ART_SRC_BASE64_H_ -#include "src/globals.h" +#include "globals.h" namespace art { diff --git a/src/calling_convention.cc b/src/calling_convention.cc index ae6ac251dd..5ab5b45ff4 100644 --- a/src/calling_convention.cc +++ b/src/calling_convention.cc @@ -1,9 +1,9 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: irogers@google.com (Ian Rogers) -#include "src/calling_convention.h" -#include "src/logging.h" -#include "src/utils.h" +#include "calling_convention.h" +#include "logging.h" +#include "utils.h" namespace art { diff --git a/src/calling_convention.h b/src/calling_convention.h index 4e2eab7605..6dec292365 100644 --- a/src/calling_convention.h +++ b/src/calling_convention.h @@ -4,9 +4,9 @@ #ifndef ART_SRC_CALLING_CONVENTION_H_ #define ART_SRC_CALLING_CONVENTION_H_ -#include "src/managed_register.h" -#include "src/object.h" -#include "src/thread.h" +#include "managed_register.h" +#include "object.h" +#include "thread.h" namespace art { diff --git a/src/calling_convention_arm.cc b/src/calling_convention_arm.cc index bac943b312..7535389a97 100644 --- a/src/calling_convention_arm.cc +++ b/src/calling_convention_arm.cc @@ -1,8 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: irogers@google.com (Ian Rogers) -#include "src/calling_convention.h" -#include "src/logging.h" +#include "calling_convention.h" +#include "logging.h" namespace art { diff --git a/src/calling_convention_x86.cc b/src/calling_convention_x86.cc index f1b96a64f2..c2120130de 100644 --- a/src/calling_convention_x86.cc +++ b/src/calling_convention_x86.cc @@ -1,9 +1,9 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: irogers@google.com (Ian Rogers) -#include "src/calling_convention.h" -#include "src/logging.h" -#include "src/utils.h" +#include "calling_convention.h" +#include "logging.h" +#include "utils.h" namespace art { diff --git a/src/casts.h b/src/casts.h index cdb57ee9c4..0534eca90c 100644 --- a/src/casts.h +++ b/src/casts.h @@ -5,7 +5,7 @@ #include <assert.h> #include <string.h> -#include "src/macros.h" +#include "macros.h" namespace art { diff --git a/src/class_linker.cc b/src/class_linker.cc index 6fac61071c..20960d209b 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -1,32 +1,39 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/class_linker.h" +#include "class_linker.h" #include <vector> #include <utility> -#include "src/casts.h" -#include "src/dex_verifier.h" -#include "src/heap.h" -#include "src/logging.h" -#include "src/monitor.h" -#include "src/object.h" -#include "src/raw_dex_file.h" -#include "src/scoped_ptr.h" -#include "src/thread.h" -#include "src/utils.h" +#include "casts.h" +#include "dex_file.h" +#include "dex_verifier.h" +#include "heap.h" +#include "logging.h" +#include "monitor.h" +#include "object.h" +#include "raw_dex_file.h" +#include "scoped_ptr.h" +#include "thread.h" +#include "utils.h" namespace art { -ClassLinker* ClassLinker::Create() { +ClassLinker* ClassLinker::Create(std::vector<RawDexFile*> boot_class_path) { scoped_ptr<ClassLinker> class_linker(new ClassLinker); - class_linker->Init(); + class_linker->Init(boot_class_path); // TODO: check for failure during initialization return class_linker.release(); } -void ClassLinker::Init() { +void ClassLinker::Init(std::vector<RawDexFile*> boot_class_path) { + + // setup boot_class_path_ so that object_array_class_ can be properly initialized + for (size_t i = 0; i != boot_class_path.size(); ++i) { + AppendToBootClassPath(boot_class_path[i]); + } + // Allocate and partially initialize the Class, Object, Field, Method classes. // Initialization will be completed when the definitions are loaded. java_lang_Class_ = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(Class))); @@ -74,10 +81,17 @@ void ClassLinker::Init() { char_array_class_ = FindSystemClass("[C"); CHECK(char_array_class_ != NULL); + + object_array_class_ = FindSystemClass("[Ljava/lang/Object;"); + CHECK(object_array_class_ != NULL); +} + +DexFile* ClassLinker::AllocDexFile() { + return down_cast<DexFile*>(Heap::AllocObjectArray(object_array_class_, DexFile::kMax)); } Class* ClassLinker::AllocClass(DexFile* dex_file) { - Class* klass = reinterpret_cast<Class*>(Heap::AllocObject(java_lang_Class_)); + Class* klass = down_cast<Class*>(Heap::AllocObject(java_lang_Class_)); klass->dex_file_ = dex_file; return klass; } @@ -97,8 +111,13 @@ Method* ClassLinker::AllocMethod() { sizeof(Method))); } +ObjectArray* ClassLinker::AllocObjectArray(size_t length) { + return Heap::AllocObjectArray(object_array_class_, length); +} + Class* ClassLinker::FindClass(const StringPiece& descriptor, - Object* class_loader) { + Object* class_loader, + const RawDexFile* raw_dex_file) { Thread* self = Thread::Current(); DCHECK(self != NULL); CHECK(!self->IsExceptionPending()); @@ -107,15 +126,22 @@ Class* ClassLinker::FindClass(const StringPiece& descriptor, if (klass == NULL) { // Class is not yet loaded. if (descriptor[0] == '[') { - return CreateArrayClass(descriptor, class_loader); + return CreateArrayClass(descriptor, class_loader, raw_dex_file); } - ClassPathEntry pair = FindInClassPath(descriptor); - if (pair.first == NULL) { + ClassPathEntry pair; + if (raw_dex_file == NULL) { + pair = FindInBootClassPath(descriptor); + } else { + pair.first = raw_dex_file; + pair.second = raw_dex_file->FindClassDef(descriptor); + } + if (pair.second == NULL) { LG << "Class " << descriptor << " not found"; // TODO: NoClassDefFoundError return NULL; } - DexFile* dex_file = pair.first; + const RawDexFile* raw_dex_file = pair.first; const RawDexFile::ClassDef* class_def = pair.second; + DexFile* dex_file = FindDexFile(raw_dex_file); // Load the class from the dex file. if (descriptor == "Ljava/lang/Object;") { klass = java_lang_Object_; @@ -147,7 +173,7 @@ Class* ClassLinker::FindClass(const StringPiece& descriptor, } else { klass = AllocClass(dex_file); } - LoadClass(*class_def, klass); + LoadClass(*raw_dex_file, *class_def, klass); // Check for a pending exception during load if (self->IsExceptionPending()) { // TODO: free native allocations in klass @@ -166,7 +192,7 @@ Class* ClassLinker::FindClass(const StringPiece& descriptor, CHECK(klass != NULL); } else { // Link the class. - if (!LinkClass(klass)) { + if (!LinkClass(klass, raw_dex_file)) { // Linking failed. // TODO: CHECK(self->IsExceptionPending()); lock.NotifyAll(); @@ -197,14 +223,15 @@ Class* ClassLinker::FindClass(const StringPiece& descriptor, return klass; } -void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) { +void ClassLinker::LoadClass(const RawDexFile& raw_dex_file, + const RawDexFile::ClassDef& class_def, + Class* klass) { CHECK(klass != NULL); CHECK(klass->dex_file_ != NULL); - const RawDexFile* raw = klass->GetDexFile()->GetRaw(); - const byte* class_data = raw->GetClassData(class_def); - RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data); + const byte* class_data = raw_dex_file.GetClassData(class_def); + RawDexFile::ClassDataHeader header = raw_dex_file.ReadClassDataHeader(&class_data); - const char* descriptor = raw->GetClassDescriptor(class_def); + const char* descriptor = raw_dex_file.GetClassDescriptor(class_def); CHECK(descriptor != NULL); klass->klass_ = java_lang_Class_; @@ -223,10 +250,10 @@ void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) klass->num_direct_methods_ = header.direct_methods_size_; klass->num_virtual_methods_ = header.virtual_methods_size_; - klass->source_file_ = raw->dexGetSourceFile(class_def); + klass->source_file_ = raw_dex_file.dexGetSourceFile(class_def); // Load class interfaces. - LoadInterfaces(class_def, klass); + LoadInterfaces(raw_dex_file, class_def, klass); // Load static fields. if (klass->NumStaticFields() != 0) { @@ -235,10 +262,10 @@ void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) uint32_t last_idx = 0; for (size_t i = 0; i < klass->NumStaticFields(); ++i) { RawDexFile::Field raw_field; - raw->dexReadClassDataField(&class_data, &raw_field, &last_idx); + raw_dex_file.dexReadClassDataField(&class_data, &raw_field, &last_idx); StaticField* sfield = AllocStaticField(); klass->sfields_[i] = sfield; - LoadField(klass, raw_field, sfield); + LoadField(raw_dex_file, raw_field, klass, sfield); } } @@ -249,10 +276,10 @@ void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) uint32_t last_idx = 0; for (size_t i = 0; i < klass->NumInstanceFields(); ++i) { RawDexFile::Field raw_field; - raw->dexReadClassDataField(&class_data, &raw_field, &last_idx); + raw_dex_file.dexReadClassDataField(&class_data, &raw_field, &last_idx); InstanceField* ifield = AllocInstanceField(); klass->ifields_[i] = ifield; - LoadField(klass, raw_field, ifield); + LoadField(raw_dex_file, raw_field, klass, ifield); } } @@ -263,10 +290,10 @@ void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) uint32_t last_idx = 0; for (size_t i = 0; i < klass->NumDirectMethods(); ++i) { RawDexFile::Method raw_method; - raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx); + raw_dex_file.dexReadClassDataMethod(&class_data, &raw_method, &last_idx); Method* meth = AllocMethod(); klass->direct_methods_[i] = meth; - LoadMethod(klass, raw_method, meth); + LoadMethod(raw_dex_file, raw_method, klass, meth); // TODO: register maps } } @@ -278,19 +305,19 @@ void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) uint32_t last_idx = 0; for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) { RawDexFile::Method raw_method; - raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx); + raw_dex_file.dexReadClassDataMethod(&class_data, &raw_method, &last_idx); Method* meth = AllocMethod(); klass->virtual_methods_[i] = meth; - LoadMethod(klass, raw_method, meth); + LoadMethod(raw_dex_file, raw_method, klass, meth); // TODO: register maps } } } -void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def, +void ClassLinker::LoadInterfaces(const RawDexFile& raw_dex_file, + const RawDexFile::ClassDef& class_def, Class* klass) { - const RawDexFile* raw = klass->GetDexFile()->GetRaw(); - const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def); + const RawDexFile::TypeList* list = raw_dex_file.GetInterfacesList(class_def); if (list != NULL) { klass->interface_count_ = list->Size(); // TODO: allocate the interfaces array on the object heap. @@ -302,29 +329,31 @@ void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def, } } -void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src, +void ClassLinker::LoadField(const RawDexFile& raw_dex_file, + const RawDexFile::Field& src, + Class* klass, Field* dst) { - const RawDexFile* raw = klass->GetDexFile()->GetRaw(); - const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_); + const RawDexFile::FieldId& field_id = raw_dex_file.GetFieldId(src.field_idx_); dst->klass_ = klass; - dst->name_ = raw->dexStringById(field_id.name_idx_); - dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_); + dst->name_ = raw_dex_file.dexStringById(field_id.name_idx_); + dst->signature_ = raw_dex_file.dexStringByTypeIdx(field_id.type_idx_); dst->access_flags_ = src.access_flags_; } -void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src, +void ClassLinker::LoadMethod(const RawDexFile& raw_dex_file, + const RawDexFile::Method& src, + Class* klass, Method* dst) { - const RawDexFile* raw = klass->GetDexFile()->GetRaw(); - const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_); + const RawDexFile::MethodId& method_id = raw_dex_file.GetMethodId(src.method_idx_); dst->klass_ = klass; - dst->name_.set(raw->dexStringById(method_id.name_idx_)); + dst->name_.set(raw_dex_file.dexStringById(method_id.name_idx_)); dst->proto_idx_ = method_id.proto_idx_; - dst->shorty_.set(raw->GetShorty(method_id.proto_idx_)); + dst->shorty_.set(raw_dex_file.GetShorty(method_id.proto_idx_)); dst->access_flags_ = src.access_flags_; // TODO: check for finalize method - const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src); + const RawDexFile::CodeItem* code_item = raw_dex_file.GetCodeItem(src); if (code_item != NULL) { dst->num_registers_ = code_item->registers_size_; dst->num_ins_ = code_item->ins_size_; @@ -340,19 +369,53 @@ void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src, } } -ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const StringPiece& descriptor) { - for (size_t i = 0; i != class_path_.size(); ++i) { - DexFile* dex_file = class_path_[i]; - const RawDexFile::ClassDef* class_def = dex_file->GetRaw()->FindClassDef(descriptor); +ClassLinker::ClassPathEntry ClassLinker::FindInBootClassPath(const StringPiece& descriptor) { + for (size_t i = 0; i != boot_class_path_.size(); ++i) { + RawDexFile* raw_dex_file = boot_class_path_[i]; + const RawDexFile::ClassDef* class_def = raw_dex_file->FindClassDef(descriptor); if (class_def != NULL) { - return ClassPathEntry(dex_file, class_def); + return ClassPathEntry(raw_dex_file, class_def); } } return ClassPathEntry(NULL, NULL); } -void ClassLinker::AppendToClassPath(DexFile* dex_file) { - class_path_.push_back(dex_file); +void ClassLinker::AppendToBootClassPath(RawDexFile* raw_dex_file) { + boot_class_path_.push_back(raw_dex_file); + RegisterDexFile(raw_dex_file); +} + +void ClassLinker::RegisterDexFile(RawDexFile* raw_dex_file) { + raw_dex_files_.push_back(raw_dex_file); + DexFile* dex_file = AllocDexFile(); + CHECK(dex_file != NULL); + dex_file->Init(AllocObjectArray(raw_dex_file->NumStringIds()), + AllocObjectArray(raw_dex_file->NumTypeIds()), + AllocObjectArray(raw_dex_file->NumMethodIds()), + AllocObjectArray(raw_dex_file->NumFieldIds())); + dex_files_.push_back(dex_file); +} + +const RawDexFile* ClassLinker::FindRawDexFile(const DexFile* dex_file) const { + CHECK(dex_file != NULL); + for (size_t i = 0; i != dex_files_.size(); ++i) { + if (dex_files_[i] == dex_file) { + return raw_dex_files_[i]; + } + } + CHECK(false) << "Could not find RawDexFile"; + return NULL; +} + +DexFile* ClassLinker::FindDexFile(const RawDexFile* raw_dex_file) const { + CHECK(raw_dex_file != NULL); + for (size_t i = 0; i != raw_dex_files_.size(); ++i) { + if (raw_dex_files_[i] == raw_dex_file) { + return dex_files_[i]; + } + } + CHECK(false) << "Could not find DexFile"; + return NULL; } Class* ClassLinker::CreatePrimitiveClass(const StringPiece& descriptor) { @@ -381,7 +444,9 @@ Class* ClassLinker::CreatePrimitiveClass(const StringPiece& descriptor) { // always comes from the base element class. // // Returns NULL with an exception raised on failure. -Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* class_loader) +Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, + Object* class_loader, + const RawDexFile* raw_dex_file) { CHECK(descriptor[0] == '['); DCHECK(java_lang_Class_ != NULL); @@ -392,7 +457,7 @@ Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* clas int array_rank; if (descriptor[1] == '[') { // array of arrays; keep descriptor and grab stuff from parent - Class* outer = FindClass(descriptor.substr(1), class_loader); + Class* outer = FindClass(descriptor.substr(1), class_loader, raw_dex_file); if (outer != NULL) { // want the base class, not "outer", in our component_type_ component_type_ = outer->component_type_; @@ -405,8 +470,7 @@ Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* clas if (descriptor[1] == 'L') { // array of objects; strip off "[" and look up descriptor. const StringPiece subDescriptor = descriptor.substr(1); - LG << "searching for element class '" << subDescriptor << "'"; - component_type_ = FindClass(subDescriptor, class_loader); // TODO FindClassNoInit + component_type_ = FindClass(subDescriptor, class_loader, raw_dex_file); } else { // array of a primitive type component_type_ = FindPrimitiveClass(descriptor[1]); @@ -474,7 +538,7 @@ Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* clas // interfaces. We need to set that up here, so that stuff like // "instanceof" works right. // - // Note: The GC could run during the call to FindSystemClassNoInit(), + // Note: The GC could run during the call to FindSystemClass, // so we need to make sure the class object is GC-valid while we're in // there. Do this by clearing the interface list so the GC will just // think that the entries are null. @@ -735,7 +799,7 @@ bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) { bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method, const Class* klass1, const Class* klass2) { - const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw(); + const RawDexFile* raw = FindRawDexFile(method->GetClass()->GetDexFile()); const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_); RawDexFile::ParameterIterator *it; for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) { @@ -769,9 +833,9 @@ bool ClassLinker::HasSameDescriptorClasses(const char* descriptor, CHECK(klass1 != NULL); CHECK(klass2 != NULL); #if 0 - Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader()); + Class* found1 = FindClass(descriptor, klass1->GetClassLoader()); // TODO: found1 == NULL - Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader()); + Class* found2 = FindClass(descriptor, klass2->GetClassLoader()); // TODO: found2 == NULL // TODO: lookup found1 in initiating loader list if (found1 == NULL || found2 == NULL) { @@ -786,6 +850,44 @@ bool ClassLinker::HasSameDescriptorClasses(const char* descriptor, return true; } +bool ClassLinker::HasSameArgumentTypes(const Method* m1, const Method* m2) const { + const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile()); + const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile()); + const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_); + const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_); + + // TODO: compare ProtoId objects for equality and exit early + const RawDexFile::TypeList* type_list1 = raw1->GetProtoParameters(proto1); + const RawDexFile::TypeList* type_list2 = raw2->GetProtoParameters(proto2); + size_t arity1 = (type_list1 == NULL) ? 0 : type_list1->Size(); + size_t arity2 = (type_list2 == NULL) ? 0 : type_list2->Size(); + if (arity1 != arity2) { + return false; + } + + for (size_t i = 0; i < arity1; ++i) { + uint32_t type_idx1 = type_list1->GetTypeItem(i).type_idx_; + uint32_t type_idx2 = type_list2->GetTypeItem(i).type_idx_; + const char* type1 = raw1->dexStringByTypeIdx(type_idx1); + const char* type2 = raw2->dexStringByTypeIdx(type_idx2); + if (strcmp(type1, type2) != 0) { + return false; + } + } + + return true; +} + +bool ClassLinker::HasSameReturnType(const Method* m1, const Method* m2) const { + const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile()); + const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile()); + const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_); + const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_); + const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_); + const char* type2 = raw2->dexStringByTypeIdx(proto2.return_type_idx_); + return (strcmp(type1, type2) == 0); +} + bool ClassLinker::InitializeSuperClass(Class* klass) { CHECK(klass != NULL); // TODO: assert klass lock is acquired @@ -817,7 +919,7 @@ void ClassLinker::InitializeStaticFields(Class* klass) { return; } const StringPiece& descriptor = klass->GetDescriptor(); - const RawDexFile* raw = dex_file->GetRaw(); + const RawDexFile* raw = FindRawDexFile(dex_file); const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor); CHECK(class_def != NULL); const byte* addr = raw->GetEncodedArray(*class_def); @@ -866,11 +968,11 @@ void ClassLinker::InitializeStaticFields(Class* klass) { } } -bool ClassLinker::LinkClass(Class* klass) { +bool ClassLinker::LinkClass(Class* klass, const RawDexFile* raw_dex_file) { CHECK(klass->status_ == Class::kStatusIdx || klass->status_ == Class::kStatusLoaded); if (klass->status_ == Class::kStatusIdx) { - if (!LinkInterfaces(klass)) { + if (!LinkInterfaces(klass, raw_dex_file)) { return false; } } @@ -889,7 +991,7 @@ bool ClassLinker::LinkClass(Class* klass) { return true; } -bool ClassLinker::LinkInterfaces(Class* klass) { +bool ClassLinker::LinkInterfaces(Class* klass, const RawDexFile* raw_dex_file) { scoped_array<uint32_t> interfaces_idx; // TODO: store interfaces_idx in the Class object // TODO: move this outside of link interfaces @@ -902,7 +1004,7 @@ bool ClassLinker::LinkInterfaces(Class* klass) { // Mark the class as loaded. klass->status_ = Class::kStatusLoaded; if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) { - Class* super_class = ResolveClass(klass, klass->super_class_idx_); + Class* super_class = ResolveClass(klass, klass->super_class_idx_, raw_dex_file); if (super_class == NULL) { LG << "Failed to resolve superclass"; return false; @@ -912,7 +1014,7 @@ bool ClassLinker::LinkInterfaces(Class* klass) { if (klass->interface_count_ > 0) { for (size_t i = 0; i < klass->interface_count_; ++i) { uint32_t idx = interfaces_idx[i]; - klass->interfaces_[i] = ResolveClass(klass, idx); + klass->interfaces_[i] = ResolveClass(klass, idx, raw_dex_file); if (klass->interfaces_[i] == NULL) { LG << "Failed to resolve interface"; return false; @@ -1004,7 +1106,7 @@ bool ClassLinker::LinkVirtualMethods(Class* klass) { size_t j = 0; for (; j < klass->GetSuperClass()->vtable_count_; ++j) { const Method* super_method = klass->vtable_[j]; - if (local_method->HasSameNameAndPrototype(super_method)) { + if (HasSameNameAndPrototype(local_method, super_method)) { // Verify if (super_method->IsFinal()) { LG << "Method overrides final method"; // TODO: VirtualMachineError @@ -1115,7 +1217,7 @@ bool ClassLinker::LinkInterfaceMethods(Class* klass) { Method* interface_method = interface->GetVirtualMethod(j); int k; // must be signed for (k = klass->vtable_count_ - 1; k >= 0; --k) { - if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) { + if (HasSameNameAndPrototype(interface_method, klass->vtable_[k])) { if (!klass->vtable_[k]->IsPublic()) { LG << "Implementation not public"; return false; @@ -1135,7 +1237,7 @@ bool ClassLinker::LinkInterfaceMethods(Class* klass) { } int mir; for (mir = 0; mir < miranda_count; mir++) { - if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) { + if (HasSameNameAndPrototype(miranda_list[mir], interface_method)) { break; } } @@ -1349,17 +1451,19 @@ void ClassLinker::CreateReferenceOffsets(Class* klass) { } } -Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) { +Class* ClassLinker::ResolveClass(const Class* referrer, + uint32_t class_idx, + const RawDexFile* raw_dex_file) { DexFile* dex_file = referrer->GetDexFile(); Class* resolved = dex_file->GetResolvedClass(class_idx); if (resolved != NULL) { return resolved; } - const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx); + const char* descriptor = raw_dex_file->dexStringByTypeIdx(class_idx); if (descriptor[0] != '\0' && descriptor[1] == '\0') { resolved = FindPrimitiveClass(descriptor[0]); } else { - resolved = FindClass(descriptor, referrer->GetClassLoader()); + resolved = FindClass(descriptor, referrer->GetClassLoader(), raw_dex_file); } if (resolved != NULL) { Class* check = resolved->IsArray() ? resolved->component_type_ : resolved; @@ -1369,7 +1473,7 @@ Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) { return NULL; } } - dex_file->SetResolvedClass(resolved, class_idx); + dex_file->SetResolvedClass(class_idx, resolved); } else { DCHECK(Thread::Current()->IsExceptionPending()); } @@ -1384,14 +1488,14 @@ Method* ResolveMethod(const Class* referrer, uint32_t method_idx, String* ClassLinker::ResolveString(const Class* referring, uint32_t string_idx) { - const RawDexFile* raw = referring->GetDexFile()->GetRaw(); + const RawDexFile* raw = FindRawDexFile(referring->GetDexFile()); const RawDexFile::StringId& string_id = raw->GetStringId(string_idx); const char* string_data = raw->GetStringData(string_id); String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_, char_array_class_, string_data); // TODO: intern the new string - referring->GetDexFile()->SetResolvedString(new_string, string_idx); + referring->GetDexFile()->SetResolvedString(string_idx, new_string); return new_string; } diff --git a/src/class_linker.h b/src/class_linker.h index 47f8c24017..d7bb1916c0 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -7,64 +7,90 @@ #include <utility> #include <vector> -#include "src/macros.h" -#include "src/thread.h" -#include "src/object.h" +#include "macros.h" +#include "raw_dex_file.h" +#include "thread.h" +#include "object.h" +#include "gtest/gtest.h" namespace art { class ClassLinker { public: // Initializes the class linker. - static ClassLinker* Create(); + static ClassLinker* Create(std::vector<RawDexFile*> boot_class_path); ~ClassLinker() {} + DexFile* AllocDexFile(); Class* AllocClass(DexFile* dex_file); StaticField* AllocStaticField(); InstanceField* AllocInstanceField(); Method* AllocMethod(); + ObjectArray* AllocObjectArray(size_t length); // Finds a class by its descriptor name. + // If raw_dex_file is null, searches boot_class_path_. Class* FindClass(const StringPiece& descriptor, - Object* class_loader); + Object* class_loader, + const RawDexFile* raw_dex_file); Class* FindSystemClass(const StringPiece& descriptor) { - return FindClass(descriptor, NULL); + return FindClass(descriptor, NULL, NULL); } - Class* FindPrimitiveClass(char type); - bool InitializeClass(Class* klass); Class* LookupClass(const StringPiece& descriptor, Object* class_loader); - Class* ResolveClass(const Class* referring, uint32_t class_idx); + Class* ResolveClass(const Class* referring, + uint32_t class_idx, + const RawDexFile* raw_dex_file); String* ResolveString(const Class* referring, uint32_t string_idx); - typedef std::pair<DexFile*, const RawDexFile::ClassDef*> ClassPathEntry; - - ClassPathEntry FindInClassPath(const StringPiece& descriptor); - - void AppendToClassPath(DexFile* dex_file); + void RegisterDexFile(RawDexFile* raw_dex_file); private: ClassLinker() {} - void Init(); + void Init(std::vector<RawDexFile*> boot_class_path_); Class* CreatePrimitiveClass(const StringPiece& descriptor); - Class* CreateArrayClass(const StringPiece& descriptor, Object* class_loader); + Class* CreateArrayClass(const StringPiece& descriptor, + Object* class_loader, + const RawDexFile* raw_dex_file); + + Class* FindPrimitiveClass(char type); + + const RawDexFile* FindRawDexFile(const DexFile* dex_file) const; + + DexFile* FindDexFile(const RawDexFile* raw_dex_file) const; + + typedef std::pair<const RawDexFile*, const RawDexFile::ClassDef*> ClassPathEntry; + + void AppendToBootClassPath(RawDexFile* raw_dex_file); + + ClassPathEntry FindInBootClassPath(const StringPiece& descriptor); - void LoadClass(const RawDexFile::ClassDef& class_def, Class* klass); + void LoadClass(const RawDexFile& raw_dex_file, + const RawDexFile::ClassDef& class_def, + Class* klass); - void LoadInterfaces(const RawDexFile::ClassDef& class_def, Class *klass); + void LoadInterfaces(const RawDexFile& raw_dex_file, + const RawDexFile::ClassDef& class_def, + Class *klass); - void LoadField(Class* klass, const RawDexFile::Field& src, Field* dst); + void LoadField(const RawDexFile& raw_dex_file, + const RawDexFile::Field& src, + Class* klass, + Field* dst); - void LoadMethod(Class* klass, const RawDexFile::Method& src, Method* dst); + void LoadMethod(const RawDexFile& raw_dex_file, + const RawDexFile::Method& src, + Class* klass, + Method* dst); // Inserts a class into the class table. Returns true if the class // was inserted. @@ -84,11 +110,27 @@ class ClassLinker { const Class* klass1, const Class* klass2); - bool LinkClass(Class* klass); + bool HasSameNameAndPrototype(const Method* m1, const Method* m2) const { + return HasSameName(m1, m2) && HasSamePrototype(m1, m2); + } + + bool HasSameName(const Method* m1, const Method* m2) const { + return m1->GetName() == m2->GetName(); + } + + bool HasSamePrototype(const Method* m1, const Method* m2) const { + return HasSameReturnType(m1, m2) && HasSameArgumentTypes(m1, m2); + } + + bool HasSameReturnType(const Method* m1, const Method* m2) const; + + bool HasSameArgumentTypes(const Method* m1, const Method* m2) const; + + bool LinkClass(Class* klass, const RawDexFile* raw_dex_file); bool LinkSuperClass(Class* klass); - bool LinkInterfaces(Class* klass); + bool LinkInterfaces(Class* klass, const RawDexFile* raw_dex_file); bool LinkMethods(Class* klass); @@ -102,7 +144,11 @@ class ClassLinker { void CreateReferenceOffsets(Class* klass); - std::vector<DexFile*> class_path_; + std::vector<RawDexFile*> boot_class_path_; + + std::vector<RawDexFile*> raw_dex_files_; + + std::vector<DexFile*> dex_files_; // TODO: multimap typedef std::map<const StringPiece, Class*> Table; @@ -131,8 +177,11 @@ class ClassLinker { Class* primitive_long_; Class* primitive_void_; + Class* object_array_class_; Class* char_array_class_; + FRIEND_TEST(ClassLinkerTest, ProtoCompare); + FRIEND_TEST(ClassLinkerTest, ProtoCompare2); DISALLOW_COPY_AND_ASSIGN(ClassLinker); }; diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index 888ef1263c..a128445846 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -1,132 +1,116 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/common_test.h" -#include "src/class_linker.h" -#include "src/dex_file.h" -#include "src/heap.h" +#include "common_test.h" +#include "class_linker.h" +#include "dex_file.h" +#include "heap.h" #include "gtest/gtest.h" namespace art { -class ClassLinkerTest : public RuntimeTest {}; +class ClassLinkerTest : public RuntimeTest { + protected: + void AssertNonExistantClass(const StringPiece& descriptor) { + EXPECT_TRUE(class_linker_.get()->FindSystemClass(descriptor) == NULL); + } -TEST_F(ClassLinkerTest, FindClassNonexistent) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassDex)); - ASSERT_TRUE(dex != NULL); + void AssertPrimitiveClass(const StringPiece& descriptor) { + Class* primitive = class_linker_.get()->FindSystemClass(descriptor); + ASSERT_TRUE(primitive != NULL); + ASSERT_TRUE(primitive->GetClass() != NULL); + ASSERT_EQ(primitive->GetClass(), primitive->GetClass()->GetClass()); + EXPECT_TRUE(primitive->GetClass()->GetSuperClass() != NULL); + ASSERT_EQ(descriptor, primitive->GetDescriptor()); + EXPECT_TRUE(primitive->GetSuperClass() == NULL); + EXPECT_FALSE(primitive->HasSuperClass()); + EXPECT_TRUE(primitive->GetComponentType() == NULL); + EXPECT_TRUE(primitive->GetStatus() == Class::kStatusInitialized); + EXPECT_FALSE(primitive->IsErroneous()); + EXPECT_TRUE(primitive->IsVerified()); + EXPECT_TRUE(primitive->IsLinked()); + EXPECT_FALSE(primitive->IsArray()); + EXPECT_EQ(0, primitive->array_rank_); + EXPECT_FALSE(primitive->IsInterface()); + EXPECT_TRUE(primitive->IsPublic()); + EXPECT_TRUE(primitive->IsFinal()); + EXPECT_TRUE(primitive->IsPrimitive()); + EXPECT_EQ(0U, primitive->NumDirectMethods()); + EXPECT_EQ(0U, primitive->NumVirtualMethods()); + EXPECT_EQ(0U, primitive->NumInstanceFields()); + EXPECT_EQ(0U, primitive->NumStaticFields()); + EXPECT_EQ(0U, primitive->interface_count_); + } - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); + void AssertArrayClass(const StringPiece& array_descriptor, + int32_t array_rank, + const StringPiece& component_type) { + Class* array = class_linker_.get()->FindSystemClass(array_descriptor); + ASSERT_TRUE(array != NULL); + ASSERT_TRUE(array->GetClass() != NULL); + ASSERT_EQ(array->GetClass(), array->GetClass()->GetClass()); + EXPECT_TRUE(array->GetClass()->GetSuperClass() != NULL); + ASSERT_EQ(array_descriptor, array->GetDescriptor()); + EXPECT_TRUE(array->GetSuperClass() != NULL); + EXPECT_EQ(class_linker_.get()->FindSystemClass("Ljava/lang/Object;"), array->GetSuperClass()); + EXPECT_TRUE(array->HasSuperClass()); + ASSERT_TRUE(array->GetComponentType() != NULL); + ASSERT_TRUE(array->GetComponentType()->GetDescriptor() != NULL); + EXPECT_EQ(component_type, array->GetComponentType()->GetDescriptor()); + EXPECT_TRUE(array->GetStatus() == Class::kStatusInitialized); + EXPECT_FALSE(array->IsErroneous()); + EXPECT_TRUE(array->IsVerified()); + EXPECT_TRUE(array->IsLinked()); + EXPECT_TRUE(array->IsArray()); + EXPECT_EQ(array_rank, array->array_rank_); + EXPECT_FALSE(array->IsInterface()); + EXPECT_EQ(array->GetComponentType()->IsPublic(), array->IsPublic()); + EXPECT_TRUE(array->IsFinal()); + EXPECT_FALSE(array->IsPrimitive()); + EXPECT_EQ(0U, array->NumDirectMethods()); + EXPECT_EQ(0U, array->NumVirtualMethods()); + EXPECT_EQ(0U, array->NumInstanceFields()); + EXPECT_EQ(0U, array->NumStaticFields()); + EXPECT_EQ(2U, array->interface_count_); + } +}; - Class* result1 = linker.get()->FindClass("NoSuchClass;", NULL); +TEST_F(ClassLinkerTest, FindClassNonexistent) { + Class* result1 = class_linker_.get()->FindSystemClass("NoSuchClass;"); EXPECT_TRUE(result1 == NULL); - Class* result2 = linker.get()->FindClass("LNoSuchClass;", NULL); + Class* result2 = class_linker_.get()->FindSystemClass("LNoSuchClass;"); EXPECT_TRUE(result2 == NULL); } TEST_F(ClassLinkerTest, FindClassNested) { - scoped_ptr<DexFile> objectDex(OpenDexFileBase64(kJavaLangDex)); - ASSERT_TRUE(objectDex != NULL); - scoped_ptr<DexFile> nestedDex(OpenDexFileBase64(kNestedDex)); - ASSERT_TRUE(nestedDex != NULL); - - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(objectDex.get()); - linker->AppendToClassPath(nestedDex.get()); + scoped_ptr<RawDexFile> nestedDex(OpenRawDexFileBase64(kNestedDex)); + class_linker_.get()->RegisterDexFile(nestedDex.get()); - Class* outer = linker.get()->FindClass("LNested;", NULL); + Class* outer = class_linker_.get()->FindClass("LNested;", NULL, nestedDex.get()); ASSERT_TRUE(outer != NULL); EXPECT_EQ(0U, outer->NumVirtualMethods()); EXPECT_EQ(1U, outer->NumDirectMethods()); - Class* inner = linker.get()->FindClass("LNested$Inner;", NULL); + Class* inner = class_linker_.get()->FindClass("LNested$Inner;", NULL, nestedDex.get()); ASSERT_TRUE(inner != NULL); EXPECT_EQ(0U, inner->NumVirtualMethods()); EXPECT_EQ(1U, inner->NumDirectMethods()); } -static void AssertNonExistantClass(ClassLinker* linker, const StringPiece& descriptor) { - EXPECT_TRUE(linker->FindClass(descriptor, NULL) == NULL); -} - -static void AssertPrimitiveClass(ClassLinker* linker, const StringPiece& descriptor) { - Class* primitive = linker->FindClass(descriptor, NULL); - ASSERT_TRUE(primitive != NULL); - ASSERT_TRUE(primitive->GetClass() != NULL); - ASSERT_EQ(primitive->GetClass(), primitive->GetClass()->GetClass()); - EXPECT_TRUE(primitive->GetClass()->GetSuperClass() != NULL); - ASSERT_EQ(descriptor, primitive->GetDescriptor()); - EXPECT_TRUE(primitive->GetSuperClass() == NULL); - EXPECT_FALSE(primitive->HasSuperClass()); - EXPECT_TRUE(primitive->GetComponentType() == NULL); - EXPECT_TRUE(primitive->GetStatus() == Class::kStatusInitialized); - EXPECT_FALSE(primitive->IsErroneous()); - EXPECT_TRUE(primitive->IsVerified()); - EXPECT_TRUE(primitive->IsLinked()); - EXPECT_FALSE(primitive->IsArray()); - EXPECT_EQ(0, primitive->array_rank_); - EXPECT_FALSE(primitive->IsInterface()); - EXPECT_TRUE(primitive->IsPublic()); - EXPECT_TRUE(primitive->IsFinal()); - EXPECT_TRUE(primitive->IsPrimitive()); - EXPECT_EQ(0U, primitive->NumDirectMethods()); - EXPECT_EQ(0U, primitive->NumVirtualMethods()); - EXPECT_EQ(0U, primitive->NumInstanceFields()); - EXPECT_EQ(0U, primitive->NumStaticFields()); - EXPECT_EQ(0U, primitive->interface_count_); -} - -static void AssertArrayClass(ClassLinker* linker, - const StringPiece& array_descriptor, - int32_t array_rank, - const StringPiece& component_type) { - Class* array = linker->FindClass(array_descriptor, NULL); - ASSERT_TRUE(array != NULL); - ASSERT_TRUE(array->GetClass() != NULL); - ASSERT_EQ(array->GetClass(), array->GetClass()->GetClass()); - EXPECT_TRUE(array->GetClass()->GetSuperClass() != NULL); - ASSERT_EQ(array_descriptor, array->GetDescriptor()); - EXPECT_TRUE(array->GetSuperClass() != NULL); - EXPECT_EQ(linker->FindSystemClass("Ljava/lang/Object;"), array->GetSuperClass()); - EXPECT_TRUE(array->HasSuperClass()); - ASSERT_TRUE(array->GetComponentType() != NULL); - ASSERT_TRUE(array->GetComponentType()->GetDescriptor() != NULL); - EXPECT_EQ(component_type, array->GetComponentType()->GetDescriptor()); - EXPECT_TRUE(array->GetStatus() == Class::kStatusInitialized); - EXPECT_FALSE(array->IsErroneous()); - EXPECT_TRUE(array->IsVerified()); - EXPECT_TRUE(array->IsLinked()); - EXPECT_TRUE(array->IsArray()); - EXPECT_EQ(array_rank, array->array_rank_); - EXPECT_FALSE(array->IsInterface()); - EXPECT_EQ(array->GetComponentType()->IsPublic(), array->IsPublic()); - EXPECT_TRUE(array->IsFinal()); - EXPECT_FALSE(array->IsPrimitive()); - EXPECT_EQ(0U, array->NumDirectMethods()); - EXPECT_EQ(0U, array->NumVirtualMethods()); - EXPECT_EQ(0U, array->NumInstanceFields()); - EXPECT_EQ(0U, array->NumStaticFields()); - EXPECT_EQ(2U, array->interface_count_); -} - TEST_F(ClassLinkerTest, FindClass) { - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); + ClassLinker* linker = class_linker_.get(); StringPiece expected = "BCDFIJSZV"; for (int ch = 0; ch < 255; ch++) { char* s = reinterpret_cast<char*>(&ch); StringPiece descriptor(s, 1); if (expected.find(ch) == StringPiece::npos) { - AssertNonExistantClass(linker.get(), descriptor); + AssertNonExistantClass(descriptor); } else { - AssertPrimitiveClass(linker.get(), descriptor); + AssertPrimitiveClass(descriptor); } } - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassDex)); - ASSERT_TRUE(dex != NULL); - linker->AppendToClassPath(dex.get()); - - Class* JavaLangObject = linker->FindClass("Ljava/lang/Object;", NULL); + Class* JavaLangObject = linker->FindSystemClass("Ljava/lang/Object;"); ASSERT_TRUE(JavaLangObject != NULL); ASSERT_TRUE(JavaLangObject->GetClass() != NULL); ASSERT_EQ(JavaLangObject->GetClass(), JavaLangObject->GetClass()->GetClass()); @@ -151,7 +135,10 @@ TEST_F(ClassLinkerTest, FindClass) { EXPECT_EQ(0U, JavaLangObject->interface_count_); - Class* MyClass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassDex)); + linker->RegisterDexFile(dex.get()); + EXPECT_TRUE(linker->FindSystemClass("LMyClass;") == NULL); + Class* MyClass = linker->FindClass("LMyClass;", NULL, dex.get()); ASSERT_TRUE(MyClass != NULL); ASSERT_TRUE(MyClass->GetClass() != NULL); ASSERT_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass()); @@ -179,12 +166,111 @@ TEST_F(ClassLinkerTest, FindClass) { EXPECT_EQ(JavaLangObject->GetClass()->GetClass(), MyClass->GetClass()->GetClass()); // created by class_linker - AssertArrayClass(linker.get(), "[C", 1, "C"); + AssertArrayClass("[C", 1, "C"); + AssertArrayClass("[Ljava/lang/Object;", 1, "Ljava/lang/Object;"); // synthesized on the fly - AssertArrayClass(linker.get(), "[[C", 2, "C"); - AssertArrayClass(linker.get(), "[[[LMyClass;", 3, "LMyClass;"); + AssertArrayClass("[[C", 2, "C"); + AssertArrayClass("[[[LMyClass;", 3, "LMyClass;"); // or not available at all - AssertNonExistantClass(linker.get(), "[[[[LNonExistantClass;"); + AssertNonExistantClass("[[[[LNonExistantClass;"); +} + +TEST_F(ClassLinkerTest, ProtoCompare) { + ClassLinker* linker = class_linker_.get(); + + scoped_ptr<RawDexFile> proto_dex_file(OpenRawDexFileBase64(kProtoCompareDex)); + linker->RegisterDexFile(proto_dex_file.get()); + + Class* klass = linker->FindClass("LProtoCompare;", NULL, proto_dex_file.get()); + ASSERT_TRUE(klass != NULL); + + ASSERT_EQ(4U, klass->NumVirtualMethods()); + + Method* m1 = klass->GetVirtualMethod(0); + ASSERT_EQ("m1", m1->GetName()); + + Method* m2 = klass->GetVirtualMethod(1); + ASSERT_EQ("m2", m2->GetName()); + + Method* m3 = klass->GetVirtualMethod(2); + ASSERT_EQ("m3", m3->GetName()); + + Method* m4 = klass->GetVirtualMethod(3); + ASSERT_EQ("m4", m4->GetName()); + + EXPECT_TRUE(linker->HasSameReturnType(m1, m2)); + EXPECT_TRUE(linker->HasSameReturnType(m2, m1)); + + EXPECT_TRUE(linker->HasSameReturnType(m1, m2)); + EXPECT_TRUE(linker->HasSameReturnType(m2, m1)); + + EXPECT_FALSE(linker->HasSameReturnType(m1, m4)); + EXPECT_FALSE(linker->HasSameReturnType(m4, m1)); + + EXPECT_TRUE(linker->HasSameArgumentTypes(m1, m2)); + EXPECT_TRUE(linker->HasSameArgumentTypes(m2, m1)); + + EXPECT_FALSE(linker->HasSameArgumentTypes(m1, m3)); + EXPECT_FALSE(linker->HasSameArgumentTypes(m3, m1)); + + EXPECT_FALSE(linker->HasSameArgumentTypes(m1, m4)); + EXPECT_FALSE(linker->HasSameArgumentTypes(m4, m1)); + + EXPECT_TRUE(linker->HasSamePrototype(m1, m2)); + EXPECT_TRUE(linker->HasSamePrototype(m2, m1)); + + EXPECT_FALSE(linker->HasSamePrototype(m1, m3)); + EXPECT_FALSE(linker->HasSamePrototype(m3, m1)); + + EXPECT_FALSE(linker->HasSamePrototype(m3, m4)); + EXPECT_FALSE(linker->HasSamePrototype(m4, m3)); + + EXPECT_FALSE(linker->HasSameName(m1, m2)); + EXPECT_FALSE(linker->HasSameNameAndPrototype(m1, m2)); +} + +TEST_F(ClassLinkerTest, ProtoCompare2) { + ClassLinker* linker = class_linker_.get(); + + scoped_ptr<RawDexFile> proto1_dex_file(OpenRawDexFileBase64(kProtoCompareDex)); + linker->RegisterDexFile(proto1_dex_file.get()); + scoped_ptr<RawDexFile> proto2_dex_file(OpenRawDexFileBase64(kProtoCompare2Dex)); + linker->RegisterDexFile(proto2_dex_file.get()); + + Class* klass1 = linker->FindClass("LProtoCompare;", NULL, proto1_dex_file.get()); + ASSERT_TRUE(klass1 != NULL); + Class* klass2 = linker->FindClass("LProtoCompare2;", NULL, proto2_dex_file.get()); + ASSERT_TRUE(klass2 != NULL); + + Method* m1_1 = klass1->GetVirtualMethod(0); + ASSERT_EQ("m1", m1_1->GetName()); + Method* m2_1 = klass1->GetVirtualMethod(1); + ASSERT_EQ("m2", m2_1->GetName()); + Method* m3_1 = klass1->GetVirtualMethod(2); + ASSERT_EQ("m3", m3_1->GetName()); + Method* m4_1 = klass1->GetVirtualMethod(3); + ASSERT_EQ("m4", m4_1->GetName()); + + Method* m1_2 = klass2->GetVirtualMethod(0); + ASSERT_EQ("m1", m1_2->GetName()); + Method* m2_2 = klass2->GetVirtualMethod(1); + ASSERT_EQ("m2", m2_2->GetName()); + Method* m3_2 = klass2->GetVirtualMethod(2); + ASSERT_EQ("m3", m3_2->GetName()); + Method* m4_2 = klass2->GetVirtualMethod(3); + ASSERT_EQ("m4", m4_2->GetName()); + + EXPECT_TRUE(linker->HasSameNameAndPrototype(m1_1, m1_2)); + EXPECT_TRUE(linker->HasSameNameAndPrototype(m1_2, m1_1)); + + EXPECT_TRUE(linker->HasSameNameAndPrototype(m2_1, m2_2)); + EXPECT_TRUE(linker->HasSameNameAndPrototype(m2_2, m2_1)); + + EXPECT_TRUE(linker->HasSameNameAndPrototype(m3_1, m3_2)); + EXPECT_TRUE(linker->HasSameNameAndPrototype(m3_2, m3_1)); + + EXPECT_TRUE(linker->HasSameNameAndPrototype(m4_1, m4_2)); + EXPECT_TRUE(linker->HasSameNameAndPrototype(m4_2, m4_1)); } } // namespace art diff --git a/src/common_test.h b/src/common_test.h index bb82d19025..26a4348360 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -1,41 +1,15 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/base64.h" -#include "src/heap.h" -#include "src/thread.h" -#include "src/dex_file.h" +#include "base64.h" +#include "heap.h" +#include "thread.h" +#include "class_linker.h" +#include "dex_file.h" #include "gtest/gtest.h" namespace art { -static inline RawDexFile* OpenRawDexFileBase64(const char* base64) { - CHECK(base64 != NULL); - size_t length; - byte* dex_file = DecodeBase64(base64, &length); - if (dex_file == NULL) { - return NULL; - } - return RawDexFile::OpenPtr(dex_file, length); -} - -static inline DexFile* OpenDexFileBase64(const char* base64) { - return DexFile::Open(OpenRawDexFileBase64(base64)); -} - -class RuntimeTest : public testing::Test { - protected: - virtual void SetUp() { - ASSERT_TRUE(Thread::Init()); - ASSERT_TRUE(Thread::Attach() != NULL); - ASSERT_TRUE(Heap::Init()); - } - - virtual void TearDown() { - Heap::Destroy(); - } -}; - // package java.lang; // public class Object {} // @@ -171,4 +145,38 @@ static const char kMyClassNativesDex[] = "AAAACQAAAAwBAAAGAAAAAgAAAFQBAAABIAAAAgAAAJQBAAABEAAABAAAAMABAAACIAAAEwAAAOIB" "AAADIAAAAgAAAHUCAAAAIAAAAgAAAH8CAAAAEAAAAQAAALACAAA="; +static inline RawDexFile* OpenRawDexFileBase64(const char* base64) { + CHECK(base64 != NULL); + size_t length; + byte* dex_file = DecodeBase64(base64, &length); + CHECK(dex_file != NULL); + RawDexFile* raw_dex_file = RawDexFile::OpenPtr(dex_file, length); + CHECK(raw_dex_file != NULL); + return raw_dex_file; +} + +class RuntimeTest : public testing::Test { + protected: + virtual void SetUp() { + ASSERT_TRUE(Thread::Init()); + ASSERT_TRUE(Thread::Attach() != NULL); + ASSERT_TRUE(Heap::Init()); + + java_lang_raw_dex_file_.reset(OpenRawDexFileBase64(kJavaLangDex)); + + std::vector<RawDexFile*> boot_class_path; + boot_class_path.push_back(java_lang_raw_dex_file_.get()); + + class_linker_.reset(ClassLinker::Create(boot_class_path)); + CHECK(class_linker_ != NULL); + } + + virtual void TearDown() { + Heap::Destroy(); + } + + scoped_ptr<RawDexFile> java_lang_raw_dex_file_; + scoped_ptr<ClassLinker> class_linker_; +}; + } // namespace art diff --git a/src/constants.h b/src/constants.h index 22a4043207..2dd13b7195 100644 --- a/src/constants.h +++ b/src/constants.h @@ -4,9 +4,9 @@ #define ART_SRC_CONSTANTS_H_ #if defined(__i386__) -#include "src/constants_x86.h" +#include "constants_x86.h" #elif defined(__arm__) -#include "src/constants_arm.h" +#include "constants_arm.h" #endif #endif // ART_SRC_CONSTANTS_H_ diff --git a/src/constants_arm.h b/src/constants_arm.h index c2aed30ce8..2d2acb7fa2 100644 --- a/src/constants_arm.h +++ b/src/constants_arm.h @@ -5,9 +5,9 @@ #include <stdint.h> #include <iosfwd> -#include "src/casts.h" -#include "src/globals.h" -#include "src/logging.h" +#include "casts.h" +#include "globals.h" +#include "logging.h" namespace art { diff --git a/src/constants_x86.h b/src/constants_x86.h index c7457c9c71..391d0780ca 100644 --- a/src/constants_x86.h +++ b/src/constants_x86.h @@ -4,9 +4,9 @@ #define ART_SRC_CONSTANTS_X86_H_ #include <iosfwd> -#include "src/globals.h" -#include "src/logging.h" -#include "src/macros.h" +#include "globals.h" +#include "logging.h" +#include "macros.h" namespace art { diff --git a/src/dex_file.cc b/src/dex_file.cc index 6cb8258aa1..e3c8fa0919 100644 --- a/src/dex_file.cc +++ b/src/dex_file.cc @@ -1,47 +1,19 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/dex_file.h" -#include "src/heap.h" -#include "src/globals.h" -#include "src/logging.h" -#include "src/object.h" -#include "src/raw_dex_file.h" +#include "dex_file.h" +#include "heap.h" +#include "globals.h" +#include "logging.h" +#include "object.h" +#include "raw_dex_file.h" namespace art { -DexFile* DexFile::OpenFile(const char* filename) { - RawDexFile* raw = RawDexFile::OpenFile(filename); - return Open(raw); -} - -DexFile* DexFile::Open(RawDexFile* raw) { - if (raw == NULL) { - return NULL; - } - DexFile* dex_file = new DexFile(raw); - dex_file->Init(); - return dex_file; -} - -DexFile::~DexFile() { - delete[] strings_; - delete[] classes_; - delete[] methods_; - delete[] fields_; -} - -void DexFile::Init() { - num_strings_ = raw_->NumStringIds(); - strings_ = new String*[num_strings_](); - - num_classes_ = raw_->NumTypeIds(); - classes_ = new Class*[num_classes_](); - - num_methods_ = raw_->NumMethodIds(); - methods_ = new Method*[num_methods_](); - - num_fields_ = raw_->NumFieldIds(); - fields_ = new Field*[num_fields_](); +void DexFile::Init(ObjectArray* strings, ObjectArray* classes, ObjectArray* methods, ObjectArray* fields) { + Set(kStrings, strings); + Set(kClasses, classes); + Set(kMethods, methods); + Set(kFields, fields); } } // namespace art diff --git a/src/dex_file.h b/src/dex_file.h index 1f4afa33c9..63393176c2 100644 --- a/src/dex_file.h +++ b/src/dex_file.h @@ -3,9 +3,9 @@ #ifndef ART_SRC_DEX_FILE_H_ #define ART_SRC_DEX_FILE_H_ -#include "src/globals.h" -#include "src/macros.h" -#include "src/raw_dex_file.h" +#include "globals.h" +#include "macros.h" +#include "object.h" namespace art { @@ -15,82 +15,81 @@ class Method; class String; union JValue; -class DexFile { +class DexFile : public ObjectArray { public: - // Opens a .dex file from the file system. Returns NULL on failure. - static DexFile* OpenFile(const char* filename); - // Opens a .dex file from a RawDexFile. Takes ownership of the - // RawDexFile. - static DexFile* Open(RawDexFile* raw); + enum ArrayIndexes { + kStrings = 0, + kClasses = 1, + kMethods = 2, + kFields = 3, + kMax = 4, + }; - // Close and deallocate. - ~DexFile(); + void Init(ObjectArray* strings, ObjectArray* classes, ObjectArray* methods, ObjectArray* fields); - size_t NumTypes() const { - return num_classes_; + size_t NumStrings() const { + return GetStrings()->GetLength(); } - size_t NumMethods() const { - return num_methods_; + size_t NumClasses() const { + return GetClasses()->GetLength(); } - bool HasClass(const StringPiece& descriptor) { - return raw_->FindClassDef(descriptor) != NULL; + size_t NumMethods() const { + return GetMethods()->GetLength(); } - RawDexFile* GetRaw() const { - return raw_.get(); + size_t NumFields() const { + return GetFields()->GetLength(); } String* GetResolvedString(uint32_t string_idx) const { - CHECK_LT(string_idx, num_strings_); - return strings_[string_idx]; + return down_cast<String*>(GetStrings()->Get(string_idx)); } - void SetResolvedString(String* resolved, uint32_t string_idx) { - CHECK_LT(string_idx, num_strings_); - strings_[string_idx] = resolved; + void SetResolvedString(uint32_t string_idx, String* resolved) { + GetStrings()->Set(string_idx, resolved); } Class* GetResolvedClass(uint32_t class_idx) const { - CHECK_LT(class_idx, num_classes_); - return classes_[class_idx]; + return down_cast<Class*>(GetClasses()->Get(class_idx)); } - void SetResolvedClass(Class* resolved, uint32_t class_idx) { - CHECK_LT(class_idx, num_classes_); - classes_[class_idx] = resolved; + void SetResolvedClass(uint32_t class_idx, Class* resolved) { + GetClasses()->Set(class_idx, resolved); } - private: - DexFile(RawDexFile* raw) : raw_(raw) {}; - - void Init(); - - // Table of contents for interned String objects. - String** strings_; - size_t num_strings_; - - // Table of contents for Class objects. - Class** classes_; - size_t num_classes_; - - // Table of contents for methods. - Method** methods_; - size_t num_methods_; + Method* GetResolvedMethod(uint32_t method_idx) const { + return down_cast<Method*>(GetMethods()->Get(method_idx)); + } - // Table of contents for fields. - Field** fields_; - size_t num_fields_; + void SetResolvedMethod(uint32_t method_idx, Method* resolved) { + GetMethods()->Set(method_idx, resolved); + } - // The size of the DEX file, in bytes. - size_t length_; + Field* GetResolvedField(uint32_t field_idx) const { + return down_cast<Field*>(GetFields()->Get(field_idx)); + } - // The underlying dex file. - scoped_ptr<RawDexFile> raw_; + void SetResolvedfield(uint32_t field_idx, Field* resolved) { + GetFields()->Set(field_idx, resolved); + } - DISALLOW_COPY_AND_ASSIGN(DexFile); + private: + ObjectArray* GetStrings() const { + return down_cast<ObjectArray*>(Get(kStrings)); + } + ObjectArray* GetClasses() const { + return down_cast<ObjectArray*>(Get(kClasses)); + } + ObjectArray* GetMethods() const { + return down_cast<ObjectArray*>(Get(kMethods)); + } + ObjectArray* GetFields() const { + return down_cast<ObjectArray*>(Get(kFields)); + } + DexFile(); }; } // namespace art diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc index 561c740b55..0ad0b3b5e0 100644 --- a/src/dex_file_test.cc +++ b/src/dex_file_test.cc @@ -1,18 +1,31 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/common_test.h" -#include "src/dex_file.h" -#include "src/object.h" -#include "src/scoped_ptr.h" +#include "class_linker.h" +#include "common_test.h" +#include "dex_file.h" +#include "heap.h" +#include "object.h" +#include "scoped_ptr.h" #include <stdio.h> #include "gtest/gtest.h" namespace art { -TEST(DexFileTest, Open) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kNestedDex)); - ASSERT_TRUE(dex != NULL); +class DexFileTest : public RuntimeTest {}; + +TEST_F(DexFileTest, Open) { + + DexFile* dex_file = down_cast<DexFile*>(class_linker_->AllocObjectArray(DexFile::kMax)); + ASSERT_TRUE(dex_file != NULL); + dex_file->Init(class_linker_->AllocObjectArray(1), + class_linker_->AllocObjectArray(2), + class_linker_->AllocObjectArray(3), + class_linker_->AllocObjectArray(4)); + EXPECT_EQ(1U, dex_file->NumStrings()); + EXPECT_EQ(2U, dex_file->NumClasses()); + EXPECT_EQ(3U, dex_file->NumMethods()); + EXPECT_EQ(4U, dex_file->NumFields()); } } // namespace art diff --git a/src/dex_instruction.cc b/src/dex_instruction.cc index 37585a62ee..d753204326 100644 --- a/src/dex_instruction.cc +++ b/src/dex_instruction.cc @@ -1,12 +1,12 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/dex_instruction.h" +#include "dex_instruction.h" namespace art { const char* const Instruction::kInstructionNames[] = { #define INSTRUCTION_NAME(o, c, pname, f, r, i, a) pname, -#include "src/dex_instruction_list.h" +#include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_NAME) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_NAME @@ -14,7 +14,7 @@ const char* const Instruction::kInstructionNames[] = { Instruction::InstructionFormat const Instruction::kInstructionFormats[] = { #define INSTRUCTION_FORMAT(o, c, p, format, r, i, a) format, -#include "src/dex_instruction_list.h" +#include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_FORMAT @@ -22,7 +22,7 @@ Instruction::InstructionFormat const Instruction::kInstructionFormats[] = { int const Instruction::kInstructionFlags[] = { #define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags) flags, -#include "src/dex_instruction_list.h" +#include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_FLAGS diff --git a/src/dex_instruction.h b/src/dex_instruction.h index f1bb7bf1cd..617f818192 100644 --- a/src/dex_instruction.h +++ b/src/dex_instruction.h @@ -3,9 +3,9 @@ #ifndef ART_SRC_DEX_INSTRUCTION_H_ #define ART_SRC_DEX_INSTRUCTION_H_ -#include "src/globals.h" -#include "src/logging.h" -#include "src/macros.h" +#include "globals.h" +#include "logging.h" +#include "macros.h" namespace art { @@ -20,7 +20,7 @@ class Instruction { enum Code { #define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a) cname = opcode, -#include "src/dex_instruction_list.h" +#include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_ENUM diff --git a/src/dex_instruction_visitor.h b/src/dex_instruction_visitor.h index 2af26e3787..f7fdf77bce 100644 --- a/src/dex_instruction_visitor.h +++ b/src/dex_instruction_visitor.h @@ -3,8 +3,8 @@ #ifndef ART_SRC_DEX_INSTRUCTION_VISITOR_H_ #define ART_SRC_DEX_INSTRUCTION_VISITOR_H_ -#include "src/dex_instruction.h" -#include "src/macros.h" +#include "dex_instruction.h" +#include "macros.h" namespace art { @@ -23,7 +23,7 @@ class DexInstructionVisitor { derived->Do_ ## cname(inst); \ break; \ } -#include "src/dex_instruction_list.h" +#include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_CASE) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_CASE @@ -42,7 +42,7 @@ class DexInstructionVisitor { T* derived = static_cast<T*>(this); \ derived->Do_Default(inst); \ }; -#include "src/dex_instruction_list.h" +#include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_VISITOR) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_VISITOR diff --git a/src/dex_instruction_visitor_test.cc b/src/dex_instruction_visitor_test.cc index 3889d73069..ff24e52b3c 100644 --- a/src/dex_instruction_visitor_test.cc +++ b/src/dex_instruction_visitor_test.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/dex_instruction_visitor.h" -#include "src/scoped_ptr.h" +#include "dex_instruction_visitor.h" +#include "scoped_ptr.h" #include <iostream> #include "gtest/gtest.h" diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc index 53bc3059e9..63f6e8c71c 100644 --- a/src/dex_verifier.cc +++ b/src/dex_verifier.cc @@ -1,6 +1,6 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/dex_verifier.h" +#include "dex_verifier.h" #include <iostream> diff --git a/src/dex_verifier.h b/src/dex_verifier.h index eb4c6e3f97..03b2c9673e 100644 --- a/src/dex_verifier.h +++ b/src/dex_verifier.h @@ -3,8 +3,8 @@ #ifndef ART_SRC_DEX_VERIFY_H_ #define ART_SRC_DEX_VERIFY_H_ -#include "src/macros.h" -#include "src/object.h" +#include "macros.h" +#include "object.h" namespace art { diff --git a/src/heap.cc b/src/heap.cc index bbdf80a181..3955a31723 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -1,9 +1,9 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/heap.h" -#include "src/object.h" -#include "src/space.h" +#include "heap.h" +#include "object.h" +#include "space.h" namespace art { diff --git a/src/heap.h b/src/heap.h index f35e3f8571..3721604da5 100644 --- a/src/heap.h +++ b/src/heap.h @@ -4,10 +4,10 @@ #ifndef ART_SRC_HEAP_H_ #define ART_SRC_HEAP_H_ -#include "src/globals.h" -#include "src/object.h" -#include "src/object_bitmap.h" -#include "src/thread.h" +#include "globals.h" +#include "object.h" +#include "object_bitmap.h" +#include "thread.h" namespace art { @@ -40,13 +40,21 @@ class Heap { return obj; } - static CharArray* AllocCharArray(Class* char_array, size_t length) { - size_t size = sizeof(Array) + length * sizeof(uint16_t); - Object* new_array = AllocObject(char_array, size); - if (new_array != NULL) { - char_array->klass_ = char_array; + static Array* AllocArray(Class* array_class, size_t component_count, size_t component_size) { + size_t size = sizeof(Array) + component_count * component_size; + Array* array = down_cast<Array*>(AllocObject(array_class, size)); + if (array != NULL) { + array->SetLength(component_count); } - return down_cast<CharArray*>(new_array); + return array; + } + + static ObjectArray* AllocObjectArray(Class* object_array_class, size_t length) { + return down_cast<ObjectArray*>(AllocArray(object_array_class, length, sizeof(uint32_t))); + } + + static CharArray* AllocCharArray(Class* char_array_class, size_t length) { + return down_cast<CharArray*>(AllocArray(char_array_class, length, sizeof(uint16_t))); } static String* AllocString(Class* java_lang_String) { diff --git a/src/jni_compiler.cc b/src/jni_compiler.cc index a6f5fafdcf..f80e7ad20e 100644 --- a/src/jni_compiler.cc +++ b/src/jni_compiler.cc @@ -1,14 +1,17 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: irogers@google.com (Ian Rogers) -#include "src/jni_compiler.h" + +#include "jni_compiler.h" + #include <sys/mman.h> -#include "src/assembler.h" -#include "src/calling_convention.h" -#include "src/jni_internal.h" -#include "src/macros.h" -#include "src/managed_register.h" -#include "src/logging.h" -#include "src/thread.h" + +#include "assembler.h" +#include "calling_convention.h" +#include "jni_internal.h" +#include "macros.h" +#include "managed_register.h" +#include "logging.h" +#include "thread.h" namespace art { diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc index db8a9e7a93..c7af269fe0 100644 --- a/src/jni_compiler_test.cc +++ b/src/jni_compiler_test.cc @@ -2,22 +2,26 @@ // Author: irogers@google.com (Ian Rogers) #include <sys/mman.h> -#include "src/assembler.h" -#include "src/class_linker.h" -#include "src/common_test.h" -#include "src/dex_file.h" -#include "src/jni_compiler.h" -#include "src/runtime.h" -#include "src/thread.h" + +#include "assembler.h" +#include "class_linker.h" +#include "common_test.h" +#include "dex_file.h" +#include "jni_compiler.h" +#include "runtime.h" +#include "thread.h" #include "gtest/gtest.h" namespace art { -class JniCompilerTest : public testing::Test { +class JniCompilerTest : public RuntimeTest { protected: virtual void SetUp() { + RuntimeTest::SetUp(); // Create runtime and attach thread - runtime_ = Runtime::Create(); + std::vector<RawDexFile*> boot_class_path; + boot_class_path.push_back(java_lang_raw_dex_file_.get()); + runtime_ = Runtime::Create(boot_class_path); CHECK(runtime_->AttachCurrentThread()); // Create thunk code that performs the native to managed transition thunk_code_size_ = 4096; @@ -180,10 +184,9 @@ jobject Java_MyClass_fooSSIOO(JNIEnv*, jclass klass, jint x, jobject y, } TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("foo"); Assembler jni_asm; @@ -206,10 +209,9 @@ TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) { } TEST_F(JniCompilerTest, CompileAndRunIntMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("fooI"); Assembler jni_asm; @@ -234,10 +236,9 @@ TEST_F(JniCompilerTest, CompileAndRunIntMethod) { } TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("fooII"); Assembler jni_asm; @@ -265,10 +266,9 @@ TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) { TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("fooDD"); Assembler jni_asm; @@ -295,10 +295,9 @@ TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) { } TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("fooIOO"); Assembler jni_asm; @@ -351,10 +350,9 @@ TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) { } TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindDirectMethod("fooSIOO"); Assembler jni_asm; @@ -404,10 +402,9 @@ TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) { } TEST_F(JniCompilerTest, CompileAndRunStaticSynchronizedIntObjectObjectMethod) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindDirectMethod("fooSSIOO"); Assembler jni_asm; @@ -463,10 +460,9 @@ void SuspendCountHandler(Method** frame) { Thread::Current()->DecrementSuspendCount(); } TEST_F(JniCompilerTest, SuspendCountAcknolewdgement) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("fooI"); Assembler jni_asm; @@ -505,10 +501,9 @@ void ExceptionHandler(Method** frame) { Thread::Current()->ClearException(); } TEST_F(JniCompilerTest, ExceptionHandling) { - scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex)); - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(dex.get()); - Class* klass = linker->FindClass("LMyClass;", NULL); + scoped_ptr<RawDexFile> dex(OpenRawDexFileBase64(kMyClassNativesDex)); + class_linker_.get()->RegisterDexFile(dex.get()); + Class* klass = class_linker_.get()->FindClass("LMyClass;", NULL, dex.get()); Method* method = klass->FindVirtualMethod("foo"); Assembler jni_asm; diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 7a5025afca..74f8961216 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/jni_internal.h" -#include "src/logging.h" +#include "jni_internal.h" +#include "logging.h" namespace art { diff --git a/src/jni_internal.h b/src/jni_internal.h index 64941cc471..e1474abae3 100644 --- a/src/jni_internal.h +++ b/src/jni_internal.h @@ -4,8 +4,9 @@ #define ART_SRC_JNI_INTERNAL_H_ #include "jni.h" -#include "src/assembler.h" -#include "src/macros.h" + +#include "assembler.h" +#include "macros.h" namespace art { diff --git a/src/leb128.h b/src/leb128.h index aa8b895f2d..51df6c92f8 100644 --- a/src/leb128.h +++ b/src/leb128.h @@ -3,7 +3,7 @@ #ifndef ART_SRC_LEB128_H_ #define ART_SRC_LEB128_H_ -#include "src/globals.h" +#include "globals.h" namespace art { diff --git a/src/managed_register.h b/src/managed_register.h index 7e077a088d..2540895089 100644 --- a/src/managed_register.h +++ b/src/managed_register.h @@ -4,9 +4,9 @@ #define ART_SRC_MANAGED_REGISTER_H_ #if defined(__i386__) -#include "src/managed_register_x86.h" +#include "managed_register_x86.h" #elif defined(__arm__) -#include "src/managed_register_arm.h" +#include "managed_register_arm.h" #else #error Unknown architecture. #endif diff --git a/src/managed_register_arm.cc b/src/managed_register_arm.cc index d20368946d..227467e0c0 100644 --- a/src/managed_register_arm.cc +++ b/src/managed_register_arm.cc @@ -1,8 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/globals.h" -#include "src/calling_convention.h" -#include "src/managed_register.h" +#include "globals.h" +#include "calling_convention.h" +#include "managed_register.h" namespace art { diff --git a/src/managed_register_arm.h b/src/managed_register_arm.h index 843095c241..a132fa9afb 100644 --- a/src/managed_register_arm.h +++ b/src/managed_register_arm.h @@ -3,8 +3,8 @@ #ifndef ART_SRC_MANAGED_REGISTER_ARM_H_ #define ART_SRC_MANAGED_REGISTER_ARM_H_ -#include "src/constants.h" -#include "src/logging.h" +#include "constants.h" +#include "logging.h" namespace art { diff --git a/src/managed_register_arm_test.cc b/src/managed_register_arm_test.cc index 7ffe894e0e..238291f44d 100644 --- a/src/managed_register_arm_test.cc +++ b/src/managed_register_arm_test.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/globals.h" -#include "src/managed_register_arm.h" +#include "globals.h" +#include "managed_register_arm.h" #include "gtest/gtest.h" namespace art { diff --git a/src/managed_register_x86.cc b/src/managed_register_x86.cc index 414c51b868..d2271fb03e 100644 --- a/src/managed_register_x86.cc +++ b/src/managed_register_x86.cc @@ -1,8 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/globals.h" -#include "src/calling_convention.h" -#include "src/managed_register.h" +#include "globals.h" +#include "calling_convention.h" +#include "managed_register.h" namespace art { diff --git a/src/managed_register_x86.h b/src/managed_register_x86.h index 5d906c3469..1d38d7fcd6 100644 --- a/src/managed_register_x86.h +++ b/src/managed_register_x86.h @@ -3,7 +3,7 @@ #ifndef ART_SRC_MANAGED_REGISTER_X86_H_ #define ART_SRC_MANAGED_REGISTER_X86_H_ -#include "src/constants_x86.h" +#include "constants_x86.h" namespace art { diff --git a/src/managed_register_x86_test.cc b/src/managed_register_x86_test.cc index 3192bb3b88..2059f65cf2 100644 --- a/src/managed_register_x86_test.cc +++ b/src/managed_register_x86_test.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/globals.h" -#include "src/managed_register.h" +#include "globals.h" +#include "managed_register.h" #include "gtest/gtest.h" namespace art { diff --git a/src/mark_stack.cc b/src/mark_stack.cc index 1d6634645c..c6d77123af 100644 --- a/src/mark_stack.cc +++ b/src/mark_stack.cc @@ -1,13 +1,13 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/mark_stack.h" +#include "mark_stack.h" #include <sys/mman.h> -#include "src/globals.h" -#include "src/logging.h" -#include "src/scoped_ptr.h" +#include "globals.h" +#include "logging.h" +#include "scoped_ptr.h" namespace art { diff --git a/src/mark_stack.h b/src/mark_stack.h index 3f9d5e91e9..a3e19e909f 100644 --- a/src/mark_stack.h +++ b/src/mark_stack.h @@ -4,8 +4,8 @@ #ifndef ART_SRC_MARK_STACK_H_ #define ART_SRC_MARK_STACK_H_ -#include "src/logging.h" -#include "src/macros.h" +#include "logging.h" +#include "macros.h" namespace art { diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc index 5ab9e3eea5..d2e7b66eff 100644 --- a/src/mark_sweep.cc +++ b/src/mark_sweep.cc @@ -1,13 +1,13 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/mark_sweep.h" +#include "mark_sweep.h" -#include "src/logging.h" -#include "src/macros.h" -#include "src/mark_stack.h" -#include "src/object.h" -#include "src/thread.h" +#include "logging.h" +#include "macros.h" +#include "mark_stack.h" +#include "object.h" +#include "thread.h" #define CLZ(x) __builtin_clz(x) diff --git a/src/mark_sweep.h b/src/mark_sweep.h index 98fbf1b43b..d0c0a44d1b 100644 --- a/src/mark_sweep.h +++ b/src/mark_sweep.h @@ -4,9 +4,9 @@ #ifndef ART_SRC_MARK_SWEEP_H_ #define ART_SRC_MARK_SWEEP_H_ -#include "src/macros.h" -#include "src/mark_stack.h" -#include "src/object_bitmap.h" +#include "macros.h" +#include "mark_stack.h" +#include "object_bitmap.h" namespace art { diff --git a/src/memory_region.cc b/src/memory_region.cc index 30d61edc78..987db51807 100644 --- a/src/memory_region.cc +++ b/src/memory_region.cc @@ -2,9 +2,9 @@ #include <stdint.h> #include <string.h> -#include "src/globals.h" -#include "src/logging.h" -#include "src/memory_region.h" +#include "globals.h" +#include "logging.h" +#include "memory_region.h" namespace art { diff --git a/src/memory_region.h b/src/memory_region.h index f5382cd288..3d04d91d92 100644 --- a/src/memory_region.h +++ b/src/memory_region.h @@ -4,10 +4,10 @@ #define ART_SRC_MEMORY_REGION_H_ #include <stdint.h> -#include "src/globals.h" -#include "src/logging.h" -#include "src/macros.h" -#include "src/memory_region.h" +#include "globals.h" +#include "logging.h" +#include "macros.h" +#include "memory_region.h" namespace art { diff --git a/src/monitor.h b/src/monitor.h index f624056d35..2f5b5ff128 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -4,8 +4,8 @@ #ifndef ART_SRC_MONITOR_H_ #define ART_SRC_MONITOR_H_ -#include "src/logging.h" -#include "src/macros.h" +#include "logging.h" +#include "macros.h" namespace art { diff --git a/src/object.cc b/src/object.cc index c79271d07e..fb80fb96e1 100644 --- a/src/object.cc +++ b/src/object.cc @@ -1,12 +1,14 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/object.h" +#include "object.h" + #include <string.h> #include <algorithm> -#include "src/globals.h" -#include "src/logging.h" -#include "src/dex_file.h" -#include "src/raw_dex_file.h" + +#include "globals.h" +#include "logging.h" +#include "dex_file.h" +#include "raw_dex_file.h" namespace art { @@ -152,50 +154,6 @@ size_t Method::ReturnSize() const { return ShortyCharToSize(shorty_[0]); } -bool Method::HasSameArgumentTypes(const Method* that) const { - const RawDexFile* raw1 = this->GetClass()->GetDexFile()->GetRaw(); - const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(this->proto_idx_); - const RawDexFile* raw2 = that->GetClass()->GetDexFile()->GetRaw(); - const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(that->proto_idx_); - - // TODO: compare ProtoId objects for equality and exit early - - const RawDexFile::TypeList* type_list1 = raw1->GetProtoParameters(proto1); - size_t arity1 = (type_list1 == NULL) ? 0 : type_list1->Size(); - const RawDexFile::TypeList* type_list2 = raw2->GetProtoParameters(proto2); - size_t arity2 = (type_list2 == NULL) ? 0 : type_list2->Size(); - - if (arity1 != arity2) { - return false; - } - - for (size_t i = 0; i < arity1; ++i) { - uint32_t type_idx1 = type_list1->GetTypeItem(i).type_idx_; - const char* type1 = raw1->dexStringByTypeIdx(type_idx1); - - uint32_t type_idx2 = type_list2->GetTypeItem(i).type_idx_; - const char* type2 = raw2->dexStringByTypeIdx(type_idx2); - - if (strcmp(type1, type2) != 0) { - return false; - } - } - - return true; -} - -bool Method::HasSameReturnType(const Method* that) const { - const RawDexFile* raw1 = this->GetClass()->GetDexFile()->GetRaw(); - const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(this->proto_idx_); - const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_); - - const RawDexFile* raw2 = that->GetClass()->GetDexFile()->GetRaw(); - const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(that->proto_idx_); - const char* type2 = raw2->dexStringByTypeIdx(proto2.return_type_idx_); - - return (strcmp(type1, type2) == 0); -} - Method* Class::FindDirectMethod(const StringPiece& name) const { Method* result = NULL; for (size_t i = 0; i < NumDirectMethods(); i++) { diff --git a/src/object.h b/src/object.h index 218aed94e1..abbf6ca390 100644 --- a/src/object.h +++ b/src/object.h @@ -3,15 +3,14 @@ #ifndef ART_SRC_OBJECT_H_ #define ART_SRC_OBJECT_H_ -#include "src/constants.h" -#include "src/casts.h" -#include "src/dex_file.h" -#include "src/globals.h" -#include "src/logging.h" -#include "src/macros.h" -#include "src/offsets.h" -#include "src/stringpiece.h" -#include "src/monitor.h" +#include "constants.h" +#include "casts.h" +#include "globals.h" +#include "logging.h" +#include "macros.h" +#include "offsets.h" +#include "stringpiece.h" +#include "monitor.h" namespace art { @@ -433,22 +432,6 @@ class Method : public Object { // Number of argument registers required by the prototype. uint32_t NumArgRegisters(); - bool HasSameNameAndPrototype(const Method* that) const { - return HasSameName(that) && HasSamePrototype(that); - } - - bool HasSameName(const Method* that) const { - return this->GetName() == that->GetName(); - } - - bool HasSamePrototype(const Method* that) const { - return HasSameReturnType(that) && HasSameArgumentTypes(that); - } - - bool HasSameReturnType(const Method* that) const; - - bool HasSameArgumentTypes(const Method* that) const; - public: // TODO: private #define METHOD_FIELD_SLOTS 1+11 // AccessibleObject #0 flag @@ -911,26 +894,32 @@ std::ostream& operator<<(std::ostream& os, const Class::Status& rhs); class DataObject : public Object { public: - uint32_t fields_[1]; + uint32_t fields_[0]; private: DataObject(); }; class Array : public Object { public: - uint32_t GetLength() const{ + uint32_t GetLength() const { return length_; } - void SetLength(uint32_t length) { length_ = length; } + const void* GetData() const { + return &elements_; + } + void* GetData() { + return &elements_; + } private: // The number of array elements. uint32_t length_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(Array); + // Location of first element. + uint32_t elements_[0]; + Array(); }; class CharArray : public Array { @@ -940,19 +929,20 @@ class CharArray : public Array { class ObjectArray : public Array { public: - Object* Get(int32_t i) { - return NULL; + Object* Get(uint32_t i) const { + DCHECK_LT(i, GetLength()); + Object* const * data = reinterpret_cast<Object* const *>(GetData()); + return data[i]; } - - const Object* Get(int32_t i) const { - return NULL; + void Set(uint32_t i, Object* object) { + DCHECK_LT(i, GetLength()); + Object** data = reinterpret_cast<Object**>(GetData()); + data[i] = object; } - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectArray); + ObjectArray(); }; - class String : public Object { public: CharArray* array_; diff --git a/src/object_bitmap.cc b/src/object_bitmap.cc index 7234143996..85fee73fd0 100644 --- a/src/object_bitmap.cc +++ b/src/object_bitmap.cc @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/object_bitmap.h" +#include "object_bitmap.h" #include <sys/mman.h> -#include "src/logging.h" -#include "src/scoped_ptr.h" +#include "logging.h" +#include "scoped_ptr.h" namespace art { diff --git a/src/object_bitmap.h b/src/object_bitmap.h index 3e779b2abb..d766a832ca 100644 --- a/src/object_bitmap.h +++ b/src/object_bitmap.h @@ -18,8 +18,8 @@ #include <limits.h> #include <stdint.h> -#include "src/globals.h" -#include "src/logging.h" +#include "globals.h" +#include "logging.h" namespace art { diff --git a/src/object_test.cc b/src/object_test.cc index 334461a37b..6598167a10 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -1,12 +1,12 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/class_linker.h" -#include "src/common_test.h" -#include "src/dex_file.h" -#include "src/heap.h" -#include "src/object.h" -#include "src/scoped_ptr.h" +#include "class_linker.h" +#include "common_test.h" +#include "dex_file.h" +#include "heap.h" +#include "object.h" +#include "scoped_ptr.h" #include <stdio.h> #include "gtest/gtest.h" @@ -29,116 +29,17 @@ TEST_F(ObjectTest, IsInSamePackage) { "Ljava/lang/reflect/Method;")); } -class MethodTest : public RuntimeTest {}; - -// TODO: test 0 argument methods -// TODO: make this test simpler and shorter -TEST_F(MethodTest, ProtoCompare) { - scoped_ptr<DexFile> object_dex_file(OpenDexFileBase64(kJavaLangDex)); - ASSERT_TRUE(object_dex_file != NULL); - scoped_ptr<DexFile> proto_dex_file(OpenDexFileBase64(kProtoCompareDex)); - ASSERT_TRUE(proto_dex_file != NULL); - - scoped_ptr<ClassLinker> linker(ClassLinker::Create()); - linker->AppendToClassPath(object_dex_file.get()); - linker->AppendToClassPath(proto_dex_file.get()); - - Class* klass = linker->FindClass("LProtoCompare;", NULL); - ASSERT_TRUE(klass != NULL); - - ASSERT_EQ(4U, klass->NumVirtualMethods()); - - Method* m1 = klass->GetVirtualMethod(0u); - ASSERT_EQ("m1", m1->GetName()); - - Method* m2 = klass->GetVirtualMethod(1); - ASSERT_EQ("m2", m2->GetName()); - - Method* m3 = klass->GetVirtualMethod(2); - ASSERT_EQ("m3", m3->GetName()); - - Method* m4 = klass->GetVirtualMethod(3); - ASSERT_EQ("m4", m4->GetName()); - - EXPECT_TRUE(m1->HasSameReturnType(m2)); - EXPECT_TRUE(m2->HasSameReturnType(m1)); - - EXPECT_TRUE(m1->HasSameReturnType(m2)); - EXPECT_TRUE(m2->HasSameReturnType(m1)); - - EXPECT_FALSE(m1->HasSameReturnType(m4)); - EXPECT_FALSE(m4->HasSameReturnType(m1)); - - EXPECT_TRUE(m1->HasSameArgumentTypes(m2)); - EXPECT_TRUE(m2->HasSameArgumentTypes(m1)); - - EXPECT_FALSE(m1->HasSameArgumentTypes(m3)); - EXPECT_FALSE(m3->HasSameArgumentTypes(m1)); - - EXPECT_FALSE(m1->HasSameArgumentTypes(m4)); - EXPECT_FALSE(m4->HasSameArgumentTypes(m1)); - - EXPECT_TRUE(m1->HasSamePrototype(m2)); - EXPECT_TRUE(m2->HasSamePrototype(m1)); - - EXPECT_FALSE(m1->HasSamePrototype(m3)); - EXPECT_FALSE(m3->HasSamePrototype(m1)); - - EXPECT_FALSE(m3->HasSamePrototype(m4)); - EXPECT_FALSE(m4->HasSamePrototype(m3)); - - EXPECT_FALSE(m1->HasSameName(m2)); - EXPECT_FALSE(m1->HasSameNameAndPrototype(m2)); -} - -TEST_F(MethodTest, ProtoCompare2) { - scoped_ptr<DexFile> object_dex_file(OpenDexFileBase64(kJavaLangDex)); - ASSERT_TRUE(object_dex_file != NULL); - scoped_ptr<DexFile> proto1_dex_file(OpenDexFileBase64(kProtoCompareDex)); - ASSERT_TRUE(proto1_dex_file != NULL); - scoped_ptr<DexFile> proto2_dex_file(OpenDexFileBase64(kProtoCompare2Dex)); - ASSERT_TRUE(proto2_dex_file != NULL); - scoped_ptr<ClassLinker> linker1(ClassLinker::Create()); - linker1->AppendToClassPath(object_dex_file.get()); - linker1->AppendToClassPath(proto1_dex_file.get()); - scoped_ptr<ClassLinker> linker2(ClassLinker::Create()); - linker2->AppendToClassPath(object_dex_file.get()); - linker2->AppendToClassPath(proto2_dex_file.get()); - - Class* klass1 = linker1->FindClass("LProtoCompare;", NULL); - ASSERT_TRUE(klass1 != NULL); - Class* klass2 = linker2->FindClass("LProtoCompare2;", NULL); - ASSERT_TRUE(klass2 != NULL); - - Method* m1_1 = klass1->GetVirtualMethod(0u); - ASSERT_EQ("m1", m1_1->GetName()); - Method* m2_1 = klass1->GetVirtualMethod(1); - ASSERT_EQ("m2", m2_1->GetName()); - Method* m3_1 = klass1->GetVirtualMethod(2); - ASSERT_EQ("m3", m3_1->GetName()); - Method* m4_1 = klass1->GetVirtualMethod(3); - ASSERT_EQ("m4", m4_1->GetName()); - - Method* m1_2 = klass2->GetVirtualMethod(0u); - ASSERT_EQ("m1", m1_2->GetName()); - Method* m2_2 = klass2->GetVirtualMethod(1); - ASSERT_EQ("m2", m2_2->GetName()); - Method* m3_2 = klass2->GetVirtualMethod(2); - ASSERT_EQ("m3", m3_2->GetName()); - Method* m4_2 = klass2->GetVirtualMethod(3); - ASSERT_EQ("m4", m4_2->GetName()); - - EXPECT_TRUE(m1_1->HasSameNameAndPrototype(m1_2)); - EXPECT_TRUE(m1_2->HasSameNameAndPrototype(m1_1)); - - EXPECT_TRUE(m2_1->HasSameNameAndPrototype(m2_2)); - EXPECT_TRUE(m2_2->HasSameNameAndPrototype(m2_1)); - - EXPECT_TRUE(m3_1->HasSameNameAndPrototype(m3_2)); - EXPECT_TRUE(m3_2->HasSameNameAndPrototype(m3_1)); - - EXPECT_TRUE(m4_1->HasSameNameAndPrototype(m4_2)); - EXPECT_TRUE(m4_2->HasSameNameAndPrototype(m4_1)); +TEST_F(ObjectTest, AllocObjectArray) { + ObjectArray* oa = class_linker_->AllocObjectArray(2); + EXPECT_EQ(2U, oa->GetLength()); + EXPECT_TRUE(oa->Get(0) == NULL); + EXPECT_TRUE(oa->Get(1) == NULL); + oa->Set(0, oa); + EXPECT_TRUE(oa->Get(0) == oa); + EXPECT_TRUE(oa->Get(1) == NULL); + oa->Set(1, oa); + EXPECT_TRUE(oa->Get(0) == oa); + EXPECT_TRUE(oa->Get(1) == oa); } } // namespace art diff --git a/src/offsets.cc b/src/offsets.cc index 1dce268e89..6fdc4d149c 100644 --- a/src/offsets.cc +++ b/src/offsets.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/offsets.h" +#include "offsets.h" #include <iostream> // NOLINT diff --git a/src/offsets.h b/src/offsets.h index 33f395fdc5..2fe873cf8f 100644 --- a/src/offsets.h +++ b/src/offsets.h @@ -5,7 +5,7 @@ #define ART_SRC_OFFSETS_H_ #include <iostream> // NOLINT -#include "src/globals.h" +#include "globals.h" namespace art { diff --git a/src/raw_dex_file.cc b/src/raw_dex_file.cc index d03723df1c..21badb4b7d 100644 --- a/src/raw_dex_file.cc +++ b/src/raw_dex_file.cc @@ -1,6 +1,6 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/raw_dex_file.h" +#include "raw_dex_file.h" #include <fcntl.h> #include <string.h> @@ -9,11 +9,11 @@ #include <sys/types.h> #include <map> -#include "src/globals.h" -#include "src/logging.h" -#include "src/object.h" -#include "src/scoped_ptr.h" -#include "src/utils.h" +#include "globals.h" +#include "logging.h" +#include "object.h" +#include "scoped_ptr.h" +#include "utils.h" namespace art { diff --git a/src/raw_dex_file.h b/src/raw_dex_file.h index 0bfab121c2..da7cd86b51 100644 --- a/src/raw_dex_file.h +++ b/src/raw_dex_file.h @@ -3,12 +3,12 @@ #ifndef ART_SRC_RAW_DEX_FILE_H_ #define ART_SRC_RAW_DEX_FILE_H_ -#include "src/globals.h" -#include "src/leb128.h" -#include "src/logging.h" -#include "src/scoped_ptr.h" -#include "src/stringpiece.h" -#include "src/strutil.h" +#include "globals.h" +#include "leb128.h" +#include "logging.h" +#include "scoped_ptr.h" +#include "stringpiece.h" +#include "strutil.h" #include <map> diff --git a/src/raw_dex_file_test.cc b/src/raw_dex_file_test.cc index 0395bbdea6..4be9991d69 100644 --- a/src/raw_dex_file_test.cc +++ b/src/raw_dex_file_test.cc @@ -1,9 +1,9 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/common_test.h" -#include "src/dex_file.h" -#include "src/raw_dex_file.h" -#include "src/scoped_ptr.h" +#include "common_test.h" +#include "dex_file.h" +#include "raw_dex_file.h" +#include "scoped_ptr.h" #include <stdio.h> #include "gtest/gtest.h" diff --git a/src/runtime.cc b/src/runtime.cc index 3adaea7578..be926c3873 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1,13 +1,13 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/runtime.h" +#include "runtime.h" #include <cstdio> #include <cstdlib> -#include "src/class_linker.h" -#include "src/heap.h" -#include "src/thread.h" +#include "class_linker.h" +#include "heap.h" +#include "thread.h" namespace art { @@ -44,9 +44,9 @@ void Runtime::Abort(const char* file, int line) { // notreached } -Runtime* Runtime::Create() { +Runtime* Runtime::Create(std::vector<RawDexFile*> boot_class_path) { scoped_ptr<Runtime> runtime(new Runtime()); - bool success = runtime->Init(); + bool success = runtime->Init(boot_class_path); if (!success) { return NULL; } else { @@ -54,13 +54,13 @@ Runtime* Runtime::Create() { } } -bool Runtime::Init() { +bool Runtime::Init(std::vector<RawDexFile*> boot_class_path) { thread_list_ = ThreadList::Create(); Heap::Init(Heap::kStartupSize, Heap::kMaximumSize); Thread::Init(); Thread* current_thread = Thread::Attach(); thread_list_->Register(current_thread); - class_linker_ = ClassLinker::Create(); + class_linker_ = ClassLinker::Create(boot_class_path); return true; } diff --git a/src/runtime.h b/src/runtime.h index cbccccbea9..69f6228014 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -3,9 +3,12 @@ #ifndef ART_SRC_RUNTIME_H_ #define ART_SRC_RUNTIME_H_ -#include "src/globals.h" -#include "src/macros.h" -#include "src/stringpiece.h" +#include <vector> + +#include "globals.h" +#include "macros.h" +#include "raw_dex_file.h" +#include "stringpiece.h" namespace art { @@ -16,7 +19,7 @@ class ThreadList; class Runtime { public: // Creates and initializes a new runtime. - static Runtime* Create(); + static Runtime* Create(std::vector<RawDexFile*> boot_class_path); // Compiles a dex file. static void Compile(const StringPiece& filename); @@ -42,7 +45,7 @@ class Runtime { Runtime() : class_linker_(NULL), thread_list_(NULL) {} // Initializes a new uninitialized runtime. - bool Init(); + bool Init(std::vector<RawDexFile*> boot_class_path); ClassLinker* class_linker_; diff --git a/src/runtime_linux.cc b/src/runtime_linux.cc index e59111fde8..e150d8e2d0 100644 --- a/src/runtime_linux.cc +++ b/src/runtime_linux.cc @@ -23,7 +23,7 @@ void Runtime::PlatformAbort(const char* file, int line) { // TODO: in practice, we may find that we should use backtrace_symbols_fd // to avoid allocation, rather than use our own custom formatting. art::scoped_ptr_malloc<char*> symbols(backtrace_symbols(frames, frame_count)); - if (symbols.get() == NULL) { + if (symbols == NULL) { PLOG(ERROR) << "backtrace_symbols failed"; return; } diff --git a/src/scoped_ptr.h b/src/scoped_ptr.h index ce21cc531f..a3b30d59bb 100644 --- a/src/scoped_ptr.h +++ b/src/scoped_ptr.h @@ -18,7 +18,7 @@ // implementation of the scoped_ptr class, and its closely-related brethren, // scoped_array, scoped_ptr_malloc, and make_scoped_ptr. -#include "src/macros.h" +#include "macros.h" #include <assert.h> #include <stdlib.h> diff --git a/src/space.cc b/src/space.cc index dc9950c862..9e091f2f81 100644 --- a/src/space.cc +++ b/src/space.cc @@ -1,14 +1,14 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/space.h" +#include "space.h" #include <sys/mman.h> -#include "src/logging.h" -#include "src/mspace.h" -#include "src/scoped_ptr.h" -#include "src/utils.h" +#include "logging.h" +#include "mspace.h" +#include "scoped_ptr.h" +#include "utils.h" namespace art { diff --git a/src/space.h b/src/space.h index ac69ba633c..c61d91f327 100644 --- a/src/space.h +++ b/src/space.h @@ -4,8 +4,8 @@ #ifndef ART_SRC_SPACE_H_ #define ART_SRC_SPACE_H_ -#include "src/globals.h" -#include "src/macros.h" +#include "globals.h" +#include "macros.h" namespace art { diff --git a/src/space_test.cc b/src/space_test.cc index db623eb495..9a61fa57eb 100644 --- a/src/space_test.cc +++ b/src/space_test.cc @@ -1,12 +1,12 @@ // Copyright 2011 Google Inc. All Rights Reserved. // Author: cshapiro@google.com (Carl Shapiro) -#include "src/space.h" +#include "space.h" #include "gtest/gtest.h" -#include "src/globals.h" -#include "src/scoped_ptr.h" +#include "globals.h" +#include "scoped_ptr.h" namespace art { diff --git a/src/stringpiece.cc b/src/stringpiece.cc index 9927309f89..37795508d6 100644 --- a/src/stringpiece.cc +++ b/src/stringpiece.cc @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/stringpiece.h" +#include "stringpiece.h" #include <iostream> #include <utility> diff --git a/src/thread.cc b/src/thread.cc index 5b4b073820..56eeb7f6b4 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -1,6 +1,6 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/thread.h" +#include "thread.h" #include <pthread.h> #include <sys/mman.h> @@ -8,8 +8,8 @@ #include <cerrno> #include <list> -#include "src/runtime.h" -#include "src/utils.h" +#include "runtime.h" +#include "utils.h" namespace art { diff --git a/src/thread.h b/src/thread.h index fd03464f96..ed2ba12f1f 100644 --- a/src/thread.h +++ b/src/thread.h @@ -7,13 +7,13 @@ #include <pthread.h> #include <list> -#include "src/globals.h" -#include "src/jni_internal.h" -#include "src/logging.h" -#include "src/macros.h" -#include "src/object.h" -#include "src/offsets.h" -#include "src/runtime.h" +#include "globals.h" +#include "jni_internal.h" +#include "logging.h" +#include "macros.h" +#include "object.h" +#include "offsets.h" +#include "runtime.h" #include "jni.h" diff --git a/src/thread_arm.cc b/src/thread_arm.cc index 4b5eab7c5a..8b0d9a4288 100644 --- a/src/thread_arm.cc +++ b/src/thread_arm.cc @@ -1,7 +1,7 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/macros.h" -#include "src/thread.h" +#include "macros.h" +#include "thread.h" namespace art { diff --git a/src/thread_x86.cc b/src/thread_x86.cc index 718e9b8c7d..d0a4469e2c 100644 --- a/src/thread_x86.cc +++ b/src/thread_x86.cc @@ -1,10 +1,12 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "src/thread.h" +#include "thread.h" + #include <asm/ldt.h> #include <sys/syscall.h> #include <sys/types.h> -#include "src/macros.h" + +#include "macros.h" namespace art { diff --git a/src/utils.h b/src/utils.h index 217bd69274..1da7c8805c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -3,7 +3,7 @@ #ifndef ART_SRC_UTILS_H_ #define ART_SRC_UTILS_H_ -#include "src/globals.h" +#include "globals.h" namespace art { |