diff options
| author | 2011-07-21 14:07:47 -0700 | |
|---|---|---|
| committer | 2011-07-22 15:23:33 -0700 | |
| commit | 578bbdc684db8ed68e9fedbc678669d27fa68b6e (patch) | |
| tree | d752941d81ad6d7e248c349ce21371a8ae369693 | |
| parent | 45a76cb99104a222d6a9bd768a084893dcb7cf30 (diff) | |
Move DexFiles to be allocated on the heap
Removed pointer from DexFile to RawDexfile to allow heap allocation of
DexFile. DexFile is now an ObjectArray of ObjectArrays. Removing the
pointer from DexFile to RawDexfile meant adding arguments to pass the
RawDexfile along to ClassLinker::LoadClass, LoadInterfaces, LoadField,
LoadMethod, LinkClass, LinkInterfaces, ResolveClass to avoid the need
to look a RawDexfile up from a DexFile. ClassLinker::CreateArrayClass
now takes the raw_dex_file to assist in looking up the component class
from the proper source. Moved Method::HasSame* methods to ClassLinker
since for access to the RawDexfile (and tests of HasSame from
ObjectTest to ClassLinkerTest.
src/dex_file.cc
src/dex_file.h
src/class_linker.cc
src/class_linker.h
src/object.h
RunTime::Create/RunTime::Init/ClassLinker::Create/ClassLinker::Init
now take the boot class path. A boot class path with
Ljava/lang/Object; must be provided to initalize [Ljava/lang/Object;
during startup in order to heap allocate DexFiles.
src/class_linker.cc
src/class_linker.h
src/runtime.cc
src/runtime.h
Restored FindClass to load from a specific dex file. This is for use
by class loaders, otherwise it is assumed the caller wants to use the
boot classpath. We now distinguish and track the boot classpath as
separate from other dex files known to the class linker. Renamed
AppendToClassPath to AppendToBootClassPath and FindInClassPath to
FindInBootClassPath to clarify.
src/class_linker.cc
src/class_linker.h
Cleaned up AllocCharArray to generic AllocArray and added
AllocObjectArray. Added a functional ObjectArray implementation and a
ObjectTest to cover it.
src/heap.h
src/object.h
src/object_test.cc
Switched more Object* downcasting to down_cast
src/class_linker.cc
Switched order of arguments for DexFile::SetResolved to follow more
conventional collection ordering ( "(index, value)" vs "(value, index)" )
src/dex_file.h
src/class_linker.cc
src/class_linker.h
Added class_linker_ and java_lang_raw_dex_file_ to RuntimeTest as
convenience to test subclasses. ClassLinkerTest now can use these to
simplify its ::Assert* methods. JniCompilerTest now uses it for
setting up its boot class path. Removed now unneeded
OpenDexFileBase64.
src/common_test.h
src/class_linker_test.cc
src/jni_compiler_test.cc
Add external/gtest/include to non-test include path so FRIEND_TEST can be used.
Add src to include path to remove the need of using in in art/src files.
build/Android.libart.host.mk
build/Android.libart.mk
src/assembler.cc
src/assembler.h
src/assembler_arm.cc
src/assembler_arm.h
src/assembler_x86.cc
src/assembler_x86.h
src/assembler_x86_test.cc
src/base64.cc
src/base64.h
src/calling_convention.cc
src/calling_convention.h
src/calling_convention_arm.cc
src/calling_convention_x86.cc
src/casts.h
src/class_linker.h
src/class_linker_test.cc
src/common_test.h
src/constants.h
src/constants_arm.h
src/constants_x86.h
src/dex_file.cc
src/dex_file.h
src/dex_file_test.cc
src/dex_instruction.cc
src/dex_instruction.h
src/dex_instruction_visitor.h
src/dex_instruction_visitor_test.cc
src/dex_verifier.cc
src/dex_verifier.h
src/heap.cc
src/heap.h
src/jni_compiler.cc
src/jni_compiler_test.cc
src/jni_internal.cc
src/jni_internal.h
src/leb128.h
src/managed_register.h
src/managed_register_arm.cc
src/managed_register_arm.h
src/managed_register_arm_test.cc
src/managed_register_x86.cc
src/managed_register_x86.h
src/managed_register_x86_test.cc
src/mark_stack.cc
src/mark_stack.h
src/mark_sweep.cc
src/mark_sweep.h
src/memory_region.cc
src/memory_region.h
src/monitor.h
src/object.cc
src/object.h
src/object_bitmap.cc
src/object_bitmap.h
src/object_test.cc
src/offsets.cc
src/offsets.h
src/raw_dex_file.cc
src/raw_dex_file.h
src/raw_dex_file_test.cc
src/runtime.cc
src/runtime.h
src/scoped_ptr.h
src/space.cc
src/space.h
src/space_test.cc
src/stringpiece.cc
src/thread.cc
src/thread.h
src/thread_arm.cc
src/thread_x86.cc
src/utils.h
Change-Id: Ib633cea878c36921e9037b0464cb903aec318c3e
76 files changed, 877 insertions, 783 deletions
diff --git a/build/Android.libart.host.mk b/build/Android.libart.host.mk index 92cc4da295..9772d63ee8 100644 --- a/build/Android.libart.host.mk +++ b/build/Android.libart.host.mk @@ -20,6 +20,7 @@ LOCAL_MODULE := libart LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(LIBART_HOST_SRC_FILES) LOCAL_CFLAGS := $(ART_CFLAGS) +LOCAL_C_INCLUDES += src external/gtest/include LOCAL_SHARED_LIBRARIES := liblog libz-host LOCAL_LDLIBS := -ldl -lpthread -lrt include $(BUILD_HOST_SHARED_LIBRARY) diff --git a/build/Android.libart.mk b/build/Android.libart.mk index 94442a1426..fae5c7e127 100644 --- a/build/Android.libart.mk +++ b/build/Android.libart.mk @@ -21,5 +21,6 @@ LOCAL_MODULE := libart LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(LIBART_TARGET_SRC_FILES) LOCAL_CFLAGS := $(ART_CFLAGS) +LOCAL_C_INCLUDES += src external/gtest/include LOCAL_SHARED_LIBRARIES := libcutils liblog libstlport libz include $(BUILD_SHARED_LIBRARY) 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 { |