summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2012-10-03 21:09:42 -0700
committerIan Rogers <irogers@google.com>2012-10-04 09:27:04 -0700
commit1f5393447b9f45be7918042d9ee7b521376de866 (patch)
tree1793cb0ae00b38a63f8cfd3a25b6cb0ee4edca16
parent870ea4772199f8d4cbd9a269f9093620ee50a59c (diff)
downloadart-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.cc147
-rw-r--r--src/class_linker.h4
-rw-r--r--src/class_linker_test.cc25
-rw-r--r--src/compiler.cc7
-rw-r--r--src/debugger.cc5
-rw-r--r--src/dex2oat.cc11
-rw-r--r--src/dex_cache_test.cc3
-rw-r--r--src/exception_test.cc4
-rw-r--r--src/heap.cc9
-rw-r--r--src/heap.h2
-rw-r--r--src/heap_test.cc3
-rw-r--r--src/image_writer.cc17
-rw-r--r--src/intern_table_test.cc47
-rw-r--r--src/jni_internal_test.cc8
-rw-r--r--src/native/java_lang_reflect_Array.cc23
-rw-r--r--src/oat/runtime/arm/stub_arm.cc7
-rw-r--r--src/oat/runtime/mips/stub_mips.cc7
-rw-r--r--src/oat/runtime/x86/stub_x86.cc7
-rw-r--r--src/object.cc10
-rw-r--r--src/object_test.cc77
-rw-r--r--src/object_utils.h4
-rw-r--r--src/runtime.cc10
-rw-r--r--src/sirt_ref.h55
-rw-r--r--src/stack_indirect_reference_table.h34
-rw-r--r--src/thread.cc46
-rw-r--r--src/thread.h14
-rw-r--r--src/utils_test.cc5
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()) {
diff --git a/src/heap.h b/src/heap.h
index 0a054e2..76206c4 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -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;");