diff options
author | Ian Rogers <irogers@google.com> | 2012-10-03 21:09:42 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2012-10-04 09:27:04 -0700 |
commit | 1f5393447b9f45be7918042d9ee7b521376de866 (patch) | |
tree | 1793cb0ae00b38a63f8cfd3a25b6cb0ee4edca16 | |
parent | 870ea4772199f8d4cbd9a269f9093620ee50a59c (diff) | |
download | art-1f5393447b9f45be7918042d9ee7b521376de866.zip art-1f5393447b9f45be7918042d9ee7b521376de866.tar.gz art-1f5393447b9f45be7918042d9ee7b521376de866.tar.bz2 |
Make PopSirt inlinable, pass self to SirtRef.
Change-Id: Ieb91526b1cb1f8644ceb3c5b99649f658f43bbc1
-rw-r--r-- | src/class_linker.cc | 147 | ||||
-rw-r--r-- | src/class_linker.h | 4 | ||||
-rw-r--r-- | src/class_linker_test.cc | 25 | ||||
-rw-r--r-- | src/compiler.cc | 7 | ||||
-rw-r--r-- | src/debugger.cc | 5 | ||||
-rw-r--r-- | src/dex2oat.cc | 11 | ||||
-rw-r--r-- | src/dex_cache_test.cc | 3 | ||||
-rw-r--r-- | src/exception_test.cc | 4 | ||||
-rw-r--r-- | src/heap.cc | 9 | ||||
-rw-r--r-- | src/heap.h | 2 | ||||
-rw-r--r-- | src/heap_test.cc | 3 | ||||
-rw-r--r-- | src/image_writer.cc | 17 | ||||
-rw-r--r-- | src/intern_table_test.cc | 47 | ||||
-rw-r--r-- | src/jni_internal_test.cc | 8 | ||||
-rw-r--r-- | src/native/java_lang_reflect_Array.cc | 23 | ||||
-rw-r--r-- | src/oat/runtime/arm/stub_arm.cc | 7 | ||||
-rw-r--r-- | src/oat/runtime/mips/stub_mips.cc | 7 | ||||
-rw-r--r-- | src/oat/runtime/x86/stub_x86.cc | 7 | ||||
-rw-r--r-- | src/object.cc | 10 | ||||
-rw-r--r-- | src/object_test.cc | 77 | ||||
-rw-r--r-- | src/object_utils.h | 4 | ||||
-rw-r--r-- | src/runtime.cc | 10 | ||||
-rw-r--r-- | src/sirt_ref.h | 55 | ||||
-rw-r--r-- | src/stack_indirect_reference_table.h | 34 | ||||
-rw-r--r-- | src/thread.cc | 46 | ||||
-rw-r--r-- | src/thread.h | 14 | ||||
-rw-r--r-- | src/utils_test.cc | 5 |
27 files changed, 333 insertions, 258 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index fdcbf20..448ad6a 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -47,6 +47,7 @@ #endif #include "ScopedLocalRef.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "space.h" #include "space_bitmap.h" #include "stack_indirect_reference_table.h" @@ -232,42 +233,43 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class CHECK(!init_done_); // java_lang_Class comes first, it's needed for AllocClass + Thread* self = Thread::Current(); Heap* heap = Runtime::Current()->GetHeap(); - SirtRef<Class> java_lang_Class(down_cast<Class*>(heap->AllocObject(NULL, sizeof(ClassClass)))); + SirtRef<Class> java_lang_Class(self, down_cast<Class*>(heap->AllocObject(NULL, sizeof(ClassClass)))); CHECK(java_lang_Class.get() != NULL); java_lang_Class->SetClass(java_lang_Class.get()); java_lang_Class->SetClassSize(sizeof(ClassClass)); // AllocClass(Class*) can now be used // Class[] is used for reflection support. - SirtRef<Class> class_array_class(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> class_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class))); class_array_class->SetComponentType(java_lang_Class.get()); // java_lang_Object comes next so that object_array_class can be created. - SirtRef<Class> java_lang_Object(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> java_lang_Object(self, AllocClass(java_lang_Class.get(), sizeof(Class))); CHECK(java_lang_Object.get() != NULL); // backfill Object as the super class of Class. java_lang_Class->SetSuperClass(java_lang_Object.get()); java_lang_Object->SetStatus(Class::kStatusLoaded); // Object[] next to hold class roots. - SirtRef<Class> object_array_class(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> object_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class))); object_array_class->SetComponentType(java_lang_Object.get()); // Object[][] needed for iftables. - SirtRef<Class> object_array_array_class(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> object_array_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class))); object_array_array_class->SetComponentType(object_array_class.get()); // Setup the char class to be used for char[]. - SirtRef<Class> char_class(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> char_class(self, AllocClass(java_lang_Class.get(), sizeof(Class))); // Setup the char[] class to be used for String. - SirtRef<Class> char_array_class(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> char_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class))); char_array_class->SetComponentType(char_class.get()); CharArray::SetArrayClass(char_array_class.get()); // Setup String. - SirtRef<Class> java_lang_String(AllocClass(java_lang_Class.get(), sizeof(StringClass))); + SirtRef<Class> java_lang_String(self, AllocClass(java_lang_Class.get(), sizeof(StringClass))); String::SetClass(java_lang_String.get()); java_lang_String->SetObjectSize(sizeof(String)); java_lang_String->SetStatus(Class::kStatusResolved); @@ -297,7 +299,7 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class array_iftable_ = AllocIfTable(2); // Create int array type for AllocDexCache (done in AppendToBootClassPath). - SirtRef<Class> int_array_class(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> int_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class))); int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt)); IntArray::SetArrayClass(int_array_class.get()); SetClassRoot(kIntArrayClass, int_array_class.get()); @@ -305,33 +307,33 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class // now that these are registered, we can use AllocClass() and AllocObjectArray // Setup DexCache. This can not be done later since AppendToBootClassPath calls AllocDexCache. - SirtRef<Class> java_lang_DexCache(AllocClass(java_lang_Class.get(), sizeof(DexCacheClass))); + SirtRef<Class> java_lang_DexCache(self, AllocClass(java_lang_Class.get(), sizeof(DexCacheClass))); SetClassRoot(kJavaLangDexCache, java_lang_DexCache.get()); java_lang_DexCache->SetObjectSize(sizeof(DexCacheClass)); java_lang_DexCache->SetStatus(Class::kStatusResolved); // Constructor, Field, Method, and AbstractMethod are necessary so that FindClass can link members. - SirtRef<Class> java_lang_reflect_Constructor(AllocClass(java_lang_Class.get(), + SirtRef<Class> java_lang_reflect_Constructor(self, AllocClass(java_lang_Class.get(), sizeof(MethodClass))); CHECK(java_lang_reflect_Constructor.get() != NULL); java_lang_reflect_Constructor->SetObjectSize(sizeof(Constructor)); SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor.get()); java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved); - SirtRef<Class> java_lang_reflect_Field(AllocClass(java_lang_Class.get(), sizeof(FieldClass))); + SirtRef<Class> java_lang_reflect_Field(self, AllocClass(java_lang_Class.get(), sizeof(FieldClass))); CHECK(java_lang_reflect_Field.get() != NULL); java_lang_reflect_Field->SetObjectSize(sizeof(Field)); SetClassRoot(kJavaLangReflectField, java_lang_reflect_Field.get()); java_lang_reflect_Field->SetStatus(Class::kStatusResolved); Field::SetClass(java_lang_reflect_Field.get()); - SirtRef<Class> java_lang_reflect_Method(AllocClass(java_lang_Class.get(), sizeof(MethodClass))); + SirtRef<Class> java_lang_reflect_Method(self, AllocClass(java_lang_Class.get(), sizeof(MethodClass))); CHECK(java_lang_reflect_Method.get() != NULL); java_lang_reflect_Method->SetObjectSize(sizeof(Method)); SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method.get()); java_lang_reflect_Method->SetStatus(Class::kStatusResolved); - SirtRef<Class> java_lang_reflect_AbstractMethod(AllocClass(java_lang_Class.get(), + SirtRef<Class> java_lang_reflect_AbstractMethod(self, AllocClass(java_lang_Class.get(), sizeof(MethodClass))); CHECK(java_lang_reflect_AbstractMethod.get() != NULL); java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod)); @@ -340,15 +342,15 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class AbstractMethod::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get()); // Set up array classes for string, field, method - SirtRef<Class> object_array_string(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> object_array_string(self, AllocClass(java_lang_Class.get(), sizeof(Class))); object_array_string->SetComponentType(java_lang_String.get()); SetClassRoot(kJavaLangStringArrayClass, object_array_string.get()); - SirtRef<Class> object_array_field(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> object_array_field(self, AllocClass(java_lang_Class.get(), sizeof(Class))); object_array_field->SetComponentType(java_lang_reflect_Field.get()); SetClassRoot(kJavaLangReflectFieldArrayClass, object_array_field.get()); - SirtRef<Class> object_array_abstract_method(AllocClass(java_lang_Class.get(), sizeof(Class))); + SirtRef<Class> object_array_abstract_method(self, AllocClass(java_lang_Class.get(), sizeof(Class))); object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get()); SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get()); @@ -960,8 +962,9 @@ void ClassLinker::InitFromImage() { CHECK_EQ(oat_file->GetOatHeader().GetDexFileCount(), static_cast<uint32_t>(dex_caches->GetLength())); + Thread* self = Thread::Current(); for (int i = 0; i < dex_caches->GetLength(); i++) { - SirtRef<DexCache> dex_cache(dex_caches->Get(i)); + SirtRef<DexCache> dex_cache(self, dex_caches->Get(i)); const std::string& dex_file_location(dex_cache->GetLocation()->ToModifiedUtf8()); const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file_location); const DexFile* dex_file = oat_dex_file->OpenDexFile(); @@ -1110,32 +1113,35 @@ ClassLinker::~ClassLinker() { DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) { Heap* heap = Runtime::Current()->GetHeap(); Class* dex_cache_class = GetClassRoot(kJavaLangDexCache); + Thread* self = Thread::Current(); SirtRef<DexCache> dex_cache( + self, down_cast<DexCache*>(heap->AllocObject(dex_cache_class, dex_cache_class->GetObjectSize()))); if (dex_cache.get() == NULL) { return NULL; } - SirtRef<String> location(intern_table_->InternStrong(dex_file.GetLocation().c_str())); + SirtRef<String> location(self, intern_table_->InternStrong(dex_file.GetLocation().c_str())); if (location.get() == NULL) { return NULL; } - SirtRef<ObjectArray<String> > strings(AllocStringArray(dex_file.NumStringIds())); + SirtRef<ObjectArray<String> > strings(self, AllocStringArray(dex_file.NumStringIds())); if (strings.get() == NULL) { return NULL; } - SirtRef<ObjectArray<Class> > types(AllocClassArray(dex_file.NumTypeIds())); + SirtRef<ObjectArray<Class> > types(self, AllocClassArray(dex_file.NumTypeIds())); if (types.get() == NULL) { return NULL; } - SirtRef<ObjectArray<AbstractMethod> > methods(AllocMethodArray(dex_file.NumMethodIds())); + SirtRef<ObjectArray<AbstractMethod> > methods(self, AllocMethodArray(dex_file.NumMethodIds())); if (methods.get() == NULL) { return NULL; } - SirtRef<ObjectArray<Field> > fields(AllocFieldArray(dex_file.NumFieldIds())); + SirtRef<ObjectArray<Field> > fields(self, AllocFieldArray(dex_file.NumFieldIds())); if (fields.get() == NULL) { return NULL; } - SirtRef<ObjectArray<StaticStorageBase> > initialized_static_storage(AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds())); + SirtRef<ObjectArray<StaticStorageBase> > + initialized_static_storage(self, AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds())); if (initialized_static_storage.get() == NULL) { return NULL; } @@ -1152,8 +1158,9 @@ DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) { InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) { DCHECK(interface->IsInterface()); - SirtRef<ObjectArray<Object> > array(AllocObjectArray<Object>(InterfaceEntry::LengthAsArray())); - SirtRef<InterfaceEntry> interface_entry(down_cast<InterfaceEntry*>(array.get())); + Thread* self = Thread::Current(); + SirtRef<ObjectArray<Object> > array(self, AllocObjectArray<Object>(InterfaceEntry::LengthAsArray())); + SirtRef<InterfaceEntry> interface_entry(self, down_cast<InterfaceEntry*>(array.get())); interface_entry->SetInterface(interface); return interface_entry.get(); } @@ -1161,7 +1168,8 @@ InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) { Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) { DCHECK_GE(class_size, sizeof(Class)); Heap* heap = Runtime::Current()->GetHeap(); - SirtRef<Class> klass(heap->AllocObject(java_lang_Class, class_size)->AsClass()); + SirtRef<Class> klass(Thread::Current(), + heap->AllocObject(java_lang_Class, class_size)->AsClass()); klass->SetPrimitiveType(Primitive::kPrimNot); // default to not being primitive klass->SetClassSize(class_size); return klass.get(); @@ -1195,7 +1203,7 @@ static Class* EnsureResolved(Class* klass) // Wait for the class if it has not already been linked. Thread* self = Thread::Current(); if (!klass->IsResolved() && !klass->IsErroneous()) { - ObjectLock lock(klass); + ObjectLock lock(self, klass); // Check for circular dependencies between classes. if (!klass->IsResolved() && klass->GetClinitThreadId() == self->GetTid()) { self->ThrowNewException("Ljava/lang/ClassCircularityError;", @@ -1311,7 +1319,8 @@ Class* ClassLinker::DefineClass(const StringPiece& descriptor, ClassLoader* class_loader, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def) { - SirtRef<Class> klass(NULL); + Thread* self = Thread::Current(); + SirtRef<Class> klass(self, NULL); // Load the class from the dex file. if (!init_done_) { // finish up init of hand crafted class_roots_ @@ -1340,15 +1349,14 @@ Class* ClassLinker::DefineClass(const StringPiece& descriptor, klass->SetDexCache(FindDexCache(dex_file)); LoadClass(dex_file, dex_class_def, klass, class_loader); // Check for a pending exception during load - Thread* self = Thread::Current(); if (self->IsExceptionPending()) { klass->SetStatus(Class::kStatusError); return NULL; } - ObjectLock lock(klass.get()); + ObjectLock lock(self, klass.get()); klass->SetClinitThreadId(self->GetTid()); // Add the newly loaded class to the loaded classes table. - SirtRef<Class> existing(InsertClass(descriptor, klass.get(), false)); + SirtRef<Class> existing(self, InsertClass(descriptor, klass.get(), false)); if (existing.get() != NULL) { // We failed to insert because we raced with another thread. return EnsureResolved(existing.get()); @@ -1586,13 +1594,14 @@ void ClassLinker::LoadClass(const DexFile& dex_file, if (it.NumInstanceFields() != 0) { klass->SetIFields(AllocObjectArray<Field>(it.NumInstanceFields())); } + Thread* self = Thread::Current(); for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) { - SirtRef<Field> sfield(AllocField()); + SirtRef<Field> sfield(self, AllocField()); klass->SetStaticField(i, sfield.get()); LoadField(dex_file, it, klass, sfield); } for (size_t i = 0; it.HasNextInstanceField(); i++, it.Next()) { - SirtRef<Field> ifield(AllocField()); + SirtRef<Field> ifield(self, AllocField()); klass->SetInstanceField(i, ifield.get()); LoadField(dex_file, it, klass, ifield); } @@ -1613,7 +1622,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, } size_t class_def_method_index = 0; for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) { - SirtRef<AbstractMethod> method(LoadMethod(dex_file, it, klass)); + SirtRef<AbstractMethod> method(self, LoadMethod(dex_file, it, klass)); klass->SetDirectMethod(i, method.get()); if (oat_class.get() != NULL) { LinkCode(method, oat_class.get(), class_def_method_index); @@ -1622,7 +1631,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, class_def_method_index++; } for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) { - SirtRef<AbstractMethod> method(LoadMethod(dex_file, it, klass)); + SirtRef<AbstractMethod> method(self, LoadMethod(dex_file, it, klass)); klass->SetVirtualMethod(i, method.get()); DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i); if (oat_class.get() != NULL) { @@ -1704,7 +1713,7 @@ AbstractMethod* ClassLinker::LoadMethod(const DexFile& dex_file, const ClassData } void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) { - SirtRef<DexCache> dex_cache(AllocDexCache(dex_file)); + SirtRef<DexCache> dex_cache(Thread::Current(), AllocDexCache(dex_file)); AppendToBootClassPath(dex_file, dex_cache); } @@ -1738,8 +1747,9 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<DexCach } void ClassLinker::RegisterDexFile(const DexFile& dex_file) { + Thread* self = Thread::Current(); { - MutexLock mu(dex_lock_); + MutexLock mu(self, dex_lock_); if (IsDexFileRegisteredLocked(dex_file)) { return; } @@ -1747,9 +1757,9 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file) { // Don't alloc while holding the lock, since allocation may need to // suspend all threads and another thread may need the dex_lock_ to // get to a suspend point. - SirtRef<DexCache> dex_cache(AllocDexCache(dex_file)); + SirtRef<DexCache> dex_cache(self, AllocDexCache(dex_file)); { - MutexLock mu(dex_lock_); + MutexLock mu(self, dex_lock_); if (IsDexFileRegisteredLocked(dex_file)) { return; } @@ -1793,7 +1803,8 @@ void ClassLinker::FixupDexCaches(AbstractMethod* resolution_method) const { Class* ClassLinker::InitializePrimitiveClass(Class* primitive_class, Primitive::Type type) { CHECK(primitive_class != NULL); - ObjectLock lock(primitive_class); // Must hold lock on object when initializing. + // Must hold lock on object when initializing. + ObjectLock lock(Thread::Current(), primitive_class); primitive_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract); primitive_class->SetPrimitiveType(type); primitive_class->SetStatus(Class::kStatusInitialized); @@ -1857,8 +1868,8 @@ Class* ClassLinker::CreateArrayClass(const std::string& descriptor, ClassLoader* // // Array classes are simple enough that we don't need to do a full // link step. - - SirtRef<Class> new_class(NULL); + Thread* self = Thread::Current(); + SirtRef<Class> new_class(self, NULL); if (!init_done_) { // Classes that were hand created, ie not by FindSystemClass if (descriptor == "[Ljava/lang/Class;") { @@ -1886,7 +1897,7 @@ Class* ClassLinker::CreateArrayClass(const std::string& descriptor, ClassLoader* } new_class->SetComponentType(component_type); } - ObjectLock lock(new_class.get()); // Must hold lock on object when initializing. + ObjectLock lock(self, new_class.get()); // Must hold lock on object when initializing. DCHECK(new_class->GetComponentType() != NULL); Class* java_lang_Object = GetClassRoot(kJavaLangObject); new_class->SetSuperClass(java_lang_Object); @@ -2074,7 +2085,8 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<Class*>& cla void ClassLinker::VerifyClass(Class* klass) { // TODO: assert that the monitor on the Class is held - ObjectLock lock(klass); + Thread* self = Thread::Current(); + ObjectLock lock(self, klass); // Don't attempt to re-verify if already sufficiently verified. if (klass->IsVerified() || @@ -2102,7 +2114,7 @@ void ClassLinker::VerifyClass(Class* klass) { std::string error_msg; if (super != NULL) { // Acquire lock to prevent races on verifying the super class. - ObjectLock lock(super); + ObjectLock lock(self, super); if (!super->IsVerified() && !super->IsErroneous()) { Runtime::Current()->GetClassLinker()->VerifyClass(super); @@ -2113,8 +2125,7 @@ void ClassLinker::VerifyClass(Class* klass) { error_msg += " that attempts to sub-class erroneous class "; error_msg += PrettyDescriptor(super); LOG(ERROR) << error_msg << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8(); - Thread* self = Thread::Current(); - SirtRef<Throwable> cause(self->GetException()); + SirtRef<Throwable> cause(self, self->GetException()); if (cause.get() != NULL) { self->ClearException(); } @@ -2151,7 +2162,7 @@ void ClassLinker::VerifyClass(Class* klass) { << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8() << " because: " << error_msg; } - Thread::Current()->AssertNoPendingException(); + self->AssertNoPendingException(); // Make sure all classes referenced by catch blocks are resolved. ResolveClassExceptionHandlerTypes(dex_file, klass); if (verifier_failure == verifier::MethodVerifier::kNoFailure) { @@ -2171,7 +2182,6 @@ void ClassLinker::VerifyClass(Class* klass) { LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(klass) << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8() << " because: " << error_msg; - Thread* self = Thread::Current(); self->AssertNoPendingException(); self->ThrowNewException("Ljava/lang/VerifyError;", error_msg.c_str()); klass->SetStatus(Class::kStatusError); @@ -2284,7 +2294,8 @@ static void CheckProxyMethod(AbstractMethod* method, SirtRef<AbstractMethod>& pr Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interfaces, ClassLoader* loader, ObjectArray<AbstractMethod>* methods, ObjectArray<ObjectArray<Class> >* throws) { - SirtRef<Class> klass(AllocClass(GetClassRoot(kJavaLangClass), sizeof(SynthesizedProxyClass))); + Thread* self = Thread::Current(); + SirtRef<Class> klass(self, AllocClass(GetClassRoot(kJavaLangClass), sizeof(SynthesizedProxyClass))); CHECK(klass.get() != NULL); DCHECK(klass->GetClass() != NULL); klass->SetObjectSize(sizeof(Proxy)); @@ -2303,13 +2314,13 @@ Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interface klass->SetSFields(AllocObjectArray<Field>(2)); // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by // our proxy, so Class.getInterfaces doesn't return the flattened set. - SirtRef<Field> interfaces_sfield(AllocField()); + SirtRef<Field> interfaces_sfield(self, AllocField()); klass->SetStaticField(0, interfaces_sfield.get()); interfaces_sfield->SetDexFieldIndex(0); interfaces_sfield->SetDeclaringClass(klass.get()); interfaces_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal); // 2. Create a static field 'throws' that holds exceptions thrown by our methods. - SirtRef<Field> throws_sfield(AllocField()); + SirtRef<Field> throws_sfield(self, AllocField()); klass->SetStaticField(1, throws_sfield.get()); throws_sfield->SetDexFieldIndex(1); throws_sfield->SetDeclaringClass(klass.get()); @@ -2323,7 +2334,7 @@ Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interface size_t num_virtual_methods = methods->GetLength(); klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(num_virtual_methods)); for (size_t i = 0; i < num_virtual_methods; ++i) { - SirtRef<AbstractMethod> prototype(methods->Get(i)); + SirtRef<AbstractMethod> prototype(self, methods->Get(i)); klass->SetVirtualMethod(i, CreateProxyMethod(klass, prototype)); } @@ -2337,7 +2348,7 @@ Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interface return NULL; } { - ObjectLock lock(klass.get()); // Must hold lock on object when initializing. + ObjectLock lock(self, klass.get()); // Must hold lock on object when initializing. interfaces_sfield->SetObject(NULL, interfaces); throws_sfield->SetObject(NULL, throws); klass->SetStatus(Class::kStatusInitialized); @@ -2348,7 +2359,7 @@ Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interface CHECK(klass->GetIFields() == NULL); CheckProxyConstructor(klass->GetDirectMethod(0)); for (size_t i = 0; i < num_virtual_methods; ++i) { - SirtRef<AbstractMethod> prototype(methods->Get(i)); + SirtRef<AbstractMethod> prototype(self, methods->Get(i)); CheckProxyMethod(klass->GetVirtualMethod(i), prototype); } @@ -2483,7 +2494,7 @@ bool ClassLinker::InitializeClass(Class* klass, bool can_run_clinit, bool can_in AbstractMethod* clinit = NULL; { // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol - ObjectLock lock(klass); + ObjectLock lock(self, klass); if (klass->GetStatus() == Class::kStatusInitialized) { return true; @@ -2555,7 +2566,7 @@ bool ClassLinker::InitializeClass(Class* klass, bool can_run_clinit, bool can_in CHECK(klass->IsErroneous()); } // Signal to any waiting threads that saw this class as initializing. - ObjectLock lock(klass); + ObjectLock lock(self, klass); lock.NotifyAll(); return false; } @@ -2572,7 +2583,7 @@ bool ClassLinker::InitializeClass(Class* klass, bool can_run_clinit, bool can_in bool success = true; { - ObjectLock lock(klass); + ObjectLock lock(self, klass); if (self->IsExceptionPending()) { WrapExceptionInInitializer(); @@ -2739,7 +2750,8 @@ bool ClassLinker::InitializeSuperClass(Class* klass, bool can_run_clinit, bool c Class* super_class = klass->GetSuperClass(); if (!super_class->IsInitialized()) { CHECK(!super_class->IsInterface()); - ObjectLock lock(klass); // Must hold lock on object when initializing and setting status. + // Must hold lock on object when initializing and setting status. + ObjectLock lock(Thread::Current(), klass); bool super_initialized = InitializeClass(super_class, can_run_clinit, can_init_fields); // TODO: check for a pending exception if (!super_initialized) { @@ -2961,12 +2973,14 @@ bool ClassLinker::LinkMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfa } bool ClassLinker::LinkVirtualMethods(SirtRef<Class>& klass) { + Thread* self = Thread::Current(); if (klass->HasSuperClass()) { uint32_t max_count = klass->NumVirtualMethods() + klass->GetSuperClass()->GetVTable()->GetLength(); size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength(); CHECK_LE(actual_count, max_count); // TODO: do not assign to the vtable field until it is fully constructed. - SirtRef<ObjectArray<AbstractMethod> > vtable(klass->GetSuperClass()->GetVTable()->CopyOf(max_count)); + SirtRef<ObjectArray<AbstractMethod> > + vtable(self, klass->GetSuperClass()->GetVTable()->CopyOf(max_count)); // See if any of our virtual methods override the superclass. MethodHelper local_mh(NULL, this); MethodHelper super_mh(NULL, this); @@ -3019,7 +3033,8 @@ bool ClassLinker::LinkVirtualMethods(SirtRef<Class>& klass) { ThrowClassFormatError("Too many methods: %d", num_virtual_methods); return false; } - SirtRef<ObjectArray<AbstractMethod> > vtable(AllocObjectArray<AbstractMethod>(num_virtual_methods)); + SirtRef<ObjectArray<AbstractMethod> > + vtable(self, AllocObjectArray<AbstractMethod>(num_virtual_methods)); for (size_t i = 0; i < num_virtual_methods; ++i) { AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i); vtable->Set(i, virtual_method); @@ -3051,7 +3066,8 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class> // DCHECK(klass->GetIfTable() == NULL); return true; } - SirtRef<ObjectArray<InterfaceEntry> > iftable(AllocIfTable(ifcount)); + Thread* self = Thread::Current(); + SirtRef<ObjectArray<InterfaceEntry> > iftable(self, AllocIfTable(ifcount)); if (super_ifcount != 0) { ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable(); for (size_t i = 0; i < super_ifcount; i++) { @@ -3066,7 +3082,6 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class> DCHECK(interface != NULL); if (!interface->IsInterface()) { ClassHelper ih(interface); - Thread* self = Thread::Current(); self->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;", "Class %s implements non-interface class %s", PrettyDescriptor(klass.get()).c_str(), @@ -3150,7 +3165,7 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class> } } if (k < 0) { - SirtRef<AbstractMethod> miranda_method(NULL); + SirtRef<AbstractMethod> miranda_method(self, NULL); for (size_t mir = 0; mir < miranda_list.size(); mir++) { AbstractMethod* mir_method = miranda_list[mir]; vtable_mh.ChangeMethod(mir_method); @@ -3175,7 +3190,7 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class> ? AllocObjectArray<AbstractMethod>(new_method_count) : klass->GetVirtualMethods()->CopyOf(new_method_count)); - SirtRef<ObjectArray<AbstractMethod> > vtable(klass->GetVTableDuringLinking()); + SirtRef<ObjectArray<AbstractMethod> > vtable(self, klass->GetVTableDuringLinking()); CHECK(vtable.get() != NULL); int old_vtable_count = vtable->GetLength(); int new_vtable_count = old_vtable_count + miranda_list.size(); diff --git a/src/class_linker.h b/src/class_linker.h index d75e1b2..b07157a 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -30,7 +30,6 @@ #include "oat_file.h" #include "object.h" #include "safe_map.h" -#include "stack_indirect_reference_table.h" namespace art { @@ -38,12 +37,13 @@ class ClassLoader; class ImageSpace; class InternTable; class ObjectLock; +template<class T> class SirtRef; typedef bool (ClassVisitor)(Class* c, void* arg); class ClassLinker { public: - // Creates the class linker by boot strapping from dex files. + // Creates the class linker by bootstrapping from dex files. static ClassLinker* CreateFromCompiler(const std::vector<const DexFile*>& boot_class_path, InternTable* intern_table) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index 106598e..d0b9e16 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -24,6 +24,7 @@ #include "dex_file.h" #include "heap.h" #include "runtime_support.h" +#include "sirt_ref.h" namespace art { @@ -654,7 +655,7 @@ TEST_F(ClassLinkerTest, FindClassNonexistent) { TEST_F(ClassLinkerTest, FindClassNested) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("Nested"))); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(LoadDex("Nested"))); Class* outer = class_linker_->FindClass("LNested;", class_loader.get()); ASSERT_TRUE(outer != NULL); @@ -718,7 +719,7 @@ TEST_F(ClassLinkerTest, FindClass) { EXPECT_EQ(0U, JavaLangObject->NumStaticFields()); EXPECT_EQ(0U, kh.NumDirectInterfaces()); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("MyClass"))); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(LoadDex("MyClass"))); AssertNonExistentClass("LMyClass;"); Class* MyClass = class_linker_->FindClass("LMyClass;", class_loader.get()); kh.ChangeClass(MyClass); @@ -785,27 +786,27 @@ TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) { TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<LongArray> long_array(LongArray::Alloc(0)); + SirtRef<LongArray> long_array(soa.Self(), LongArray::Alloc(0)); EXPECT_EQ(class_linker_->FindSystemClass("[J"), long_array->GetClass()); uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData()); EXPECT_TRUE(IsAligned<8>(data_offset)); // Longs require 8 byte alignment - SirtRef<DoubleArray> double_array(DoubleArray::Alloc(0)); + SirtRef<DoubleArray> double_array(soa.Self(), DoubleArray::Alloc(0)); EXPECT_EQ(class_linker_->FindSystemClass("[D"), double_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(double_array->GetData()); EXPECT_TRUE(IsAligned<8>(data_offset)); // Doubles require 8 byte alignment - SirtRef<IntArray> int_array(IntArray::Alloc(0)); + SirtRef<IntArray> int_array(soa.Self(), IntArray::Alloc(0)); EXPECT_EQ(class_linker_->FindSystemClass("[I"), int_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(int_array->GetData()); EXPECT_TRUE(IsAligned<4>(data_offset)); // Ints require 4 byte alignment - SirtRef<CharArray> char_array(CharArray::Alloc(0)); + SirtRef<CharArray> char_array(soa.Self(), CharArray::Alloc(0)); EXPECT_EQ(class_linker_->FindSystemClass("[C"), char_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(char_array->GetData()); EXPECT_TRUE(IsAligned<2>(data_offset)); // Chars require 2 byte alignment - SirtRef<ShortArray> short_array(ShortArray::Alloc(0)); + SirtRef<ShortArray> short_array(soa.Self(), ShortArray::Alloc(0)); EXPECT_EQ(class_linker_->FindSystemClass("[S"), short_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(short_array->GetData()); EXPECT_TRUE(IsAligned<2>(data_offset)); // Shorts require 2 byte alignment @@ -846,8 +847,8 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) { TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<ClassLoader> class_loader_1(soa.Decode<ClassLoader*>(LoadDex("MyClass"))); - SirtRef<ClassLoader> class_loader_2(soa.Decode<ClassLoader*>(LoadDex("MyClass"))); + SirtRef<ClassLoader> class_loader_1(soa.Self(), soa.Decode<ClassLoader*>(LoadDex("MyClass"))); + SirtRef<ClassLoader> class_loader_2(soa.Self(), soa.Decode<ClassLoader*>(LoadDex("MyClass"))); Class* MyClass_1 = class_linker_->FindClass("LMyClass;", class_loader_1.get()); Class* MyClass_2 = class_linker_->FindClass("LMyClass;", class_loader_2.get()); EXPECT_TRUE(MyClass_1 != NULL); @@ -857,7 +858,7 @@ TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) { TEST_F(ClassLinkerTest, StaticFields) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("Statics"))); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(LoadDex("Statics"))); Class* statics = class_linker_->FindClass("LStatics;", class_loader.get()); class_linker_->EnsureInitialized(statics, true, true); @@ -939,7 +940,7 @@ TEST_F(ClassLinkerTest, StaticFields) { TEST_F(ClassLinkerTest, Interfaces) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("Interfaces"))); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(LoadDex("Interfaces"))); Class* I = class_linker_->FindClass("LInterfaces$I;", class_loader.get()); Class* J = class_linker_->FindClass("LInterfaces$J;", class_loader.get()); Class* K = class_linker_->FindClass("LInterfaces$K;", class_loader.get()); @@ -999,7 +1000,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("StaticsFromCode"); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(jclass_loader)); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader)); const DexFile* dex_file = Runtime::Current()->GetCompileTimeClassPath(jclass_loader)[0]; CHECK(dex_file != NULL); diff --git a/src/compiler.cc b/src/compiler.cc index edadc12..10b4939 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -1271,8 +1271,9 @@ static void InitializeClassWithoutClinit(const CompilationContext* context, ClassLoader* class_loader = soa.Decode<ClassLoader*>(context->GetClassLoader()); const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def); Class* klass = context->GetClassLinker()->FindClass(descriptor, class_loader); + Thread* self = Thread::Current(); if (klass != NULL) { - ObjectLock lock(klass); + ObjectLock lock(self, klass); if (klass->IsVerified()) { // Only try to initialize classes that were successfully verified. bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1; @@ -1295,8 +1296,8 @@ static void InitializeClassWithoutClinit(const CompilationContext* context, DCHECK_EQ(status, compiled_class->GetStatus()); } } - // clear any class not found or verification exceptions - Thread::Current()->ClearException(); + // Clear any class not found or verification exceptions. + self->ClearException(); } void Compiler::InitializeClassesWithoutClinit(jobject jni_class_loader, const DexFile& dex_file, diff --git a/src/debugger.cc b/src/debugger.cc index ee52984..e28845f 100644 --- a/src/debugger.cc +++ b/src/debugger.cc @@ -31,6 +31,7 @@ #include "ScopedLocalRef.h" #include "ScopedPrimitiveArray.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "space.h" #include "stack_indirect_reference_table.h" #include "thread_list.h" @@ -2464,7 +2465,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) { // We can be called while an exception is pending. We need // to preserve that across the method invocation. - SirtRef<Throwable> old_exception(soa.Self()->GetException()); + SirtRef<Throwable> old_exception(soa.Self(), soa.Self()->GetException()); soa.Self()->ClearException(); // Translate the method through the vtable, unless the debugger wants to suppress it. @@ -2677,7 +2678,7 @@ void Dbg::DdmSendThreadNotification(Thread* t, uint32_t type) { } else { CHECK(type == CHUNK_TYPE("THCR") || type == CHUNK_TYPE("THNM")) << type; ScopedObjectAccessUnchecked soa(Thread::Current()); - SirtRef<String> name(t->GetThreadName(soa)); + SirtRef<String> name(soa.Self(), t->GetThreadName(soa)); size_t char_count = (name.get() != NULL) ? name->GetLength() : 0; const jchar* chars = name->GetCharArray()->GetData(); diff --git a/src/dex2oat.cc b/src/dex2oat.cc index 05ff0c0..28960b9 100644 --- a/src/dex2oat.cc +++ b/src/dex2oat.cc @@ -35,6 +35,7 @@ #include "runtime.h" #include "ScopedLocalRef.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "stl_util.h" #include "stringpiece.h" #include "timing_logger.h" @@ -148,6 +149,7 @@ class Dex2Oat { // Load all the classes specified in the file ClassLinker* class_linker = runtime_->GetClassLinker(); + Thread* self = Thread::Current(); while (image_classes_file->good()) { std::string dot; std::getline(*image_classes_file.get(), dot); @@ -155,7 +157,7 @@ class Dex2Oat { continue; } std::string descriptor(DotToDescriptor(dot.c_str())); - SirtRef<Class> klass(class_linker->FindSystemClass(descriptor.c_str())); + SirtRef<Class> klass(self, class_linker->FindSystemClass(descriptor.c_str())); if (klass.get() == NULL) { LOG(WARNING) << "Failed to find class " << descriptor; Thread::Current()->ClearException(); @@ -167,7 +169,8 @@ class Dex2Oat { // exceptions are resolved by the verifier when there is a catch block in an interested method. // Do this here so that exception classes appear to have been specified image classes. std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types; - SirtRef<Class> java_lang_Throwable(class_linker->FindSystemClass("Ljava/lang/Throwable;")); + SirtRef<Class> java_lang_Throwable(self, + class_linker->FindSystemClass("Ljava/lang/Throwable;")); do { unresolved_exception_types.clear(); class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor, @@ -180,8 +183,8 @@ class Dex2Oat { const DexFile* dex_file = it->second; DexCache* dex_cache = class_linker->FindDexCache(*dex_file); ClassLoader* class_loader = NULL; - SirtRef<Class> klass(class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, - class_loader)); + SirtRef<Class> klass(self, class_linker->ResolveType(*dex_file, exception_type_idx, + dex_cache, class_loader)); if (klass.get() == NULL) { const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx); const char* descriptor = dex_file->GetTypeDescriptor(type_id); diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc index da02125..6c0107c 100644 --- a/src/dex_cache_test.cc +++ b/src/dex_cache_test.cc @@ -19,6 +19,7 @@ #include "dex_cache.h" #include "heap.h" #include "object.h" +#include "sirt_ref.h" #include <stdio.h> @@ -28,7 +29,7 @@ class DexCacheTest : public CommonTest {}; TEST_F(DexCacheTest, Open) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<DexCache> dex_cache(class_linker_->AllocDexCache(*java_lang_dex_file_)); + SirtRef<DexCache> dex_cache(soa.Self(), class_linker_->AllocDexCache(*java_lang_dex_file_)); ASSERT_TRUE(dex_cache.get() != NULL); EXPECT_EQ(java_lang_dex_file_->NumStringIds(), dex_cache->NumStrings()); diff --git a/src/exception_test.cc b/src/exception_test.cc index b82f8f7..c35572d 100644 --- a/src/exception_test.cc +++ b/src/exception_test.cc @@ -20,6 +20,7 @@ #include "gtest/gtest.h" #include "runtime.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "thread.h" #include "UniquePtr.h" @@ -31,7 +32,8 @@ class ExceptionTest : public CommonTest { CommonTest::SetUp(); ScopedObjectAccess soa(Thread::Current()); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("ExceptionHandle"))); + SirtRef<ClassLoader> class_loader(soa.Self(), + soa.Decode<ClassLoader*>(LoadDex("ExceptionHandle"))); my_klass_ = class_linker_->FindClass("LExceptionHandle;", class_loader.get()); ASSERT_TRUE(my_klass_ != NULL); class_linker_->EnsureInitialized(my_klass_, false, true); diff --git a/src/heap.cc b/src/heap.cc index 703549f..5c6a606 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -34,6 +34,7 @@ #include "os.h" #include "ScopedLocalRef.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "space.h" #include "stl_util.h" #include "thread_list.h" @@ -420,8 +421,9 @@ Object* Heap::AllocObject(Class* c, size_t byte_count) { concurrent_start_bytes_ = std::numeric_limits<size_t>::max(); bytes_since_last_gc_ = 0; // The SirtRef is necessary since the calls in RequestConcurrentGC are a safepoint. - SirtRef<Object> ref(obj); - RequestConcurrentGC(); + Thread* self = Thread::Current(); + SirtRef<Object> ref(self, obj); + RequestConcurrentGC(self); } VerifyObject(obj); @@ -1923,14 +1925,13 @@ void Heap::EnqueueClearedReferences(Object** cleared) { } } -void Heap::RequestConcurrentGC() { +void Heap::RequestConcurrentGC(Thread* self) { // Make sure that we can do a concurrent GC. Runtime* runtime = Runtime::Current(); if (requesting_gc_ || runtime == NULL || !runtime->IsFinishedStarting() || !runtime->IsConcurrentGcEnabled()) { return; } - Thread* self = Thread::Current(); { MutexLock mu(self, *Locks::runtime_shutdown_lock_); if (runtime->IsShuttingDown()) { @@ -301,7 +301,7 @@ class LOCKABLE Heap { void EnqueueClearedReferences(Object** cleared_references); void RequestHeapTrim(); - void RequestConcurrentGC(); + void RequestConcurrentGC(Thread* self); // Swap bitmaps (if we are a full Gc then we swap the zygote bitmap too). void SwapBitmaps(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_); diff --git a/src/heap_test.cc b/src/heap_test.cc index d846db5..881a765 100644 --- a/src/heap_test.cc +++ b/src/heap_test.cc @@ -15,6 +15,7 @@ */ #include "common_test.h" +#include "sirt_ref.h" namespace art { @@ -38,7 +39,7 @@ TEST_F(HeapTest, GarbageCollectClassLinkerInit) { Class* c = class_linker_->FindSystemClass("[Ljava/lang/Object;"); for (size_t i = 0; i < 1024; ++i) { - SirtRef<ObjectArray<Object> > array(ObjectArray<Object>::Alloc(c, 2048)); + SirtRef<ObjectArray<Object> > array(soa.Self(), ObjectArray<Object>::Alloc(c, 2048)); for (size_t j = 0; j < 2048; ++j) { array->Set(j, String::AllocFromModifiedUtf8("hello, world!")); } diff --git a/src/image_writer.cc b/src/image_writer.cc index e883599..33d37c7 100644 --- a/src/image_writer.cc +++ b/src/image_writer.cc @@ -36,6 +36,7 @@ #include "object_utils.h" #include "runtime.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "space.h" #include "UniquePtr.h" #include "utils.h" @@ -320,7 +321,7 @@ void ImageWriter::CalculateNewObjectOffsetsCallback(Object* obj, void* arg) { DCHECK_EQ(obj, obj->AsString()->Intern()); return; } - SirtRef<String> interned(obj->AsString()->Intern()); + SirtRef<String> interned(Thread::Current(), obj->AsString()->Intern()); if (obj != interned.get()) { if (!image_writer->IsImageOffsetAssigned(interned.get())) { // interned obj is after us, allocate its location early @@ -351,8 +352,9 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const { } // build an Object[] of the roots needed to restore the runtime - SirtRef<ObjectArray<Object> > image_roots( - ObjectArray<Object>::Alloc(object_array_class, ImageHeader::kImageRootsMax)); + SirtRef<ObjectArray<Object> > + image_roots(Thread::Current(), + ObjectArray<Object>::Alloc(object_array_class, ImageHeader::kImageRootsMax)); image_roots->Set(ImageHeader::kJniStubArray, runtime->GetJniDlsymLookupStub()); image_roots->Set(ImageHeader::kAbstractMethodErrorStubArray, runtime->GetAbstractMethodErrorStubArray()); @@ -380,7 +382,8 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const { } void ImageWriter::CalculateNewObjectOffsets() { - SirtRef<ObjectArray<Object> > image_roots(CreateImageRoots()); + Thread* self = Thread::Current(); + SirtRef<ObjectArray<Object> > image_roots(self, CreateImageRoots()); Heap* heap = Runtime::Current()->GetHeap(); const Spaces& spaces = heap->GetSpaces(); @@ -392,20 +395,20 @@ void ImageWriter::CalculateNewObjectOffsets() { image_end_ += RoundUp(sizeof(ImageHeader), 8); // 64-bit-alignment { - ReaderMutexLock mu(*Locks::heap_bitmap_lock_); + ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_); heap->FlushAllocStack(); } { // TODO: Image spaces only? // TODO: Add InOrderWalk to heap bitmap. - const char* old = Thread::Current()->StartAssertNoThreadSuspension("ImageWriter"); + const char* old = self->StartAssertNoThreadSuspension("ImageWriter"); DCHECK(heap->GetLargeObjectsSpace()->GetLiveObjects()->IsEmpty()); for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) { (*it)->GetLiveBitmap()->InOrderWalk(CalculateNewObjectOffsetsCallback, this); DCHECK_LT(image_end_, image_->Size()); } - Thread::Current()->EndAssertNoThreadSuspension(old); + self->EndAssertNoThreadSuspension(old); } // Note that image_top_ is left at end of used space diff --git a/src/intern_table_test.cc b/src/intern_table_test.cc index 15fa259..2833f6e 100644 --- a/src/intern_table_test.cc +++ b/src/intern_table_test.cc @@ -18,6 +18,7 @@ #include "common_test.h" #include "object.h" +#include "sirt_ref.h" namespace art { @@ -26,10 +27,10 @@ class InternTableTest : public CommonTest {}; TEST_F(InternTableTest, Intern) { ScopedObjectAccess soa(Thread::Current()); InternTable intern_table; - SirtRef<String> foo_1(intern_table.InternStrong(3, "foo")); - SirtRef<String> foo_2(intern_table.InternStrong(3, "foo")); - SirtRef<String> foo_3(String::AllocFromModifiedUtf8("foo")); - SirtRef<String> bar(intern_table.InternStrong(3, "bar")); + SirtRef<String> foo_1(soa.Self(), intern_table.InternStrong(3, "foo")); + SirtRef<String> foo_2(soa.Self(), intern_table.InternStrong(3, "foo")); + SirtRef<String> foo_3(soa.Self(), String::AllocFromModifiedUtf8("foo")); + SirtRef<String> bar(soa.Self(), intern_table.InternStrong(3, "bar")); EXPECT_TRUE(foo_1->Equals("foo")); EXPECT_TRUE(foo_2->Equals("foo")); EXPECT_TRUE(foo_3->Equals("foo")); @@ -46,7 +47,7 @@ TEST_F(InternTableTest, Size) { InternTable t; EXPECT_EQ(0U, t.Size()); t.InternStrong(3, "foo"); - SirtRef<String> foo(String::AllocFromModifiedUtf8("foo")); + SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8("foo")); t.InternWeak(foo.get()); EXPECT_EQ(1U, t.Size()); t.InternStrong(3, "bar"); @@ -90,10 +91,10 @@ TEST_F(InternTableTest, SweepInternTableWeaks) { InternTable t; t.InternStrong(3, "foo"); t.InternStrong(3, "bar"); - SirtRef<String> hello(String::AllocFromModifiedUtf8("hello")); - SirtRef<String> world(String::AllocFromModifiedUtf8("world")); - SirtRef<String> s0(t.InternWeak(hello.get())); - SirtRef<String> s1(t.InternWeak(world.get())); + SirtRef<String> hello(soa.Self(), String::AllocFromModifiedUtf8("hello")); + SirtRef<String> world(soa.Self(), String::AllocFromModifiedUtf8("world")); + SirtRef<String> s0(soa.Self(), t.InternWeak(hello.get())); + SirtRef<String> s1(soa.Self(), t.InternWeak(world.get())); EXPECT_EQ(4U, t.Size()); @@ -102,14 +103,14 @@ TEST_F(InternTableTest, SweepInternTableWeaks) { p.Expect(s0.get()); p.Expect(s1.get()); { - ReaderMutexLock mu(*Locks::heap_bitmap_lock_); + ReaderMutexLock mu(soa.Self(), *Locks::heap_bitmap_lock_); t.SweepInternTableWeaks(IsMarked, &p); } EXPECT_EQ(2U, t.Size()); // Just check that we didn't corrupt the map. - SirtRef<String> still_here(String::AllocFromModifiedUtf8("still here")); + SirtRef<String> still_here(soa.Self(), String::AllocFromModifiedUtf8("still here")); t.InternWeak(still_here.get()); EXPECT_EQ(3U, t.Size()); } @@ -119,9 +120,9 @@ TEST_F(InternTableTest, ContainsWeak) { { // Strongs are never weak. InternTable t; - SirtRef<String> interned_foo_1(t.InternStrong(3, "foo")); + SirtRef<String> interned_foo_1(soa.Self(), t.InternStrong(3, "foo")); EXPECT_FALSE(t.ContainsWeak(interned_foo_1.get())); - SirtRef<String> interned_foo_2(t.InternStrong(3, "foo")); + SirtRef<String> interned_foo_2(soa.Self(), t.InternStrong(3, "foo")); EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get())); EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get()); } @@ -129,11 +130,11 @@ TEST_F(InternTableTest, ContainsWeak) { { // Weaks are always weak. InternTable t; - SirtRef<String> foo_1(String::AllocFromModifiedUtf8("foo")); - SirtRef<String> foo_2(String::AllocFromModifiedUtf8("foo")); + SirtRef<String> foo_1(soa.Self(), String::AllocFromModifiedUtf8("foo")); + SirtRef<String> foo_2(soa.Self(), String::AllocFromModifiedUtf8("foo")); EXPECT_NE(foo_1.get(), foo_2.get()); - SirtRef<String> interned_foo_1(t.InternWeak(foo_1.get())); - SirtRef<String> interned_foo_2(t.InternWeak(foo_2.get())); + SirtRef<String> interned_foo_1(soa.Self(), t.InternWeak(foo_1.get())); + SirtRef<String> interned_foo_2(soa.Self(), t.InternWeak(foo_2.get())); EXPECT_TRUE(t.ContainsWeak(interned_foo_2.get())); EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get()); } @@ -141,10 +142,10 @@ TEST_F(InternTableTest, ContainsWeak) { { // A weak can be promoted to a strong. InternTable t; - SirtRef<String> foo(String::AllocFromModifiedUtf8("foo")); - SirtRef<String> interned_foo_1(t.InternWeak(foo.get())); + SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8("foo")); + SirtRef<String> interned_foo_1(soa.Self(), t.InternWeak(foo.get())); EXPECT_TRUE(t.ContainsWeak(interned_foo_1.get())); - SirtRef<String> interned_foo_2(t.InternStrong(3, "foo")); + SirtRef<String> interned_foo_2(soa.Self(), t.InternStrong(3, "foo")); EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get())); EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get()); } @@ -152,10 +153,10 @@ TEST_F(InternTableTest, ContainsWeak) { { // Interning a weak after a strong gets you the strong. InternTable t; - SirtRef<String> interned_foo_1(t.InternStrong(3, "foo")); + SirtRef<String> interned_foo_1(soa.Self(), t.InternStrong(3, "foo")); EXPECT_FALSE(t.ContainsWeak(interned_foo_1.get())); - SirtRef<String> foo(String::AllocFromModifiedUtf8("foo")); - SirtRef<String> interned_foo_2(t.InternWeak(foo.get())); + SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8("foo")); + SirtRef<String> interned_foo_2(soa.Self(), t.InternWeak(foo.get())); EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get())); EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get()); } diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc index 469a26c..bc1be28 100644 --- a/src/jni_internal_test.cc +++ b/src/jni_internal_test.cc @@ -20,6 +20,7 @@ #include "common_test.h" #include "ScopedLocalRef.h" +#include "sirt_ref.h" namespace art { @@ -73,7 +74,10 @@ class JniInternalTest : public CommonTest { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods"; jobject jclass_loader(LoadDex(class_name)); - SirtRef<ClassLoader> class_loader(ScopedObjectAccessUnchecked(Thread::Current()).Decode<ClassLoader*>(jclass_loader)); + Thread* self = Thread::Current(); + SirtRef<ClassLoader> + class_loader(self, + ScopedObjectAccessUnchecked(self).Decode<ClassLoader*>(jclass_loader)); if (is_static) { CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature); } else { @@ -1382,7 +1386,7 @@ TEST_F(JniInternalTest, DeleteWeakGlobalRef) { TEST_F(JniInternalTest, StaticMainMethod) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("Main"); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(jclass_loader)); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader)); CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V"); Class* klass = class_linker_->FindClass("LMain;", class_loader.get()); diff --git a/src/native/java_lang_reflect_Array.cc b/src/native/java_lang_reflect_Array.cc index 49a4694..d3a57bf 100644 --- a/src/native/java_lang_reflect_Array.cc +++ b/src/native/java_lang_reflect_Array.cc @@ -19,17 +19,19 @@ #include "object.h" #include "object_utils.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" namespace art { // Recursively create an array with multiple dimensions. Elements may be // Objects or primitive types. -static Array* CreateMultiArray(Class* array_class, int current_dimension, IntArray* dimensions) +static Array* CreateMultiArray(Thread* self, Class* array_class, int current_dimension, + IntArray* dimensions) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { int32_t array_length = dimensions->Get(current_dimension++); - SirtRef<Array> new_array(Array::Alloc(array_class, array_length)); + SirtRef<Array> new_array(self, Array::Alloc(array_class, array_length)); if (new_array.get() == NULL) { - CHECK(Thread::Current()->IsExceptionPending()); + CHECK(self->IsExceptionPending()); return NULL; } if (current_dimension == dimensions->GetLength()) { @@ -46,16 +48,17 @@ static Array* CreateMultiArray(Class* array_class, int current_dimension, IntArr Class* sub_array_class = class_linker->FindClass(sub_array_descriptor.c_str(), array_class->GetClassLoader()); if (sub_array_class == NULL) { - CHECK(Thread::Current()->IsExceptionPending()); + CHECK(self->IsExceptionPending()); return NULL; } DCHECK(sub_array_class->IsArrayClass()); // Create a new sub-array in every element of the array. - SirtRef<ObjectArray<Array> > object_array(new_array->AsObjectArray<Array>()); + SirtRef<ObjectArray<Array> > object_array(self, new_array->AsObjectArray<Array>()); for (int32_t i = 0; i < array_length; i++) { - SirtRef<Array> sub_array(CreateMultiArray(sub_array_class, current_dimension, dimensions)); + SirtRef<Array> sub_array(self, CreateMultiArray(self, sub_array_class, current_dimension, + dimensions)); if (sub_array.get() == NULL) { - CHECK(Thread::Current()->IsExceptionPending()); + CHECK(self->IsExceptionPending()); return NULL; } object_array->Set(i, sub_array.get()); @@ -105,13 +108,13 @@ static jobject Array_createMultiArray(JNIEnv* env, jclass, jclass javaElementCla ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Class* array_class = class_linker->FindClass(descriptor.c_str(), element_class->GetClassLoader()); if (array_class == NULL) { - CHECK(Thread::Current()->IsExceptionPending()); + CHECK(soa.Self()->IsExceptionPending()); return NULL; } // create the array - Array* new_array = CreateMultiArray(array_class, 0, dimensions_array); + Array* new_array = CreateMultiArray(soa.Self(), array_class, 0, dimensions_array); if (new_array == NULL) { - CHECK(Thread::Current()->IsExceptionPending()); + CHECK(soa.Self()->IsExceptionPending()); return NULL; } return soa.AddLocalReference<jobject>(new_array); diff --git a/src/oat/runtime/arm/stub_arm.cc b/src/oat/runtime/arm/stub_arm.cc index dca6d02..7add255 100644 --- a/src/oat/runtime/arm/stub_arm.cc +++ b/src/oat/runtime/arm/stub_arm.cc @@ -20,6 +20,7 @@ #include "oat/runtime/stub.h" #include "object.h" #include "stack_indirect_reference_table.h" +#include "sirt_ref.h" #define __ assembler-> @@ -81,7 +82,7 @@ ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type) { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> resolution_trampoline(ByteArray::Alloc(cs)); + SirtRef<ByteArray> resolution_trampoline(Thread::Current(), ByteArray::Alloc(cs)); CHECK(resolution_trampoline.get() != NULL); MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength()); assembler->FinalizeInstructions(code); @@ -127,7 +128,7 @@ ByteArray* CreateAbstractMethodErrorStub() { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> abstract_stub(ByteArray::Alloc(cs)); + SirtRef<ByteArray> abstract_stub(Thread::Current(), ByteArray::Alloc(cs)); CHECK(abstract_stub.get() != NULL); MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength()); assembler->FinalizeInstructions(code); @@ -155,7 +156,7 @@ ByteArray* CreateJniDlsymLookupStub() { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> jni_stub(ByteArray::Alloc(cs)); + SirtRef<ByteArray> jni_stub(Thread::Current(), ByteArray::Alloc(cs)); CHECK(jni_stub.get() != NULL); MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength()); assembler->FinalizeInstructions(code); diff --git a/src/oat/runtime/mips/stub_mips.cc b/src/oat/runtime/mips/stub_mips.cc index 7b4c85e..d545e4a 100644 --- a/src/oat/runtime/mips/stub_mips.cc +++ b/src/oat/runtime/mips/stub_mips.cc @@ -20,6 +20,7 @@ #include "oat/utils/mips/assembler_mips.h" #include "object.h" #include "stack_indirect_reference_table.h" +#include "sirt_ref.h" #define __ assembler-> @@ -111,7 +112,7 @@ ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> resolution_trampoline(ByteArray::Alloc(cs)); + SirtRef<ByteArray> resolution_trampoline(Thread::Current(), ByteArray::Alloc(cs)); CHECK(resolution_trampoline.get() != NULL); MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength()); assembler->FinalizeInstructions(code); @@ -156,7 +157,7 @@ ByteArray* CreateAbstractMethodErrorStub() { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> abstract_stub(ByteArray::Alloc(cs)); + SirtRef<ByteArray> abstract_stub(Thread::Current(), ByteArray::Alloc(cs)); CHECK(abstract_stub.get() != NULL); MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength()); assembler->FinalizeInstructions(code); @@ -196,7 +197,7 @@ ByteArray* CreateJniDlsymLookupStub() { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> jni_stub(ByteArray::Alloc(cs)); + SirtRef<ByteArray> jni_stub(Thread::Current(), ByteArray::Alloc(cs)); CHECK(jni_stub.get() != NULL); MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength()); assembler->FinalizeInstructions(code); diff --git a/src/oat/runtime/x86/stub_x86.cc b/src/oat/runtime/x86/stub_x86.cc index 97b686f..7941d15 100644 --- a/src/oat/runtime/x86/stub_x86.cc +++ b/src/oat/runtime/x86/stub_x86.cc @@ -20,6 +20,7 @@ #include "oat/utils/x86/assembler_x86.h" #include "object.h" #include "stack_indirect_reference_table.h" +#include "sirt_ref.h" #define __ assembler-> @@ -91,7 +92,7 @@ ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type) { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> resolution_trampoline(ByteArray::Alloc(cs)); + SirtRef<ByteArray> resolution_trampoline(Thread::Current(), ByteArray::Alloc(cs)); CHECK(resolution_trampoline.get() != NULL); MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength()); assembler->FinalizeInstructions(code); @@ -145,7 +146,7 @@ ByteArray* CreateAbstractMethodErrorStub() { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> abstract_stub(ByteArray::Alloc(cs)); + SirtRef<ByteArray> abstract_stub(Thread::Current(),ByteArray::Alloc(cs)); CHECK(abstract_stub.get() != NULL); MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength()); assembler->FinalizeInstructions(code); @@ -178,7 +179,7 @@ ByteArray* CreateJniDlsymLookupStub() { assembler->EmitSlowPaths(); size_t cs = assembler->CodeSize(); - SirtRef<ByteArray> jni_stub(ByteArray::Alloc(cs)); + SirtRef<ByteArray> jni_stub(Thread::Current(), ByteArray::Alloc(cs)); CHECK(jni_stub.get() != NULL); MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength()); assembler->FinalizeInstructions(code); diff --git a/src/object.cc b/src/object.cc index 0cf2aa8..8582a21 100644 --- a/src/object.cc +++ b/src/object.cc @@ -35,6 +35,7 @@ #include "object_utils.h" #include "runtime.h" #include "runtime_support.h" +#include "sirt_ref.h" #include "stack.h" #include "utils.h" #include "well_known_classes.h" @@ -54,7 +55,7 @@ Object* Object::Clone() { // Using c->AllocObject() here would be wrong. size_t num_bytes = SizeOf(); Heap* heap = Runtime::Current()->GetHeap(); - SirtRef<Object> copy(heap->AllocObject(c, num_bytes)); + SirtRef<Object> copy(Thread::Current(), heap->AllocObject(c, num_bytes)); if (copy.get() == NULL) { return NULL; } @@ -696,7 +697,7 @@ void Class::SetStatus(Status new_status) { // stash current exception Thread* self = Thread::Current(); - SirtRef<Throwable> exception(self->GetException()); + SirtRef<Throwable> exception(self, self->GetException()); CHECK(exception.get() != NULL); // clear exception to call FindSystemClass @@ -1447,7 +1448,7 @@ String* String::AllocFromModifiedUtf8(int32_t utf16_length, } String* String::Alloc(Class* java_lang_String, int32_t utf16_length) { - SirtRef<CharArray> array(CharArray::Alloc(utf16_length)); + SirtRef<CharArray> array(Thread::Current(), CharArray::Alloc(utf16_length)); if (array.get() == NULL) { return NULL; } @@ -1455,7 +1456,8 @@ String* String::Alloc(Class* java_lang_String, int32_t utf16_length) { } String* String::Alloc(Class* java_lang_String, CharArray* array) { - SirtRef<CharArray> array_ref(array); // hold reference in case AllocObject causes GC + // Hold reference in case AllocObject causes GC. + SirtRef<CharArray> array_ref(Thread::Current(), array); String* string = down_cast<String*>(java_lang_String->AllocObject()); if (string == NULL) { return NULL; diff --git a/src/object_test.cc b/src/object_test.cc index 3dfa0a9..f28c20b 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -19,13 +19,14 @@ #include <stdint.h> #include <stdio.h> -#include "UniquePtr.h" +#include "asm_support.h" #include "class_linker.h" #include "common_test.h" #include "dex_file.h" #include "heap.h" #include "runtime_support.h" -#include "asm_support.h" +#include "sirt_ref.h" +#include "UniquePtr.h" namespace art { @@ -43,7 +44,7 @@ class ObjectTest : public CommonTest { utf16_expected[i] = ch; } - SirtRef<String> string(String::AllocFromModifiedUtf8(length, utf8_in)); + SirtRef<String> string(Thread::Current(), String::AllocFromModifiedUtf8(length, utf8_in)); ASSERT_EQ(length, string->GetLength()); ASSERT_TRUE(string->GetCharArray() != NULL); ASSERT_TRUE(string->GetCharArray()->GetData() != NULL); @@ -76,7 +77,7 @@ TEST_F(ObjectTest, IsInSamePackage) { TEST_F(ObjectTest, Clone) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<ObjectArray<Object> > a1(class_linker_->AllocObjectArray<Object>(256)); + SirtRef<ObjectArray<Object> > a1(soa.Self(), class_linker_->AllocObjectArray<Object>(256)); size_t s1 = a1->SizeOf(); Object* clone = a1->Clone(); EXPECT_EQ(s1, clone->SizeOf()); @@ -85,7 +86,7 @@ TEST_F(ObjectTest, Clone) { TEST_F(ObjectTest, AllocObjectArray) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<ObjectArray<Object> > oa(class_linker_->AllocObjectArray<Object>(2)); + SirtRef<ObjectArray<Object> > oa(soa.Self(), class_linker_->AllocObjectArray<Object>(2)); EXPECT_EQ(2, oa->GetLength()); EXPECT_TRUE(oa->Get(0) == NULL); EXPECT_TRUE(oa->Get(1) == NULL); @@ -96,18 +97,17 @@ TEST_F(ObjectTest, AllocObjectArray) { EXPECT_TRUE(oa->Get(0) == oa.get()); EXPECT_TRUE(oa->Get(1) == oa.get()); - Thread* self = Thread::Current(); Class* aioobe = class_linker_->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;"); EXPECT_TRUE(oa->Get(-1) == NULL); - EXPECT_TRUE(self->IsExceptionPending()); - EXPECT_EQ(aioobe, self->GetException()->GetClass()); - self->ClearException(); + EXPECT_TRUE(soa.Self()->IsExceptionPending()); + EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass()); + soa.Self()->ClearException(); EXPECT_TRUE(oa->Get(2) == NULL); - EXPECT_TRUE(self->IsExceptionPending()); - EXPECT_EQ(aioobe, self->GetException()->GetClass()); - self->ClearException(); + EXPECT_TRUE(soa.Self()->IsExceptionPending()); + EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass()); + soa.Self()->ClearException(); ASSERT_TRUE(oa->GetClass() != NULL); ClassHelper oa_ch(oa->GetClass()); @@ -119,7 +119,7 @@ TEST_F(ObjectTest, AllocObjectArray) { TEST_F(ObjectTest, AllocArray) { ScopedObjectAccess soa(Thread::Current()); Class* c = class_linker_->FindSystemClass("[I"); - SirtRef<Array> a(Array::Alloc(c, 1)); + SirtRef<Array> a(soa.Self(), Array::Alloc(c, 1)); ASSERT_TRUE(c == a->GetClass()); c = class_linker_->FindSystemClass("[Ljava/lang/Object;"); @@ -147,18 +147,17 @@ void TestPrimitiveArray(ClassLinker* cl) { EXPECT_EQ(T(123), a->Get(0)); EXPECT_EQ(T(321), a->Get(1)); - Thread* self = Thread::Current(); Class* aioobe = cl->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;"); EXPECT_EQ(0, a->Get(-1)); - EXPECT_TRUE(self->IsExceptionPending()); - EXPECT_EQ(aioobe, self->GetException()->GetClass()); - self->ClearException(); + EXPECT_TRUE(soa.Self()->IsExceptionPending()); + EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass()); + soa.Self()->ClearException(); EXPECT_EQ(0, a->Get(2)); - EXPECT_TRUE(self->IsExceptionPending()); - EXPECT_EQ(aioobe, self->GetException()->GetClass()); - self->ClearException(); + EXPECT_TRUE(soa.Self()->IsExceptionPending()); + EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass()); + soa.Self()->ClearException(); } TEST_F(ObjectTest, PrimitiveArray_Boolean_Alloc) { @@ -239,7 +238,7 @@ TEST_F(ObjectTest, StaticFieldFromCode) { Object* s0 = field->GetObj(NULL); EXPECT_EQ(NULL, s0); - SirtRef<CharArray> char_array(CharArray::Alloc(0)); + SirtRef<CharArray> char_array(soa.Self(), CharArray::Alloc(0)); field->SetObj(NULL, char_array.get()); EXPECT_EQ(char_array.get(), field->GetObj(NULL)); @@ -275,7 +274,7 @@ TEST_F(ObjectTest, String) { TEST_F(ObjectTest, StringEqualsUtf8) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<String> string(String::AllocFromModifiedUtf8("android")); + SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8("android")); EXPECT_TRUE(string->Equals("android")); EXPECT_FALSE(string->Equals("Android")); EXPECT_FALSE(string->Equals("ANDROID")); @@ -283,15 +282,15 @@ TEST_F(ObjectTest, StringEqualsUtf8) { EXPECT_FALSE(string->Equals("and")); EXPECT_FALSE(string->Equals("androids")); - SirtRef<String> empty(String::AllocFromModifiedUtf8("")); + SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8("")); EXPECT_TRUE(empty->Equals("")); EXPECT_FALSE(empty->Equals("a")); } TEST_F(ObjectTest, StringEquals) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<String> string(String::AllocFromModifiedUtf8("android")); - SirtRef<String> string_2(String::AllocFromModifiedUtf8("android")); + SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8("android")); + SirtRef<String> string_2(soa.Self(), String::AllocFromModifiedUtf8("android")); EXPECT_TRUE(string->Equals(string_2.get())); EXPECT_FALSE(string->Equals("Android")); EXPECT_FALSE(string->Equals("ANDROID")); @@ -299,14 +298,14 @@ TEST_F(ObjectTest, StringEquals) { EXPECT_FALSE(string->Equals("and")); EXPECT_FALSE(string->Equals("androids")); - SirtRef<String> empty(String::AllocFromModifiedUtf8("")); + SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8("")); EXPECT_TRUE(empty->Equals("")); EXPECT_FALSE(empty->Equals("a")); } TEST_F(ObjectTest, StringLength) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<String> string(String::AllocFromModifiedUtf8("android")); + SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8("android")); EXPECT_EQ(string->GetLength(), 7); EXPECT_EQ(string->GetUtfLength(), 7); @@ -323,8 +322,8 @@ TEST_F(ObjectTest, DescriptorCompare) { jobject jclass_loader_1 = LoadDex("ProtoCompare"); jobject jclass_loader_2 = LoadDex("ProtoCompare2"); - SirtRef<ClassLoader> class_loader_1(soa.Decode<ClassLoader*>(jclass_loader_1)); - SirtRef<ClassLoader> class_loader_2(soa.Decode<ClassLoader*>(jclass_loader_2)); + SirtRef<ClassLoader> class_loader_1(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader_1)); + SirtRef<ClassLoader> class_loader_2(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader_2)); Class* klass1 = linker->FindClass("LProtoCompare;", class_loader_1.get()); ASSERT_TRUE(klass1 != NULL); @@ -381,9 +380,9 @@ TEST_F(ObjectTest, DescriptorCompare) { TEST_F(ObjectTest, StringHashCode) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<String> empty(String::AllocFromModifiedUtf8("")); - SirtRef<String> A(String::AllocFromModifiedUtf8("A")); - SirtRef<String> ABC(String::AllocFromModifiedUtf8("ABC")); + SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8("")); + SirtRef<String> A(soa.Self(), String::AllocFromModifiedUtf8("A")); + SirtRef<String> ABC(soa.Self(), String::AllocFromModifiedUtf8("ABC")); EXPECT_EQ(0, empty->GetHashCode()); EXPECT_EQ(65, A->GetHashCode()); @@ -393,15 +392,15 @@ TEST_F(ObjectTest, StringHashCode) { TEST_F(ObjectTest, InstanceOf) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(jclass_loader)); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader)); Class* X = class_linker_->FindClass("LX;", class_loader.get()); Class* Y = class_linker_->FindClass("LY;", class_loader.get()); ASSERT_TRUE(X != NULL); ASSERT_TRUE(Y != NULL); - SirtRef<Object> x(X->AllocObject()); - SirtRef<Object> y(Y->AllocObject()); + SirtRef<Object> x(soa.Self(), X->AllocObject()); + SirtRef<Object> y(soa.Self(), Y->AllocObject()); ASSERT_TRUE(x.get() != NULL); ASSERT_TRUE(y.get() != NULL); @@ -427,7 +426,7 @@ TEST_F(ObjectTest, InstanceOf) { TEST_F(ObjectTest, IsAssignableFrom) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(jclass_loader)); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader)); Class* X = class_linker_->FindClass("LX;", class_loader.get()); Class* Y = class_linker_->FindClass("LY;", class_loader.get()); @@ -464,7 +463,7 @@ TEST_F(ObjectTest, IsAssignableFrom) { TEST_F(ObjectTest, IsAssignableFromArray) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); - SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(jclass_loader)); + SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader)); Class* X = class_linker_->FindClass("LX;", class_loader.get()); Class* Y = class_linker_->FindClass("LY;", class_loader.get()); ASSERT_TRUE(X != NULL); @@ -516,7 +515,7 @@ TEST_F(ObjectTest, IsAssignableFromArray) { TEST_F(ObjectTest, FindInstanceField) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<String> s(String::AllocFromModifiedUtf8("ABC")); + SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8("ABC")); ASSERT_TRUE(s.get() != NULL); Class* c = s->GetClass(); ASSERT_TRUE(c != NULL); @@ -549,7 +548,7 @@ TEST_F(ObjectTest, FindInstanceField) { TEST_F(ObjectTest, FindStaticField) { ScopedObjectAccess soa(Thread::Current()); - SirtRef<String> s(String::AllocFromModifiedUtf8("ABC")); + SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8("ABC")); ASSERT_TRUE(s.get() != NULL); Class* c = s->GetClass(); ASSERT_TRUE(c != NULL); diff --git a/src/object_utils.h b/src/object_utils.h index 035f689..1d66c8f 100644 --- a/src/object_utils.h +++ b/src/object_utils.h @@ -32,8 +32,8 @@ namespace art { class ObjectLock { public: - explicit ObjectLock(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : self_(Thread::Current()), obj_(object) { + explicit ObjectLock(Thread* self, Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) + : self_(self), obj_(object) { CHECK(object != NULL); obj_->MonitorEnter(self_); } diff --git a/src/runtime.cc b/src/runtime.cc index 61d93f8..d10c351 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -40,6 +40,7 @@ #include "scoped_thread_state_change.h" #include "signal_catcher.h" #include "signal_set.h" +#include "sirt_ref.h" #include "space.h" #include "thread.h" #include "thread_list.h" @@ -983,7 +984,8 @@ void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, Trampolin AbstractMethod* Runtime::CreateResolutionMethod() { Class* method_class = AbstractMethod::GetMethodClass(); - SirtRef<AbstractMethod> method(down_cast<AbstractMethod*>(method_class->AllocObject())); + SirtRef<AbstractMethod> method(Thread::Current(), + down_cast<AbstractMethod*>(method_class->AllocObject())); method->SetDeclaringClass(method_class); // TODO: use a special method for resolution method saves method->SetDexMethodIndex(DexFile::kDexNoIndex16); @@ -993,9 +995,11 @@ AbstractMethod* Runtime::CreateResolutionMethod() { return method.get(); } -AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type) { +AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, + CalleeSaveType type) { Class* method_class = AbstractMethod::GetMethodClass(); - SirtRef<AbstractMethod> method(down_cast<AbstractMethod*>(method_class->AllocObject())); + SirtRef<AbstractMethod> + method(Thread::Current(), down_cast<AbstractMethod*>(method_class->AllocObject())); method->SetDeclaringClass(method_class); // TODO: use a special method for callee saves method->SetDexMethodIndex(DexFile::kDexNoIndex16); diff --git a/src/sirt_ref.h b/src/sirt_ref.h new file mode 100644 index 0000000..ea0b9a3 --- /dev/null +++ b/src/sirt_ref.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_SIRT_REF_H_ +#define ART_SRC_SIRT_REF_H_ + +#include "logging.h" +#include "macros.h" +#include "thread.h" + +namespace art { + +template<class T> +class SirtRef { + public: + SirtRef(Thread* self, T* object) : self_(self), sirt_(object) { + self_->PushSirt(&sirt_); + } + ~SirtRef() { + CHECK(self_->PopSirt() == &sirt_); + } + + T& operator*() const { return *get(); } + T* operator->() const { return get(); } + T* get() const { + return down_cast<T*>(sirt_.GetReference(0)); + } + + void reset(T* object = NULL) { + sirt_.SetReference(0, object); + } + + private: + Thread* const self_; + StackIndirectReferenceTable sirt_; + + DISALLOW_COPY_AND_ASSIGN(SirtRef); +}; + +} // namespace art + +#endif // ART_SRC_SIRT_REF_H_ diff --git a/src/stack_indirect_reference_table.h b/src/stack_indirect_reference_table.h index 681405f..506f00a 100644 --- a/src/stack_indirect_reference_table.h +++ b/src/stack_indirect_reference_table.h @@ -17,30 +17,24 @@ #ifndef ART_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_ #define ART_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_ -#include "casts.h" #include "logging.h" #include "macros.h" -#include "thread.h" namespace art { class Object; +class Thread; // Stack allocated indirect reference table. It can allocated within // the bridge frame between managed and native code backed by stack // storage or manually allocated by SirtRef to hold one reference. class StackIndirectReferenceTable { public: - explicit StackIndirectReferenceTable(Object* object) { - number_of_references_ = 1; + explicit StackIndirectReferenceTable(Object* object) : number_of_references_(1), link_(NULL) { references_[0] = object; - Thread::Current()->PushSirt(this); } - ~StackIndirectReferenceTable() { - StackIndirectReferenceTable* sirt = Thread::Current()->PopSirt(); - CHECK_EQ(this, sirt); - } + ~StackIndirectReferenceTable() {} // Number of references contained within this SIRT size_t NumberOfReferences() const { @@ -98,28 +92,6 @@ class StackIndirectReferenceTable { DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable); }; -template<class T> -class SirtRef { - public: - explicit SirtRef(T* object) : sirt_(object) {} - ~SirtRef() {} - - T& operator*() const { return *get(); } - T* operator->() const { return get(); } - T* get() const { - return down_cast<T*>(sirt_.GetReference(0)); - } - - void reset(T* object = NULL) { - sirt_.SetReference(0, object); - } - - private: - StackIndirectReferenceTable sirt_; - - DISALLOW_COPY_AND_ASSIGN(SirtRef); -}; - } // namespace art #endif // ART_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_ diff --git a/src/thread.cc b/src/thread.cc index bd58e6a..15a4f1b 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -46,6 +46,7 @@ #include "runtime_support.h" #include "scoped_thread_state_change.h" #include "ScopedLocalRef.h" +#include "sirt_ref.h" #include "space.h" #include "stack.h" #include "stack_indirect_reference_table.h" @@ -119,7 +120,7 @@ void* Thread::CreateCallback(void* arg) { { ScopedObjectAccess soa(self); { - SirtRef<String> thread_name(self->GetThreadName(soa)); + SirtRef<String> thread_name(self, self->GetThreadName(soa)); self->SetThreadName(thread_name->ToModifiedUtf8().c_str()); } Dbg::PostThreadStart(self); @@ -378,7 +379,7 @@ void Thread::CreatePeer(const char* name, bool as_daemon, jobject thread_group) reinterpret_cast<jint>(self)); ScopedObjectAccess soa(self); - SirtRef<String> peer_thread_name(GetThreadName(soa)); + SirtRef<String> peer_thread_name(soa.Self(), GetThreadName(soa)); if (peer_thread_name.get() == NULL) { Object* native_peer = soa.Decode<Object*>(peer.get()); // The Thread constructor should have set the Thread.name to a @@ -1240,17 +1241,18 @@ class CountStackDepthVisitor : public StackVisitor { class BuildInternalStackTraceVisitor : public StackVisitor { public: - explicit BuildInternalStackTraceVisitor(const ManagedStack* stack, + explicit BuildInternalStackTraceVisitor(Thread* self, const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack, int skip_depth) - : StackVisitor(stack, trace_stack, NULL), + : StackVisitor(stack, trace_stack, NULL), self_(self), skip_depth_(skip_depth), count_(0), dex_pc_trace_(NULL), method_trace_(NULL) {} - bool Init(int depth, const ScopedObjectAccess& soa) + bool Init(int depth) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Allocate method trace with an extra slot that will hold the PC trace SirtRef<ObjectArray<Object> > - method_trace(Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(depth + 1)); + method_trace(self_, + Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(depth + 1)); if (method_trace.get() == NULL) { return false; } @@ -1263,7 +1265,7 @@ class BuildInternalStackTraceVisitor : public StackVisitor { method_trace->Set(depth, dex_pc_trace); // Set the Object*s and assert that no thread suspension is now possible. const char* last_no_suspend_cause = - soa.Self()->StartAssertNoThreadSuspension("Building internal stack trace"); + self_->StartAssertNoThreadSuspension("Building internal stack trace"); CHECK(last_no_suspend_cause == NULL) << last_no_suspend_cause; method_trace_ = method_trace.get(); dex_pc_trace_ = dex_pc_trace; @@ -1272,7 +1274,7 @@ class BuildInternalStackTraceVisitor : public StackVisitor { virtual ~BuildInternalStackTraceVisitor() { if (method_trace_ != NULL) { - Thread::Current()->EndAssertNoThreadSuspension(NULL); + self_->EndAssertNoThreadSuspension(NULL); } } @@ -1299,6 +1301,7 @@ class BuildInternalStackTraceVisitor : public StackVisitor { } private: + Thread* const self_; // How many more frames to skip. int32_t skip_depth_; // Current position down stack trace. @@ -1309,18 +1312,6 @@ class BuildInternalStackTraceVisitor : public StackVisitor { ObjectArray<Object>* method_trace_; }; -void Thread::PushSirt(StackIndirectReferenceTable* sirt) { - sirt->SetLink(top_sirt_); - top_sirt_ = sirt; -} - -StackIndirectReferenceTable* Thread::PopSirt() { - CHECK(top_sirt_ != NULL); - StackIndirectReferenceTable* sirt = top_sirt_; - top_sirt_ = top_sirt_->GetLink(); - return sirt; -} - jobject Thread::CreateInternalStackTrace(const ScopedObjectAccess& soa) const { // Compute depth of stack CountStackDepthVisitor count_visitor(GetManagedStack(), GetTraceStack()); @@ -1328,11 +1319,11 @@ jobject Thread::CreateInternalStackTrace(const ScopedObjectAccess& soa) const { int32_t depth = count_visitor.GetDepth(); int32_t skip_depth = count_visitor.GetSkipDepth(); - // Build internal stack trace - BuildInternalStackTraceVisitor build_trace_visitor(GetManagedStack(), GetTraceStack(), + // Build internal stack trace. + BuildInternalStackTraceVisitor build_trace_visitor(soa.Self(), GetManagedStack(), GetTraceStack(), skip_depth); - if (!build_trace_visitor.Init(depth, soa)) { - return NULL; // Allocation failed + if (!build_trace_visitor.Init(depth)) { + return NULL; // Allocation failed. } build_trace_visitor.WalkStack(); return soa.AddLocalReference<jobjectArray>(build_trace_visitor.GetInternalStackTrace()); @@ -1382,18 +1373,19 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray(JNIEnv* env, job const char* descriptor = mh.GetDeclaringClassDescriptor(); CHECK(descriptor != NULL); std::string class_name(PrettyDescriptor(descriptor)); - SirtRef<String> class_name_object(String::AllocFromModifiedUtf8(class_name.c_str())); + SirtRef<String> class_name_object(soa.Self(), + String::AllocFromModifiedUtf8(class_name.c_str())); if (class_name_object.get() == NULL) { return NULL; } const char* method_name = mh.GetName(); CHECK(method_name != NULL); - SirtRef<String> method_name_object(String::AllocFromModifiedUtf8(method_name)); + SirtRef<String> method_name_object(soa.Self(), String::AllocFromModifiedUtf8(method_name)); if (method_name_object.get() == NULL) { return NULL; } const char* source_file = mh.GetDeclaringClassSourceFile(); - SirtRef<String> source_name_object(String::AllocFromModifiedUtf8(source_file)); + SirtRef<String> source_name_object(soa.Self(), String::AllocFromModifiedUtf8(source_file)); StackTraceElement* obj = StackTraceElement::Alloc(class_name_object.get(), method_name_object.get(), source_name_object.get(), diff --git a/src/thread.h b/src/thread.h index 1e80a80..06798cd 100644 --- a/src/thread.h +++ b/src/thread.h @@ -32,6 +32,7 @@ #include "offsets.h" #include "runtime_stats.h" #include "stack.h" +#include "stack_indirect_reference_table.h" #include "trace.h" #include "UniquePtr.h" #ifdef ART_USE_GREENLAND_COMPILER @@ -518,8 +519,17 @@ class PACKED Thread { void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg); - void PushSirt(StackIndirectReferenceTable* sirt); - StackIndirectReferenceTable* PopSirt(); + void PushSirt(StackIndirectReferenceTable* sirt) { + sirt->SetLink(top_sirt_); + top_sirt_ = sirt; + } + + StackIndirectReferenceTable* PopSirt() { + StackIndirectReferenceTable* sirt = top_sirt_; + DCHECK(sirt != NULL); + top_sirt_ = top_sirt_->GetLink(); + return sirt; + } static ThreadOffset TopSirtOffset() { return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_)); diff --git a/src/utils_test.cc b/src/utils_test.cc index 0b27fc5..1fcb4b3 100644 --- a/src/utils_test.cc +++ b/src/utils_test.cc @@ -17,6 +17,7 @@ #include "object.h" #include "common_test.h" #include "scoped_thread_state_change.h" +#include "sirt_ref.h" #include "utils.h" namespace art { @@ -88,10 +89,10 @@ TEST_F(UtilsTest, PrettyTypeOf) { ScopedObjectAccess soa(Thread::Current()); EXPECT_EQ("null", PrettyTypeOf(NULL)); - SirtRef<String> s(String::AllocFromModifiedUtf8("")); + SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8("")); EXPECT_EQ("java.lang.String", PrettyTypeOf(s.get())); - SirtRef<ShortArray> a(ShortArray::Alloc(2)); + SirtRef<ShortArray> a(soa.Self(), ShortArray::Alloc(2)); EXPECT_EQ("short[]", PrettyTypeOf(a.get())); Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;"); |