Explicitly pass Thread::Current to MutexLock and Alloc.
Change-Id: I8b75bc0617915465f102815b32306aa7760dcae4
diff --git a/src/atomic.cc b/src/atomic.cc
index 2638b21..008aa87 100644
--- a/src/atomic.cc
+++ b/src/atomic.cc
@@ -22,6 +22,7 @@
#include "mutex.h"
#include "stl_util.h"
#include "stringprintf.h"
+#include "thread.h"
#if defined(__APPLE__)
#include <libkern/OSAtomic.h>
@@ -172,7 +173,7 @@
}
int64_t QuasiAtomic::Swap64(int64_t value, volatile int64_t* addr) {
- MutexLock mu(GetSwapLock(addr));
+ MutexLock mu(Thread::Current(), GetSwapLock(addr));
int64_t old_value = *addr;
*addr = value;
return old_value;
@@ -184,7 +185,7 @@
}
int QuasiAtomic::Cas64(int64_t old_value, int64_t new_value, volatile int64_t* addr) {
- MutexLock mu(GetSwapLock(addr));
+ MutexLock mu(Thread::Current(), GetSwapLock(addr));
if (*addr == old_value) {
*addr = new_value;
return 0;
@@ -193,7 +194,7 @@
}
int64_t QuasiAtomic::Read64(volatile const int64_t* addr) {
- MutexLock mu(GetSwapLock(addr));
+ MutexLock mu(Thread::Current(), GetSwapLock(addr));
return *addr;
}
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 448ad6a..9ce641f 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -235,47 +235,48 @@
// java_lang_Class comes first, it's needed for AllocClass
Thread* self = Thread::Current();
Heap* heap = Runtime::Current()->GetHeap();
- SirtRef<Class> java_lang_Class(self, down_cast<Class*>(heap->AllocObject(NULL, sizeof(ClassClass))));
+ SirtRef<Class>
+ java_lang_Class(self, down_cast<Class*>(heap->AllocObject(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> class_array_class(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> java_lang_Object(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> object_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
object_array_class->SetComponentType(java_lang_Object.get());
// Object[][] needed for iftables.
- SirtRef<Class> object_array_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> object_array_array_class(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> char_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
// Setup the char[] class to be used for String.
- SirtRef<Class> char_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> char_array_class(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(StringClass)));
+ SirtRef<Class> java_lang_String(self, AllocClass(self, java_lang_Class.get(), sizeof(StringClass)));
String::SetClass(java_lang_String.get());
java_lang_String->SetObjectSize(sizeof(String));
java_lang_String->SetStatus(Class::kStatusResolved);
// Create storage for root classes, save away our work so far (requires descriptors).
- class_roots_ = ObjectArray<Class>::Alloc(object_array_class.get(), kClassRootsMax);
+ class_roots_ = ObjectArray<Class>::Alloc(self, object_array_class.get(), kClassRootsMax);
CHECK(class_roots_ != NULL);
SetClassRoot(kJavaLangClass, java_lang_Class.get());
SetClassRoot(kJavaLangObject, java_lang_Object.get());
@@ -286,20 +287,20 @@
SetClassRoot(kJavaLangString, java_lang_String.get());
// Setup the primitive type classes.
- SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(Primitive::kPrimBoolean));
- SetClassRoot(kPrimitiveByte, CreatePrimitiveClass(Primitive::kPrimByte));
- SetClassRoot(kPrimitiveShort, CreatePrimitiveClass(Primitive::kPrimShort));
- SetClassRoot(kPrimitiveInt, CreatePrimitiveClass(Primitive::kPrimInt));
- SetClassRoot(kPrimitiveLong, CreatePrimitiveClass(Primitive::kPrimLong));
- SetClassRoot(kPrimitiveFloat, CreatePrimitiveClass(Primitive::kPrimFloat));
- SetClassRoot(kPrimitiveDouble, CreatePrimitiveClass(Primitive::kPrimDouble));
- SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass(Primitive::kPrimVoid));
+ SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
+ SetClassRoot(kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
+ SetClassRoot(kPrimitiveShort, CreatePrimitiveClass(self, Primitive::kPrimShort));
+ SetClassRoot(kPrimitiveInt, CreatePrimitiveClass(self, Primitive::kPrimInt));
+ SetClassRoot(kPrimitiveLong, CreatePrimitiveClass(self, Primitive::kPrimLong));
+ SetClassRoot(kPrimitiveFloat, CreatePrimitiveClass(self, Primitive::kPrimFloat));
+ SetClassRoot(kPrimitiveDouble, CreatePrimitiveClass(self, Primitive::kPrimDouble));
+ SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass(self, Primitive::kPrimVoid));
// Create array interface entries to populate once we can load system classes.
- array_iftable_ = AllocIfTable(2);
+ array_iftable_ = AllocIfTable(self, 2);
// Create int array type for AllocDexCache (done in AppendToBootClassPath).
- SirtRef<Class> int_array_class(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> int_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
IntArray::SetArrayClass(int_array_class.get());
SetClassRoot(kIntArrayClass, int_array_class.get());
@@ -307,34 +308,37 @@
// 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(self, AllocClass(java_lang_Class.get(), sizeof(DexCacheClass)));
+ SirtRef<Class>
+ java_lang_DexCache(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(),
- sizeof(MethodClass)));
+ SirtRef<Class> java_lang_reflect_Constructor(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(FieldClass)));
+ SirtRef<Class> java_lang_reflect_Field(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(MethodClass)));
+ SirtRef<Class> java_lang_reflect_Method(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(),
- sizeof(MethodClass)));
+ SirtRef<Class> java_lang_reflect_AbstractMethod(self, AllocClass(self, java_lang_Class.get(),
+ sizeof(MethodClass)));
CHECK(java_lang_reflect_AbstractMethod.get() != NULL);
java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod));
SetClassRoot(kJavaLangReflectAbstractMethod, java_lang_reflect_AbstractMethod.get());
@@ -342,15 +346,15 @@
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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> object_array_string(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> object_array_field(self, AllocClass(self, 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(self, AllocClass(java_lang_Class.get(), sizeof(Class)));
+ SirtRef<Class> object_array_abstract_method(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get());
SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get());
@@ -426,8 +430,8 @@
CHECK(java_io_Serializable != NULL);
// We assume that Cloneable/Serializable don't have superinterfaces -- normally we'd have to
// crawl up and explicitly list all of the supers as well.
- array_iftable_->Set(0, AllocInterfaceEntry(java_lang_Cloneable));
- array_iftable_->Set(1, AllocInterfaceEntry(java_io_Serializable));
+ array_iftable_->Set(0, AllocInterfaceEntry(self, java_lang_Cloneable));
+ array_iftable_->Set(1, AllocInterfaceEntry(self, java_io_Serializable));
// Sanity check Class[] and Object[]'s interfaces.
ClassHelper kh(class_array_class.get(), this);
@@ -667,17 +671,17 @@
}
void ClassLinker::RegisterOatFile(const OatFile& oat_file) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
RegisterOatFileLocked(oat_file);
}
void ClassLinker::RegisterOatFileLocked(const OatFile& oat_file) {
- dex_lock_.AssertHeld();
+ dex_lock_.AssertHeld(Thread::Current());
oat_files_.push_back(&oat_file);
}
OatFile* ClassLinker::OpenOat(const ImageSpace* space) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
const Runtime* runtime = Runtime::Current();
const ImageHeader& image_header = space->GetImageHeader();
// Grab location but don't use Object::AsString as we haven't yet initialized the roots to
@@ -708,7 +712,7 @@
}
const OatFile* ClassLinker::FindOpenedOatFileForDexFile(const DexFile& dex_file) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
return FindOpenedOatFileFromDexLocation(dex_file.GetLocation());
}
@@ -750,7 +754,7 @@
const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& dex_location,
const std::string& oat_location) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
return FindOrCreateOatFileForDexLocationLocked(dex_location, oat_location);
}
@@ -855,7 +859,7 @@
}
const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location);
if (open_oat_file != NULL) {
@@ -922,7 +926,7 @@
}
const OatFile* ClassLinker::FindOatFileFromOatLocation(const std::string& oat_location) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
return FindOatFileFromOatLocationLocked(oat_location);
}
@@ -980,7 +984,7 @@
// reinit clases_ table
{
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
heap->FlushAllocStack();
heap->GetLiveBitmap()->Walk(InitFromImageCallback, this);
}
@@ -1037,16 +1041,16 @@
// mapped image.
void ClassLinker::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
visitor(class_roots_, arg);
-
+ Thread* self = Thread::Current();
{
- MutexLock mu(dex_lock_);
+ MutexLock mu(self, dex_lock_);
for (size_t i = 0; i < dex_caches_.size(); i++) {
visitor(dex_caches_[i], arg);
}
}
{
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(self, *Locks::classlinker_classes_lock_);
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
visitor(it->second, arg);
@@ -1060,7 +1064,7 @@
}
void ClassLinker::VisitClasses(ClassVisitor* visitor, void* arg) const {
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
if (!visitor(it->second, arg)) {
@@ -1110,13 +1114,12 @@
STLDeleteElements(&oat_files_);
}
-DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) {
+DexCache* ClassLinker::AllocDexCache(Thread* self, 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())));
+ SirtRef<DexCache> dex_cache(self,
+ down_cast<DexCache*>(heap->AllocObject(self, dex_cache_class,
+ dex_cache_class->GetObjectSize())));
if (dex_cache.get() == NULL) {
return NULL;
}
@@ -1124,24 +1127,26 @@
if (location.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<String> > strings(self, AllocStringArray(dex_file.NumStringIds()));
+ SirtRef<ObjectArray<String> > strings(self, AllocStringArray(self, dex_file.NumStringIds()));
if (strings.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<Class> > types(self, AllocClassArray(dex_file.NumTypeIds()));
+ SirtRef<ObjectArray<Class> > types(self, AllocClassArray(self, dex_file.NumTypeIds()));
if (types.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<AbstractMethod> > methods(self, AllocMethodArray(dex_file.NumMethodIds()));
+ SirtRef<ObjectArray<AbstractMethod> >
+ methods(self, AllocMethodArray(self, dex_file.NumMethodIds()));
if (methods.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<Field> > fields(self, AllocFieldArray(dex_file.NumFieldIds()));
+ SirtRef<ObjectArray<Field> > fields(self, AllocFieldArray(self, dex_file.NumFieldIds()));
if (fields.get() == NULL) {
return NULL;
}
SirtRef<ObjectArray<StaticStorageBase> >
- initialized_static_storage(self, AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds()));
+ initialized_static_storage(self,
+ AllocObjectArray<StaticStorageBase>(self, dex_file.NumTypeIds()));
if (initialized_static_storage.get() == NULL) {
return NULL;
}
@@ -1156,52 +1161,51 @@
return dex_cache.get();
}
-InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) {
+InterfaceEntry* ClassLinker::AllocInterfaceEntry(Thread* self, Class* interface) {
DCHECK(interface->IsInterface());
- Thread* self = Thread::Current();
- SirtRef<ObjectArray<Object> > array(self, AllocObjectArray<Object>(InterfaceEntry::LengthAsArray()));
+ SirtRef<ObjectArray<Object> > array(self, AllocObjectArray<Object>(self, InterfaceEntry::LengthAsArray()));
SirtRef<InterfaceEntry> interface_entry(self, down_cast<InterfaceEntry*>(array.get()));
interface_entry->SetInterface(interface);
return interface_entry.get();
}
-Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
+Class* ClassLinker::AllocClass(Thread* self, Class* java_lang_Class, size_t class_size) {
DCHECK_GE(class_size, sizeof(Class));
Heap* heap = Runtime::Current()->GetHeap();
- SirtRef<Class> klass(Thread::Current(),
- heap->AllocObject(java_lang_Class, class_size)->AsClass());
+ SirtRef<Class> klass(self,
+ heap->AllocObject(self, java_lang_Class, class_size)->AsClass());
klass->SetPrimitiveType(Primitive::kPrimNot); // default to not being primitive
klass->SetClassSize(class_size);
return klass.get();
}
-Class* ClassLinker::AllocClass(size_t class_size) {
- return AllocClass(GetClassRoot(kJavaLangClass), class_size);
+Class* ClassLinker::AllocClass(Thread* self, size_t class_size) {
+ return AllocClass(self, GetClassRoot(kJavaLangClass), class_size);
}
-Field* ClassLinker::AllocField() {
- return down_cast<Field*>(GetClassRoot(kJavaLangReflectField)->AllocObject());
+Field* ClassLinker::AllocField(Thread* self) {
+ return down_cast<Field*>(GetClassRoot(kJavaLangReflectField)->AllocObject(self));
}
-Method* ClassLinker::AllocMethod() {
- return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject());
+Method* ClassLinker::AllocMethod(Thread* self) {
+ return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject(self));
}
-Constructor* ClassLinker::AllocConstructor() {
- return down_cast<Constructor*>(GetClassRoot(kJavaLangReflectConstructor)->AllocObject());
+Constructor* ClassLinker::AllocConstructor(Thread* self) {
+ return down_cast<Constructor*>(GetClassRoot(kJavaLangReflectConstructor)->AllocObject(self));
}
-ObjectArray<StackTraceElement>* ClassLinker::AllocStackTraceElementArray(size_t length) {
- return ObjectArray<StackTraceElement>::Alloc(
- GetClassRoot(kJavaLangStackTraceElementArrayClass),
- length);
+ObjectArray<StackTraceElement>* ClassLinker::AllocStackTraceElementArray(Thread* self,
+ size_t length) {
+ return ObjectArray<StackTraceElement>::Alloc(self,
+ GetClassRoot(kJavaLangStackTraceElementArrayClass),
+ length);
}
-static Class* EnsureResolved(Class* klass)
+static Class* EnsureResolved(Thread* self, Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(klass != NULL);
// Wait for the class if it has not already been linked.
- Thread* self = Thread::Current();
if (!klass->IsResolved() && !klass->IsErroneous()) {
ObjectLock lock(self, klass);
// Check for circular dependencies between classes.
@@ -1245,7 +1249,7 @@
// Find the class in the loaded classes table.
Class* klass = LookupClass(descriptor, class_loader);
if (klass != NULL) {
- return EnsureResolved(klass);
+ return EnsureResolved(self, klass);
}
// Class is not yet loaded.
if (descriptor[0] == '[') {
@@ -1341,10 +1345,10 @@
} else if (descriptor == "Ljava/lang/reflect/Method;") {
klass.reset(GetClassRoot(kJavaLangReflectMethod));
} else {
- klass.reset(AllocClass(SizeOfClass(dex_file, dex_class_def)));
+ klass.reset(AllocClass(self, SizeOfClass(dex_file, dex_class_def)));
}
} else {
- klass.reset(AllocClass(SizeOfClass(dex_file, dex_class_def)));
+ klass.reset(AllocClass(self, SizeOfClass(dex_file, dex_class_def)));
}
klass->SetDexCache(FindDexCache(dex_file));
LoadClass(dex_file, dex_class_def, klass, class_loader);
@@ -1359,7 +1363,7 @@
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());
+ return EnsureResolved(self, existing.get());
}
// Finish loading (if necessary) by finding parents
CHECK(!klass->IsLoaded());
@@ -1588,20 +1592,20 @@
return; // no fields or methods - for example a marker interface
}
ClassDataItemIterator it(dex_file, class_data);
+ Thread* self = Thread::Current();
if (it.NumStaticFields() != 0) {
- klass->SetSFields(AllocObjectArray<Field>(it.NumStaticFields()));
+ klass->SetSFields(AllocObjectArray<Field>(self, it.NumStaticFields()));
}
if (it.NumInstanceFields() != 0) {
- klass->SetIFields(AllocObjectArray<Field>(it.NumInstanceFields()));
+ klass->SetIFields(AllocObjectArray<Field>(self, it.NumInstanceFields()));
}
- Thread* self = Thread::Current();
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
- SirtRef<Field> sfield(self, AllocField());
+ SirtRef<Field> sfield(self, AllocField(self));
klass->SetStaticField(i, sfield.get());
LoadField(dex_file, it, klass, sfield);
}
for (size_t i = 0; it.HasNextInstanceField(); i++, it.Next()) {
- SirtRef<Field> ifield(self, AllocField());
+ SirtRef<Field> ifield(self, AllocField(self));
klass->SetInstanceField(i, ifield.get());
LoadField(dex_file, it, klass, ifield);
}
@@ -1614,15 +1618,15 @@
// Load methods.
if (it.NumDirectMethods() != 0) {
// TODO: append direct methods to class object
- klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(it.NumDirectMethods()));
+ klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(self, it.NumDirectMethods()));
}
if (it.NumVirtualMethods() != 0) {
// TODO: append direct methods to class object
- klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(it.NumVirtualMethods()));
+ klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(self, it.NumVirtualMethods()));
}
size_t class_def_method_index = 0;
for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
- SirtRef<AbstractMethod> method(self, LoadMethod(dex_file, it, klass));
+ SirtRef<AbstractMethod> method(self, LoadMethod(self, dex_file, it, klass));
klass->SetDirectMethod(i, method.get());
if (oat_class.get() != NULL) {
LinkCode(method, oat_class.get(), class_def_method_index);
@@ -1631,7 +1635,7 @@
class_def_method_index++;
}
for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) {
- SirtRef<AbstractMethod> method(self, LoadMethod(dex_file, it, klass));
+ SirtRef<AbstractMethod> method(self, LoadMethod(self, dex_file, it, klass));
klass->SetVirtualMethod(i, method.get());
DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i);
if (oat_class.get() != NULL) {
@@ -1650,21 +1654,22 @@
dst->SetAccessFlags(it.GetMemberAccessFlags());
}
-AbstractMethod* ClassLinker::LoadMethod(const DexFile& dex_file, const ClassDataItemIterator& it,
- SirtRef<Class>& klass) {
+AbstractMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file,
+ const ClassDataItemIterator& it,
+ SirtRef<Class>& klass) {
uint32_t dex_method_idx = it.GetMemberIndex();
const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
StringPiece method_name(dex_file.GetMethodName(method_id));
AbstractMethod* dst = NULL;
if (method_name == "<init>") {
- dst = AllocConstructor();
+ dst = AllocConstructor(self);
} else {
- dst = AllocMethod();
+ dst = AllocMethod(self);
}
DCHECK(dst->IsMethod()) << PrettyDescriptor(dst->GetClass());
- const char* old_cause = Thread::Current()->StartAssertNoThreadSuspension("LoadMethod");
+ const char* old_cause = self->StartAssertNoThreadSuspension("LoadMethod");
dst->SetDexMethodIndex(dex_method_idx);
dst->SetDeclaringClass(klass.get());
@@ -1708,12 +1713,13 @@
CHECK(dst->IsMethod());
- Thread::Current()->EndAssertNoThreadSuspension(old_cause);
+ self->EndAssertNoThreadSuspension(old_cause);
return dst;
}
void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
- SirtRef<DexCache> dex_cache(Thread::Current(), AllocDexCache(dex_file));
+ Thread* self = Thread::Current();
+ SirtRef<DexCache> dex_cache(self, AllocDexCache(self, dex_file));
AppendToBootClassPath(dex_file, dex_cache);
}
@@ -1724,7 +1730,7 @@
}
bool ClassLinker::IsDexFileRegisteredLocked(const DexFile& dex_file) const {
- dex_lock_.AssertHeld();
+ dex_lock_.AssertHeld(Thread::Current());
for (size_t i = 0; i != dex_caches_.size(); ++i) {
if (dex_caches_[i]->GetDexFile() == &dex_file) {
return true;
@@ -1734,12 +1740,12 @@
}
bool ClassLinker::IsDexFileRegistered(const DexFile& dex_file) const {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
return IsDexFileRegisteredLocked(dex_file);
}
void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<DexCache>& dex_cache) {
- dex_lock_.AssertHeld();
+ dex_lock_.AssertHeld(Thread::Current());
CHECK(dex_cache.get() != NULL) << dex_file.GetLocation();
CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation()));
dex_caches_.push_back(dex_cache.get());
@@ -1757,7 +1763,7 @@
// 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(self, AllocDexCache(dex_file));
+ SirtRef<DexCache> dex_cache(self, AllocDexCache(self, dex_file));
{
MutexLock mu(self, dex_lock_);
if (IsDexFileRegisteredLocked(dex_file)) {
@@ -1768,7 +1774,7 @@
}
void ClassLinker::RegisterDexFile(const DexFile& dex_file, SirtRef<DexCache>& dex_cache) {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
RegisterDexFileLocked(dex_file, dex_cache);
}
@@ -1783,7 +1789,7 @@
}
DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
for (size_t i = 0; i != dex_caches_.size(); ++i) {
DexCache* dex_cache = dex_caches_[i];
if (dex_cache->GetDexFile() == &dex_file) {
@@ -1795,7 +1801,7 @@
}
void ClassLinker::FixupDexCaches(AbstractMethod* resolution_method) const {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
for (size_t i = 0; i != dex_caches_.size(); ++i) {
dex_caches_[i]->Fixup(resolution_method);
}
@@ -1891,7 +1897,7 @@
}
}
if (new_class.get() == NULL) {
- new_class.reset(AllocClass(sizeof(Class)));
+ new_class.reset(AllocClass(self, sizeof(Class)));
if (new_class.get() == NULL) {
return NULL;
}
@@ -1986,7 +1992,7 @@
LOG(INFO) << "Loaded class " << descriptor << source;
}
size_t hash = StringPieceHash()(descriptor);
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
Table& classes = image_class ? image_classes_ : classes_;
Class* existing = LookupClassLocked(descriptor.data(), klass->GetClassLoader(), hash, classes);
#ifndef NDEBUG
@@ -2003,7 +2009,7 @@
bool ClassLinker::RemoveClass(const char* descriptor, const ClassLoader* class_loader) {
size_t hash = Hash(descriptor);
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
typedef Table::iterator It; // TODO: C++0x auto
// TODO: determine if its better to search classes_ or image_classes_ first
ClassHelper kh;
@@ -2028,7 +2034,7 @@
Class* ClassLinker::LookupClass(const char* descriptor, const ClassLoader* class_loader) {
size_t hash = Hash(descriptor);
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
// TODO: determine if its better to search classes_ or image_classes_ first
Class* klass = LookupClassLocked(descriptor, class_loader, hash, classes_);
if (klass != NULL) {
@@ -2063,7 +2069,7 @@
void ClassLinker::LookupClasses(const char* descriptor, std::vector<Class*>& classes) {
classes.clear();
size_t hash = Hash(descriptor);
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
typedef Table::const_iterator It; // TODO: C++0x auto
// TODO: determine if its better to search classes_ or image_classes_ first
ClassHelper kh(NULL, this);
@@ -2295,7 +2301,8 @@
ClassLoader* loader, ObjectArray<AbstractMethod>* methods,
ObjectArray<ObjectArray<Class> >* throws) {
Thread* self = Thread::Current();
- SirtRef<Class> klass(self, AllocClass(GetClassRoot(kJavaLangClass), sizeof(SynthesizedProxyClass)));
+ SirtRef<Class> klass(self, AllocClass(self, GetClassRoot(kJavaLangClass),
+ sizeof(SynthesizedProxyClass)));
CHECK(klass.get() != NULL);
DCHECK(klass->GetClass() != NULL);
klass->SetObjectSize(sizeof(Proxy));
@@ -2311,31 +2318,31 @@
klass->SetDexTypeIndex(DexFile::kDexNoIndex16);
// Instance fields are inherited, but we add a couple of static fields...
- klass->SetSFields(AllocObjectArray<Field>(2));
+ klass->SetSFields(AllocObjectArray<Field>(self, 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(self, AllocField());
+ SirtRef<Field> interfaces_sfield(self, AllocField(self));
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(self, AllocField());
+ SirtRef<Field> throws_sfield(self, AllocField(self));
klass->SetStaticField(1, throws_sfield.get());
throws_sfield->SetDexFieldIndex(1);
throws_sfield->SetDeclaringClass(klass.get());
throws_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
// Proxies have 1 direct method, the constructor
- klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(1));
- klass->SetDirectMethod(0, CreateProxyConstructor(klass, proxy_class));
+ klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(self, 1));
+ klass->SetDirectMethod(0, CreateProxyConstructor(self, klass, proxy_class));
// Create virtual method using specified prototypes
size_t num_virtual_methods = methods->GetLength();
- klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(num_virtual_methods));
+ klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(self, num_virtual_methods));
for (size_t i = 0; i < num_virtual_methods; ++i) {
SirtRef<AbstractMethod> prototype(self, methods->Get(i));
- klass->SetVirtualMethod(i, CreateProxyMethod(klass, prototype));
+ klass->SetVirtualMethod(i, CreateProxyMethod(self, klass, prototype));
}
klass->SetSuperClass(proxy_class); // The super class is java.lang.reflect.Proxy
@@ -2392,7 +2399,7 @@
DexCache* dex_cache = NULL;
{
ObjectArray<Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes();
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
for (size_t i = 0; i != dex_caches_.size(); ++i) {
if (dex_caches_[i]->GetResolvedTypes() == resolved_types) {
dex_cache = dex_caches_[i];
@@ -2408,14 +2415,14 @@
}
-AbstractMethod* ClassLinker::CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class) {
+AbstractMethod* ClassLinker::CreateProxyConstructor(Thread* self, SirtRef<Class>& klass, Class* proxy_class) {
// Create constructor for Proxy that must initialize h
ObjectArray<AbstractMethod>* proxy_direct_methods = proxy_class->GetDirectMethods();
CHECK_EQ(proxy_direct_methods->GetLength(), 15);
AbstractMethod* proxy_constructor = proxy_direct_methods->Get(2);
// Clone the existing constructor of Proxy (our constructor would just invoke it so steal its
// code_ too)
- AbstractMethod* constructor = down_cast<AbstractMethod*>(proxy_constructor->Clone());
+ AbstractMethod* constructor = down_cast<AbstractMethod*>(proxy_constructor->Clone(self));
// Make this constructor public and fix the class to be our Proxy version
constructor->SetAccessFlags((constructor->GetAccessFlags() & ~kAccProtected) | kAccPublic);
constructor->SetDeclaringClass(klass.get());
@@ -2431,14 +2438,15 @@
DCHECK(constructor->IsPublic());
}
-AbstractMethod* ClassLinker::CreateProxyMethod(SirtRef<Class>& klass, SirtRef<AbstractMethod>& prototype) {
+AbstractMethod* ClassLinker::CreateProxyMethod(Thread* self, SirtRef<Class>& klass,
+ SirtRef<AbstractMethod>& prototype) {
// Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden
// prototype method
prototype->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(),
prototype.get());
// We steal everything from the prototype (such as DexCache, invoke stub, etc.) then specialize
// as necessary
- AbstractMethod* method = down_cast<AbstractMethod*>(prototype->Clone());
+ AbstractMethod* method = down_cast<AbstractMethod*>(prototype->Clone(self));
// Set class to be the concrete proxy class and clear the abstract flag, modify exceptions to
// the intersection of throw exceptions as defined in Proxy
@@ -2980,7 +2988,7 @@
CHECK_LE(actual_count, max_count);
// TODO: do not assign to the vtable field until it is fully constructed.
SirtRef<ObjectArray<AbstractMethod> >
- vtable(self, klass->GetSuperClass()->GetVTable()->CopyOf(max_count));
+ vtable(self, klass->GetSuperClass()->GetVTable()->CopyOf(self, max_count));
// See if any of our virtual methods override the superclass.
MethodHelper local_mh(NULL, this);
MethodHelper super_mh(NULL, this);
@@ -3023,7 +3031,7 @@
// Shrink vtable if possible
CHECK_LE(actual_count, max_count);
if (actual_count < max_count) {
- vtable.reset(vtable->CopyOf(actual_count));
+ vtable.reset(vtable->CopyOf(self, actual_count));
}
klass->SetVTable(vtable.get());
} else {
@@ -3034,7 +3042,7 @@
return false;
}
SirtRef<ObjectArray<AbstractMethod> >
- vtable(self, AllocObjectArray<AbstractMethod>(num_virtual_methods));
+ vtable(self, AllocObjectArray<AbstractMethod>(self, num_virtual_methods));
for (size_t i = 0; i < num_virtual_methods; ++i) {
AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i);
vtable->Set(i, virtual_method);
@@ -3067,12 +3075,12 @@
return true;
}
Thread* self = Thread::Current();
- SirtRef<ObjectArray<InterfaceEntry> > iftable(self, AllocIfTable(ifcount));
+ SirtRef<ObjectArray<InterfaceEntry> > iftable(self, AllocIfTable(self, ifcount));
if (super_ifcount != 0) {
ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
for (size_t i = 0; i < super_ifcount; i++) {
Class* super_interface = super_iftable->Get(i)->GetInterface();
- iftable->Set(i, AllocInterfaceEntry(super_interface));
+ iftable->Set(i, AllocInterfaceEntry(self, super_interface));
}
}
// Flatten the interface inheritance hierarchy.
@@ -3099,7 +3107,7 @@
}
if (!duplicate) {
// Add this non-duplicate interface.
- iftable->Set(idx++, AllocInterfaceEntry(interface));
+ iftable->Set(idx++, AllocInterfaceEntry(self, interface));
// Add this interface's non-duplicate super-interfaces.
for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
Class* super_interface = interface->GetIfTable()->Get(j)->GetInterface();
@@ -3112,14 +3120,14 @@
}
}
if (!super_duplicate) {
- iftable->Set(idx++, AllocInterfaceEntry(super_interface));
+ iftable->Set(idx++, AllocInterfaceEntry(self, super_interface));
}
}
}
}
// Shrink iftable in case duplicates were found
if (idx < ifcount) {
- iftable.reset(iftable->CopyOf(idx));
+ iftable.reset(iftable->CopyOf(self, idx));
ifcount = idx;
} else {
CHECK_EQ(idx, ifcount);
@@ -3136,7 +3144,8 @@
for (size_t i = 0; i < ifcount; ++i) {
InterfaceEntry* interface_entry = iftable->Get(i);
Class* interface = interface_entry->GetInterface();
- ObjectArray<AbstractMethod>* method_array = AllocObjectArray<AbstractMethod>(interface->NumVirtualMethods());
+ ObjectArray<AbstractMethod>* method_array =
+ AllocObjectArray<AbstractMethod>(self, interface->NumVirtualMethods());
interface_entry->SetMethodArray(method_array);
ObjectArray<AbstractMethod>* vtable = klass->GetVTableDuringLinking();
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
@@ -3176,7 +3185,7 @@
}
if (miranda_method.get() == NULL) {
// point the interface table at a phantom slot
- miranda_method.reset(down_cast<AbstractMethod*>(interface_method->Clone()));
+ miranda_method.reset(down_cast<AbstractMethod*>(interface_method->Clone(self)));
miranda_list.push_back(miranda_method.get());
}
method_array->Set(j, miranda_method.get());
@@ -3187,14 +3196,14 @@
int old_method_count = klass->NumVirtualMethods();
int new_method_count = old_method_count + miranda_list.size();
klass->SetVirtualMethods((old_method_count == 0)
- ? AllocObjectArray<AbstractMethod>(new_method_count)
- : klass->GetVirtualMethods()->CopyOf(new_method_count));
+ ? AllocObjectArray<AbstractMethod>(self, new_method_count)
+ : klass->GetVirtualMethods()->CopyOf(self, new_method_count));
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();
- vtable.reset(vtable->CopyOf(new_vtable_count));
+ vtable.reset(vtable->CopyOf(self, new_vtable_count));
for (size_t i = 0; i < miranda_list.size(); ++i) {
AbstractMethod* method = miranda_list[i];
// Leave the declaring class alone as type indices are relative to it
@@ -3730,7 +3739,7 @@
// lock held, because it might need to resolve a field's type, which would try to take the lock.
std::vector<Class*> all_classes;
{
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
all_classes.push_back(it->second);
@@ -3746,13 +3755,13 @@
}
void ClassLinker::DumpForSigQuit(std::ostream& os) const {
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
os << "Loaded classes: " << image_classes_.size() << " image classes; "
<< classes_.size() << " allocated classes\n";
}
size_t ClassLinker::NumLoadedClasses() const {
- MutexLock mu(*Locks::classlinker_classes_lock_);
+ MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
return classes_.size() + image_classes_.size();
}
@@ -3776,7 +3785,7 @@
}
void ClassLinker::RelocateExecutable() {
- MutexLock mu(dex_lock_);
+ MutexLock mu(Thread::Current(), dex_lock_);
for (size_t i = 0; i < oat_files_.size(); ++i) {
const_cast<OatFile*>(oat_files_[i])->RelocateExecutable();
}
diff --git a/src/class_linker.h b/src/class_linker.h
index b07157a..38b402f 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -313,38 +313,38 @@
// TODO: replace this with multiple methods that allocate the correct managed type.
template <class T>
- ObjectArray<T>* AllocObjectArray(size_t length)
+ ObjectArray<T>* AllocObjectArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
+ return ObjectArray<T>::Alloc(self, GetClassRoot(kObjectArrayClass), length);
}
- ObjectArray<Class>* AllocClassArray(size_t length)
+ ObjectArray<Class>* AllocClassArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<Class>::Alloc(GetClassRoot(kClassArrayClass), length);
+ return ObjectArray<Class>::Alloc(self, GetClassRoot(kClassArrayClass), length);
}
- ObjectArray<String>* AllocStringArray(size_t length)
+ ObjectArray<String>* AllocStringArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<String>::Alloc(GetClassRoot(kJavaLangStringArrayClass), length);
+ return ObjectArray<String>::Alloc(self, GetClassRoot(kJavaLangStringArrayClass), length);
}
- ObjectArray<AbstractMethod>* AllocMethodArray(size_t length)
+ ObjectArray<AbstractMethod>* AllocMethodArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<AbstractMethod>::Alloc(
+ return ObjectArray<AbstractMethod>::Alloc(self,
GetClassRoot(kJavaLangReflectAbstractMethodArrayClass), length);
}
- ObjectArray<InterfaceEntry>* AllocIfTable(size_t length)
+ ObjectArray<InterfaceEntry>* AllocIfTable(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<InterfaceEntry>::Alloc(GetClassRoot(kObjectArrayArrayClass), length);
+ return ObjectArray<InterfaceEntry>::Alloc(self, GetClassRoot(kObjectArrayArrayClass), length);
}
- ObjectArray<Field>* AllocFieldArray(size_t length)
+ ObjectArray<Field>* AllocFieldArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<Field>::Alloc(GetClassRoot(kJavaLangReflectFieldArrayClass), length);
+ return ObjectArray<Field>::Alloc(self, GetClassRoot(kJavaLangReflectFieldArrayClass), length);
}
- ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length)
+ ObjectArray<StackTraceElement>* AllocStackTraceElementArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void VerifyClass(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -396,25 +396,25 @@
void FinishInit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// For early bootstrapping by Init
- Class* AllocClass(Class* java_lang_Class, size_t class_size)
+ Class* AllocClass(Thread* self, Class* java_lang_Class, size_t class_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Alloc* convenience functions to avoid needing to pass in Class*
// values that are known to the ClassLinker such as
// kObjectArrayClass and kJavaLangString etc.
- Class* AllocClass(size_t class_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- DexCache* AllocDexCache(const DexFile& dex_file)
+ Class* AllocClass(Thread* self, size_t class_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ DexCache* AllocDexCache(Thread* self, const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Field* AllocField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Method* AllocMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Constructor* AllocConstructor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Field* AllocField(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Method* AllocMethod(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Constructor* AllocConstructor(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- InterfaceEntry* AllocInterfaceEntry(Class* interface)
+ InterfaceEntry* AllocInterfaceEntry(Thread* self, Class* interface)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* CreatePrimitiveClass(Primitive::Type type)
+ Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return InitializePrimitiveClass(AllocClass(sizeof(Class)), type);
+ return InitializePrimitiveClass(AllocClass(self, sizeof(Class)), type);
}
Class* InitializePrimitiveClass(Class* primitive_class, Primitive::Type type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -444,8 +444,9 @@
void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it, SirtRef<Class>& klass,
SirtRef<Field>& dst) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* LoadMethod(const DexFile& dex_file, const ClassDataItemIterator& dex_method,
- SirtRef<Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ AbstractMethod* LoadMethod(Thread* self, const DexFile& dex_file,
+ const ClassDataItemIterator& dex_method,
+ SirtRef<Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupStaticTrampolines(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -538,9 +539,10 @@
EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class)
+ AbstractMethod* CreateProxyConstructor(Thread* self, SirtRef<Class>& klass, Class* proxy_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* CreateProxyMethod(SirtRef<Class>& klass, SirtRef<AbstractMethod>& prototype)
+ AbstractMethod* CreateProxyMethod(Thread* self, SirtRef<Class>& klass,
+ SirtRef<AbstractMethod>& prototype)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::vector<const DexFile*> boot_class_path_;
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index d0b9e16..02512eb 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -773,7 +773,7 @@
TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
ScopedObjectAccess soa(Thread::Current());
Class* array_class = class_linker_->FindSystemClass("[Ljava/lang/String;");
- ObjectArray<String>* array = ObjectArray<String>::Alloc(array_class, 0);
+ ObjectArray<String>* array = ObjectArray<String>::Alloc(soa.Self(), array_class, 0);
uint32_t array_offset = reinterpret_cast<uint32_t>(array);
uint32_t data_offset =
array_offset + ObjectArray<String>::DataOffset(sizeof(String*)).Uint32Value();
@@ -786,27 +786,27 @@
TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<LongArray> long_array(soa.Self(), LongArray::Alloc(0));
+ SirtRef<LongArray> long_array(soa.Self(), LongArray::Alloc(soa.Self(), 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(soa.Self(), DoubleArray::Alloc(0));
+ SirtRef<DoubleArray> double_array(soa.Self(), DoubleArray::Alloc(soa.Self(), 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(soa.Self(), IntArray::Alloc(0));
+ SirtRef<IntArray> int_array(soa.Self(), IntArray::Alloc(soa.Self(), 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(soa.Self(), CharArray::Alloc(0));
+ SirtRef<CharArray> char_array(soa.Self(), CharArray::Alloc(soa.Self(), 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(soa.Self(), ShortArray::Alloc(0));
+ SirtRef<ShortArray> short_array(soa.Self(), ShortArray::Alloc(soa.Self(), 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
@@ -923,7 +923,7 @@
fh.ChangeField(s8);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimNot);
EXPECT_TRUE(s8->GetObject(NULL)->AsString()->Equals("android"));
- s8->SetObject(NULL, String::AllocFromModifiedUtf8("robot"));
+ s8->SetObject(NULL, String::AllocFromModifiedUtf8(soa.Self(), "robot"));
// TODO: Remove EXPECT_FALSE when GCC can handle EXPECT_EQ
// http://code.google.com/p/googletest/issues/detail?id=322
diff --git a/src/compiler.cc b/src/compiler.cc
index 10b4939..3899ce9 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -34,6 +34,7 @@
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
#include "stl_util.h"
+#include "thread.h"
#include "timing_logger.h"
#include "verifier/method_verifier.h"
@@ -110,9 +111,9 @@
}
}
-// Allow lossy statistics in non-debug builds
+// Allow lossy statistics in non-debug builds.
#ifndef NDEBUG
-#define STATS_LOCK() MutexLock mu(stats_lock_)
+#define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_)
#else
#define STATS_LOCK()
#endif
@@ -359,30 +360,31 @@
}
Compiler::~Compiler() {
+ Thread* self = Thread::Current();
{
- MutexLock mu(compiled_classes_lock_);
+ MutexLock mu(self, compiled_classes_lock_);
STLDeleteValues(&compiled_classes_);
}
{
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(self, compiled_methods_lock_);
STLDeleteValues(&compiled_methods_);
}
{
- MutexLock mu(compiled_invoke_stubs_lock_);
+ MutexLock mu(self, compiled_invoke_stubs_lock_);
STLDeleteValues(&compiled_invoke_stubs_);
}
#if defined(ART_USE_LLVM_COMPILER)
{
- MutexLock mu(compiled_proxy_stubs_lock_);
+ MutexLock mu(self, compiled_proxy_stubs_lock_);
STLDeleteValues(&compiled_proxy_stubs_);
}
#endif
{
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(self, compiled_methods_lock_);
STLDeleteElements(&code_to_patch_);
}
{
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(self, compiled_methods_lock_);
STLDeleteElements(&methods_to_patch_);
}
#if defined(ART_USE_LLVM_COMPILER)
@@ -554,7 +556,7 @@
}
void Compiler::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) {
- MutexLock mu(Compiler::compiled_classes_lock_);
+ MutexLock mu(Thread::Current(), Compiler::compiled_classes_lock_);
compiled_classes_.Put(ref, compiled_class);
}
@@ -929,7 +931,7 @@
uint32_t target_method_idx,
InvokeType target_invoke_type,
size_t literal_offset) {
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(Thread::Current(), compiled_methods_lock_);
code_to_patch_.push_back(new PatchInformation(dex_file,
referrer_method_idx,
referrer_invoke_type,
@@ -943,7 +945,7 @@
uint32_t target_method_idx,
InvokeType target_invoke_type,
size_t literal_offset) {
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(Thread::Current(), compiled_methods_lock_);
methods_to_patch_.push_back(new PatchInformation(dex_file,
referrer_method_idx,
referrer_invoke_type,
@@ -1068,10 +1070,7 @@
// Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
// thread destructor's called below perform join).
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- CHECK_NE(self->GetState(), kRunnable);
- }
+ CHECK_NE(self->GetState(), kRunnable);
STLDeleteElements(&threads);
}
@@ -1427,11 +1426,12 @@
<< " took " << PrettyDuration(duration_ns);
}
+ Thread* self = Thread::Current();
if (compiled_method != NULL) {
MethodReference ref(&dex_file, method_idx);
CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file);
{
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(self, compiled_methods_lock_);
compiled_methods_.Put(ref, compiled_method);
}
DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file);
@@ -1459,10 +1459,10 @@
}
#endif
- if (Thread::Current()->IsExceptionPending()) {
- ScopedObjectAccess soa(Thread::Current());
+ if (self->IsExceptionPending()) {
+ ScopedObjectAccess soa(self);
LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
- << Thread::Current()->GetException()->Dump();
+ << self->GetException()->Dump();
}
}
@@ -1472,7 +1472,7 @@
}
const CompiledInvokeStub* Compiler::FindInvokeStub(const std::string& key) const {
- MutexLock mu(compiled_invoke_stubs_lock_);
+ MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
if (it == compiled_invoke_stubs_.end()) {
return NULL;
@@ -1484,7 +1484,7 @@
void Compiler::InsertInvokeStub(const std::string& key,
const CompiledInvokeStub* compiled_invoke_stub) {
- MutexLock mu(compiled_invoke_stubs_lock_);
+ MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key);
if (it != compiled_invoke_stubs_.end()) {
// Someone else won the race.
@@ -1496,7 +1496,7 @@
#if defined(ART_USE_LLVM_COMPILER)
const CompiledInvokeStub* Compiler::FindProxyStub(const char* shorty) const {
- MutexLock mu(compiled_proxy_stubs_lock_);
+ MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty);
if (it == compiled_proxy_stubs_.end()) {
return NULL;
@@ -1508,7 +1508,7 @@
void Compiler::InsertProxyStub(const char* shorty,
const CompiledInvokeStub* compiled_proxy_stub) {
- MutexLock mu(compiled_proxy_stubs_lock_);
+ MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty);
if (it != compiled_proxy_stubs_.end()) {
// Someone else won the race.
@@ -1520,7 +1520,7 @@
#endif
CompiledClass* Compiler::GetCompiledClass(ClassReference ref) const {
- MutexLock mu(compiled_classes_lock_);
+ MutexLock mu(Thread::Current(), compiled_classes_lock_);
ClassTable::const_iterator it = compiled_classes_.find(ref);
if (it == compiled_classes_.end()) {
return NULL;
@@ -1530,7 +1530,7 @@
}
CompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const {
- MutexLock mu(compiled_methods_lock_);
+ MutexLock mu(Thread::Current(), compiled_methods_lock_);
MethodTable::const_iterator it = compiled_methods_.find(ref);
if (it == compiled_methods_.end()) {
return NULL;
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index f65f684..85ae794 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -126,7 +126,7 @@
CompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
- MutexLock GUARD(num_cunits_lock_);
+ MutexLock GUARD(Thread::Current(), num_cunits_lock_);
CompilationUnit* cunit = new CompilationUnit(this, num_cunits_++);
if (!bitcode_filename_.empty()) {
cunit->SetBitcodeFileName(StringPrintf("%s-%zu", bitcode_filename_.c_str(), num_cunits_-1));
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index 3bb4ae5..d7e146a 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -230,17 +230,17 @@
Object* art_alloc_array_from_code(uint32_t type_idx,
AbstractMethod* referrer,
uint32_t length,
- Thread* /*thread*/)
+ Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return AllocArrayFromCode(type_idx, referrer, length, false);
+ return AllocArrayFromCode(type_idx, referrer, length, self, false);
}
Object* art_alloc_array_from_code_with_access_check(uint32_t type_idx,
AbstractMethod* referrer,
uint32_t length,
- Thread* /*thread*/)
+ Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return AllocArrayFromCode(type_idx, referrer, length, true);
+ return AllocArrayFromCode(type_idx, referrer, length, self, true);
}
Object* art_check_and_alloc_array_from_code(uint32_t type_idx,
@@ -748,12 +748,12 @@
va_start(ap, proxy_method);
Object* receiver = va_arg(ap, Object*);
- Thread* thread = va_arg(ap, Thread*);
+ Thread* self = va_arg(ap, Thread*);
MethodHelper proxy_mh(proxy_method);
const size_t num_params = proxy_mh.NumArgs();
// Start new JNI local reference state
- JNIEnvExt* env = thread->GetJniEnv();
+ JNIEnvExt* env = self->GetJniEnv();
ScopedObjectAccessUnchecked soa(env);
ScopedJniEnvLocalRefState env_state(env);
@@ -773,9 +773,9 @@
args_jobj[2].l = NULL;
ObjectArray<Object>* args = NULL;
if ((num_params - 1) > 0) {
- args = Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(num_params - 1);
+ args = Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(self, num_params - 1);
if (args == NULL) {
- CHECK(thread->IsExceptionPending());
+ CHECK(self->IsExceptionPending());
return;
}
args_jobj[2].l = soa.AddLocalReference<jobjectArray>(args);
@@ -783,9 +783,9 @@
// Get parameter types.
const char* shorty = proxy_mh.GetShorty();
- ObjectArray<Class>* param_types = proxy_mh.GetParameterTypes();
+ ObjectArray<Class>* param_types = proxy_mh.GetParameterTypes(self);
if (param_types == NULL) {
- CHECK(thread->IsExceptionPending());
+ CHECK(self->IsExceptionPending());
return;
}
@@ -822,7 +822,7 @@
Class* param_type = param_types->Get(i);
if (param_type->IsPrimitive()) {
BoxPrimitive(param_type->GetPrimitiveType(), val);
- if (thread->IsExceptionPending()) {
+ if (self->IsExceptionPending()) {
return;
}
}
@@ -836,19 +836,19 @@
jobject result = env->CallObjectMethodA(inv_hand, WellKnownClasses::java_lang_reflect_InvocationHandler_invoke, args_jobj);
// Place result in stack args
- if (!thread->IsExceptionPending()) {
+ if (!self->IsExceptionPending()) {
if (shorty[0] == 'V') {
return;
}
- Object* result_ref = thread->DecodeJObject(result);
+ Object* result_ref = self->DecodeJObject(result);
JValue* result_unboxed = va_arg(ap, JValue*);
if (result_ref == NULL) {
result_unboxed->SetL(NULL);
} else {
bool unboxed_okay = UnboxPrimitiveForResult(result_ref, proxy_mh.GetReturnType(), *result_unboxed);
if (!unboxed_okay) {
- thread->ClearException();
- thread->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
+ self->ClearException();
+ self->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
"Couldn't convert result of type %s to %s",
PrettyTypeOf(result_ref).c_str(),
PrettyDescriptor(proxy_mh.GetReturnType()).c_str());
@@ -858,7 +858,7 @@
} else {
// In the case of checked exceptions that aren't declared, the exception must be wrapped by
// a UndeclaredThrowableException.
- Throwable* exception = thread->GetException();
+ Throwable* exception = self->GetException();
if (exception->IsCheckedException()) {
SynthesizedProxyClass* proxy_class =
down_cast<SynthesizedProxyClass*>(proxy_method->GetDeclaringClass());
@@ -879,7 +879,7 @@
declares_exception = declared_exception->IsAssignableFrom(exception_class);
}
if (!declares_exception) {
- thread->ThrowNewWrappedException("Ljava/lang/reflect/UndeclaredThrowableException;", NULL);
+ self->ThrowNewWrappedException("Ljava/lang/reflect/UndeclaredThrowableException;", NULL);
}
}
}
diff --git a/src/debugger.cc b/src/debugger.cc
index e28845f..c8e7381 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -55,19 +55,19 @@
return 0;
}
JDWP::ObjectId id = static_cast<JDWP::ObjectId>(reinterpret_cast<uintptr_t>(o));
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
map_.Overwrite(id, o);
return id;
}
void Clear() {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
LOG(DEBUG) << "Debugger has detached; object registry had " << map_.size() << " entries";
map_.clear();
}
bool Contains(JDWP::ObjectId id) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
return map_.find(id) != map_.end();
}
@@ -76,14 +76,14 @@
return NULL;
}
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
typedef SafeMap<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
It it = map_.find(id);
return (it != map_.end()) ? reinterpret_cast<T>(it->second) : reinterpret_cast<T>(kInvalidId);
}
void VisitRoots(Heap::RootVisitor* visitor, void* arg) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
typedef SafeMap<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
for (It it = map_.begin(); it != map_.end(); ++it) {
visitor(it->second, arg);
@@ -184,7 +184,7 @@
static bool IsBreakpoint(AbstractMethod* m, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
for (size_t i = 0; i < gBreakpoints.size(); ++i) {
if (gBreakpoints[i].method == m && gBreakpoints[i].dex_pc == dex_pc) {
VLOG(jdwp) << "Hit breakpoint #" << i << ": " << gBreakpoints[i];
@@ -492,7 +492,7 @@
}
static void SetDebuggerUpdatesEnabled(bool enabled) {
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(SetDebuggerUpdatesEnabledCallback, &enabled);
}
@@ -508,7 +508,7 @@
{
// TODO: dalvik only warned if there were breakpoints left over. clear in Dbg::Disconnected?
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
CHECK_EQ(gBreakpoints.size(), 0U);
}
@@ -884,7 +884,7 @@
}
JDWP::ObjectId Dbg::CreateString(const std::string& str) {
- return gRegistry->Add(String::AllocFromModifiedUtf8(str.c_str()));
+ return gRegistry->Add(String::AllocFromModifiedUtf8(Thread::Current(), str.c_str()));
}
JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object) {
@@ -893,7 +893,7 @@
if (c == NULL) {
return status;
}
- new_object = gRegistry->Add(c->AllocObject());
+ new_object = gRegistry->Add(c->AllocObject(Thread::Current()));
return JDWP::ERR_NONE;
}
@@ -907,7 +907,7 @@
if (c == NULL) {
return status;
}
- new_array = gRegistry->Add(Array::Alloc(c, length));
+ new_array = gRegistry->Add(Array::Alloc(Thread::Current(), c, length));
return JDWP::ERR_NONE;
}
@@ -1331,8 +1331,9 @@
}
bool Dbg::GetThreadName(JDWP::ObjectId threadId, std::string& name) {
- MutexLock mu(*Locks::thread_list_lock_);
- ScopedObjectAccessUnchecked soa(Thread::Current());
+ Thread* self = Thread::Current();
+ MutexLock mu(self, *Locks::thread_list_lock_);
+ ScopedObjectAccessUnchecked soa(self);
Thread* thread = DecodeThread(soa, threadId);
if (thread == NULL) {
return false;
@@ -1349,7 +1350,7 @@
}
// Okay, so it's an object, but is it actually a thread?
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
if (DecodeThread(soa, threadId) == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
@@ -1408,13 +1409,13 @@
bool Dbg::GetThreadStatus(JDWP::ObjectId threadId, JDWP::JdwpThreadStatus* pThreadStatus, JDWP::JdwpSuspendStatus* pSuspendStatus) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = DecodeThread(soa, threadId);
if (thread == NULL) {
return false;
}
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
// TODO: if we're in Thread.sleep(long), we should return TS_SLEEPING,
// even if it's implemented using Object.wait(long).
@@ -1448,28 +1449,28 @@
JDWP::JdwpError Dbg::GetThreadDebugSuspendCount(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = DecodeThread(soa, threadId);
if (thread == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
expandBufAdd4BE(pReply, thread->GetDebugSuspendCount());
return JDWP::ERR_NONE;
}
bool Dbg::ThreadExists(JDWP::ObjectId threadId) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
return DecodeThread(soa, threadId) != NULL;
}
bool Dbg::IsSuspended(JDWP::ObjectId threadId) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = DecodeThread(soa, threadId);
CHECK(thread != NULL);
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
return thread->IsSuspended();
}
@@ -1513,7 +1514,7 @@
ScopedObjectAccessUnchecked soa(Thread::Current());
Object* thread_group = gRegistry->Get<Object*>(thread_group_id);
ThreadListVisitor tlv(soa, thread_group, thread_ids);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(ThreadListVisitor::Visit, &tlv);
}
@@ -1554,7 +1555,7 @@
};
if (kIsDebugBuild) {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
+ MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_);
CHECK(thread->IsSuspended());
}
CountStackDepthVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack());
@@ -1652,7 +1653,7 @@
void Dbg::ResumeThread(JDWP::ObjectId threadId) {
ScopedObjectAccessUnchecked soa(Thread::Current());
Object* peer = gRegistry->Get<Object*>(threadId);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, peer);
if (thread == NULL) {
LOG(WARNING) << "No such thread for resume: " << peer;
@@ -1660,7 +1661,7 @@
}
bool needs_resume;
{
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
needs_resume = thread->GetSuspendCount() > 0;
}
if (needs_resume) {
@@ -1716,12 +1717,12 @@
ScopedObjectAccessUnchecked soa(Thread::Current());
Thread* thread;
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
thread = DecodeThread(soa, thread_id);
if (thread == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
if (!thread->IsSuspended()) {
return JDWP::ERR_THREAD_NOT_SUSPENDED;
}
@@ -2020,7 +2021,7 @@
// If the debugger is single-stepping one of our threads, check to
// see if we're that thread and we've reached a step point.
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
if (gSingleStepControl.is_active && gSingleStepControl.thread == self) {
CHECK(!m->IsNative());
if (gSingleStepControl.step_depth == JDWP::SD_INTO) {
@@ -2104,14 +2105,14 @@
}
void Dbg::WatchLocation(const JDWP::JdwpLocation* location) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
AbstractMethod* m = FromMethodId(location->method_id);
gBreakpoints.push_back(Breakpoint(m, location->dex_pc));
VLOG(jdwp) << "Set breakpoint #" << (gBreakpoints.size() - 1) << ": " << gBreakpoints[gBreakpoints.size() - 1];
}
void Dbg::UnwatchLocation(const JDWP::JdwpLocation* location) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
AbstractMethod* m = FromMethodId(location->method_id);
for (size_t i = 0; i < gBreakpoints.size(); ++i) {
if (gBreakpoints[i].method == m && gBreakpoints[i].dex_pc == location->dex_pc) {
@@ -2130,7 +2131,7 @@
return JDWP::ERR_INVALID_THREAD;
}
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(soa.Self(), gBreakpointsLock);
// TODO: there's no theoretical reason why we couldn't support single-stepping
// of multiple threads at once, but we never did so historically.
if (gSingleStepControl.thread != NULL && thread != gSingleStepControl.thread) {
@@ -2149,7 +2150,7 @@
EXCLUSIVE_LOCKS_REQUIRED(gBreakpointsLock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: StackVisitor(stack, trace_stack, NULL) {
- gBreakpointsLock.AssertHeld();
+ gBreakpointsLock.AssertHeld(Thread::Current());
gSingleStepControl.method = NULL;
gSingleStepControl.stack_depth = 0;
}
@@ -2157,7 +2158,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
- gBreakpointsLock.AssertHeld();
+ gBreakpointsLock.AssertHeld(Thread::Current());
const AbstractMethod* m = GetMethod();
if (!m->IsRuntimeMethod()) {
++gSingleStepControl.stack_depth;
@@ -2188,7 +2189,7 @@
}
static bool Callback(void* raw_context, uint32_t address, uint32_t line_number) {
- MutexLock mu(gBreakpointsLock); // Keep GCC happy.
+ MutexLock mu(Thread::Current(), gBreakpointsLock); // Keep GCC happy.
DebugCallbackContext* context = reinterpret_cast<DebugCallbackContext*>(raw_context);
if (static_cast<int32_t>(line_number) == gSingleStepControl.line_number) {
if (!context->last_pc_valid) {
@@ -2209,7 +2210,7 @@
}
~DebugCallbackContext() {
- MutexLock mu(gBreakpointsLock); // Keep GCC happy.
+ MutexLock mu(Thread::Current(), gBreakpointsLock); // Keep GCC happy.
// If the line number was the last in the position table...
if (last_pc_valid) {
size_t end = MethodHelper(gSingleStepControl.method).GetCodeItem()->insns_size_in_code_units_;
@@ -2259,7 +2260,7 @@
}
void Dbg::UnconfigureStep(JDWP::ObjectId /*threadId*/) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
gSingleStepControl.is_active = false;
gSingleStepControl.thread = NULL;
@@ -2307,7 +2308,7 @@
Thread* self = Thread::Current();
{
ScopedObjectAccessUnchecked soa(self);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
targetThread = DecodeThread(soa, threadId);
if (targetThread == NULL) {
LOG(ERROR) << "InvokeMethod request for non-existent thread " << threadId;
@@ -2335,7 +2336,7 @@
*/
int suspend_count;
{
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
suspend_count = targetThread->GetSuspendCount();
}
if (suspend_count > 1) {
@@ -2411,7 +2412,7 @@
VLOG(jdwp) << " Transferring control to event thread";
{
- MutexLock mu(req->lock_);
+ MutexLock mu(self, req->lock_);
if ((options & JDWP::INVOKE_SINGLE_THREADED) == 0) {
VLOG(jdwp) << " Resuming all threads";
@@ -2631,12 +2632,9 @@
VLOG(jdwp) << "Broadcasting DDM " << (connect ? "connect" : "disconnect") << "...";
Thread* self = Thread::Current();
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- if (self->GetState() != kRunnable) {
- LOG(ERROR) << "DDM broadcast in thread state " << self->GetState();
- /* try anyway? */
- }
+ if (self->GetState() != kRunnable) {
+ LOG(ERROR) << "DDM broadcast in thread state " << self->GetState();
+ /* try anyway? */
}
JNIEnv* env = self->GetJniEnv();
@@ -2699,12 +2697,13 @@
// notification.
SuspendVM();
std::list<Thread*> threads;
+ Thread* self = Thread::Current();
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(self, *Locks::thread_list_lock_);
threads = Runtime::Current()->GetThreadList()->GetList();
}
{
- ScopedObjectAccess soa(Thread::Current());
+ ScopedObjectAccess soa(self);
typedef std::list<Thread*>::const_iterator It; // TODO: C++0x auto
for (It it = threads.begin(), end = threads.end(); it != end; ++it) {
Dbg::DdmSendThreadNotification(*it, CHUNK_TYPE("THCR"));
@@ -3096,9 +3095,10 @@
} else {
Heap* heap = Runtime::Current()->GetHeap();
const Spaces& spaces = heap->GetSpaces();
+ Thread* self = Thread::Current();
for (Spaces::const_iterator cur = spaces.begin(); cur != spaces.end(); ++cur) {
if ((*cur)->IsAllocSpace()) {
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
(*cur)->AsAllocSpace()->Walk(HeapChunkContext::HeapChunkCallback, &context);
}
}
@@ -3111,7 +3111,7 @@
}
void Dbg::SetAllocTrackingEnabled(bool enabled) {
- MutexLock mu(gAllocTrackerLock);
+ MutexLock mu(Thread::Current(), gAllocTrackerLock);
if (enabled) {
if (recent_allocation_records_ == NULL) {
LOG(INFO) << "Enabling alloc tracker (" << kNumAllocRecords << " entries, "
@@ -3164,7 +3164,7 @@
Thread* self = Thread::Current();
CHECK(self != NULL);
- MutexLock mu(gAllocTrackerLock);
+ MutexLock mu(self, gAllocTrackerLock);
if (recent_allocation_records_ == NULL) {
return;
}
@@ -3203,7 +3203,7 @@
void Dbg::DumpRecentAllocations() {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(gAllocTrackerLock);
+ MutexLock mu(soa.Self(), gAllocTrackerLock);
if (recent_allocation_records_ == NULL) {
LOG(INFO) << "Not recording tracked allocations";
return;
@@ -3323,7 +3323,8 @@
DumpRecentAllocations();
}
- MutexLock mu(gAllocTrackerLock);
+ Thread* self = Thread::Current();
+ MutexLock mu(self, gAllocTrackerLock);
//
// Part 1: generate string tables.
@@ -3428,7 +3429,7 @@
method_names.WriteTo(bytes);
filenames.WriteTo(bytes);
- JNIEnv* env = Thread::Current()->GetJniEnv();
+ JNIEnv* env = self->GetJniEnv();
jbyteArray result = env->NewByteArray(bytes.size());
if (result != NULL) {
env->SetByteArrayRegion(result, 0, bytes.size(), reinterpret_cast<const jbyte*>(&bytes[0]));
diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc
index 6c0107c..b131e4c 100644
--- a/src/dex_cache_test.cc
+++ b/src/dex_cache_test.cc
@@ -29,7 +29,8 @@
TEST_F(DexCacheTest, Open) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<DexCache> dex_cache(soa.Self(), class_linker_->AllocDexCache(*java_lang_dex_file_));
+ SirtRef<DexCache> dex_cache(soa.Self(), class_linker_->AllocDexCache(soa.Self(),
+ *java_lang_dex_file_));
ASSERT_TRUE(dex_cache.get() != NULL);
EXPECT_EQ(java_lang_dex_file_->NumStringIds(), dex_cache->NumStrings());
diff --git a/src/heap.cc b/src/heap.cc
index fa044c2..f7cb68d 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -277,7 +277,7 @@
};
void Heap::AddSpace(ContinuousSpace* space) {
- WriterMutexLock mu(*Locks::heap_bitmap_lock_);
+ WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
DCHECK(space != NULL);
DCHECK(space->GetLiveBitmap() != NULL);
live_bitmap_->AddSpaceBitmap(space->GetLiveBitmap());
@@ -357,7 +357,7 @@
}
}
-Object* Heap::AllocObject(Class* c, size_t byte_count) {
+Object* Heap::AllocObject(Thread* self, Class* c, size_t byte_count) {
DCHECK(c == NULL || (c->IsClassClass() && byte_count >= sizeof(Class)) ||
(c->IsVariableSize() || c->GetObjectSize() == byte_count) ||
strlen(ClassHelper(c).GetDescriptor()) == 0);
@@ -372,7 +372,7 @@
// range. This also means that we rely on SetClass not dirtying the object's card.
if (byte_count >= large_object_threshold_ && have_zygote_space_ && c->IsPrimitiveArray()) {
size = RoundUp(byte_count, kPageSize);
- obj = Allocate(NULL, size);
+ obj = Allocate(self, NULL, size);
if (obj != NULL) {
// Make sure that our large object didn't get placed anywhere within the space interval or else
@@ -381,7 +381,7 @@
reinterpret_cast<byte*>(obj) >= spaces_.back()->End());
}
} else {
- obj = Allocate(alloc_space_, byte_count);
+ obj = Allocate(self, alloc_space_, byte_count);
size = alloc_space_->AllocationSize(obj);
if (obj != NULL) {
@@ -405,7 +405,6 @@
// concurrent_start_bytes_.
concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
// The SirtRef is necessary since the calls in RequestConcurrentGC are a safepoint.
- Thread* self = Thread::Current();
SirtRef<Object> ref(self, obj);
RequestConcurrentGC(self);
}
@@ -424,7 +423,7 @@
std::string msg(StringPrintf("Failed to allocate a %zd-byte %s (%lld total bytes free; largest possible contiguous allocation %zd bytes)",
byte_count, PrettyDescriptor(c).c_str(), total_bytes_free, max_contiguous_allocation));
- Thread::Current()->ThrowOutOfMemoryError(msg.c_str());
+ self->ThrowOutOfMemoryError(msg.c_str());
return NULL;
}
@@ -483,7 +482,7 @@
if (!std::binary_search(live_stack_->Begin(), live_stack_->End(), obj) &&
std::find(allocation_stack_->Begin(), allocation_stack_->End(), obj) ==
allocation_stack_->End()) {
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
if (large_object_space_->GetLiveObjects()->Test(obj)) {
DumpSpaces();
LOG(FATAL) << "Object is dead: " << obj;
@@ -520,7 +519,7 @@
}
void Heap::VerifyHeap() {
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
GetLiveBitmap()->Walk(Heap::VerificationCallback, this);
}
@@ -561,44 +560,38 @@
}
}
-Object* Heap::TryToAllocate(AllocSpace* space, size_t alloc_size, bool grow) {
+Object* Heap::TryToAllocate(Thread* self, AllocSpace* space, size_t alloc_size, bool grow) {
// Should we try to use a CAS here and fix up num_bytes_allocated_ later with AllocationSize?
if (num_bytes_allocated_ + alloc_size > growth_limit_) {
return NULL;
}
if (UNLIKELY(space == NULL)) {
- return large_object_space_->Alloc(alloc_size);
+ return large_object_space_->Alloc(self, alloc_size);
} else if (grow) {
- return space->AllocWithGrowth(alloc_size);
+ return space->AllocWithGrowth(self, alloc_size);
} else {
- return space->AllocWithoutGrowth(alloc_size);
+ return space->AllocWithoutGrowth(self, alloc_size);
}
}
-Object* Heap::Allocate(AllocSpace* space, size_t alloc_size) {
+Object* Heap::Allocate(Thread* self, AllocSpace* space, size_t alloc_size) {
// Since allocation can cause a GC which will need to SuspendAll, make sure all allocations are
// done in the runnable state where suspension is expected.
-#ifndef NDEBUG
- Thread* self = Thread::Current();
DCHECK_EQ(self->GetState(), kRunnable);
self->AssertThreadSuspensionIsAllowable();
-#endif
- Object* ptr = TryToAllocate(space, alloc_size, false);
+ Object* ptr = TryToAllocate(self, space, alloc_size, false);
if (ptr != NULL) {
return ptr;
}
// The allocation failed. If the GC is running, block until it completes, and then retry the
// allocation.
-#ifdef NDEBUG
- Thread* self = Thread::Current();
-#endif
GcType last_gc = WaitForConcurrentGcToComplete(self);
if (last_gc != kGcTypeNone) {
// A GC was in progress and we blocked, retry allocation now that memory has been freed.
- ptr = TryToAllocate(space, alloc_size, false);
+ ptr = TryToAllocate(self, space, alloc_size, false);
if (ptr != NULL) {
return ptr;
}
@@ -635,7 +628,7 @@
self->TransitionFromSuspendedToRunnable();
// Did we free sufficient memory for the allocation to succeed?
- ptr = TryToAllocate(space, alloc_size, false);
+ ptr = TryToAllocate(self, space, alloc_size, false);
if (ptr != NULL) {
return ptr;
}
@@ -644,7 +637,7 @@
// Allocations have failed after GCs; this is an exceptional state.
// Try harder, growing the heap if necessary.
- ptr = TryToAllocate(space, alloc_size, true);
+ ptr = TryToAllocate(self, space, alloc_size, true);
if (ptr != NULL) {
if (space != NULL) {
size_t new_footprint = space->GetFootprintLimit();
@@ -669,7 +662,7 @@
self->TransitionFromRunnableToSuspended(kWaitingPerformingGc);
CollectGarbageInternal(kGcTypeFull, kGcCauseForAlloc, true);
self->TransitionFromSuspendedToRunnable();
- return TryToAllocate(space, alloc_size, true);
+ return TryToAllocate(self, space, alloc_size, true);
}
int64_t Heap::GetMaxMemory() {
@@ -721,7 +714,7 @@
};
int64_t Heap::CountInstances(Class* c, bool count_assignable) {
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
InstanceCounter counter(c, count_assignable);
GetLiveBitmap()->Walk(InstanceCounter::Callback, &counter);
return counter.GetCount();
@@ -1620,12 +1613,12 @@
{
// TODO: this lock shouldn't be necessary (it's why we did the bitmap flip above).
if (gc_type != kGcTypeSticky) {
- WriterMutexLock mu(*Locks::heap_bitmap_lock_);
+ WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
mark_sweep.SweepLargeObjects(swap);
timings.AddSplit("SweepLargeObjects");
mark_sweep.Sweep(gc_type == kGcTypePartial, swap);
} else {
- WriterMutexLock mu(*Locks::heap_bitmap_lock_);
+ WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
mark_sweep.SweepArray(timings, live_stack_.get(), swap);
timings.AddSplit("SweepArray");
}
diff --git a/src/heap.h b/src/heap.h
index 5fe491f..7a96fd6 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -77,7 +77,7 @@
};
std::ostream& operator<<(std::ostream& os, const GcCause& policy);
-class LOCKABLE Heap {
+class Heap {
public:
static const size_t kInitialSize = 2 * MB;
@@ -95,7 +95,7 @@
~Heap();
// Allocates and initializes storage for an object instance.
- Object* AllocObject(Class* klass, size_t num_bytes)
+ Object* AllocObject(Thread* self, Class* klass, size_t num_bytes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Check sanity of given reference. Requires the heap lock.
@@ -296,12 +296,12 @@
private:
// Allocates uninitialized storage. Passing in a null space tries to place the object in the
// large object space.
- Object* Allocate(AllocSpace* space, size_t num_bytes)
+ Object* Allocate(Thread* self, AllocSpace* space, size_t num_bytes)
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Try to allocate a number of bytes, this function never does any GCs.
- Object* TryToAllocate(AllocSpace* space, size_t alloc_size, bool grow)
+ Object* TryToAllocate(Thread* self, AllocSpace* space, size_t alloc_size, bool grow)
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/src/heap_test.cc b/src/heap_test.cc
index 881a765..6db7416 100644
--- a/src/heap_test.cc
+++ b/src/heap_test.cc
@@ -39,9 +39,10 @@
Class* c = class_linker_->FindSystemClass("[Ljava/lang/Object;");
for (size_t i = 0; i < 1024; ++i) {
- SirtRef<ObjectArray<Object> > array(soa.Self(), ObjectArray<Object>::Alloc(c, 2048));
+ SirtRef<ObjectArray<Object> > array(soa.Self(),
+ ObjectArray<Object>::Alloc(soa.Self(), c, 2048));
for (size_t j = 0; j < 2048; ++j) {
- array->Set(j, String::AllocFromModifiedUtf8("hello, world!"));
+ array->Set(j, String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
}
}
}
diff --git a/src/hprof/hprof.cc b/src/hprof/hprof.cc
index 0cad709..125b19a 100644
--- a/src/hprof/hprof.cc
+++ b/src/hprof/hprof.cc
@@ -407,12 +407,13 @@
// Walk the roots and the heap.
current_record_.StartNewRecord(body_fp_, HPROF_TAG_HEAP_DUMP_SEGMENT, HPROF_TIME);
Runtime::Current()->VisitRoots(RootVisitor, this);
+ Thread* self = Thread::Current();
{
- WriterMutexLock mu(*Locks::heap_bitmap_lock_);
+ WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
Runtime::Current()->GetHeap()->FlushAllocStack();
}
{
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
Runtime::Current()->GetHeap()->GetLiveBitmap()->Walk(HeapBitmapCallback, this);
}
current_record_.StartNewRecord(body_fp_, HPROF_TAG_HEAP_DUMP_END, HPROF_TIME);
@@ -444,22 +445,27 @@
if (fd_ >= 0) {
out_fd = dup(fd_);
if (out_fd < 0) {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno));
+ self->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
+ "Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno));
return;
}
} else {
out_fd = open(filename_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (out_fd < 0) {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(), strerror(errno));
+ self->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
+ "Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(),
+ strerror(errno));
return;
}
}
UniquePtr<File> file(OS::FileFromFd(filename_.c_str(), out_fd));
- okay = file->WriteFully(header_data_ptr_, header_data_size_) && file->WriteFully(body_data_ptr_, body_data_size_);
+ okay = file->WriteFully(header_data_ptr_, header_data_size_) &&
+ file->WriteFully(body_data_ptr_, body_data_size_);
if (!okay) {
- std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", filename_.c_str(), strerror(errno)));
- Thread::Current()->ThrowNewException("Ljava/lang/RuntimeException;", msg.c_str());
+ std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s",
+ filename_.c_str(), strerror(errno)));
+ self->ThrowNewException("Ljava/lang/RuntimeException;", msg.c_str());
LOG(ERROR) << msg;
}
close(out_fd);
@@ -468,7 +474,9 @@
// Throw out a log message for the benefit of "runhat".
if (okay) {
uint64_t duration = NanoTime() - start_ns_;
- LOG(INFO) << "hprof: heap dump completed (" << PrettySize(header_data_size_ + body_data_size_ + 1023) << ") in " << PrettyDuration(duration);
+ LOG(INFO) << "hprof: heap dump completed ("
+ << PrettySize(header_data_size_ + body_data_size_ + 1023)
+ << ") in " << PrettyDuration(duration);
}
}
diff --git a/src/image_writer.cc b/src/image_writer.cc
index c876329..fe12baf 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -192,7 +192,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// TODO: Check image spaces only?
Heap* heap = Runtime::Current()->GetHeap();
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
heap->FlushAllocStack();
heap->GetLiveBitmap()->Walk(ComputeEagerResolvedStringsCallback, this);
}
@@ -276,12 +276,13 @@
}
Heap* heap = Runtime::Current()->GetHeap();
+ Thread* self = Thread::Current();
{
- WriterMutexLock mu(*Locks::heap_bitmap_lock_);
+ WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
heap->FlushAllocStack();
}
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
heap->GetLiveBitmap()->Walk(CheckNonImageClassesRemovedCallback, this);
}
@@ -340,9 +341,10 @@
Runtime* runtime = Runtime::Current();
ClassLinker* class_linker = runtime->GetClassLinker();
Class* object_array_class = class_linker->FindSystemClass("[Ljava/lang/Object;");
+ Thread* self = Thread::Current();
// build an Object[] of all the DexCaches used in the source_space_
- ObjectArray<Object>* dex_caches = ObjectArray<Object>::Alloc(object_array_class,
+ ObjectArray<Object>* dex_caches = ObjectArray<Object>::Alloc(self, object_array_class,
dex_caches_.size());
int i = 0;
typedef Set::const_iterator It; // TODO: C++0x auto
@@ -352,8 +354,9 @@
// build an Object[] of the roots needed to restore the runtime
SirtRef<ObjectArray<Object> >
- image_roots(Thread::Current(),
- ObjectArray<Object>::Alloc(object_array_class, ImageHeader::kImageRootsMax));
+ image_roots(self,
+ ObjectArray<Object>::Alloc(self, object_array_class,
+ ImageHeader::kImageRootsMax));
image_roots->Set(ImageHeader::kJniStubArray, runtime->GetJniDlsymLookupStub());
image_roots->Set(ImageHeader::kAbstractMethodErrorStubArray,
runtime->GetAbstractMethodErrorStubArray());
@@ -369,7 +372,7 @@
image_roots->Set(ImageHeader::kRefsAndArgsSaveMethod,
runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs));
image_roots->Set(ImageHeader::kOatLocation,
- String::AllocFromModifiedUtf8(oat_file_->GetLocation().c_str()));
+ String::AllocFromModifiedUtf8(self, oat_file_->GetLocation().c_str()));
image_roots->Set(ImageHeader::kDexCaches,
dex_caches);
image_roots->Set(ImageHeader::kClassRoots,
@@ -425,15 +428,16 @@
void ImageWriter::CopyAndFixupObjects()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const char* old_cause = Thread::Current()->StartAssertNoThreadSuspension("ImageWriter");
+ Thread* self = Thread::Current();
+ const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
Heap* heap = Runtime::Current()->GetHeap();
// TODO: heap validation can't handle this fix up pass
heap->DisableObjectValidation();
// TODO: Image spaces only?
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
heap->FlushAllocStack();
heap->GetLiveBitmap()->Walk(CopyAndFixupObjectsCallback, this);
- Thread::Current()->EndAssertNoThreadSuspension(old_cause);
+ self->EndAssertNoThreadSuspension(old_cause);
}
void ImageWriter::CopyAndFixupObjectsCallback(Object* object, void* arg) {
diff --git a/src/indirect_reference_table_test.cc b/src/indirect_reference_table_test.cc
index 971e42a..b5a05ec 100644
--- a/src/indirect_reference_table_test.cc
+++ b/src/indirect_reference_table_test.cc
@@ -49,13 +49,13 @@
Class* c = class_linker_->FindSystemClass("Ljava/lang/Object;");
ASSERT_TRUE(c != NULL);
- Object* obj0 = c->AllocObject();
+ Object* obj0 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj0 != NULL);
- Object* obj1 = c->AllocObject();
+ Object* obj1 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj1 != NULL);
- Object* obj2 = c->AllocObject();
+ Object* obj2 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj2 != NULL);
- Object* obj3 = c->AllocObject();
+ Object* obj3 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj3 != NULL);
const uint32_t cookie = IRT_FIRST_SEGMENT;
diff --git a/src/intern_table.cc b/src/intern_table.cc
index 10dd7f0..5ad3958 100644
--- a/src/intern_table.cc
+++ b/src/intern_table.cc
@@ -25,19 +25,19 @@
}
size_t InternTable::Size() const {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
return strong_interns_.size() + weak_interns_.size();
}
void InternTable::DumpForSigQuit(std::ostream& os) const {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
os << "Intern table: " << strong_interns_.size() << " strong; "
<< weak_interns_.size() << " weak; "
<< image_strong_interns_.size() << " image strong\n";
}
void InternTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = strong_interns_.begin(), end = strong_interns_.end(); it != end; ++it) {
visitor(it->second, arg);
@@ -46,7 +46,7 @@
}
String* InternTable::Lookup(Table& table, String* s, uint32_t hash_code) {
- intern_table_lock_.AssertHeld();
+ intern_table_lock_.AssertHeld(Thread::Current());
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = table.find(hash_code), end = table.end(); it != end; ++it) {
String* existing_string = it->second;
@@ -58,18 +58,18 @@
}
String* InternTable::Insert(Table& table, String* s, uint32_t hash_code) {
- intern_table_lock_.AssertHeld();
+ intern_table_lock_.AssertHeld(Thread::Current());
table.insert(std::make_pair(hash_code, s));
return s;
}
void InternTable::RegisterStrong(String* s) {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
Insert(image_strong_interns_, s, s->GetHashCode());
}
void InternTable::Remove(Table& table, const String* s, uint32_t hash_code) {
- intern_table_lock_.AssertHeld();
+ intern_table_lock_.AssertHeld(Thread::Current());
typedef Table::iterator It; // TODO: C++0x auto
for (It it = table.find(hash_code), end = table.end(); it != end; ++it) {
if (it->second == s) {
@@ -80,7 +80,7 @@
}
String* InternTable::Insert(String* s, bool is_strong) {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
DCHECK(s != NULL);
uint32_t hash_code = s->GetHashCode();
@@ -129,11 +129,11 @@
}
String* InternTable::InternStrong(int32_t utf16_length, const char* utf8_data) {
- return InternStrong(String::AllocFromModifiedUtf8(utf16_length, utf8_data));
+ return InternStrong(String::AllocFromModifiedUtf8(Thread::Current(), utf16_length, utf8_data));
}
String* InternTable::InternStrong(const char* utf8_data) {
- return InternStrong(String::AllocFromModifiedUtf8(utf8_data));
+ return InternStrong(String::AllocFromModifiedUtf8(Thread::Current(), utf8_data));
}
String* InternTable::InternStrong(String* s) {
@@ -151,13 +151,13 @@
}
bool InternTable::ContainsWeak(String* s) {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
const String* found = Lookup(weak_interns_, s, s->GetHashCode());
return found == s;
}
void InternTable::SweepInternTableWeaks(Heap::IsMarkedTester is_marked, void* arg) {
- MutexLock mu(intern_table_lock_);
+ MutexLock mu(Thread::Current(), intern_table_lock_);
typedef Table::iterator It; // TODO: C++0x auto
for (It it = weak_interns_.begin(), end = weak_interns_.end(); it != end;) {
Object* object = it->second;
diff --git a/src/intern_table_test.cc b/src/intern_table_test.cc
index 2833f6e..ee9165e 100644
--- a/src/intern_table_test.cc
+++ b/src/intern_table_test.cc
@@ -29,7 +29,7 @@
InternTable intern_table;
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> foo_3(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
SirtRef<String> bar(soa.Self(), intern_table.InternStrong(3, "bar"));
EXPECT_TRUE(foo_1->Equals("foo"));
EXPECT_TRUE(foo_2->Equals("foo"));
@@ -47,7 +47,7 @@
InternTable t;
EXPECT_EQ(0U, t.Size());
t.InternStrong(3, "foo");
- SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8("foo"));
+ SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
t.InternWeak(foo.get());
EXPECT_EQ(1U, t.Size());
t.InternStrong(3, "bar");
@@ -91,8 +91,8 @@
InternTable t;
t.InternStrong(3, "foo");
t.InternStrong(3, "bar");
- SirtRef<String> hello(soa.Self(), String::AllocFromModifiedUtf8("hello"));
- SirtRef<String> world(soa.Self(), String::AllocFromModifiedUtf8("world"));
+ SirtRef<String> hello(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "hello"));
+ SirtRef<String> world(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "world"));
SirtRef<String> s0(soa.Self(), t.InternWeak(hello.get()));
SirtRef<String> s1(soa.Self(), t.InternWeak(world.get()));
@@ -110,7 +110,7 @@
EXPECT_EQ(2U, t.Size());
// Just check that we didn't corrupt the map.
- SirtRef<String> still_here(soa.Self(), String::AllocFromModifiedUtf8("still here"));
+ SirtRef<String> still_here(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "still here"));
t.InternWeak(still_here.get());
EXPECT_EQ(3U, t.Size());
}
@@ -130,8 +130,8 @@
{
// Weaks are always weak.
InternTable t;
- SirtRef<String> foo_1(soa.Self(), String::AllocFromModifiedUtf8("foo"));
- SirtRef<String> foo_2(soa.Self(), String::AllocFromModifiedUtf8("foo"));
+ SirtRef<String> foo_1(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<String> foo_2(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
EXPECT_NE(foo_1.get(), 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()));
@@ -142,7 +142,7 @@
{
// A weak can be promoted to a strong.
InternTable t;
- SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8("foo"));
+ SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "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(soa.Self(), t.InternStrong(3, "foo"));
@@ -155,7 +155,7 @@
InternTable t;
SirtRef<String> interned_foo_1(soa.Self(), t.InternStrong(3, "foo"));
EXPECT_FALSE(t.ContainsWeak(interned_foo_1.get()));
- SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8("foo"));
+ SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "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/jdwp/jdwp_event.cc b/src/jdwp/jdwp_event.cc
index 19f10eb..2865f3a 100644
--- a/src/jdwp/jdwp_event.cc
+++ b/src/jdwp/jdwp_event.cc
@@ -141,7 +141,7 @@
* not be added to the list, and an appropriate error will be returned.
*/
JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
CHECK(pEvent != NULL);
CHECK(pEvent->prev == NULL);
@@ -234,7 +234,7 @@
* explicitly remove one-off single-step events.)
*/
void JdwpState::UnregisterEventById(uint32_t requestId) {
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
JdwpEvent* pEvent = event_list_;
while (pEvent != NULL) {
@@ -254,7 +254,7 @@
* Remove all entries from the event list.
*/
void JdwpState::UnregisterAll() {
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
JdwpEvent* pEvent = event_list_;
while (pEvent != NULL) {
@@ -537,7 +537,7 @@
pReq->invoke_needed_ = false;
VLOG(jdwp) << "invoke complete, signaling and self-suspending";
- MutexLock mu(pReq->lock_);
+ MutexLock mu(Thread::Current(), pReq->lock_);
pReq->cond_.Signal();
}
}
@@ -615,7 +615,7 @@
* function is called by dvmSuspendSelf(), and the transition back
* to RUNNING would confuse it.
*/
- MutexLock mu(event_thread_lock_);
+ MutexLock mu(Thread::Current(), event_thread_lock_);
CHECK_NE(event_thread_id_, 0U);
VLOG(jdwp) << StringPrintf("cleared event token (%#llx)", event_thread_id_);
@@ -676,7 +676,7 @@
ExpandBuf* pReq = eventPrep();
{
- MutexLock mu(event_list_lock_); // probably don't need this here
+ MutexLock mu(Thread::Current(), event_list_lock_); // probably don't need this here
VLOG(jdwp) << "EVENT: " << EK_VM_START;
VLOG(jdwp) << " suspend_policy=" << suspend_policy;
@@ -757,7 +757,7 @@
JdwpSuspendPolicy suspend_policy = SP_NONE;
{
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
match_list = AllocMatchList(event_list_size_);
if ((eventFlags & Dbg::kBreakpoint) != 0) {
FindMatchingEvents(EK_BREAKPOINT, &basket, match_list, &match_count);
@@ -828,7 +828,7 @@
int match_count = 0;
{
// Don't allow the list to be updated while we scan it.
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
JdwpEvent** match_list = AllocMatchList(event_list_size_);
if (start) {
@@ -917,7 +917,7 @@
ExpandBuf* pReq = NULL;
JdwpSuspendPolicy suspend_policy = SP_NONE;
{
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
match_list = AllocMatchList(event_list_size_);
FindMatchingEvents(EK_EXCEPTION, &basket, match_list, &match_count);
if (match_count != 0) {
@@ -987,7 +987,7 @@
JdwpSuspendPolicy suspend_policy = SP_NONE;
int match_count = 0;
{
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
JdwpEvent** match_list = AllocMatchList(event_list_size_);
FindMatchingEvents(EK_CLASS_PREPARE, &basket, match_list, &match_count);
if (match_count != 0) {
diff --git a/src/jdwp/jdwp_main.cc b/src/jdwp/jdwp_main.cc
index 0c3a9a0..69fc2fc 100644
--- a/src/jdwp/jdwp_main.cc
+++ b/src/jdwp/jdwp_main.cc
@@ -47,7 +47,7 @@
* Write a packet. Grabs a mutex to assure atomicity.
*/
ssize_t JdwpNetStateBase::writePacket(ExpandBuf* pReply) {
- MutexLock mu(socket_lock_);
+ MutexLock mu(Thread::Current(), socket_lock_);
return write(clientSock, expandBufGetBuffer(pReply), expandBufGetLength(pReply));
}
@@ -55,7 +55,7 @@
* Write a buffered packet. Grabs a mutex to assure atomicity.
*/
ssize_t JdwpNetStateBase::writeBufferedPacket(const iovec* iov, int iov_count) {
- MutexLock mu(socket_lock_);
+ MutexLock mu(Thread::Current(), socket_lock_);
return writev(clientSock, iov, iov_count);
}
@@ -72,7 +72,7 @@
* packets to the debugger.
*/
uint32_t JdwpState::NextRequestSerial() {
- MutexLock mu(serial_lock_);
+ MutexLock mu(Thread::Current(), serial_lock_);
return request_serial_++;
}
@@ -81,7 +81,7 @@
* message type EventRequest.Set.
*/
uint32_t JdwpState::NextEventSerial() {
- MutexLock mu(serial_lock_);
+ MutexLock mu(Thread::Current(), serial_lock_);
return event_serial_++;
}
@@ -145,7 +145,7 @@
* won't signal the cond var before we're waiting.
*/
{
- MutexLock thread_start_locker(state->thread_start_lock_);
+ MutexLock thread_start_locker(self, state->thread_start_lock_);
const bool should_suspend = options->suspend;
if (!should_suspend) {
/*
@@ -161,7 +161,7 @@
state->thread_start_cond_.Wait(self, state->thread_start_lock_);
} else {
{
- MutexLock attach_locker(state->attach_lock_);
+ MutexLock attach_locker(self, state->attach_lock_);
/*
* We have bound to a port, or are trying to connect outbound to a
* debugger. Create the JDWP thread and let it continue the mission.
@@ -217,7 +217,7 @@
UnregisterAll();
{
- MutexLock mu(event_list_lock_);
+ MutexLock mu(Thread::Current(), event_list_lock_);
CHECK(event_list_ == NULL);
}
@@ -302,11 +302,8 @@
}
/* set the thread state to kWaitingInMainDebuggerLoop so GCs don't wait for us */
- {
- MutexLock mu(thread_, *Locks::thread_suspend_count_lock_);
- CHECK_EQ(thread_->GetState(), kNative);
- thread_->SetState(kWaitingInMainDebuggerLoop);
- }
+ CHECK_EQ(thread_->GetState(), kNative);
+ thread_->SetState(kWaitingInMainDebuggerLoop);
/*
* Loop forever if we're in server mode, processing connections. In
@@ -334,7 +331,7 @@
*/
if (!(*transport_->establish)(this, options_)) {
/* wake anybody who was waiting for us to succeed */
- MutexLock mu(attach_lock_);
+ MutexLock mu(thread_, attach_lock_);
attach_cond_.Broadcast();
break;
}
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index 81941c0..16976d4 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -115,11 +115,8 @@
void Java_MyClassNatives_foo(JNIEnv* env, jobject thisObj) {
// 1 = thisObj
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- Locks::mutator_lock_->AssertNotHeld(Thread::Current());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
+ Locks::mutator_lock_->AssertNotHeld(Thread::Current());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -169,10 +166,7 @@
jint Java_MyClassNatives_fooI(JNIEnv* env, jobject thisObj, jint x) {
// 1 = thisObj
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -197,10 +191,7 @@
jint Java_MyClassNatives_fooII(JNIEnv* env, jobject thisObj, jint x, jint y) {
// 1 = thisObj
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -226,10 +217,7 @@
jlong Java_MyClassNatives_fooJJ(JNIEnv* env, jobject thisObj, jlong x, jlong y) {
// 1 = thisObj
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -256,10 +244,7 @@
jdouble Java_MyClassNatives_fooDD(JNIEnv* env, jobject thisObj, jdouble x, jdouble y) {
// 1 = thisObj
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -287,10 +272,7 @@
jlong Java_MyClassNatives_fooJJ_synchronized(JNIEnv* env, jobject thisObj, jlong x, jlong y) {
// 1 = thisObj
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -315,10 +297,7 @@
jobject z) {
// 3 = this + y + z
EXPECT_EQ(3U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(thisObj != NULL);
EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
@@ -368,10 +347,7 @@
jint Java_MyClassNatives_fooSII(JNIEnv* env, jclass klass, jint x, jint y) {
// 1 = klass
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(klass != NULL);
EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
@@ -393,10 +369,7 @@
jdouble Java_MyClassNatives_fooSDD(JNIEnv* env, jclass klass, jdouble x, jdouble y) {
// 1 = klass
EXPECT_EQ(1U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(klass != NULL);
EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
@@ -424,10 +397,7 @@
jobject z) {
// 3 = klass + y + z
EXPECT_EQ(3U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(klass != NULL);
EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
@@ -478,10 +448,7 @@
jobject Java_MyClassNatives_fooSSIOO(JNIEnv* env, jclass klass, jint x, jobject y, jobject z) {
// 3 = klass + y + z
EXPECT_EQ(3U, Thread::Current()->NumStackReferences());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- EXPECT_EQ(kNative, Thread::Current()->GetState());
- }
+ EXPECT_EQ(kNative, Thread::Current()->GetState());
EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
EXPECT_TRUE(klass != NULL);
EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 75ab1f0..22438a0 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -195,7 +195,7 @@
}
JavaVMExt* vm = soa.Vm();
IndirectReferenceTable& weak_globals = vm->weak_globals;
- MutexLock mu(vm->weak_globals_lock);
+ MutexLock mu(soa.Self(), vm->weak_globals_lock);
IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, obj);
return reinterpret_cast<jweak>(ref);
}
@@ -203,15 +203,27 @@
static void CheckMethodArguments(AbstractMethod* m, JValue* args)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
MethodHelper mh(m);
- ObjectArray<Class>* parameter_types = mh.GetParameterTypes();
- CHECK(parameter_types != NULL);
+ const DexFile::TypeList* params = mh.GetParameterTypeList();
+ if (params == NULL) {
+ return; // No arguments so nothing to check.
+ }
+ uint32_t num_params = params->Size();
size_t error_count = 0;
- for (int i = 0; i < parameter_types->GetLength(); ++i) {
- Class* parameter_type = parameter_types->Get(i);
- // TODO: check primitives are in range.
- if (!parameter_type->IsPrimitive()) {
+ for (uint32_t i = 0; i < num_params; i++) {
+ uint16_t type_idx = params->GetTypeItem(i).type_idx_;
+ Class* param_type = mh.GetClassFromTypeIdx(type_idx);
+ if (param_type == NULL) {
+ Thread* self = Thread::Current();
+ CHECK(self->IsExceptionPending());
+ LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: "
+ << mh.GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
+ << self->GetException()->Dump();
+ self->ClearException();
+ ++error_count;
+ } else if (!param_type->IsPrimitive()) {
+ // TODO: check primitives are in range.
Object* argument = args[i].GetL();
- if (argument != NULL && !argument->InstanceOf(parameter_type)) {
+ if (argument != NULL && !argument->InstanceOf(param_type)) {
LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
<< PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m);
++error_count;
@@ -382,14 +394,14 @@
static void PinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
JavaVMExt* vm = soa.Vm();
- MutexLock mu(vm->pins_lock);
+ MutexLock mu(soa.Self(), vm->pins_lock);
vm->pin_table.Add(array);
}
static void UnpinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
JavaVMExt* vm = soa.Vm();
- MutexLock mu(vm->pins_lock);
+ MutexLock mu(soa.Self(), vm->pins_lock);
vm->pin_table.Remove(array);
}
@@ -521,7 +533,7 @@
self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
bool okay;
{
- MutexLock mu(jni_on_load_lock_);
+ MutexLock mu(self, jni_on_load_lock_);
if (jni_on_load_thread_id_ == self->GetThinLockId()) {
// Check this so we don't end up waiting for ourselves. We need to return "true" so the
@@ -544,7 +556,7 @@
}
void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
- MutexLock mu(jni_on_load_lock_);
+ MutexLock mu(Thread::Current(), jni_on_load_lock_);
jni_on_load_result_ = result ? kOkay : kFailed;
jni_on_load_thread_id_ = 0;
@@ -836,7 +848,7 @@
JavaVMExt* vm = soa.Vm();
IndirectReferenceTable& globals = vm->globals;
Object* decoded_obj = soa.Decode<Object*>(obj);
- MutexLock mu(vm->globals_lock);
+ MutexLock mu(soa.Self(), vm->globals_lock);
IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
return reinterpret_cast<jobject>(ref);
}
@@ -848,7 +860,7 @@
ScopedObjectAccess soa(env);
JavaVMExt* vm = soa.Vm();
IndirectReferenceTable& globals = vm->globals;
- MutexLock mu(vm->globals_lock);
+ MutexLock mu(soa.Self(), vm->globals_lock);
if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
@@ -868,7 +880,7 @@
ScopedObjectAccess soa(env);
JavaVMExt* vm = soa.Vm();
IndirectReferenceTable& weak_globals = vm->weak_globals;
- MutexLock mu(vm->weak_globals_lock);
+ MutexLock mu(soa.Self(), vm->weak_globals_lock);
if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) {
LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
@@ -918,7 +930,7 @@
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
return NULL;
}
- return soa.AddLocalReference<jobject>(c->AllocObject());
+ return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
}
static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) {
@@ -935,7 +947,7 @@
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
return NULL;
}
- Object* result = c->AllocObject();
+ Object* result = c->AllocObject(soa.Self());
if (result == NULL) {
return NULL;
}
@@ -954,7 +966,7 @@
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
return NULL;
}
- Object* result = c->AllocObject();
+ Object* result = c->AllocObject(soa.Self());
if (result == NULL) {
return NULL;
}
@@ -1754,7 +1766,7 @@
static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
ScopedObjectAccess soa(env);
- String* result = String::AllocFromUtf16(char_count, chars);
+ String* result = String::AllocFromUtf16(soa.Self(), char_count, chars);
return soa.AddLocalReference<jstring>(result);
}
@@ -1763,7 +1775,7 @@
return NULL;
}
ScopedObjectAccess soa(env);
- String* result = String::AllocFromModifiedUtf8(utf);
+ String* result = String::AllocFromModifiedUtf8(soa.Self(), utf);
return soa.AddLocalReference<jstring>(result);
}
@@ -1923,7 +1935,7 @@
// Allocate and initialize if necessary.
Class* array_class = soa.Decode<Class*>(java_array_class.get());
- ObjectArray<Object>* result = ObjectArray<Object>::Alloc(array_class, length);
+ ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length);
if (initial_element != NULL) {
Object* initial_object = soa.Decode<Object*>(initial_element);
for (jsize i = 0; i < length; ++i) {
@@ -2297,7 +2309,7 @@
static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK_GE(length, 0); // TODO: ReportJniError
- ArtT* result = ArtT::Alloc(length);
+ ArtT* result = ArtT::Alloc(soa.Self(), length);
return soa.AddLocalReference<JniT>(result);
}
@@ -2762,16 +2774,17 @@
os << " (with forcecopy)";
}
os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off");
+ Thread* self = Thread::Current();
{
- MutexLock mu(pins_lock);
+ MutexLock mu(self, pins_lock);
os << "; pins=" << pin_table.Size();
}
{
- MutexLock mu(globals_lock);
+ MutexLock mu(self, globals_lock);
os << "; globals=" << globals.Capacity();
}
{
- MutexLock mu(weak_globals_lock);
+ MutexLock mu(self, weak_globals_lock);
if (weak_globals.Capacity() > 0) {
os << " (plus " << weak_globals.Capacity() << " weak)";
}
@@ -2779,22 +2792,23 @@
os << '\n';
{
- MutexLock mu(libraries_lock);
+ MutexLock mu(self, libraries_lock);
os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
}
}
void JavaVMExt::DumpReferenceTables(std::ostream& os) {
+ Thread* self = Thread::Current();
{
- MutexLock mu(globals_lock);
+ MutexLock mu(self, globals_lock);
globals.Dump(os);
}
{
- MutexLock mu(weak_globals_lock);
+ MutexLock mu(self, weak_globals_lock);
weak_globals.Dump(os);
}
{
- MutexLock mu(pins_lock);
+ MutexLock mu(self, pins_lock);
pin_table.Dump(os);
}
}
@@ -2808,9 +2822,10 @@
// TODO: for better results we should canonicalize the pathname (or even compare
// inodes). This implementation is fine if everybody is using System.loadLibrary.
SharedLibrary* library;
+ Thread* self = Thread::Current();
{
// TODO: move the locking (and more of this logic) into Libraries.
- MutexLock mu(libraries_lock);
+ MutexLock mu(self, libraries_lock);
library = libraries->Get(path);
}
if (library != NULL) {
@@ -2847,7 +2862,6 @@
// This can execute slowly for a large library on a busy system, so we
// want to switch from kRunnable while it executes. This allows the GC to ignore us.
- Thread* self = Thread::Current();
self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY);
self->TransitionFromSuspendedToRunnable();
@@ -2864,7 +2878,7 @@
// TODO: move the locking (and more of this logic) into Libraries.
bool created_library = false;
{
- MutexLock mu(libraries_lock);
+ MutexLock mu(self, libraries_lock);
library = libraries->Get(path);
if (library == NULL) { // We won race to get libraries_lock
library = new SharedLibrary(path, handle, class_loader);
@@ -2942,24 +2956,26 @@
std::string detail;
void* native_method;
+ Thread* self = Thread::Current();
{
- MutexLock mu(libraries_lock);
+ MutexLock mu(self, libraries_lock);
native_method = libraries->FindNativeMethod(m, detail);
}
// throwing can cause libraries_lock to be reacquired
if (native_method == NULL) {
- Thread::Current()->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
+ self->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
}
return native_method;
}
void JavaVMExt::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+ Thread* self = Thread::Current();
{
- MutexLock mu(globals_lock);
+ MutexLock mu(self, globals_lock);
globals.VisitRoots(visitor, arg);
}
{
- MutexLock mu(pins_lock);
+ MutexLock mu(self, pins_lock);
pin_table.VisitRoots(visitor, arg);
}
// The weak_globals table is visited by the GC itself (because it mutates the table).
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index bc1be28..d94da1e 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -93,7 +93,7 @@
: c->FindVirtualMethod(method_name, method_signature);
CHECK(method != NULL);
- receiver = (is_static ? NULL : c->AllocObject());
+ receiver = (is_static ? NULL : c->AllocObject(self));
AbstractMethod::InvokeStub* stub = method->GetInvokeStub();
CHECK(stub != NULL);
diff --git a/src/logging.cc b/src/logging.cc
index 48785c5..5680ed0 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -105,7 +105,7 @@
// Do the actual logging with the lock held.
{
- MutexLock mu(*Locks::logging_lock_);
+ MutexLock mu(Thread::Current(), *Locks::logging_lock_);
if (msg.find('\n') == std::string::npos) {
LogLine(msg.c_str());
} else {
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index e9056f5..96223a9 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -378,7 +378,7 @@
}
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
- MutexLock mu(vm->weak_globals_lock);
+ MutexLock mu(Thread::Current(), vm->weak_globals_lock);
IndirectReferenceTable* table = &vm->weak_globals;
typedef IndirectReferenceTable::iterator It; // TODO: C++0x auto
for (It it = table->begin(), end = table->end(); it != end; ++it) {
@@ -428,7 +428,7 @@
runtime->GetMonitorList()->SweepMonitorList(VerifyIsLiveCallback, this);
JavaVMExt* vm = runtime->GetJavaVM();
- MutexLock mu(vm->weak_globals_lock);
+ MutexLock mu(Thread::Current(), vm->weak_globals_lock);
IndirectReferenceTable* table = &vm->weak_globals;
typedef IndirectReferenceTable::iterator It; // TODO: C++0x auto
for (It it = table->begin(), end = table->end(); it != end; ++it) {
@@ -440,17 +440,18 @@
struct SweepCallbackContext {
MarkSweep* mark_sweep;
AllocSpace* space;
+ Thread* self;
};
void MarkSweep::SweepCallback(size_t num_ptrs, Object** ptrs, void* arg) {
- Locks::heap_bitmap_lock_->AssertExclusiveHeld(Thread::Current());
-
size_t freed_objects = num_ptrs;
size_t freed_bytes = 0;
SweepCallbackContext* context = static_cast<SweepCallbackContext*>(arg);
MarkSweep* mark_sweep = context->mark_sweep;
Heap* heap = mark_sweep->GetHeap();
AllocSpace* space = context->space;
+ Thread* self = context->self;
+ Locks::heap_bitmap_lock_->AssertExclusiveHeld(self);
// Use a bulk free, that merges consecutive objects before freeing or free per object?
// Documentation suggests better free performance with merging, but this may be at the expensive
// of allocation.
@@ -462,12 +463,12 @@
freed_bytes += space->AllocationSize(obj);
}
// AllocSpace::FreeList clears the value in ptrs, so perform after clearing the live bit
- space->FreeList(num_ptrs, ptrs);
+ space->FreeList(self, num_ptrs, ptrs);
} else {
for (size_t i = 0; i < num_ptrs; ++i) {
Object* obj = static_cast<Object*>(ptrs[i]);
freed_bytes += space->AllocationSize(obj);
- space->Free(obj);
+ space->Free(self, obj);
}
}
@@ -477,9 +478,8 @@
}
void MarkSweep::ZygoteSweepCallback(size_t num_ptrs, Object** ptrs, void* arg) {
- Locks::heap_bitmap_lock_->AssertExclusiveHeld(Thread::Current());
-
SweepCallbackContext* context = static_cast<SweepCallbackContext*>(arg);
+ Locks::heap_bitmap_lock_->AssertExclusiveHeld(context->self);
Heap* heap = context->mark_sweep->GetHeap();
// We don't free any actual memory to avoid dirtying the shared zygote pages.
for (size_t i = 0; i < num_ptrs; ++i) {
@@ -516,6 +516,7 @@
Object** out = objects;
// Empty the allocation stack.
+ Thread* self = Thread::Current();
for (size_t i = 0;i < count;++i) {
Object* obj = objects[i];
// There should only be objects in the AllocSpace/LargeObjectSpace in the allocation stack.
@@ -530,7 +531,7 @@
++freed_large_objects;
size_t size = large_object_space->AllocationSize(obj);
freed_bytes += size;
- large_object_space->Free(obj);
+ large_object_space->Free(self, obj);
}
}
logger.AddSplit("Process allocation stack");
@@ -538,7 +539,7 @@
size_t freed_objects = out - objects;
VLOG(heap) << "Freed " << freed_objects << "/" << count
<< " objects with size " << PrettySize(freed_bytes);
- space->FreeList(freed_objects, objects);
+ space->FreeList(self, freed_objects, objects);
heap_->RecordFree(freed_objects + freed_large_objects, freed_bytes);
freed_objects_ += freed_objects;
freed_bytes_ += freed_bytes;
@@ -557,6 +558,7 @@
const Spaces& spaces = heap_->GetSpaces();
SweepCallbackContext scc;
scc.mark_sweep = this;
+ scc.self = Thread::Current();
// TODO: C++0x auto
for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
ContinuousSpace* space = *it;
@@ -598,10 +600,11 @@
size_t freed_objects = 0;
size_t freed_bytes = 0;
// TODO: C++0x
+ Thread* self = Thread::Current();
for (SpaceSetMap::Objects::iterator it = live_objects.begin(); it != live_objects.end(); ++it) {
if (!large_mark_objects->Test(*it)) {
freed_bytes += large_object_space->AllocationSize(*it);
- large_object_space->Free(const_cast<Object*>(*it));
+ large_object_space->Free(self, const_cast<Object*>(*it));
++freed_objects;
}
}
diff --git a/src/monitor.cc b/src/monitor.cc
index c0484af..9890822 100644
--- a/src/monitor.cc
+++ b/src/monitor.cc
@@ -284,7 +284,7 @@
{
// TODO: isn't this too late to prevent threads from disappearing?
// Acquire thread list lock so threads won't disappear from under us.
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
// Re-read owner now that we hold lock.
current_owner = (monitor != NULL) ? monitor->owner_ : NULL;
// Get short descriptions of the threads involved.
@@ -427,7 +427,7 @@
ThrowIllegalMonitorStateExceptionF("object not locked by thread before wait()");
return;
}
- monitor_lock_.AssertHeld();
+ monitor_lock_.AssertHeld(self);
WaitWithLock(self, ms, ns, interruptShouldThrow);
}
@@ -476,7 +476,7 @@
bool wasInterrupted = false;
{
// Pseudo-atomically wait on self's wait_cond_ and release the monitor lock.
- MutexLock mu(*self->wait_mutex_);
+ MutexLock mu(self, *self->wait_mutex_);
// Set wait_monitor_ to the monitor object we will be waiting on. When wait_monitor_ is
// non-NULL a notifying or interrupting thread must signal the thread's wait_cond_ to wake it
@@ -538,7 +538,7 @@
* cleared when this exception is thrown."
*/
{
- MutexLock mu(*self->wait_mutex_);
+ MutexLock mu(self, *self->wait_mutex_);
self->interrupted_ = false;
}
if (interruptShouldThrow) {
@@ -554,11 +554,11 @@
ThrowIllegalMonitorStateExceptionF("object not locked by thread before notify()");
return;
}
- monitor_lock_.AssertHeld();
- NotifyWithLock();
+ monitor_lock_.AssertHeld(self);
+ NotifyWithLock(self);
}
-void Monitor::NotifyWithLock() {
+void Monitor::NotifyWithLock(Thread* self) {
// Signal the first waiting thread in the wait set.
while (wait_set_ != NULL) {
Thread* thread = wait_set_;
@@ -566,7 +566,7 @@
thread->wait_next_ = NULL;
// Check to see if the thread is still waiting.
- MutexLock mu(*thread->wait_mutex_);
+ MutexLock mu(self, *thread->wait_mutex_);
if (thread->wait_monitor_ != NULL) {
thread->wait_cond_->Signal();
return;
@@ -581,7 +581,7 @@
ThrowIllegalMonitorStateExceptionF("object not locked by thread before notifyAll()");
return;
}
- monitor_lock_.AssertHeld();
+ monitor_lock_.AssertHeld(self);
NotifyAllWithLock();
}
@@ -872,10 +872,7 @@
void Monitor::DescribeWait(std::ostream& os, const Thread* thread) {
ThreadState state;
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- state = thread->GetState();
- }
+ state = thread->GetState();
Object* object = NULL;
uint32_t lock_owner = ThreadList::kInvalidId;
@@ -883,7 +880,7 @@
os << " - waiting on ";
Monitor* monitor;
{
- MutexLock mu(*thread->wait_mutex_);
+ MutexLock mu(Thread::Current(), *thread->wait_mutex_);
monitor = thread->wait_monitor_;
}
if (monitor != NULL) {
@@ -1002,17 +999,17 @@
}
MonitorList::~MonitorList() {
- MutexLock mu(monitor_list_lock_);
+ MutexLock mu(Thread::Current(), monitor_list_lock_);
STLDeleteElements(&list_);
}
void MonitorList::Add(Monitor* m) {
- MutexLock mu(monitor_list_lock_);
+ MutexLock mu(Thread::Current(), monitor_list_lock_);
list_.push_front(m);
}
void MonitorList::SweepMonitorList(Heap::IsMarkedTester is_marked, void* arg) {
- MutexLock mu(monitor_list_lock_);
+ MutexLock mu(Thread::Current(), monitor_list_lock_);
typedef std::list<Monitor*>::iterator It; // TODO: C++0x auto
It it = list_.begin();
while (it != list_.end()) {
diff --git a/src/monitor.h b/src/monitor.h
index 4a62728..4277d2c 100644
--- a/src/monitor.h
+++ b/src/monitor.h
@@ -115,7 +115,7 @@
bool Unlock(Thread* thread, bool for_wait) UNLOCK_FUNCTION(monitor_lock_);
void Notify(Thread* self) NO_THREAD_SAFETY_ANALYSIS;
- void NotifyWithLock()
+ void NotifyWithLock(Thread* self)
EXCLUSIVE_LOCKS_REQUIRED(monitor_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/src/mutex.cc b/src/mutex.cc
index 522f849..96e04ef 100644
--- a/src/mutex.cc
+++ b/src/mutex.cc
@@ -196,7 +196,7 @@
if (rc != 0) {
errno = rc;
// TODO: should we just not log at all if shutting down? this could be the logging mutex!
- MutexLock mu(*Locks::runtime_shutdown_lock_);
+ MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_);
Runtime* runtime = Runtime::Current();
bool shutting_down = (runtime == NULL) || runtime->IsShuttingDown();
PLOG(shutting_down ? WARNING : FATAL) << "pthread_mutex_destroy failed for " << name_;
@@ -329,7 +329,7 @@
if (rc != 0) {
errno = rc;
// TODO: should we just not log at all if shutting down? this could be the logging mutex!
- MutexLock mu(*Locks::runtime_shutdown_lock_);
+ MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_);
Runtime* runtime = Runtime::Current();
bool shutting_down = runtime == NULL || runtime->IsShuttingDown();
PLOG(shutting_down ? WARNING : FATAL) << "pthread_rwlock_destroy failed for " << name_;
@@ -586,7 +586,7 @@
int rc = pthread_cond_destroy(&cond_);
if (rc != 0) {
errno = rc;
- MutexLock mu(*Locks::runtime_shutdown_lock_);
+ MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_);
Runtime* runtime = Runtime::Current();
bool shutting_down = (runtime == NULL) || runtime->IsShuttingDown();
PLOG(shutting_down ? WARNING : FATAL) << "pthread_cond_destroy failed for " << name_;
diff --git a/src/mutex.h b/src/mutex.h
index 32aeaf9..d51e2cc 100644
--- a/src/mutex.h
+++ b/src/mutex.h
@@ -25,8 +25,8 @@
#include "globals.h"
#include "locks.h"
+#include "logging.h"
#include "macros.h"
-#include "thread.h"
#if defined(__APPLE__)
#define ART_USE_FUTEXES 0
@@ -43,6 +43,8 @@
namespace art {
+class Thread;
+
const bool kDebugLocking = kIsDebugBuild;
// Base class for all Mutex implementations
@@ -110,7 +112,6 @@
}
}
void AssertHeld(const Thread* self) { AssertExclusiveHeld(self); }
- void AssertHeld() { AssertExclusiveHeld(Thread::Current()); }
// Assert that the Mutex is not held by the current thread.
void AssertNotHeldExclusive(const Thread* self) {
@@ -275,10 +276,6 @@
mu_.ExclusiveLock(self_);
}
- explicit MutexLock(Mutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : self_(Thread::Current()), mu_(mu) {
- mu_.ExclusiveLock(self_);
- }
-
~MutexLock() UNLOCK_FUNCTION() {
mu_.ExclusiveUnlock(self_);
}
@@ -300,11 +297,6 @@
mu_.SharedLock(self_);
}
- explicit ReaderMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
- self_(Thread::Current()), mu_(mu) {
- mu_.SharedLock(self_);
- }
-
~ReaderMutexLock() UNLOCK_FUNCTION() {
mu_.SharedUnlock(self_);
}
@@ -327,17 +319,12 @@
mu_.ExclusiveLock(self_);
}
- explicit WriterMutexLock(ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
- self_(Thread::Current()), mu_(mu) {
- mu_.ExclusiveLock(self_);
- }
-
~WriterMutexLock() UNLOCK_FUNCTION() {
mu_.ExclusiveUnlock(self_);
}
private:
- Thread* self_;
+ Thread* const self_;
ReaderWriterMutex& mu_;
DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
};
diff --git a/src/native/dalvik_system_VMRuntime.cc b/src/native/dalvik_system_VMRuntime.cc
index 7184e48..91b7b5f 100644
--- a/src/native/dalvik_system_VMRuntime.cc
+++ b/src/native/dalvik_system_VMRuntime.cc
@@ -54,11 +54,11 @@
Class* element_class = soa.Decode<Class*>(javaElementClass);
if (element_class == NULL) {
- Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", "element class == null");
+ soa.Self()->ThrowNewException("Ljava/lang/NullPointerException;", "element class == null");
return NULL;
}
if (length < 0) {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", length);
+ soa.Self()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", length);
return NULL;
}
@@ -67,7 +67,7 @@
descriptor += "[";
descriptor += ClassHelper(element_class).GetDescriptor();
Class* array_class = class_linker->FindClass(descriptor.c_str(), NULL);
- Array* result = Array::Alloc(array_class, length);
+ Array* result = Array::Alloc(soa.Self(), array_class, length);
if (result == NULL) {
return NULL;
}
@@ -81,7 +81,7 @@
ScopedObjectAccess soa(env);
Array* array = soa.Decode<Array*>(javaArray);
if (!array->IsArrayInstance()) {
- Thread::Current()->ThrowNewException("Ljava/lang/IllegalArgumentException;", "not an array");
+ soa.Self()->ThrowNewException("Ljava/lang/IllegalArgumentException;", "not an array");
return 0;
}
// TODO: we should also check that this is a non-movable array.
@@ -127,7 +127,7 @@
}
#endif
-static void VMRuntime_setTargetSdkVersion(JNIEnv*, jobject, jint targetSdkVersion) {
+static void VMRuntime_setTargetSdkVersion(JNIEnv* env, jobject, jint targetSdkVersion) {
// This is the target SDK version of the app we're about to run.
// Note that targetSdkVersion may be CUR_DEVELOPMENT (10000).
// Note that targetSdkVersion may be 0, meaning "current".
@@ -138,7 +138,8 @@
#if !defined(ART_USE_LLVM_COMPILER)
if (vm->check_jni) {
LOG(WARNING) << "Turning off CheckJNI so we can turn on JNI app bug workarounds...";
- MutexLock mu(*Locks::thread_list_lock_);
+ Thread* self = static_cast<JNIEnvExt*>(env)->self;
+ MutexLock mu(self, *Locks::thread_list_lock_);
vm->SetCheckJniEnabled(false);
runtime->GetThreadList()->ForEach(DisableCheckJniCallback, NULL);
}
@@ -148,6 +149,7 @@
vm->work_around_app_jni_bugs = true;
#else
+ UNUSED(env);
LOG(WARNING) << "LLVM does not work-around app jni bugs.";
vm->work_around_app_jni_bugs = false;
#endif
diff --git a/src/native/java_lang_Class.cc b/src/native/java_lang_Class.cc
index c023b7e..488df80 100644
--- a/src/native/java_lang_Class.cc
+++ b/src/native/java_lang_Class.cc
@@ -199,7 +199,8 @@
AbstractMethod* m = c->GetVirtualMethod(i);
mh.ChangeMethod(m);
if (IsVisibleMethod(m, publicOnly)) {
- if (mh.GetReturnType() == NULL || mh.GetParameterTypes() == NULL) {
+ // TODO: the use of GetParameterTypes creates an unused array here.
+ if (mh.GetReturnType() == NULL || mh.GetParameterTypes(soa.Self()) == NULL) {
DCHECK(env->ExceptionOccurred());
return NULL;
}
@@ -213,7 +214,8 @@
AbstractMethod* m = c->GetDirectMethod(i);
mh.ChangeMethod(m);
if (IsVisibleMethod(m, publicOnly)) {
- if (mh.GetReturnType() == NULL || mh.GetParameterTypes() == NULL) {
+ // TODO: the use of GetParameterTypes creates an unused array here.
+ if (mh.GetReturnType() == NULL || mh.GetParameterTypes(soa.Self()) == NULL) {
DCHECK(env->ExceptionOccurred());
return NULL;
}
@@ -349,7 +351,7 @@
static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
SynthesizedProxyClass* c = down_cast<SynthesizedProxyClass*>(DecodeClass(soa, javaThis));
- return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone());
+ return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone(soa.Self()));
}
static jboolean Class_isAssignableFrom(JNIEnv* env, jobject javaLhs, jclass javaRhs) {
@@ -412,7 +414,7 @@
return NULL;
}
- Object* new_obj = c->AllocObject();
+ Object* new_obj = c->AllocObject(soa.Self());
if (new_obj == NULL) {
DCHECK(soa.Self()->IsExceptionPending());
return NULL;
diff --git a/src/native/java_lang_Object.cc b/src/native/java_lang_Object.cc
index 89019f7..a6ae49d 100644
--- a/src/native/java_lang_Object.cc
+++ b/src/native/java_lang_Object.cc
@@ -23,7 +23,7 @@
static jobject Object_internalClone(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
Object* o = soa.Decode<Object*>(javaThis);
- return soa.AddLocalReference<jobject>(o->Clone());
+ return soa.AddLocalReference<jobject>(o->Clone(soa.Self()));
}
static void Object_notify(JNIEnv* env, jobject javaThis) {
diff --git a/src/native/java_lang_Thread.cc b/src/native/java_lang_Thread.cc
index edf55c3..cf475e2 100644
--- a/src/native/java_lang_Thread.cc
+++ b/src/native/java_lang_Thread.cc
@@ -34,7 +34,7 @@
static jboolean Thread_isInterrupted(JNIEnv* env, jobject java_thread) {
ScopedObjectAccess soa(env);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, java_thread);
return (thread != NULL) ? thread->IsInterrupted() : JNI_FALSE;
}
@@ -55,10 +55,9 @@
ScopedObjectAccess soa(env);
ThreadState internal_thread_state = (has_been_started ? kTerminated : kStarting);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, java_thread);
if (thread != NULL) {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
internal_thread_state = thread->GetState();
}
switch (internal_thread_state) {
@@ -91,7 +90,7 @@
Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", "object == null");
return JNI_FALSE;
}
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, java_thread);
return thread->HoldsLock(object);
}
@@ -138,7 +137,7 @@
*/
static void Thread_nativeSetPriority(JNIEnv* env, jobject java_thread, jint new_priority) {
ScopedObjectAccess soa(env);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, java_thread);
if (thread != NULL) {
thread->SetNativePriority(new_priority);
diff --git a/src/native/java_lang_reflect_Array.cc b/src/native/java_lang_reflect_Array.cc
index d3a57bf..863f9fc 100644
--- a/src/native/java_lang_reflect_Array.cc
+++ b/src/native/java_lang_reflect_Array.cc
@@ -29,7 +29,7 @@
IntArray* dimensions)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
int32_t array_length = dimensions->Get(current_dimension++);
- SirtRef<Array> new_array(self, Array::Alloc(array_class, array_length));
+ SirtRef<Array> new_array(self, Array::Alloc(self, array_class, array_length));
if (new_array.get() == NULL) {
CHECK(self->IsExceptionPending());
return NULL;
@@ -139,7 +139,7 @@
return NULL;
}
DCHECK(array_class->IsArrayClass());
- Array* new_array = Array::Alloc(array_class, length);
+ Array* new_array = Array::Alloc(soa.Self(), array_class, length);
if (new_array == NULL) {
CHECK(soa.Self()->IsExceptionPending());
return NULL;
diff --git a/src/native/java_lang_reflect_Constructor.cc b/src/native/java_lang_reflect_Constructor.cc
index 44b459d..ed0d1f1 100644
--- a/src/native/java_lang_reflect_Constructor.cc
+++ b/src/native/java_lang_reflect_Constructor.cc
@@ -45,7 +45,7 @@
return NULL;
}
- Object* receiver = c->AllocObject();
+ Object* receiver = c->AllocObject(soa.Self());
if (receiver == NULL) {
return NULL;
}
diff --git a/src/native/java_lang_reflect_Method.cc b/src/native/java_lang_reflect_Method.cc
index 63a277b..b1eb6e0 100644
--- a/src/native/java_lang_reflect_Method.cc
+++ b/src/native/java_lang_reflect_Method.cc
@@ -44,7 +44,7 @@
}
CHECK_NE(throws_index, -1);
ObjectArray<Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index);
- return soa.AddLocalReference<jobject>(declared_exceptions->Clone());
+ return soa.AddLocalReference<jobject>(declared_exceptions->Clone(soa.Self()));
}
static jobject Method_findOverriddenMethodNative(JNIEnv* env, jobject javaMethod) {
diff --git a/src/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc b/src/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc
index 66c27e4..0ed964b 100644
--- a/src/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc
+++ b/src/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc
@@ -39,7 +39,7 @@
return Dbg::IsAllocTrackingEnabled();
}
-static jobject FindThreadByThinLockId(JNIEnv*, uint32_t thin_lock_id) {
+static jobject FindThreadByThinLockId(JNIEnv* env, uint32_t thin_lock_id) {
struct ThreadFinder {
explicit ThreadFinder(uint32_t thin_lock_id) : thin_lock_id(thin_lock_id), thread(NULL) {
}
@@ -56,7 +56,8 @@
};
ThreadFinder finder(thin_lock_id);
{
- MutexLock mu(*Locks::thread_list_lock_);
+ Thread* self = static_cast<JNIEnvExt*>(env)->self;
+ MutexLock mu(self, *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(ThreadFinder::Callback, &finder);
}
if (finder.thread != NULL) {
@@ -133,10 +134,7 @@
std::vector<uint8_t>& bytes = *reinterpret_cast<std::vector<uint8_t>*>(context);
JDWP::Append4BE(bytes, t->GetThinLockId());
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- JDWP::Append1BE(bytes, t->GetState());
- }
+ JDWP::Append1BE(bytes, t->GetState());
JDWP::Append4BE(bytes, t->GetTid());
JDWP::Append4BE(bytes, utime);
JDWP::Append4BE(bytes, stime);
@@ -145,8 +143,9 @@
static jbyteArray DdmVmInternal_getThreadStats(JNIEnv* env, jclass) {
std::vector<uint8_t> bytes;
+ Thread* self = static_cast<JNIEnvExt*>(env)->self;
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(self, *Locks::thread_list_lock_);
ThreadList* thread_list = Runtime::Current()->GetThreadList();
uint16_t thread_count = 0;
diff --git a/src/oat/runtime/arm/stub_arm.cc b/src/oat/runtime/arm/stub_arm.cc
index 7add255..4099ddb 100644
--- a/src/oat/runtime/arm/stub_arm.cc
+++ b/src/oat/runtime/arm/stub_arm.cc
@@ -82,7 +82,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> resolution_trampoline(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> resolution_trampoline(self, ByteArray::Alloc(self, cs));
CHECK(resolution_trampoline.get() != NULL);
MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
assembler->FinalizeInstructions(code);
@@ -128,7 +129,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> abstract_stub(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> abstract_stub(self, ByteArray::Alloc(self, cs));
CHECK(abstract_stub.get() != NULL);
MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
assembler->FinalizeInstructions(code);
@@ -156,7 +158,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> jni_stub(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> jni_stub(self, ByteArray::Alloc(self, 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 d545e4a..9691308 100644
--- a/src/oat/runtime/mips/stub_mips.cc
+++ b/src/oat/runtime/mips/stub_mips.cc
@@ -112,7 +112,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> resolution_trampoline(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> resolution_trampoline(self, ByteArray::Alloc(self, cs));
CHECK(resolution_trampoline.get() != NULL);
MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
assembler->FinalizeInstructions(code);
@@ -157,7 +158,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> abstract_stub(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> abstract_stub(self, ByteArray::Alloc(self, cs));
CHECK(abstract_stub.get() != NULL);
MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
assembler->FinalizeInstructions(code);
@@ -197,7 +199,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> jni_stub(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> jni_stub(self, ByteArray::Alloc(self, cs));
CHECK(jni_stub.get() != NULL);
MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
assembler->FinalizeInstructions(code);
diff --git a/src/oat/runtime/support_alloc.cc b/src/oat/runtime/support_alloc.cc
index fd7fb65..fb70285 100644
--- a/src/oat/runtime/support_alloc.cc
+++ b/src/oat/runtime/support_alloc.cc
@@ -37,7 +37,7 @@
Thread* self, AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- return AllocArrayFromCode(type_idx, method, component_count, false);
+ return AllocArrayFromCode(type_idx, method, component_count, self, false);
}
extern "C" Array* artAllocArrayFromCodeWithAccessCheck(uint32_t type_idx, AbstractMethod* method,
@@ -45,7 +45,7 @@
Thread* self, AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- return AllocArrayFromCode(type_idx, method, component_count, true);
+ return AllocArrayFromCode(type_idx, method, component_count, self, true);
}
extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, AbstractMethod* method,
diff --git a/src/oat/runtime/support_proxy.cc b/src/oat/runtime/support_proxy.cc
index 4ff2e5f..3d0c1c8 100644
--- a/src/oat/runtime/support_proxy.cc
+++ b/src/oat/runtime/support_proxy.cc
@@ -104,7 +104,7 @@
args_jobj[2].l = NULL;
ObjectArray<Object>* args = NULL;
if ((num_params - 1) > 0) {
- args = Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(num_params - 1);
+ args = Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(self, num_params - 1);
if (args == NULL) {
CHECK(self->IsExceptionPending());
return;
@@ -120,7 +120,7 @@
cur_arg = 0; // reset stack location to read to start
// reset index, will index into param type array which doesn't include the receiver
param_index = 0;
- ObjectArray<Class>* param_types = proxy_mh.GetParameterTypes();
+ ObjectArray<Class>* param_types = proxy_mh.GetParameterTypes(self);
if (param_types == NULL) {
CHECK(self->IsExceptionPending());
return;
diff --git a/src/oat/runtime/x86/stub_x86.cc b/src/oat/runtime/x86/stub_x86.cc
index 7941d15..cade99d 100644
--- a/src/oat/runtime/x86/stub_x86.cc
+++ b/src/oat/runtime/x86/stub_x86.cc
@@ -92,7 +92,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> resolution_trampoline(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> resolution_trampoline(self, ByteArray::Alloc(self, cs));
CHECK(resolution_trampoline.get() != NULL);
MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
assembler->FinalizeInstructions(code);
@@ -146,7 +147,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> abstract_stub(Thread::Current(),ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> abstract_stub(self, ByteArray::Alloc(self, cs));
CHECK(abstract_stub.get() != NULL);
MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
assembler->FinalizeInstructions(code);
@@ -179,7 +181,8 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
- SirtRef<ByteArray> jni_stub(Thread::Current(), ByteArray::Alloc(cs));
+ Thread* self = Thread::Current();
+ SirtRef<ByteArray> jni_stub(self, ByteArray::Alloc(self, cs));
CHECK(jni_stub.get() != NULL);
MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
assembler->FinalizeInstructions(code);
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 7e14199..01b2042 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -575,11 +575,12 @@
// Loop through all the image spaces and dump their objects.
Heap* heap = Runtime::Current()->GetHeap();
const Spaces& spaces = heap->GetSpaces();
+ Thread* self = Thread::Current();
{
- WriterMutexLock mu(*Locks::heap_bitmap_lock_);
+ WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
heap->FlushAllocStack();
}
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
// TODO: C++0x auto
for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
Space* space = *it;
diff --git a/src/object.cc b/src/object.cc
index 8582a21..e8381db 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -47,7 +47,7 @@
return down_cast<String*>(this);
}
-Object* Object::Clone() {
+Object* Object::Clone(Thread* self) {
Class* c = GetClass();
DCHECK(!c->IsClassClass());
@@ -55,7 +55,7 @@
// Using c->AllocObject() here would be wrong.
size_t num_bytes = SizeOf();
Heap* heap = Runtime::Current()->GetHeap();
- SirtRef<Object> copy(Thread::Current(), heap->AllocObject(c, num_bytes));
+ SirtRef<Object> copy(self, heap->AllocObject(self, c, num_bytes));
if (copy.get() == NULL) {
return NULL;
}
@@ -727,13 +727,13 @@
SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
}
-Object* Class::AllocObject() {
+Object* Class::AllocObject(Thread* self) {
DCHECK(!IsArrayClass()) << PrettyClass(this);
DCHECK(IsInstantiable()) << PrettyClass(this);
// TODO: decide whether we want this check. It currently fails during bootstrap.
// DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
DCHECK_GE(this->object_size_, sizeof(Object));
- return Runtime::Current()->GetHeap()->AllocObject(this, this->object_size_);
+ return Runtime::Current()->GetHeap()->AllocObject(self, this, this->object_size_);
}
void Class::SetClassSize(size_t new_class_size) {
@@ -768,7 +768,7 @@
default:
LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
}
- name = String::AllocFromModifiedUtf8(c_name);
+ name = String::AllocFromModifiedUtf8(Thread::Current(), c_name);
} else {
// Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package
// components.
@@ -777,7 +777,7 @@
descriptor.erase(descriptor.size() - 1);
}
std::replace(descriptor.begin(), descriptor.end(), '/', '.');
- name = String::AllocFromModifiedUtf8(descriptor.c_str());
+ name = String::AllocFromModifiedUtf8(Thread::Current(), descriptor.c_str());
}
SetName(name);
return name;
@@ -1288,7 +1288,8 @@
return NULL;
}
-Array* Array::Alloc(Class* array_class, int32_t component_count, size_t component_size) {
+Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count,
+ size_t component_size) {
DCHECK(array_class != NULL);
DCHECK_GE(component_count, 0);
DCHECK(array_class->IsArrayClass());
@@ -1300,14 +1301,14 @@
// Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
size_t component_shift = sizeof(size_t) * 8 - 1 - CLZ(component_size);
if (data_size >> component_shift != size_t(component_count) || size < data_size) {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/OutOfMemoryError;",
+ self->ThrowNewExceptionF("Ljava/lang/OutOfMemoryError;",
"%s of length %d would overflow",
PrettyDescriptor(array_class).c_str(), component_count);
return NULL;
}
Heap* heap = Runtime::Current()->GetHeap();
- Array* array = down_cast<Array*>(heap->AllocObject(array_class, size));
+ Array* array = down_cast<Array*>(heap->AllocObject(self, array_class, size));
if (array != NULL) {
DCHECK(array->IsArrayInstance());
array->SetLength(component_count);
@@ -1315,9 +1316,9 @@
return array;
}
-Array* Array::Alloc(Class* array_class, int32_t component_count) {
+Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count) {
DCHECK(array_class->IsArrayClass());
- return Alloc(array_class, component_count, array_class->GetComponentSize());
+ return Alloc(self, array_class, component_count, array_class->GetComponentSize());
}
bool Array::ThrowArrayIndexOutOfBoundsException(int32_t index) const {
@@ -1334,9 +1335,9 @@
}
template<typename T>
-PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
+PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
DCHECK(array_class_ != NULL);
- Array* raw_array = Array::Alloc(array_class_, length, sizeof(T));
+ Array* raw_array = Array::Alloc(self, array_class_, length, sizeof(T));
return down_cast<PrimitiveArray<T>*>(raw_array);
}
@@ -1402,11 +1403,12 @@
return GetCharArray()->Get(index + GetOffset());
}
-String* String::AllocFromUtf16(int32_t utf16_length,
+String* String::AllocFromUtf16(Thread* self,
+ int32_t utf16_length,
const uint16_t* utf16_data_in,
int32_t hash_code) {
CHECK(utf16_data_in != NULL || utf16_length == 0);
- String* string = Alloc(GetJavaLangString(), utf16_length);
+ String* string = Alloc(self, GetJavaLangString(), utf16_length);
if (string == NULL) {
return NULL;
}
@@ -1426,17 +1428,17 @@
return string;
}
-String* String::AllocFromModifiedUtf8(const char* utf) {
+ String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
if (utf == NULL) {
return NULL;
}
size_t char_count = CountModifiedUtf8Chars(utf);
- return AllocFromModifiedUtf8(char_count, utf);
+ return AllocFromModifiedUtf8(self, char_count, utf);
}
-String* String::AllocFromModifiedUtf8(int32_t utf16_length,
+String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
const char* utf8_data_in) {
- String* string = Alloc(GetJavaLangString(), utf16_length);
+ String* string = Alloc(self, GetJavaLangString(), utf16_length);
if (string == NULL) {
return NULL;
}
@@ -1447,18 +1449,18 @@
return string;
}
-String* String::Alloc(Class* java_lang_String, int32_t utf16_length) {
- SirtRef<CharArray> array(Thread::Current(), CharArray::Alloc(utf16_length));
+String* String::Alloc(Thread* self, Class* java_lang_String, int32_t utf16_length) {
+ SirtRef<CharArray> array(self, CharArray::Alloc(self, utf16_length));
if (array.get() == NULL) {
return NULL;
}
- return Alloc(java_lang_String, array.get());
+ return Alloc(self, java_lang_String, array.get());
}
-String* String::Alloc(Class* java_lang_String, CharArray* array) {
+String* String::Alloc(Thread* self, Class* java_lang_String, CharArray* array) {
// Hold reference in case AllocObject causes GC.
- SirtRef<CharArray> array_ref(Thread::Current(), array);
- String* string = down_cast<String*>(java_lang_String->AllocObject());
+ SirtRef<CharArray> array_ref(self, array);
+ String* string = down_cast<String*>(java_lang_String->AllocObject(self));
if (string == NULL) {
return NULL;
}
@@ -1610,12 +1612,13 @@
java_lang_StackTraceElement_ = NULL;
}
-StackTraceElement* StackTraceElement::Alloc(String* declaring_class,
+StackTraceElement* StackTraceElement::Alloc(Thread* self,
+ String* declaring_class,
String* method_name,
String* file_name,
int32_t line_number) {
StackTraceElement* trace =
- down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject());
+ down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject(self));
trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_),
const_cast<String*>(declaring_class), false);
trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_),
diff --git a/src/object.h b/src/object.h
index 5fccb04..baa7313 100644
--- a/src/object.h
+++ b/src/object.h
@@ -177,7 +177,7 @@
size_t SizeOf() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* Clone() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
int32_t IdentityHashCode() const {
#ifdef MOVING_GARBAGE_COLLECTOR
@@ -1054,10 +1054,11 @@
public:
// A convenience for code that doesn't know the component size,
// and doesn't want to have to work it out itself.
- static Array* Alloc(Class* array_class, int32_t component_count)
+ static Array* Alloc(Thread* self, Class* array_class, int32_t component_count)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static Array* Alloc(Class* array_class, int32_t component_count, size_t component_size)
+ static Array* Alloc(Thread* self, Class* array_class, int32_t component_count,
+ size_t component_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
size_t SizeOf() const;
@@ -1121,7 +1122,7 @@
template<class T>
class MANAGED ObjectArray : public Array {
public:
- static ObjectArray<T>* Alloc(Class* object_array_class, int32_t length)
+ static ObjectArray<T>* Alloc(Thread* self, Class* object_array_class, int32_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
T* Get(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -1139,7 +1140,7 @@
size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ObjectArray<T>* CopyOf(int32_t new_length)
+ ObjectArray<T>* CopyOf(Thread* self, int32_t new_length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
private:
@@ -1147,8 +1148,8 @@
};
template<class T>
-ObjectArray<T>* ObjectArray<T>::Alloc(Class* object_array_class, int32_t length) {
- Array* array = Array::Alloc(object_array_class, length, sizeof(Object*));
+ObjectArray<T>* ObjectArray<T>::Alloc(Thread* self, Class* object_array_class, int32_t length) {
+ Array* array = Array::Alloc(self, object_array_class, length, sizeof(Object*));
if (UNLIKELY(array == NULL)) {
return NULL;
} else {
@@ -1166,8 +1167,8 @@
}
template<class T>
-ObjectArray<T>* ObjectArray<T>::CopyOf(int32_t new_length) {
- ObjectArray<T>* new_array = Alloc(GetClass(), new_length);
+ObjectArray<T>* ObjectArray<T>::CopyOf(Thread* self, int32_t new_length) {
+ ObjectArray<T>* new_array = Alloc(self, GetClass(), new_length);
Copy(this, 0, new_array, 0, std::min(GetLength(), new_length));
return new_array;
}
@@ -1450,7 +1451,7 @@
}
// Creates a raw object instance but does not invoke the default constructor.
- Object* AllocObject() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Object* AllocObject(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsVariableSize() const {
// Classes and arrays vary in size, and so the object_size_ field cannot
@@ -2282,7 +2283,7 @@
public:
typedef T ElementType;
- static PrimitiveArray<T>* Alloc(size_t length)
+ static PrimitiveArray<T>* Alloc(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const T* GetData() const {
@@ -2370,22 +2371,23 @@
String* Intern() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static String* AllocFromUtf16(int32_t utf16_length,
+ static String* AllocFromUtf16(Thread* self,
+ int32_t utf16_length,
const uint16_t* utf16_data_in,
int32_t hash_code = 0)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static String* AllocFromModifiedUtf8(const char* utf)
+ static String* AllocFromModifiedUtf8(Thread* self, const char* utf)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static String* AllocFromModifiedUtf8(int32_t utf16_length,
+ static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
const char* utf8_data_in)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static String* Alloc(Class* java_lang_String, int32_t utf16_length)
+ static String* Alloc(Thread* self, Class* java_lang_String, int32_t utf16_length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static String* Alloc(Class* java_lang_String, CharArray* array)
+ static String* Alloc(Thread* self, Class* java_lang_String, CharArray* array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool Equals(const char* modified_utf8) const
@@ -2617,7 +2619,8 @@
OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_), false);
}
- static StackTraceElement* Alloc(String* declaring_class,
+ static StackTraceElement* Alloc(Thread* self,
+ String* declaring_class,
String* method_name,
String* file_name,
int32_t line_number)
diff --git a/src/object_test.cc b/src/object_test.cc
index f28c20b..9ad0534 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -44,7 +44,8 @@
utf16_expected[i] = ch;
}
- SirtRef<String> string(Thread::Current(), String::AllocFromModifiedUtf8(length, utf8_in));
+ Thread* self = Thread::Current();
+ SirtRef<String> string(self, String::AllocFromModifiedUtf8(self, length, utf8_in));
ASSERT_EQ(length, string->GetLength());
ASSERT_TRUE(string->GetCharArray() != NULL);
ASSERT_TRUE(string->GetCharArray()->GetData() != NULL);
@@ -77,16 +78,18 @@
TEST_F(ObjectTest, Clone) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<ObjectArray<Object> > a1(soa.Self(), class_linker_->AllocObjectArray<Object>(256));
+ SirtRef<ObjectArray<Object> > a1(soa.Self(),
+ class_linker_->AllocObjectArray<Object>(soa.Self(), 256));
size_t s1 = a1->SizeOf();
- Object* clone = a1->Clone();
+ Object* clone = a1->Clone(soa.Self());
EXPECT_EQ(s1, clone->SizeOf());
EXPECT_TRUE(clone->GetClass() == a1->GetClass());
}
TEST_F(ObjectTest, AllocObjectArray) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<ObjectArray<Object> > oa(soa.Self(), class_linker_->AllocObjectArray<Object>(2));
+ SirtRef<ObjectArray<Object> > oa(soa.Self(),
+ class_linker_->AllocObjectArray<Object>(soa.Self(), 2));
EXPECT_EQ(2, oa->GetLength());
EXPECT_TRUE(oa->Get(0) == NULL);
EXPECT_TRUE(oa->Get(1) == NULL);
@@ -119,15 +122,15 @@
TEST_F(ObjectTest, AllocArray) {
ScopedObjectAccess soa(Thread::Current());
Class* c = class_linker_->FindSystemClass("[I");
- SirtRef<Array> a(soa.Self(), Array::Alloc(c, 1));
+ SirtRef<Array> a(soa.Self(), Array::Alloc(soa.Self(), c, 1));
ASSERT_TRUE(c == a->GetClass());
c = class_linker_->FindSystemClass("[Ljava/lang/Object;");
- a.reset(Array::Alloc(c, 1));
+ a.reset(Array::Alloc(soa.Self(), c, 1));
ASSERT_TRUE(c == a->GetClass());
c = class_linker_->FindSystemClass("[[Ljava/lang/Object;");
- a.reset(Array::Alloc(c, 1));
+ a.reset(Array::Alloc(soa.Self(), c, 1));
ASSERT_TRUE(c == a->GetClass());
}
@@ -136,7 +139,7 @@
ScopedObjectAccess soa(Thread::Current());
typedef typename ArrayT::ElementType T;
- ArrayT* a = ArrayT::Alloc(2);
+ ArrayT* a = ArrayT::Alloc(soa.Self(), 2);
EXPECT_EQ(2, a->GetLength());
EXPECT_EQ(0, a->Get(0));
EXPECT_EQ(0, a->Get(1));
@@ -238,7 +241,7 @@
Object* s0 = field->GetObj(NULL);
EXPECT_EQ(NULL, s0);
- SirtRef<CharArray> char_array(soa.Self(), CharArray::Alloc(0));
+ SirtRef<CharArray> char_array(soa.Self(), CharArray::Alloc(soa.Self(), 0));
field->SetObj(NULL, char_array.get());
EXPECT_EQ(char_array.get(), field->GetObj(NULL));
@@ -274,7 +277,7 @@
TEST_F(ObjectTest, StringEqualsUtf8) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8("android"));
+ SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
EXPECT_TRUE(string->Equals("android"));
EXPECT_FALSE(string->Equals("Android"));
EXPECT_FALSE(string->Equals("ANDROID"));
@@ -282,15 +285,15 @@
EXPECT_FALSE(string->Equals("and"));
EXPECT_FALSE(string->Equals("androids"));
- SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(""));
+ SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
EXPECT_TRUE(empty->Equals(""));
EXPECT_FALSE(empty->Equals("a"));
}
TEST_F(ObjectTest, StringEquals) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8("android"));
- SirtRef<String> string_2(soa.Self(), String::AllocFromModifiedUtf8("android"));
+ SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
+ SirtRef<String> string_2(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
EXPECT_TRUE(string->Equals(string_2.get()));
EXPECT_FALSE(string->Equals("Android"));
EXPECT_FALSE(string->Equals("ANDROID"));
@@ -298,14 +301,14 @@
EXPECT_FALSE(string->Equals("and"));
EXPECT_FALSE(string->Equals("androids"));
- SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(""));
+ SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
EXPECT_TRUE(empty->Equals(""));
EXPECT_FALSE(empty->Equals("a"));
}
TEST_F(ObjectTest, StringLength) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8("android"));
+ SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
EXPECT_EQ(string->GetLength(), 7);
EXPECT_EQ(string->GetUtfLength(), 7);
@@ -380,9 +383,9 @@
TEST_F(ObjectTest, StringHashCode) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(""));
- SirtRef<String> A(soa.Self(), String::AllocFromModifiedUtf8("A"));
- SirtRef<String> ABC(soa.Self(), String::AllocFromModifiedUtf8("ABC"));
+ SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
+ SirtRef<String> A(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "A"));
+ SirtRef<String> ABC(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "ABC"));
EXPECT_EQ(0, empty->GetHashCode());
EXPECT_EQ(65, A->GetHashCode());
@@ -399,8 +402,8 @@
ASSERT_TRUE(X != NULL);
ASSERT_TRUE(Y != NULL);
- SirtRef<Object> x(soa.Self(), X->AllocObject());
- SirtRef<Object> y(soa.Self(), Y->AllocObject());
+ SirtRef<Object> x(soa.Self(), X->AllocObject(soa.Self()));
+ SirtRef<Object> y(soa.Self(), Y->AllocObject(soa.Self()));
ASSERT_TRUE(x.get() != NULL);
ASSERT_TRUE(y.get() != NULL);
@@ -416,7 +419,7 @@
EXPECT_TRUE(Object_array_class->InstanceOf(java_lang_Class));
// All array classes implement Cloneable and Serializable.
- Object* array = ObjectArray<Object>::Alloc(Object_array_class, 1);
+ Object* array = ObjectArray<Object>::Alloc(soa.Self(), Object_array_class, 1);
Class* java_lang_Cloneable = class_linker_->FindSystemClass("Ljava/lang/Cloneable;");
Class* java_io_Serializable = class_linker_->FindSystemClass("Ljava/io/Serializable;");
EXPECT_TRUE(array->InstanceOf(java_lang_Cloneable));
@@ -515,7 +518,7 @@
TEST_F(ObjectTest, FindInstanceField) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8("ABC"));
+ SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "ABC"));
ASSERT_TRUE(s.get() != NULL);
Class* c = s->GetClass();
ASSERT_TRUE(c != NULL);
@@ -548,7 +551,7 @@
TEST_F(ObjectTest, FindStaticField) {
ScopedObjectAccess soa(Thread::Current());
- SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8("ABC"));
+ SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "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 1d66c8f..297035f 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -24,6 +24,7 @@
#include "monitor.h"
#include "object.h"
#include "runtime.h"
+#include "sirt_ref.h"
#include "UniquePtr.h"
#include <string>
@@ -486,12 +487,15 @@
return GetDexFile().GetProtoParameters(proto);
}
- ObjectArray<Class>* GetParameterTypes()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ ObjectArray<Class>* GetParameterTypes(Thread* self)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile::TypeList* params = GetParameterTypeList();
- Class* array_class = GetClassLinker()->FindSystemClass("[Ljava/lang/Class;");
uint32_t num_params = params == NULL ? 0 : params->Size();
- ObjectArray<Class>* result = ObjectArray<Class>::Alloc(array_class, num_params);
+ SirtRef<ObjectArray<Class> > result(self, GetClassLinker()->AllocClassArray(self, num_params));
+ if (UNLIKELY(result.get() == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return NULL;
+ }
for (uint32_t i = 0; i < num_params; i++) {
Class* param_type = GetClassFromTypeIdx(params->GetTypeItem(i).type_idx_);
if (param_type == NULL) {
@@ -500,7 +504,7 @@
}
result->Set(i, param_type);
}
- return result;
+ return result.get();
}
Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
diff --git a/src/reference_table_test.cc b/src/reference_table_test.cc
index b35110d..c400f83 100644
--- a/src/reference_table_test.cc
+++ b/src/reference_table_test.cc
@@ -25,7 +25,7 @@
TEST_F(ReferenceTableTest, Basics) {
ScopedObjectAccess soa(Thread::Current());
- Object* o1 = String::AllocFromModifiedUtf8("hello");
+ Object* o1 = String::AllocFromModifiedUtf8(soa.Self(), "hello");
ReferenceTable rt("test", 0, 11);
@@ -56,7 +56,7 @@
}
// Add a second object 10 times and check dumping is sane.
- Object* o2 = ShortArray::Alloc(0);
+ Object* o2 = ShortArray::Alloc(soa.Self(), 0);
for (size_t i = 0; i < 10; ++i) {
rt.Add(o2);
EXPECT_EQ(i + 2, rt.Size());
diff --git a/src/reflection.cc b/src/reflection.cc
index 7d73ae2..c793d2c 100644
--- a/src/reflection.cc
+++ b/src/reflection.cc
@@ -234,11 +234,10 @@
LOG(FATAL) << static_cast<int>(src_class);
}
- if (kIsDebugBuild) {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- CHECK_EQ(Thread::Current()->GetState(), kRunnable);
- }
ScopedObjectAccessUnchecked soa(Thread::Current());
+ if (kIsDebugBuild) {
+ CHECK_EQ(soa.Self()->GetState(), kRunnable);
+ }
JValue args[1] = { value };
soa.DecodeMethod(m)->Invoke(soa.Self(), NULL, args, &value);
}
diff --git a/src/runtime.cc b/src/runtime.cc
index d10c351..3444f78 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -187,7 +187,7 @@
void Runtime::Abort() {
// Ensure that we don't have multiple threads trying to abort at once,
// which would result in significantly worse diagnostics.
- MutexLock mu(*Locks::abort_lock_);
+ MutexLock mu(Thread::Current(), *Locks::abort_lock_);
// Get any pending output out of the way.
fflush(NULL);
@@ -661,10 +661,7 @@
Thread* self = Thread::Current();
// Must be in the kNative state for calling native methods.
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- CHECK_EQ(self->GetState(), kNative);
- }
+ CHECK_EQ(self->GetState(), kNative);
JNIEnv* env = self->GetJniEnv();
env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons, WellKnownClasses::java_lang_Daemons_start);
@@ -762,10 +759,7 @@
JNIEnv* env = self->GetJniEnv();
// Must be in the kNative state for calling native methods (JNI_OnLoad code).
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- CHECK_EQ(self->GetState(), kNative);
- }
+ CHECK_EQ(self->GetState(), kNative);
// First set up JniConstants, which is used by both the runtime's built-in native
// methods and libcore.
@@ -984,8 +978,8 @@
AbstractMethod* Runtime::CreateResolutionMethod() {
Class* method_class = AbstractMethod::GetMethodClass();
- SirtRef<AbstractMethod> method(Thread::Current(),
- down_cast<AbstractMethod*>(method_class->AllocObject()));
+ Thread* self = Thread::Current();
+ SirtRef<AbstractMethod> method(self, down_cast<AbstractMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for resolution method saves
method->SetDexMethodIndex(DexFile::kDexNoIndex16);
@@ -998,8 +992,8 @@
AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set,
CalleeSaveType type) {
Class* method_class = AbstractMethod::GetMethodClass();
- SirtRef<AbstractMethod>
- method(Thread::Current(), down_cast<AbstractMethod*>(method_class->AllocObject()));
+ Thread* self = Thread::Current();
+ SirtRef<AbstractMethod> method(self, down_cast<AbstractMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for callee saves
method->SetDexMethodIndex(DexFile::kDexNoIndex16);
diff --git a/src/runtime_linux.cc b/src/runtime_linux.cc
index 85eeb8f..01c08d3 100644
--- a/src/runtime_linux.cc
+++ b/src/runtime_linux.cc
@@ -23,6 +23,7 @@
#include "logging.h"
#include "mutex.h"
#include "stringprintf.h"
+#include "thread.h"
#include "utils.h"
namespace art {
@@ -227,7 +228,7 @@
};
static void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
- MutexLock mu(*Locks::unexpected_signal_lock_);
+ MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
bool has_address = (signal_number == SIGILL || signal_number == SIGBUS ||
signal_number == SIGFPE || signal_number == SIGSEGV);
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 4af6fe5..54baa42 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -100,19 +100,19 @@
if (UNLIKELY(klass == NULL)) { // Not in dex cache so try to resolve
klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
if (klass == NULL) { // Error
- DCHECK(Thread::Current()->IsExceptionPending());
+ DCHECK(self->IsExceptionPending());
return NULL; // Failure
}
}
if (UNLIKELY(klass->IsPrimitive() && !klass->IsPrimitiveInt())) {
if (klass->IsPrimitiveLong() || klass->IsPrimitiveDouble()) {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
- "Bad filled array request for type %s",
- PrettyDescriptor(klass).c_str());
+ self->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
+ "Bad filled array request for type %s",
+ PrettyDescriptor(klass).c_str());
} else {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/InternalError;",
- "Found type %s; filled-new-array not implemented for anything but \'int\'",
- PrettyDescriptor(klass).c_str());
+ self->ThrowNewExceptionF("Ljava/lang/InternalError;",
+ "Found type %s; filled-new-array not implemented for anything but \'int\'",
+ PrettyDescriptor(klass).c_str());
}
return NULL; // Failure
} else {
@@ -124,7 +124,7 @@
}
}
DCHECK(klass->IsArrayClass()) << PrettyClass(klass);
- return Array::Alloc(klass, component_count);
+ return Array::Alloc(self, klass, component_count);
}
}
diff --git a/src/runtime_support.h b/src/runtime_support.h
index eff50b3..0d24e48 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -78,7 +78,7 @@
DCHECK(self->IsExceptionPending());
return NULL; // Failure
}
- return klass->AllocObject();
+ return klass->AllocObject(self);
}
// Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If
@@ -86,11 +86,10 @@
// When verification/compiler hasn't been able to verify access, optionally perform an access
// check.
static inline Array* AllocArrayFromCode(uint32_t type_idx, AbstractMethod* method, int32_t component_count,
- bool access_check)
+ Thread* self, bool access_check)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (UNLIKELY(component_count < 0)) {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d",
- component_count);
+ self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", component_count);
return NULL; // Failure
}
Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
@@ -109,7 +108,7 @@
return NULL; // Failure
}
}
- return Array::Alloc(klass, component_count);
+ return Array::Alloc(self, klass, component_count);
}
extern Array* CheckAndAllocArrayFromCode(uint32_t type_idx, AbstractMethod* method, int32_t component_count,
diff --git a/src/scoped_thread_state_change.h b/src/scoped_thread_state_change.h
index 9da41e0..32c3685 100644
--- a/src/scoped_thread_state_change.h
+++ b/src/scoped_thread_state_change.h
@@ -35,7 +35,7 @@
if (self_ == NULL) {
// Value chosen arbitrarily and won't be used in the destructor since thread_ == NULL.
old_thread_state_ = kTerminated;
- MutexLock mu(*Locks::runtime_shutdown_lock_);
+ MutexLock mu(NULL, *Locks::runtime_shutdown_lock_);
Runtime* runtime = Runtime::Current();
CHECK(runtime == NULL || !runtime->IsStarted() || runtime->IsShuttingDown());
} else {
@@ -63,7 +63,7 @@
~ScopedThreadStateChange() LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) {
if (self_ == NULL) {
if (!expected_has_no_thread_) {
- MutexLock mu(*Locks::runtime_shutdown_lock_);
+ MutexLock mu(NULL, *Locks::runtime_shutdown_lock_);
Runtime* runtime = Runtime::Current();
bool shutting_down = (runtime == NULL) || runtime->IsShuttingDown();
CHECK(shutting_down);
diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc
index 8376bb6..b6f6a41 100644
--- a/src/signal_catcher.cc
+++ b/src/signal_catcher.cc
@@ -85,12 +85,12 @@
}
void SignalCatcher::SetHaltFlag(bool new_value) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
halt_ = new_value;
}
bool SignalCatcher::ShouldHalt() {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
return halt_;
}
diff --git a/src/space.cc b/src/space.cc
index 58476ad..c1f4384 100644
--- a/src/space.cc
+++ b/src/space.cc
@@ -208,13 +208,13 @@
return result;
}
-Object* AllocSpace::AllocWithoutGrowth(size_t num_bytes) {
- MutexLock mu(lock_);
+Object* AllocSpace::AllocWithoutGrowth(Thread* self, size_t num_bytes) {
+ MutexLock mu(self, lock_);
return AllocWithoutGrowthLocked(num_bytes);
}
-Object* AllocSpace::AllocWithGrowth(size_t num_bytes) {
- MutexLock mu(lock_);
+Object* AllocSpace::AllocWithGrowth(Thread* self, size_t num_bytes) {
+ MutexLock mu(self, lock_);
// Grow as much as possible within the mspace.
size_t max_allowed = Capacity();
mspace_set_footprint_limit(mspace_, max_allowed);
@@ -284,8 +284,8 @@
return alloc_space;
}
-void AllocSpace::Free(Object* ptr) {
- MutexLock mu(lock_);
+void AllocSpace::Free(Thread* self, Object* ptr) {
+ MutexLock mu(self, lock_);
if (kDebugSpaces) {
CHECK(ptr != NULL);
CHECK(Contains(ptr)) << "Free (" << ptr << ") not in bounds of heap " << *this;
@@ -298,8 +298,8 @@
mspace_free(mspace_, ptr);
}
-void AllocSpace::FreeList(size_t num_ptrs, Object** ptrs) {
- MutexLock mu(lock_);
+void AllocSpace::FreeList(Thread* self, size_t num_ptrs, Object** ptrs) {
+ MutexLock mu(self, lock_);
if (kDebugSpaces) {
CHECK(ptrs != NULL);
size_t num_broken_ptrs = 0;
@@ -329,7 +329,7 @@
}
void* AllocSpace::MoreCore(intptr_t increment) {
- lock_.AssertHeld();
+ lock_.AssertHeld(Thread::Current());
byte* original_end = end_;
if (increment != 0) {
VLOG(heap) << "AllocSpace::MoreCore " << PrettySize(increment);
@@ -382,7 +382,7 @@
}
void AllocSpace::Trim() {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
// Trim to release memory at the end of the space.
mspace_trim(mspace_, 0);
// Visit space looking for page-sized holes to advise the kernel we don't need.
@@ -391,18 +391,18 @@
void AllocSpace::Walk(void(*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
void* arg) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
mspace_inspect_all(mspace_, callback, arg);
callback(NULL, NULL, 0, arg); // Indicate end of a space.
}
size_t AllocSpace::GetFootprintLimit() {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
return mspace_footprint_limit(mspace_);
}
void AllocSpace::SetFootprintLimit(size_t new_size) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
VLOG(heap) << "AllocSpace::SetFootprintLimit " << PrettySize(new_size);
// Compare against the actual footprint, rather than the Size(), because the heap may not have
// grown all the way to the allowed size yet.
@@ -575,12 +575,12 @@
return new LargeObjectMapSpace(name);
}
-Object* LargeObjectMapSpace::Alloc(size_t num_bytes) {
- MutexLock mu(lock_);
+Object* LargeObjectMapSpace::Alloc(Thread* self, size_t num_bytes) {
MemMap* mem_map = MemMap::MapAnonymous("allocation", NULL, num_bytes, PROT_READ | PROT_WRITE);
if (mem_map == NULL) {
return NULL;
}
+ MutexLock mu(self, lock_);
Object* obj = reinterpret_cast<Object*>(mem_map->Begin());
large_objects_.push_back(obj);
mem_maps_.Put(obj, mem_map);
@@ -589,8 +589,8 @@
return obj;
}
-void LargeObjectMapSpace::Free(Object* ptr) {
- MutexLock mu(lock_);
+void LargeObjectMapSpace::Free(Thread* self, Object* ptr) {
+ MutexLock mu(self, lock_);
MemMaps::iterator found = mem_maps_.find(ptr);
CHECK(found != mem_maps_.end()) << "Attempted to free large object which was not live";
DCHECK_GE(num_bytes_allocated_, found->second->Size());
@@ -601,14 +601,14 @@
}
size_t LargeObjectMapSpace::AllocationSize(const Object* obj) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
MemMaps::iterator found = mem_maps_.find(const_cast<Object*>(obj));
CHECK(found != mem_maps_.end()) << "Attempted to get size of a large object which is not live";
return found->second->Size();
}
void LargeObjectMapSpace::Walk(AllocSpace::WalkCallback callback, void* arg) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
for (MemMaps::iterator it = mem_maps_.begin(); it != mem_maps_.end(); ++it) {
MemMap* mem_map = it->second;
callback(mem_map->Begin(), mem_map->End(), mem_map->Size(), arg);
@@ -617,7 +617,7 @@
}
bool LargeObjectMapSpace::Contains(const Object* obj) const {
- MutexLock mu(const_cast<Mutex&>(lock_));
+ MutexLock mu(Thread::Current(), lock_);
return mem_maps_.find(const_cast<Object*>(obj)) != mem_maps_.end();
}
@@ -679,7 +679,7 @@
}
void FreeListSpace::Walk(AllocSpace::WalkCallback callback, void* arg) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
for (Chunk* chunk = &chunks_.front(); chunk < &chunks_.back(); ) {
if (!chunk->IsFree()) {
size_t size = chunk->GetSize();
@@ -692,8 +692,8 @@
}
}
-void FreeListSpace::Free(Object* obj) {
- MutexLock mu(lock_);
+void FreeListSpace::Free(Thread* self, Object* obj) {
+ MutexLock mu(self, lock_);
CHECK(Contains(obj));
// Check adjacent chunks to see if we need to combine.
Chunk* chunk = ChunkFromAddr(obj);
@@ -734,8 +734,8 @@
return chunk->GetSize();
}
-Object* FreeListSpace::Alloc(size_t num_bytes) {
- MutexLock mu(lock_);
+Object* FreeListSpace::Alloc(Thread* self, size_t num_bytes) {
+ MutexLock mu(self, lock_);
num_bytes = RoundUp(num_bytes, kAlignment);
Chunk temp;
temp.SetSize(num_bytes);
@@ -762,9 +762,9 @@
return reinterpret_cast<Object*>(addr);
}
-void FreeListSpace::FreeList(size_t num_ptrs, Object** ptrs) {
+void FreeListSpace::FreeList(Thread* self, size_t num_ptrs, Object** ptrs) {
for (size_t i = 0; i < num_ptrs; ++i) {
- Free(ptrs[i]);
+ Free(self, ptrs[i]);
}
}
diff --git a/src/space.h b/src/space.h
index 12682f9..af6ab3b 100644
--- a/src/space.h
+++ b/src/space.h
@@ -241,15 +241,15 @@
size_t capacity, byte* requested_begin);
// Allocate num_bytes without allowing the underlying mspace to grow.
- virtual Object* AllocWithGrowth(size_t num_bytes);
+ virtual Object* AllocWithGrowth(Thread* self, size_t num_bytes);
// Allocate num_bytes allowing the underlying mspace to grow.
- virtual Object* AllocWithoutGrowth(size_t num_bytes);
+ virtual Object* AllocWithoutGrowth(Thread* self, size_t num_bytes);
// Return the storage space required by obj.
virtual size_t AllocationSize(const Object* obj);
- virtual void Free(Object* ptr);
- virtual void FreeList(size_t num_ptrs, Object** ptrs);
+ virtual void Free(Thread* self, Object* ptr);
+ virtual void FreeList(Thread* self, size_t num_ptrs, Object** ptrs);
void* MoreCore(intptr_t increment);
@@ -435,8 +435,8 @@
// Return the storage space required by obj.
virtual size_t AllocationSize(const Object* obj) = 0;
- virtual Object* Alloc(size_t num_bytes) = 0;
- virtual void Free(Object* ptr) = 0;
+ virtual Object* Alloc(Thread* self, size_t num_bytes) = 0;
+ virtual void Free(Thread* self, Object* ptr) = 0;
virtual void Walk(AllocSpace::WalkCallback, void* arg) = 0;
virtual ~LargeObjectSpace() {}
@@ -472,8 +472,8 @@
// Return the storage space required by obj.
virtual size_t AllocationSize(const Object* obj);
- virtual Object* Alloc(size_t num_bytes);
- virtual void Free(Object* ptr);
+ virtual Object* Alloc(Thread* self, size_t num_bytes);
+ virtual void Free(Thread* self, Object* ptr);
virtual void Walk(AllocSpace::WalkCallback, void* arg);
virtual bool Contains(const Object* obj) const;
private:
@@ -481,7 +481,7 @@
virtual ~LargeObjectMapSpace() {}
// Used to ensure mutual exclusion when the allocation spaces data structures are being modified.
- Mutex lock_;
+ mutable Mutex lock_;
std::vector<Object*> large_objects_;
typedef SafeMap<Object*, MemMap*> MemMaps;
MemMaps mem_maps_;
@@ -493,9 +493,9 @@
static FreeListSpace* Create(const std::string& name, byte* requested_begin, size_t capacity);
virtual size_t AllocationSize(const Object* obj);
- virtual Object* Alloc(size_t num_bytes);
- virtual void Free(Object* obj);
- virtual void FreeList(size_t num_ptrs, Object** ptrs);
+ virtual Object* Alloc(Thread* self, size_t num_bytes);
+ virtual void Free(Thread* self, Object* obj);
+ virtual void FreeList(Thread* self, size_t num_ptrs, Object** ptrs);
virtual bool Contains(const Object* obj) const;
virtual void Walk(AllocSpace::WalkCallback callback, void* arg);
diff --git a/src/space_test.cc b/src/space_test.cc
index e9c45c4..0319147 100644
--- a/src/space_test.cc
+++ b/src/space_test.cc
@@ -80,106 +80,108 @@
// Make space findable to the heap, will also delete space when runtime is cleaned up
Runtime::Current()->GetHeap()->AddSpace(space);
+ Thread* self = Thread::Current();
// Succeeds, fits without adjusting the footprint limit.
- Object* ptr1 = space->AllocWithoutGrowth(1 * MB);
+ Object* ptr1 = space->AllocWithoutGrowth(self, 1 * MB);
EXPECT_TRUE(ptr1 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr2 = space->AllocWithoutGrowth(8 * MB);
+ Object* ptr2 = space->AllocWithoutGrowth(self, 8 * MB);
EXPECT_TRUE(ptr2 == NULL);
// Succeeds, adjusts the footprint.
- Object* ptr3 = space->AllocWithGrowth(8 * MB);
+ Object* ptr3 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr3 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr4 = space->AllocWithoutGrowth(8 * MB);
+ Object* ptr4 = space->AllocWithoutGrowth(self, 8 * MB);
EXPECT_TRUE(ptr4 == NULL);
// Also fails, requires a higher allowed footprint.
- Object* ptr5 = space->AllocWithGrowth(8 * MB);
+ Object* ptr5 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr5 == NULL);
// Release some memory.
size_t free3 = space->AllocationSize(ptr3);
- space->Free(ptr3);
+ space->Free(self, ptr3);
EXPECT_LE(8U * MB, free3);
// Succeeds, now that memory has been freed.
- void* ptr6 = space->AllocWithGrowth(9 * MB);
+ void* ptr6 = space->AllocWithGrowth(self, 9 * MB);
EXPECT_TRUE(ptr6 != NULL);
// Final clean up.
size_t free1 = space->AllocationSize(ptr1);
- space->Free(ptr1);
+ space->Free(self, ptr1);
EXPECT_LE(1U * MB, free1);
// Make sure that the zygote space isn't directly at the start of the space.
- space->AllocWithoutGrowth(1U * MB);
+ space->AllocWithoutGrowth(self, 1U * MB);
space = space->CreateZygoteSpace();
// Make space findable to the heap, will also delete space when runtime is cleaned up
Runtime::Current()->GetHeap()->AddSpace(space);
// Succeeds, fits without adjusting the footprint limit.
- ptr1 = space->AllocWithoutGrowth(1 * MB);
+ ptr1 = space->AllocWithoutGrowth(self, 1 * MB);
EXPECT_TRUE(ptr1 != NULL);
// Fails, requires a higher footprint limit.
- ptr2 = space->AllocWithoutGrowth(8 * MB);
+ ptr2 = space->AllocWithoutGrowth(self, 8 * MB);
EXPECT_TRUE(ptr2 == NULL);
// Succeeds, adjusts the footprint.
- ptr3 = space->AllocWithGrowth(2 * MB);
+ ptr3 = space->AllocWithGrowth(self, 2 * MB);
EXPECT_TRUE(ptr3 != NULL);
- space->Free(ptr3);
+ space->Free(self, ptr3);
// Final clean up.
free1 = space->AllocationSize(ptr1);
- space->Free(ptr1);
+ space->Free(self, ptr1);
EXPECT_LE(1U * MB, free1);
}
TEST_F(SpaceTest, AllocAndFree) {
AllocSpace* space(AllocSpace::Create("test", 4 * MB, 16 * MB, 16 * MB, NULL));
ASSERT_TRUE(space != NULL);
+ Thread* self = Thread::Current();
// Make space findable to the heap, will also delete space when runtime is cleaned up
Runtime::Current()->GetHeap()->AddSpace(space);
// Succeeds, fits without adjusting the footprint limit.
- Object* ptr1 = space->AllocWithoutGrowth(1 * MB);
+ Object* ptr1 = space->AllocWithoutGrowth(self, 1 * MB);
EXPECT_TRUE(ptr1 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr2 = space->AllocWithoutGrowth(8 * MB);
+ Object* ptr2 = space->AllocWithoutGrowth(self, 8 * MB);
EXPECT_TRUE(ptr2 == NULL);
// Succeeds, adjusts the footprint.
- Object* ptr3 = space->AllocWithGrowth(8 * MB);
+ Object* ptr3 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr3 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr4 = space->AllocWithoutGrowth(8 * MB);
+ Object* ptr4 = space->AllocWithoutGrowth(self, 8 * MB);
EXPECT_TRUE(ptr4 == NULL);
// Also fails, requires a higher allowed footprint.
- Object* ptr5 = space->AllocWithGrowth(8 * MB);
+ Object* ptr5 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr5 == NULL);
// Release some memory.
size_t free3 = space->AllocationSize(ptr3);
- space->Free(ptr3);
+ space->Free(self, ptr3);
EXPECT_LE(8U * MB, free3);
// Succeeds, now that memory has been freed.
- void* ptr6 = space->AllocWithGrowth(9 * MB);
+ void* ptr6 = space->AllocWithGrowth(self, 9 * MB);
EXPECT_TRUE(ptr6 != NULL);
// Final clean up.
size_t free1 = space->AllocationSize(ptr1);
- space->Free(ptr1);
+ space->Free(self, ptr1);
EXPECT_LE(1U * MB, free1);
}
@@ -189,28 +191,29 @@
// Make space findable to the heap, will also delete space when runtime is cleaned up
Runtime::Current()->GetHeap()->AddSpace(space);
+ Thread* self = Thread::Current();
// Succeeds, fits without adjusting the max allowed footprint.
Object* lots_of_objects[1024];
for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
- lots_of_objects[i] = space->AllocWithoutGrowth(16);
+ lots_of_objects[i] = space->AllocWithoutGrowth(self, 16);
EXPECT_TRUE(lots_of_objects[i] != NULL);
}
// Release memory and check pointers are NULL
- space->FreeList(arraysize(lots_of_objects), lots_of_objects);
+ space->FreeList(self, arraysize(lots_of_objects), lots_of_objects);
for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
EXPECT_TRUE(lots_of_objects[i] == NULL);
}
// Succeeds, fits by adjusting the max allowed footprint.
for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
- lots_of_objects[i] = space->AllocWithGrowth(1024);
+ lots_of_objects[i] = space->AllocWithGrowth(self, 1024);
EXPECT_TRUE(lots_of_objects[i] != NULL);
}
// Release memory and check pointers are NULL
- space->FreeList(arraysize(lots_of_objects), lots_of_objects);
+ space->FreeList(self, arraysize(lots_of_objects), lots_of_objects);
for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
EXPECT_TRUE(lots_of_objects[i] == NULL);
}
@@ -252,6 +255,7 @@
UniquePtr<Object*[]> lots_of_objects(new Object*[max_objects]);
size_t last_object = 0; // last object for which allocation succeeded
size_t amount_allocated = 0; // amount of space allocated
+ Thread* self = Thread::Current();
for (size_t i = 0; i < max_objects; i++) {
size_t alloc_fails = 0; // number of failed allocations
size_t max_fails = 30; // number of times we fail allocation before giving up
@@ -267,9 +271,9 @@
}
Object* object;
if (round <= 1) {
- object = space->AllocWithoutGrowth(alloc_size);
+ object = space->AllocWithoutGrowth(self, alloc_size);
} else {
- object = space->AllocWithGrowth(alloc_size);
+ object = space->AllocWithGrowth(self, alloc_size);
}
footprint = mspace_footprint(mspace);
EXPECT_GE(space->Size(), footprint); // invariant
@@ -332,7 +336,7 @@
} else {
EXPECT_GE(allocation_size, 8u);
}
- space->Free(object);
+ space->Free(self, object);
lots_of_objects.get()[i] = NULL;
amount_allocated -= allocation_size;
footprint = mspace_footprint(mspace);
@@ -346,9 +350,9 @@
Object* large_object;
size_t three_quarters_space = (growth_limit / 2) + (growth_limit / 4);
if (round <= 1) {
- large_object = space->AllocWithoutGrowth(three_quarters_space);
+ large_object = space->AllocWithoutGrowth(self, three_quarters_space);
} else {
- large_object = space->AllocWithGrowth(three_quarters_space);
+ large_object = space->AllocWithGrowth(self, three_quarters_space);
}
EXPECT_TRUE(large_object != NULL);
@@ -359,7 +363,7 @@
EXPECT_LE(space->Size(), growth_limit);
// Clean up
- space->Free(large_object);
+ space->Free(self, large_object);
// Sanity check footprint
footprint = mspace_footprint(mspace);
diff --git a/src/thread.cc b/src/thread.cc
index ba8763c..a63a5aa 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -110,7 +110,9 @@
return NULL;
}
{
- MutexLock mu(*Locks::runtime_shutdown_lock_);
+ // TODO: pass self to MutexLock - requires self to equal Thread::Current(), which is only true
+ // after self->Init().
+ MutexLock mu(NULL, *Locks::runtime_shutdown_lock_);
// Check that if we got here we cannot be shutting down (as shutdown should never have started
// while threads are being born).
CHECK(!runtime->IsShuttingDown());
@@ -719,7 +721,6 @@
if (is_daemon) {
os << " daemon";
}
- MutexLock mu(self, *Locks::thread_suspend_count_lock_);
os << " prio=" << priority
<< " tid=" << thread->GetThinLockId()
<< " " << thread->GetState() << "\n";
@@ -874,7 +875,7 @@
void Thread::Startup() {
{
- MutexLock mu(*Locks::thread_suspend_count_lock_); // Keep GCC happy.
+ MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_); // Keep GCC happy.
resume_cond_ = new ConditionVariable("Thread resumption condition variable");
}
@@ -1166,7 +1167,7 @@
// Implements java.lang.Thread.interrupted.
bool Thread::Interrupted() {
- MutexLock mu(*wait_mutex_);
+ MutexLock mu(Thread::Current(), *wait_mutex_);
bool interrupted = interrupted_;
interrupted_ = false;
return interrupted;
@@ -1174,12 +1175,12 @@
// Implements java.lang.Thread.isInterrupted.
bool Thread::IsInterrupted() {
- MutexLock mu(*wait_mutex_);
+ MutexLock mu(Thread::Current(), *wait_mutex_);
return interrupted_;
}
void Thread::Interrupt() {
- MutexLock mu(*wait_mutex_);
+ MutexLock mu(Thread::Current(), *wait_mutex_);
if (interrupted_) {
return;
}
@@ -1188,7 +1189,7 @@
}
void Thread::Notify() {
- MutexLock mu(*wait_mutex_);
+ MutexLock mu(Thread::Current(), *wait_mutex_);
NotifyLocked();
}
@@ -1252,11 +1253,12 @@
// Allocate method trace with an extra slot that will hold the PC trace
SirtRef<ObjectArray<Object> >
method_trace(self_,
- Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(depth + 1));
+ Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(self_,
+ depth + 1));
if (method_trace.get() == NULL) {
return false;
}
- IntArray* dex_pc_trace = IntArray::Alloc(depth);
+ IntArray* dex_pc_trace = IntArray::Alloc(self_, depth);
if (dex_pc_trace == NULL) {
return false;
}
@@ -1350,7 +1352,7 @@
depth = std::min(depth, java_traces->GetLength());
} else {
// Create java_trace array and place in local reference table
- java_traces = class_linker->AllocStackTraceElementArray(depth);
+ java_traces = class_linker->AllocStackTraceElementArray(soa.Self(), depth);
if (java_traces == NULL) {
return NULL;
}
@@ -1374,19 +1376,23 @@
CHECK(descriptor != NULL);
std::string class_name(PrettyDescriptor(descriptor));
SirtRef<String> class_name_object(soa.Self(),
- String::AllocFromModifiedUtf8(class_name.c_str()));
+ String::AllocFromModifiedUtf8(soa.Self(),
+ 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(soa.Self(), String::AllocFromModifiedUtf8(method_name));
+ SirtRef<String> method_name_object(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(),
+ method_name));
if (method_name_object.get() == NULL) {
return NULL;
}
const char* source_file = mh.GetDeclaringClassSourceFile();
- SirtRef<String> source_name_object(soa.Self(), String::AllocFromModifiedUtf8(source_file));
- StackTraceElement* obj = StackTraceElement::Alloc(class_name_object.get(),
+ SirtRef<String> source_name_object(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(),
+ source_file));
+ StackTraceElement* obj = StackTraceElement::Alloc(soa.Self(),
+ class_name_object.get(),
method_name_object.get(),
source_name_object.get(),
line_number);
@@ -1450,7 +1456,7 @@
if (exception.get() != NULL) {
ScopedObjectAccessUnchecked soa(env);
Throwable* t = reinterpret_cast<Throwable*>(soa.Self()->DecodeJObject(exception.get()));
- t->SetDetailMessage(String::AllocFromModifiedUtf8(msg));
+ t->SetDetailMessage(String::AllocFromModifiedUtf8(soa.Self(), msg));
soa.Self()->SetException(t);
} else {
LOG(ERROR) << "Couldn't throw new " << descriptor << " because JNI AllocObject failed: "
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 83f2658..4030be6 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -66,7 +66,7 @@
void ThreadList::DumpForSigQuit(std::ostream& os) {
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
DumpLocked(os);
}
DumpUnattachedThreads(os);
@@ -91,13 +91,14 @@
dirent de;
dirent* e;
+ Thread* self = Thread::Current();
while (!readdir_r(d, &de, &e) && e != NULL) {
char* end;
pid_t tid = strtol(de.d_name, &end, 10);
if (!*end) {
bool contains;
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(self, *Locks::thread_list_lock_);
contains = Contains(tid);
}
if (!contains) {
@@ -109,7 +110,7 @@
}
void ThreadList::DumpLocked(std::ostream& os) {
- Locks::thread_list_lock_->AssertHeld();
+ Locks::thread_list_lock_->AssertHeld(Thread::Current());
os << "DALVIK THREADS (" << list_.size() << "):\n";
for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
(*it)->Dump(os);
@@ -117,9 +118,9 @@
}
}
-void ThreadList::AssertThreadsAreSuspended(Thread* ignore1, Thread* ignore2) {
- MutexLock mu(*Locks::thread_list_lock_);
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+void ThreadList::AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2) {
+ MutexLock mu(self, *Locks::thread_list_lock_);
+ MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
Thread* thread = *it;
if (thread != ignore1 || thread == ignore2) {
@@ -194,7 +195,7 @@
#endif
// Debug check that all threads are suspended.
- AssertThreadsAreSuspended(self);
+ AssertThreadsAreSuspended(self, self);
VLOG(threads) << *self << " SuspendAll complete";
}
@@ -205,7 +206,7 @@
VLOG(threads) << *self << " ResumeAll starting";
// Debug check that all threads are suspended.
- AssertThreadsAreSuspended(self);
+ AssertThreadsAreSuspended(self, self);
Locks::mutator_lock_->ExclusiveUnlock(self);
{
@@ -297,7 +298,7 @@
Locks::mutator_lock_->ExclusiveLock(self);
Locks::mutator_lock_->ExclusiveUnlock(self);
#endif
- AssertThreadsAreSuspended(self, debug_thread);
+ AssertThreadsAreSuspended(self, self, debug_thread);
VLOG(threads) << *self << " SuspendAll complete";
}
@@ -422,7 +423,6 @@
bool all_suspended = true;
for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
Thread* thread = *it;
- MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
if (thread != self && thread->GetState() == kRunnable) {
if (!have_complained) {
LOG(WARNING) << "daemon thread not yet suspended: " << *thread;
diff --git a/src/thread_list.h b/src/thread_list.h
index b5546e3..94e987f 100644
--- a/src/thread_list.h
+++ b/src/thread_list.h
@@ -105,7 +105,7 @@
LOCKS_EXCLUDED(Locks::thread_list_lock_,
Locks::thread_suspend_count_lock_);
- void AssertThreadsAreSuspended(Thread* ignore1, Thread* ignore2 = NULL)
+ void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL)
LOCKS_EXCLUDED(Locks::thread_list_lock_,
Locks::thread_suspend_count_lock_);
diff --git a/src/thread_x86.cc b/src/thread_x86.cc
index 6a72286..c841235 100644
--- a/src/thread_x86.cc
+++ b/src/thread_x86.cc
@@ -21,6 +21,7 @@
#include "asm_support.h"
#include "macros.h"
+#include "thread.h"
#include "thread_list.h"
#if defined(__APPLE__)
@@ -41,7 +42,7 @@
void Thread::InitCpu() {
static Mutex modify_ldt_lock("modify_ldt lock");
- MutexLock mu(modify_ldt_lock);
+ MutexLock mu(Thread::Current(), modify_ldt_lock);
const uintptr_t base = reinterpret_cast<uintptr_t>(this);
const size_t limit = kPageSize;
diff --git a/src/utils_test.cc b/src/utils_test.cc
index 1fcb4b3..f1983be 100644
--- a/src/utils_test.cc
+++ b/src/utils_test.cc
@@ -89,15 +89,15 @@
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyTypeOf(NULL));
- SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(""));
+ SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
EXPECT_EQ("java.lang.String", PrettyTypeOf(s.get()));
- SirtRef<ShortArray> a(soa.Self(), ShortArray::Alloc(2));
+ SirtRef<ShortArray> a(soa.Self(), ShortArray::Alloc(soa.Self(), 2));
EXPECT_EQ("short[]", PrettyTypeOf(a.get()));
Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- Object* o = ObjectArray<String>::Alloc(c, 0);
+ Object* o = ObjectArray<String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.String[]", PrettyTypeOf(o));
EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyTypeOf(o->GetClass()));
}
@@ -107,7 +107,7 @@
EXPECT_EQ("null", PrettyClass(NULL));
Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- Object* o = ObjectArray<String>::Alloc(c, 0);
+ Object* o = ObjectArray<String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyClass(o->GetClass()));
}
@@ -116,7 +116,7 @@
EXPECT_EQ("null", PrettyClassAndClassLoader(NULL));
Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- Object* o = ObjectArray<String>::Alloc(c, 0);
+ Object* o = ObjectArray<String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.Class<java.lang.String[],null>", PrettyClassAndClassLoader(o->GetClass()));
}
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index dd9aa8b..ad238b8 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -3229,7 +3229,7 @@
void MethodVerifier::SetDexGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& gc_map) {
{
- MutexLock mu(*dex_gc_maps_lock_);
+ MutexLock mu(Thread::Current(), *dex_gc_maps_lock_);
DexGcMapTable::iterator it = dex_gc_maps_->find(ref);
if (it != dex_gc_maps_->end()) {
delete it->second;
@@ -3241,7 +3241,7 @@
}
const std::vector<uint8_t>* MethodVerifier::GetDexGcMap(Compiler::MethodReference ref) {
- MutexLock mu(*dex_gc_maps_lock_);
+ MutexLock mu(Thread::Current(), *dex_gc_maps_lock_);
DexGcMapTable::const_iterator it = dex_gc_maps_->find(ref);
if (it == dex_gc_maps_->end()) {
return NULL;
@@ -3263,29 +3263,31 @@
void MethodVerifier::Init() {
dex_gc_maps_lock_ = new Mutex("verifier GC maps lock");
+ Thread* self = Thread::Current();
{
- MutexLock mu(*dex_gc_maps_lock_);
+ MutexLock mu(self, *dex_gc_maps_lock_);
dex_gc_maps_ = new MethodVerifier::DexGcMapTable;
}
rejected_classes_lock_ = new Mutex("verifier rejected classes lock");
{
- MutexLock mu(*rejected_classes_lock_);
+ MutexLock mu(self, *rejected_classes_lock_);
rejected_classes_ = new MethodVerifier::RejectedClassesTable;
}
#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
inferred_reg_category_maps_lock_ = new Mutex("verifier GC maps lock");
{
- MutexLock mu(*inferred_reg_category_maps_lock_);
+ MutexLock mu(self, *inferred_reg_category_maps_lock_);
inferred_reg_category_maps_ = new MethodVerifier::InferredRegCategoryMapTable;
}
#endif
}
void MethodVerifier::Shutdown() {
+ Thread* self = Thread::Current();
{
- MutexLock mu(*dex_gc_maps_lock_);
+ MutexLock mu(self, *dex_gc_maps_lock_);
STLDeleteValues(dex_gc_maps_);
delete dex_gc_maps_;
dex_gc_maps_ = NULL;
@@ -3294,7 +3296,7 @@
dex_gc_maps_lock_ = NULL;
{
- MutexLock mu(*rejected_classes_lock_);
+ MutexLock mu(self, *rejected_classes_lock_);
delete rejected_classes_;
rejected_classes_ = NULL;
}
@@ -3303,7 +3305,7 @@
#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
{
- MutexLock mu(*inferred_reg_category_maps_lock_);
+ MutexLock mu(self, *inferred_reg_category_maps_lock_);
STLDeleteValues(inferred_reg_category_maps_);
delete inferred_reg_category_maps_;
inferred_reg_category_maps_ = NULL;
@@ -3315,14 +3317,14 @@
void MethodVerifier::AddRejectedClass(Compiler::ClassReference ref) {
{
- MutexLock mu(*rejected_classes_lock_);
+ MutexLock mu(Thread::Current(), *rejected_classes_lock_);
rejected_classes_->insert(ref);
}
CHECK(IsClassRejected(ref));
}
bool MethodVerifier::IsClassRejected(Compiler::ClassReference ref) {
- MutexLock mu(*rejected_classes_lock_);
+ MutexLock mu(Thread::Current(), *rejected_classes_lock_);
return (rejected_classes_->find(ref) != rejected_classes_->end());
}
@@ -3374,7 +3376,7 @@
void MethodVerifier::SetInferredRegCategoryMap(Compiler::MethodReference ref,
const InferredRegCategoryMap& inferred_reg_category_map) {
{
- MutexLock mu(*inferred_reg_category_maps_lock_);
+ MutexLock mu(Thread::Current(), *inferred_reg_category_maps_lock_);
InferredRegCategoryMapTable::iterator it = inferred_reg_category_maps_->find(ref);
if (it == inferred_reg_category_maps_->end()) {
inferred_reg_category_maps_->Put(ref, &inferred_reg_category_map);
@@ -3388,7 +3390,7 @@
const greenland::InferredRegCategoryMap*
MethodVerifier::GetInferredRegCategoryMap(Compiler::MethodReference ref) {
- MutexLock mu(*inferred_reg_category_maps_lock_);
+ MutexLock mu(Thread::Current(), *inferred_reg_category_maps_lock_);
InferredRegCategoryMapTable::const_iterator it =
inferred_reg_category_maps_->find(ref);