diff options
author | 2011-08-23 16:02:11 -0700 | |
---|---|---|
committer | 2011-08-31 09:46:57 -0700 | |
commit | 1f87008b165d26541d832ff805250afdc89c253d (patch) | |
tree | a84122b3757b8f856eb0656a951ed6621b6d01a8 | |
parent | c5bfa8f49d8548d7c685a99b411311ef56bedffa (diff) |
Add HeapTest and make GC work enough to pass it
Change-Id: If06eaef2921b64b3226bfd347acaec60ec993e67
40 files changed, 412 insertions, 208 deletions
diff --git a/build/Android.common.mk b/build/Android.common.mk index bd8a83b8d1..0ee1825109 100644 --- a/build/Android.common.mk +++ b/build/Android.common.mk @@ -43,6 +43,7 @@ LIBART_COMMON_SRC_FILES := \ src/calling_convention.cc \ src/check_jni.cc \ src/class_linker.cc \ + src/class_loader.cc \ src/compiler.cc \ src/compiler/Dataflow.cc \ src/compiler/Frontend.cc \ @@ -121,6 +122,7 @@ TEST_COMMON_SRC_FILES := \ src/dex_verifier_test.cc \ src/exception_test.cc \ src/file_test.cc \ + src/heap_test.cc \ src/image_test.cc \ src/indirect_reference_table_test.cc \ src/intern_table_test.cc \ diff --git a/src/check_jni.cc b/src/check_jni.cc index 93d3b313b3..eb829a0bbb 100644 --- a/src/check_jni.cc +++ b/src/check_jni.cc @@ -23,6 +23,7 @@ #include "logging.h" #include "scoped_jni_thread_state.h" #include "thread.h" +#include "runtime.h" namespace art { diff --git a/src/class_linker.cc b/src/class_linker.cc index 9bbcb0cb93..89b425fee8 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -7,6 +7,7 @@ #include "UniquePtr.h" #include "casts.h" +#include "class_loader.h" #include "dex_cache.h" #include "dex_file.h" #include "dex_verifier.h" @@ -14,6 +15,7 @@ #include "logging.h" #include "monitor.h" #include "object.h" +#include "runtime.h" #include "space.h" #include "thread.h" #include "utils.h" @@ -242,14 +244,44 @@ void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path) { SetClassRoot(kFloatArrayClass, FindSystemClass("[F")); SetClassRoot(kLongArrayClass, FindSystemClass("[J")); SetClassRoot(kShortArrayClass, FindSystemClass("[S")); - SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;")); - SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;")); BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass)); ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass)); DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass)); FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass)); LongArray::SetArrayClass(GetClassRoot(kLongArrayClass)); ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass)); + + // java.lang.ref classes need to be specially flagged, but otherwise are normal classes + Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;"); + Class* java_lang_ref_PhantomReference = FindSystemClass("Ljava/lang/ref/PhantomReference;"); + Class* java_lang_ref_SoftReference = FindSystemClass("Ljava/lang/ref/SoftReference;"); + Class* java_lang_ref_WeakReference = FindSystemClass("Ljava/lang/ref/WeakReference;"); + java_lang_ref_FinalizerReference->access_flags_ |= kAccClassIsReference | kAccClassIsFinalizerReference; + java_lang_ref_PhantomReference->access_flags_ |= kAccClassIsReference | kAccClassIsPhantomReference; + java_lang_ref_SoftReference->access_flags_ |= kAccClassIsReference; + java_lang_ref_WeakReference->access_flags_ |= kAccClassIsReference | kAccClassIsWeakReference; + + // Let the heap know some key offsets into java.lang.ref instances + Class* java_lang_ref_Reference = FindSystemClass("Ljava/lang/ref/Reference;"); + Field* referent = java_lang_ref_Reference->FindDeclaredInstanceField( + "referent", "Ljava/lang/Object;"); + Field* queue = java_lang_ref_Reference->FindDeclaredInstanceField( + "queue", "Ljava/lang/ref/ReferenceQueue;"); + Field* queueNext = java_lang_ref_Reference->FindDeclaredInstanceField( + "queueNext", "Ljava/lang/ref/Reference;"); + Field* pendingNext = java_lang_ref_Reference->FindDeclaredInstanceField( + "pendingNext", "Ljava/lang/ref/Reference;"); + Field* zombie = java_lang_ref_FinalizerReference->FindDeclaredInstanceField( + "zombie", "Ljava/lang/Object;"); + Heap::SetReferenceOffsets(referent->GetOffset(), + queue->GetOffset(), + queueNext->GetOffset(), + pendingNext->GetOffset(), + zombie->GetOffset()); + + // Optimization for quick stack trace allocation + SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;")); + SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;")); StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement)); FinishInit(); @@ -455,11 +487,11 @@ Class* ClassLinker::AllocClass(size_t class_size) { } Field* ClassLinker::AllocField() { - return down_cast<Field*>(GetClassRoot(kJavaLangReflectField)->NewInstance()); + return down_cast<Field*>(GetClassRoot(kJavaLangReflectField)->AllocObject()); } Method* ClassLinker::AllocMethod() { - return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->NewInstance()); + return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject()); } ObjectArray<StackTraceElement>* ClassLinker::AllocStackTraceElementArray(size_t length) { @@ -649,6 +681,9 @@ void ClassLinker::LoadClass(const DexFile& dex_file, klass->primitive_type_ = Class::kPrimNot; klass->status_ = Class::kStatusIdx; + // Make sure the aren't any "bonus" flags set, since we use them for runtime state. + CHECK_EQ(klass->access_flags_ & ~kAccClassFlagsMask, 0U); + klass->super_class_ = NULL; klass->super_class_type_idx_ = dex_class_def.superclass_idx_; @@ -701,7 +736,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); Method* meth = AllocMethod(); klass->SetDirectMethod(i, meth); - LoadMethod(dex_file, dex_method, klass, meth, true); + LoadMethod(dex_file, dex_method, klass, meth); // TODO: register maps } } @@ -717,7 +752,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); Method* meth = AllocMethod(); klass->SetVirtualMethod(i, meth); - LoadMethod(dex_file, dex_method, klass, meth, false); + LoadMethod(dex_file, dex_method, klass, meth); // TODO: register maps } } @@ -754,8 +789,7 @@ void ClassLinker::LoadField(const DexFile& dex_file, void ClassLinker::LoadMethod(const DexFile& dex_file, const DexFile::Method& src, Class* klass, - Method* dst, - bool is_direct) { + Method* dst) { const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_); dst->declaring_class_ = klass; dst->name_ = ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache()); @@ -776,8 +810,6 @@ void ClassLinker::LoadMethod(const DexFile& dex_file, dst->dex_cache_code_and_direct_methods_ = klass->dex_cache_->GetCodeAndDirectMethods(); dst->dex_cache_initialized_static_storage_ = klass->dex_cache_->GetInitializedStaticStorage(); - dst->is_direct_ = is_direct; - // TODO: check for finalize method const DexFile::CodeItem* code_item = dex_file.GetCodeItem(src); diff --git a/src/class_linker.h b/src/class_linker.h index 6e13aa7d2c..1f233b0c8e 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -18,6 +18,8 @@ #include "gtest/gtest.h" +class ClassLoader; + namespace art { class ClassLinker { @@ -192,8 +194,7 @@ class ClassLinker { void LoadMethod(const DexFile& dex_file, const DexFile::Method& dex_method, Class* klass, - Method* dst, - bool is_direct); + Method* dst); Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader); diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index e207fd982a..c403065762 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -7,7 +7,6 @@ #include "dex_cache.h" #include "dex_file.h" #include "heap.h" -#include "gtest/gtest.h" namespace art { diff --git a/src/class_loader.cc b/src/class_loader.cc new file mode 100644 index 0000000000..97691362c4 --- /dev/null +++ b/src/class_loader.cc @@ -0,0 +1,37 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +#include "class_loader.h" + +#include "class_linker.h" +#include "runtime.h" + +namespace art { + +const std::vector<const DexFile*>& ClassLoader::GetClassPath(const ClassLoader* class_loader) { + if (class_loader == NULL) { + return Runtime::Current()->GetClassLinker()->GetBootClassPath(); + } + return class_loader->class_path_; +} + +// TODO: get global references for these +Class* PathClassLoader::dalvik_system_PathClassLoader_ = NULL; + +const PathClassLoader* PathClassLoader::Alloc(std::vector<const DexFile*> dex_files) { + PathClassLoader* p = down_cast<PathClassLoader*>(dalvik_system_PathClassLoader_->AllocObject()); + p->SetClassPath(dex_files); + return p; +} + +void PathClassLoader::SetClass(Class* dalvik_system_PathClassLoader) { + CHECK(dalvik_system_PathClassLoader_ == NULL); + CHECK(dalvik_system_PathClassLoader != NULL); + dalvik_system_PathClassLoader_ = dalvik_system_PathClassLoader; +} + +void PathClassLoader::ResetClass() { + CHECK(dalvik_system_PathClassLoader_ != NULL); + dalvik_system_PathClassLoader_ = NULL; +} + +} // namespace art diff --git a/src/class_loader.h b/src/class_loader.h new file mode 100644 index 0000000000..da19539be0 --- /dev/null +++ b/src/class_loader.h @@ -0,0 +1,54 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +#ifndef ART_SRC_CLASS_LOADER_H_ +#define ART_SRC_CLASS_LOADER_H_ + +#include <vector> + +#include "dex_file.h" +#include "object.h" + +namespace art { + +// ClassLoader objects. +class ClassLoader : public Object { + public: + static const std::vector<const DexFile*>& GetClassPath(const ClassLoader* class_loader); + + void SetClassPath(std::vector<const DexFile*>& class_path) { + DCHECK_EQ(0U, class_path_.size()); + class_path_ = class_path; + } + + private: + // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". + Object* packages_; + ClassLoader* parent_; + + // TODO: remove once we can create a real PathClassLoader + std::vector<const DexFile*> class_path_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(ClassLoader); +}; + +class BaseDexClassLoader : public ClassLoader { + private: + // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". + String* original_path_; + Object* path_list_; + DISALLOW_IMPLICIT_CONSTRUCTORS(BaseDexClassLoader); +}; + +class PathClassLoader : public BaseDexClassLoader { + public: + static const PathClassLoader* Alloc(std::vector<const DexFile*> dex_files); + static void SetClass(Class* dalvik_system_PathClassLoader); + static void ResetClass(); + private: + static Class* dalvik_system_PathClassLoader_; + DISALLOW_IMPLICIT_CONSTRUCTORS(PathClassLoader); +}; + +} // namespace art + +#endif // ART_SRC_OBJECT_H_ diff --git a/src/common_test.h b/src/common_test.h index bb9b93cd9c..c79cea6e10 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -8,9 +8,11 @@ #include "UniquePtr.h" #include "base64.h" #include "class_linker.h" +#include "class_loader.h" #include "dex_file.h" -#include "heap.h" #include "gtest/gtest.h" +#include "heap.h" +#include "runtime.h" #include "stringprintf.h" #include "thread.h" #include "unicode/uclean.h" diff --git a/src/compiler.cc b/src/compiler.cc index 37f8298051..8396bdffa5 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -4,8 +4,10 @@ #include "assembler.h" #include "class_linker.h" +#include "class_loader.h" #include "dex_cache.h" #include "jni_compiler.h" +#include "runtime.h" extern bool oatCompileMethod(art::Method*, art::InstructionSet); diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc index 6c31cfe5b3..9ef2b4fe51 100644 --- a/src/compiler/Frontend.cc +++ b/src/compiler/Frontend.cc @@ -18,6 +18,7 @@ #include "CompilerInternals.h" #include "Dataflow.h" #include "constants.h" +#include "runtime.h" static inline bool contentIsInsn(const u2* codePtr) { u2 instr = *codePtr; diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index 699a56163a..3da5aaa5fb 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -535,7 +535,7 @@ static void genNewInstance(CompilationUnit* cUnit, MIR* mir, { oatFlushAllRegs(cUnit); /* Everything to home location */ loadWordDisp(cUnit, rSELF, - OFFSETOF_MEMBER(Thread, pNewInstanceFromCode), rLR); + OFFSETOF_MEMBER(Thread, pAllocObjectFromCode), rLR); loadCurrMethodDirect(cUnit, r1); // arg1 <= Method* loadConstant(cUnit, r0, mir->dalvikInsn.vB); // arg0 <- type_id opReg(cUnit, kOpBlx, rLR); diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc index 843466d020..a01647a36a 100644 --- a/src/dex_cache_test.cc +++ b/src/dex_cache_test.cc @@ -7,7 +7,6 @@ #include "object.h" #include <stdio.h> -#include "gtest/gtest.h" namespace art { diff --git a/src/dex_file.cc b/src/dex_file.cc index fde6f014fd..4b56435284 100644 --- a/src/dex_file.cc +++ b/src/dex_file.cc @@ -3,6 +3,7 @@ #include "dex_file.h" #include <fcntl.h> +#include <limits.h> #include <stdio.h> #include <string.h> #include <sys/file.h> diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc index e0702b7aca..0e62b258bd 100644 --- a/src/dex_verifier.cc +++ b/src/dex_verifier.cc @@ -1,14 +1,15 @@ // Copyright 2011 Google Inc. All Rights Reserved. -#include "class_linker.h" -#include "dex_file.h" -#include "dex_instruction.h" -#include "dex_instruction_visitor.h" #include "dex_verifier.h" #include <iostream> +#include "class_linker.h" +#include "dex_file.h" +#include "dex_instruction.h" +#include "dex_instruction_visitor.h" #include "logging.h" +#include "runtime.h" #include "stringpiece.h" namespace art { diff --git a/src/file_test.cc b/src/file_test.cc index 0019c1de36..99e4b41a8d 100644 --- a/src/file_test.cc +++ b/src/file_test.cc @@ -4,7 +4,6 @@ #include "UniquePtr.h" #include "common_test.h" -#include "gtest/gtest.h" #include "os.h" namespace art { diff --git a/src/heap.cc b/src/heap.cc index 286d7061e7..bffd19dd05 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -31,6 +31,12 @@ HeapBitmap* Heap::mark_bitmap_ = NULL; HeapBitmap* Heap::live_bitmap_ = NULL; +size_t Heap::reference_referent_offset_ = 0; // TODO +size_t Heap::reference_queue_offset_ = 0; // TODO +size_t Heap::reference_queueNext_offset_ = 0; // TODO +size_t Heap::reference_pendingNext_offset_ = 0; // TODO +size_t Heap::finalizer_reference_zombie_offset_ = 0; // TODO + bool Heap::Init(size_t initial_size, size_t maximum_size, const char* boot_image_file_name) { Space* boot_space; byte* requested_base; diff --git a/src/heap.h b/src/heap.h index bbd05dbf2d..d4d43e7408 100644 --- a/src/heap.h +++ b/src/heap.h @@ -67,6 +67,48 @@ class Heap { return mark_bitmap_; } + static void SetReferenceOffsets(size_t reference_referent_offset, + size_t reference_queue_offset, + size_t reference_queueNext_offset, + size_t reference_pendingNext_offset, + size_t finalizer_reference_zombie_offset) { + CHECK_NE(reference_referent_offset, 0U); + CHECK_NE(reference_queue_offset, 0U); + CHECK_NE(reference_queueNext_offset, 0U); + CHECK_NE(reference_pendingNext_offset, 0U); + CHECK_NE(finalizer_reference_zombie_offset, 0U); + reference_referent_offset_ = reference_referent_offset; + reference_queue_offset_ = reference_queue_offset; + reference_queueNext_offset_ = reference_queueNext_offset; + reference_pendingNext_offset_ = reference_pendingNext_offset; + finalizer_reference_zombie_offset_ = finalizer_reference_zombie_offset; + } + + static size_t GetReferenceReferentOffset() { + DCHECK_NE(reference_referent_offset_, 0U); + return reference_referent_offset_; + } + + static size_t GetReferenceQueueOffset() { + DCHECK_NE(reference_queue_offset_, 0U); + return reference_queue_offset_; + } + + static size_t GetReferenceQueueNextOffset() { + DCHECK_NE(reference_queueNext_offset_, 0U); + return reference_queueNext_offset_; + } + + static size_t GetReferencePendingNextOffset() { + DCHECK_NE(reference_pendingNext_offset_, 0U); + return reference_pendingNext_offset_; + } + + static size_t GetFinalizerReferenceZombieOffset() { + DCHECK_NE(finalizer_reference_zombie_offset_, 0U); + return finalizer_reference_zombie_offset_; + } + private: // Allocates uninitialized storage. static Object* Allocate(size_t num_bytes); @@ -108,6 +150,21 @@ class Heap { // free. static size_t num_objects_allocated_; + // offset of java.lang.ref.Reference.referent + static size_t reference_referent_offset_; + + // offset of java.lang.ref.Reference.queue + static size_t reference_queue_offset_; + + // offset of java.lang.ref.Reference.queueNext + static size_t reference_queueNext_offset_; + + // offset of java.lang.ref.Reference.pendingNext + static size_t reference_pendingNext_offset_; + + // offset of java.lang.ref.FinalizerReference.zombie + static size_t finalizer_reference_zombie_offset_; + DISALLOW_IMPLICIT_CONSTRUCTORS(Heap); }; diff --git a/src/heap_test.cc b/src/heap_test.cc new file mode 100644 index 0000000000..568ddd2830 --- /dev/null +++ b/src/heap_test.cc @@ -0,0 +1,14 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +#include "common_test.h" + +namespace art { + +class HeapTest : public CommonTest {}; + +TEST_F(HeapTest, GarbageCollectClassLinkerInit) { + // garbage is created during ClassLinker::Init + Heap::CollectGarbage(); +} + +} // namespace art diff --git a/src/image_test.cc b/src/image_test.cc index 34e243d78d..b03cbe3584 100644 --- a/src/image_test.cc +++ b/src/image_test.cc @@ -7,8 +7,6 @@ #include "space.h" #include "utils.h" -#include "gtest/gtest.h" - namespace art { class ImageTest : public CommonTest {}; diff --git a/src/image_writer.cc b/src/image_writer.cc index 0a66664d26..fd3ec4d0c1 100644 --- a/src/image_writer.cc +++ b/src/image_writer.cc @@ -8,6 +8,7 @@ #include "UniquePtr.h" #include "class_linker.h" +#include "class_loader.h" #include "dex_cache.h" #include "file.h" #include "globals.h" @@ -16,6 +17,7 @@ #include "intern_table.h" #include "logging.h" #include "object.h" +#include "runtime.h" #include "space.h" #include "utils.h" diff --git a/src/image_writer.h b/src/image_writer.h index 4299373267..80012bcef6 100644 --- a/src/image_writer.h +++ b/src/image_writer.h @@ -11,6 +11,7 @@ #include "mem_map.h" #include "object.h" #include "os.h" +#include "space.h" namespace art { diff --git a/src/indirect_reference_table_test.cc b/src/indirect_reference_table_test.cc index 352ebd5c2e..cea4afd87e 100644 --- a/src/indirect_reference_table_test.cc +++ b/src/indirect_reference_table_test.cc @@ -18,8 +18,6 @@ #include "indirect_reference_table.h" -#include "gtest/gtest.h" - namespace art { class IndirectReferenceTableTest : public CommonTest { @@ -32,13 +30,13 @@ TEST_F(IndirectReferenceTableTest, BasicTest) { Class* c = class_linker_->FindSystemClass("Ljava/lang/Object;"); ASSERT_TRUE(c != NULL); - Object* obj0 = c->NewInstance(); + Object* obj0 = c->AllocObject(); ASSERT_TRUE(obj0 != NULL); - Object* obj1 = c->NewInstance(); + Object* obj1 = c->AllocObject(); ASSERT_TRUE(obj1 != NULL); - Object* obj2 = c->NewInstance(); + Object* obj2 = c->AllocObject(); ASSERT_TRUE(obj2 != NULL); - Object* obj3 = c->NewInstance(); + Object* obj3 = c->AllocObject(); ASSERT_TRUE(obj3 != NULL); const uint32_t cookie = IRT_FIRST_SEGMENT; diff --git a/src/intern_table_test.cc b/src/intern_table_test.cc index 662a8b6c67..a01c6dd8e4 100644 --- a/src/intern_table_test.cc +++ b/src/intern_table_test.cc @@ -5,8 +5,6 @@ #include "common_test.h" #include "object.h" -#include "gtest/gtest.h" - namespace art { class InternTableTest : public CommonTest {}; diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 921305658a..5acb155f9c 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -14,6 +14,7 @@ #include "UniquePtr.h" #include "assembler.h" #include "class_linker.h" +#include "class_loader.h" #include "jni.h" #include "logging.h" #include "object.h" @@ -904,7 +905,7 @@ class JNI { if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) { return NULL; } - return AddLocalReference<jobject>(ts, c->NewInstance()); + return AddLocalReference<jobject>(ts, c->AllocObject()); } static jobject NewObject(JNIEnv* env, jclass clazz, jmethodID mid, ...) { @@ -922,7 +923,7 @@ class JNI { if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) { return NULL; } - Object* result = c->NewInstance(); + Object* result = c->AllocObject(); jobject local_result = AddLocalReference<jobject>(ts, result); CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args); return local_result; @@ -934,7 +935,7 @@ class JNI { if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) { return NULL; } - Object* result = c->NewInstance(); + Object* result = c->AllocObject(); jobject local_result = AddLocalReference<jobjectArray>(ts, result); CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args); return local_result; diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc index 1d0f35f980..42ab1586e9 100644 --- a/src/jni_internal_test.cc +++ b/src/jni_internal_test.cc @@ -6,7 +6,6 @@ #include <sys/mman.h> #include "common_test.h" -#include "gtest/gtest.h" namespace art { diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc index eb81cf60a8..b803c4829c 100644 --- a/src/mark_sweep.cc +++ b/src/mark_sweep.cc @@ -10,17 +10,13 @@ #include "macros.h" #include "mark_stack.h" #include "object.h" +#include "class_loader.h" +#include "runtime.h" #include "space.h" #include "thread.h" namespace art { -size_t MarkSweep::reference_referent_offset_ = 0; // TODO -size_t MarkSweep::reference_queue_offset_ = 0; // TODO -size_t MarkSweep::reference_queueNext_offset_ = 0; // TODO -size_t MarkSweep::reference_pendingNext_offset_ = 0; // TODO -size_t MarkSweep::finalizer_reference_zombie_offset_ = 0; // TODO - bool MarkSweep::Init() { mark_stack_ = MarkStack::Create(); if (mark_stack_ == NULL) { @@ -65,9 +61,16 @@ void MarkSweep::MarkObject(const Object* obj) { } } +void MarkSweep::MarkObjectVisitor(Object* root, void* arg) { + DCHECK(root != NULL); + DCHECK(arg != NULL); + MarkSweep* mark_sweep = reinterpret_cast<MarkSweep*>(arg); + mark_sweep->MarkObject0(root, true); +} + // Marks all objects in the root set. void MarkSweep::MarkRoots() { - UNIMPLEMENTED(FATAL); + Runtime::Current()->VisitRoots(MarkObjectVisitor, this); } void MarkSweep::ScanBitmapCallback(Object* obj, void* finger, void* arg) { @@ -79,13 +82,21 @@ void MarkSweep::ScanBitmapCallback(Object* obj, void* finger, void* arg) { // Populates the mark stack based on the set of marked objects and // recursively marks until the mark stack is emptied. void MarkSweep::RecursiveMark() { + + // RecursiveMark will build the lists of known instances of the Reference classes. + // See DelayReferenceReferent for details. + CHECK(soft_reference_list_ == NULL); + CHECK(weak_reference_list_ == NULL); + CHECK(finalizer_reference_list_ == NULL); + CHECK(phantom_reference_list_ == NULL); + CHECK(cleared_reference_list_ == NULL); + void* arg = reinterpret_cast<void*>(this); const std::vector<Space*>& spaces = Heap::GetSpaces(); for (size_t i = 0; i < spaces.size(); ++i) { if (spaces[i]->IsCondemned()) { uintptr_t base = reinterpret_cast<uintptr_t>(spaces[i]->GetBase()); - uintptr_t limit = reinterpret_cast<uintptr_t>(spaces[i]->GetLimit()); - mark_bitmap_->ScanWalk(base, limit, &MarkSweep::ScanBitmapCallback, arg); + mark_bitmap_->ScanWalk(base, &MarkSweep::ScanBitmapCallback, arg); } } finger_ = reinterpret_cast<Object*>(~0); @@ -224,7 +235,7 @@ void MarkSweep::ScanArray(const Object* obj) { void MarkSweep::EnqueuePendingReference(Object* ref, Object** list) { DCHECK(ref != NULL); DCHECK(list != NULL); - size_t offset = reference_pendingNext_offset_; + size_t offset = Heap::GetReferencePendingNextOffset(); if (*list == NULL) { ref->SetFieldObject(offset, ref); *list = ref; @@ -238,7 +249,7 @@ void MarkSweep::EnqueuePendingReference(Object* ref, Object** list) { Object* MarkSweep::DequeuePendingReference(Object** list) { DCHECK(list != NULL); DCHECK(*list != NULL); - size_t offset = reference_pendingNext_offset_; + size_t offset = Heap::GetReferencePendingNextOffset(); Object* head = (*list)->GetFieldObject(offset); Object* ref; if (*list == head) { @@ -258,19 +269,20 @@ Object* MarkSweep::DequeuePendingReference(Object** list) { // the gcHeap for later processing. void MarkSweep::DelayReferenceReferent(Object* obj) { DCHECK(obj != NULL); - DCHECK(obj->GetClass() != NULL); - DCHECK(obj->IsReference()); - Object* pending = obj->GetFieldObject(reference_pendingNext_offset_); - Object* referent = obj->GetFieldObject(reference_referent_offset_); + Class* klass = obj->GetClass(); + DCHECK(klass != NULL); + DCHECK(klass->IsReference()); + Object* pending = obj->GetFieldObject(Heap::GetReferencePendingNextOffset()); + Object* referent = obj->GetFieldObject(Heap::GetReferenceReferentOffset()); if (pending == NULL && referent != NULL && !IsMarked(referent)) { Object** list = NULL; - if (obj->IsSoftReference()) { + if (klass->IsSoftReference()) { list = &soft_reference_list_; - } else if (obj->IsWeakReference()) { + } else if (klass->IsWeakReference()) { list = &weak_reference_list_; - } else if (obj->IsFinalizerReference()) { + } else if (klass->IsFinalizerReference()) { list = &finalizer_reference_list_; - } else if (obj->IsPhantomReference()) { + } else if (klass->IsPhantomReference()) { list = &phantom_reference_list_; } DCHECK(list != NULL); @@ -283,10 +295,11 @@ void MarkSweep::DelayReferenceReferent(Object* obj) { // processing void MarkSweep::ScanOther(const Object* obj) { DCHECK(obj != NULL); - DCHECK(obj->GetClass() != NULL); - MarkObject(obj->GetClass()); + Class* klass = obj->GetClass(); + DCHECK(klass != NULL); + MarkObject(klass); ScanInstanceFields(obj); - if (obj->IsReference()) { + if (klass->IsReference()) { DelayReferenceReferent(const_cast<Object*>(obj)); } } @@ -321,20 +334,20 @@ void MarkSweep::ScanDirtyObjects() { void MarkSweep::ClearReference(Object* ref) { DCHECK(ref != NULL); - ref->SetFieldObject(reference_referent_offset_, NULL); + ref->SetFieldObject(Heap::GetReferenceReferentOffset(), NULL); } bool MarkSweep::IsEnqueuable(const Object* ref) { DCHECK(ref != NULL); - const Object* queue = ref->GetFieldObject(reference_queue_offset_); - const Object* queue_next = ref->GetFieldObject(reference_queueNext_offset_); + const Object* queue = ref->GetFieldObject(Heap::GetReferenceQueueOffset()); + const Object* queue_next = ref->GetFieldObject(Heap::GetReferenceQueueNextOffset()); return (queue != NULL) && (queue_next == NULL); } void MarkSweep::EnqueueReference(Object* ref) { DCHECK(ref != NULL); - CHECK(ref->GetFieldObject(reference_queue_offset_) != NULL); - CHECK(ref->GetFieldObject(reference_queueNext_offset_) == NULL); + CHECK(ref->GetFieldObject(Heap::GetReferenceQueueOffset()) != NULL); + CHECK(ref->GetFieldObject(Heap::GetReferenceQueueNextOffset()) == NULL); EnqueuePendingReference(ref, &cleared_reference_list_); } @@ -348,7 +361,7 @@ void MarkSweep::PreserveSomeSoftReferences(Object** list) { size_t counter = 0; while (*list != NULL) { Object* ref = DequeuePendingReference(list); - Object* referent = ref->GetFieldObject(reference_referent_offset_); + Object* referent = ref->GetFieldObject(Heap::GetReferenceReferentOffset()); if (referent == NULL) { // Referent was cleared by the user during marking. continue; @@ -375,7 +388,7 @@ void MarkSweep::PreserveSomeSoftReferences(Object** list) { // scheduled for appending by the heap worker thread. void MarkSweep::ClearWhiteReferences(Object** list) { DCHECK(list != NULL); - size_t offset = reference_referent_offset_; + size_t offset = Heap::GetReferenceReferentOffset(); while (*list != NULL) { Object* ref = DequeuePendingReference(list); Object* referent = ref->GetFieldObject(offset); @@ -395,8 +408,8 @@ void MarkSweep::ClearWhiteReferences(Object** list) { // referent field is cleared. void MarkSweep::EnqueueFinalizerReferences(Object** list) { DCHECK(list != NULL); - size_t referent_offset = reference_referent_offset_; - size_t zombie_offset = finalizer_reference_zombie_offset_; + size_t referent_offset = Heap::GetReferenceReferentOffset(); + size_t zombie_offset = Heap::GetFinalizerReferenceZombieOffset(); bool has_enqueued = false; while (*list != NULL) { Object* ref = DequeuePendingReference(list); diff --git a/src/mark_sweep.h b/src/mark_sweep.h index 5f374ae9e4..00bfc4c67d 100644 --- a/src/mark_sweep.h +++ b/src/mark_sweep.h @@ -15,7 +15,13 @@ class Object; class MarkSweep { public: MarkSweep() : - finger_(NULL), condemned_(NULL) { + finger_(NULL), + condemned_(NULL), + soft_reference_list_(NULL), + weak_reference_list_(NULL), + finalizer_reference_list_(NULL), + phantom_reference_list_(NULL), + cleared_reference_list_(NULL) { } ~MarkSweep(); @@ -48,6 +54,8 @@ class MarkSweep { return mark_bitmap_->Test(object); } + static void MarkObjectVisitor(Object* root, void* arg); + // Marks an object. void MarkObject(const Object* obj); @@ -140,16 +148,6 @@ class MarkSweep { Object* cleared_reference_list_; - static size_t reference_referent_offset_; - - static size_t reference_queue_offset_; - - static size_t reference_queueNext_offset_; - - static size_t reference_pendingNext_offset_; - - static size_t finalizer_reference_zombie_offset_; - DISALLOW_COPY_AND_ASSIGN(MarkSweep); }; diff --git a/src/object.cc b/src/object.cc index 66ea03f2cd..e0544df179 100644 --- a/src/object.cc +++ b/src/object.cc @@ -6,21 +6,16 @@ #include <algorithm> #include "class_linker.h" +#include "class_loader.h" #include "globals.h" #include "heap.h" #include "logging.h" #include "dex_cache.h" #include "dex_file.h" +#include "runtime.h" namespace art { -const std::vector<const DexFile*>& ClassLoader::GetClassPath(const ClassLoader* class_loader) { - if (class_loader == NULL) { - return Runtime::Current()->GetClassLinker()->GetBootClassPath(); - } - return class_loader->class_path_; -} - Array* Array::Alloc(Class* array_class, int32_t component_count, size_t component_size) { DCHECK_GE(component_count, 0); DCHECK(array_class->IsArrayClass()); @@ -50,7 +45,7 @@ Array* Array::AllocFromCode(uint32_t type_idx, Method* method, int32_t component return Array::Alloc(klass, component_count); } -Object* Class::NewInstanceFromCode(uint32_t type_idx, Method* method) { +Object* Class::AllocObjectFromCode(uint32_t type_idx, Method* method) { Class* klass = method->dex_cache_resolved_types_->Get(type_idx); if (klass == NULL) { klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method); @@ -59,7 +54,12 @@ Object* Class::NewInstanceFromCode(uint32_t type_idx, Method* method) { return NULL; } } - return klass->NewInstance(); + return klass->AllocObject(); +} + +Object* Class::AllocObject() { + DCHECK(!IsAbstract()); + return Heap::AllocObject(this, this->object_size_); } bool Class::Implements(const Class* klass) const { @@ -675,26 +675,6 @@ void String::ResetClass() { java_lang_String_ = NULL; } -// TODO: get global references for these -Class* PathClassLoader::dalvik_system_PathClassLoader_ = NULL; - -const PathClassLoader* PathClassLoader::Alloc(std::vector<const DexFile*> dex_files) { - PathClassLoader* p = down_cast<PathClassLoader*>(dalvik_system_PathClassLoader_->NewInstance()); - p->SetClassPath(dex_files); - return p; -} - -void PathClassLoader::SetClass(Class* dalvik_system_PathClassLoader) { - CHECK(dalvik_system_PathClassLoader_ == NULL); - CHECK(dalvik_system_PathClassLoader != NULL); - dalvik_system_PathClassLoader_ = dalvik_system_PathClassLoader; -} - -void PathClassLoader::ResetClass() { - CHECK(dalvik_system_PathClassLoader_ != NULL); - dalvik_system_PathClassLoader_ = NULL; -} - Class* StackTraceElement::java_lang_StackTraceElement_ = NULL; void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) { diff --git a/src/object.h b/src/object.h index 438b58723b..1db3e83167 100644 --- a/src/object.h +++ b/src/object.h @@ -3,22 +3,26 @@ #ifndef ART_SRC_OBJECT_H_ #define ART_SRC_OBJECT_H_ +#include <vector> + #include "UniquePtr.h" #include "casts.h" #include "constants.h" #include "globals.h" -#include "heap.h" #include "logging.h" #include "macros.h" #include "monitor.h" +#include "monitor.h" #include "offsets.h" #include "stringpiece.h" +#include "thread.h" #include "utf.h" namespace art { class Array; class Class; +class ClassLoader; class CodeAndDirectMethods; class DexCache; class Field; @@ -77,6 +81,52 @@ static const uint32_t kAccJavaFlagsMask = 0xffff; // bits set from Java sources static const uint32_t kAccConstructor = 0x00010000; // method (Dalvik only) static const uint32_t kAccDeclaredSynchronized = 0x00020000; // method (Dalvik only) +static const uint32_t kAccClassFlagsMask = (kAccPublic + | kAccFinal + | kAccInterface + | kAccAbstract + | kAccSynthetic + | kAccAnnotation + | kAccEnum); +static const uint32_t kAccInnerClassFlagsMask = (kAccClassFlagsMask + | kAccPrivate + | kAccProtected + | kAccStatic); +static const uint32_t kAccFieldFlagsMask = (kAccPublic + | kAccPrivate + | kAccProtected + | kAccStatic + | kAccFinal + | kAccVolatile + | kAccTransient + | kAccSynthetic + | kAccEnum); +static const uint32_t kAccMethodFlagsMask = (kAccPublic + | kAccPrivate + | kAccProtected + | kAccStatic + | kAccFinal + | kAccSynchronized + | kAccBridge + | kAccVarargs + | kAccNative + | kAccAbstract + | kAccStrict + | kAccSynthetic + | kAccConstructor + | kAccDeclaredSynchronized); + +// if only kAccClassIsReference is set, we have a soft reference +static const uint32_t kAccClassIsReference = 0x8000000; // class is a soft/weak/phantom ref +static const uint32_t kAccClassIsWeakReference = 0x4000000; // class is a weak reference +static const uint32_t kAccClassIsFinalizerReference = 0x2000000; // class is a finalizer reference +static const uint32_t kAccClassIsPhantomReference = 0x1000000; // class is a phantom reference + +static const uint32_t kAccReferenceFlagsMask = (kAccClassIsReference + | kAccClassIsWeakReference + | kAccClassIsFinalizerReference + | kAccClassIsPhantomReference); + /* * Definitions for packing refOffsets in Class. */ @@ -221,31 +271,6 @@ class Object { return down_cast<const ObjectArray<T>*>(this); } - bool IsReference() const { - UNIMPLEMENTED(FATAL); - return true; - } - - bool IsWeakReference() const { - UNIMPLEMENTED(FATAL); - return true; - } - - bool IsSoftReference() const { - UNIMPLEMENTED(FATAL); - return true; - } - - bool IsFinalizerReference() const { - UNIMPLEMENTED(FATAL); - return true; - } - - bool IsPhantomReference() const { - UNIMPLEMENTED(FATAL); - return true; - } - bool IsArrayInstance() const; Array* AsArray() { @@ -465,6 +490,16 @@ class Method : public AccessibleObject { return (access_flags_ & kAccStatic) != 0; } + // Returns true if the method is a constructor. + bool IsConstructor() const { + return (access_flags_ & kAccConstructor) != 0; + } + + // Returns true if the method is static, private, or a constructor. + bool IsDirect() const { + return IsStatic() || IsPrivate() || IsConstructor(); + } + // Returns true if the method is declared synchronized. bool IsSynchronized() const { uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized; @@ -552,10 +587,6 @@ class Method : public AccessibleObject { return shorty_[0] == 'V'; } - bool IsDirect() const { - return is_direct_; - } - // "Args" may refer to any of the 3 levels of "Args." // To avoid confusion, our code will denote which "Args" clearly: // 1. UserArgs: Args that a user see. @@ -736,8 +767,6 @@ class Method : public AccessibleObject { CodeAndDirectMethods* dex_cache_code_and_direct_methods_; ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_; - bool is_direct_; - private: // Compiled code associated with this method UniquePtr<MemMap> code_area_; @@ -870,45 +899,6 @@ class ObjectArray : public Array { DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectArray); }; -// ClassLoader objects. -class ClassLoader : public Object { - public: - static const std::vector<const DexFile*>& GetClassPath(const ClassLoader* class_loader); - - void SetClassPath(std::vector<const DexFile*>& class_path) { - DCHECK_EQ(0U, class_path_.size()); - class_path_ = class_path; - } - - private: - // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". - Object* packages_; - ClassLoader* parent_; - - // TODO: remove once we can create a real PathClassLoader - std::vector<const DexFile*> class_path_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ClassLoader); -}; - -class BaseDexClassLoader : public ClassLoader { - private: - // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". - String* original_path_; - Object* path_list_; - DISALLOW_IMPLICIT_CONSTRUCTORS(BaseDexClassLoader); -}; - -class PathClassLoader : public BaseDexClassLoader { - public: - static const PathClassLoader* Alloc(std::vector<const DexFile*> dex_files); - static void SetClass(Class* dalvik_system_PathClassLoader); - static void ResetClass(); - private: - static Class* dalvik_system_PathClassLoader_; - DISALLOW_IMPLICIT_CONSTRUCTORS(PathClassLoader); -}; - // Type for the InitializedStaticStorage table. Currently the Class // provides the static storage. However, this might change to improve // image sharing, so we use this type to avoid assumptions on the @@ -962,12 +952,10 @@ class Class : public Object, public StaticStorageBase { // Given the context of a calling Method, use its DexCache to // resolve a type to a Class. If it cannot be resolved, throw an // error. If it can, use it to create an instance. - static Object* NewInstanceFromCode(uint32_t type_idx, Method* method); + static Object* AllocObjectFromCode(uint32_t type_idx, Method* method); - Object* NewInstance() { - DCHECK(!IsAbstract()); - return Heap::AllocObject(this, this->object_size_); - } + // Creates a raw object instance but does not invoke the default constructor. + Object* AllocObject(); Class* GetSuperClass() const { return super_class_; @@ -1101,6 +1089,26 @@ class Class : public Object, public StaticStorageBase { return (access_flags_ & kAccSynthetic) != 0; } + bool IsReference() const { + return (access_flags_ & kAccClassIsReference) != 0; + } + + bool IsWeakReference() const { + return (access_flags_ & kAccClassIsWeakReference) != 0; + } + + bool IsSoftReference() const { + return (access_flags_ & ~kAccReferenceFlagsMask) == kAccClassIsReference; + } + + bool IsFinalizerReference() const { + return (access_flags_ & kAccClassIsFinalizerReference) != 0; + } + + bool IsPhantomReference() const { + return (access_flags_ & kAccClassIsPhantomReference) != 0; + } + // Returns true if this class can access that class. bool CanAccess(const Class* that) const { return that->IsPublic() || this->IsInSamePackage(that); @@ -1188,6 +1196,7 @@ class Class : public Object, public StaticStorageBase { Field* FindInstanceField(const StringPiece& name, const StringPiece& descriptor); + // Finds the given instance field in this class. Field* FindDeclaredInstanceField(const StringPiece& name, const StringPiece& descriptor); @@ -1195,6 +1204,7 @@ class Class : public Object, public StaticStorageBase { Field* FindStaticField(const StringPiece& name, const StringPiece& descriptor); + // Finds the given static field in this class. Field* FindDeclaredStaticField(const StringPiece& name, const StringPiece& descriptor); @@ -1616,7 +1626,7 @@ class String : public Object { } static String* Alloc(Class* java_lang_String, CharArray* array) { - String* string = down_cast<String*>(java_lang_String->NewInstance()); + String* string = down_cast<String*>(java_lang_String->AllocObject()); string->array_ = array; string->count_ = array->GetLength(); return string; @@ -1730,7 +1740,7 @@ class StackTraceElement : public Object { static StackTraceElement* Alloc(const String* declaring_class, const String* method_name, const String* file_name, int32_t line_number) { - StackTraceElement* trace = down_cast<StackTraceElement*>(GetStackTraceElement()->NewInstance()); + StackTraceElement* trace = down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject()); trace->declaring_class_ = declaring_class; trace->method_name_ = method_name; trace->file_name_ = file_name; diff --git a/src/object_bitmap.cc b/src/object_bitmap.cc index ae67ee5a95..4b4c5ee84b 100644 --- a/src/object_bitmap.cc +++ b/src/object_bitmap.cc @@ -31,7 +31,7 @@ HeapBitmap* HeapBitmap::Create(byte* base, size_t length) { } // Initialize a HeapBitmap so that it points to a bitmap large enough -// to cover a heap at <base> of <maxSize> bytes, where objects are +// to cover a heap at <base> of <max_size> bytes, where objects are // guaranteed to be kAlignment-aligned. bool HeapBitmap::Init(const byte* base, size_t max_size) { CHECK(base != NULL); @@ -107,14 +107,11 @@ void HeapBitmap::Walk(HeapBitmap::Callback* callback, void* arg) { // address will be visited by the traversal. If the callback sets a // bit for an address below the finger, this address will not be // visited. -void HeapBitmap::ScanWalk(uintptr_t base, uintptr_t max, - ScanCallback* callback, void* arg) { +void HeapBitmap::ScanWalk(uintptr_t base, ScanCallback* callback, void* arg) { CHECK(words_ != NULL); CHECK(callback != NULL); - CHECK(base <= max); CHECK(base >= base_); - CHECK(max <= max_); - uintptr_t end = HB_OFFSET_TO_INDEX(max - base); + uintptr_t end = HB_OFFSET_TO_INDEX(max_ - base); for (uintptr_t i = 0; i <= end; ++i) { unsigned long word = words_[i]; if (word != 0) { @@ -148,7 +145,7 @@ void HeapBitmap::SweepWalk(const HeapBitmap& live_bitmap, CHECK(callback != NULL); CHECK(base <= max); CHECK(base >= live_bitmap.base_); - CHECK(max <= live_bitmap.max_); + max = std::min(max-1, live_bitmap.max_); if (live_bitmap.max_ < live_bitmap.base_) { // Easy case; both are obviously empty. // TODO: this should never happen diff --git a/src/object_bitmap.h b/src/object_bitmap.h index fc9a3a8266..dd23d15abb 100644 --- a/src/object_bitmap.h +++ b/src/object_bitmap.h @@ -85,8 +85,7 @@ class HeapBitmap { void Walk(Callback* callback, void* arg); - void ScanWalk(uintptr_t base, uintptr_t max, - ScanCallback* thunk, void* arg); + void ScanWalk(uintptr_t base, ScanCallback* thunk, void* arg); static void SweepWalk(const HeapBitmap& live, const HeapBitmap& mark, @@ -131,7 +130,7 @@ class HeapBitmap { // The highest pointer value ever returned by an allocation from // this heap. I.e., the highest address that may correspond to a - // set bit. If there are no bits set, (max < base). + // set bit. If there are no bits set, (max_ < base_). uintptr_t max_; const char* name_; diff --git a/src/object_test.cc b/src/object_test.cc index 99567e8c82..f397b2e506 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -10,7 +10,6 @@ #include "common_test.h" #include "dex_file.h" #include "heap.h" -#include "gtest/gtest.h" namespace art { @@ -185,7 +184,7 @@ TEST_F(ObjectTest, AllocObjectFromCode) { Class* java_lang_Object = class_linker_->FindSystemClass("Ljava/lang/Object;"); Method* toString = java_lang_Object->FindVirtualMethod("toString", "()Ljava/lang/String;"); uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "Ljava/lang/String;"); - Object* string = Class::NewInstanceFromCode(type_idx, toString); + Object* string = Class::AllocObjectFromCode(type_idx, toString); EXPECT_TRUE(string->IsString()); } @@ -334,8 +333,8 @@ TEST_F(ObjectTest, InstanceOf) { EXPECT_FALSE(Object::InstanceOf(NULL, X)); EXPECT_FALSE(Object::InstanceOf(NULL, Y)); - Object* x = X->NewInstance(); - Object* y = Y->NewInstance(); + Object* x = X->AllocObject(); + Object* y = Y->AllocObject(); ASSERT_TRUE(x != NULL); ASSERT_TRUE(y != NULL); diff --git a/src/reference_table_test.cc b/src/reference_table_test.cc index 1f065e6fde..73ec87beca 100644 --- a/src/reference_table_test.cc +++ b/src/reference_table_test.cc @@ -4,8 +4,6 @@ #include "reference_table.h" -#include "gtest/gtest.h" - namespace art { class ReferenceTableTest : public CommonTest { diff --git a/src/runtime.cc b/src/runtime.cc index 50f25fee45..1ac45f4661 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -383,4 +383,9 @@ bool Runtime::DetachCurrentThread() { return true; } +void Runtime::VisitRoots(Heap::RootVistor* root_visitor, void* arg) const { + GetClassLinker()->VisitRoots(root_visitor, arg); + UNIMPLEMENTED(WARNING) << "mark other roots including per thread state and thread stacks"; +} + } // namespace art diff --git a/src/runtime.h b/src/runtime.h index 8694b3c304..40db8145c0 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -12,6 +12,7 @@ #include <jni.h> +#include "heap.h" #include "globals.h" #include "macros.h" #include "stringpiece.h" @@ -93,6 +94,8 @@ class Runtime { return java_vm_; } + void VisitRoots(Heap::RootVistor* root_visitor, void* arg) const; + private: static void PlatformAbort(const char*, int); diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc index e6e423d298..b83e71d152 100644 --- a/src/signal_catcher.cc +++ b/src/signal_catcher.cc @@ -23,6 +23,7 @@ #include <unistd.h> #include "heap.h" +#include "runtime.h" #include "thread.h" #include "utils.h" diff --git a/src/thread.cc b/src/thread.cc index 9d2862d41e..062550df41 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -62,7 +62,7 @@ void Thread::InitFunctionPointers() { pLmul = __aeabi_lmul; #endif pAllocFromCode = Array::AllocFromCode; - pNewInstanceFromCode = Class::NewInstanceFromCode; + pAllocObjectFromCode = Class::AllocObjectFromCode; pMemcpy = memcpy; pArtHandleFillArrayDataNoThrow = artHandleFillArrayDataNoThrow; pGet32Static = Field::Get32StaticFromCode; diff --git a/src/thread.h b/src/thread.h index 82cca6d687..41bb0dac67 100644 --- a/src/thread.h +++ b/src/thread.h @@ -6,21 +6,20 @@ #include <pthread.h> #include <list> +#include "dex_file.h" #include "globals.h" #include "jni_internal.h" #include "logging.h" #include "macros.h" #include "mem_map.h" #include "offsets.h" -#include "runtime.h" - namespace art { class Array; class Class; +class ClassLinker; class ClassLoader; -class JNIEnvExt; class Method; class Object; class Runtime; @@ -202,7 +201,7 @@ class Thread { long long (*pLmul)(long long, long long); long long (*pLdivmod)(long long, long long); Array* (*pAllocFromCode)(uint32_t, Method*, int32_t); - Object* (*pNewInstanceFromCode)(uint32_t, Method*); + Object* (*pAllocObjectFromCode)(uint32_t, Method*); uint32_t (*pGet32Static)(uint32_t, const Method*); void (*pSet32Static)(uint32_t, const Method*, uint32_t); uint64_t (*pGet64Static)(uint32_t, const Method*); diff --git a/src/utils_test.cc b/src/utils_test.cc index 3d53c35302..21167d6836 100644 --- a/src/utils_test.cc +++ b/src/utils_test.cc @@ -4,8 +4,6 @@ #include "common_test.h" #include "utils.h" -#include "gtest/gtest.h" - namespace art { class UtilsTest : public CommonTest { diff --git a/src/zip_archive_test.cc b/src/zip_archive_test.cc index e6b40024da..051f096d8e 100644 --- a/src/zip_archive_test.cc +++ b/src/zip_archive_test.cc @@ -8,7 +8,6 @@ #include "UniquePtr.h" #include "common_test.h" -#include "gtest/gtest.h" #include "os.h" namespace art { |